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