blob: 78526678063b8bd33e9e3c05daa3bd10e9f09068 [file] [log] [blame]
/*
* Copyright (c) 2012-2013, 2016 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 VossWrapper.c
@brief This source file contains the various function definitions for the
RTOS abstraction layer, implemented for VOSS
===========================================================================*/
/*===========================================================================
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
-------- --- --------------------------------------------------------
03/31/09 sho Remove the use of vosTimerIsActive flag as it is not
thread-safe
02/17/08 sho Fix the timer callback function to work when it is called
after the timer has stopped due to a race condition.
02/10/08 sho Refactor the TX timer to use VOS timer directly instead
of using VOS utility timer
12/15/08 sho Resolved errors and warnings from the AMSS compiler when
this is ported from WM
11/20/08 sho Renamed this to VosWrapper.c; remove all dependencies on
WM platform and allow this to work on all VOSS enabled
platform
06/24/08 tbh Modified the file to remove the dependecy on HDD files as
part of Gen6 bring up process.
10/29/02 Neelay Das Created file.
===========================================================================*/
/*---------------------------------------------------------------------------
* Include Files
* ------------------------------------------------------------------------*/
#include "VossWrapper.h"
#ifdef WLAN_DEBUG
#define TIMER_NAME (timer_ptr->timerName)
#else
#define TIMER_NAME "N/A"
#endif
/**---------------------------------------------------------------------
* tx_time_get()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return current system time in units of miliseconds
*
*/
v_ULONG_t tx_time_get( void )
{
return(vos_timer_get_system_ticks());
} //* tx_time_get()
/**---------------------------------------------------------------------
* tx_timer_activate()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return TX_SUCCESS.
*
*/
v_UINT_t tx_timer_activate(TX_TIMER *timer_ptr)
{
VOS_STATUS status;
// Uncomment the asserts, if the intention is to debug the occurence of the
// following anomalous cnditions.
// Assert that the timer structure pointer passed, is not NULL
//dbgAssert(NULL != timer_ptr);
// If the NIC is halting just spoof a successful timer activation, so that all
// the timers can be cleaned up.
if(NULL == timer_ptr)
return TX_TIMER_ERROR;
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
VOS_ASSERT( timer_ptr->tmrSignature == 0 );
return TX_TIMER_ERROR;
}
// Check for an uninitialized timer
VOS_ASSERT(0 != strlen(TIMER_NAME));
status = vos_timer_start( &timer_ptr->vosTimer,
timer_ptr->initScheduleTimeInMsecs );
if (VOS_STATUS_SUCCESS == status)
{
return TX_SUCCESS;
}
else if (VOS_STATUS_E_ALREADY == status)
{
// starting timer fails because timer is already started; this is okay
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"Timer %s is already running\n", TIMER_NAME);
return TX_SUCCESS;
}
else
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Timer %s fails to activate\n", TIMER_NAME);
return TX_TIMER_ERROR;
}
} /*** tx_timer_activate() ***/
/**---------------------------------------------------------------------
* tx_timer_change()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return TX_SUCCESS.
*
*/
v_UINT_t tx_timer_change(TX_TIMER *timer_ptr,
v_ULONG_t initScheduleTimeInTicks, v_ULONG_t rescheduleTimeInTicks)
{
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
VOS_ASSERT( timer_ptr->tmrSignature == 0 );
return TX_TIMER_ERROR;
}
// changes cannot be applied until timer stops running
if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer))
{
timer_ptr->initScheduleTimeInMsecs = TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
timer_ptr->rescheduleTimeInMsecs = TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
return TX_SUCCESS;
}
else
{
return TX_TIMER_ERROR;
}
} /*** tx_timer_change() ***/
/**---------------------------------------------------------------------
* tx_timer_change_context()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return TX_SUCCESS.
*
*/
v_UINT_t tx_timer_change_context(TX_TIMER *timer_ptr, tANI_U32 expiration_input)
{
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature) {
VOS_ASSERT( timer_ptr->tmrSignature == 0 );
return TX_TIMER_ERROR;
}
// changes cannot be applied until timer stops running
if (VOS_TIMER_STATE_STOPPED == vos_timer_getCurrentState(&timer_ptr->vosTimer))
{
timer_ptr->expireInput = expiration_input;
return TX_SUCCESS;
}
else
{
return TX_TIMER_ERROR;
}
} /*** tx_timer_change() ***/
/**---------------------------------------------------------------------
* tx_main_timer_func()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return None.
*
*/
static v_VOID_t tx_main_timer_func( v_PVOID_t functionContext )
{
TX_TIMER *timer_ptr = (TX_TIMER *)functionContext;
if (NULL == timer_ptr)
{
VOS_ASSERT(0);
return;
}
if (NULL == timer_ptr->pExpireFunc)
{
VOS_ASSERT(0);
return;
}
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"Timer %s triggered", TIMER_NAME);
// Now call the actual timer function, taking the function pointer,
// from the timer structure.
(* timer_ptr->pExpireFunc)( timer_ptr->pMac, timer_ptr->expireInput );
// check if this needs to be rescheduled
if (0 != timer_ptr->rescheduleTimeInMsecs)
{
VOS_STATUS status;
status = vos_timer_start( &timer_ptr->vosTimer,
timer_ptr->rescheduleTimeInMsecs );
timer_ptr->rescheduleTimeInMsecs = 0;
if (VOS_STATUS_SUCCESS != status)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_WARN,
"Unable to reschedule timer %s; status=%d", TIMER_NAME, status);
}
}
} /*** tx_timer_change() ***/
#ifdef TIMER_MANAGER
v_UINT_t tx_timer_create_intern_debug( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr,
char *name_ptr,
v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ),
tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks,
v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate,
char* fileName, v_U32_t lineNum)
{
VOS_STATUS status;
if (NULL == expiration_function)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"NULL timer expiration");
VOS_ASSERT(0);
return TX_TIMER_ERROR;
}
if(NULL == name_ptr)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"NULL name pointer for timer");
VOS_ASSERT(0);
return TX_TIMER_ERROR;
}
if (!initScheduleTimeInTicks)
return TX_TICK_ERROR;
if (!timer_ptr)
return TX_TIMER_ERROR;
// Initialize timer structure
timer_ptr->pExpireFunc = expiration_function;
timer_ptr->expireInput = expiration_input;
timer_ptr->initScheduleTimeInMsecs =
TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
timer_ptr->rescheduleTimeInMsecs =
TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
timer_ptr->pMac = pMacGlobal;
// Set the flag indicating that the timer was created
timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
#ifdef WLAN_DEBUG
// Store the timer name
strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
#endif // Store the timer name, for Debug build only
status = vos_timer_init_debug( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW,
tx_main_timer_func, (v_PVOID_t)timer_ptr, fileName, lineNum);
if (VOS_STATUS_SUCCESS != status)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Cannot create timer for %s\n", TIMER_NAME);
return TX_TIMER_ERROR;
}
if(0 != rescheduleTimeInTicks)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"Creating periodic timer for %s\n", TIMER_NAME);
}
// Activate this timer if required
if (auto_activate)
{
tx_timer_activate(timer_ptr);
}
return TX_SUCCESS;
} //** tx_timer_create() ***/
#else
v_UINT_t tx_timer_create_intern( v_PVOID_t pMacGlobal, TX_TIMER *timer_ptr,
char *name_ptr,
v_VOID_t ( *expiration_function )( v_PVOID_t, tANI_U32 ),
tANI_U32 expiration_input, v_ULONG_t initScheduleTimeInTicks,
v_ULONG_t rescheduleTimeInTicks, v_ULONG_t auto_activate )
{
VOS_STATUS status;
if((NULL == name_ptr) || (NULL == expiration_function))
return TX_TIMER_ERROR;
if (!initScheduleTimeInTicks)
return TX_TICK_ERROR;
if (!timer_ptr)
return TX_TIMER_ERROR;
// Initialize timer structure
timer_ptr->pExpireFunc = expiration_function;
timer_ptr->expireInput = expiration_input;
timer_ptr->initScheduleTimeInMsecs =
TX_MSECS_IN_1_TICK * initScheduleTimeInTicks;
timer_ptr->rescheduleTimeInMsecs =
TX_MSECS_IN_1_TICK * rescheduleTimeInTicks;
timer_ptr->pMac = pMacGlobal;
// Set the flag indicating that the timer was created
timer_ptr->tmrSignature = TX_AIRGO_TMR_SIGNATURE;
#ifdef WLAN_DEBUG
// Store the timer name
strlcpy(timer_ptr->timerName, name_ptr, sizeof(timer_ptr->timerName));
#endif // Store the timer name, for Debug build only
status = vos_timer_init( &timer_ptr->vosTimer, VOS_TIMER_TYPE_SW,
tx_main_timer_func, (v_PVOID_t)timer_ptr );
if (VOS_STATUS_SUCCESS != status)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_ERROR,
"Cannot create timer for %s\n", TIMER_NAME);
return TX_TIMER_ERROR;
}
if(0 != rescheduleTimeInTicks)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO,
"Creating periodic timer for %s\n", TIMER_NAME);
}
// Activate this timer if required
if (auto_activate)
{
tx_timer_activate(timer_ptr);
}
return TX_SUCCESS;
} //** tx_timer_create() ***/
#endif
/**---------------------------------------------------------------------
* tx_timer_deactivate()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return TX_SUCCESS.
*
*/
v_UINT_t tx_timer_deactivate(TX_TIMER *timer_ptr)
{
VOS_STATUS vStatus;
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature)
{
return TX_TIMER_ERROR;
}
// if the timer is not running then we do not need to do anything here
vStatus = vos_timer_stop( &timer_ptr->vosTimer );
if (VOS_STATUS_SUCCESS != vStatus)
{
VOS_TRACE(VOS_MODULE_ID_SYS, VOS_TRACE_LEVEL_INFO_HIGH,
"Unable to stop timer %s; status =%d\n",
TIMER_NAME, vStatus);
}
return TX_SUCCESS;
} /*** tx_timer_deactivate() ***/
v_UINT_t tx_timer_delete( TX_TIMER *timer_ptr )
{
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature)
{
return TX_TIMER_ERROR;
}
vos_timer_destroy( &timer_ptr->vosTimer );
return TX_SUCCESS;
} /*** tx_timer_delete() ***/
/**---------------------------------------------------------------------
* tx_timer_running()
*
* FUNCTION:
*
* LOGIC:
*
* ASSUMPTIONS:
*
* NOTE:
*
* @param
*
* @return TX_SUCCESS.
*
*/
v_BOOL_t tx_timer_running(TX_TIMER *timer_ptr)
{
// Put a check for the free builds
if (TX_AIRGO_TMR_SIGNATURE != timer_ptr->tmrSignature)
return VOS_FALSE;
if (VOS_TIMER_STATE_RUNNING ==
vos_timer_getCurrentState( &timer_ptr->vosTimer ))
{
return VOS_TRUE;
}
return VOS_FALSE;
} /*** tx_timer_running() ***/