1 /* 2 * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #if !defined(__SCHEDULER_API_H) 21 #define __SCHEDULER_API_H 22 23 #include <qdf_event.h> 24 #include <qdf_types.h> 25 #include <qdf_lock.h> 26 #include <qdf_mc_timer.h> 27 #include <qdf_status.h> 28 29 /* Controller thread various event masks 30 * MC_POST_EVENT_MASK: wake up thread after posting message 31 * MC_SUSPEND_EVENT_MASK: signal thread to suspend during kernel pm suspend 32 * MC_SHUTDOWN_EVENT_MASK: signal thread to shutdown and exit during unload 33 */ 34 #define MC_POST_EVENT_MASK 0x001 35 #define MC_SUSPEND_EVENT_MASK 0x002 36 #define MC_SHUTDOWN_EVENT_MASK 0x010 37 38 /* 39 * Cookie for timer messages. Note that anyone posting a timer message 40 * has to write the COOKIE in the reserved field of the message. The 41 * timer queue handler relies on this COOKIE 42 */ 43 #define SYS_MSG_COOKIE 0xFACE 44 45 #define scheduler_get_src_id(qid) (((qid) >> 20) & 0x3FF) 46 #define scheduler_get_dest_id(qid) (((qid) >> 10) & 0x3FF) 47 #define scheduler_get_que_id(qid) ((qid) & 0x3FF) 48 #define scheduler_get_qid(src, dest, que_id) ((que_id) | ((dest) << 10) |\ 49 ((src) << 20)) 50 51 typedef enum { 52 SYS_MSG_ID_MC_TIMER, 53 SYS_MSG_ID_FTM_RSP, 54 SYS_MSG_ID_QVIT, 55 SYS_MSG_ID_DATA_STALL_MSG, 56 SYS_MSG_ID_UMAC_STOP, 57 } SYS_MSG_ID; 58 59 struct scheduler_msg; 60 typedef QDF_STATUS (*scheduler_msg_process_fn_t)(struct scheduler_msg *msg); 61 typedef void (*hdd_suspend_callback)(void); 62 63 /** 64 * struct scheduler_msg: scheduler message structure 65 * @type: message type 66 * @reserved: reserved field 67 * @bodyval: message body val 68 * @bodyptr: message body pointer based on the type either a bodyptr pointer 69 * into memory or bodyval as a 32 bit data is used. bodyptr is always a 70 * freeable pointer, one should always make sure that bodyptr is always 71 * freeable. 72 * Messages should use either bodyptr or bodyval; not both !!! 73 * @callback: callback to be called by scheduler thread once message is posted 74 * and scheduler thread has started processing the message. 75 * @flush_callback: flush callback which will be invoked during driver unload 76 * such that component can release the ref count of common global objects 77 * like PSOC, PDEV, VDEV and PEER. A component needs to populate flush 78 * callback in message body pointer for those messages which have taken ref 79 * count for above mentioned common objects. 80 * @node: list node for queue membership 81 * @queue_id: Id of the queue the message was added to 82 * @queue_depth: depth of the queue when the message was queued 83 * @queued_at_us: timestamp when the message was queued in microseconds 84 */ 85 struct scheduler_msg { 86 uint16_t type; 87 uint16_t reserved; 88 uint32_t bodyval; 89 void *bodyptr; 90 scheduler_msg_process_fn_t callback; 91 scheduler_msg_process_fn_t flush_callback; 92 qdf_list_node_t node; 93 #ifdef WLAN_SCHED_HISTORY_SIZE 94 QDF_MODULE_ID queue_id; 95 uint32_t queue_depth; 96 uint64_t queued_at_us; 97 #endif /* WLAN_SCHED_HISTORY_SIZE */ 98 }; 99 100 struct sched_qdf_mc_timer_cb_wrapper; 101 102 /** 103 * scheduler_qdf_mc_timer_init() - initialize and fill callback and data 104 * @timer_callback: callback to timer 105 * @data: data pointer 106 * 107 * Return: return pointer to struct sched_qdf_mc_timer_cb_wrapper 108 */ 109 struct sched_qdf_mc_timer_cb_wrapper *scheduler_qdf_mc_timer_init( 110 qdf_mc_timer_callback_t timer_callback, 111 void *data); 112 113 /** 114 * scheduler_qdf_mc_timer_deinit_return_data_ptr() - deinitialize callback and 115 * return data 116 * @wrapper_ptr: wrapper ptr 117 * 118 * Return: original data supplied to scheduler_qdf_mc_timer_init() 119 */ 120 void *scheduler_qdf_mc_timer_deinit_return_data_ptr( 121 struct sched_qdf_mc_timer_cb_wrapper *wrapper_ptr); 122 123 /** 124 * scheduler_qdf_mc_timer_callback_t_wrapper() - wrapper for mc timer callbacks 125 * @msg: message pointer 126 * 127 * Return: None 128 */ 129 QDF_STATUS scheduler_qdf_mc_timer_callback_t_wrapper(struct scheduler_msg *msg); 130 131 /** 132 * sched_history_print() - print scheduler history 133 * 134 * This API prints the scheduler history. 135 * 136 * Return: None 137 */ 138 void sched_history_print(void); 139 140 /** 141 * scheduler_init() - initialize control path scheduler 142 * 143 * This API initializes control path scheduler. 144 * 145 * Return: QDF status 146 */ 147 QDF_STATUS scheduler_init(void); 148 149 /** 150 * scheduler_deinit() - de-initialize control path scheduler 151 * 152 * This API de-initializes control path scheduler. 153 * 154 * Return: QDF status 155 */ 156 QDF_STATUS scheduler_deinit(void); 157 158 /** 159 * scheduler_enable() - start the scheduler module 160 * 161 * Ready the scheduler module to service requests, and start the scheduler's 162 * message processing thread. Must only be called after scheduler_init(). 163 * 164 * Return: QDF_STATUS 165 */ 166 QDF_STATUS scheduler_enable(void); 167 168 /** 169 * scheduler_disable() - stop the scheduler module 170 * 171 * Stop the scheduler module from servicing requests, and terminate the 172 * scheduler's message processing thread. Must be called before 173 * scheduler_deinit(). 174 * 175 * Return: QDF_STATUS 176 */ 177 QDF_STATUS scheduler_disable(void); 178 179 /** 180 * scheduler_register_module() - register input module/queue id 181 * @qid: queue id to get registered 182 * @callback: queue message to be called when a message is posted 183 * 184 * Return: QDF status 185 */ 186 QDF_STATUS scheduler_register_module(QDF_MODULE_ID qid, 187 scheduler_msg_process_fn_t callback); 188 189 /** 190 * scheduler_deregister_module() - deregister input module/queue id 191 * @qid: queue id to get deregistered 192 * 193 * Return: QDF status 194 */ 195 QDF_STATUS scheduler_deregister_module(QDF_MODULE_ID qid); 196 197 /** 198 * scheduler_post_msg_by_priority() - post messages by priority 199 * @qid: queue id to which the message has to be posted. 200 * @msg: message pointer 201 * @is_high_priority: set to true for high priority message else false 202 * 203 * Return: QDF status 204 */ 205 QDF_STATUS scheduler_post_msg_by_priority(uint32_t qid, 206 struct scheduler_msg *msg, 207 bool is_high_priority); 208 209 /** 210 * scheduler_post_msg() - post normal messages(no priority) 211 * @qid: queue id to which the message has to be posted. 212 * @msg: message pointer 213 * 214 * Return: QDF status 215 */ scheduler_post_msg(uint32_t qid,struct scheduler_msg * msg)216 static inline QDF_STATUS scheduler_post_msg(uint32_t qid, 217 struct scheduler_msg *msg) 218 { 219 return scheduler_post_msg_by_priority(qid, msg, false); 220 } 221 222 /** 223 * scheduler_post_message_debug() - post normal messages(no priority) 224 * @src_id: Source module of the message 225 * @dest_id: Destination module of the message 226 * @que_id: Queue to which the message has to posted. 227 * @msg: message pointer 228 * @line: caller line number 229 * @func: caller function 230 * 231 * This function will mask the src_id, and destination id to qid of 232 * scheduler_post_msg 233 * 234 * Return: QDF status 235 */ 236 QDF_STATUS scheduler_post_message_debug(QDF_MODULE_ID src_id, 237 QDF_MODULE_ID dest_id, 238 QDF_MODULE_ID que_id, 239 struct scheduler_msg *msg, 240 int line, 241 const char *func); 242 243 /** 244 * scheduler_post_message() - post normal messages(no priority) 245 * @src_id: Source module of the message 246 * @dest_id: Destination module of the message 247 * @que_id: Queue to which the message has to posted. 248 * @msg: message pointer 249 * 250 * This function will mask the src_id, and destination id to qid of 251 * scheduler_post_msg 252 * 253 * Return: QDF status 254 */ 255 #define scheduler_post_message(src_id, dest_id, que_id, msg) \ 256 scheduler_post_message_debug(src_id, dest_id, que_id, msg, \ 257 __LINE__, __func__) 258 259 /** 260 * scheduler_resume() - resume scheduler thread 261 * 262 * Complete scheduler thread resume wait event such that scheduler 263 * thread can wake up and process message queues 264 * 265 * Return: none 266 */ 267 void scheduler_resume(void); 268 269 /** 270 * scheduler_set_watchdog_timeout() - set scheduler timeout for msg processing 271 * @timeout: timeout value in milliseconds 272 * 273 * Configure the timeout for triggering the scheduler watchdog timer 274 * in milliseconds 275 * 276 * Return: none 277 */ 278 void scheduler_set_watchdog_timeout(uint32_t timeout); 279 280 /** 281 * scheduler_register_hdd_suspend_callback() - suspend callback to hdd 282 * @callback: hdd callback to be called when controller thread is suspended 283 * 284 * Return: none 285 */ 286 void scheduler_register_hdd_suspend_callback(hdd_suspend_callback callback); 287 288 /** 289 * scheduler_wake_up_controller_thread() - wake up controller thread 290 * 291 * Wake up controller thread to process a critical message. 292 * 293 * Return: none 294 */ 295 void scheduler_wake_up_controller_thread(void); 296 297 /** 298 * scheduler_set_event_mask() - set given event mask 299 * @event_mask: event mask to set 300 * 301 * Set given event mask such that controller scheduler thread can do 302 * specified work after wake up. 303 * 304 * Return: none 305 */ 306 void scheduler_set_event_mask(uint32_t event_mask); 307 308 /** 309 * scheduler_clear_event_mask() - clear given event mask 310 * @event_mask: event mask to set 311 * 312 * Return: none 313 */ 314 void scheduler_clear_event_mask(uint32_t event_mask); 315 316 /** 317 * scheduler_target_if_mq_handler() - top level message queue handler for 318 * target_if message queue 319 * @msg: pointer to actual message being handled 320 * 321 * Return: none 322 */ 323 QDF_STATUS scheduler_target_if_mq_handler(struct scheduler_msg *msg); 324 325 /** 326 * scheduler_os_if_mq_handler() - top level message queue handler for 327 * os_if message queue 328 * @msg: pointer to actual message being handled 329 * 330 * Return: none 331 */ 332 QDF_STATUS scheduler_os_if_mq_handler(struct scheduler_msg *msg); 333 334 /** 335 * scheduler_timer_q_mq_handler() - top level message queue handler for 336 * timer queue 337 * @msg: pointer to actual message being handled 338 * 339 * Return: none 340 */ 341 QDF_STATUS scheduler_timer_q_mq_handler(struct scheduler_msg *msg); 342 343 /** 344 * scheduler_mlme_mq_handler() - top level message queue handler for 345 * mlme queue 346 * @msg: pointer to actual message being handled 347 * 348 * Return: QDF status 349 */ 350 QDF_STATUS scheduler_mlme_mq_handler(struct scheduler_msg *msg); 351 352 /** 353 * scheduler_scan_mq_handler() - top level message queue handler for 354 * scan queue 355 * @msg: pointer to actual message being handled 356 * 357 * Return: QDF status 358 */ 359 QDF_STATUS scheduler_scan_mq_handler(struct scheduler_msg *msg); 360 361 /** 362 * scheduler_register_wma_legacy_handler() - register legacy wma handler 363 * @callback: legacy wma handler to be called for WMA messages 364 * 365 * Return: QDF status 366 */ 367 QDF_STATUS scheduler_register_wma_legacy_handler(scheduler_msg_process_fn_t 368 callback); 369 370 /** 371 * scheduler_register_sys_legacy_handler() - register legacy sys handler 372 * @callback: legacy sys handler to be called for sys messages 373 * 374 * Return: QDF status 375 */ 376 QDF_STATUS scheduler_register_sys_legacy_handler(scheduler_msg_process_fn_t 377 callback); 378 /** 379 * scheduler_deregister_sys_legacy_handler() - deregister legacy sys handler 380 * 381 * Return: QDF status 382 */ 383 QDF_STATUS scheduler_deregister_sys_legacy_handler(void); 384 385 /** 386 * scheduler_deregister_wma_legacy_handler() - deregister legacy wma handler 387 * 388 * Return: QDF status 389 */ 390 QDF_STATUS scheduler_deregister_wma_legacy_handler(void); 391 392 /** 393 * scheduler_mc_timer_callback() - timer callback, gets called at time out 394 * @timer: holds the mc timer object. 395 * 396 * Return: None 397 */ 398 void scheduler_mc_timer_callback(qdf_mc_timer_t *timer); 399 400 /** 401 * scheduler_get_queue_size() - Get the current size of the scheduler queue 402 * @qid: Queue ID for which the size is requested 403 * @size: Pointer to size where the size would be returned to the caller 404 * 405 * This API finds the size of the scheduler queue for the given Queue ID 406 * 407 * Return: QDF Status 408 */ 409 QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size); 410 #endif 411