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