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