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