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