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