blob: a04573f89e9a4c00c8464523de124c9233657c66 [file] [log] [blame]
/*
* Copyright (c) 2012-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.
*/
#if !defined( __VOS_SCHED_H )
#define __VOS_SCHED_H
/**=========================================================================
\file vos_sched.h
\brief virtual Operating System Servies (vOSS)
Definitions for some of the internal data type that is internally used
by the vOSS scheduler on Windows Mobile.
This file defines a vOSS message queue on Win Mobile and give some
insights about how the scheduler implements the execution model supported
by 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
-------- --- --------------------------------------------------------
09/15/08 lac Removed hardcoded #define for VOS_TRACE.
06/12/08 hba Created module.
===========================================================================*/
/*--------------------------------------------------------------------------
Include Files
------------------------------------------------------------------------*/
#include <vos_event.h>
#include "i_vos_types.h"
#include <linux/wait.h>
#include <vos_mq.h>
#include <adf_os_types.h>
#include <vos_lock.h>
#include <vos_timer.h>
#define TX_POST_EVENT 0x000
#define TX_SUSPEND_EVENT 0x001
#define MC_POST_EVENT 0x000
#define MC_SUSPEND_EVENT 0x001
#define RX_POST_EVENT 0x000
#define RX_SUSPEND_EVENT 0x001
#define TX_SHUTDOWN_EVENT 0x002
#define MC_SHUTDOWN_EVENT 0x002
#define RX_SHUTDOWN_EVENT 0x002
#define WD_POST_EVENT 0x000
#define WD_SHUTDOWN_EVENT 0x001
#define WD_CHIP_RESET_EVENT 0x002
#define WD_WLAN_SHUTDOWN_EVENT 0x003
#define WD_WLAN_REINIT_EVENT 0x004
#define WD_WLAN_DETECT_THREAD_STUCK 0x005
/*
** Maximum number of messages in the system
** These are buffers to account for all current messages
** with some accounting of what we think is a
** worst-case scenario. Must be able to handle all
** incoming frames, as well as overhead for internal
** messaging
**
** Increased to 8000 to handle more RX frames
*/
#define VOS_CORE_MAX_MESSAGES 8000
#ifdef QCA_CONFIG_SMP
/*
** Maximum number of vos messages to be allocated for
** Tlshim Rx thread.
*/
#define VOSS_MAX_TLSHIM_PKT 4000
typedef void (*vos_tlshim_cb) (void *context, void *rxpkt, u_int16_t staid);
#endif
/*
** vOSS Message queue definition.
*/
typedef struct _VosMqType
{
/* Lock use to synchronize access to this message queue */
spinlock_t mqLock;
/* List of vOS Messages waiting on this queue */
struct list_head mqList;
} VosMqType, *pVosMqType;
#ifdef QCA_CONFIG_SMP
/*
** VOSS message wrapper for data rx from Tlshim.
*/
typedef struct VosTlshimPkt
{
struct list_head list;
/* Tlshim context */
void *context;
/* Rx skb */
void *Rxpkt;
/* Station id to which this packet is destined */
u_int16_t staId;
/* Call back to further send this packet to tlshim layer */
vos_tlshim_cb callback;
} *pVosTlshimPkt;
#endif
/*
** vOSS Scheduler context
** The scheduler context contains the following:
** ** the messages queues
** ** the handle to the tread
** ** pointer to the events that gracefully shutdown the MC and Tx threads
**
*/
typedef struct _VosSchedContext
{
/* Place holder to the VOSS Context */
v_PVOID_t pVContext;
/* WDA Message queue on the Main thread*/
VosMqType wdaMcMq;
/* PE Message queue on the Main thread*/
VosMqType peMcMq;
/* SME Message queue on the Main thread*/
VosMqType smeMcMq;
/* TL Message queue on the Main thread */
VosMqType tlMcMq;
/* SYS Message queue on the Main thread */
VosMqType sysMcMq;
/* Handle of Event for MC thread to signal startup */
struct completion McStartEvent;
struct task_struct* McThread;
/* completion object for MC thread shutdown */
struct completion McShutdown;
/* Wait queue for MC thread */
wait_queue_head_t mcWaitQueue;
unsigned long mcEventFlag;
/* Completion object to resume Mc thread */
struct completion ResumeMcEvent;
/* lock to make sure that McThread and TxThread Suspend/resume mechanism is in sync*/
spinlock_t McThreadLock;
#ifdef QCA_CONFIG_SMP
spinlock_t TlshimRxThreadLock;
/* Tlshim Rx thread handle */
struct task_struct *TlshimRxThread;
/* Handle of Event for Rx thread to signal startup */
struct completion TlshimRxStartEvent;
/* Completion object to suspend tlshim rx thread */
struct completion SuspndTlshimRxEvent;
/* Completion objext to resume tlshim rx thread */
struct completion ResumeTlshimRxEvent;
/* Completion object for Tlshim Rxthread shutdown */
struct completion TlshimRxShutdown;
/* Waitq for tlshim Rx thread */
wait_queue_head_t tlshimRxWaitQueue;
unsigned long tlshimRxEvtFlg;
/* Rx buffer queue */
struct list_head tlshimRxQueue;
/* Spinlock to synchronize between tasklet and thread */
spinlock_t TlshimRxQLock;
/* Rx queue length */
unsigned int TlshimRxQlen;
/* Lock to synchronize free buffer queue access */
spinlock_t VosTlshimPktFreeQLock;
/* Free message queue for Tlshim Rx processing */
struct list_head VosTlshimPktFreeQ;
/* cpu hotplug notifier */
struct notifier_block *cpuHotPlugNotifier;
/* affinity lock */
vos_lock_t affinity_lock;
/* rx thread affinity cpu */
unsigned long rx_thread_cpu;
/* high throughput required */
bool high_throughput_required;
#endif
} VosSchedContext, *pVosSchedContext;
/*
** VOSS watchdog context
** The watchdog context contains the following:
** The messages queues and events
** The handle to the thread
**
*/
typedef struct _VosWatchdogContext
{
/* Place holder to the VOSS Context */
v_PVOID_t pVContext;
/* Handle of Event for Watchdog thread to signal startup */
struct completion WdStartEvent;
/* Watchdog Thread handle */
struct task_struct* WdThread;
/* completion object for Watchdog thread shutdown */
struct completion WdShutdown;
/* Wait queue for Watchdog thread */
wait_queue_head_t wdWaitQueue;
/* Event flag for events handled by Watchdog */
unsigned long wdEventFlag;
v_BOOL_t resetInProgress;
/* Lock for preventing multiple reset being triggered simultaneously */
spinlock_t wdLock;
/* Timer to detect thread stuck issue */
vos_timer_t thread_stuck_timer;
/* Count to determine thread stuck */
unsigned int mc_thread_stuck_count;
/* lock to synchronize access to the thread stuck counts */
spinlock_t thread_stuck_lock;
} VosWatchdogContext, *pVosWatchdogContext;
/*
** vOSS Sched Msg Wrapper
** Wrapper messages so that they can be chained to their respective queue
** in the scheduler.
*/
typedef struct _VosMsgWrapper
{
/* Message node */
struct list_head msgNode;
/* the Vos message it is associated to */
vos_msg_t *pVosMsg;
} VosMsgWrapper, *pVosMsgWrapper;
/**
* struct vos_log_complete - Log completion internal structure
* @is_fatal: Type is fatal or not
* @indicator: Source of bug report
* @reason_code: Reason code for bug report
* @is_report_in_progress: If bug report is in progress
*
* This structure internally stores the log related params
*/
struct vos_log_complete {
uint32_t is_fatal;
uint32_t indicator;
uint32_t reason_code;
bool is_report_in_progress;
};
/**
* struct vos_wdthread_timer_work - Watchdog timer thread structure
* @callback: Watchdog timer work call back
* @userdata: Input to the timer call back function
* @node: wdthread timer work Linklist
*
* This structure internally stores wdthread timer work related params
*/
struct vos_wdthread_timer_work {
vos_timer_callback_t callback;
void *userdata;
struct list_head node;
};
typedef struct _VosContextType
{
/* Messages buffers */
vos_msg_t aMsgBuffers[VOS_CORE_MAX_MESSAGES];
VosMsgWrapper aMsgWrappers[VOS_CORE_MAX_MESSAGES];
/* Free Message queue*/
VosMqType freeVosMq;
/* Scheduler Context */
VosSchedContext vosSched;
/* Watchdog Context */
VosWatchdogContext vosWatchdog;
/* HDD Module Context */
v_VOID_t *pHDDContext;
/* TL Module Context */
v_VOID_t *pTLContext;
/* MAC Module Context */
v_VOID_t *pMACContext;
vos_event_t ProbeEvent;
volatile v_U8_t isLogpInProgress;
vos_event_t wdaCompleteEvent;
/* WDA Context */
v_VOID_t *pWDAContext;
v_VOID_t *pHIFContext;
v_VOID_t *htc_ctx;
/*
* adf_ctx will be used by adf
* while allocating dma memory
* to access dev information.
*/
adf_os_device_t adf_ctx;
v_VOID_t *pdev_txrx_ctx;
/* Configuration handle used to get system configuration */
v_VOID_t *cfg_ctx;
volatile v_U8_t isLoadUnloadInProgress;
volatile v_U8_t is_load_in_progress;
volatile v_U8_t is_unload_in_progress;
/* SSR re-init in progress */
volatile v_U8_t isReInitInProgress;
/* SSR shutdown in progress */
v_U8_t is_shutdown_in_progress;
bool is_wakelock_log_enabled;
uint32_t wakelock_log_level;
uint32_t connectivity_log_level;
uint32_t packet_stats_log_level;
uint32_t driver_debug_log_level;
uint32_t fw_debug_log_level;
struct vos_log_complete log_complete;
vos_spin_lock_t bug_report_lock;
bool crash_indication_pending;
bool enable_fatal_event;
/* radio index per driver */
int radio_index;
struct vos_wdthread_timer_work wdthread_timer_work;
struct list_head wdthread_timer_work_list;
struct work_struct wdthread_work;
spinlock_t wdthread_work_lock;
} VosContextType, *pVosContextType;
/*---------------------------------------------------------------------------
Function declarations and documenation
---------------------------------------------------------------------------*/
#ifdef QCA_CONFIG_SMP
int vos_sched_handle_cpu_hot_plug(void);
int vos_sched_handle_throughput_req(bool high_tput_required);
/*---------------------------------------------------------------------------
\brief vos_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta
The \a vos_drop_rxpkt_by_staid() drops queued packets for a station, to drop
all the pending packets the caller has to send WLAN_MAX_STA_COUNT as staId.
\param pSchedContext - pointer to the global vOSS Sched Context
\param staId - Station Id
\return Nothing
\sa vos_drop_rxpkt_by_staid()
-------------------------------------------------------------------------*/
void vos_drop_rxpkt_by_staid(pVosSchedContext pSchedContext, u_int16_t staId);
/*---------------------------------------------------------------------------
\brief vos_indicate_rxpkt() - API to Indicate rx data packet
The \a vos_indicate_rxpkt() enqueues the rx packet onto tlshimRxQueue
and notifies VosTlshimRxThread().
\param Arg - pointer to the global vOSS Sched Context
\param pkt - Vos data message buffer
\return Nothing
\sa vos_indicate_rxpkt()
-------------------------------------------------------------------------*/
void vos_indicate_rxpkt(pVosSchedContext pSchedContext,
struct VosTlshimPkt *pkt);
/*---------------------------------------------------------------------------
\brief vos_alloc_tlshim_pkt() - API to return next available vos message
The \a vos_alloc_tlshim_pkt() returns next available vos message buffer
used for Rx Data processing.
\param pSchedContext - pointer to the global vOSS Sched Context
\return pointer to vos message buffer
\sa vos_alloc_tlshim_pkt()
-------------------------------------------------------------------------*/
struct VosTlshimPkt *vos_alloc_tlshim_pkt(pVosSchedContext pSchedContext);
/*---------------------------------------------------------------------------
\brief vos_free_tlshim_pkt() - API to release vos message to the freeq
The \a vos_free_tlshim_pkt() returns the vos message used for Rx data
to the free queue.
\param pSchedContext - pointer to the global vOSS Sched Context
\param pkt - Vos message buffer to be returned to free queue.
\return Nothing
\sa vos_free_tlshim_pkt()
-------------------------------------------------------------------------*/
void vos_free_tlshim_pkt(pVosSchedContext pSchedContext,
struct VosTlshimPkt *pkt);
/*---------------------------------------------------------------------------
\brief vos_free_tlshim_pkt_freeq() - Free voss buffer free queue
The \a vos_free_tlshim_pkt_freeq() does mem free of the buffers
available in free vos buffer queue which is used for Data rx processing
from Tlshim.
\param pSchedContext - pointer to the global vOSS Sched Context
\return Nothing
\sa vos_free_tlshim_pkt_freeq()
-------------------------------------------------------------------------*/
void vos_free_tlshim_pkt_freeq(pVosSchedContext pSchedContext);
#else
static inline int vos_sched_handle_throughput_req(
bool high_tput_required)
{
return 0;
}
#endif
/*---------------------------------------------------------------------------
\brief vos_sched_open() - initialize the vOSS Scheduler
The \a vos_sched_open() function initializes the vOSS Scheduler
Upon successful initialization:
- All the message queues are initialized
- The Main Controller thread is created and ready to receive and
dispatch messages.
- The Tx thread is created and ready to receive and dispatch messages
\param pVosContext - pointer to the global vOSS Context
\param pVosSchedContext - pointer to a previously allocated buffer big
enough to hold a scheduler context.
\
\return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
is ready to be used.
VOS_STATUS_E_RESOURCES - System resources (other than memory)
are unavailable to initilize the scheduler
VOS_STATUS_E_NOMEM - insufficient memory exists to initialize
the scheduler
VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open
function
VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/
\sa vos_sched_open()
-------------------------------------------------------------------------*/
VOS_STATUS vos_sched_open( v_PVOID_t pVosContext,
pVosSchedContext pSchedCxt,
v_SIZE_t SchedCtxSize);
/*---------------------------------------------------------------------------
\brief vos_watchdog_open() - initialize the vOSS watchdog
The \a vos_watchdog_open() function initializes the vOSS watchdog. Upon successful
initialization, the watchdog thread is created and ready to receive and process messages.
\param pVosContext - pointer to the global vOSS Context
\param pWdContext - pointer to a previously allocated buffer big
enough to hold a watchdog context.
\return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and
is ready to be used.
VOS_STATUS_E_RESOURCES - System resources (other than memory)
are unavailable to initilize the Watchdog
VOS_STATUS_E_NOMEM - insufficient memory exists to initialize
the Watchdog
VOS_STATUS_E_INVAL - Invalid parameter passed to the Watchdog Open
function
VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/
\sa vos_watchdog_open()
-------------------------------------------------------------------------*/
VOS_STATUS vos_watchdog_open
(
v_PVOID_t pVosContext,
pVosWatchdogContext pWdContext,
v_SIZE_t wdCtxSize
);
/*---------------------------------------------------------------------------
\brief vos_sched_close() - Close the vOSS Scheduler
The \a vos_sched_closes() function closes the vOSS Scheduler
Upon successful closing:
- All the message queues are flushed
- The Main Controller thread is closed
- The Tx thread is closed
\param pVosContext - pointer to the global vOSS Context
\return VOS_STATUS_SUCCESS - Scheduler was successfully initialized and
is ready to be used.
VOS_STATUS_E_INVAL - Invalid parameter passed to the scheduler Open
function
VOS_STATUS_E_FAILURE - Failure to initialize the scheduler/
\sa vos_sched_close()
---------------------------------------------------------------------------*/
VOS_STATUS vos_sched_close( v_PVOID_t pVosContext);
/*---------------------------------------------------------------------------
\brief vos_watchdog_close() - Close the vOSS Watchdog
The \a vos_watchdog_close() function closes the vOSS Watchdog
Upon successful closing:
- The Watchdog thread is closed
\param pVosContext - pointer to the global vOSS Context
\return VOS_STATUS_SUCCESS - Watchdog was successfully initialized and
is ready to be used.
VOS_STATUS_E_INVAL - Invalid parameter passed
VOS_STATUS_E_FAILURE - Failure to initialize the Watchdog/
\sa vos_watchdog_close()
---------------------------------------------------------------------------*/
VOS_STATUS vos_watchdog_close ( v_PVOID_t pVosContext );
/* Helper routines provided to other VOS API's */
VOS_STATUS vos_mq_init(pVosMqType pMq);
void vos_mq_deinit(pVosMqType pMq);
void vos_mq_put(pVosMqType pMq, pVosMsgWrapper pMsgWrapper);
void vos_mq_put_front(pVosMqType mq, pVosMsgWrapper msg_wrapper);
pVosMsgWrapper vos_mq_get(pVosMqType pMq);
v_BOOL_t vos_is_mq_empty(pVosMqType pMq);
pVosSchedContext get_vos_sched_ctxt(void);
pVosWatchdogContext get_vos_watchdog_ctxt(void);
VOS_STATUS vos_sched_init_mqs (pVosSchedContext pSchedContext);
void vos_sched_deinit_mqs (pVosSchedContext pSchedContext);
void vos_sched_flush_mc_mqs (pVosSchedContext pSchedContext);
void clearWlanResetReason(void);
void vos_timer_module_init( void );
VOS_STATUS vos_watchdog_wlan_shutdown(void);
VOS_STATUS vos_watchdog_wlan_re_init(void);
v_BOOL_t isWDresetInProgress(void);
void vos_ssr_protect_init(void);
void vos_ssr_protect(const char *caller_func);
void vos_ssr_unprotect(const char *caller_func);
bool vos_is_ssr_ready(const char *caller_func);
void vos_load_unload_protect(const char *caller_func);
void vos_load_unload_unprotect(const char *caller_func);
bool vos_is_load_unload_ready(const char *caller_func);
int vos_get_gfp_flags(void);
void vos_wd_reset_thread_stuck_count(int thread_id);
bool vos_is_wd_thread(int thread_id);
int vos_sched_is_mc_thread(int thread_id);
void vos_thread_stuck_timer_init(pVosWatchdogContext wd_ctx);
#define vos_wait_for_work_thread_completion(func) vos_is_ssr_ready(func)
#endif // #if !defined __VOSS_SCHED_H