1 /* 2 * Copyright (c) 2014-2018 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 2000 31 #endif 32 #define SCHEDULER_NUMBER_OF_MSG_QUEUE 6 33 #define SCHEDULER_WRAPPER_MAX_FAIL_COUNT (SCHEDULER_CORE_MAX_MESSAGES * 3) 34 #define SCHEDULER_WATCHDOG_TIMEOUT (10 * 1000) /* 10s */ 35 36 #define __sched_log(level, format, args...) \ 37 QDF_TRACE(QDF_MODULE_ID_SCHEDULER, level, FL(format), ## args) 38 39 #define sched_fatal(format, args...) \ 40 __sched_log(QDF_TRACE_LEVEL_FATAL, format, ## args) 41 #define sched_err(format, args...) \ 42 __sched_log(QDF_TRACE_LEVEL_ERROR, format, ## args) 43 #define sched_warn(format, args...) \ 44 __sched_log(QDF_TRACE_LEVEL_WARN, format, ## args) 45 #define sched_info(format, args...) \ 46 __sched_log(QDF_TRACE_LEVEL_INFO, format, ## args) 47 #define sched_debug(format, args...) \ 48 __sched_log(QDF_TRACE_LEVEL_DEBUG, format, ## args) 49 50 #define sched_enter() sched_debug("Enter") 51 #define sched_exit() sched_debug("Exit") 52 53 /** 54 * struct scheduler_mq_type - scheduler message queue 55 * @mq_lock: message queue lock 56 * @mq_list: message queue list 57 * @qid: queue id 58 */ 59 struct scheduler_mq_type { 60 qdf_spinlock_t mq_lock; 61 qdf_list_t mq_list; 62 QDF_MODULE_ID qid; 63 }; 64 65 /** 66 * struct scheduler_msg_wrapper - scheduler message wrapper 67 * @msg_node: message node 68 * @msg_buf: message buffer pointer 69 */ 70 struct scheduler_msg_wrapper { 71 qdf_list_node_t msg_node; 72 struct scheduler_msg *msg_buf; 73 }; 74 75 /** 76 * struct scheduler_mq_ctx - scheduler message queue context 77 * @msg_buffers: array of message buffers 78 * @msg_wrappers: array of message wrappers 79 * @free_msg_q: free message queue 80 * @sch_msg_q: scheduler message queue 81 * @scheduler_msg_qid_to_qidx: message qid to qidx mapping 82 * @scheduler_msg_process_fn: array of message queue handler function pointers 83 */ 84 struct scheduler_mq_ctx { 85 struct scheduler_msg msg_buffers[SCHEDULER_CORE_MAX_MESSAGES]; 86 struct scheduler_msg_wrapper msg_wrappers[SCHEDULER_CORE_MAX_MESSAGES]; 87 struct scheduler_mq_type free_msg_q; 88 struct scheduler_mq_type sch_msg_q[SCHEDULER_NUMBER_OF_MSG_QUEUE]; 89 uint8_t scheduler_msg_qid_to_qidx[QDF_MODULE_ID_MAX]; 90 QDF_STATUS (*scheduler_msg_process_fn[SCHEDULER_NUMBER_OF_MSG_QUEUE]) 91 (struct scheduler_msg *msg); 92 }; 93 94 /** 95 * struct scheduler_ctx - scheduler context 96 * @queue_ctx: message queue context 97 * @sch_start_event: scheduler thread start wait event 98 * @sch_thread: scheduler thread 99 * @sch_shutdown: scheduler thread shutdown wait event 100 * @sch_wait_queue: scheduler wait queue 101 * @sch_event_flag: scheduler events flag 102 * @resume_sch_event: scheduler resume wait event 103 * @sch_thread_lock: scheduler thread lock 104 * @sch_last_qidx: scheduler last qidx allocation 105 * @hdd_callback: os if suspend callback 106 * @legacy_wma_handler: legacy wma message handler 107 * @legacy_sys_handler: legacy sys message handler 108 * @watchdog_timer: timer for triggering a scheduler watchdog bite 109 * @watchdog_msg_type: 'type' of the current msg being processed 110 * @watchdog_callback: the callback of the current msg being processed 111 */ 112 struct scheduler_ctx { 113 struct scheduler_mq_ctx queue_ctx; 114 qdf_event_t sch_start_event; 115 qdf_thread_t *sch_thread; 116 qdf_event_t sch_shutdown; 117 qdf_wait_queue_head_t sch_wait_queue; 118 unsigned long sch_event_flag; 119 qdf_event_t resume_sch_event; 120 qdf_spinlock_t sch_thread_lock; 121 uint8_t sch_last_qidx; 122 hdd_suspend_callback hdd_callback; 123 scheduler_msg_process_fn_t legacy_wma_handler; 124 scheduler_msg_process_fn_t legacy_sys_handler; 125 qdf_timer_t watchdog_timer; 126 uint16_t watchdog_msg_type; 127 void *watchdog_callback; 128 }; 129 130 131 /** 132 * scheduler_get_context() - to get scheduler context 133 * 134 * This routine is used retrieve scheduler context 135 * 136 * Return: Pointer to scheduler context 137 */ 138 struct scheduler_ctx *scheduler_get_context(void); 139 /** 140 * scheduler_thread() - spawned thread will execute this routine 141 * @arg: pointer to scheduler context 142 * 143 * Newly created thread will use this routine to perform its duty 144 * 145 * Return: none 146 */ 147 int scheduler_thread(void *arg); 148 149 /** 150 * scheduler_cleanup_queues() - to clean up the given module's queue 151 * @sch_ctx: pointer to scheduler context 152 * @idx: index of the queue which needs to be cleanup. 153 * 154 * This routine is used to clean the module's queue provided by 155 * user through idx field 156 * 157 * Return: none 158 */ 159 void scheduler_cleanup_queues(struct scheduler_ctx *sch_ctx, int idx); 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 * scheduler_mq_init() - initialize scheduler message queue 178 * @msg_q: Pointer to the message queue 179 * 180 * This function initializes the Message queue. 181 * 182 * Return: qdf status 183 */ 184 QDF_STATUS scheduler_mq_init(struct scheduler_mq_type *msg_q); 185 /** 186 * scheduler_mq_deinit() - de-initialize scheduler message queue 187 * @msg_q: Pointer to the message queue 188 * 189 * This function de-initializes scheduler message queue 190 * 191 * Return: none 192 */ 193 void scheduler_mq_deinit(struct scheduler_mq_type *msg_q); 194 /** 195 * scheduler_mq_put() - put message in the back of queue 196 * @msg_q: Pointer to the message queue 197 * @msg_wrapper: pointer to message wrapper 198 * 199 * This function is used to put message in back of provided message 200 * queue 201 * 202 * Return: none 203 */ 204 void scheduler_mq_put(struct scheduler_mq_type *msg_q, 205 struct scheduler_msg_wrapper *msg_wrapper); 206 /** 207 * scheduler_mq_put_front() - put message in the front of queue 208 * @msg_q: Pointer to the message queue 209 * @msg_wrapper: pointer to message wrapper 210 * 211 * This function is used to put message in front of provided message 212 * queue 213 * 214 * Return: none 215 */ 216 void scheduler_mq_put_front(struct scheduler_mq_type *msg_q, 217 struct scheduler_msg_wrapper *msg_wrapper); 218 /** 219 * scheduler_mq_get() - to get message from message queue 220 * @msg_q: Pointer to the message queue 221 * 222 * This function is used to get message from given message queue 223 * 224 * Return: none 225 */ 226 struct scheduler_msg_wrapper *scheduler_mq_get(struct scheduler_mq_type *msg_q); 227 /** 228 * scheduler_is_mq_empty() - to check if message queue is empty 229 * @msg_q: Pointer to the message queue 230 * 231 * This function is used to check if message queue is empty 232 * 233 * Return: true or false 234 */ 235 bool scheduler_is_mq_empty(struct scheduler_mq_type *msg_q); 236 /** 237 * scheduler_queues_init() - to initialize all the modules' queues 238 * @sched_ctx: pointer to scheduler context 239 * 240 * This function is used to initialize the queues for all the modules 241 * 242 * Return: QDF_STATUS based on success of failure 243 */ 244 QDF_STATUS scheduler_queues_init(struct scheduler_ctx *sched_ctx); 245 /** 246 * scheduler_queues_deinit() - to de-initialize all the modules' queues 247 * @sched_ctx: pointer to scheduler context 248 * 249 * This function is used to de-initialize the queues for all the modules 250 * 251 * Return: QDF_STATUS based on success of failure 252 */ 253 QDF_STATUS scheduler_queues_deinit(struct scheduler_ctx *gp_sch_ctx); 254 #endif 255