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