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