1 /*
2 * Copyright (c) 2014-2019, 2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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 /**
82 * qdf_try_allowing_sleep() - clean up timer states after it has been deactivated
83 * @type: timer type
84 *
85 * Clean up timer states after it has been deactivated check and try to allow
86 * sleep after a timer has been stopped or expired.
87 *
88 * Return: none
89 */
90 void qdf_try_allowing_sleep(QDF_TIMER_TYPE type);
91
92 #ifdef TIMER_MANAGER
93 /**
94 * qdf_mc_timer_manager_init() - initialize QDF debug timer manager
95 * This API initializes QDF timer debug functionality.
96 *
97 * Return: none
98 */
99 void qdf_mc_timer_manager_init(void);
100
101 /**
102 * qdf_mc_timer_manager_exit() - exit QDF timer debug functionality
103 * This API exists QDF timer debug functionality
104 *
105 * Return: none
106 */
107 void qdf_mc_timer_manager_exit(void);
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 void qdf_mc_timer_check_for_leaks(void);
117 #else
qdf_mc_timer_manager_init(void)118 static inline void qdf_mc_timer_manager_init(void)
119 {
120 }
121
qdf_mc_timer_manager_exit(void)122 static inline void qdf_mc_timer_manager_exit(void)
123 {
124 }
125
qdf_mc_timer_check_for_leaks(void)126 static inline void qdf_mc_timer_check_for_leaks(void)
127 {
128 }
129 #endif
130 /**
131 * qdf_mc_timer_get_current_state() - get the current state of the timer
132 * @timer: Pointer to timer object
133 *
134 * Return:
135 * QDF_TIMER_STATE - qdf timer state
136 */
137 QDF_TIMER_STATE qdf_mc_timer_get_current_state(qdf_mc_timer_t *timer);
138
139 /**
140 * qdf_mc_timer_init() - initialize a QDF timer
141 * @timer: Pointer to timer object
142 * @timer_type: Type of timer
143 * @callback: Callback to be called after timer expiry
144 * @user_data: User data which will be passed to callback function
145 *
146 * This API initializes a QDF Timer object.
147 *
148 * qdf_mc_timer_init() initializes a QDF Timer object. A timer must be
149 * initialized by calling qdf_mc_timer_initialize() before it may be used in
150 * any other timer functions.
151 *
152 * Attempting to initialize timer that is already initialized results in
153 * a failure. A destroyed timer object can be re-initialized with a call to
154 * qdf_mc_timer_init(). The results of otherwise referencing the object
155 * after it has been destroyed are undefined.
156 *
157 * Calls to QDF timer functions to manipulate the timer such
158 * as qdf_mc_timer_set() will fail if the timer is not initialized or has
159 * been destroyed. Therefore, don't use the timer after it has been
160 * destroyed until it has been re-initialized.
161 *
162 * All callback will be executed within the CDS main thread unless it is
163 * initialized from the Tx thread flow, in which case it will be executed
164 * within the tx thread flow.
165 *
166 * Return:
167 * QDF_STATUS_SUCCESS - Timer is initialized successfully
168 * QDF failure status - Timer initialization failed
169 */
170 #ifdef TIMER_MANAGER
171 #define qdf_mc_timer_init(timer, timer_type, callback, user_data) \
172 qdf_mc_timer_init_debug(timer, timer_type, callback, user_data, \
173 __FILE__, __LINE__)
174
175 QDF_STATUS qdf_mc_timer_init_debug(qdf_mc_timer_t *timer,
176 QDF_TIMER_TYPE timer_type,
177 qdf_mc_timer_callback_t callback,
178 void *user_data, char *file_name,
179 uint32_t line_num);
180 #else
181 QDF_STATUS qdf_mc_timer_init(qdf_mc_timer_t *timer, QDF_TIMER_TYPE timer_type,
182 qdf_mc_timer_callback_t callback,
183 void *user_data);
184 #endif
185
186 /**
187 * qdf_mc_timer_destroy() - destroy QDF timer
188 * @timer: Pointer to timer object
189 *
190 * qdf_mc_timer_destroy() function shall destroy the timer object.
191 * After a successful return from \a qdf_mc_timer_destroy() the timer
192 * object becomes, in effect, uninitialized.
193 *
194 * A destroyed timer object can be re-initialized by calling
195 * qdf_mc_timer_init(). The results of otherwise referencing the object
196 * after it has been destroyed are undefined.
197 *
198 * Calls to QDF timer functions to manipulate the timer, such
199 * as qdf_mc_timer_set() will fail if the lock is destroyed. Therefore,
200 * don't use the timer after it has been destroyed until it has
201 * been re-initialized.
202 *
203 * Return:
204 * QDF_STATUS_SUCCESS - Timer is initialized successfully
205 * QDF failure status - Timer initialization failed
206 */
207 QDF_STATUS qdf_mc_timer_destroy(qdf_mc_timer_t *timer);
208
209 /**
210 * qdf_mc_timer_start() - start a QDF Timer object
211 * @timer: Pointer to timer object
212 * @expiration_time: Time to expire
213 *
214 * qdf_mc_timer_start() function starts a timer to expire after the
215 * specified interval, thus running the timer callback function when
216 * the interval expires.
217 *
218 * A timer only runs once (a one-shot timer). To re-start the
219 * timer, qdf_mc_timer_start() has to be called after the timer runs
220 * or has been cancelled.
221 *
222 * Return:
223 * QDF_STATUS_SUCCESS - Timer is initialized successfully
224 * QDF failure status - Timer initialization failed
225 */
226 QDF_STATUS qdf_mc_timer_start(qdf_mc_timer_t *timer, uint32_t expiration_time);
227
228 /**
229 * qdf_mc_timer_stop() - stop a QDF Timer
230 * @timer: Pointer to timer object
231 * qdf_mc_timer_stop() function stops a timer that has been started but
232 * has not expired, essentially cancelling the 'start' request.
233 *
234 * After a timer is stopped, it goes back to the state it was in after it
235 * was created and can be started again via a call to qdf_mc_timer_start().
236 *
237 * Return:
238 * QDF_STATUS_SUCCESS - Timer is initialized successfully
239 * QDF failure status - Timer initialization failed
240 */
241 QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer);
242
243 /**
244 * qdf_mc_timer_stop_sync() - stop a QDF Timer
245 * @timer: Pointer to timer object
246 * qdf_mc_timer_stop_sync() function stops a timer synchronously
247 * that has been started but has not expired, essentially
248 * cancelling the 'start' request.
249 *
250 * After a timer is stopped, it goes back to the state it was in after it
251 * was created and can be started again via a call to qdf_mc_timer_start().
252 *
253 * Return:
254 * QDF_STATUS_SUCCESS - Timer is initialized successfully
255 * QDF failure status - Timer initialization failed
256 */
257 QDF_STATUS qdf_mc_timer_stop_sync(qdf_mc_timer_t *timer);
258
259 /**
260 * qdf_mc_timer_get_system_ticks() - get the system time in 10ms ticks
261 *
262 * qdf_mc_timer_get_system_ticks() function returns the current number
263 * of timer ticks in 10msec intervals. This function is suitable timestamping
264 * and calculating time intervals by calculating the difference between two
265 * timestamps.
266 *
267 * Return:
268 * The current system tick count (in 10msec intervals). This
269 * function cannot fail.
270 */
271 unsigned long qdf_mc_timer_get_system_ticks(void);
272
273 /**
274 * qdf_mc_timer_get_system_time() - Get the system time in milliseconds
275 *
276 * qdf_mc_timer_get_system_time() function returns the number of milliseconds
277 * that have elapsed since the system was started
278 *
279 * Return:
280 * The current system time in milliseconds
281 */
282 unsigned long qdf_mc_timer_get_system_time(void);
283
284 /**
285 * qdf_get_monotonic_boottime_ns() - Get kernel boottime in ns
286 *
287 * Return: kernel boottime in nano sec (includes time spent in suspend)
288 */
289 s64 qdf_get_monotonic_boottime_ns(void);
290
291 /**
292 * qdf_timer_module_init() - initializes a QDF timer module.
293 *
294 * This API initializes the QDF timer module. This needs to be called
295 * exactly once prior to using any QDF timers.
296 *
297 * Return: none
298 */
299 void qdf_timer_module_init(void);
300
301 /**
302 * qdf_get_time_of_the_day_us() - Get time of the day in microseconds
303 *
304 * Return: None
305 */
306 uint64_t qdf_get_time_of_the_day_us(void);
307
308 /**
309 * qdf_get_time_of_the_day_ms() - get time of the day in millisec
310 *
311 * Return: time of the day in ms
312 */
313 qdf_time_t qdf_get_time_of_the_day_ms(void);
314
315 /**
316 * qdf_timer_module_deinit() - Deinitializes the QDF timer module.
317 *
318 * This API deinitializes the QDF timer module.
319 * Return: none
320 */
321 void qdf_timer_module_deinit(void);
322
323 /**
324 * qdf_get_time_of_the_day_in_hr_min_sec_usec() - Get system time
325 * @tbuf: Pointer to time stamp buffer
326 * @len: Time buffer size
327 *
328 * This function updates the 'tbuf' with system time in hr:min:sec:msec format
329 *
330 * Return: None
331 */
332 void qdf_get_time_of_the_day_in_hr_min_sec_usec(char *tbuf, int len);
333
334 void qdf_register_mc_timer_callback(void (*callback) (qdf_mc_timer_t *data));
335
336 /**
337 * qdf_timer_set_multiplier() - set the global QDF timer scalar value
338 * @multiplier: the scalar value to apply
339 *
340 * Return: None
341 */
342 void qdf_timer_set_multiplier(uint32_t multiplier);
343
344 /**
345 * qdf_timer_get_multiplier() - get the global QDF timer scalar value
346 *
347 * Return: the global QDF timer scalar value
348 */
349 uint32_t qdf_timer_get_multiplier(void);
350
351 #endif /* __QDF_MC_TIMER_H */
352