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