1 /* 2 * Copyright (c) 2014-2020 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_API_H) 20 #define __SCHEDULER_API_H 21 22 #include <qdf_event.h> 23 #include <qdf_types.h> 24 #include <qdf_lock.h> 25 #include <qdf_mc_timer.h> 26 #include <qdf_status.h> 27 28 /* Controller thread various event masks 29 * MC_POST_EVENT_MASK: wake up thread after posting message 30 * MC_SUSPEND_EVENT_MASK: signal thread to suspend during kernel pm suspend 31 * MC_SHUTDOWN_EVENT_MASK: signal thread to shutdown and exit during unload 32 */ 33 #define MC_POST_EVENT_MASK 0x001 34 #define MC_SUSPEND_EVENT_MASK 0x002 35 #define MC_SHUTDOWN_EVENT_MASK 0x010 36 37 /* 38 * Cookie for timer messages. Note that anyone posting a timer message 39 * has to write the COOKIE in the reserved field of the message. The 40 * timer queue handler relies on this COOKIE 41 */ 42 #define SYS_MSG_COOKIE 0xFACE 43 44 #define scheduler_get_src_id(qid) (((qid) >> 20) & 0x3FF) 45 #define scheduler_get_dest_id(qid) (((qid) >> 10) & 0x3FF) 46 #define scheduler_get_que_id(qid) ((qid) & 0x3FF) 47 #define scheduler_get_qid(src, dest, que_id) ((que_id) | ((dest) << 10) |\ 48 ((src) << 20)) 49 50 typedef enum { 51 SYS_MSG_ID_MC_TIMER, 52 SYS_MSG_ID_FTM_RSP, 53 SYS_MSG_ID_QVIT, 54 SYS_MSG_ID_DATA_STALL_MSG, 55 SYS_MSG_ID_UMAC_STOP, 56 } SYS_MSG_ID; 57 58 /** 59 * struct scheduler_msg: scheduler message structure 60 * @type: message type 61 * @reserved: reserved field 62 * @bodyval: message body val 63 * @bodyptr: message body pointer based on the type either a bodyptr pointer 64 * into memory or bodyval as a 32 bit data is used. bodyptr is always a 65 * freeable pointer, one should always make sure that bodyptr is always 66 * freeable. 67 * Messages should use either bodyptr or bodyval; not both !!! 68 * @callback: callback to be called by scheduler thread once message is posted 69 * and scheduler thread has started processing the message. 70 * @flush_callback: flush callback which will be invoked during driver unload 71 * such that component can release the ref count of common global objects 72 * like PSOC, PDEV, VDEV and PEER. A component needs to populate flush 73 * callback in message body pointer for those messages which have taken ref 74 * count for above mentioned common objects. 75 * @node: list node for queue membership 76 * @queue_id: Id of the queue the message was added to 77 * @queue_depth: depth of the queue when the message was queued 78 * @queued_at_us: timestamp when the message was queued in microseconds 79 */ 80 struct scheduler_msg { 81 uint16_t type; 82 uint16_t reserved; 83 uint32_t bodyval; 84 void *bodyptr; 85 void *callback; 86 void *flush_callback; 87 qdf_list_node_t node; 88 #ifdef WLAN_SCHED_HISTORY_SIZE 89 QDF_MODULE_ID queue_id; 90 uint32_t queue_depth; 91 uint64_t queued_at_us; 92 #endif /* WLAN_SCHED_HISTORY_SIZE */ 93 }; 94 95 /** 96 * sched_history_print() - print scheduler history 97 * 98 * This API prints the scheduler history. 99 * 100 * Return: None 101 */ 102 void sched_history_print(void); 103 104 typedef QDF_STATUS (*scheduler_msg_process_fn_t) (struct scheduler_msg *msg); 105 typedef void (*hdd_suspend_callback)(void); 106 107 /** 108 * scheduler_init() - initialize control path scheduler 109 * 110 * This API initializes control path scheduler. 111 * 112 * Return: QDF status 113 */ 114 QDF_STATUS scheduler_init(void); 115 116 /** 117 * scheduler_deinit() - de-initialize control path scheduler 118 * 119 * This API de-initializes control path scheduler. 120 * 121 * Return: QDF status 122 */ 123 QDF_STATUS scheduler_deinit(void); 124 125 /** 126 * scheduler_enable() - start the scheduler module 127 * 128 * Ready the scheduler module to service requests, and start the scheduler's 129 * message processing thread. Must only be called after scheduler_init(). 130 * 131 * Return: QDF_STATUS 132 */ 133 QDF_STATUS scheduler_enable(void); 134 135 /** 136 * scheduler_disable() - stop the scheduler module 137 * 138 * Stop the scheduler module from servicing requests, and terminate the 139 * scheduler's message processing thread. Must be called before 140 * scheduler_deinit(). 141 * 142 * Return: QDF_STATUS 143 */ 144 QDF_STATUS scheduler_disable(void); 145 146 /** 147 * scheduler_register_module() - register input module/queue id 148 * @qid: queue id to get registered 149 * @callback: queue message to be called when a message is posted 150 * 151 * Return: QDF status 152 */ 153 QDF_STATUS scheduler_register_module(QDF_MODULE_ID qid, 154 scheduler_msg_process_fn_t callback); 155 156 /** 157 * scheduler_deregister_module() - deregister input module/queue id 158 * @qid: queue id to get deregistered 159 * 160 * Return: QDF status 161 */ 162 QDF_STATUS scheduler_deregister_module(QDF_MODULE_ID qid); 163 164 /** 165 * scheduler_post_msg_by_priority() - post messages by priority 166 * @qid: queue id to which the message has to be posted. 167 * @msg: message pointer 168 * @is_high_priority: set to true for high priority message else false 169 * 170 * Return: QDF status 171 */ 172 QDF_STATUS scheduler_post_msg_by_priority(uint32_t qid, 173 struct scheduler_msg *msg, 174 bool is_high_priority); 175 176 /** 177 * scheduler_post_msg() - post normal messages(no priority) 178 * @qid: queue id to which the message has to be posted. 179 * @msg: message pointer 180 * 181 * Return: QDF status 182 */ 183 static inline QDF_STATUS scheduler_post_msg(uint32_t qid, 184 struct scheduler_msg *msg) 185 { 186 return scheduler_post_msg_by_priority(qid, msg, false); 187 } 188 189 /** 190 * scheduler_post_message() - post normal messages(no priority) 191 * @src_id: Source module of the message 192 * @dest_id: Destination module of the message 193 * @que_id: Queue to which the message has to posted. 194 * @msg: message pointer 195 * 196 * This function will mask the src_id, and destination id to qid of 197 * scheduler_post_msg 198 * Return: QDF status 199 */ 200 QDF_STATUS scheduler_post_message_debug(QDF_MODULE_ID src_id, 201 QDF_MODULE_ID dest_id, 202 QDF_MODULE_ID que_id, 203 struct scheduler_msg *msg, 204 int line, 205 const char *func); 206 207 #define scheduler_post_message(src_id, dest_id, que_id, msg) \ 208 scheduler_post_message_debug(src_id, dest_id, que_id, msg, \ 209 __LINE__, __func__) 210 211 /** 212 * scheduler_resume() - resume scheduler thread 213 * 214 * Complete scheduler thread resume wait event such that scheduler 215 * thread can wake up and process message queues 216 * 217 * Return: none 218 */ 219 void scheduler_resume(void); 220 221 /** 222 * scheduler_register_hdd_suspend_callback() - suspend callback to hdd 223 * @callback: hdd callback to be called when controllred thread is suspended 224 * 225 * Return: none 226 */ 227 void scheduler_register_hdd_suspend_callback(hdd_suspend_callback callback); 228 229 /** 230 * scheduler_wake_up_controller_thread() - wake up controller thread 231 * 232 * Wake up controller thread to process a critical message. 233 * 234 * Return: none 235 */ 236 void scheduler_wake_up_controller_thread(void); 237 238 /** 239 * scheduler_set_event_mask() - set given event mask 240 * @event_mask: event mask to set 241 * 242 * Set given event mask such that controller scheduler thread can do 243 * specified work after wake up. 244 * 245 * Return: none 246 */ 247 void scheduler_set_event_mask(uint32_t event_mask); 248 249 /** 250 * scheduler_clear_event_mask() - clear given event mask 251 * @event_mask: event mask to set 252 * 253 * Return: none 254 */ 255 void scheduler_clear_event_mask(uint32_t event_mask); 256 257 /** 258 * scheduler_target_if_mq_handler() - top level message queue handler for 259 * target_if message queue 260 * @msg: pointer to actual message being handled 261 * 262 * Return: none 263 */ 264 QDF_STATUS scheduler_target_if_mq_handler(struct scheduler_msg *msg); 265 266 /** 267 * scheduler_os_if_mq_handler() - top level message queue handler for 268 * os_if message queue 269 * @msg: pointer to actual message being handled 270 * 271 * Return: none 272 */ 273 QDF_STATUS scheduler_os_if_mq_handler(struct scheduler_msg *msg); 274 275 /** 276 * scheduler_timer_q_mq_handler() - top level message queue handler for 277 * timer queue 278 * @msg: pointer to actual message being handled 279 * 280 * Return: none 281 */ 282 QDF_STATUS scheduler_timer_q_mq_handler(struct scheduler_msg *msg); 283 284 /** 285 * scheduler_mlme_mq_handler() - top level message queue handler for 286 * mlme queue 287 * @msg: pointer to actual message being handled 288 * 289 * Return: QDF status 290 */ 291 QDF_STATUS scheduler_mlme_mq_handler(struct scheduler_msg *msg); 292 293 /** 294 * scheduler_scan_mq_handler() - top level message queue handler for 295 * scan queue 296 * @msg: pointer to actual message being handled 297 * 298 * Return: QDF status 299 */ 300 QDF_STATUS scheduler_scan_mq_handler(struct scheduler_msg *msg); 301 302 /** 303 * scheduler_register_wma_legacy_handler() - register legacy wma handler 304 * @callback: legacy wma handler to be called for WMA messages 305 * 306 * Return: QDF status 307 */ 308 QDF_STATUS scheduler_register_wma_legacy_handler(scheduler_msg_process_fn_t 309 callback); 310 311 /** 312 * scheduler_register_sys_legacy_handler() - register legacy sys handler 313 * @callback: legacy sys handler to be called for sys messages 314 * 315 * Return: QDF status 316 */ 317 QDF_STATUS scheduler_register_sys_legacy_handler(scheduler_msg_process_fn_t 318 callback); 319 /** 320 * scheduler_deregister_sys_legacy_handler() - deregister legacy sys handler 321 * 322 * Return: QDF status 323 */ 324 QDF_STATUS scheduler_deregister_sys_legacy_handler(void); 325 326 /** 327 * scheduler_deregister_wma_legacy_handler() - deregister legacy wma handler 328 * 329 * Return: QDF status 330 */ 331 QDF_STATUS scheduler_deregister_wma_legacy_handler(void); 332 333 /** 334 * scheduler_mc_timer_callback() - timer callback, gets called at time out 335 * @timer: holds the mc timer object. 336 * 337 * Return: None 338 */ 339 void scheduler_mc_timer_callback(qdf_mc_timer_t *timer); 340 341 /** 342 * scheduler_get_queue_size() - Get the current size of the scheduler queue 343 * @qid: Queue ID for which the size is requested 344 * @size: Pointer to size where the size would be returned to the caller 345 * 346 * This API finds the size of the scheduler queue for the given Queue ID 347 * 348 * Return: QDF Status 349 */ 350 QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size); 351 #endif 352