xref: /wlan-dirver/qca-wifi-host-cmn/qdf/inc/qdf_time.h (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
2  * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * DOC: qdf_time
30  * This file abstracts time related functionality.
31  */
32 
33 #ifndef _QDF_OS_TIME_H
34 #define _QDF_OS_TIME_H
35 
36 #include <i_qdf_time.h>
37 
38 typedef __qdf_time_t qdf_time_t;
39 typedef __qdf_ktime_t qdf_ktime_t;
40 
41 /**
42  * qdf_ns_to_ktime - Converts nanoseconds to a qdf_ktime_t object
43  * @ns: time in nanoseconds
44  *
45  * Return: nanoseconds as qdf_ktime_t object
46  */
47 
48 static inline qdf_ktime_t qdf_ns_to_ktime(uint64_t ns)
49 {
50 	return __qdf_ns_to_ktime(ns);
51 }
52 
53 /**
54  * qdf_ktime_add - Adds two qdf_ktime_t objects and returns
55  * a qdf_ktime_t object
56  * @ktime1: time as qdf_ktime_t object
57  * @ktime2: time as qdf_ktime_t object
58  *
59  * Return: sum of both qdf_ktime_t as qdf_ktime_t object
60  */
61 
62 static inline qdf_ktime_t qdf_ktime_add(qdf_ktime_t ktime1, qdf_ktime_t ktime2)
63 {
64 	return __qdf_ktime_add(ktime1, ktime2);
65 }
66 
67 /**
68  * qdf_ktime_get - Gets the current time as qdf_ktime_t object
69  *
70  * Return: current time as qdf_ktime_t object
71  */
72 
73 static inline qdf_ktime_t qdf_ktime_get(void)
74 {
75 	return __qdf_ktime_get();
76 }
77 
78 /**
79  * qdf_ktime_add_ns - Adds qdf_ktime_t object and nanoseconds value and
80  * returns the qdf_ktime_t object
81  * @ktime: time as qdf_ktime_t object
82  * @ns: time in nanoseconds
83  *
84  * Return: qdf_ktime_t object
85  */
86 
87 static inline qdf_ktime_t qdf_ktime_add_ns(qdf_ktime_t ktime, int64_t ns)
88 {
89 	return __qdf_ktime_add_ns(ktime, ns);
90 }
91 
92 /**
93  * qdf_ktime_to_ms - Convert the qdf_ktime_t object into milliseconds
94  * @ktime: time as qdf_ktime_t object
95  *
96  * Return: qdf_ktime_t in milliseconds
97  */
98 
99 static inline int64_t qdf_ktime_to_ms(qdf_ktime_t ktime)
100 {
101 	return __qdf_ktime_to_ms(ktime);
102 }
103 
104 /**
105  * qdf_ktime_to_ns - Convert the qdf_ktime_t object into nanoseconds
106  * @ktime: time as qdf_ktime_t object
107  *
108  * Return: qdf_ktime_t in nanoseconds
109  */
110 
111 static inline int64_t qdf_ktime_to_ns(qdf_ktime_t ktime)
112 {
113 	return __qdf_ktime_to_ns(ktime);
114 }
115 
116 /**
117  * qdf_system_ticks - Count the number of ticks elapsed from the time when
118  * the system booted
119  *
120  * Return: ticks
121  */
122 static inline qdf_time_t qdf_system_ticks(void)
123 {
124 	return __qdf_system_ticks();
125 }
126 
127 /**
128  * qdf_system_ticks_to_msecs - convert ticks to milliseconds
129  * @clock_ticks: Number of ticks
130  *
131  * Return: unsigned int Time in milliseconds
132  */
133 static inline uint32_t qdf_system_ticks_to_msecs(unsigned long clock_ticks)
134 {
135 	return __qdf_system_ticks_to_msecs(clock_ticks);
136 }
137 
138 /**
139  * qdf_system_msecs_to_ticks - convert milliseconds to ticks
140  * @msec: Time in milliseconds
141  *
142  * Return: unsigned long number of ticks
143  */
144 static inline qdf_time_t qdf_system_msecs_to_ticks(uint32_t msecs)
145 {
146 	return __qdf_system_msecs_to_ticks(msecs);
147 }
148 
149 /**
150  * qdf_get_system_uptime - Return a monotonically increasing time
151  * This increments once per HZ ticks
152  *
153  * Return: qdf_time_t system up time in ticks
154  */
155 static inline qdf_time_t qdf_get_system_uptime(void)
156 {
157 	return __qdf_get_system_uptime();
158 }
159 
160 /**
161  * qdf_get_bootbased_boottime_ns() - Get the bootbased time in nanoseconds
162  *
163  * qdf_get_bootbased_boottime_ns() function returns the number of nanoseconds
164  * that have elapsed since the system was booted. It also includes the time when
165  * system was suspended.
166  *
167  * Return:
168  * The time since system booted in nanoseconds
169  */
170 
171 #if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 10, 0))
172 static inline s64 qdf_get_bootbased_boottime_ns(void)
173 {
174 	return ktime_get_boot_ns();
175 }
176 
177 #else
178 static inline s64 qdf_get_bootbased_boottime_ns(void)
179 {
180 	return ktime_to_ns(ktime_get_boottime());
181 }
182 #endif
183 
184 /**
185  * qdf_get_system_timestamp - Return current timestamp
186  *
187  * Return: unsigned long timestamp in ms.
188  */
189 static inline unsigned long qdf_get_system_timestamp(void)
190 {
191 	return __qdf_get_system_timestamp();
192 }
193 
194 /**
195  * qdf_udelay - delay in microseconds
196  * @usecs: Number of microseconds to delay
197  *
198  * Return: none
199  */
200 static inline void qdf_udelay(int usecs)
201 {
202 	__qdf_udelay(usecs);
203 }
204 
205 /**
206  * qdf_mdelay - Delay in milliseconds.
207  * @msec: Number of milliseconds to delay
208  *
209  * Return: none
210  */
211 static inline void qdf_mdelay(int msecs)
212 {
213 	__qdf_mdelay(msecs);
214 }
215 
216 /**
217  * qdf_system_time_after() - Check if a is later than b
218  * @a: Time stamp value a
219  * @b: Time stamp value b
220  *
221  * Return:
222  * true if a < b else false
223  */
224 static inline bool qdf_system_time_after(qdf_time_t a, qdf_time_t b)
225 {
226 	return __qdf_system_time_after(a, b);
227 }
228 
229 /**
230  * qdf_system_time_before() - Check if a is before b
231  * @a: Time stamp value a
232  * @b: Time stamp value b
233  *
234  * Return:
235  * true if a is before b else false
236  */
237 static inline bool qdf_system_time_before(qdf_time_t a, qdf_time_t b)
238 {
239 	return __qdf_system_time_before(a, b);
240 }
241 
242 /**
243  * qdf_system_time_after_eq() - Check if a atleast as recent as b, if not
244  * later
245  * @a: Time stamp value a
246  * @b: Time stamp value b
247  *
248  * Return:
249  * true if a >= b else false
250  */
251 static inline bool qdf_system_time_after_eq(qdf_time_t a, qdf_time_t b)
252 {
253 	return __qdf_system_time_after_eq(a, b);
254 }
255 
256 /**
257  * enum qdf_timestamp_unit - what unit the qdf timestamp is in
258  * @KERNEL_LOG: boottime time in uS (micro seconds)
259  * @QTIMER: QTIME in (1/19200)S
260  *
261  * This enum is used to distinguish which timer source is used.
262  */
263 enum qdf_timestamp_unit {
264 	KERNEL_LOG,
265 	QTIMER,
266 };
267 
268 #ifdef QCA_WIFI_3_0_ADRASTEA
269 #define QDF_LOG_TIMESTAMP_UNIT QTIMER
270 #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 192
271 
272 static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
273 {
274 	/*
275 	 * Try to preserve precision by multiplying by 10 first.
276 	 * If that would cause a wrap around, divide first instead.
277 	 */
278 	if (time * 10 < time) {
279 		do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
280 		return time * 10;
281 	}
282 
283 	time = time * 10;
284 	do_div(time, QDF_LOG_TIMESTAMP_CYCLES_PER_10_US);
285 
286 	return time;
287 }
288 #else
289 #define QDF_LOG_TIMESTAMP_UNIT KERNEL_LOG
290 #define QDF_LOG_TIMESTAMP_CYCLES_PER_10_US 10
291 
292 static inline uint64_t qdf_log_timestamp_to_usecs(uint64_t time)
293 {
294 	/* timestamps are already in micro seconds */
295 	return time;
296 }
297 #endif
298 
299 static inline void qdf_log_timestamp_to_secs(uint64_t time, uint64_t *secs,
300 					     uint64_t *usecs)
301 {
302 	*secs = qdf_log_timestamp_to_usecs(time);
303 	*usecs = do_div(*secs, 1000000ul);
304 }
305 
306 static inline uint64_t qdf_usecs_to_log_timestamp(uint64_t usecs)
307 {
308 	return (usecs * QDF_LOG_TIMESTAMP_CYCLES_PER_10_US) / 10;
309 }
310 
311 /**
312  * qdf_get_log_timestamp - get time stamp for logging
313  * For adrastea this API returns QTIMER tick which is needed to synchronize
314  * host and fw log timestamps
315  * For ROME and other discrete solution this API returns system boot time stamp
316  *
317  * Return:
318  * QTIMER ticks(19.2MHz) for adrastea
319  * System tick for rome and other future discrete solutions
320  */
321 static inline uint64_t qdf_get_log_timestamp(void)
322 {
323 	return __qdf_get_log_timestamp();
324 }
325 
326 /**
327  * qdf_get_monotonic_boottime - get monotonic kernel boot time
328  * This API is similar to qdf_get_system_boottime but it includes
329  * time spent in suspend.
330  *
331  * Return: Time in microseconds
332  */
333 static inline uint64_t qdf_get_monotonic_boottime(void)
334 {
335 	return __qdf_get_monotonic_boottime();
336 }
337 
338 #endif
339