1*5113495bSYour Name /* 2*5113495bSYour Name * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3*5113495bSYour Name * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. 4*5113495bSYour Name * 5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for 6*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the 7*5113495bSYour Name * above copyright notice and this permission notice appear in all 8*5113495bSYour Name * copies. 9*5113495bSYour Name * 10*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE. 18*5113495bSYour Name */ 19*5113495bSYour Name 20*5113495bSYour Name #if !defined(__SCHEDULER_CORE_H) 21*5113495bSYour Name #define __SCHEDULER_CORE_H 22*5113495bSYour Name 23*5113495bSYour Name #include <qdf_threads.h> 24*5113495bSYour Name #include <qdf_timer.h> 25*5113495bSYour Name #include <scheduler_api.h> 26*5113495bSYour Name #include <qdf_list.h> 27*5113495bSYour Name 28*5113495bSYour Name #ifndef SCHEDULER_CORE_MAX_MESSAGES 29*5113495bSYour Name #define SCHEDULER_CORE_MAX_MESSAGES 4000 30*5113495bSYour Name #endif 31*5113495bSYour Name #ifndef WLAN_SCHED_REDUCTION_LIMIT 32*5113495bSYour Name #define WLAN_SCHED_REDUCTION_LIMIT 32 33*5113495bSYour Name #endif 34*5113495bSYour Name #define SCHEDULER_NUMBER_OF_MSG_QUEUE 6 35*5113495bSYour Name #define SCHEDULER_WRAPPER_MAX_FAIL_COUNT (SCHEDULER_CORE_MAX_MESSAGES * 3) 36*5113495bSYour Name #define SCHEDULER_WATCHDOG_TIMEOUT (10 * 1000) /* 10s */ 37*5113495bSYour Name 38*5113495bSYour Name #ifdef CONFIG_AP_PLATFORM 39*5113495bSYour Name #define SCHED_DEBUG_PANIC(msg) 40*5113495bSYour Name #else 41*5113495bSYour Name #define SCHED_DEBUG_PANIC(msg) QDF_DEBUG_PANIC(msg) 42*5113495bSYour Name #endif 43*5113495bSYour Name 44*5113495bSYour Name #define sched_fatal(params...) \ 45*5113495bSYour Name QDF_TRACE_FATAL(QDF_MODULE_ID_SCHEDULER, params) 46*5113495bSYour Name #define sched_err(params...) \ 47*5113495bSYour Name QDF_TRACE_ERROR(QDF_MODULE_ID_SCHEDULER, params) 48*5113495bSYour Name #define sched_warn(params...) \ 49*5113495bSYour Name QDF_TRACE_WARN(QDF_MODULE_ID_SCHEDULER, params) 50*5113495bSYour Name #define sched_info(params...) \ 51*5113495bSYour Name QDF_TRACE_INFO(QDF_MODULE_ID_SCHEDULER, params) 52*5113495bSYour Name #define sched_debug(params...) \ 53*5113495bSYour Name QDF_TRACE_DEBUG(QDF_MODULE_ID_SCHEDULER, params) 54*5113495bSYour Name 55*5113495bSYour Name #define sched_nofl_fatal(params...) \ 56*5113495bSYour Name QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_SCHEDULER, params) 57*5113495bSYour Name #define sched_nofl_err(params...) \ 58*5113495bSYour Name QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_SCHEDULER, params) 59*5113495bSYour Name #define sched_nofl_warn(params...) \ 60*5113495bSYour Name QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_SCHEDULER, params) 61*5113495bSYour Name #define sched_nofl_info(params...) \ 62*5113495bSYour Name QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_SCHEDULER, params) 63*5113495bSYour Name #define sched_nofl_debug(params...) \ 64*5113495bSYour Name QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_SCHEDULER, params) 65*5113495bSYour Name 66*5113495bSYour Name #define sched_enter() sched_debug("Enter") 67*5113495bSYour Name #define sched_exit() sched_debug("Exit") 68*5113495bSYour Name 69*5113495bSYour Name /** 70*5113495bSYour Name * struct scheduler_mq_type - scheduler message queue 71*5113495bSYour Name * @mq_lock: message queue lock 72*5113495bSYour Name * @mq_list: message queue list 73*5113495bSYour Name * @qid: queue id 74*5113495bSYour Name */ 75*5113495bSYour Name struct scheduler_mq_type { 76*5113495bSYour Name qdf_spinlock_t mq_lock; 77*5113495bSYour Name qdf_list_t mq_list; 78*5113495bSYour Name QDF_MODULE_ID qid; 79*5113495bSYour Name }; 80*5113495bSYour Name 81*5113495bSYour Name /** 82*5113495bSYour Name * struct scheduler_mq_ctx - scheduler message queue context 83*5113495bSYour Name * @sch_msg_q: scheduler message queue 84*5113495bSYour Name * @scheduler_msg_qid_to_qidx: message qid to qidx mapping 85*5113495bSYour Name * @scheduler_msg_process_fn: array of message queue handler function pointers 86*5113495bSYour Name */ 87*5113495bSYour Name struct scheduler_mq_ctx { 88*5113495bSYour Name struct scheduler_mq_type sch_msg_q[SCHEDULER_NUMBER_OF_MSG_QUEUE]; 89*5113495bSYour Name uint8_t scheduler_msg_qid_to_qidx[QDF_MODULE_ID_MAX]; 90*5113495bSYour Name QDF_STATUS (*scheduler_msg_process_fn[SCHEDULER_NUMBER_OF_MSG_QUEUE]) 91*5113495bSYour Name (struct scheduler_msg *msg); 92*5113495bSYour Name }; 93*5113495bSYour Name 94*5113495bSYour Name /** 95*5113495bSYour Name * struct scheduler_ctx - scheduler context 96*5113495bSYour Name * @queue_ctx: message queue context 97*5113495bSYour Name * @sch_start_event: scheduler thread start wait event 98*5113495bSYour Name * @sch_thread: scheduler thread 99*5113495bSYour Name * @sch_shutdown: scheduler thread shutdown wait event 100*5113495bSYour Name * @sch_wait_queue: scheduler wait queue 101*5113495bSYour Name * @sch_event_flag: scheduler events flag 102*5113495bSYour Name * @resume_sch_event: scheduler resume wait event 103*5113495bSYour Name * @sch_thread_lock: scheduler thread lock 104*5113495bSYour Name * @sch_last_qidx: scheduler last qidx allocation 105*5113495bSYour Name * @watchdog_msg_type: 'type' of the current msg being processed 106*5113495bSYour Name * @hdd_callback: os if suspend callback 107*5113495bSYour Name * @legacy_wma_handler: legacy wma message handler 108*5113495bSYour Name * @legacy_sys_handler: legacy sys message handler 109*5113495bSYour Name * @timeout: timeout value for scheduler watchdog timer 110*5113495bSYour Name * @watchdog_timer: timer for triggering a scheduler watchdog bite 111*5113495bSYour Name * @watchdog_callback: the callback of the current msg being processed 112*5113495bSYour Name */ 113*5113495bSYour Name struct scheduler_ctx { 114*5113495bSYour Name struct scheduler_mq_ctx queue_ctx; 115*5113495bSYour Name qdf_event_t sch_start_event; 116*5113495bSYour Name qdf_thread_t *sch_thread; 117*5113495bSYour Name qdf_event_t sch_shutdown; 118*5113495bSYour Name qdf_wait_queue_head_t sch_wait_queue; 119*5113495bSYour Name unsigned long sch_event_flag; 120*5113495bSYour Name qdf_event_t resume_sch_event; 121*5113495bSYour Name qdf_spinlock_t sch_thread_lock; 122*5113495bSYour Name uint8_t sch_last_qidx; 123*5113495bSYour Name uint16_t watchdog_msg_type; 124*5113495bSYour Name hdd_suspend_callback hdd_callback; 125*5113495bSYour Name scheduler_msg_process_fn_t legacy_wma_handler; 126*5113495bSYour Name scheduler_msg_process_fn_t legacy_sys_handler; 127*5113495bSYour Name uint32_t timeout; 128*5113495bSYour Name qdf_timer_t watchdog_timer; 129*5113495bSYour Name void *watchdog_callback; 130*5113495bSYour Name }; 131*5113495bSYour Name 132*5113495bSYour Name /** 133*5113495bSYour Name * scheduler_core_msg_dup() - duplicate the given scheduler message 134*5113495bSYour Name * @msg: the message to duplicated 135*5113495bSYour Name * 136*5113495bSYour Name * Note: Duplicated messages must be freed using scheduler_core_msg_free(). 137*5113495bSYour Name * 138*5113495bSYour Name * Return: pointer to the duplicated message 139*5113495bSYour Name */ 140*5113495bSYour Name struct scheduler_msg *scheduler_core_msg_dup(struct scheduler_msg *msg); 141*5113495bSYour Name 142*5113495bSYour Name /** 143*5113495bSYour Name * scheduler_core_msg_free() - free the given scheduler message 144*5113495bSYour Name * @msg: the duplicated message to free 145*5113495bSYour Name * 146*5113495bSYour Name * Return: None 147*5113495bSYour Name */ 148*5113495bSYour Name void scheduler_core_msg_free(struct scheduler_msg *msg); 149*5113495bSYour Name 150*5113495bSYour Name /** 151*5113495bSYour Name * scheduler_get_context() - to get scheduler context 152*5113495bSYour Name * 153*5113495bSYour Name * This routine is used retrieve scheduler context 154*5113495bSYour Name * 155*5113495bSYour Name * Return: Pointer to scheduler context 156*5113495bSYour Name */ 157*5113495bSYour Name struct scheduler_ctx *scheduler_get_context(void); 158*5113495bSYour Name 159*5113495bSYour Name /** 160*5113495bSYour Name * scheduler_thread() - spawned thread will execute this routine 161*5113495bSYour Name * @arg: pointer to scheduler context 162*5113495bSYour Name * 163*5113495bSYour Name * Newly created thread will use this routine to perform its duty 164*5113495bSYour Name * 165*5113495bSYour Name * Return: none 166*5113495bSYour Name */ 167*5113495bSYour Name int scheduler_thread(void *arg); 168*5113495bSYour Name 169*5113495bSYour Name /** 170*5113495bSYour Name * scheduler_create_ctx() - to create scheduler context 171*5113495bSYour Name * 172*5113495bSYour Name * This routine is used to create scheduler context 173*5113495bSYour Name * 174*5113495bSYour Name * Return: QDF_STATUS based on success or failure 175*5113495bSYour Name */ 176*5113495bSYour Name QDF_STATUS scheduler_create_ctx(void); 177*5113495bSYour Name /** 178*5113495bSYour Name * scheduler_destroy_ctx() - to destroy scheduler context 179*5113495bSYour Name * 180*5113495bSYour Name * This routine is used to destroy scheduler context 181*5113495bSYour Name * 182*5113495bSYour Name * Return: QDF_STATUS based on success or failure 183*5113495bSYour Name */ 184*5113495bSYour Name QDF_STATUS scheduler_destroy_ctx(void); 185*5113495bSYour Name 186*5113495bSYour Name /** 187*5113495bSYour Name * scheduler_mq_put() - put message in the back of queue 188*5113495bSYour Name * @msg_q: Pointer to the message queue 189*5113495bSYour Name * @msg: the message to enqueue 190*5113495bSYour Name * 191*5113495bSYour Name * This function is used to put message in back of provided message 192*5113495bSYour Name * queue 193*5113495bSYour Name * 194*5113495bSYour Name * Return: none 195*5113495bSYour Name */ 196*5113495bSYour Name void scheduler_mq_put(struct scheduler_mq_type *msg_q, 197*5113495bSYour Name struct scheduler_msg *msg); 198*5113495bSYour Name /** 199*5113495bSYour Name * scheduler_mq_put_front() - put message in the front of queue 200*5113495bSYour Name * @msg_q: Pointer to the message queue 201*5113495bSYour Name * @msg: the message to enqueue 202*5113495bSYour Name * 203*5113495bSYour Name * This function is used to put message in front of provided message 204*5113495bSYour Name * queue 205*5113495bSYour Name * 206*5113495bSYour Name * Return: none 207*5113495bSYour Name */ 208*5113495bSYour Name void scheduler_mq_put_front(struct scheduler_mq_type *msg_q, 209*5113495bSYour Name struct scheduler_msg *msg); 210*5113495bSYour Name /** 211*5113495bSYour Name * scheduler_mq_get() - to get message from message queue 212*5113495bSYour Name * @msg_q: Pointer to the message queue 213*5113495bSYour Name * 214*5113495bSYour Name * This function is used to get message from given message queue 215*5113495bSYour Name * 216*5113495bSYour Name * Return: none 217*5113495bSYour Name */ 218*5113495bSYour Name struct scheduler_msg *scheduler_mq_get(struct scheduler_mq_type *msg_q); 219*5113495bSYour Name 220*5113495bSYour Name /** 221*5113495bSYour Name * scheduler_queues_init() - to initialize all the modules' queues 222*5113495bSYour Name * @sched_ctx: pointer to scheduler context 223*5113495bSYour Name * 224*5113495bSYour Name * This function is used to initialize the queues for all the modules 225*5113495bSYour Name * 226*5113495bSYour Name * Return: QDF_STATUS based on success of failure 227*5113495bSYour Name */ 228*5113495bSYour Name QDF_STATUS scheduler_queues_init(struct scheduler_ctx *sched_ctx); 229*5113495bSYour Name 230*5113495bSYour Name /** 231*5113495bSYour Name * scheduler_queues_deinit() - to de-initialize all the modules' queues 232*5113495bSYour Name * @sched_ctx: pointer to scheduler context 233*5113495bSYour Name * 234*5113495bSYour Name * This function is used to de-initialize the queues for all the modules 235*5113495bSYour Name * 236*5113495bSYour Name * Return: QDF_STATUS based on success of failure 237*5113495bSYour Name */ 238*5113495bSYour Name QDF_STATUS scheduler_queues_deinit(struct scheduler_ctx *sched_ctx); 239*5113495bSYour Name 240*5113495bSYour Name /** 241*5113495bSYour Name * scheduler_queues_flush() - flush all of the scheduler queues 242*5113495bSYour Name * @sched_ctx: pointer to scheduler context 243*5113495bSYour Name * 244*5113495bSYour Name * This routine is used to clean the module's queues 245*5113495bSYour Name * 246*5113495bSYour Name * Return: none 247*5113495bSYour Name */ 248*5113495bSYour Name void scheduler_queues_flush(struct scheduler_ctx *sched_ctx); 249*5113495bSYour Name #endif 250