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