blob: 5a632100e25fcccd798471f8523644e6c9860e9b [file] [log] [blame]
/*
* Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This file was originally distributed by Qualcomm Atheros, Inc.
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
/**=========================================================================
\file 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;
tANI_U32 nTime = 0;
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(csrIsAllSessionDisconnected(pMac) &&
!HAL_STATUS_SUCCESS(csrScanTriggerIdleScan(pMac,
&nTime))) {
csrScanStartIdleScanTimer(pMac, nTime);
}
/*
* 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)
{
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:
{
status = sme_HandlePreChannelSwitchInd(pMac);
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 rescived from PE, SME tdls msg processor shall be called
* to process commands recieved 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_CHANNEL_SWITCH_RSP:
{
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->bodyval);
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_zero(pMsg->bodyptr,
sizeof(tSirGtkOffloadGetInfoRspParams));
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->pAdapter, pMsg->bodyptr);
}
vos_mem_free(pMsg->bodyptr);
break;
#endif /* FEATURE_WLAN_LPHB */
#ifdef WLAN_FEATURE_RMC
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 ;
#endif /* WLAN_FEATURE_RMC */
#ifdef FEATURE_WLAN_CH_AVOID
/* LPHB timeout indication 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->pAdapter, pMsg->bodyptr);
}
vos_mem_free(pMsg->bodyptr);
break;
#endif /* FEATURE_WLAN_CH_AVOID */
case eWNI_SME_ENCRYPT_MSG_RSP:
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type));
if (pMsg->bodyptr)
{
sme_EncryptMsgResponseHandler(pMac, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog(pMac, LOGE,
"Empty rsp message for (eWNI_SME_ENCRYPT_MSG_RSP),"
" nothing to process");
}
break ;
case eWNI_SME_UPDATE_MAX_RATE_IND:
if (pMsg->bodyptr)
{
sme_UpdateMaxRateInd(pMac, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog(pMac, LOGE,
"Empty message for (eWNI_SME_UPDATE_MAX_RATE_IND),"
" nothing to process");
}
break;
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);
}
else
{
smsLog(pMac, LOGE,
"Empty message for (eWNI_SME_NAN_EVENT),"
" nothing to process");
}
break;
case eWNI_SME_ECSA_IE_BEACON_COMP_IND:
case eWNI_SME_ECSA_CHAN_CHANGE_RSP:
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_WDA_MSG, NO_SESSION, pMsg->type));
if (pMsg->bodyptr)
{
sme_ecsa_msg_processor(pMac, pMsg->type, pMsg->bodyptr);
vos_mem_free(pMsg->bodyptr);
}
else
{
smsLog(pMac, LOGE,
FL("Empty message for (eWNI_SME_ECSA_IE_BEACON_COMP_IND)"));
}
break;
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 );
status = WLANSAP_Stop(vos_get_global_context(VOS_MODULE_ID_SAP, NULL));
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "WLANSAP_Stop failed during smeStop with status=%d",
status );
fail_status = status;
}
p2pStop(hHal);
status = pmcStop(hHal);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "pmcStop 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 );
status = csrClose(pMac);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "csrClose failed during sme close with status=%d",
status );
fail_status = status;
}
status = WLANSAP_Close(vos_get_global_context(VOS_MODULE_ID_SAP, NULL));
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "WLANSAP_close failed during sme close with status=%d",
status );
fail_status = status;
}
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
status = btcClose(hHal);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "BTC close failed during sme close with status=%d",
status );
fail_status = status;
}
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;
}
status = pmcClose(hHal);
if ( ! HAL_STATUS_SUCCESS( status ) ) {
smsLog( pMac, LOGE, "pmcClose failed during sme close with 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
#if defined WLAN_FEATURE_VOWIFI_11R
sme_FTClose(hHal);
#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;
}
v_VOID_t sme_PreClose(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
if(!pMac)
return;
smsLog(pMac, LOGW, FL("Stopping Active CMD List Timer"));
vos_timer_stop( pMac->sme.smeCmdActiveList.cmdTimeoutTimer );
}
#ifdef FEATURE_WLAN_LFR
tANI_BOOLEAN csrIsScanAllowed(tpAniSirGlobal pMac)
{
#if 0
switch(pMac->roam.neighborRoamInfo.neighborRoamState) {
case eCSR_NEIGHBOR_ROAM_STATE_REPORT_SCAN:
case eCSR_NEIGHBOR_ROAM_STATE_PREAUTHENTICATING:
case eCSR_NEIGHBOR_ROAM_STATE_PREAUTH_DONE:
case eCSR_NEIGHBOR_ROAM_STATE_REASSOCIATING:
return eANI_BOOLEAN_FALSE;
default:
return eANI_BOOLEAN_TRUE;
}
#else
/*
* TODO: always return TRUE for now until
* we figure out why we could be stuck in
* one of the roaming states forever.
*/
return eANI_BOOLEAN_TRUE;
#endif
}
#endif
/* ---------------------------------------------------------------------------
\fn sco_isScanAllowed
\brief check for scan interface connection status
\param pMac - Pointer to the global MAC parameter structure
\param pScanReq - scan request structure.
\return tANI_BOOLEAN TRUE to allow scan otherwise FALSE
---------------------------------------------------------------------------*/
tANI_BOOLEAN sco_isScanAllowed(tpAniSirGlobal pMac, tCsrScanRequest *pscanReq)
{
tANI_BOOLEAN ret;
if (pscanReq->p2pSearch)
ret = csrIsP2pSessionConnected(pMac);
else
ret = csrIsStaSessionConnected(pMac);
return !ret;
}
/* ---------------------------------------------------------------------------
\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, LOG1,
FL("isCoexScoIndSet %d disable_scan_during_sco %d is_disconnected %d"),
pMac->isCoexScoIndSet,
pMac->scan.disable_scan_during_sco,
csrIsConnStateDisconnected(pMac, sessionId));
if (pMac->isCoexScoIndSet && pMac->scan.disable_scan_during_sco &&
csrIsConnStateDisconnected(pMac, sessionId)) {
csrScanFlushResult(pMac);
pMac->scan.disable_scan_during_sco_timer_info.callback = callback;
pMac->scan.disable_scan_during_sco_timer_info.dev = pContext;
pMac->scan.disable_scan_during_sco_timer_info.scan_id= *pScanRequestID;
vos_timer_start(&pMac->scan.disable_scan_during_sco_timer,
CSR_DISABLE_SCAN_DURING_SCO);
return eHAL_STATUS_SUCCESS;
}
do
{
if(pMac->scan.fScanEnable &&
(pMac->isCoexScoIndSet ? sco_isScanAllowed(pMac, pscanReq) : TRUE))
{
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
{
#ifdef FEATURE_WLAN_LFR
if(csrIsScanAllowed(pMac))
{
#endif
status = csrScanRequest( hHal, sessionId, pscanReq,
pScanRequestID, callback, pContext );
if ( !HAL_STATUS_SUCCESS( status ) )
{
smsLog(pMac, LOGE, FL("csrScanRequest failed"
" SId=%d"), sessionId);
}
#ifdef FEATURE_WLAN_LFR
}
else
{
smsLog(pMac, LOGE, FL("Scan denied in state %s"
"(sub-state %s)"),
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState),
macTraceGetcsrRoamSubState(
pMac->roam.curSubState[sessionId]));
/*HandOff is in progress. So schedule this scan later*/
status = eHAL_STATUS_RESOURCES;
}
#endif
}
sme_ReleaseGlobalLock( &pMac->sme );
} //sme_AcquireGlobalLock success
else
{
smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock failed"));
}
} //if(pMac->scan.fScanEnable)
else
{
smsLog(pMac, LOGE, FL("fScanEnable %d isCoexScoIndSet: %d "),
pMac->scan.fScanEnable, pMac->isCoexScoIndSet);
status = eHAL_STATUS_RESOURCES;
}
} 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);
}
/* ---------------------------------------------------------------------------
\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 );
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
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_FilterScanResults(tHalHandle hHal, tANI_U8 sessionId)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
MTRACE(macTraceNew(pMac, 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);
}
/*
* ---------------------------------------------------------------------------
* \fn sme_FilterScanDFSResults
* \brief a wrapper function to request CSR to filter BSSIDs on DFS channels
* from the scan results.
* \return eHalStatus
*---------------------------------------------------------------------------
*/
eHalStatus sme_FilterScanDFSResults(tHalHandle hHal)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
csrScanFilterDFSResults(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 reutrns.
\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 retruning, 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));
}
/* ---------------------------------------------------------------------------
\fn sme_RoamRegisterCallback
\brief a wrapper function to allow HDD to register a callback with CSR.
Unlike scan, roam has one callback for all the roam requests
\param callback - a callback function that roam calls upon when state changes
\param pContext - a pointer passed in for the callback
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_RoamRegisterCallback(tHalHandle hHal,
csrRoamCompleteCallback callback,
void *pContext)
{
return(csrRoamRegisterCallback((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;
}
#ifdef WLAN_FEATURE_AP_HT40_24G
/* ---------------------------------------------------------------------------
\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.channelBondingAPMode24GHz;
}
/* ---------------------------------------------------------------------------
\fn sme_UpdateChannelBondingMode24G
\brief update the channel bonding mode for 2.4G band
\param hHal - HAL handle
\param cbMode - channel bonding mode
\return
---------------------------------------------------------------------------*/
void sme_UpdateChannelBondingMode24G(tHalHandle hHal, tANI_U8 cbMode)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tSmeConfigParams smeConfig;
vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
sme_GetConfigParam(pMac, &smeConfig);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("Previous Channel Bonding : = %d"),
smeConfig.csrConfig.channelBondingAPMode24GHz);
smeConfig.csrConfig.channelBondingAPMode24GHz = cbMode;
sme_UpdateConfig(hHal, &smeConfig);
VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
FL("New Channel Bonding : = %d"),
sme_GetChannelBondingMode24G(hHal));
return;
}
/* ---------------------------------------------------------------------------
\fn sme_SetHT2040Mode
\brief To update HT Operation beacon IE & Channel Bonding.
\param
\return eHalStatus SUCCESS
FAILURE or RESOURCES
The API finished and failed.
-------------------------------------------------------------------------------*/
eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 cbMode)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("Channel Bonding =%d"),
cbMode);
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status))
{
status = csrSetHT2040Mode(pMac, sessionId, cbMode);
sme_ReleaseGlobalLock(&pMac->sme );
}
return (status);
}
#endif
/* ---------------------------------------------------------------------------
\fn sme_RoamConnect
\brief a wrapper function to request CSR to inititiate 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 inititiate 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))
{
tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, sessionId );
/* to force the AP initiate fresh 802.1x authentication need to clear
* the PMKID cache for that set the following boolean. this is needed
* by the HS 2.0 passpoint certification 5.2.a and b testcases */
pSession->fIgnorePMKIDCache = TRUE;
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 );
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 meanful.
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_RoamDisconnect(tHalHandle hHal, tANI_U8 sessionId, eCsrRoamDisconnectReason reason)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
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 ) )
{
/*
* Indicate csr of disconnect so that
* in progress connection, scan for ssid and preauth
* can be aborted
*/
csr_abortConnection(pMac, sessionId);
status = csrRoamDisconnect(pMac, sessionId, reason);
}
else
{
status = eHAL_STATUS_INVALID_PARAMETER;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
/* ---------------------------------------------------------------------------
\fn.sme_abortConnection
\brief a wrapper function to request CSR to stop from connecting a network
\retun void.
---------------------------------------------------------------------------*/
void sme_abortConnection(tHalHandle hHal, tANI_U8 sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_FAILURE;
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
{
csr_abortConnection( pMac, sessionId);
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return;
}
/* 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 );
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_FALSE );
}
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,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tANI_U8 *pPeerMacAddr
#else
tANI_U8 *pPeerMacAddr
#endif
)
{
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, pPeerMacAddr,
eSIR_MAC_DEAUTH_LEAVING_BSS_REASON);
}
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 associtated 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 associatd 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 retruning, 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,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
tPmkidCacheInfo *pmksa,
#else
tPmkidCacheInfo *pmksa,
#endif
tANI_BOOLEAN flush_cache )
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_ROAM_DEL_PMKIDCACHE, sessionId, flush_cache));
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);
}
/* ---------------------------------------------------------------------------
\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 );
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;
}
#if defined WLAN_FEATURE_P2P_INTERNAL
status = p2pGetConfigParam(pMac, &pParam->p2pConfig);
if (status != eHAL_STATUS_SUCCESS)
{
smsLog( pMac, LOGE, "%s p2pGetConfigParam failed", __func__);
sme_ReleaseGlobalLock( &pMac->sme );
return status;
}
#endif
pParam->fBtcEnableIndTimerVal = pMac->fBtcEnableIndTimerVal;
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_HT40StopOBSSScan
\brief HDD or SME - Command to stop the OBSS scan
THis is implemented only for debugging purpose.
As per spec while operating in 2.4GHz OBSS scan shouldnt be stopped.
\param sessionId - sessionId
changing which can cause reassoc
\return eHalStatus
-------------------------------------------------------------------------------*/
eHalStatus sme_HT40StopOBSSScan(tHalHandle hHal, tANI_U8 sessionId)
{
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 ) )
{
if( CSR_IS_SESSION_VALID( pMac, sessionId ) )
{
csrHT40StopOBSSScan( pMac, sessionId );
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Invalid session sessionId %d", __func__,sessionId);
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_SignalPowerEvent
\brief Signals to PMC that a power event has occurred. Used for putting
the chip into deep sleep mode.
\param hHal - The handle returned by macOpen.
\param event - the event that has occurred
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_SignalPowerEvent (tHalHandle hHal, tPmcPowerEvent event)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = pmcSignalPowerEvent(hHal, event);
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);
}
/* ---------------------------------------------------------------------------
\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 psMode - the power saving mode
\return eHalStatus
---------------------------------------------------------------------------*/
tANI_BOOLEAN sme_IsPowerSaveEnabled (tHalHandle hHal, 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 ) )
{
result = pmcIsPowerSaveEnabled(hHal, 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 entery 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.
\return eHalStatus
eHAL_STATUS_FAILURE Device cannot exit WoWLAN mode.
eHAL_STATUS_SUCCESS Request accepted to exit WoWLAN mode.
---------------------------------------------------------------------------*/
eHalStatus sme_ExitWowl (tHalHandle hHal, tWowlExitSource wowlExitSrc)
{
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, wowlExitSrc);
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;
}
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))
{
#ifdef SAP_AUTH_OFFLOAD
if (pMac->sap_auth_offload_sec_type)
{
smsLog(pMac, LOGE,
FL("No set key is required in sap auth offload enable"));
sme_ReleaseGlobalLock(&pMac->sme);
return eHAL_STATUS_SUCCESS;
}
#endif
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 );
}
if (pMac->roam.configParam.roamDelayStatsEnabled)
{
//Store sent PTK key time
if(pSetKey->keyDirection == eSIR_TX_RX)
{
vos_record_roam_event(e_HDD_SET_PTK_REQ, NULL, 0);
}
else if(pSetKey->keyDirection == eSIR_RX_ONLY)
{
vos_record_roam_event(e_HDD_SET_GTK_REQ, NULL, 0);
}
else
{
return (status);
}
}
return (status);
}
/* ---------------------------------------------------------------------------
\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 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_GetRssi(tHalHandle hHal,
tCsrRssiCallback callback,
tANI_U8 staId, tCsrBssid bssId,
void *pContext, void* pVosContext)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = csrGetRssi( pMac, callback,
staId, bssId, 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 WLAN_FEATURE_VOWIFI_11R || defined FEATURE_WLAN_ESE || defined(FEATURE_WLAN_LFR)
/* ---------------------------------------------------------------------------
\fn sme_GetRoamRssi
\brief a wrapper function that client calls to register a callback to get Roam RSSI
\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_GetRoamRssi(tHalHandle hHal,
tCsrRssiCallback callback,
tANI_U8 staId, tCsrBssid bssId,
void *pContext, void* pVosContext)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = csrGetRoamRssi( pMac, callback,
staId, bssId, pContext, pVosContext);
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
#endif
#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
\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)
{
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);
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
eHalStatus sme_GetFwStats(tHalHandle hHal, tANI_U32 stats,
void *pContext, tSirFWStatsCallback callback)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
vos_msg_t msg;
tSirFWStatsGetReq *pGetFWStatsReq;
smsLog(pMac, LOG1, FL(" ENTER stats = %d "),stats);
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ))
{
pGetFWStatsReq = (tSirFWStatsGetReq *)vos_mem_malloc(sizeof(tSirFWStatsGetReq));
if ( NULL == pGetFWStatsReq)
{
smsLog(pMac, LOGE, FL("Not able to allocate memory for "
"WDA_FW_STATS_GET_REQ"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
pGetFWStatsReq->stats = stats;
pGetFWStatsReq->callback = (tSirFWStatsCallback)callback;
pGetFWStatsReq->data = pContext;
msg.type = WDA_FW_STATS_GET_REQ;
msg.reserved = 0;
msg.bodyptr = pGetFWStatsReq;
if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, &msg))
{
smsLog(pMac, LOGE,
FL("Not able to post WDA_FW_STATS_GET_REQ message to HAL"));
vos_mem_free(pGetFWStatsReq);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_SUCCESS;
}
return eHAL_STATUS_FAILURE;
}
/* ---------------------------------------------------------------------------
\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 howm 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 upperlayer 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 upperlayer 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_InitChannels
\brief Used to initialize CSR channel lists while driver loading
\param hHal - global pMac structure
\return eHalStatus SUCCESS.
FAILURE or RESOURCES The API finished and failed.
-------------------------------------------------------------------------------*/
eHalStatus sme_InitChannels(tHalHandle hHal)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (NULL == pMac)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
"%s: pMac is null", __func__);
return status;
}
status = csrInitChannels(pMac);
return status;
}
#ifdef CONFIG_ENABLE_LINUX_REG
/*-------------------------------------------------------------------------
\fn sme_InitChannelsForCC
\brief Used to issue regulatory hint to user
\param hHal - global pMac structure
\return eHalStatus SUCCESS.
FAILURE or RESOURCES The API finished and failed.
--------------------------------------------------------------------------*/
eHalStatus sme_InitChannelsForCC(tHalHandle hHal, driver_load_type init)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (NULL == pMac)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
"%s: pMac is null", __func__);
return status;
}
status = csrInitChannelsForCC(pMac, init);
return status;
}
#endif
/* ---------------------------------------------------------------------------
\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 device.
\return eHalStatus SUCCESS.
FAILURE or RESOURCES The API finished and failed.
--------------------------------------------------------------------------*/
eHalStatus sme_DHCPStartInd( tHalHandle hHal,
tANI_U8 device_mode,
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->macAddr, 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 device.
\return eHalStatus SUCCESS.
FAILURE or RESOURCES The API finished and failed.
--------------------------------------------------------------------------*/
eHalStatus sme_DHCPStopInd( tHalHandle hHal,
tANI_U8 device_mode,
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 = true;
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->macAddr, 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);
}
#ifdef WLAN_FEATURE_RMC
/*---------------------------------------------------------------------------
\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);
}
#endif /* WLAN_FEATURE_RMC */
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
void sme_PERRoamScanStartStop(void *hHal, tANI_U8 start)
{
eHalStatus status;
VOS_STATUS vosStatus;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tPERRoamScanStart *pMsg;
status = sme_AcquireGlobalLock(&pMac->sme);
if ( eHAL_STATUS_SUCCESS == status)
{
pMsg = (tPERRoamScanStart *)
vos_mem_malloc(sizeof(tPERRoamScanStart));
if (NULL == pMsg)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Failed to allocate memory", __func__);
sme_ReleaseGlobalLock( &pMac->sme );
return;
}
pMsg->msgType = WDA_PER_ROAM_SCAN_TRIGGER_REQ;
pMsg->msgLen = (tANI_U16)sizeof(*pMsg);
pMsg->start = start;
vosMessage.type = WDA_PER_ROAM_SCAN_TRIGGER_REQ;
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);
}
}
/* sme_set_per_roam_rxconfig : set PER config for Rx monitoring
* @hHal: hal pointer
* @staId: station id
* @minRate : rate at which to start monitoring
* @maxRate : Rate at which to stop monitoring
* @minPercentage: minimum % of packets required in minRate to trigger a scan
* @minPktRequired: minimum number of packets required to trigger a scan
* @waitPeriodForNextPERScan: time to wait before start monitoring again once
* roam scan is triggered
* */
VOS_STATUS sme_set_per_roam_rxconfig (tHalHandle hHal, v_U8_t staId,
v_U16_t minRate, v_U16_t maxRate,
v_U8_t minPercentage, v_U16_t minPktRequired,
v_U64_t waitPeriodForNextPERScan)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);
WLANTL_StartRxRateMonitor(pVosContext, staId, minRate, maxRate,
minPercentage, minPktRequired,
(void *) hHal, waitPeriodForNextPERScan,
sme_PERRoamScanStartStop);
pMac->PERroamCandidatesCnt = 0;
return eHAL_STATUS_SUCCESS;
}
/* sme_unset_per_roam_rxconfig : unset PER config for Rx monitoring
* */
VOS_STATUS sme_unset_per_roam_rxconfig (tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
v_VOID_t * pVosContext = vos_get_global_context(VOS_MODULE_ID_SME, NULL);
vos_mem_set(pMac->previousRoamApInfo,
sizeof(tSirRoamAPInfo) * SIR_PER_ROAM_MAX_CANDIDATE_CNT, 0);
WLANTL_StopRxRateMonitor(pVosContext);
return eHAL_STATUS_SUCCESS;
}
#endif
/* ---------------------------------------------------------------------------
\fn sme_BtcSignalBtEvent
\brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the
BT event type and the current operating mode of Libra (full power,
BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy
would be employed.
\param hHal - The handle returned by macOpen.
\param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent
Caller owns the memory and is responsible for freeing it.
\return VOS_STATUS
VOS_STATUS_E_FAILURE BT Event not passed to HAL. This can happen
if BTC execution mode is set to BTC_WLAN_ONLY
or BTC_PTA_ONLY.
VOS_STATUS_SUCCESS BT Event passed to HAL
---------------------------------------------------------------------------*/
VOS_STATUS sme_BtcSignalBtEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_BTC_SIGNALEVENT, NO_SESSION, 0));
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
{
status = btcSignalBTEvent (hHal, pBtEvent);
sme_ReleaseGlobalLock( &pMac->sme );
}
#endif
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_BtcSetConfig
\brief API to change the current Bluetooth Coexistence (BTC) configuration
This function should be invoked only after CFG download has completed.
Calling it after sme_HDDReadyInd is recommended.
\param hHal - The handle returned by macOpen.
\param pSmeBtcConfig - Pointer to a caller allocated object of type tSmeBtcConfig.
Caller owns the memory and is responsible for freeing it.
\return VOS_STATUS
VOS_STATUS_E_FAILURE Config not passed to HAL.
VOS_STATUS_SUCCESS Config passed to HAL
---------------------------------------------------------------------------*/
VOS_STATUS sme_BtcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_BTC_SETCONFIG, NO_SESSION, 0));
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
{
status = btcSetConfig (hHal, pSmeBtcConfig);
sme_ReleaseGlobalLock( &pMac->sme );
}
#endif
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_BtcGetConfig
\brief API to retrieve the current Bluetooth Coexistence (BTC) configuration
\param hHal - The handle returned by macOpen.
\param pSmeBtcConfig - Pointer to a caller allocated object of type
tSmeBtcConfig. 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_BtcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
#ifndef WLAN_MDM_CODE_REDUCTION_OPT
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_BTC_GETCONFIG, NO_SESSION, 0));
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ) )
{
status = btcGetConfig (hHal, pSmeBtcConfig);
sme_ReleaseGlobalLock( &pMac->sme );
}
#endif
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
//The following are debug APIs to support direct read/write register/memory
//They are placed in SME because HW cannot be access when in LOW_POWER state
//AND not connected. The knowledge and synchronization is done in SME
//sme_DbgReadRegister
//Caller needs to validate the input values
VOS_STATUS sme_DbgReadRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t *pRegValue)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tPmcPowerState PowerState;
tANI_U32 sessionId = 0;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_DBG_READREG, NO_SESSION, 0));
/* 1) To make Quarky work in FTM mode **************************************/
if(eDRIVER_TYPE_MFG == pMac->gDriverType)
{
if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgReadRegister(regAddr, pRegValue))
{
return VOS_STATUS_SUCCESS;
}
return VOS_STATUS_E_FAILURE;
}
/* 2) NON FTM mode driver *************************************************/
/* Acquire SME global lock */
if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme))
{
return VOS_STATUS_E_FAILURE;
}
if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL)))
{
/* Are we not in IMPS mode? Or are we in connected? Then we're safe*/
if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState))
{
if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgReadRegister(regAddr, pRegValue))
{
status = VOS_STATUS_SUCCESS;
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
/* This is a hack for Qualky/pttWniSocket
Current implementation doesn't allow pttWniSocket to inform Qualky an error */
if ( VOS_STATUS_SUCCESS != status )
{
*pRegValue = 0xDEADBEEF;
status = VOS_STATUS_SUCCESS;
}
/* Release SME global lock */
sme_ReleaseGlobalLock(&pMac->sme);
return (status);
}
//sme_DbgWriteRegister
//Caller needs to validate the input values
VOS_STATUS sme_DbgWriteRegister(tHalHandle hHal, v_U32_t regAddr, v_U32_t regValue)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tPmcPowerState PowerState;
tANI_U32 sessionId = 0;
/* 1) To make Quarky work in FTM mode **************************************/
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_DBG_WRITEREG, NO_SESSION, 0));
if(eDRIVER_TYPE_MFG == pMac->gDriverType)
{
if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteRegister(regAddr, regValue))
{
return VOS_STATUS_SUCCESS;
}
return VOS_STATUS_E_FAILURE;
}
/* 2) NON FTM mode driver *************************************************/
/* Acquire SME global lock */
if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme))
{
return VOS_STATUS_E_FAILURE;
}
if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL)))
{
/* Are we not in IMPS mode? Or are we in connected? Then we're safe*/
if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState))
{
if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteRegister(regAddr, regValue))
{
status = VOS_STATUS_SUCCESS;
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
/* Release SME global lock */
sme_ReleaseGlobalLock(&pMac->sme);
return (status);
}
//sme_DbgReadMemory
//Caller needs to validate the input values
//pBuf caller allocated buffer has the length of nLen
VOS_STATUS sme_DbgReadMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tPmcPowerState PowerState;
tANI_U32 sessionId = 0;
tANI_U32 cmd = READ_MEMORY_DUMP_CMD;
tANI_U32 arg1 = memAddr;
tANI_U32 arg2 = nLen/4;
tANI_U32 arg3 = 4;
tANI_U32 arg4 = 0;
/* 1) To make Quarky work in FTM mode **************************************/
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_DBG_READMEM, NO_SESSION, 0));
if(eDRIVER_TYPE_MFG == pMac->gDriverType)
{
if (VOS_STATUS_SUCCESS == WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, (tANI_U8*)pBuf, 0))
{
return VOS_STATUS_SUCCESS;
}
return VOS_STATUS_E_FAILURE;
}
/* 2) NON FTM mode driver *************************************************/
/* Acquire SME global lock */
if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme))
{
return VOS_STATUS_E_FAILURE;
}
if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL)))
{
/* Are we not in IMPS mode? Or are we in connected? Then we're safe*/
if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState))
{
if (VOS_STATUS_SUCCESS == WDA_HALDumpCmdReq(pMac, cmd, arg1, arg2, arg3, arg4, (tANI_U8 *)pBuf, 0))
{
status = VOS_STATUS_SUCCESS;
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
/* This is a hack for Qualky/pttWniSocket
Current implementation doesn't allow pttWniSocket to inform Qualky an error */
if (VOS_STATUS_SUCCESS != status)
{
vos_mem_set(pBuf, nLen, 0xCD);
status = VOS_STATUS_SUCCESS;
smsLog(pMac, LOGE, FL(" filled with 0xCD because it cannot access the hardware"));
}
/* Release SME lock */
sme_ReleaseGlobalLock(&pMac->sme);
return (status);
}
//sme_DbgWriteMemory
//Caller needs to validate the input values
VOS_STATUS sme_DbgWriteMemory(tHalHandle hHal, v_U32_t memAddr, v_U8_t *pBuf, v_U32_t nLen)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tPmcPowerState PowerState;
tANI_U32 sessionId = 0;
/* 1) To make Quarky work in FTM mode **************************************/
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_DBG_WRITEMEM, NO_SESSION, 0));
if(eDRIVER_TYPE_MFG == pMac->gDriverType)
{
{
return VOS_STATUS_SUCCESS;
}
return VOS_STATUS_E_FAILURE;
}
/* 2) NON FTM mode driver *************************************************/
/* Acquire SME global lock */
if (eHAL_STATUS_SUCCESS != sme_AcquireGlobalLock(&pMac->sme))
{
return VOS_STATUS_E_FAILURE;
}
if(HAL_STATUS_SUCCESS(pmcQueryPowerState(pMac, &PowerState, NULL, NULL)))
{
/* Are we not in IMPS mode? Or are we in connected? Then we're safe*/
if(!csrIsConnStateDisconnected(pMac, sessionId) || (ePMC_LOW_POWER != PowerState))
{
if (eWLAN_PAL_STATUS_SUCCESS == wpalDbgWriteMemory(memAddr, (void *)pBuf, nLen))
{
status = VOS_STATUS_SUCCESS;
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
else
{
status = VOS_STATUS_E_FAILURE;
}
}
/* Release Global lock */
sme_ReleaseGlobalLock(&pMac->sme);
return (status);
}
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_RoamSetBKIDCache
\brief The SME API exposed to HDD to allow HDD to provde SME the BKID
candidate list.
\param hHal - Handle to the HAL. The HAL handle is returned by the HAL after
it is opened (by calling halOpen).
\param pBKIDCache - caller allocated buffer point to an array of tBkidCacheInfo
\param numItems - a variable that has the number of tBkidCacheInfo allocated
when retruning, this is the number of items put into pBKIDCache
\return eHalStatus - when fail, it usually means the buffer allocated is not
big enough and pNumItems has the number of tBkidCacheInfo.
---------------------------------------------------------------------------*/
eHalStatus sme_RoamSetBKIDCache( tHalHandle hHal, tANI_U32 sessionId, tBkidCacheInfo *pBKIDCache,
tANI_U32 numItems )
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = csrRoamSetBKIDCache( pMac, sessionId, pBKIDCache, numItems );
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_RoamGetBKIDCache
\brief The SME API exposed to HDD to allow HDD to request SME to return its
BKID cache.
\param hHal - Handle to the HAL. The HAL handle is returned by the HAL after
it is opened (by calling halOpen).
\param pNum - caller allocated memory that has the space of the number of
tBkidCacheInfo as input. Upon returned, *pNum has the needed number of entries
in SME cache.
\param pBkidCache - Caller allocated memory that contains BKID cache, if any,
upon return
\return eHalStatus - when fail, it usually means the buffer allocated is not
big enough.
---------------------------------------------------------------------------*/
eHalStatus sme_RoamGetBKIDCache(tHalHandle hHal, tANI_U32 *pNum,
tBkidCacheInfo *pBkidCache)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
smsLog(pMac, LOGE, FL(" !!!!!!!!!!!!!!!!!!SessionId is hardcoded"));
status = csrRoamGetBKIDCache( pMac, 0, pNum, pBkidCache );
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_RoamGetNumBKIDCache
\brief The SME API exposed to HDD to allow HDD to request SME to return the
number of BKID cache entries.
\param hHal - Handle to the HAL. The HAL handle is returned by the HAL after
it is opened (by calling halOpen).
\return tANI_U32 - the number of BKID cache entries.
---------------------------------------------------------------------------*/
tANI_U32 sme_RoamGetNumBKIDCache(tHalHandle hHal, tANI_U32 sessionId)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tANI_U32 numBkidCache = 0;
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
numBkidCache = csrRoamGetNumBKIDCache( pMac, sessionId );
sme_ReleaseGlobalLock( &pMac->sme );
}
return (numBkidCache);
}
/* ---------------------------------------------------------------------------
\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 retruning, 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_getOemDataRsp
\brief a wrapper function to obtain the OEM DATA RSP
\param pOemDataRsp - A pointer to the response object
\param pContext - a pointer passed in for the callback
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_getOemDataRsp(tHalHandle hHal,
tOemDataRsp **pOemDataRsp)
{
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))
{
break;
}
if(pMac->oemData.pOemDataRsp != NULL)
{
*pOemDataRsp = pMac->oemData.pOemDataRsp;
}
else
{
status = eHAL_STATUS_FAILURE;
}
//release the lock for the sme object
sme_ReleaseGlobalLock( &pMac->sme );
} while(0);
return status;
}
/* ---------------------------------------------------------------------------
\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
\param callback - a callback function that is called upon finish
\param pContext - a pointer passed in for the callback
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_OemDataReq(tHalHandle hHal,
tANI_U8 sessionId,
tOemDataReqConfig *pOemDataReqConfig,
tANI_U32 *pOemDataReqID,
oemData_OemDataReqCompleteCallback callback,
void *pContext)
{
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, callback, pContext);
//release the lock for the sme object
sme_ReleaseGlobalLock( &pMac->sme );
}
} while(0);
smsLog(pMac, LOGW, "exiting function %s", __func__);
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_OemDataReqNew
\brief a wrapper function for OEM DATA REQ NEW
\param pOemDataReqNewConfig - Data to be passed to FW
---------------------------------------------------------------------------*/
void sme_OemDataReqNew(tHalHandle hHal,
tOemDataReqNewConfig *pOemDataReqNewConfig)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tOemDataReqNewConfig *pLocalOemDataReqNewConfig;
vos_msg_t vosMessage = {0};
pLocalOemDataReqNewConfig =
vos_mem_malloc(sizeof(*pLocalOemDataReqNewConfig));
if (!pLocalOemDataReqNewConfig)
{
smsLog(pMac, LOGE,
"Failed to allocate memory for WDA_START_OEM_DATA_REQ_IND_NEW");
return;
}
vos_mem_zero(pLocalOemDataReqNewConfig, sizeof(tOemDataReqNewConfig));
vos_mem_copy(pLocalOemDataReqNewConfig, pOemDataReqNewConfig,
sizeof(tOemDataReqNewConfig));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pLocalOemDataReqNewConfig;
vosMessage.type = WDA_START_OEM_DATA_REQ_IND_NEW;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type));
if(VOS_STATUS_SUCCESS !=
vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:"
"Failed to post WDA_START_OEM_DATA_REQ_IND_NEW msg to WDA",
__func__);
vos_mem_free(pLocalOemDataReqNewConfig);
}
sme_ReleaseGlobalLock(&pMac->sme);
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
"sme_AcquireGlobalLock error", __func__);
vos_mem_free(pLocalOemDataReqNewConfig);
}
}
#endif /*FEATURE_OEM_DATA_SUPPORT*/
/*--------------------------------------------------------------------------
\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)
{
eHalStatus status;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
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);
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,
tANI_BOOLEAN fSync,
tANI_U8 bPurgeSmeCmdList,
csrRoamSessionCloseCallback callback,
void *pContext)
{
eHalStatus status;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
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, fSync, bPurgeSmeCmdList,
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 sme_sendBTAmpEvent
\brief to receive the coex priorty request from BT-AMP PAL
and send the BT_AMP link state to HAL
\param btAmpEvent - btAmpEvent
\return eHalStatus: SUCCESS : BTAmp event successfully sent to HAL
FAILURE: API failed
-------------------------------------------------------------------------------*/
eHalStatus sme_sendBTAmpEvent(tHalHandle hHal, tSmeBtAmpEvent btAmpEvent)
{
vos_msg_t msg;
tpSmeBtAmpEvent ptrSmeBtAmpEvent = NULL;
eHalStatus status = eHAL_STATUS_FAILURE;
ptrSmeBtAmpEvent = vos_mem_malloc(sizeof(tSmeBtAmpEvent));
if (NULL == ptrSmeBtAmpEvent)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
"Not able to allocate memory for BTAmp event", __func__);
return status;
}
vos_mem_copy(ptrSmeBtAmpEvent, (void*)&btAmpEvent, sizeof(tSmeBtAmpEvent));
msg.type = WDA_SIGNAL_BTAMP_EVENT;
msg.reserved = 0;
msg.bodyptr = ptrSmeBtAmpEvent;
//status = halFW_SendBTAmpEventMesg(pMac, event);
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 SIR_HAL_SIGNAL_BTAMP_EVENT message to HAL", __func__);
vos_mem_free(ptrSmeBtAmpEvent);
return status;
}
return eHAL_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------
\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 channel - channel number on which fastroam is requested
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus smeIssueFastRoamNeighborAPEvent (tHalHandle hHal,
tANI_U8 *bssid,
tSmeFastRoamTrigger fastRoamTrig,
tANI_U8 channel)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
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__);
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));
/*
* As FastReassoc is based on assumption that roamable AP should be
* present into the occupied channel list.We shd add i/p channel
* in occupied channel list if roamable-ap(BSSID in fastreassoc cmd)
* aged out prior to connection and there is no scan from aged out
* to till connection indication.
*/
csrAddChannelToOccupiedChannelList(pMac, channel);
vosStatus = csrNeighborRoamTransitToCFGChanScan(pMac);
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));
vosStatus = csrNeighborRoamReassocIndCallback(pMac->roam.gVosContext,
0,
pMac,
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 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);
}
eHalStatus sme_SetRSSIFilter(tHalHandle hHal, v_U8_t rssiThreshold)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme ) ) )
{
pmcSetRssiFilter(hHal, rssiThreshold);
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 tSirAbortScanStatus Abort scan status
---------------------------------------------------------------------------*/
tSirAbortScanStatus sme_AbortMacScan(tHalHandle hHal, tANI_U8 sessionId,
eCsrAbortReason reason)
{
tSirAbortScanStatus scanAbortStatus = eSIR_ABORT_SCAN_FAILURE;
eHalStatus status;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
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 ) )
{
scanAbortStatus = csrScanAbortMacScan(pMac, sessionId, reason);
sme_ReleaseGlobalLock( &pMac->sme );
}
return ( scanAbortStatus );
}
/* ----------------------------------------------------------------------------
\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_mgmt_frame_ind_callback() - Register a callback for
* management frame indication to PE.
* @hHal: 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 hHal,
sir_mgmt_frame_ind_callback callback)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
struct sir_sme_mgmt_frame_cb_req *msg;
eHalStatus status = eHAL_STATUS_SUCCESS;
smsLog(pMac, LOG1, FL(": ENTER"));
if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
{
msg = vos_mem_malloc(sizeof(*msg));
if (NULL == msg)
{
smsLog(pMac, LOGE,
FL("Not able to allocate memory for eWNI_SME_REGISTER_MGMT_FRAME_CB"));
sme_ReleaseGlobalLock( &pMac->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(pMac->hHdd, msg);
sme_ReleaseGlobalLock( &pMac->sme );
return status;
}
return eHAL_STATUS_FAILURE;
}
/* ---------------------------------------------------------------------------
\fn sme_RegisterMgtFrame
\brief To register managment 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(!pSession)
{
smsLog(pMac, LOGE, FL(" session %d not found "), 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;
}
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 managment 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);
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(!pSession)
{
smsLog(pMac, LOGE, FL(" session %d not found "), 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;
}
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
#ifdef WLAN_FEATURE_P2P_INTERNAL
, eP2PRemainOnChnReasonUnknown
#endif
);
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 falg: to set the Probe request forarding 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);
//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;
sirDumpBuf( pMac, SIR_LIM_MODULE_ID, LOG2,
pMac->p2pContext.probeRspIe,
pMac->p2pContext.probeRspIeLength );
vos_mem_copy((tANI_U8 *)pMac->p2pContext.probeRspIe, p2pIe,
p2pIeLength);
}
//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_GetFramesLog
\brief a wrapper function that client calls to register a callback to get
mgmt frames logged
\param flag - flag tells to clear OR send the frame log buffer
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_GetFramesLog(tHalHandle hHal, tANI_U8 flag)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
tSmeCmd *pGetFrameLogCmd;
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
pGetFrameLogCmd = csrGetCommandBuffer(pMac);
if (pGetFrameLogCmd)
{
pGetFrameLogCmd->command = eSmeCommandGetFrameLogRequest;
pGetFrameLogCmd->u.getFramelogCmd.getFrameLogCmdFlag= flag;
status = csrQueueSmeCommand(pMac, pGetFrameLogCmd, eANI_BOOLEAN_TRUE);
if ( !HAL_STATUS_SUCCESS( status ) )
{
smsLog( pMac, LOGE, FL("fail to send msg status = %d\n"), status );
csrReleaseCommandScan(pMac, pGetFrameLogCmd);
}
}
else
{
//log error
smsLog(pMac, LOGE, FL("can not obtain a common buffer\n"));
status = eHAL_STATUS_RESOURCES;
}
sme_ReleaseGlobalLock( &pMac->sme);
}
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_InitMgmtFrameLogging
\brief
SME will pass this request to lower mac to initialize Frame Logging.
\param
hHal - The handle returned by macOpen.
wlanFWLoggingInitParam - Params to initialize frame logging
\return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_InitMgmtFrameLogging( tHalHandle hHal,
tSirFWLoggingInitParam *wlanFWLoggingInitParam)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tpSirFWLoggingInitParam msg;
msg = vos_mem_malloc(sizeof(tSirFWLoggingInitParam));
if (NULL == msg)
{
smsLog(pMac, LOGE, FL("Failed to alloc mem of size %zu for msg"),
sizeof(*msg));
return eHAL_STATUS_FAILED_ALLOC;
}
*msg = *wlanFWLoggingInitParam;
if ( eHAL_STATUS_SUCCESS == ( status =
sme_AcquireGlobalLock( &pMac->sme ) ) )
{
/* serialize the req through MC thread */
vosMessage.bodyptr = msg;
vosMessage.type = WDA_MGMT_LOGGING_INIT_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_mem_free(msg);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
else
{
smsLog(pMac, LOGE, FL("sme_AcquireGlobalLock error"));
vos_mem_free(msg);
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_StartRssiMonitoring
\brief
SME will pass this request to lower mac to start monitoring rssi range on
a bssid.
\param
hHal - The handle returned by macOpen.
tSirRssiMonitorReq req- depict the monitor req params.
\return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_StartRssiMonitoring( tHalHandle hHal,
tSirRssiMonitorReq *req)
{
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 = req;
vosMessage.type = WDA_START_RSSI_MONITOR_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_StopRssiMonitoring
\brief
SME will pass this request to lower mac to stop monitoring rssi range on
a bssid.
\param
hHal - The handle returned by macOpen.
tSirRssiMonitorReq req- depict the monitor req params.
\return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_StopRssiMonitoring(tHalHandle hHal,
tSirRssiMonitorReq *req)
{
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 = req;
vosMessage.type = WDA_STOP_RSSI_MONITOR_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_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_update_hal_int_param
\brief
SME will pass this request to lower mac to indicate that the host needs to
update the cfg item
\param
hHal - The handle returned by macOpen.
cfg_id- cfg param id
\return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_update_cfg_int_param(tHalHandle hHal,
tANI_U32 cfg_id)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tpSirUpdateCfgIntParam updateCfgIntParam =
vos_mem_malloc(sizeof(tSirUpdateCfgIntParam));
if (updateCfgIntParam == NULL)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: vos_mem_alloc for updateCfgIntParam", __func__);
return eHAL_STATUS_FAILURE;
}
updateCfgIntParam->cfgId = cfg_id;
/*
* This API expect user must have updated cfg item using cfg API's.
* Hence it just need the cfg param id not the cfg value.
*/
status = sme_AcquireGlobalLock(&pMac->sme);
if (eHAL_STATUS_SUCCESS == status)
{
/* serialize the req through MC thread */
vosMessage.bodyptr = updateCfgIntParam;
vosMessage.type = WDA_UPDATE_CFG_INT_PARAM;
vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage);
if (!VOS_IS_STATUS_SUCCESS(vosStatus))
{
status = eHAL_STATUS_FAILURE;
vos_mem_free(updateCfgIntParam);
}
sme_ReleaseGlobalLock(&pMac->sme);
}
else
{
status = eHAL_STATUS_FAILURE;
vos_mem_free(updateCfgIntParam);
}
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
\return eHalStatus
--------------------------------------------------------------------------- */
eHalStatus sme_ConfigureSuspendInd( tHalHandle hHal,
tpSirWlanSuspendParam wlanSuspendParam)
{
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));
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) )
{
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);
}
/* ---------------------------------------------------------------------------
\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);
}
tANI_U32 sme_get_sessionid_from_activeList(tpAniSirGlobal mac)
{
tListElem *entry = NULL;
tSmeCmd *command = NULL;
tANI_U32 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);
}
/* ---------------------------------------------------------------------------
\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 poerating 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_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__);
status = eHAL_STATUS_FAILURE;
}
else
{
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, LOG1, FL(" SSID=%s frame length %d"),
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 %u needed %zu"),
pPrefNetworkFoundInd->mesgLen, sizeof(tSirPrefNetworkFoundInd));
}
/* Call Preferred Netowrk 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);
}
eHalStatus sme_SetCfgScanControlList(tHalHandle hHal, tANI_U8 *countryCode, tCsrChannel *pChannelList)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
csrSetCfgScanControlList(pMac, countryCode, pChannelList);
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 courtry 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 (pMac->scan.fcc_constraint)
{
pMac->scan.fcc_constraint = false;
if (VOS_TRUE== vos_mem_compare(pMac->scan.countryCodeCurrent,
pMsg->countryCode, 2))
{
csrInitGetChannels(pMac);
csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
csrScanFilterResults(pMac);
return status ;
}
}
/* 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 Domian 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 defualt 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
status = csrSetRegulatoryDomain(pMac, domainIdIoctl, NULL);
if (status != eHAL_STATUS_SUCCESS)
{
smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status);
}
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 ) );
}
}
#ifndef CONFIG_ENABLE_LINUX_REG
/* set to default domain ID */
pMac->scan.domainIdDefault = pMac->scan.domainIdCurrent;
/* 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);
/* Country code Changed, Purge Only scan result
* which does not have channel number belong to 11d
* channel list
*/
csrScanFilterResults(pMac);
#endif
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;
}
smsLog( pMac, LOG1, FL("pMsg->countryCode : %c%c,"
"pMac->scan.countryCode11d : %c%c\n"),
pMsg->countryCode[0], pMsg->countryCode[1],
pMac->scan.countryCode11d[0], pMac->scan.countryCode11d[1]);
/* Set the country code given by userspace 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)&&
(!pMac->roam.configParam.fEnforceCountryCode) )
{
smsLog( pMac, LOGW, FL(" incorrect country being set, nullify this request"));
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.fEnforceCountryCode))
{
pMac->roam.configParam.Is11dSupportEnabled = eANI_BOOLEAN_FALSE;
smsLog( pMac, LOG1, FL(" 11d is being disabled"));
}
pMac->roam.configParam.fEnforceCountryCode = eANI_BOOLEAN_FALSE;
vos_mem_copy(pMac->scan.countryCodeCurrent, pMsg->countryCode,
WNI_CFG_COUNTRY_CODE_LEN);
vos_mem_copy(pMac->scan.countryCode11d, pMsg->countryCode,
WNI_CFG_COUNTRY_CODE_LEN);
status = csrSetRegulatoryDomain(pMac, reg_domain_id, NULL);
if (status != eHAL_STATUS_SUCCESS)
{
smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status);
}
status = WDA_SetRegDomain(pMac, reg_domain_id, eSIR_TRUE);
if (VOS_FALSE == is11dCountry )
{
/* overwrite the defualt 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 = csrSetRegulatoryDomain(pMac, REGDOMAIN_WORLD, NULL);
if (status != eHAL_STATUS_SUCCESS)
{
smsLog( pMac, LOGE, FL("fail to set regId.status : %d"), status);
}
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 connetced, it sends the disconnect to the AP/P2P GO
\param pMac - The handle returned by macOpen
\return eHalStatus
-------------------------------------------------------------------------------*/
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))
{
pSession = CSR_GET_SESSION( pMac, sessionId );
}
if(pSession == NULL )
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN, "%s: Unable to find "
"the right session", __func__);
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 ))
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: Ignoring the "
"indication as we are not connected", __func__);
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_HandlePreChannelSwitchInd
\brief Processes the indcation from PE for pre-channel switch.
\param hHal
\- The handle returned by macOpen. return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_HandlePreChannelSwitchInd(tHalHandle hHal)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = pmcRequestFullPower(hHal, sme_PreChannelSwitchIndFullPowerCB,
pMac, eSME_FULL_PWR_NEEDED_BY_CHANNEL_SWITCH);
sme_ReleaseGlobalLock( &pMac->sme );
}
return (status);
}
/* ---------------------------------------------------------------------------
\fn sme_HandlePostChannelSwitchInd
\brief Processes the indcation 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
\eBand band value to be configured
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_SetFreqBand(tHalHandle hHal, 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, 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);
smsLog(pMac, LOG1, "Wake Reason Indication in %s(), reason=%d", __func__, pWakeReasonInd->ulReason);
}
return(status);
}
#endif // WLAN_WAKEUP_EVENTS
/**
* 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 pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
tSmeCmd *set_max_tx_pwr;
if (pMac->max_power_cmd_pending)
{
smsLog(pMac, 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(pMac, 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( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
set_max_tx_pwr = csrGetCommandBuffer(pMac);
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;
pMac->max_power_cmd_pending = true;
status = csrQueueSmeCommand(pMac, set_max_tx_pwr, eANI_BOOLEAN_TRUE);
if ( !HAL_STATUS_SUCCESS( status ) )
{
smsLog( pMac, LOGE, FL("fail to send msg status = %d"), status );
csrReleaseCommandScan(pMac, set_max_tx_pwr);
pMac->max_power_cmd_pending = false;
}
}
else
{
smsLog(pMac, LOGE, FL("can not obtain a common buffer"));
status = eHAL_STATUS_RESOURCES;
}
sme_ReleaseGlobalLock( &pMac->sme);
}
return (status);
}
/**
* 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)
{
vos_msg_t msg;
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);
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, msg.type));
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;
}
/* ---------------------------------------------------------------------------
\fn sme_SetTxPower
\brief Set Transmit Power dynamically. Note: this setting will
not persist over reboots.
\param hHal
\param sessionId Target Session ID
\param mW power to set in mW
\- return eHalStatus
-------------------------------------------------------------------------------*/
eHalStatus sme_SetTxPower(tHalHandle hHal, v_U8_t sessionId, v_U8_t mW)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_SET_TXPOW, NO_SESSION, 0));
smsLog(pMac, LOG1, FL("set tx power %dmW"), mW);
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status))
{
status = csrSetTxPower(pMac, sessionId, mW);
sme_ReleaseGlobalLock(&pMac->sme);
}
return status;
}
/* ---------------------------------------------------------------------------
\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);
}
VOS_STATUS
sme_featureCapsExchange(struct sir_feature_caps_params *params)
{
VOS_STATUS status;
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));
status = WDA_featureCapsExchange(vosContext, params);
return status;
}
/*---------------------------------------------------------------------------
\brief sme_disableFeatureCapablity() - SME interface to disable Active mode offload capablity
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 querry 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 nProbes number of probe requests to be sent out
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_UpdateRoamScanNProbes(tHalHandle hHal, const v_U8_t nProbes)
{
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: 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, 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 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, const v_U16_t nRoamScanHomeAwayTime,
const eAniBoolean bSendOffloadCmd)
{
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: 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, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
REASON_HOME_AWAY_TIME_CHANGED);
}
#endif
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.
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_UpdateImmediateRoamRssiDiff(tHalHandle hHal, v_U8_t nImmediateRoamRssiDiff)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_UPDATE_IMMRSSIDIFF, 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 immediate roam rssi diff to"
"%d - old value is %d - roam state is %s",
nImmediateRoamRssiDiff,
pMac->roam.configParam.nImmediateRoamRssiDiff,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.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 RoamRssiDiff - minimum rssi difference between potential
candidate and current AP.
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_UpdateRoamRssiDiff(tHalHandle hHal, v_U8_t RoamRssiDiff)
{
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 roam rssi diff to %d"
" - old value is %d - roam state is %s",
RoamRssiDiff,
pMac->roam.configParam.RoamRssiDiff,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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
\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)
{
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.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
\return eHAL_STATUS_SUCCESS - SME update config successfully.
Other status means SME failure to update
-------------------------------------------------------------------------*/
eHalStatus sme_SetRoamScanControl(tHalHandle hHal, 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.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);
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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.
\return eHAL_STATUS_SUCCESS - SME update isFastRoamIniFeatureEnabled config successfully.
Other status means SME is failed to update isFastRoamIniFeatureEnabled.
\sa
--------------------------------------------------------------------------*/
eHalStatus sme_UpdateIsFastRoamIniFeatureEnabled(tHalHandle hHal,
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_INFO,
"%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))
{
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_INFO,
"%s: FastRoamEnabled is changed from %d to %d", __func__,
pMac->roam.configParam.isFastRoamIniFeatureEnabled,
isFastRoamIniFeatureEnabled);
pMac->roam.configParam.isFastRoamIniFeatureEnabled = isFastRoamIniFeatureEnabled;
csrNeighborRoamUpdateFastRoamingEnabled(pMac, isFastRoamIniFeatureEnabled);
return eHAL_STATUS_SUCCESS;
}
/*--------------------------------------------------------------------------
\brief sme_ConfigFwrRoaming() - enable/disable LFR support at runtime
When Supplicant issue enabled / disable fwr based roaming on the basis
of the Bssid modification in network block ( e.g. AutoJoin mody N/W block)
This is a synchronous call
\param hHal - The handle returned by macOpen.
\return eHAL_STATUS_SUCCESS - SME (enabled/disabled) offload scan successfully.
Other status means SME is failed to (enabled/disabled) offload scan.
\sa
--------------------------------------------------------------------------*/
eHalStatus sme_ConfigFwrRoaming(tHalHandle hHal,
const v_BOOL_t isFastRoamEnabled)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
if (!pMac->roam.configParam.isFastRoamIniFeatureEnabled)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: FastRoam is disabled through ini", __func__);
return eHAL_STATUS_FAILURE;
}
csrNeighborRoamUpdateFastRoamingEnabled(pMac, isFastRoamEnabled);
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_UpdateEnableFastRoamInConcurrency() - enable/disable LFR if Concurrent session exists
This is a synchronuous 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.
\return eHAL_STATUS_SUCCESS - SME update isEseIniFeatureEnabled config successfully.
Other status means SME is failed to update isEseIniFeatureEnabled.
\sa
--------------------------------------------------------------------------*/
eHalStatus sme_UpdateIsEseFeatureEnabled(tHalHandle hHal,
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, isEseIniFeatureEnabled);
if(TRUE == isEseIniFeatureEnabled)
{
sme_UpdateFastTransitionEnabled(hHal, TRUE);
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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
/*--------------------------------------------------------------------------
\brief sme_setNeighborLookupRssiThreshold() - update 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
--------------------------------------------------------------------------*/
eHalStatus sme_setNeighborLookupRssiThreshold(tHalHandle hHal,
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, 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.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborLookupRssiThreshold =
neighborLookupRssiThreshold;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
/*--------------------------------------------------------------------------
\brief sme_setNeighborReassocRssiThreshold() - update neighbor reassoc 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
--------------------------------------------------------------------------*/
eHalStatus sme_setNeighborReassocRssiThreshold(tHalHandle hHal,
v_U8_t neighborReassocRssiThreshold)
{
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 Reassoc threshold to %d"
"- old value is %d - roam state is %s",
neighborReassocRssiThreshold,
pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborReassocRssiThreshold =
neighborReassocRssiThreshold;
pMac->roam.neighborRoamInfo.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.
\return eHAL_STATUS_SUCCESS - SME update config successful.
Other status means SME is failed to update
\sa
--------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanRefreshPeriod(tHalHandle hHal,
v_U16_t neighborScanResultsRefreshPeriod)
{
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 scan refresh period to %d"
" - old value is %d - roam state is %s",
neighborScanResultsRefreshPeriod,
pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborResultsRefreshPeriod =
neighborScanResultsRefreshPeriod;
pMac->roam.neighborRoamInfo.cfgParams.neighborResultsRefreshPeriod =
neighborScanResultsRefreshPeriod;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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 feaure
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_INFO,
"%s: gRoamScanOffloadEnabled is changed from %d to %d", __func__,
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 synchronuous 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 nEmptyScanRefreshPeriod - scan period following empty scan results.
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_UpdateEmptyScanRefreshPeriod(tHalHandle hHal, v_U16_t nEmptyScanRefreshPeriod)
{
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 scan period to %d -"
"old value is %d - roam state is %s",
nEmptyScanRefreshPeriod,
pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nEmptyScanRefreshPeriod = nEmptyScanRefreshPeriod;
pMac->roam.neighborRoamInfo.cfgParams.emptyScanRefreshPeriod = nEmptyScanRefreshPeriod;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanMinChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMinChanTime)
{
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.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborScanMinChanTime = nNeighborScanMinChanTime;
pMac->roam.neighborRoamInfo.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 nNeighborScanMinChanTime - Channel maximum dwell time
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanMaxChanTime(tHalHandle hHal, const v_U16_t nNeighborScanMaxChanTime)
{
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 max dwell time to %d"
" - old value is %d - roam state is %s",
nNeighborScanMaxChanTime,
pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborScanMaxChanTime = nNeighborScanMaxChanTime;
pMac->roam.neighborRoamInfo.cfgParams.maxChannelScanTime = nNeighborScanMaxChanTime;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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.
\return v_U16_t - channel min time value
-------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanMinChanTime(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->roam.neighborRoamInfo.cfgParams.minChannelScanTime;
}
/* ---------------------------------------------------------------------------
\fn sme_getNeighborScanMaxChanTime
\brief get neighbor scan max channel time
\param hHal - The handle returned by macOpen.
\return v_U16_t - channel max time value
-------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanMaxChanTime(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->roam.neighborRoamInfo.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 nNeighborScanPeriod - neighbor scan period
\- return Success or failure
-------------------------------------------------------------------------*/
eHalStatus sme_setNeighborScanPeriod(tHalHandle hHal, const v_U16_t nNeighborScanPeriod)
{
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 neighbor scan period to %d"
" - old value is %d - roam state is %s",
nNeighborScanPeriod,
pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
pMac->roam.configParam.neighborRoamConfig.nNeighborScanTimerPeriod = nNeighborScanPeriod;
pMac->roam.neighborRoamInfo.cfgParams.neighborScanPeriod = nNeighborScanPeriod;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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.
\return v_U16_t - neighbor scan period
-------------------------------------------------------------------------*/
v_U16_t sme_getNeighborScanPeriod(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->roam.neighborRoamInfo.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.
\return eHAL_STATUS_SUCCESS - SME update config successful.
Other status means SME is failed to update
\sa
--------------------------------------------------------------------------*/
eHalStatus sme_ChangeRoamScanChannelList(tHalHandle hHal, tANI_U8 *pChannelList,
tANI_U8 numChannels)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
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);
csrCreateBgScanRoamChannelList(pMac, pChannelList, numChannels);
sme_SetRoamScanControl(hHal, 1);
if (NULL != pNeighborRoamInfo->cfgParams.channelInfo.ChannelList)
{
j = 0;
for (i = 0; i < pNeighborRoamInfo->cfgParams.channelInfo.numOfChannels; i++)
{
if (j < sizeof(oldChannelList))
{
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 %s",
newChannelList, oldChannelList,
macTraceGetNeighbourRoamState(
pMac->roam.neighborRoamInfo.neighborRoamState));
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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 synchronuous 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
--------------------------------------------------------------------------*/
eHalStatus sme_SetEseRoamScanChannelList(tHalHandle hHal,
tANI_U8 *pChannelList,
tANI_U8 numChannels)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
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, 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 %s",
newChannelList, oldChannelList,
macTraceGetNeighbourRoamState(pMac->roam.neighborRoamInfo.neighborRoamState));
}
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
{
csrRoamOffloadScan(pMac, 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.
\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)
{
int i = 0;
tANI_U8 *pOutPtr = pChannelList;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = &pMac->roam.neighborRoamInfo;
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 synchronuous 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 synchronuous 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 synchronuous 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 a feature is enabled by FW
\param featEnumValue - Enumeration value from placeHolderInCapBitmap
\- return 1/0 (TRUE/FALSE)
-------------------------------------------------------------------------*/
tANI_U8 sme_IsFeatureSupportedByFW(tANI_U8 featEnumValue)
{
return IS_FEATURE_SUPPORTED_BY_FW(featEnumValue);
}
/* ---------------------------------------------------------------------------
\fn sme_IsFeatureSupportedByDriver
\brief Check if a feature is enabled by Driver
\param featEnumValue - Enumeration value from placeHolderInCapBitmap
\- return 1/0 (TRUE/FALSE)
-------------------------------------------------------------------------*/
tANI_U8 sme_IsFeatureSupportedByDriver(tANI_U8 featEnumValue)
{
return IS_FEATURE_SUPPORTED_BY_DRIVER(featEnumValue);
}
#ifdef FEATURE_WLAN_TDLS
/* ---------------------------------------------------------------------------
\fn sme_SendTdlsMgmtFrame
\brief API to send TDLS management frames.
\param peerMac - peer's Mac Adress.
\param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_SendTdlsLinkEstablishParams(tHalHandle hHal,
tANI_U8 sessionId,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tSirMacAddr peerMac,
#else
tSirMacAddr peerMac,
#endif
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 ;
}
// tdlsoffchan
/* ---------------------------------------------------------------------------
\fn sme_SendTdlsChanSwitchReq
\brief API to send TDLS management frames.
\param peerMac - peer's Mac Adress.
\param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_SendTdlsChanSwitchReq(tHalHandle hHal,
tANI_U8 sessionId,
tSirMacAddr peerMac,
tANI_S32 tdlsOffCh,
tANI_S32 tdlsOffChBwOffset,
tANI_U8 tdlsSwMode)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_TDLS_CHAN_SWITCH_REQ,
sessionId, tdlsOffCh));
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
status = csrTdlsSendChanSwitchReq(hHal, sessionId, peerMac,
tdlsOffCh, tdlsOffChBwOffset,
tdlsSwMode);
}
sme_ReleaseGlobalLock( &pMac->sme );
return status ;
}
/* ---------------------------------------------------------------------------
\fn sme_SendTdlsMgmtFrame
\brief API to send TDLS management frames.
\param peerMac - peer's Mac Adress.
\param frame_type - Type of TDLS mgmt frame to be sent.
\param dialog - dialog token used in the frame.
\param status - status to be incuded in the frame.
\param peerCapability - peer cpabilities
\param buf - additional IEs to be included
\param len - lenght of additional Ies
\param responder - Tdls request type
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_SendTdlsMgmtFrame(tHalHandle hHal, tANI_U8 sessionId,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tSirMacAddr peerMac,
#else
tSirMacAddr peerMac,
#endif
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 Adress.
\param staParams - Peer Station Parameters
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_ChangeTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tSirMacAddr peerMac,
#else
tSirMacAddr peerMac,
#endif
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 Adress.
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_AddTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tSirMacAddr peerMac
#else
tSirMacAddr peerMac
#endif
)
{
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 Adress.
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
VOS_STATUS sme_DeleteTdlsPeerSta(tHalHandle hHal, tANI_U8 sessionId,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const tSirMacAddr peerMac
#else
tSirMacAddr peerMac
#endif
)
{
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, v_BOOL_t val)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
pMac->isTdlsPowerSaveProhibited = val;
smsLog(pMac, LOG1, FL("isTdlsPowerSaveProhibited is %d"),
pMac->isTdlsPowerSaveProhibited);
return;
}
#endif
/* ---------------------------------------------------------------------------
\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"));
if (pMac->fActiveScanOnDFSChannels)
{
smsLog(pMac, LOG1, FL("Skip updating fEnableDFSChnlScan"
" as DFS feature is triggered"));
return (status);
}
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);
}
/* ---------------------------------------------------------------------------
\fn sme_UpdateDFSRoamMode
\brief Update DFS roam scan mode
This function is called to configure allowDFSChannelRoam
dynamically
\param hHal - HAL handle for device
\param allowDFSChannelRoam - DFS roaming scan mode
mode 0 disable roam scan on DFS channels
mode 1 enables roam scan (passive/active) on DFS channels
\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_UpdateDFSRoamMode(tHalHandle hHal, tANI_U8 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",
allowDFSChannelRoam,
pMac->roam.configParam.allowDFSChannelRoam);
pMac->roam.configParam.allowDFSChannelRoam = allowDFSChannelRoam;
sme_ReleaseGlobalLock( &pMac->sme );
}
#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
if (csrRoamIsRoamOffloadScanEnabled(pMac))
{
csrRoamOffloadScan(pMac, ROAM_SCAN_OFFLOAD_UPDATE_CFG,
REASON_CHANNEL_LIST_CHANGED);
}
#endif
return status ;
}
/* ---------------------------------------------------------------------------
\fn sme_UpdateDFSScanMode
\brief Update DFS scan mode
This function is called to configure fEnableDFSChnlScan.
\param hHal - HAL handle for device
\param dfsScanMode - DFS scan mode
mode 0 disable scan on DFS channels
mode 1 enables passive scan on DFS channels
mode 2 enables active scan on DFS channels for static list
\return eHAL_STATUS_SUCCESS - SME update DFS roaming scan config
successfully.
Other status means SME failed to update DFS scan config.
\sa
-------------------------------------------------------------------------*/
eHalStatus sme_UpdateDFSScanMode(tHalHandle hHal, tANI_U8 dfsScanMode)
{
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,
"DFS scan Mode changed to %d, old value is %d ",
dfsScanMode,
pMac->scan.fEnableDFSChnlScan);
pMac->scan.fEnableDFSChnlScan = dfsScanMode;
sme_ReleaseGlobalLock( &pMac->sme );
}
sme_FilterScanDFSResults(hHal);
sme_UpdateChannelList( hHal );
return status ;
}
/*--------------------------------------------------------------------------
\brief sme_GetDFSScanMode() - get DFS scan mode
\param hHal - The handle returned by macOpen.
\return DFS scan mode
mode 0 disable scan on DFS channels
mode 1 enables passive scan on DFS channels
mode 2 enables active scan on DFS channels for static list
\sa
--------------------------------------------------------------------------*/
v_U8_t sme_GetDFSScanMode(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
return pMac->scan.fEnableDFSChnlScan;
}
/* ---------------------------------------------------------------------------
\fn sme_HandleDFSChanScan
\brief Gets Valid channel list and updates scan control list according to
dfsScanMode
\param hHal - HAL handle for device
\return eHAL_STATUS_FAILURE when failed to get valid channel list
Otherwise eHAL_STATUS_SUCCESS -
\sa
-------------------------------------------------------------------------*/
eHalStatus sme_HandleDFSChanScan(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status = eHAL_STATUS_SUCCESS;
tCsrChannel ChannelList;
/*
* Set Flag to block driver scan type conversion from active to passive
* and vice versa in case if fEnableDFSChnlScan is
* DFS_CHNL_SCAN_ENABLED_ACTIVE
*/
if (DFS_CHNL_SCAN_ENABLED_ACTIVE ==
pMac->scan.fEnableDFSChnlScan)
pMac->fActiveScanOnDFSChannels = 1;
else
pMac->fActiveScanOnDFSChannels = 0;
ChannelList.numChannels = sizeof(ChannelList.channelList);
status = sme_GetCfgValidChannels(hHal, (tANI_U8 *)ChannelList.channelList,
(tANI_U32*)&ChannelList.numChannels);
if (!HAL_STATUS_SUCCESS(status))
{
smsLog(pMac, LOGE,
FL("Failed to get valid channel list (err=%d)"), status);
return status;
}
smsLog(pMac, LOG1, FL("Valid Channel list:"));
VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
ChannelList.channelList, ChannelList.numChannels);
sme_SetCfgScanControlList(hHal, pMac->scan.countryCodeCurrent,
&ChannelList);
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 messsage, 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 .. etc.
*
*/
static VOS_STATUS sme_AdjustCBMode(tAniSirGlobal* pMac,
tSmeConfigParams *smeConfig,
tANI_U8 channel)
{
const tANI_U8 step = SME_START_CHAN_STEP;
tANI_U8 i, startChan = channel, chanCnt = 0, chanBitmap = 0;
tANI_BOOLEAN violation = VOS_FALSE;
tANI_U32 newMode, mode;
tANI_U8 centerChan = channel;
/* to validate 40MHz channels against the regulatory domain */
tANI_BOOLEAN ht40PhyMode = 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;
centerChan = channel - CSR_CB_CENTER_CHANNEL_OFFSET;
ht40PhyMode = VOS_TRUE;
break;
case eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY:
startChan = channel;
chanCnt=2;
centerChan = channel + CSR_CB_CENTER_CHANNEL_OFFSET;
ht40PhyMode = 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))) ==
eHAL_STATUS_SUCCESS)
chanBitmap = chanBitmap | 1 << i;
else
violation = VOS_TRUE;
}
/* validate if 40MHz channel is allowed */
if (ht40PhyMode)
{
if (!csrRoamIsValid40MhzChannel(pMac, centerChan))
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;
}
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
*/
VOS_STATUS sme_SelectCBMode(tHalHandle hHal,
eCsrPhyMode eCsrPhyMode, tANI_U8 channel,
enum eSirMacHTChannelWidth max_bw)
{
tSmeConfigParams smeConfig;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
#ifdef WLAN_FEATURE_11AC
tANI_U8 vht80Allowed;
#endif
if (
#ifdef WLAN_FEATURE_11AC
eCSR_DOT11_MODE_11ac != eCsrPhyMode &&
eCSR_DOT11_MODE_11ac_ONLY != eCsrPhyMode &&
#endif
eCSR_DOT11_MODE_11n != eCsrPhyMode &&
eCSR_DOT11_MODE_11n_ONLY != eCsrPhyMode &&
eCSR_DOT11_MODE_11a != eCsrPhyMode &&
eCSR_DOT11_MODE_11a_ONLY != eCsrPhyMode &&
eCSR_DOT11_MODE_abg != eCsrPhyMode
)
{
return VOS_STATUS_SUCCESS;
}
vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
sme_GetConfigParam(pMac, &smeConfig);
/* If channel bonding mode is not required */
#ifdef WLAN_FEATURE_AP_HT40_24G
if ( !pMac->roam.configParam.channelBondingMode5GHz
&& !smeConfig.csrConfig.apHT40_24GEnabled ) {
#else
if ( !pMac->roam.configParam.channelBondingMode5GHz ) {
#endif
return VOS_STATUS_SUCCESS;
}
/* Check if VHT80 is allowed for the channel*/
vht80Allowed = vos_is_channel_valid_for_vht80(channel);
#ifdef WLAN_FEATURE_11AC
if ((eCSR_DOT11_MODE_11ac == eCsrPhyMode ||
eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode) &&
vht80Allowed && (max_bw >= eHT_CHANNEL_WIDTH_80MHZ)) {
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;
}
#ifdef WLAN_FEATURE_AP_HT40_24G
if (smeConfig.csrConfig.apHT40_24GEnabled &&
max_bw >= eHT_CHANNEL_WIDTH_40MHZ)
{
if (channel >= 1 && channel <= 7)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
else if (channel >= 8 && channel <= 13)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
else if (channel ==14)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_SINGLE_CHANNEL_CENTERED;
}
#endif
} else
#endif
if ((eCSR_DOT11_MODE_11n == eCsrPhyMode ||
eCSR_DOT11_MODE_11n_ONLY == eCsrPhyMode ||
eCSR_DOT11_MODE_11ac == eCsrPhyMode ||
eCSR_DOT11_MODE_11ac_ONLY == eCsrPhyMode) &&
(max_bw >= eHT_CHANNEL_WIDTH_40MHZ)) {
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;
}
#ifdef WLAN_FEATURE_AP_HT40_24G
if (smeConfig.csrConfig.apHT40_24GEnabled)
{
if (channel >= 1 && channel <= 7)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
else if (channel >= 8 && channel <= 13)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
else if (channel ==14)
smeConfig.csrConfig.channelBondingAPMode24GHz =
eCSR_INI_SINGLE_CHANNEL_CENTERED;
}
#endif
} else {
#ifdef WLAN_FEATURE_AP_HT40_24G
if (CSR_IS_CHANNEL_24GHZ(channel)) {
smeConfig.csrConfig.channelBondingMode24GHz =
eCSR_INI_SINGLE_CHANNEL_CENTERED;
} else
#endif
{
smeConfig.csrConfig.channelBondingMode5GHz =
eCSR_INI_SINGLE_CHANNEL_CENTERED;
}
}
sme_AdjustCBMode(pMac, &smeConfig, channel);
#ifdef WLAN_FEATURE_AP_HT40_24G
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("%s cbmode selected=%d bonding mode:%s"),
(channel <= 14) ? "2G" : "5G",
(channel <= 14) ? smeConfig.csrConfig.channelBondingAPMode24GHz :
smeConfig.csrConfig.channelBondingMode5GHz,
(channel <= 14) ?
sme_CBMode2String(smeConfig.csrConfig.channelBondingAPMode24GHz) :
sme_CBMode2String(smeConfig.csrConfig.channelBondingMode5GHz));
#else
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_WARN,
"cbmode selected=%d", smeConfig.csrConfig.channelBondingMode5GHz);
#endif
sme_UpdateConfig (pMac, &smeConfig);
return VOS_STATUS_SUCCESS;
}
/*--------------------------------------------------------------------------
\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;
}
#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 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,
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, pHandoffInfo);
sme_ReleaseGlobalLock( &pMac->sme );
}
return status ;
}
#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;
}
/*
* SME API to check if any sessoion connected.
*/
VOS_STATUS sme_is_any_session_connected(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
if(csrIsAnySessionConnected(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 *pAdapter, void *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 */
/*--------------------------------------------------------------------------
\brief sme_enable_disable_split_scan() - a wrapper function to set the split
scan parameter.
This is a synchronous call
\param hHal - The handle returned by macOpen
\return NONE.
\sa
--------------------------------------------------------------------------*/
void sme_enable_disable_split_scan (tHalHandle hHal, tANI_U8 nNumStaChan,
tANI_U8 nNumP2PChan)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
pMac->roam.configParam.nNumStaChanCombinedConc = nNumStaChan;
pMac->roam.configParam.nNumP2PChanCombinedConc = nNumP2PChan;
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: SCAN nNumStaChanCombinedConc : %d,"
"nNumP2PChanCombinedConc : %d ",
__func__, nNumStaChan, nNumP2PChan);
return;
}
/**
* 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;
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;
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;
}
#ifdef WLAN_FEATURE_RMC
/* ---------------------------------------------------------------------------
\fn sme_EnableRMC
\brief Used to enable RMC
setting will not persist over reboots
\param hHal
\param sessionId
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_EnableRMC(tHalHandle hHal, tANI_U32 sessionId)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
smsLog(pMac, LOG1, FL("enable RMC"));
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status))
{
status = csrEnableRMC(pMac, sessionId);
sme_ReleaseGlobalLock(&pMac->sme);
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_DisableRMC
\brief Used to disable RMC
setting will not persist over reboots
\param hHal
\param sessionId
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_DisableRMC(tHalHandle hHal, tANI_U32 sessionId)
{
eHalStatus status = eHAL_STATUS_FAILURE;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
smsLog(pMac, LOG1, FL("disable RMC"));
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status))
{
status = csrDisableRMC(pMac, sessionId);
sme_ReleaseGlobalLock(&pMac->sme);
}
return status;
}
#endif /* WLAN_FEATURE_RMC */
/* ---------------------------------------------------------------------------
\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;
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
{
msg.type = WDA_RATE_UPDATE_IND;
msg.bodyptr = rateUpdateParams;
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__);
sme_ReleaseGlobalLock(&pMac->sme);
return eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&pMac->sme);
return eHAL_STATUS_SUCCESS;
}
return status;
}
#ifdef WLAN_FEATURE_RMC
/* ---------------------------------------------------------------------------
\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);
}
#endif
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_FATAL,
"%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 FEATURE_WLAN_BATCH_SCAN
/* ---------------------------------------------------------------------------
\fn sme_SetBatchScanReq
\brief API to set batch scan request in FW
\param hHal - The handle returned by macOpen.
\param pRequest - Pointer to the batch request.
\param sessionId - session ID
\param callbackRoutine - HDD callback which needs to be invoked after
getting set batch scan response from FW
\param callbackContext - pAdapter context
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_SetBatchScanReq
(
tHalHandle hHal, tSirSetBatchScanReq *pRequest, tANI_U8 sessionId,
void (*callbackRoutine) (void *callbackCtx, tSirSetBatchScanRsp *pRsp),
void *callbackContext
)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status;
if (!pMac)
{
return eHAL_STATUS_FAILURE;
}
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
status = pmcSetBatchScanReq(hHal, pRequest, sessionId, callbackRoutine,
callbackContext);
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_TriggerBatchScanResultInd
\brief API to trigger batch scan result indications from FW
\param hHal - The handle returned by macOpen.
\param pRequest - Pointer to get batch request.
\param sessionId - session ID
\param callbackRoutine - HDD callback which needs to be invoked after
getting batch scan result indication from FW
\param callbackContext - pAdapter context
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_TriggerBatchScanResultInd
(
tHalHandle hHal, tSirTriggerBatchScanResultInd *pRequest, tANI_U8 sessionId,
void (*callbackRoutine) (void *callbackCtx, void *pRsp),
void *callbackContext
)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
status = pmcTriggerBatchScanResultInd(hHal, pRequest, sessionId,
callbackRoutine, callbackContext);
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_StopBatchScanInd
\brief API to stop batch scan request in FW
\param hHal - The handle returned by macOpen.
\param pRequest - Pointer to the batch request.
\param sessionId - session ID
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_StopBatchScanInd
(
tHalHandle hHal, tSirStopBatchScanInd *pRequest, tANI_U8 sessionId
)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
status = pmcStopBatchScanInd(hHal, pRequest, sessionId);
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
#endif
void activeListCmdTimeoutHandle(void *userData)
{
tHalHandle hHal= (tHalHandle) userData;
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
tListElem *pEntry;
tSmeCmd *pTempCmd = NULL;
if (NULL == pMac)
{
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 ((NULL == userData) ||
(0 == csrLLCount(&pMac->sme.smeCmdActiveList)))
return;
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Active List command timeout Cmd List Count %d", __func__,
csrLLCount(&pMac->sme.smeCmdActiveList) );
smeGetCommandQStatus(hHal);
vos_state_info_dump_all();
pEntry = csrLLPeekHead(&pMac->sme.smeCmdActiveList, LL_ACCESS_LOCK);
if (pEntry) {
pTempCmd = GET_BASE_ADDR(pEntry, tSmeCmd, Link);
}
/* If user initiated scan took more than active list timeout
* abort it.
*/
if (pTempCmd && (eSmeCommandScan == pTempCmd->command) &&
(eCsrScanUserRequest == pTempCmd->u.scanCmd.reason)) {
sme_AbortMacScan(hHal, pTempCmd->sessionId,
eCSR_SCAN_ABORT_DEFAULT);
return;
} else if (pTempCmd &&
(eSmeCommandRemainOnChannel == pTempCmd->command)) {
/* Ignore if ROC took more than 120 sec */
return;
}
if (pMac->roam.configParam.enableFatalEvent)
{
vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
WLAN_LOG_INDICATOR_HOST_DRIVER,
WLAN_LOG_REASON_SME_COMMAND_STUCK,
FALSE, FALSE);
}
else
{
/* Initiate SSR to recover */
if (!(vos_isLoadUnloadInProgress() ||
vos_is_logp_in_progress(VOS_MODULE_ID_SME, NULL)))
{
vos_wlanRestart(VOS_ACTIVE_LIST_TIMEOUT);
}
}
}
#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_INFO,
"%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);
}
#endif /* FEATURE_WLAN_CH_AVOID */
/**
* 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.rssiThresholdBreachedCb = cb;
sme_ReleaseGlobalLock(&mac->sme);
return status;
}
#ifdef WLAN_FEATURE_LINK_LAYER_STATS
/* ---------------------------------------------------------------------------
\fn sme_LLStatsSetReq
\brief API to set link layer stats request to FW
\param hHal - The handle returned by macOpen.
\Param pStatsReq - a pointer to a caller allocated object of
typedef struct tSirLLStatsSetReq, signifying the parameters to link layer
stats set.
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_LLStatsSetReq(tHalHandle hHal,
tSirLLStatsSetReq *pLinkLayerStatsSetReq)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
vos_msg_t msg;
eHalStatus status = eHAL_STATUS_FAILURE;
tSirLLStatsSetReq *plinkLayerSetReq;
plinkLayerSetReq = vos_mem_malloc(sizeof(*plinkLayerSetReq));
if ( !plinkLayerSetReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_LINK_LAYER_STATS_SET_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*plinkLayerSetReq = *pLinkLayerStatsSetReq;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
msg.type = WDA_LINK_LAYER_STATS_SET_REQ;
msg.reserved = 0;
msg.bodyptr = plinkLayerSetReq;
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 SIR_HAL_LL_STATS_SET message to HAL", __func__);
vos_mem_free(plinkLayerSetReq);
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(plinkLayerSetReq);
status = eHAL_STATUS_FAILURE;
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_LLStatsGetReq
\brief API to get link layer stats request to FW
\param hHal - The handle returned by macOpen.
\Param pStatsReq - a pointer to a caller allocated object of
typedef struct tSirLLStatsGetReq, signifying the parameters to link layer
stats get.
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_LLStatsGetReq(tHalHandle hHal,
tSirLLStatsGetReq *pLinkLayerStatsGetReq)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
vos_msg_t msg;
eHalStatus status = eHAL_STATUS_FAILURE;
tSirLLStatsGetReq *pGetStatsReq;
pGetStatsReq = vos_mem_malloc(sizeof(*pGetStatsReq));
if ( !pGetStatsReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_LINK_LAYER_STATS_GET_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pGetStatsReq = *pLinkLayerStatsGetReq;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
msg.type = WDA_LINK_LAYER_STATS_GET_REQ;
msg.reserved = 0;
msg.bodyptr = pGetStatsReq;
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 SIR_HAL_LL_STATS_GET message to HAL", __func__);
vos_mem_free(pGetStatsReq);
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(pGetStatsReq);
status = eHAL_STATUS_FAILURE;
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_LLStatsClearReq
\brief API to clear link layer stats request to FW
\param hHal - The handle returned by macOpen.
\Param pStatsReq - a pointer to a caller allocated object of
typedef struct tSirLLStatsClearReq, signifying the parameters to link layer
stats clear.
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_LLStatsClearReq(tHalHandle hHal,
tSirLLStatsClearReq *pLinkLayerStatsClear)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
vos_msg_t msg;
eHalStatus status = eHAL_STATUS_FAILURE;
tSirLLStatsClearReq *pClearStatsReq;
pClearStatsReq = vos_mem_malloc(sizeof(*pClearStatsReq));
if ( !pClearStatsReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_LINK_LAYER_STATS_CLEAR_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pClearStatsReq = *pLinkLayerStatsClear;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
msg.type = WDA_LINK_LAYER_STATS_CLEAR_REQ;
msg.reserved = 0;
msg.bodyptr = pClearStatsReq;
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 SIR_HAL_LL_STATS_CLEAR message to HAL", __func__);
vos_mem_free(pClearStatsReq);
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(pClearStatsReq);
status = eHAL_STATUS_FAILURE;
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_SetLinkLayerStatsIndCB
\brief API to trigger Link Layer Statistic indications from FW
\param hHal - The handle returned by macOpen.
\param sessionId - session ID
\param callbackRoutine - HDD callback which needs to be invoked after
getting Link Layer Statistics from FW
\param callbackContext - pAdapter context
\return eHalStatus
---------------------------------------------------------------------------*/
eHalStatus sme_SetLinkLayerStatsIndCB
(
tHalHandle hHal,
void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp,
tANI_U8 *macAddr)
)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
eHalStatus status;
if ( eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock( &pMac->sme )))
{
if (NULL != callbackRoutine)
{
pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
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);
}
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: CSR Session lookup fails %u", __func__, sessionId);
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,
"%s: QOS Mapping IE not present", __func__);
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 <= WLAN_MAX_DSCP; j++)
dscpmapping[j]= i;
}
for (i = 0; i< pSession->QosMapSet.num_dscp_exceptions; i++)
{
if (pSession->QosMapSet.dscp_exceptions[i][0] <= WLAN_MAX_DSCP)
{
dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0] ] =
pSession->QosMapSet.dscp_exceptions[i][1];
}
}
}
}
sme_ReleaseGlobalLock( &pMac->sme);
return status;
}
tANI_BOOLEAN sme_Is11dCountrycode(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
if (VOS_TRUE == vos_mem_compare(pMac->scan.countryCodeCurrent,
pMac->scan.countryCode11d, 2))
{
return eANI_BOOLEAN_TRUE;
}
else
{
return eANI_BOOLEAN_FALSE;
}
}
eHalStatus
sme_SpoofMacAddrReq(tHalHandle hHal, v_MACADDR_t *macaddr, bool spoof_mac_oui)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
tSmeCmd *pMacSpoofCmd;
status = sme_AcquireGlobalLock( &pMac->sme );
if ( HAL_STATUS_SUCCESS( status ) )
{
pMacSpoofCmd = csrGetCommandBuffer(pMac);
if (pMacSpoofCmd)
{
pMacSpoofCmd->command = eSmeCommandMacSpoofRequest;
vos_mem_set(&pMacSpoofCmd->u.macAddrSpoofCmd,
sizeof(tSirSpoofMacAddrReq), 0);
vos_mem_copy(pMacSpoofCmd->u.macAddrSpoofCmd.macAddr,
macaddr->bytes, VOS_MAC_ADDRESS_LEN);
pMacSpoofCmd->u.macAddrSpoofCmd.spoof_mac_oui = spoof_mac_oui;
status = csrQueueSmeCommand(pMac, pMacSpoofCmd, false);
if ( !HAL_STATUS_SUCCESS( status ) )
{
smsLog( pMac, LOGE, FL("fail to send msg status = %d\n"), status );
csrReleaseCommand(pMac, pMacSpoofCmd);
}
}
else
{
//log error
smsLog(pMac, LOGE, FL("can not obtain a common buffer\n"));
status = eHAL_STATUS_RESOURCES;
}
sme_ReleaseGlobalLock( &pMac->sme);
}
return (status);
}
#ifdef WLAN_FEATURE_EXTSCAN
/* ---------------------------------------------------------------------------
\fn sme_GetValidChannelsByBand
\brief SME API to fetch all valid channel filtered by band
\param hHal
\param wifiBand: RF band information
\param aValidChannels: Array to store channel info
\param len: 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 < numChannels; 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 Extended Scan capabilities
\param hHal
\param pReq: Extended Scan 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;
tSirGetEXTScanCapabilitiesReqParams *pGetEXTScanCapabilitiesReq;
pGetEXTScanCapabilitiesReq =
vos_mem_malloc(sizeof(*pGetEXTScanCapabilitiesReq));
if ( !pGetEXTScanCapabilitiesReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_GET_CAPABILITIES_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pGetEXTScanCapabilitiesReq = *pReq;
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pGetEXTScanCapabilitiesReq;
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)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
"failed to post WDA_EXTSCAN_GET_CAPABILITIES_REQ ",
__func__);
vos_mem_free(pGetEXTScanCapabilitiesReq);
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(pGetEXTScanCapabilitiesReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_EXTScanStart
\brief SME API to issue Extended Scan start
\param hHal
\param pStartCmd: Extended Scan start structure
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_EXTScanStart (tHalHandle hHal,
tSirEXTScanStartReqParams *pStartCmd)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tSirEXTScanStartReqParams *pextScanStartReq;
pextScanStartReq = vos_mem_malloc(sizeof(*pextScanStartReq));
if ( !pextScanStartReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_START_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pextScanStartReq = *pStartCmd;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_EXTSCAN_START, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pextScanStartReq;
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)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: failed to post WDA_EXTSCAN_START_REQ", __func__);
vos_mem_free(pextScanStartReq);
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(pextScanStartReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_EXTScanStop
\brief SME API to issue Extended Scan stop
\param hHal
\param pStopReq: Extended Scan 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;
tSirEXTScanStopReqParams *pEXTScanStopReq;
pEXTScanStopReq = vos_mem_malloc(sizeof(*pEXTScanStopReq));
if ( !pEXTScanStopReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_STOP_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pEXTScanStopReq = *pStopReq;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_EXTSCAN_STOP, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
{
/* Serialize the req through MC thread */
vosMessage.bodyptr = pEXTScanStopReq;
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))
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: failed to post WDA_EXTSCAN_STOP_REQ", __func__);
vos_mem_free(pEXTScanStopReq);
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(pEXTScanStopReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_SetBssHotlist
\brief SME API to set BSSID hotlist
\param hHal
\param pSetHotListReq: Extended Scan 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;
tSirEXTScanSetBssidHotListReqParams *pEXTScanSetBssidHotlistReq;
pEXTScanSetBssidHotlistReq =
vos_mem_malloc(sizeof(*pEXTScanSetBssidHotlistReq));
if ( !pEXTScanSetBssidHotlistReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_SET_BSSID_HOTLIST_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pEXTScanSetBssidHotlistReq = *pSetHotListReq;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_EXTSCAN_SET_BSS_HOTLIST, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pEXTScanSetBssidHotlistReq;
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)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: failed to post WDA_EXTSCAN_STOP_REQ", __func__);
vos_mem_free(pEXTScanSetBssidHotlistReq);
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(pEXTScanSetBssidHotlistReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_ResetBssHotlist
\brief SME API to reset BSSID hotlist
\param hHal
\param pSetHotListReq: Extended Scan 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;
tSirEXTScanResetBssidHotlistReqParams *pEXTScanHotlistResetReq;
pEXTScanHotlistResetReq = vos_mem_malloc(sizeof(*pEXTScanHotlistResetReq));
if ( !pEXTScanHotlistResetReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pEXTScanHotlistResetReq = *pResetReq;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_EXTSCAN_RESET_BSS_HOTLIST, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pEXTScanHotlistResetReq;
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)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: failed to post WDA_EXTSCAN_RESET_BSSID_HOTLIST_REQ",
__func__);
vos_mem_free(pEXTScanHotlistResetReq);
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(pEXTScanHotlistResetReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_getCachedResults
\brief SME API to get cached results
\param hHal
\param pCachedResultsReq: Extended Scan 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;
tSirEXTScanGetCachedResultsReqParams *pEXTScanCachedResultsReq;
pEXTScanCachedResultsReq =
vos_mem_malloc(sizeof(*pEXTScanCachedResultsReq));
if ( !pEXTScanCachedResultsReq)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"WDA_EXTSCAN_GET_CACHED_RESULTS_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
*pEXTScanCachedResultsReq = *pCachedResultsReq;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_EXTSCAN_GET_CACHED_RESULTS, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = pEXTScanCachedResultsReq;
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)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: failed tp post WDA_EXTSCAN_GET_CACHED_RESULTS_REQ",
__func__);
vos_mem_free(pEXTScanCachedResultsReq);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&pMac->sme);
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Failed to acquire SME Global Lock"));
vos_mem_free(pEXTScanCachedResultsReq);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
eHalStatus sme_EXTScanRegisterCallback (tHalHandle hHal,
void (*pEXTScanIndCb)(void *, const tANI_U16, void *),
void *callbackContext)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
pMac->sme.pEXTScanIndCb = pEXTScanIndCb;
pMac->sme.pEXTScanCallbackContext = callbackContext;
sme_ReleaseGlobalLock(&pMac->sme);
}
return(status);
}
#ifdef FEATURE_OEM_DATA_SUPPORT
eHalStatus sme_OemDataRegisterCallback (tHalHandle hHal,
void (*pOemDataIndCb)(void *, const tANI_U16, void *, tANI_U32),
void *callbackContext)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
pMac->sme.pOemDataIndCb = pOemDataIndCb;
pMac->sme.pOemDataCallbackContext = callbackContext;
sme_ReleaseGlobalLock(&pMac->sme);
}
return(status);
}
#endif
void sme_SetMiracastMode (tHalHandle hHal,tANI_U8 mode)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
vos_msg_t vosMessage = {0};
tSirHighPriorityDataInfoInd *phighPriorityDataInfo;
pMac->miracast_mode = mode;
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: miracast_mode: %d", __func__, mode);
phighPriorityDataInfo =
vos_mem_malloc(sizeof(*phighPriorityDataInfo));
if ( !phighPriorityDataInfo)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:"
"Failed to allocate memory for WDA_HIGH_PRIORITY_DATA_INFO_IND",
__func__);
return;
}
if (mode)
phighPriorityDataInfo->pause = TRUE;
else
phighPriorityDataInfo->pause = FALSE;
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
/* Serialize the req through MC thread */
vosMessage.bodyptr = phighPriorityDataInfo;
vosMessage.type = WDA_HIGH_PRIORITY_DATA_INFO_IND;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_WDA_MSG, NO_SESSION, vosMessage.type));
if(VOS_STATUS_SUCCESS !=
vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage)) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s:"
"Failed to post WDA_HIGH_PRIORITY_DATA_INFO_IND msg to WDA",
__func__);
vos_mem_free(phighPriorityDataInfo);
}
sme_ReleaseGlobalLock(&pMac->sme);
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
"sme_AcquireGlobalLock error", __func__);
vos_mem_free(phighPriorityDataInfo);
}
}
#endif /* WLAN_FEATURE_EXTSCAN */
void sme_resetCoexEevent(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if (pMac == NULL)
{
printk("btc: %s pMac is NULL \n",__func__);
return;
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("isCoexScoIndSet: %d"), pMac->isCoexScoIndSet);
if (pMac->isCoexScoIndSet)
{
pMac->isCoexScoIndSet = 0;
ccmCfgSetInt(pMac, WNI_CFG_DEL_ALL_RX_TX_BA_SESSIONS_2_4_G_BTC, 0,
NULL, eANI_BOOLEAN_FALSE);
}
return;
}
void sme_disable_dfs_channel(tHalHandle hHal, bool disbale_dfs)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
pMac->scan.fEnableDFSChnlScan = !disbale_dfs;
csrDisableDfsChannel(pMac);
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: Modified fEnableDFSChnlScan: %d", __func__,
pMac->scan.fEnableDFSChnlScan);
}
/* ---------------------------------------------------------------------------
\fn sme_Encryptmsgsend
\brief SME API to issue encrypt message request
\param hHal
\param pCmd: Data to be encrypted
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_Encryptmsgsend (tHalHandle hHal,
u8 *pCmd,
int length,
pEncryptMsgRSPCb encMsgCbk)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
u8 *pEncryptMsg;
pEncryptMsg = vos_mem_malloc(length);
if ( !pEncryptMsg)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for "
"SIR_HAL_ENCRYPT_MSG_REQ",
__func__);
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(pEncryptMsg, pCmd, length);
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) {
pMac->sme.pEncMsgInfoParams.pEncMsgCbk = encMsgCbk;
pMac->sme.pEncMsgInfoParams.pUserData = hHal;
/* Serialize the req through MC thread */
vosMessage.bodyptr = pEncryptMsg;
vosMessage.type = SIR_HAL_ENCRYPT_MSG_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: failed to post SIR_HAL_ENCRYPT_MSG_REQ", __func__);
vos_mem_free(pEncryptMsg);
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(pEncryptMsg);
status = eHAL_STATUS_FAILURE;
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn sme_RegisterBtCoexTDLSCallback
\brief Used to plug in callback function
Which notify btcoex on or off.
Notification come from FW.
\param hHal
\param pCallbackfn : callback function pointer should be plugged in
\- return eHalStatus
-------------------------------------------------------------------------*/
eHalStatus sme_RegisterBtCoexTDLSCallback
(
tHalHandle hHal,
void (*pCallbackfn)(void *pAdapter, int )
)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: Plug in BtCoex TDLS CB", __func__);
status = sme_AcquireGlobalLock(&pMac->sme);
if (eHAL_STATUS_SUCCESS == status)
{
if (NULL != pCallbackfn)
{
pMac->sme.pBtCoexTDLSNotification = pCallbackfn;
}
sme_ReleaseGlobalLock(&pMac->sme);
}
return(status);
}
/* ---------------------------------------------------------------------------
\fn smeNeighborMiddleOfRoaming
\brief This function is a wrapper to call csrNeighborMiddleOfRoaming
\param hHal - The handle returned by macOpen.
\return eANI_BOOLEAN_TRUE if reassoc in progress,
eANI_BOOLEAN_FALSE otherwise
---------------------------------------------------------------------------*/
tANI_BOOLEAN smeNeighborMiddleOfRoaming(tHalHandle hHal)
{
return (csrNeighborMiddleOfRoaming(PMAC_STRUCT(hHal)));
}
/* ---------------------------------------------------------------------------
\fn sme_IsTdlsOffChannelValid
\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_IsTdlsOffChannelValid(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 ) )
{
/* check whether off channel is valid and non DFS */
if (csrRoamIsChannelValid(pMac, channel))
{
if (!CSR_IS_CHANNEL_DFS(channel))
valid = TRUE;
else {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: configured channel is DFS", __func__);
}
}
else {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: configured channel is not valid", __func__);
}
sme_ReleaseGlobalLock( &pMac->sme );
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: current country code %c%c channel %d valid %d",
__func__, pMac->scan.countryCodeCurrent[0],
pMac->scan.countryCodeCurrent[1], channel, valid);
return (valid);
}
tANI_BOOLEAN sme_IsCoexScoIndicationSet(tHalHandle hHal)
{
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 = pMac->isCoexScoIndSet;
}
sme_ReleaseGlobalLock( &pMac->sme );
return (valid);
}
eHalStatus sme_SetMiracastVendorConfig(tHalHandle hHal,
tANI_U32 iniNumBuffAdvert , tANI_U32 set_value)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tANI_U8 mcsSet[SIZE_OF_SUPPORTED_MCS_SET];
tANI_U32 val = SIZE_OF_SUPPORTED_MCS_SET;
if (ccmCfgGetStr(hHal, WNI_CFG_SUPPORTED_MCS_SET, mcsSet, &val)
!= eHAL_STATUS_SUCCESS)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("failed to get ini param, WNI_CFG_SUPPORTED_MCS_SET"));
return eHAL_STATUS_FAILURE;
}
if (set_value)
{
if (pMac->miracastVendorConfig)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL(" Miracast tuning already enabled!!"));
return eHAL_STATUS_SUCCESS;
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("Enable Miracast tuning by disabling 64QAM rates, setting 4 blocks for aggregation and disabling probe response for broadcast probe in P2P-GO mode"));
if (ccmCfgSetInt(hHal, WNI_CFG_NUM_BUFF_ADVERT, 4,
NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Failure: Could not set WNI_CFG_NUM_BUFF_ADVERT"));
return eHAL_STATUS_FAILURE;
}
/* Disable 64QAM rates ie (MCS 5,6 and 7)
*/
mcsSet[0]=0x1F;
}
else
{
if (!pMac->miracastVendorConfig)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL(" Miracast tuning already disabled!!"));
return eHAL_STATUS_SUCCESS;
}
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
FL("Disable Miracast tuning by enabling all MCS rates, setting %d blocks for aggregation and enabling probe response for broadcast probe in P2P-GO mode"),
iniNumBuffAdvert);
if (ccmCfgSetInt(hHal, WNI_CFG_NUM_BUFF_ADVERT, iniNumBuffAdvert,
NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Failure: Could not set WNI_CFG_NUM_BUFF_ADVERT"));
return eHAL_STATUS_FAILURE;
}
/* Enable all MCS rates)
*/
mcsSet[0]=0xFF;
}
if (ccmCfgSetStr(hHal, WNI_CFG_SUPPORTED_MCS_SET, mcsSet,
val, NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Failure: Could not set WNI_CFG_SUPPORTED_MCS_SET"));
return eHAL_STATUS_FAILURE;
}
pMac->miracastVendorConfig = set_value;
return eHAL_STATUS_SUCCESS;
}
void sme_SetDefDot11Mode(tHalHandle hHal)
{
tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
csrSetDefaultDot11Mode(pMac);
}
/* ---------------------------------------------------------------------------
\fn sme_SetTdls2040BSSCoexistence
\brief API to enable or disable 20_40 BSS Coexistence IE in TDLS frames.
\param isEnabled - Enable or Disable.
\- return VOS_STATUS_SUCCES
-------------------------------------------------------------------------*/
eHalStatus sme_SetTdls2040BSSCoexistence(tHalHandle hHal,
tANI_S32 isTdls2040BSSCoexEnabled)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
tAniSetTdls2040BSSCoex *pMsg;
status = sme_AcquireGlobalLock( &pMac->sme );
if (HAL_STATUS_SUCCESS( status ))
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
"%s: is2040BSSCoexEnabled %d ",
__func__, isTdls2040BSSCoexEnabled);
pMsg = vos_mem_malloc(sizeof(tAniSetTdls2040BSSCoex));
if (NULL == pMsg )
{
smsLog(pMac, LOGE, "failed to allocate mem for SetTdls2040BSSCoex");
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
pMsg->msgType = pal_cpu_to_be16(
(tANI_U16)eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ);
pMsg->msgLen = (tANI_U16)sizeof(tAniSetTdls2040BSSCoex);
pMsg->SetTdls2040BSSCoex = isTdls2040BSSCoexEnabled;
msg.type = eWNI_SME_SET_TDLS_2040_BSSCOEX_REQ;
msg.reserved = 0;
msg.bodyptr = pMsg;
msg.bodyval = 0;
if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_PE, &msg))
{
smsLog(pMac, LOGE,
"sme_SetTdls2040BSSCoexistence failed to post msg to PE ");
vos_mem_free((void *)pMsg);
status = eHAL_STATUS_FAILURE;
}
smsLog(pMac, LOG1, FL(" returned"));
sme_ReleaseGlobalLock( &pMac->sme );
}
return status;
}
/* ---------------------------------------------------------------------------
\fn sme_SetRtsCtsHtVht
\brief API to to enable/disable RTS/CTS for different modes.
\param set_value - Bit mask value to enable RTS/CTS for different modes.
\- return VOS_STATUS_SUCCES if INdication is posted to
WDA else return eHAL_STATUS_FAILURE
-------------------------------------------------------------------------*/
eHalStatus sme_SetRtsCtsHtVht(tHalHandle hHal, tANI_U32 set_value)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
smsLog(pMac, LOG1, FL(" set_value = %d"), set_value);
if (ccmCfgSetInt(hHal, WNI_CFG_ENABLE_RTSCTS_HTVHT, set_value,
NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
smsLog(pMac, LOGE,
FL("Failure: Could not set WNI_CFG_ENABLE_RTSCTS_HTVHT"));
return eHAL_STATUS_FAILURE;
}
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ))
{
vos_mem_zero(&msg, sizeof(vos_msg_t));
msg.type = WDA_SET_RTS_CTS_HTVHT;
msg.reserved = 0;
msg.bodyval = set_value;
if (VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_WDA, &msg))
{
smsLog(pMac, LOGE,
FL("Not able to post WDA_SET_RTS_CTS_HTVHT message to HAL"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_SUCCESS;
}
return eHAL_STATUS_FAILURE;
}
/* ---------------------------------------------------------------------------
\fn sme_fatal_event_logs_req
\brief API to to send flush log command to FW..
\param hHal - Mac Context Handle
\- return VOS_STATUS_SUCCES if command is posted to
WDA else return eHAL_STATUS_FAILURE
-------------------------------------------------------------------------*/
eHalStatus sme_fatal_event_logs_req(tHalHandle hHal, tANI_U32 is_fatal,
tANI_U32 indicator, tANI_U32 reason_code,
tANI_BOOLEAN dump_vos_trace)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tpSirFatalEventLogsReqParam pFatalEventLogsReqParams;
/* Dump last 500 VosTrace */
if (dump_vos_trace)
vosTraceDumpAll(pMac, 0, 0, 500, 0);
if (WLAN_LOG_INDICATOR_HOST_ONLY == indicator)
{
vos_flush_host_logs_for_fatal();
return VOS_STATUS_SUCCESS;
}
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ))
{
pFatalEventLogsReqParams =
vos_mem_malloc(sizeof(*pFatalEventLogsReqParams));
if(NULL == pFatalEventLogsReqParams)
{
smsLog(pMac, LOGE,
FL("vos_mem_alloc failed "));
return eHAL_STATUS_FAILED_ALLOC;
}
vos_mem_set(pFatalEventLogsReqParams,
sizeof(*pFatalEventLogsReqParams), 0);
pFatalEventLogsReqParams->reason_code = reason_code;
vos_mem_zero(&msg, sizeof(vos_msg_t));
msg.type = WDA_FATAL_EVENT_LOGS_REQ;
msg.reserved = 0;
msg.bodyptr = pFatalEventLogsReqParams;
msg.bodyval = 0;
vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg);
if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
vos_mem_free(pFatalEventLogsReqParams);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
return status;
}
return eHAL_STATUS_FAILURE;
}
/**
* sme_handleSetFccChannel() - handle fcc constraint request
* @hal: HAL pointer
* @fcc_constraint: whether to apply or remove fcc constraint
*
* Return: tANI_BOOLEAN.
*/
tANI_BOOLEAN sme_handleSetFccChannel(tHalHandle hHal, tANI_U8 fcc_constraint,
v_U32_t scan_pending)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
status = sme_AcquireGlobalLock(&pMac->sme);
if (eHAL_STATUS_SUCCESS == status &&
(!sme_Is11dSupported(hHal)) )
{
pMac->scan.fcc_constraint = !fcc_constraint;
if (scan_pending == TRUE) {
pMac->scan.defer_update_channel_list = true;
} else {
/* update the channel list to the firmware */
csrUpdateFCCChannelList(pMac);
}
}
sme_ReleaseGlobalLock(&pMac->sme);
return status;
}
eHalStatus sme_enableDisableChanAvoidIndEvent(tHalHandle hHal, tANI_U8 set_value)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
smsLog(pMac, LOG1, FL("set_value: %d"), set_value);
if ( eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock( &pMac->sme ))
{
vos_mem_zero(&msg, sizeof(vos_msg_t));
msg.type = WDA_SEND_FREQ_RANGE_CONTROL_IND;
msg.reserved = 0;
msg.bodyval = set_value;
vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg);
if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
return status;
}
return eHAL_STATUS_FAILURE;
}
eHalStatus sme_DeleteAllTDLSPeers(tHalHandle hHal, uint8_t sessionId)
{
tSirDelAllTdlsPeers *pMsg;
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
pMsg = vos_mem_malloc(sizeof(tSirDelAllTdlsPeers));
if (NULL == pMsg)
{
smsLog(pMac, LOGE, FL("memory alloc failed"));
return eHAL_STATUS_FAILURE;
}
vos_mem_set(pMsg, sizeof( tSirDelAllTdlsPeers ), 0);
pMsg->mesgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_DEL_ALL_TDLS_PEERS);
pMsg->mesgLen = pal_cpu_to_be16((tANI_U16)sizeof( tSirDelAllTdlsPeers ));
vos_mem_copy(pMsg->bssid, pSession->connectedProfile.bssid,
sizeof(tSirMacAddr));
status = palSendMBMessage( pMac->hHdd, pMsg );
return status;
}
/**
* sme_FwMemDumpReq() - Send Fwr mem Dump Request
* @hal: HAL pointer
*
* Return: eHalStatus
*/
eHalStatus sme_FwMemDumpReq(tHalHandle hHal, tAniFwrDumpReq *recv_req)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
tAniFwrDumpReq * send_req;
send_req = vos_mem_malloc(sizeof(*send_req));
if(!send_req) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Mem allo failed for FW_MEM_DUMP"));
return eHAL_STATUS_FAILURE;
}
send_req->fwMemDumpReqCallback = recv_req->fwMemDumpReqCallback;
send_req->fwMemDumpReqContext = recv_req->fwMemDumpReqContext;
if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme))
{
msg.bodyptr = send_req;
msg.type = WDA_FW_MEM_DUMP_REQ;
msg.reserved = 0;
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_FW_MEM_DUMP"));
vos_mem_free(send_req);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&pMac->sme);
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Failed to acquire SME Global Lock"));
vos_mem_free(send_req);
status = eHAL_STATUS_FAILURE;
}
return status;
}
eHalStatus sme_set_wificonfig_params(tHalHandle hHal, tSetWifiConfigParams *req)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t msg;
status = sme_AcquireGlobalLock(&pMac->sme);
if (eHAL_STATUS_SUCCESS == status){
/* serialize the req through MC thread */
msg.type = WDA_WIFI_CONFIG_REQ;
msg.reserved = 0;
msg.bodyptr = req;
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 SIR_HAL_WIFI_CONFIG_PARAMS message to HAL", __func__);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
else
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
"sme_AcquireGlobalLock error", __func__);
}
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;
}
eHalStatus sme_GetCurrentAntennaIndex(tHalHandle hHal,
tCsrAntennaIndexCallback callback,
void *pContext, tANI_U8 sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
tSirAntennaDiversitySelectionReq *pMsg;
tCsrRoamSession *pSession;
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
vos_msg_t vosMessage;
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_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;
}
pMsg = (tSirAntennaDiversitySelectionReq*)vos_mem_malloc(sizeof(*pMsg));
if (NULL == pMsg)
{
smsLog(pMac, LOGE, FL("failed to allocated memory"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
pMsg->callback = callback;
pMsg->data = pContext;
vosMessage.type = WDA_ANTENNA_DIVERSITY_SELECTION_REQ;
vosMessage.bodyptr = pMsg;
vosMessage.reserved = 0;
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__);
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_setBcnMissPenaltyCount(tHalHandle hHal,
tModifyRoamParamsReqParams *pModifyRoamReqParams)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
eHalStatus status = eHAL_STATUS_SUCCESS;
VOS_STATUS vosStatus;
tModifyRoamParamsReqParams *pMsg;
vos_msg_t msg;
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status))
{
pMsg = (tModifyRoamParamsReqParams*)vos_mem_malloc(sizeof(*pMsg));
if (NULL == pMsg)
{
smsLog(pMac, LOGE, FL("failed to allocated memory"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
if (NULL == pModifyRoamReqParams)
{
smsLog(pMac, LOGE, FL("Invalid memory"));
vos_mem_free(pMsg);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
pMsg->param = pModifyRoamReqParams->param;
pMsg->value = pModifyRoamReqParams->value;
vos_mem_zero(&msg, sizeof(vos_msg_t));
msg.type = WDA_MODIFY_ROAM_PARAMS_IND;
msg.reserved = 0;
msg.bodyptr = pMsg;
vosStatus = vos_mq_post_message( VOS_MQ_ID_WDA, &msg);
if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
status = eHAL_STATUS_FAILURE;
vos_mem_free(pMsg);
}
sme_ReleaseGlobalLock( &pMac->sme );
return status;
}
return eHAL_STATUS_FAILURE;
}
/**
* 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 pMac = PMAC_STRUCT(hal);
status = sme_AcquireGlobalLock(&pMac->sme);
if (HAL_STATUS_SUCCESS(status)) {
csr_remove_bssid_from_scan_list(pMac, bssid);
sme_ReleaseGlobalLock(&pMac->sme);
}
return status;
}
/**
* sme_set_mgmt_frm_via_wq5() - Set INI params sendMgmtPktViaWQ5 to WDA.
* @hal: HAL pointer
* @sendMgmtPktViaWQ5: INI params to enable/disable sending mgmt pkt via WQ5.
*
* Return: void
*/
void sme_set_mgmt_frm_via_wq5(tHalHandle hHal, tANI_BOOLEAN sendMgmtPktViaWQ5)
{
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,
"sendMgmtPktViaWQ5 is %d", sendMgmtPktViaWQ5);
/* not serializing this messsage, as this is only going
* to set a variable in WDA/WDI
*/
WDA_SetMgmtPktViaWQ5(sendMgmtPktViaWQ5);
sme_ReleaseGlobalLock(&pMac->sme);
}
return;
}
/* ARP DEBUG STATS */
/**
* sme_set_nud_debug_stats() - sme api to set nud debug stats
* @hHal: handle to hal
* @pSetStatsParam: pointer to set stats param
*/
eHalStatus sme_set_nud_debug_stats(tHalHandle hHal,
setArpStatsParams *pSetStatsParam)
{
setArpStatsParams *arp_set_param;
vos_msg_t msg;
arp_set_param = vos_mem_malloc(sizeof(*arp_set_param));
if (arp_set_param == NULL) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Memory allocation failure"));
return VOS_STATUS_E_NOMEM;
}
vos_mem_copy(arp_set_param, pSetStatsParam, sizeof(*arp_set_param));
msg.type = WDA_SET_ARP_STATS_REQ;
msg.reserved = 0;
msg.bodyptr = arp_set_param;
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 message to WDA"));
vos_mem_free(arp_set_param);
return VOS_STATUS_E_FAILURE;
}
return VOS_STATUS_SUCCESS;
}
/**
* sme_get_nud_debug_stats() - sme api to get nud debug stats
* @hHal: handle to hal
* @pGetStatsParam: pointer to set stats param
*/
eHalStatus sme_get_nud_debug_stats(tHalHandle hHal,
getArpStatsParams *pGetStatsParam)
{
getArpStatsParams *arpGetParams;
vos_msg_t msg;
arpGetParams = vos_mem_malloc(sizeof(*arpGetParams));
if (arpGetParams == NULL) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
FL("Memory allocation failure"));
return VOS_STATUS_E_NOMEM;
}
vos_mem_copy(arpGetParams, pGetStatsParam, sizeof(*arpGetParams));
msg.type = WDA_GET_ARP_STATS_REQ;
msg.reserved = 0;
msg.bodyptr = arpGetParams;
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 message to WDA"));
vos_mem_free(arpGetParams);
return VOS_STATUS_E_FAILURE;
}
return VOS_STATUS_SUCCESS;
}
#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);
}
#endif
#ifdef DHCP_SERVER_OFFLOAD
/**
* sme_set_dhcp_srv_offload() - sme api to set dhcp server offload info
* @hal: handle to hal
* @dhcp_srv_info: pointer to dhcp server info
*
* Return: eHalStatus
* eHAL_STATUS_SUCCESS - success or else failure code
*/
eHalStatus sme_set_dhcp_srv_offload(tHalHandle hal,
sir_dhcp_srv_offload_info_t *dhcp_srv_info)
{
vos_msg_t vos_msg;
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
sir_dhcp_srv_offload_info_t *dhcp_serv_info = NULL;
dhcp_serv_info =
vos_mem_malloc(sizeof(*dhcp_serv_info));
if (NULL == dhcp_serv_info) {
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"Failed to alloc memory");
return VOS_STATUS_E_NOMEM;
}
vos_mem_copy(dhcp_serv_info, dhcp_srv_info,
sizeof(*dhcp_serv_info));
dhcp_serv_info->bssidx = peFindBssIdxFromSmeSessionId(mac, dhcp_srv_info->bssidx);
status = sme_AcquireGlobalLock(&mac->sme);
if (eHAL_STATUS_SUCCESS == status) {
/* serialize the req through MC thread */
vos_msg.type = WDA_SET_DHCP_SERVER_OFFLOAD_REQ;
vos_msg.bodyptr = dhcp_serv_info;
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,
"%s: Not able to post WDA_SET_DHCP_SERVER_OFFLOAD_REQ to WDA!",
__func__);
vos_mem_free(dhcp_serv_info);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&mac->sme);
} else {
VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: sme_AcquireGlobalLock error!",
__func__);
vos_mem_free(dhcp_serv_info);
}
return status;
}
#endif /* DHCP_SERVER_OFFLOAD */
#ifdef MDNS_OFFLOAD
/**
* sme_set_mdns_offload() - sme API to set mdns offload enable/disable
* @hal: handle to hal pointer
* @mdns_info: pointer to mdns offload info
*
* Return - eHalStatus
*/
eHalStatus sme_set_mdns_offload(tHalHandle hal,
sir_mdns_offload_info_t *mdns_info)
{
vos_msg_t vos_msg;
sir_mdns_offload_info_t *mdns_offload;
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
mdns_offload = vos_mem_malloc(sizeof(*mdns_offload));
if (!mdns_offload) {
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;
}
vos_mem_copy(mdns_offload, mdns_info, sizeof(*mdns_offload));
mdns_offload->bss_idx =
peFindBssIdxFromSmeSessionId(mac, mdns_info->bss_idx);
status = sme_AcquireGlobalLock(&mac->sme);
if (eHAL_STATUS_SUCCESS == status) {
/* serialize the req through MC thread */
vos_msg.type = WDA_SET_MDNS_OFFLOAD_CMD;
vos_msg.bodyptr = mdns_offload;
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,
"%s: Not able to post WDA_SET_MDNS_OFFLOAD_CMD to WDA!",
__func__);
vos_mem_free(mdns_offload);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&mac->sme);
} else {
VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: sme_AcquireGlobalLock error!",
__func__);
vos_mem_free(mdns_offload);
}
return (status);
}
/**
* sme_set_mdns_fqdn() - SME API to set mDNS Fqdn info
* @hal: hal handle
* @mdns_fqdn: mDNS Fqdn info struct
*
* Return - return eHalStatus
*/
eHalStatus sme_set_mdns_fqdn(tHalHandle hal,
sir_mdns_fqdn_info_t *mdns_fqdn)
{
vos_msg_t vos_msg;
sir_mdns_fqdn_info_t *fqdn_info;
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
fqdn_info = vos_mem_malloc(sizeof(*fqdn_info));
if (!fqdn_info) {
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;
}
vos_mem_copy(fqdn_info, mdns_fqdn, sizeof(*fqdn_info));
fqdn_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_fqdn->bss_idx);
status = sme_AcquireGlobalLock(&mac->sme);
if (eHAL_STATUS_SUCCESS == status) {
/* serialize the req through MC thread */
vos_msg.type = WDA_SET_MDNS_FQDN_CMD;
vos_msg.bodyptr = fqdn_info;
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,
"%s: Not able to post WDA_SET_MDNS_FQDN_CMD to WDA!",
__func__);
vos_mem_free(fqdn_info);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&mac->sme);
} else {
VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: sme_AcquireGlobalLock error!",
__func__);
vos_mem_free(fqdn_info);
}
return (status);
}
/**
* sme_set_mdns_resp() - SME API to set mDNS response info
* @hal: hal handle
* @mdns_resp : mDNS response info struct
*
* Return - eHalStatus
*/
eHalStatus sme_set_mdns_resp(tHalHandle hal,
sir_mdns_resp_info_t *mdns_resp)
{
vos_msg_t vos_msg;
sir_mdns_resp_info_t *resp_info;
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal mac = PMAC_STRUCT(hal);
resp_info = vos_mem_malloc(sizeof(*resp_info));
if (!resp_info) {
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;
}
vos_mem_copy(resp_info, mdns_resp, sizeof(*resp_info));
resp_info->bss_idx = peFindBssIdxFromSmeSessionId(mac, mdns_resp->bss_idx);
status = sme_AcquireGlobalLock(&mac->sme);
if (eHAL_STATUS_SUCCESS == status) {
/* serialize the req through MC thread */
vos_msg.type = WDA_SET_MDNS_RESPONSE_CMD;
vos_msg.bodyptr = resp_info;
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,
"%s: Not able to post WDA_SET_MDNS_RESPONSE_CMD to WDA!",
__func__);
vos_mem_free(resp_info);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&mac->sme);
} else {
VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: sme_AcquireGlobalLock error!",
__func__);
vos_mem_free(resp_info);
}
return (status);
}
#endif /* MDNS_OFFLOAD */
/**
* sme_update_hb_threshold() - Set heartbeat Threshold value.
* @hal: HAL pointer
* @cfgId: cfg param id
* @hbThresh: heartbeat threshold value.
*
* Return: Success/Failure
*/
eHalStatus sme_update_hb_threshold(tHalHandle hHal, tANI_U32 cfgId,
tANI_U8 hbThresh, eCsrBand eBand)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
if ((hbThresh < WNI_CFG_HEART_BEAT_THRESHOLD_STAMIN) ||
(hbThresh > WNI_CFG_HEART_BEAT_THRESHOLD_STAMAX)) {
smsLog(pMac, LOGE, FL("invalid heartbeat threshold %hhu"), hbThresh);
return eHAL_STATUS_FAILURE;
}
if(eBand == eCSR_BAND_24)
pMac->roam.configParam.HeartbeatThresh24 = hbThresh;
if(eBand == eCSR_BAND_5G)
pMac->roam.configParam.HeartbeatThresh50 = hbThresh;
status = sme_update_cfg_int_param(hHal, WNI_CFG_HEART_BEAT_THRESHOLD);
if (eHAL_STATUS_SUCCESS != status) {
smsLog(pMac, LOGE, FL("WLAN set heartbeat threshold FAILED"));
status = eHAL_STATUS_FAILURE;
}
return status;
}
#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_NOMEM;
}
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_E_FAILURE;
}
return VOS_STATUS_SUCCESS;
}
#endif /* WLAN_FEATURE_APFIND */
/**
* sme_capture_tsf_req() - send tsf capture request to firmware
* @hHal: hal handle.
* @cap_tsf_params: capture tsf request params.
*
* Return: hal status.
*/
eHalStatus sme_capture_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tpSirCapTsfParams tsf_params = NULL;
VOS_STATUS vos_status;
tCsrRoamSession *pSession;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_HDD_CAP_TSF_REQ, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme)))
{
pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id);
if (!pSession)
{
smsLog(pMac, LOGE, FL("session %d not found"),
cap_tsf_params.bss_idx);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
tsf_params = (tpSirCapTsfParams)
vos_mem_malloc(sizeof(*tsf_params));
if (NULL == tsf_params)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for sme_capture_tsf_req",
__func__);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid,
sizeof(tsf_params->bssid));
tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func;
tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx;
/* serialize the req through MC thread */
/* TODO: check if callback is required */
vosMessage.bodyptr = tsf_params;
vosMessage.type = eWNI_SME_CAP_TSF_REQ;
vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
if (!VOS_IS_STATUS_SUCCESS(vos_status))
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Post Set TM Level MSG fail", __func__);
vos_mem_free(tsf_params);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return(status);
}
eHalStatus sme_del_sta_ba_session_req(tHalHandle hHal,
tDelBaParams sta_del_params)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
ptDelBaParams del_params = NULL;
VOS_STATUS vos_status;
tCsrRoamSession *pSession;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_DEL_STA_BA_SESSION_REQ, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == ( status = sme_AcquireGlobalLock(&pMac->sme)))
{
pSession = CSR_GET_SESSION(pMac, sta_del_params.session_id);
if (!pSession)
{
smsLog(pMac, LOGE, FL("session not found"));
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
del_params = (ptDelBaParams) vos_mem_malloc(sizeof(*del_params));
if (NULL == del_params)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for sme_del_sta_ba_session_req", __func__);
sme_ReleaseGlobalLock( &pMac->sme );
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(&del_params->session_id, &pSession->sessionId,
sizeof(del_params->session_id));
vosMessage.bodyptr = del_params;
vosMessage.type = eWNI_SME_DEL_BA_SES_REQ;
vos_status = vos_mq_post_message(VOS_MQ_ID_PE, &vosMessage);
if (!VOS_IS_STATUS_SUCCESS(vos_status))
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Post Set TM Level MSG fail", __func__);
vos_mem_free(del_params);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock( &pMac->sme );
}
return(status);
}
/**
* sme_get_tsf_req() - send tsf get request to firmware
* @hHal: hal handle.
* @cap_tsf_params: capture tsf request params.
*
* Return: hal status.
*/
eHalStatus sme_get_tsf_req(tHalHandle hHal, tSirCapTsfParams cap_tsf_params)
{
eHalStatus status = eHAL_STATUS_SUCCESS;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
vos_msg_t vosMessage;
tpSirCapTsfParams tsf_params = NULL;
VOS_STATUS vosStatus;
tCsrRoamSession *pSession;
MTRACE(vos_trace(VOS_MODULE_ID_SME,
TRACE_CODE_SME_TX_HDD_GET_TSF_REQ, NO_SESSION, 0));
if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme)))
{
pSession = CSR_GET_SESSION(pMac, cap_tsf_params.session_id);
if (!pSession)
{
smsLog(pMac, LOGE, FL("session %d not found"),
cap_tsf_params.bss_idx);
sme_ReleaseGlobalLock(&pMac->sme);
return eHAL_STATUS_FAILURE;
}
tsf_params = (tpSirCapTsfParams)
vos_mem_malloc(sizeof(*tsf_params));
if (NULL == tsf_params)
{
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
"%s: Not able to allocate memory for sme_capture_tsf_req",
__func__);
sme_ReleaseGlobalLock(&pMac->sme);
return eHAL_STATUS_FAILURE;
}
vos_mem_copy(&tsf_params->bssid, &pSession->connectedProfile.bssid,
sizeof(tsf_params->bssid));
tsf_params->tsf_rsp_cb_func = cap_tsf_params.tsf_rsp_cb_func;
tsf_params->tsf_rsp_cb_ctx = cap_tsf_params.tsf_rsp_cb_ctx;
/* serialize the req through MC thread */
/* TODO: check if callback is required */
vosMessage.bodyptr = tsf_params;
vosMessage.type = eWNI_SME_GET_TSF_REQ;
vosStatus = vos_mq_post_message(VOS_MQ_ID_PE, &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(tsf_params);
status = eHAL_STATUS_FAILURE;
}
sme_ReleaseGlobalLock(&pMac->sme);
}
return(status);
}
VOS_STATUS sme_roam_csa_ie_request(tHalHandle hal, tCsrBssid bssid,
uint8_t new_chan, uint32_t phy_mode,
uint8_t sme_session_id)
{
VOS_STATUS status = VOS_STATUS_E_FAILURE;
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
uint8_t cb_mode = 0;
tCsrRoamSession *session;
session = CSR_GET_SESSION(mac_ctx, sme_session_id);
if (!session) {
smsLog(mac_ctx, LOGE, FL("session %d not found"), sme_session_id);
return VOS_STATUS_E_FAILURE;
}
status = sme_AcquireGlobalLock(&mac_ctx->sme);
if (VOS_IS_STATUS_SUCCESS(status)) {
if (CSR_IS_CHANNEL_5GHZ(new_chan)) {
sme_SelectCBMode(hal, phy_mode, new_chan,
eHT_MAX_CHANNEL_WIDTH);
cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
}
status = csr_roam_send_chan_sw_ie_request(mac_ctx, bssid,
new_chan, cb_mode);
sme_ReleaseGlobalLock(&mac_ctx->sme);
}
return status;
}
VOS_STATUS sme_roam_channel_change_req(tHalHandle hal, tCsrBssid bssid,
uint8_t new_chan, tCsrRoamProfile *profile,
uint8_t sme_session_id)
{
VOS_STATUS status;
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
uint8_t cb_mode = 0;
tCsrRoamSession *session;
session = CSR_GET_SESSION(mac_ctx, sme_session_id);
if (!session) {
smsLog(mac_ctx, LOGE, FL("session %d not found"), sme_session_id);
return VOS_STATUS_E_FAILURE;
}
status = sme_AcquireGlobalLock(&mac_ctx->sme);
if (VOS_IS_STATUS_SUCCESS(status)) {
if (CSR_IS_CHANNEL_5GHZ(new_chan)) {
sme_SelectCBMode(hal, profile->phyMode, new_chan,
eHT_MAX_CHANNEL_WIDTH);
cb_mode = mac_ctx->roam.configParam.channelBondingMode5GHz;
}
status = csr_roam_channel_change_req(mac_ctx, bssid, new_chan, cb_mode,
profile);
sme_ReleaseGlobalLock(&mac_ctx->sme);
}
return status;
}
v_TIME_t
sme_get_connect_strt_time(tHalHandle hal, uint8_t session_id)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
tCsrRoamSession *session;
if (!CSR_IS_SESSION_VALID(mac_ctx, session_id)) {
smsLog(mac_ctx, LOGE, FL("session id %d not valid"), session_id);
return vos_timer_get_system_time();
}
session = CSR_GET_SESSION(mac_ctx, session_id);
return session->connect_req_start_time;
}
void sme_request_imps(tHalHandle hal)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
csrScanStartIdleScan(mac_ctx);
}
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);
}
VOS_STATUS sme_process_msg_callback(tHalHandle hal, vos_msg_t *msg)
{
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
VOS_STATUS status = VOS_STATUS_E_FAILURE;
if (msg == NULL) {
smsLog(mac_ctx, LOGE, FL("Empty message for SME Msg callback"));
return status;
}
status = sme_ProcessMsg(hal, msg);
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);
}
/**
* 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_SAE
eHalStatus sme_handle_sae_msg(tHalHandle hal, uint8_t session_id,
uint8_t sae_status)
{
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_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", sae_msg->sae_status,
sae_msg->session_id);
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