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