xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_mc_timer.h (revision 5ee6661e575b5422cbb88a7703b46f397b551bd9)
1 /*
2  * Copyright (c) 2014-2019, 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 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 /**
21  * DOC: qdf_mc_timer
22  * QCA driver framework timer APIs serialized to MC thread
23  */
24 
25 #if !defined(__QDF_MC_TIMER_H)
26 #define __QDF_MC_TIMER_H
27 
28 /* Include Files */
29 #include <qdf_types.h>
30 #include <qdf_status.h>
31 #include <qdf_lock.h>
32 #include <i_qdf_mc_timer.h>
33 
34 #ifdef TIMER_MANAGER
35 #include <qdf_list.h>
36 #endif
37 
38 /* Preprocessor definitions and constants */
39 #define QDF_TIMER_STATE_COOKIE (0x12)
40 #define QDF_MC_TIMER_TO_MS_UNIT (1000)
41 #define QDF_MC_TIMER_TO_SEC_UNIT (1000000)
42 
43 /* Type declarations */
44 /* qdf Timer callback function prototype (well, actually a prototype for
45  * a pointer to this callback function)
46  */
47 typedef void (*qdf_mc_timer_callback_t)(void *user_data);
48 
49 typedef enum {
50 	QDF_TIMER_STATE_UNUSED = QDF_TIMER_STATE_COOKIE,
51 	QDF_TIMER_STATE_STOPPED,
52 	QDF_TIMER_STATE_STARTING,
53 	QDF_TIMER_STATE_RUNNING,
54 } QDF_TIMER_STATE;
55 
56 #ifdef TIMER_MANAGER
57 struct qdf_mc_timer_s;
58 typedef struct qdf_mc_timer_node_s {
59 	qdf_list_node_t node;
60 	char *file_name;
61 	uint32_t line_num;
62 	struct qdf_mc_timer_s *qdf_timer;
63 } qdf_mc_timer_node_t;
64 #endif
65 
66 typedef struct qdf_mc_timer_s {
67 #ifdef TIMER_MANAGER
68 	qdf_mc_timer_node_t *timer_node;
69 #endif
70 	qdf_mc_timer_platform_t platform_info;
71 	qdf_mc_timer_callback_t callback;
72 	void *user_data;
73 	qdf_mutex_t lock;
74 	QDF_TIMER_TYPE type;
75 	QDF_TIMER_STATE state;
76 	qdf_time_t timer_start_jiffies;
77 	qdf_time_t timer_end_jiffies;
78 } qdf_mc_timer_t;
79 
80 
81 void qdf_try_allowing_sleep(QDF_TIMER_TYPE type);
82 
83 /* Function declarations and documentation */
84 #ifdef TIMER_MANAGER
85 void qdf_mc_timer_manager_init(void);
86 void qdf_mc_timer_manager_exit(void);
87 void qdf_mc_timer_check_for_leaks(void);
88 #else
89 /**
90  * qdf_mc_timer_manager_init() - initialize QDF debug timer manager
91  * This API initializes QDF timer debug functionality.
92  *
93  * Return: none
94  */
95 static inline void qdf_mc_timer_manager_init(void)
96 {
97 }
98 
99 /**
100  * qdf_mc_timer_manager_exit() - exit QDF timer debug functionality
101  * This API exists QDF timer debug functionality
102  *
103  * Return: none
104  */
105 static inline void qdf_mc_timer_manager_exit(void)
106 {
107 }
108 
109 /**
110  * qdf_mc_timer_check_for_leaks() - Assert there are no active mc timers
111  *
112  * If there are active timers, this API prints them and panics.
113  *
114  * Return: None
115  */
116 static inline void qdf_mc_timer_check_for_leaks(void) { }
117 #endif
118 /**
119  * qdf_mc_timer_get_current_state() - get the current state of the timer
120  * @timer:  Pointer to timer object
121  *
122  * Return:
123  * QDF_TIMER_STATE - qdf timer state
124  */
125 
126 QDF_TIMER_STATE qdf_mc_timer_get_current_state(qdf_mc_timer_t *timer);
127 
128 /**
129  * qdf_mc_timer_init() - initialize a QDF timer
130  * @timer: Pointer to timer object
131  * @timer_type: Type of timer
132  * @callback: Callback to be called after timer expiry
133  * @ser_data: User data which will be passed to callback function
134  *
135  * This API initializes a QDF Timer object.
136  *
137  * qdf_mc_timer_init() initializes a QDF Timer object.  A timer must be
138  * initialized by calling qdf_mc_timer_initialize() before it may be used in
139  * any other timer functions.
140  *
141  * Attempting to initialize timer that is already initialized results in
142  * a failure. A destroyed timer object can be re-initialized with a call to
143  * qdf_mc_timer_init().  The results of otherwise referencing the object
144  * after it has been destroyed are undefined.
145  *
146  *  Calls to QDF timer functions to manipulate the timer such
147  *  as qdf_mc_timer_set() will fail if the timer is not initialized or has
148  *  been destroyed.  Therefore, don't use the timer after it has been
149  *  destroyed until it has been re-initialized.
150  *
151  *  All callback will be executed within the CDS main thread unless it is
152  *  initialized from the Tx thread flow, in which case it will be executed
153  *  within the tx thread flow.
154  *
155  * Return:
156  * QDF_STATUS_SUCCESS - Timer is initialized successfully
157  * QDF failure status - Timer initialization failed
158  */
159 #ifdef TIMER_MANAGER
160 #define qdf_mc_timer_init(timer, timer_type, callback, userdata) \
161 	qdf_mc_timer_init_debug(timer, timer_type, callback, userdata, \
162 				__FILE__, __LINE__)
163 
164 QDF_STATUS qdf_mc_timer_init_debug(qdf_mc_timer_t *timer,
165 				   QDF_TIMER_TYPE timer_type,
166 				   qdf_mc_timer_callback_t callback,
167 				   void *user_data, char *file_name,
168 				   uint32_t line_num);
169 #else
170 QDF_STATUS qdf_mc_timer_init(qdf_mc_timer_t *timer, QDF_TIMER_TYPE timer_type,
171 			     qdf_mc_timer_callback_t callback,
172 			     void *user_data);
173 #endif
174 
175 /**
176  * qdf_mc_timer_destroy() - destroy QDF timer
177  * @timer: Pointer to timer object
178  *
179  * qdf_mc_timer_destroy() function shall destroy the timer object.
180  * After a successful return from \a qdf_mc_timer_destroy() the timer
181  * object becomes, in effect, uninitialized.
182  *
183  * A destroyed timer object can be re-initialized by calling
184  * qdf_mc_timer_init().  The results of otherwise referencing the object
185  * after it has been destroyed are undefined.
186  *
187  * Calls to QDF timer functions to manipulate the timer, such
188  * as qdf_mc_timer_set() will fail if the lock is destroyed.  Therefore,
189  * don't use the timer after it has been destroyed until it has
190  * been re-initialized.
191  *
192  * Return:
193  * QDF_STATUS_SUCCESS - Timer is initialized successfully
194  * QDF failure status - Timer initialization failed
195  */
196 QDF_STATUS qdf_mc_timer_destroy(qdf_mc_timer_t *timer);
197 
198 /**
199  * qdf_mc_timer_start() - start a QDF Timer object
200  * @timer: Pointer to timer object
201  * @expiration_time: Time to expire
202  *
203  * qdf_mc_timer_start() function starts a timer to expire after the
204  * specified interval, thus running the timer callback function when
205  * the interval expires.
206  *
207  * A timer only runs once (a one-shot timer).  To re-start the
208  * timer, qdf_mc_timer_start() has to be called after the timer runs
209  * or has been cancelled.
210  *
211  * Return:
212  * QDF_STATUS_SUCCESS - Timer is initialized successfully
213  * QDF failure status - Timer initialization failed
214  */
215 QDF_STATUS qdf_mc_timer_start(qdf_mc_timer_t *timer, uint32_t expiration_time);
216 
217 /**
218  * qdf_mc_timer_stop() - stop a QDF Timer
219  * @timer: Pointer to timer object
220  * qdf_mc_timer_stop() function stops a timer that has been started but
221  * has not expired, essentially cancelling the 'start' request.
222  *
223  * After a timer is stopped, it goes back to the state it was in after it
224  * was created and can be started again via a call to qdf_mc_timer_start().
225  *
226  * Return:
227  * QDF_STATUS_SUCCESS - Timer is initialized successfully
228  * QDF failure status - Timer initialization failed
229  */
230 QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer);
231 
232 /**
233  * qdf_mc_timer_stop_sync() - stop a QDF Timer
234  * @timer: Pointer to timer object
235  * qdf_mc_timer_stop_sync() function stops a timer synchronously
236  * that has been started but has not expired, essentially
237  * cancelling the 'start' request.
238  *
239  * After a timer is stopped, it goes back to the state it was in after it
240  * was created and can be started again via a call to qdf_mc_timer_start().
241  *
242  * Return:
243  * QDF_STATUS_SUCCESS - Timer is initialized successfully
244  * QDF failure status - Timer initialization failed
245  */
246 QDF_STATUS qdf_mc_timer_stop_sync(qdf_mc_timer_t *timer);
247 
248 /**
249  * qdf_mc_timer_get_system_ticks() - get the system time in 10ms ticks
250  *
251  * qdf_mc_timer_get_system_ticks() function returns the current number
252  * of timer ticks in 10msec intervals.  This function is suitable timestamping
253  * and calculating time intervals by calculating the difference between two
254  * timestamps.
255  *
256  * Return:
257  * The current system tick count (in 10msec intervals).  This
258  * function cannot fail.
259  */
260 unsigned long qdf_mc_timer_get_system_ticks(void);
261 
262 /**
263  * qdf_mc_timer_get_system_time() - Get the system time in milliseconds
264  *
265  * qdf_mc_timer_get_system_time() function returns the number of milliseconds
266  * that have elapsed since the system was started
267  *
268  * Return:
269  * The current system time in milliseconds
270  */
271 unsigned long qdf_mc_timer_get_system_time(void);
272 
273 /**
274  * qdf_get_monotonic_boottime_ns() - Get kernel boottime in ns
275  *
276  * Return: kernel boottime in nano sec (includes time spent in suspend)
277  */
278 s64 qdf_get_monotonic_boottime_ns(void);
279 
280 /**
281  * qdf_timer_module_init() - initializes a QDF timer module.
282  *
283  * This API initializes the QDF timer module. This needs to be called
284  * exactly once prior to using any QDF timers.
285  *
286  * Return: none
287  */
288 void qdf_timer_module_init(void);
289 
290 /**
291  * qdf_get_time_of_the_day_us() - Get time of the day in microseconds
292  *
293  * Return: None
294  */
295 uint64_t qdf_get_time_of_the_day_us(void);
296 
297 /**
298  * qdf_get_time_of_the_day_ms() - get time of the day in millisec
299  *
300  * Return: time of the day in ms
301  */
302 qdf_time_t qdf_get_time_of_the_day_ms(void);
303 
304 /**
305  * qdf_timer_module_deinit() - Deinitializes a QDF timer module.
306  *
307  * This API deinitializes the QDF timer module.
308  * Return: none
309  */
310 void qdf_timer_module_deinit(void);
311 
312 /**
313  * qdf_get_time_of_the_day_in_hr_min_sec_usec() - Get system time
314  * @tbuf: Pointer to time stamp buffer
315  * @len: Time buffer size
316  *
317  * This function updates the 'tbuf' with system time in hr:min:sec:msec format
318  *
319  * Return: None
320  */
321 void qdf_get_time_of_the_day_in_hr_min_sec_usec(char *tbuf, int len);
322 
323 void qdf_register_mc_timer_callback(void (*callback) (qdf_mc_timer_t *data));
324 
325 /**
326  * qdf_timer_set_multiplier() - set the global QDF timer scalar value
327  * @multiplier: the scalar value to apply
328  *
329  * Return: None
330  */
331 void qdf_timer_set_multiplier(uint32_t multiplier);
332 
333 /**
334  * qdf_timer_get_multiplier() - get the global QDF timer scalar value
335  *
336  * Return: the global QDF timer scalar value
337  */
338 uint32_t qdf_timer_get_multiplier(void);
339 
340 #endif /* __QDF_MC_TIMER_H */
341