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