blob: fe027c411c270a27ca3a9433426d10c2077ffcef [file] [log] [blame]
/*
* Copyright (c) 2012-2013, 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.
*/
/*
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*===========================================================================
W L A N S Y S T E M M O D U L E
DESCRIPTION
This file contains the system module that implements the 'exectution model'
in the Gen6 host software.
Copyright (c) 2008 QUALCOMM Incorporated. All Rights Reserved.
Qualcomm Confidential and Proprietary
===========================================================================*/
/*===========================================================================
EDIT HISTORY FOR FILE
This section contains comments describing changes made to the module.
Notice that changes are listed in reverse chronological order.
$Header:$ $DateTime: $ $Author: $
when who what, where, why
-------- --- -----------------------------------------------------
12/15/08 sho Resolved AMSS compiler errors and warnings when this
is being ported from WM
07/02/08 lac Added support for eWNI_SME_START_REQ/RSP in init seq
06/26/08 hba Added implementation of mbReceiveMBMsg()
06/26/08 lac Created module.
===========================================================================*/
#include <wlan_qct_sys.h>
#include <vos_api.h>
#include <sirTypes.h> // needed for tSirRetStatus
#include <sirParams.h> // needed for tSirMbMsg
#include <sirApi.h> // needed for SIR_... message types
#include <wniApi.h> // needed for WNI_... message types
#include "aniGlobal.h"
#include "wlan_qct_wda.h"
#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
#include <halCommonApi.h> // needed for halMmhPostMsgApi()
#endif
#include "sme_Api.h"
#include "macInitApi.h"
#ifndef WLAN_FTM_STUB
VOS_STATUS WLANFTM_McProcessMsg (v_VOID_t *message);
#endif
// Cookie for SYS messages. Note that anyone posting a SYS Message has to
// write the COOKIE in the reserved field of the message. The SYS Module
// relies on this COOKIE
#ifndef WLAN_FTM_STUB
#define SYS_MSG_ID_FTM_RSP 11
#define FTM_SYS_MSG_COOKIE 0xFACE
#endif
#define SYS_MSG_COOKIE ( 0xFACE )
// need to define FIELD_OFFSET for non-WM platforms
#ifndef FIELD_OFFSET
#define FIELD_OFFSET(x,y) offsetof(x,y)
#endif
VOS_STATUS sys_SendSmeStartReq( v_CONTEXT_t pVosContext );
// add this to the sys Context data... ?
typedef struct
{
sysResponseCback mcStartCB;
v_VOID_t * mcStartUserData;
} sysContextData;
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
// keep some static global sys context for the time being... Should we move this
// into 'context' data? Probably not, it doesn't need to be persistent except
// during this messaging sequence.
static sysContextData gSysContext;
#endif
static vos_event_t gStopEvt;
VOS_STATUS sysBuildMessageHeader( SYS_MSG_ID sysMsgId, vos_msg_t *pMsg )
{
pMsg->type = sysMsgId;
pMsg->reserved = SYS_MSG_COOKIE;
return( VOS_STATUS_SUCCESS );
}
VOS_STATUS sysOpen( v_CONTEXT_t pVosContext )
{
return( VOS_STATUS_SUCCESS );
}
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
VOS_STATUS sysMcStart( v_CONTEXT_t pVosContext, sysResponseCback userCallback, v_VOID_t *pUserData )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
vos_msg_t sysMsg;
sysBuildMessageHeader( SYS_MSG_ID_MC_START, &sysMsg );
// Save the user callback and user data to callback in the body pointer
// and body data portion of the message.
// finished.
sysMsg.bodyptr = (void *)userCallback;
sysMsg.bodyval = (v_U32_t)pUserData;
// post the message..
vosStatus = vos_mq_post_message( VOS_MQ_ID_SYS, &sysMsg );
if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
vosStatus = VOS_STATUS_E_BADMSG;
}
return( vosStatus );
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
v_VOID_t sysStopCompleteCb
(
v_VOID_t *pUserData
)
{
vos_event_t* pStopEvt = (vos_event_t *) pUserData;
VOS_STATUS vosStatus;
/*-------------------------------------------------------------------------*/
vosStatus = vos_event_set( pStopEvt );
VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) );
} /* vos_sys_stop_complete_cback() */
VOS_STATUS sysStop( v_CONTEXT_t pVosContext )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
vos_msg_t sysMsg;
v_U8_t evtIndex;
/* Initialize the stop event */
vosStatus = vos_event_init( &gStopEvt );
if(! VOS_IS_STATUS_SUCCESS( vosStatus ))
{
return vosStatus;
}
/* post a message to SYS module in MC to stop SME and MAC */
sysBuildMessageHeader( SYS_MSG_ID_MC_STOP, &sysMsg );
// Save the user callback and user data to callback in the body pointer
// and body data portion of the message.
// finished.
sysMsg.bodyptr = (void *)sysStopCompleteCb;
sysMsg.bodyval = (v_U32_t) &gStopEvt;
// post the message..
vosStatus = vos_mq_post_message( VOS_MQ_ID_SYS, &sysMsg );
if ( !VOS_IS_STATUS_SUCCESS(vosStatus) )
{
vosStatus = VOS_STATUS_E_BADMSG;
}
vosStatus = vos_wait_events( &gStopEvt, 1, 0, &evtIndex );
VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) );
vosStatus = vos_event_destroy( &gStopEvt );
VOS_ASSERT( VOS_IS_STATUS_SUCCESS ( vosStatus ) );
return( vosStatus );
}
VOS_STATUS sysClose( v_CONTEXT_t pVosContext )
{
return( VOS_STATUS_SUCCESS );
}
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
static VOS_STATUS sys_PostMcThreadProbeMsg( v_CONTEXT_t pVosContext, sysResponseCback userCallback,
v_VOID_t *pUserData, SYS_MSG_ID sysMsgId )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
vos_msg_t sysMsg;
tSirRetStatus sirStatus = eSIR_SUCCESS;
/*----------------------------------------------------------------------------------------*/
sysBuildMessageHeader( sysMsgId, &sysMsg );
// Save the user callback and user data to callback in the body pointer
// and body data portion of the message.
sysMsg.bodyptr = (void *)userCallback;
sysMsg.bodyval = (v_U32_t)pUserData;
// Post the message...
vosStatus = vos_mq_post_message( VOS_MQ_ID_SYS, &sysMsg );
if ( eSIR_SUCCESS != sirStatus )
{
vosStatus = VOS_STATUS_E_BADMSG;
}
return( vosStatus );
}
static VOS_STATUS sys_PostTxThreadProbeMsg( v_CONTEXT_t pVosContext, sysResponseCback userCallback,
v_VOID_t *pUserData, SYS_MSG_ID sysMsgId )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
vos_msg_t sysMsg;
tSirRetStatus sirStatus = eSIR_SUCCESS;
/*----------------------------------------------------------------------------------------*/
sysBuildMessageHeader( sysMsgId, &sysMsg );
// Save the user callback and user data to callback in the body pointer
// and body data portion of the message.
sysMsg.bodyptr = (void *)userCallback;
sysMsg.bodyval = (v_U32_t)pUserData;
// Post the message...
vosStatus = vos_tx_mq_serialize( VOS_MQ_ID_SYS, &sysMsg );
if ( eSIR_SUCCESS != sirStatus )
{
vosStatus = VOS_STATUS_E_BADMSG;
}
return( vosStatus );
}
v_VOID_t sysMcThreadProbe( v_CONTEXT_t pVosContext, sysResponseCback userCallback,
v_VOID_t *pUserData )
{
VOS_STATUS vosStatus;
vosStatus = sys_PostMcThreadProbeMsg( pVosContext, userCallback, pUserData,
SYS_MSG_ID_MC_THR_PROBE );
if (VOS_IS_STATUS_SUCCESS( vosStatus ))
{
// we could have place the above condition within VOS_ASSERT, but
// unfortunately that would cause a compiler warning
VOS_ASSERT( 1 );
}
// !! no way to fail ??
}
v_VOID_t sysTxThreadProbe( v_CONTEXT_t pVosContext, sysResponseCback userCallback,
v_VOID_t *pUserData )
{
VOS_STATUS vosStatus;
vosStatus = sys_PostTxThreadProbeMsg( pVosContext, userCallback, pUserData,
SYS_MSG_ID_TX_THR_PROBE );
if (VOS_IS_STATUS_SUCCESS( vosStatus ))
{
// we could have place the above condition within VOS_ASSERT, but
// unfortunately that would cause a compiler warning
VOS_ASSERT( 1 );
}
// !! no way to fail ??
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
static VOS_STATUS sys_SendHalInitStartReqMsg( v_CONTEXT_t pVosContext )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tSirMbMsg msg;
tSirRetStatus sirStatus = eSIR_SUCCESS;
tSirMbMsg *pMsg = &msg;
v_VOID_t *hHal;
do
{
// get the HAL context...
hHal = vos_get_context( VOS_MODULE_ID_HAL, pVosContext );
if ( NULL == hHal ) break;
// format the Init start request message. This message has
// the hal handle in the 'data' portion of the message.
pMsg->type = WDA_INIT_START_REQ;
pMsg->data[0] = (tANI_U32)hHal;
// message length is 4 greater than the config data size
// need to add in an extra 4 for the message header.
pMsg->msgLen = sizeof( tHalHandle ) + FIELD_OFFSET( tSirMbMsg, data );
// Send the HAL Init Start Request message...
sirStatus = uMacPostCtrlMsg( hHal, pMsg );
if ( eSIR_SUCCESS != sirStatus )
{
vosStatus = VOS_STATUS_E_FAILURE;
}
} while( 0 );
return( vosStatus );
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK)
#pragma pack( push )
#pragma pack( 1 )
#elif defined(__ANI_COMPILER_PRAGMA_PACK)
#pragma pack( 1 )
#endif
typedef struct sPolFileVersion
{
unsigned char MajorVersion;
unsigned char MinorVersion;
unsigned char Suffix;
unsigned char Build;
} tPolFileVersion;
typedef struct sPolFileHeader
{
tPolFileVersion FileVersion;
tPolFileVersion HWCapabilities;
unsigned long FileLength;
unsigned long NumDirectoryEntries;
} tPolFileHeader;
typedef enum ePolFileDirTypes
{
ePOL_DIR_TYPE_BOOTLOADER = 0,
ePOL_DIR_TYPE_STA_FIRMWARE,
ePOL_DIR_TYPE_AP_FIRMWARE,
ePOL_DIR_TYPE_DIAG_FIRMWARE,
ePOL_DIR_TYPE_STA_CONFIG,
ePOL_DIR_TYPE_AP_CONFIG
} tPolFileDirTypes;
typedef struct sPolFileDirEntry
{
unsigned long DirEntryType;
unsigned long DirEntryFileOffset;
unsigned long DirEntryLength;
} tPolFileDirEntry;
#if defined(__ANI_COMPILER_PRAGMA_PACK_STACK)
#pragma pack( pop )
#endif
static unsigned short polFileChkSum( unsigned short *FileData, unsigned long NumWords )
{
unsigned long Sum;
for ( Sum = 0; NumWords > 0; NumWords-- )
{
Sum += *FileData++;
}
Sum = (Sum >> 16) + (Sum & 0xffff); // add carry
Sum += (Sum >> 16); // maybe last unsigned short
return( (unsigned short)( ~Sum ) );
}
#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
static v_BOOL_t sys_validateStaConfig( void *pImage, unsigned long cbFile,
void **ppStaConfig, v_SIZE_t *pcbStaConfig )
#else
v_BOOL_t sys_validateStaConfig( void *pImage, unsigned long cbFile,
void **ppStaConfig, v_SIZE_t *pcbStaConfig )
#endif
{
v_BOOL_t fFound = VOS_FALSE;
tPolFileHeader *pFileHeader = NULL;
tPolFileDirEntry *pDirEntry = NULL;
v_U32_t idx;
do
{
// Compute the checksum before bothering to copy...
if ( polFileChkSum( ( v_U16_t *)pImage, cbFile / sizeof( v_U16_t ) ) )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Failed to validate the checksum for CFG binary" );
break;
}
pFileHeader = (tPolFileHeader *)pImage;
*ppStaConfig = NULL;
*pcbStaConfig = 0;
pDirEntry = ( tPolFileDirEntry* ) ( pFileHeader + 1 );
for ( idx = 0; idx < pFileHeader->NumDirectoryEntries; ++idx )
{
if ( ePOL_DIR_TYPE_STA_CONFIG == pDirEntry[ idx ].DirEntryType )
{
*ppStaConfig = pDirEntry[ idx ].DirEntryFileOffset + ( v_U8_t * )pFileHeader;
*pcbStaConfig = pDirEntry[ idx ].DirEntryLength;
break;
}
} // End iteration over the header's entries
if ( NULL != *ppStaConfig )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_LOW,
"Found the Station CFG in the CFG binary!!" );
fFound = VOS_TRUE;
}
else
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Failed to find Station CFG in the CFG binary" );
}
} while( 0 );
VOS_ASSERT( VOS_TRUE == fFound );
return( fFound );
}
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
static v_U8_t _vImageArray[15000];
static VOS_STATUS sys_getCfgBinaryMsgBuffer( tSirMbMsg **ppMsg, v_SIZE_t *pcbCfgBinary )
{
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
v_VOID_t *pFileImage = NULL;
v_SIZE_t cbFileImage = 0;
v_VOID_t *pCfgBinary = NULL;
v_SIZE_t cbCfgBinary = 0;
v_BOOL_t bStatus = VOS_FALSE;
do
{
// get the number of bytes in the CFG Binary...
vosStatus = vos_get_binary_blob( VOS_BINARY_ID_CONFIG, NULL, &cbFileImage );
if ( VOS_STATUS_E_NOMEM != vosStatus )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Error obtaining binary size" );
break;
}
// malloc a buffer to read in the Configuration binary file.
//pFileImage = vos_mem_malloc( cbFileImage );
pFileImage = (v_VOID_t*)_vImageArray;
if ( NULL == pFileImage )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Unable to allocate memory for the CFG binary [size= %d bytes]",
cbFileImage );
vosStatus = VOS_STATUS_E_NOMEM;
break;
}
// Get the entire CFG file image...
vosStatus = vos_get_binary_blob( VOS_BINARY_ID_CONFIG, pFileImage, &cbFileImage );
if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Error: Cannot retrieve CFG fine image from vOSS. [size= %d bytes]",
cbFileImage );
break;
}
// Validate the binary image. This function will return a pointer and length
// where the CFG binary is located within the binary image file.
bStatus = sys_validateStaConfig( pFileImage, cbFileImage,
&pCfgBinary, &cbCfgBinary );
if ( VOS_FALSE == bStatus )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Error: Cannot find STA CFG in binary image fileze" );
vosStatus = VOS_STATUS_E_FAILURE;
break;
}
// caller wants to know the size of the cfg Binary. Return it.
*pcbCfgBinary = cbCfgBinary;
// To build the CFG download message, we need build a buffer that includes the
// tSirMbMsg header followed by the CFG data. So allocate enough space for the
// CFG binary plus the message header.
//
// This buffer (the tSir message) is returned to the caller...
*ppMsg = vos_mem_malloc( cbCfgBinary + FIELD_OFFSET( tSirMbMsg, data ) );
if ( NULL == *ppMsg )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Unable to allocate memory for the CFG download message "
"buffer [size= %d bytes]",
cbCfgBinary + FIELD_OFFSET( tSirMbMsg, data ) );
vosStatus = VOS_STATUS_E_NOMEM;
break;
}
// copy the CFG binary data into the CFG download message buffer...
vos_mem_copy( (v_VOID_t *)( ( *ppMsg )->data ), pCfgBinary , cbCfgBinary );
// if we get here, we have succeeded!
vosStatus = VOS_STATUS_SUCCESS;
} while( 0 );
// Always need to free the buffer where the binary image file was
// temporarily read...
if ( NULL == pFileImage )
{
// vos_mem_free( pFileImage );
}
// If failed and we have already allocated the memory for the CFG
// binary download message, need to free that memory. If succeeded,
// the caller is going to free this memory when it is done sending
// the message.
if ( ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) && ( NULL != *ppMsg ) )
{
vos_mem_free( *ppMsg );
*ppMsg = NULL;
*pcbCfgBinary = 0;
}
return( vosStatus );
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
static VOS_STATUS sys_SendWniCfgDnldMsg( v_CONTEXT_t pVosContext )
{
VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
tSirRetStatus sirStatus = eSIR_SUCCESS;
tSirMbMsg *pMsg = NULL;
v_VOID_t *hHal = NULL;
v_SIZE_t cbCfgBinary = 0;
do
{
hHal = vos_get_context( VOS_MODULE_ID_HAL, pVosContext );
if ( NULL == hHal ) break;
vosStatus = sys_getCfgBinaryMsgBuffer( &pMsg, &cbCfgBinary );
if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) break;
pMsg->type = WNI_CFG_DNLD_RSP;
// message length is 4 greater than the config data size
// need to add in an extra 4 for the message header.
pMsg->msgLen = (tANI_U16)( cbCfgBinary + FIELD_OFFSET( tSirMbMsg, data ) );
sirStatus = halMmhForwardMBmsg( hHal, pMsg );
if ( eSIR_SUCCESS != sirStatus )
{
vosStatus = VOS_STATUS_E_FAILURE;
}
vos_mem_free(pMsg);
} while( 0 );
return( vosStatus );
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
VOS_STATUS sys_SendSmeStartReq( v_CONTEXT_t pVosContext )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
tSirSmeStartReq msg;
tSirRetStatus sirStatus = eSIR_SUCCESS;
tSirSmeStartReq *pMsg = &msg;
v_VOID_t *hHal;
do
{
// get the HAL context...
hHal = vos_get_context( VOS_MODULE_ID_HAL, pVosContext );
if ( NULL == hHal ) break;
// format the Sme Start Request message. This message has
// the hal handle in the 'data' portion of the message.
pMsg->messageType = eWNI_SME_START_REQ;
pMsg->length = sizeof( msg );
pMsg->roamingAtPolaris = 0;
pMsg->sendNewBssInd = 0;
// Send the HAL Init Start Request message...
sirStatus = halMmhForwardMBmsg( hHal, (tSirMbMsg *)pMsg );
if ( eSIR_SUCCESS != sirStatus )
{
vosStatus = VOS_STATUS_E_FAILURE;
}
} while( 0 );
return( vosStatus );
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
VOS_STATUS sysMcProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
v_VOID_t *hHal;
VOS_ASSERT( pMsg );
// All 'new' SYS messages are identified by a cookie in the reserved
// field of the message as well as the message type. This prevents
// the possibility of overlap in the message types defined for new
// SYS messages with the 'legacy' message types. The legacy messages
// will not have this cookie in the reserved field
if ( SYS_MSG_COOKIE == pMsg->reserved )
{
// Process all the new SYS messages..
switch( pMsg->type )
{
case SYS_MSG_ID_MC_START:
{
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
// save the callback pointer and user data in the context
// data
gSysContext.mcStartCB = (sysResponseCback)pMsg->bodyptr;
gSysContext.mcStartUserData= (v_VOID_t *)pMsg->bodyval;
// Trigger the CFG download sequence by sending the
// SIR_HAL_INIT_START_REQ message to the mac module.
vosStatus = sys_SendHalInitStartReqMsg( pVosContext );
#else
/* Handling for this message is not needed now so adding
*debug print and VOS_ASSERT*/
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
" Received SYS_MSG_ID_MC_START message msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
VOS_ASSERT(0);
#endif
break;
}
case SYS_MSG_ID_MC_STOP:
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"Processing SYS MC STOP" );
// get the HAL context...
hHal = vos_get_context( VOS_MODULE_ID_PE, pVosContext );
if (NULL == hHal)
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"%s: Invalid hHal", __func__ );
}
else
{
vosStatus = sme_Stop( hHal, TRUE );
VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
vosStatus = macStop( hHal, HAL_STOP_TYPE_SYS_DEEP_SLEEP );
VOS_ASSERT( VOS_IS_STATUS_SUCCESS( vosStatus ) );
((sysResponseCback)pMsg->bodyptr)((v_VOID_t *)pMsg->bodyval);
vosStatus = VOS_STATUS_SUCCESS;
}
break;
}
// Process MC thread probe. Just callback to the
// function that is in the message.
case SYS_MSG_ID_MC_THR_PROBE:
{
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
sysResponseCback callback;
// Make a callback to the function based on the info
// in the message (callback is in bodyptr and user
// data is in bodyval)
callback = (sysResponseCback)pMsg->bodyptr;
callback( (v_VOID_t *)pMsg->bodyval );
#else
/* Handling for this message is not needed now so adding
*debug print and VOS_ASSERT*/
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
" Received SYS_MSG_ID_MC_THR_PROBE message msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
VOS_ASSERT(0);
#endif
break;
}
case SYS_MSG_ID_MC_TIMER:
{
vos_timer_callback_t timerCB;
// hummmm... note says...
// invoke the timer callback and the user data stick
// into the bodyval; no body to free. I think this is
// what that means.
timerCB = (vos_timer_callback_t)pMsg->bodyptr;
// make the callback to the timer routine...
timerCB( (v_VOID_t *)pMsg->bodyval );
break;
}
#ifndef WLAN_FTM_STUB
case SYS_MSG_ID_FTM_RSP:
{
WLANFTM_McProcessMsg((v_VOID_t *)pMsg->bodyptr);
break;
}
#endif
default:
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Unknown message type in sysMcProcessMsg() msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
break;
}
} // end switch on message type
} // end if cookie set
else
{
// Process all 'legacy' messages
switch( pMsg->type )
{
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
/* Handling for these messages are not needed now. If a request comes for
these messages they will goto default and give VOS_ASSERT*/
case WDA_APP_SETUP_NTF:
{
// we get this message after we send SIR_HAL_INIT_START_REQ but
// we have nothing to do. This one is safely ignored. Following
// this message we will get the WNI_CFG_DNLD_REQ from where we need
// to give the Configuration data back.
break;
}
case WNI_CFG_DNLD_REQ:
{
// This is the request from the MAC to download the configuration
// data. Format and send the Cfg Download to the MAC.
vosStatus = sys_SendWniCfgDnldMsg( pVosContext );
if (pMsg->bodyptr)
vos_mem_free(pMsg->bodyptr);
break;
}
case WNI_CFG_DNLD_CNF:
{
tSirMbMsg *pSirMsg = (tSirMbMsg *)pMsg->bodyptr;
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"WNI_CFG_DNLD_CNF message received with status code= %d [0x%08lX]",
pSirMsg->data[0], pSirMsg->data[0] );
// Config download confirm contains a tANI_U32 status in the 'data' field
// of the WNI message. Not sure we can do anything with this since we
// don't have a way to send a status to the waiting thread.
if ( WNI_CFG_SUCCESS == pSirMsg->data[ 0 ] )
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"WNI_CFG_DNLD_CNF received with successful status" );
}
else
{
// What to do if the CFG Download fails? We have the MC thread
// blocked waiting for a calback to unblock but we don't have
// a way to convey success / failure to the MC thread??
VOS_ASSERT( 0 );
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"WNI_CFG_DNLD_CNF received with status= %d [0x%08lX]",
pSirMsg->data[ 0 ], pSirMsg->data[ 0 ] );
}
if (pMsg->bodyptr)
vos_mem_free(pMsg->bodyptr);
break;
}
case WDA_NIC_OPER_NTF:
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"WDA_NIC_OPER_NTF message received" );
// This is the NIC Operational Notify message that comes to the
// SYS module from HAL after the Configuration download is complete.
// This message comes *after* the WNI_CFG_DNLD_CNF message
// comes to SYS from the CFG module, also at the end of CFG
// download. In response to this message, SYS has to respond with
// request from the MAC to download the configuration
// data. Format and send the Cfg Download to the MAC.
vosStatus = sys_SendSmeStartReq( pVosContext );
if (pMsg->bodyptr)
vos_mem_free(pMsg->bodyptr);
break;
}
case eWNI_SME_START_RSP:
{
tSirSmeRsp *pSirSmeRspMsg = (tSirSmeRsp *)pMsg->bodyptr;
#ifdef WLAN_DEBUG
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"eWNI_SME_START_RSP received with status code= %d [0x%08lX]",
pSirSmeRspMsg->statusCode, pSirSmeRspMsg->statusCode );
#endif
// Make a callback to the Main Controller start callback routine when
// the CFG sequence is finished... (this is the confirmation message
// from the MAC that the CFG sequence is completed).
if ( gSysContext.mcStartCB )
{
gSysContext.mcStartCB( gSysContext.mcStartUserData );
}
if (pMsg->bodyptr)
vos_mem_free(pMsg->bodyptr);
break;
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
default:
{
VOS_ASSERT( 0 );
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Received SYS message cookie with unidentified "
"MC message type= %d [0x%08lX]", pMsg->type, pMsg->type );
vosStatus = VOS_STATUS_E_BADMSG;
if (pMsg->bodyptr)
vos_mem_free(pMsg->bodyptr);
break;
}
} // end switch on pMsg->type
} // end else
return( vosStatus );
}
VOS_STATUS sysTxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
VOS_ASSERT( pMsg );
// All 'new' SYS messages are identified by a cookie in the reserved
// field of the message as well as the message type. This prevents
// the possibility of overlap in the message types defined for new
// SYS messages with the 'legacy' message types. The legacy messages
// will not have this cookie in the reserved field
if ( SYS_MSG_COOKIE == pMsg->reserved )
{
// Process all the new SYS messages..
switch( pMsg->type )
{
// Process TX thread probe. Just callback to the
// function that is in the message.
case SYS_MSG_ID_TX_THR_PROBE:
{
#if defined( FEATURE_WLAN_NON_INTEGRATED_SOC )
sysResponseCback callback;
// Make a callback to the function based on the info
// in the message (callback is in bodyptr and user
// data is in bodyval)
callback = (sysResponseCback)pMsg->bodyptr;
callback( (v_VOID_t *)pMsg->bodyval );
#else
/* Handling for this message is not needed now so adding
* debug print and VOS_ASSERT*/
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
" Received SYS_MSG_ID_TX_THR_PROBE message msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
VOS_ASSERT(0);
#endif
break;
}
case SYS_MSG_ID_TX_TIMER:
{
vos_timer_callback_t timerCB;
// hummmm... note says...
// invoke the timer callback and the user data stick
// into the bodyval; no body to free. I think this is
// what that means.
timerCB = (vos_timer_callback_t)pMsg->bodyptr;
// make the callback to the timer routine...
timerCB( (v_VOID_t *)pMsg->bodyval );
break;
}
default:
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Unknown message type in sysTxProcessMsg() msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
break;
}
} // end switch on message type
} // end if cookie set
else
{
VOS_ASSERT( 0 );
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Received SYS message cookie with unidentified TX message "
" type= %d [0x%08lX]", pMsg->type, pMsg->type );
vosStatus = VOS_STATUS_E_BADMSG;
} // end else
return( vosStatus );
}
#ifdef FEATURE_WLAN_INTEGRATED_SOC
VOS_STATUS sysRxProcessMsg( v_CONTEXT_t pVosContext, vos_msg_t *pMsg )
{
VOS_STATUS vosStatus = VOS_STATUS_SUCCESS;
VOS_ASSERT( pMsg );
// All 'new' SYS messages are identified by a cookie in the reserved
// field of the message as well as the message type. This prevents
// the possibility of overlap in the message types defined for new
// SYS messages with the 'legacy' message types. The legacy messages
// will not have this cookie in the reserved field
if ( SYS_MSG_COOKIE == pMsg->reserved )
{
// Process all the new SYS messages..
switch( pMsg->type )
{
case SYS_MSG_ID_RX_TIMER:
{
vos_timer_callback_t timerCB;
// hummmm... note says...
// invoke the timer callback and the user data stick
// into the bodyval; no body to free. I think this is
// what that means.
timerCB = (vos_timer_callback_t)pMsg->bodyptr;
// make the callback to the timer routine...
timerCB( (v_VOID_t *)pMsg->bodyval );
break;
}
default:
{
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Unknown message type in sysRxProcessMsg() msgType= %d [0x%08lx]",
pMsg->type, pMsg->type );
break;
}
} // end switch on message type
} // end if cookie set
else
{
VOS_ASSERT( 0 );
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Received SYS message cookie with unidentified RX message "
" type= %d [0x%08lX]", pMsg->type, pMsg->type );
vosStatus = VOS_STATUS_E_BADMSG;
} // end else
return( vosStatus );
}
#endif
v_VOID_t sysMcFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg )
{
return;
}
v_VOID_t sysTxFreeMsg( v_CONTEXT_t pVContext, vos_msg_t* pMsg )
{
return;
}
void
SysProcessMmhMsg
(
tpAniSirGlobal pMac,
tSirMsgQ* pMsg
)
{
VOS_MQ_ID targetMQ = VOS_MQ_ID_SYS;
/*-------------------------------------------------------------------------*/
/*
** The body of this pMsg is a tSirMbMsg
** Contrary to Gen4, we cannot free it here!
** It is up to the callee to free it
*/
VOS_ASSERT(NULL != pMsg);
switch (pMsg->type)
{
/*
** Following messages are routed to SYS
*/
case WNI_CFG_DNLD_REQ:
case WNI_CFG_DNLD_CNF:
case WDA_APP_SETUP_NTF:
case WDA_NIC_OPER_NTF:
case WDA_RESET_REQ:
case eWNI_SME_START_RSP:
{
/* Forward this message to the SYS module */
targetMQ = VOS_MQ_ID_SYS;
#if defined( FEATURE_WLAN_INTEGRATED_SOC )
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Handling for the Message ID %d is removed in SYS\r\n",
pMsg->type);
VOS_ASSERT(0);
#endif /* FEATURE_WLAN_INTEGRATED_SOC */
break;
}
/*
** Following messages are routed to HAL
*/
case WNI_CFG_DNLD_RSP:
case WDA_INIT_START_REQ:
{
/* Forward this message to the HAL module */
targetMQ = VOS_MQ_ID_WDA;
#if defined ( FEATURE_WLAN_INTEGRATED_SOC )
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Handling for the Message ID %d is removed as there is no HAL \r\n",
pMsg->type);
VOS_ASSERT(0);
#endif /* FEATURE_WLAN_INTEGRATED_SOC */
break;
}
case eWNI_SME_START_REQ:
case WNI_CFG_GET_REQ:
case WNI_CFG_SET_REQ:
case WNI_CFG_SET_REQ_NO_RSP:
case eWNI_SME_SYS_READY_IND:
{
/* Forward this message to the PE module */
targetMQ = VOS_MQ_ID_PE;
break;
}
case WNI_CFG_GET_RSP:
case WNI_CFG_SET_CNF:
/* case eWNI_SME_DISASSOC_RSP:
case eWNI_SME_STA_STAT_RSP:
case eWNI_SME_AGGR_STAT_RSP:
case eWNI_SME_GLOBAL_STAT_RSP:
case eWNI_SME_STAT_SUMM_RSP:
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_ENTER_UAPSD_RSP:
case eWNI_PMC_EXIT_UAPSD_RSP:
case eWNI_PMC_ENTER_WOWL_RSP:
case eWNI_PMC_EXIT_WOWL_RSP:
case eWNI_SME_SWITCH_CHL_REQ: */ //Taken care by the check in default case
{
/* Forward this message to the SME module */
targetMQ = VOS_MQ_ID_SME;
break;
}
default:
{
if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) && ( pMsg->type <= eWNI_SME_MSG_TYPES_END ) )
{
targetMQ = VOS_MQ_ID_SME;
break;
}
VOS_TRACE( VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Message of ID %d is not yet handled by SYS\r\n",
pMsg->type);
VOS_ASSERT(0);
}
}
/*
** Post now the message to the appropriate module for handling
*/
if(VOS_STATUS_SUCCESS != vos_mq_post_message(targetMQ, (vos_msg_t*)pMsg))
{
//Caller doesn't allocate memory for the pMsg. It allocate memory for bodyptr
/* free the mem and return */
if(pMsg->bodyptr)
{
palFreeMemory( pMac->hHdd, pMsg->bodyptr);
}
}
} /* SysProcessMmhMsg() */
#ifndef WLAN_FTM_STUB
/*==========================================================================
FUNCTION WLAN_FTM_SYS_FTM
DESCRIPTION
Called by VOSS to free a given FTM message on the Main thread when there
are messages pending in the queue when the whole system is been reset.
DEPENDENCIES
FTM must be initialized before this function can be called.
PARAMETERS
IN
pvosGCtx: pointer to the global vos context; a handle to FTM's
control block can be extracted from its context
message: type and content of the message
RETURN VALUE
The result code associated with performing the operation
VOS_STATUS_SUCCESS:
SIDE EFFECTS
NONE
============================================================================*/
void wlan_sys_ftm(void *pMsgPtr)
{
vos_msg_t vosMessage;
vosMessage.reserved = FTM_SYS_MSG_COOKIE;
vosMessage.type = SYS_MSG_ID_FTM_RSP;
vosMessage.bodyptr = pMsgPtr;
vos_mq_post_message(VOS_MQ_ID_SYS, &vosMessage);
return;
}
#endif /* ANI_MANF_DIAG */