1cd395495SRajeev Kumar /* 23149adf5SDustin Brown * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. 3cd395495SRajeev Kumar * 4cd395495SRajeev Kumar * Permission to use, copy, modify, and/or distribute this software for 5cd395495SRajeev Kumar * any purpose with or without fee is hereby granted, provided that the 6cd395495SRajeev Kumar * above copyright notice and this permission notice appear in all 7cd395495SRajeev Kumar * copies. 8cd395495SRajeev Kumar * 9cd395495SRajeev Kumar * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10cd395495SRajeev Kumar * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11cd395495SRajeev Kumar * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12cd395495SRajeev Kumar * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13cd395495SRajeev Kumar * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14cd395495SRajeev Kumar * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15cd395495SRajeev Kumar * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16cd395495SRajeev Kumar * PERFORMANCE OF THIS SOFTWARE. 17cd395495SRajeev Kumar */ 18cd395495SRajeev Kumar 19cd395495SRajeev Kumar #if !defined(__SCHEDULER_CORE_H) 20cd395495SRajeev Kumar #define __SCHEDULER_CORE_H 21cd395495SRajeev Kumar 22cd395495SRajeev Kumar #include <qdf_threads.h> 23e226cebdSDustin Brown #include <qdf_timer.h> 24cd395495SRajeev Kumar #include <scheduler_api.h> 25cd395495SRajeev Kumar #include <qdf_list.h> 26cd395495SRajeev Kumar 27f227fb74SVivek #ifdef CONFIG_MCL 28c8e2987fSDustin Brown #define SCHEDULER_CORE_MAX_MESSAGES 1000 29f227fb74SVivek #else 30f227fb74SVivek #define SCHEDULER_CORE_MAX_MESSAGES 2000 31*d78dedc9SVivek #define WLAN_SCHED_REDUCTION_LIMIT 32 32f227fb74SVivek #endif 336ecd284eSVignesh Viswanathan #define SCHEDULER_NUMBER_OF_MSG_QUEUE 6 3473c05a80SRajeev Kumar #define SCHEDULER_WRAPPER_MAX_FAIL_COUNT (SCHEDULER_CORE_MAX_MESSAGES * 3) 35e226cebdSDustin Brown #define SCHEDULER_WATCHDOG_TIMEOUT (10 * 1000) /* 10s */ 36cd395495SRajeev Kumar 373149adf5SDustin Brown #define __sched_log(level, format, args...) \ 383149adf5SDustin Brown QDF_TRACE(QDF_MODULE_ID_SCHEDULER, level, FL(format), ## args) 39e1d3d092SDustin Brown 40e1d3d092SDustin Brown #define sched_fatal(format, args...) \ 413149adf5SDustin Brown __sched_log(QDF_TRACE_LEVEL_FATAL, format, ## args) 42e1d3d092SDustin Brown #define sched_err(format, args...) \ 433149adf5SDustin Brown __sched_log(QDF_TRACE_LEVEL_ERROR, format, ## args) 44e1d3d092SDustin Brown #define sched_warn(format, args...) \ 453149adf5SDustin Brown __sched_log(QDF_TRACE_LEVEL_WARN, format, ## args) 46e1d3d092SDustin Brown #define sched_info(format, args...) \ 473149adf5SDustin Brown __sched_log(QDF_TRACE_LEVEL_INFO, format, ## args) 48e1d3d092SDustin Brown #define sched_debug(format, args...) \ 493149adf5SDustin Brown __sched_log(QDF_TRACE_LEVEL_DEBUG, format, ## args) 50e1d3d092SDustin Brown 5191abaccbSDustin Brown #define sched_enter() sched_debug("Enter") 5291abaccbSDustin Brown #define sched_exit() sched_debug("Exit") 5391abaccbSDustin Brown 54cd395495SRajeev Kumar /** 55cd395495SRajeev Kumar * struct scheduler_mq_type - scheduler message queue 56cd395495SRajeev Kumar * @mq_lock: message queue lock 57cd395495SRajeev Kumar * @mq_list: message queue list 58cd395495SRajeev Kumar * @qid: queue id 59cd395495SRajeev Kumar */ 60cd395495SRajeev Kumar struct scheduler_mq_type { 61cd395495SRajeev Kumar qdf_spinlock_t mq_lock; 62cd395495SRajeev Kumar qdf_list_t mq_list; 63cd395495SRajeev Kumar QDF_MODULE_ID qid; 64cd395495SRajeev Kumar }; 65cd395495SRajeev Kumar 66cd395495SRajeev Kumar /** 67cd395495SRajeev Kumar * struct scheduler_msg_wrapper - scheduler message wrapper 68cd395495SRajeev Kumar * @msg_node: message node 69cd395495SRajeev Kumar * @msg_buf: message buffer pointer 70cd395495SRajeev Kumar */ 71cd395495SRajeev Kumar struct scheduler_msg_wrapper { 72cd395495SRajeev Kumar qdf_list_node_t msg_node; 73cd395495SRajeev Kumar struct scheduler_msg *msg_buf; 74cd395495SRajeev Kumar }; 75cd395495SRajeev Kumar 76cd395495SRajeev Kumar /** 77cd395495SRajeev Kumar * struct scheduler_mq_ctx - scheduler message queue context 78cd395495SRajeev Kumar * @msg_buffers: array of message buffers 79cd395495SRajeev Kumar * @msg_wrappers: array of message wrappers 80cd395495SRajeev Kumar * @free_msg_q: free message queue 81cd395495SRajeev Kumar * @sch_msg_q: scheduler message queue 82cd395495SRajeev Kumar * @scheduler_msg_qid_to_qidx: message qid to qidx mapping 83cd395495SRajeev Kumar * @scheduler_msg_process_fn: array of message queue handler function pointers 84cd395495SRajeev Kumar */ 85cd395495SRajeev Kumar struct scheduler_mq_ctx { 86cd395495SRajeev Kumar struct scheduler_msg msg_buffers[SCHEDULER_CORE_MAX_MESSAGES]; 87cd395495SRajeev Kumar struct scheduler_msg_wrapper msg_wrappers[SCHEDULER_CORE_MAX_MESSAGES]; 88cd395495SRajeev Kumar struct scheduler_mq_type free_msg_q; 89cd395495SRajeev Kumar struct scheduler_mq_type sch_msg_q[SCHEDULER_NUMBER_OF_MSG_QUEUE]; 90cd395495SRajeev Kumar uint8_t scheduler_msg_qid_to_qidx[QDF_MODULE_ID_MAX]; 91cd395495SRajeev Kumar QDF_STATUS (*scheduler_msg_process_fn[SCHEDULER_NUMBER_OF_MSG_QUEUE]) 92cd395495SRajeev Kumar (struct scheduler_msg *msg); 93cd395495SRajeev Kumar }; 94cd395495SRajeev Kumar 95cd395495SRajeev Kumar /** 96cd395495SRajeev Kumar * struct scheduler_ctx - scheduler context 97cd395495SRajeev Kumar * @queue_ctx: message queue context 98cd395495SRajeev Kumar * @sch_start_event: scheduler thread start wait event 99cd395495SRajeev Kumar * @sch_thread: scheduler thread 100cd395495SRajeev Kumar * @sch_shutdown: scheduler thread shutdown wait event 101cd395495SRajeev Kumar * @sch_wait_queue: scheduler wait queue 102cd395495SRajeev Kumar * @sch_event_flag: scheduler events flag 103cd395495SRajeev Kumar * @resume_sch_event: scheduler resume wait event 104cd395495SRajeev Kumar * @sch_thread_lock: scheduler thread lock 105cd395495SRajeev Kumar * @sch_last_qidx: scheduler last qidx allocation 106cd395495SRajeev Kumar * @hdd_callback: os if suspend callback 107cd395495SRajeev Kumar * @legacy_wma_handler: legacy wma message handler 108cd395495SRajeev Kumar * @legacy_sys_handler: legacy sys message handler 109e226cebdSDustin Brown * @watchdog_timer: timer for triggering a scheduler watchdog bite 110e226cebdSDustin Brown * @watchdog_msg_type: 'type' of the current msg being processed 111e226cebdSDustin Brown * @watchdog_callback: the callback of the current msg being processed 112cd395495SRajeev Kumar */ 113cd395495SRajeev Kumar struct scheduler_ctx { 114cd395495SRajeev Kumar struct scheduler_mq_ctx queue_ctx; 115cd395495SRajeev Kumar qdf_event_t sch_start_event; 116cd395495SRajeev Kumar qdf_thread_t *sch_thread; 117cd395495SRajeev Kumar qdf_event_t sch_shutdown; 118cd395495SRajeev Kumar qdf_wait_queue_head_t sch_wait_queue; 119cd395495SRajeev Kumar unsigned long sch_event_flag; 120cd395495SRajeev Kumar qdf_event_t resume_sch_event; 121cd395495SRajeev Kumar qdf_spinlock_t sch_thread_lock; 122cd395495SRajeev Kumar uint8_t sch_last_qidx; 123cd395495SRajeev Kumar hdd_suspend_callback hdd_callback; 124cd395495SRajeev Kumar scheduler_msg_process_fn_t legacy_wma_handler; 125cd395495SRajeev Kumar scheduler_msg_process_fn_t legacy_sys_handler; 126e226cebdSDustin Brown qdf_timer_t watchdog_timer; 127e226cebdSDustin Brown uint16_t watchdog_msg_type; 128e226cebdSDustin Brown void *watchdog_callback; 129cd395495SRajeev Kumar }; 130cd395495SRajeev Kumar 131cd395495SRajeev Kumar 132cd395495SRajeev Kumar /** 133cd395495SRajeev Kumar * scheduler_get_context() - to get scheduler context 134cd395495SRajeev Kumar * 135cd395495SRajeev Kumar * This routine is used retrieve scheduler context 136cd395495SRajeev Kumar * 137cd395495SRajeev Kumar * Return: Pointer to scheduler context 138cd395495SRajeev Kumar */ 139cd395495SRajeev Kumar struct scheduler_ctx *scheduler_get_context(void); 140cd395495SRajeev Kumar /** 141cd395495SRajeev Kumar * scheduler_thread() - spawned thread will execute this routine 142cd395495SRajeev Kumar * @arg: pointer to scheduler context 143cd395495SRajeev Kumar * 144cd395495SRajeev Kumar * Newly created thread will use this routine to perform its duty 145cd395495SRajeev Kumar * 146cd395495SRajeev Kumar * Return: none 147cd395495SRajeev Kumar */ 148cd395495SRajeev Kumar int scheduler_thread(void *arg); 149cd395495SRajeev Kumar 150cd395495SRajeev Kumar /** 151cd395495SRajeev Kumar * scheduler_cleanup_queues() - to clean up the given module's queue 152cd395495SRajeev Kumar * @sch_ctx: pointer to scheduler context 153cd395495SRajeev Kumar * @idx: index of the queue which needs to be cleanup. 154cd395495SRajeev Kumar * 155cd395495SRajeev Kumar * This routine is used to clean the module's queue provided by 156cd395495SRajeev Kumar * user through idx field 157cd395495SRajeev Kumar * 158cd395495SRajeev Kumar * Return: none 159cd395495SRajeev Kumar */ 160cd395495SRajeev Kumar void scheduler_cleanup_queues(struct scheduler_ctx *sch_ctx, int idx); 161cd395495SRajeev Kumar /** 162cd395495SRajeev Kumar * scheduler_create_ctx() - to create scheduler context 163cd395495SRajeev Kumar * 164cd395495SRajeev Kumar * This routine is used to create scheduler context 165cd395495SRajeev Kumar * 166cd395495SRajeev Kumar * Return: QDF_STATUS based on success or failure 167cd395495SRajeev Kumar */ 168cd395495SRajeev Kumar QDF_STATUS scheduler_create_ctx(void); 169cd395495SRajeev Kumar /** 170cd395495SRajeev Kumar * scheduler_destroy_ctx() - to destroy scheduler context 171cd395495SRajeev Kumar * 172cd395495SRajeev Kumar * This routine is used to destroy scheduler context 173cd395495SRajeev Kumar * 174cd395495SRajeev Kumar * Return: QDF_STATUS based on success or failure 175cd395495SRajeev Kumar */ 176cd395495SRajeev Kumar QDF_STATUS scheduler_destroy_ctx(void); 177cd395495SRajeev Kumar /** 178cd395495SRajeev Kumar * scheduler_mq_init() - initialize scheduler message queue 179cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 180cd395495SRajeev Kumar * 181cd395495SRajeev Kumar * This function initializes the Message queue. 182cd395495SRajeev Kumar * 183cd395495SRajeev Kumar * Return: qdf status 184cd395495SRajeev Kumar */ 185cd395495SRajeev Kumar QDF_STATUS scheduler_mq_init(struct scheduler_mq_type *msg_q); 186cd395495SRajeev Kumar /** 187cd395495SRajeev Kumar * scheduler_mq_deinit() - de-initialize scheduler message queue 188cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 189cd395495SRajeev Kumar * 190cd395495SRajeev Kumar * This function de-initializes scheduler message queue 191cd395495SRajeev Kumar * 192cd395495SRajeev Kumar * Return: none 193cd395495SRajeev Kumar */ 194cd395495SRajeev Kumar void scheduler_mq_deinit(struct scheduler_mq_type *msg_q); 195cd395495SRajeev Kumar /** 196cd395495SRajeev Kumar * scheduler_mq_put() - put message in the back of queue 197cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 198cd395495SRajeev Kumar * @msg_wrapper: pointer to message wrapper 199cd395495SRajeev Kumar * 200cd395495SRajeev Kumar * This function is used to put message in back of provided message 201cd395495SRajeev Kumar * queue 202cd395495SRajeev Kumar * 203cd395495SRajeev Kumar * Return: none 204cd395495SRajeev Kumar */ 205cd395495SRajeev Kumar void scheduler_mq_put(struct scheduler_mq_type *msg_q, 206cd395495SRajeev Kumar struct scheduler_msg_wrapper *msg_wrapper); 207cd395495SRajeev Kumar /** 208cd395495SRajeev Kumar * scheduler_mq_put_front() - put message in the front of queue 209cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 210cd395495SRajeev Kumar * @msg_wrapper: pointer to message wrapper 211cd395495SRajeev Kumar * 212cd395495SRajeev Kumar * This function is used to put message in front of provided message 213cd395495SRajeev Kumar * queue 214cd395495SRajeev Kumar * 215cd395495SRajeev Kumar * Return: none 216cd395495SRajeev Kumar */ 217cd395495SRajeev Kumar void scheduler_mq_put_front(struct scheduler_mq_type *msg_q, 218cd395495SRajeev Kumar struct scheduler_msg_wrapper *msg_wrapper); 219cd395495SRajeev Kumar /** 220cd395495SRajeev Kumar * scheduler_mq_get() - to get message from message queue 221cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 222cd395495SRajeev Kumar * 223cd395495SRajeev Kumar * This function is used to get message from given message queue 224cd395495SRajeev Kumar * 225cd395495SRajeev Kumar * Return: none 226cd395495SRajeev Kumar */ 227cd395495SRajeev Kumar struct scheduler_msg_wrapper *scheduler_mq_get(struct scheduler_mq_type *msg_q); 228cd395495SRajeev Kumar /** 229cd395495SRajeev Kumar * scheduler_is_mq_empty() - to check if message queue is empty 230cd395495SRajeev Kumar * @msg_q: Pointer to the message queue 231cd395495SRajeev Kumar * 232cd395495SRajeev Kumar * This function is used to check if message queue is empty 233cd395495SRajeev Kumar * 234cd395495SRajeev Kumar * Return: true or false 235cd395495SRajeev Kumar */ 236cd395495SRajeev Kumar bool scheduler_is_mq_empty(struct scheduler_mq_type *msg_q); 237cd395495SRajeev Kumar /** 238cd395495SRajeev Kumar * scheduler_queues_init() - to initialize all the modules' queues 239cd395495SRajeev Kumar * @sched_ctx: pointer to scheduler context 240cd395495SRajeev Kumar * 241cd395495SRajeev Kumar * This function is used to initialize the queues for all the modules 242cd395495SRajeev Kumar * 243cd395495SRajeev Kumar * Return: QDF_STATUS based on success of failure 244cd395495SRajeev Kumar */ 245cd395495SRajeev Kumar QDF_STATUS scheduler_queues_init(struct scheduler_ctx *sched_ctx); 246cd395495SRajeev Kumar /** 247cd395495SRajeev Kumar * scheduler_queues_deinit() - to de-initialize all the modules' queues 248cd395495SRajeev Kumar * @sched_ctx: pointer to scheduler context 249cd395495SRajeev Kumar * 250cd395495SRajeev Kumar * This function is used to de-initialize the queues for all the modules 251cd395495SRajeev Kumar * 252cd395495SRajeev Kumar * Return: QDF_STATUS based on success of failure 253cd395495SRajeev Kumar */ 254cd395495SRajeev Kumar QDF_STATUS scheduler_queues_deinit(struct scheduler_ctx *gp_sch_ctx); 255cd395495SRajeev Kumar #endif 256