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 documenation */ 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