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_mq_ctx - scheduler message queue context 68 * @sch_msg_q: scheduler message queue 69 * @scheduler_msg_qid_to_qidx: message qid to qidx mapping 70 * @scheduler_msg_process_fn: array of message queue handler function pointers 71 */ 72 struct scheduler_mq_ctx { 73 struct scheduler_mq_type sch_msg_q[SCHEDULER_NUMBER_OF_MSG_QUEUE]; 74 uint8_t scheduler_msg_qid_to_qidx[QDF_MODULE_ID_MAX]; 75 QDF_STATUS (*scheduler_msg_process_fn[SCHEDULER_NUMBER_OF_MSG_QUEUE]) 76 (struct scheduler_msg *msg); 77 }; 78 79 /** 80 * struct scheduler_ctx - scheduler context 81 * @queue_ctx: message queue context 82 * @sch_start_event: scheduler thread start wait event 83 * @sch_thread: scheduler thread 84 * @sch_shutdown: scheduler thread shutdown wait event 85 * @sch_wait_queue: scheduler wait queue 86 * @sch_event_flag: scheduler events flag 87 * @resume_sch_event: scheduler resume wait event 88 * @sch_thread_lock: scheduler thread lock 89 * @sch_last_qidx: scheduler last qidx allocation 90 * @hdd_callback: os if suspend callback 91 * @legacy_wma_handler: legacy wma message handler 92 * @legacy_sys_handler: legacy sys message handler 93 * @watchdog_timer: timer for triggering a scheduler watchdog bite 94 * @watchdog_msg_type: 'type' of the current msg being processed 95 * @watchdog_callback: the callback of the current msg being processed 96 */ 97 struct scheduler_ctx { 98 struct scheduler_mq_ctx queue_ctx; 99 qdf_event_t sch_start_event; 100 qdf_thread_t *sch_thread; 101 qdf_event_t sch_shutdown; 102 qdf_wait_queue_head_t sch_wait_queue; 103 unsigned long sch_event_flag; 104 qdf_event_t resume_sch_event; 105 qdf_spinlock_t sch_thread_lock; 106 uint8_t sch_last_qidx; 107 hdd_suspend_callback hdd_callback; 108 scheduler_msg_process_fn_t legacy_wma_handler; 109 scheduler_msg_process_fn_t legacy_sys_handler; 110 qdf_timer_t watchdog_timer; 111 uint16_t watchdog_msg_type; 112 void *watchdog_callback; 113 }; 114 115 /** 116 * scheduler_core_msg_dup() duplicate the given scheduler message 117 * @msg: the message to duplicated 118 * 119 * Note: Duplicated messages must be freed using scheduler_core_msg_free(). 120 * 121 * Return: pointer to the duplicated message 122 */ 123 struct scheduler_msg *scheduler_core_msg_dup(struct scheduler_msg *msg); 124 125 /** 126 * scheduler_core_msg_free() - free the given scheduler message 127 * @msg: the duplicated message to free 128 * 129 * Return: None 130 */ 131 void scheduler_core_msg_free(struct scheduler_msg *msg); 132 133 /** 134 * scheduler_get_context() - to get scheduler context 135 * 136 * This routine is used retrieve scheduler context 137 * 138 * Return: Pointer to scheduler context 139 */ 140 struct scheduler_ctx *scheduler_get_context(void); 141 142 /** 143 * scheduler_thread() - spawned thread will execute this routine 144 * @arg: pointer to scheduler context 145 * 146 * Newly created thread will use this routine to perform its duty 147 * 148 * Return: none 149 */ 150 int scheduler_thread(void *arg); 151 152 /** 153 * scheduler_create_ctx() - to create scheduler context 154 * 155 * This routine is used to create scheduler context 156 * 157 * Return: QDF_STATUS based on success or failure 158 */ 159 QDF_STATUS scheduler_create_ctx(void); 160 /** 161 * scheduler_destroy_ctx() - to destroy scheduler context 162 * 163 * This routine is used to destroy scheduler context 164 * 165 * Return: QDF_STATUS based on success or failure 166 */ 167 QDF_STATUS scheduler_destroy_ctx(void); 168 169 /** 170 * scheduler_mq_put() - put message in the back of queue 171 * @msg_q: Pointer to the message queue 172 * @msg: the message to enqueue 173 * 174 * This function is used to put message in back of provided message 175 * queue 176 * 177 * Return: none 178 */ 179 void scheduler_mq_put(struct scheduler_mq_type *msg_q, 180 struct scheduler_msg *msg); 181 /** 182 * scheduler_mq_put_front() - put message in the front of queue 183 * @msg_q: Pointer to the message queue 184 * @msg: the message to enqueue 185 * 186 * This function is used to put message in front of provided message 187 * queue 188 * 189 * Return: none 190 */ 191 void scheduler_mq_put_front(struct scheduler_mq_type *msg_q, 192 struct scheduler_msg *msg); 193 /** 194 * scheduler_mq_get() - to get message from message queue 195 * @msg_q: Pointer to the message queue 196 * 197 * This function is used to get message from given message queue 198 * 199 * Return: none 200 */ 201 struct scheduler_msg *scheduler_mq_get(struct scheduler_mq_type *msg_q); 202 203 /** 204 * scheduler_queues_init() - to initialize all the modules' queues 205 * @sched_ctx: pointer to scheduler context 206 * 207 * This function is used to initialize the queues for all the modules 208 * 209 * Return: QDF_STATUS based on success of failure 210 */ 211 QDF_STATUS scheduler_queues_init(struct scheduler_ctx *sched_ctx); 212 213 /** 214 * scheduler_queues_deinit() - to de-initialize all the modules' queues 215 * @sched_ctx: pointer to scheduler context 216 * 217 * This function is used to de-initialize the queues for all the modules 218 * 219 * Return: QDF_STATUS based on success of failure 220 */ 221 QDF_STATUS scheduler_queues_deinit(struct scheduler_ctx *gp_sch_ctx); 222 223 /** 224 * scheduler_queues_flush() - flush all of the scheduler queues 225 * @sch_ctx: pointer to scheduler context 226 * 227 * This routine is used to clean the module's queues 228 * 229 * Return: none 230 */ 231 void scheduler_queues_flush(struct scheduler_ctx *sched_ctx); 232 #endif 233