xref: /wlan-dirver/qca-wifi-host-cmn/scheduler/inc/scheduler_core.h (revision d78dedc9dd8c4ee677ac1649d1d42f2a7c3cc1b7)
1 /*
2  * Copyright (c) 2014-2018 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_CORE_H)
20 #define __SCHEDULER_CORE_H
21 
22 #include <qdf_threads.h>
23 #include <qdf_timer.h>
24 #include <scheduler_api.h>
25 #include <qdf_list.h>
26 
27 #ifdef CONFIG_MCL
28 #define SCHEDULER_CORE_MAX_MESSAGES 1000
29 #else
30 #define SCHEDULER_CORE_MAX_MESSAGES 2000
31 #define WLAN_SCHED_REDUCTION_LIMIT 32
32 #endif
33 #define SCHEDULER_NUMBER_OF_MSG_QUEUE 6
34 #define SCHEDULER_WRAPPER_MAX_FAIL_COUNT (SCHEDULER_CORE_MAX_MESSAGES * 3)
35 #define SCHEDULER_WATCHDOG_TIMEOUT (10 * 1000) /* 10s */
36 
37 #define __sched_log(level, format, args...) \
38 	QDF_TRACE(QDF_MODULE_ID_SCHEDULER, level, FL(format), ## args)
39 
40 #define sched_fatal(format, args...) \
41 	__sched_log(QDF_TRACE_LEVEL_FATAL, format, ## args)
42 #define sched_err(format, args...) \
43 	__sched_log(QDF_TRACE_LEVEL_ERROR, format, ## args)
44 #define sched_warn(format, args...) \
45 	__sched_log(QDF_TRACE_LEVEL_WARN, format, ## args)
46 #define sched_info(format, args...) \
47 	__sched_log(QDF_TRACE_LEVEL_INFO, format, ## args)
48 #define sched_debug(format, args...) \
49 	__sched_log(QDF_TRACE_LEVEL_DEBUG, format, ## args)
50 
51 #define sched_enter() sched_debug("Enter")
52 #define sched_exit() sched_debug("Exit")
53 
54 /**
55  * struct scheduler_mq_type -  scheduler message queue
56  * @mq_lock: message queue lock
57  * @mq_list: message queue list
58  * @qid: queue id
59  */
60 struct scheduler_mq_type {
61 	qdf_spinlock_t mq_lock;
62 	qdf_list_t mq_list;
63 	QDF_MODULE_ID qid;
64 };
65 
66 /**
67  * struct scheduler_msg_wrapper - scheduler message wrapper
68  * @msg_node: message node
69  * @msg_buf: message buffer pointer
70  */
71 struct scheduler_msg_wrapper {
72 	qdf_list_node_t msg_node;
73 	struct scheduler_msg *msg_buf;
74 };
75 
76 /**
77  * struct scheduler_mq_ctx - scheduler message queue context
78  * @msg_buffers: array of message buffers
79  * @msg_wrappers: array of message wrappers
80  * @free_msg_q: free message queue
81  * @sch_msg_q: scheduler message queue
82  * @scheduler_msg_qid_to_qidx: message qid to qidx mapping
83  * @scheduler_msg_process_fn: array of message queue handler function pointers
84  */
85 struct scheduler_mq_ctx {
86 	struct scheduler_msg msg_buffers[SCHEDULER_CORE_MAX_MESSAGES];
87 	struct scheduler_msg_wrapper msg_wrappers[SCHEDULER_CORE_MAX_MESSAGES];
88 	struct scheduler_mq_type free_msg_q;
89 	struct scheduler_mq_type sch_msg_q[SCHEDULER_NUMBER_OF_MSG_QUEUE];
90 	uint8_t scheduler_msg_qid_to_qidx[QDF_MODULE_ID_MAX];
91 	QDF_STATUS (*scheduler_msg_process_fn[SCHEDULER_NUMBER_OF_MSG_QUEUE])
92 					(struct scheduler_msg *msg);
93 };
94 
95 /**
96  * struct scheduler_ctx - scheduler context
97  * @queue_ctx: message queue context
98  * @sch_start_event: scheduler thread start wait event
99  * @sch_thread: scheduler thread
100  * @sch_shutdown: scheduler thread shutdown wait event
101  * @sch_wait_queue: scheduler wait queue
102  * @sch_event_flag: scheduler events flag
103  * @resume_sch_event: scheduler resume wait event
104  * @sch_thread_lock: scheduler thread lock
105  * @sch_last_qidx: scheduler last qidx allocation
106  * @hdd_callback: os if suspend callback
107  * @legacy_wma_handler: legacy wma message handler
108  * @legacy_sys_handler: legacy sys message handler
109  * @watchdog_timer: timer for triggering a scheduler watchdog bite
110  * @watchdog_msg_type: 'type' of the current msg being processed
111  * @watchdog_callback: the callback of the current msg being processed
112  */
113 struct scheduler_ctx {
114 	struct scheduler_mq_ctx queue_ctx;
115 	qdf_event_t sch_start_event;
116 	qdf_thread_t *sch_thread;
117 	qdf_event_t sch_shutdown;
118 	qdf_wait_queue_head_t sch_wait_queue;
119 	unsigned long sch_event_flag;
120 	qdf_event_t resume_sch_event;
121 	qdf_spinlock_t sch_thread_lock;
122 	uint8_t sch_last_qidx;
123 	hdd_suspend_callback hdd_callback;
124 	scheduler_msg_process_fn_t legacy_wma_handler;
125 	scheduler_msg_process_fn_t legacy_sys_handler;
126 	qdf_timer_t watchdog_timer;
127 	uint16_t watchdog_msg_type;
128 	void *watchdog_callback;
129 };
130 
131 
132 /**
133  * scheduler_get_context() - to get scheduler context
134  *
135  * This routine is used retrieve scheduler context
136  *
137  * Return: Pointer to scheduler context
138  */
139 struct scheduler_ctx *scheduler_get_context(void);
140 /**
141  * scheduler_thread() - spawned thread will execute this routine
142  * @arg: pointer to scheduler context
143  *
144  * Newly created thread will use this routine to perform its duty
145  *
146  * Return: none
147  */
148 int scheduler_thread(void *arg);
149 
150 /**
151  * scheduler_cleanup_queues() - to clean up the given module's queue
152  * @sch_ctx: pointer to scheduler context
153  * @idx: index of the queue which needs to be cleanup.
154  *
155  * This routine  is used to clean the module's queue provided by
156  * user through idx field
157  *
158  * Return: none
159  */
160 void scheduler_cleanup_queues(struct scheduler_ctx *sch_ctx, int idx);
161 /**
162  * scheduler_create_ctx() - to create scheduler context
163  *
164  * This routine is used to create scheduler context
165  *
166  * Return: QDF_STATUS based on success or failure
167  */
168 QDF_STATUS scheduler_create_ctx(void);
169 /**
170  * scheduler_destroy_ctx() - to destroy scheduler context
171  *
172  * This routine is used to destroy scheduler context
173  *
174  * Return: QDF_STATUS based on success or failure
175  */
176 QDF_STATUS scheduler_destroy_ctx(void);
177 /**
178  * scheduler_mq_init() - initialize scheduler message queue
179  * @msg_q: Pointer to the message queue
180  *
181  * This function initializes the Message queue.
182  *
183  * Return: qdf status
184  */
185 QDF_STATUS scheduler_mq_init(struct scheduler_mq_type *msg_q);
186 /**
187  * scheduler_mq_deinit() - de-initialize scheduler message queue
188  * @msg_q: Pointer to the message queue
189  *
190  * This function de-initializes scheduler message queue
191  *
192  *  Return: none
193  */
194 void scheduler_mq_deinit(struct scheduler_mq_type *msg_q);
195 /**
196  * scheduler_mq_put() - put message in the back of queue
197  * @msg_q: Pointer to the message queue
198  * @msg_wrapper: pointer to message wrapper
199  *
200  * This function is used to put message in back of provided message
201  * queue
202  *
203  *  Return: none
204  */
205 void scheduler_mq_put(struct scheduler_mq_type *msg_q,
206 			struct scheduler_msg_wrapper *msg_wrapper);
207 /**
208  * scheduler_mq_put_front() - put message in the front of queue
209  * @msg_q: Pointer to the message queue
210  * @msg_wrapper: pointer to message wrapper
211  *
212  * This function is used to put message in front of provided message
213  * queue
214  *
215  *  Return: none
216  */
217 void scheduler_mq_put_front(struct scheduler_mq_type *msg_q,
218 			struct scheduler_msg_wrapper *msg_wrapper);
219 /**
220  * scheduler_mq_get() - to get message from message queue
221  * @msg_q: Pointer to the message queue
222  *
223  * This function is used to get message from given message queue
224  *
225  *  Return: none
226  */
227 struct scheduler_msg_wrapper *scheduler_mq_get(struct scheduler_mq_type *msg_q);
228 /**
229  * scheduler_is_mq_empty() - to check if message queue is empty
230  * @msg_q: Pointer to the message queue
231  *
232  * This function is used to check if message queue is empty
233  *
234  * Return: true or false
235  */
236 bool scheduler_is_mq_empty(struct scheduler_mq_type *msg_q);
237 /**
238  * scheduler_queues_init() - to initialize all the modules' queues
239  * @sched_ctx: pointer to scheduler context
240  *
241  * This function is used to initialize the queues for all the modules
242  *
243  * Return: QDF_STATUS based on success of failure
244  */
245 QDF_STATUS scheduler_queues_init(struct scheduler_ctx *sched_ctx);
246 /**
247  * scheduler_queues_deinit() - to de-initialize all the modules' queues
248  * @sched_ctx: pointer to scheduler context
249  *
250  * This function is used to de-initialize the queues for all the modules
251  *
252  * Return: QDF_STATUS based on success of failure
253  */
254 QDF_STATUS scheduler_queues_deinit(struct scheduler_ctx *gp_sch_ctx);
255 #endif
256