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