1 /*
2 * Copyright (c) 2016-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 #if !defined WLAN_HDD_TSF_H
21 #define WLAN_HDD_TSF_H
22 #include "wlan_hdd_cfg.h"
23 #include "wlan_hdd_main.h"
24 #ifdef WLAN_FEATURE_TSF_ACCURACY
25 #include "qdf_hrtimer.h"
26 #endif
27 /**
28 * enum hdd_tsf_get_state - status of get tsf action
29 * @TSF_RETURN: get tsf
30 * @TSF_STA_NOT_CONNECTED_NO_TSF: sta not connected to ap
31 * @TSF_NOT_RETURNED_BY_FW: fw not returned tsf
32 * @TSF_CURRENT_IN_CAP_STATE: driver in capture state
33 * @TSF_CAPTURE_FAIL: capture fail
34 * @TSF_GET_FAIL: get fail
35 * @TSF_RESET_GPIO_FAIL: GPIO reset fail
36 * @TSF_SAP_NOT_STARTED_NO_TSF: SAP not started
37 * @TSF_NOT_READY: TSF module is not initialized or init failed
38 * @TSF_DISABLED_BY_TSFPLUS: cap_tsf/get_tsf are disabled due to TSF_PLUS
39 */
40 enum hdd_tsf_get_state {
41 TSF_RETURN = 0,
42 TSF_STA_NOT_CONNECTED_NO_TSF,
43 TSF_NOT_RETURNED_BY_FW,
44 TSF_CURRENT_IN_CAP_STATE,
45 TSF_CAPTURE_FAIL,
46 TSF_GET_FAIL,
47 TSF_RESET_GPIO_FAIL,
48 TSF_SAP_NOT_STARTED_NO_TSF,
49 TSF_NOT_READY,
50 TSF_DISABLED_BY_TSFPLUS
51 };
52
53 /**
54 * enum hdd_tsf_capture_state - status of capture
55 * @TSF_IDLE: idle
56 * @TSF_CAP_STATE: current is in capture state
57 */
58 enum hdd_tsf_capture_state {
59 TSF_IDLE = 0,
60 TSF_CAP_STATE
61 };
62
63 /**
64 * struct hdd_tsf_op_response - Store TSF sync parameters if TSF sync is active
65 * @status: TSF response status defined by enum hdd_tsf_get_state
66 * @time: TSF sync Target time. Time unit is microseconds.
67 * @soc_time: TSF sync SOC time. Time unit is microseconds.
68 */
69 struct hdd_tsf_op_response {
70 enum hdd_tsf_get_state status;
71 uint64_t time;
72 uint64_t soc_time;
73 };
74
75 /**
76 * enum hdd_tsf_auto_rpt_source - trigger source of tsf auto report
77 * @HDD_TSF_AUTO_RPT_SOURCE_UPLINK_DELAY: uplink delay feature
78 * @HDD_TSF_AUTO_RPT_SOURCE_TX_LATENCY: transmit latency statistics
79 */
80 enum hdd_tsf_auto_rpt_source {
81 HDD_TSF_AUTO_RPT_SOURCE_UPLINK_DELAY,
82 HDD_TSF_AUTO_RPT_SOURCE_TX_LATENCY,
83 };
84
85 #ifdef WLAN_FEATURE_TSF_AUTO_REPORT
86 /**
87 * hdd_set_tsf_auto_report() - enable or disable tsf auto report
88 * for an adapter
89 * @adapter: pointer to Adapter context
90 * @ena: requesting state (true or false)
91 * @source: source of the request
92 *
93 * Return: 0 for success or non-zero negative failure code
94 */
95 int
96 hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena,
97 enum hdd_tsf_auto_rpt_source source);
98
99 /**
100 * hdd_tsf_auto_report_init() - initialize tsf auto report related
101 * structures for an adapter
102 * @adapter: pointer to Adapter context
103 *
104 * Return: None
105 */
106 void hdd_tsf_auto_report_init(struct hdd_adapter *adapter);
107 #else
108 static inline int
hdd_set_tsf_auto_report(struct hdd_adapter * adapter,bool ena,enum hdd_tsf_auto_rpt_source source)109 hdd_set_tsf_auto_report(struct hdd_adapter *adapter, bool ena,
110 enum hdd_tsf_auto_rpt_source source)
111 {
112 return -ENOTSUPP;
113 }
114
hdd_tsf_auto_report_init(struct hdd_adapter * adapter)115 static inline void hdd_tsf_auto_report_init(struct hdd_adapter *adapter)
116 {
117 }
118 #endif
119
120 /**
121 * struct hdd_vdev_tsf - Adapter level tsf params
122 * @cur_target_time: tsf value received from firmware.
123 * @cur_tsf_sync_soc_time: Current SOC time.
124 * @last_tsf_sync_soc_time: Last SOC time when TSF was synced.
125 * @cur_target_global_tsf_time: Global Fw TSF time.
126 * @last_target_global_tsf_time: Last reported global Fw TSF time.
127 * @host_capture_req_timer: Host timer to capture TSF time.
128 * @tsf_id: TSF id as obtained from FW report.
129 * @tsf_mac_id: mac_id as obtained from FW report.
130 * @tsf_details_valid: flag indicating whether tsf details are valid.
131 * @host_target_sync_lock: spin lock for read/write timestamps.
132 * @host_target_sync_timer: Timer to Sync host target.
133 * @host_trigger_gpio_timer: A hrtimer used for TSF Accuracy Feature to
134 * indicate TSF cycle complete.
135 * @enable_dynamic_tsf_sync: Enable/Disable TSF sync through NL interface.
136 * @host_target_sync_force: Force update host to TSF mapping.
137 * @dynamic_tsf_sync_interval: TSF sync interval configure through NL interface.
138 * @cur_host_time: Current Host time.
139 * @last_host_time: Host time when TSF read was done.
140 * @last_target_time: Last Fw reported time when TSF read was done.
141 * @continuous_error_count: Store the count of continuous invalid tstamp-pair.
142 * @continuous_cap_retry_count: to store the count of continuous capture retry.
143 * @tsf_sync_ready_flag: to indicate whether tsf_sync has been initialized.
144 * @gpio_tsf_sync_work: work to sync send TSF CAP WMI command.
145 * @auto_rpt_src: bitmap to record trigger sources of TSF auto report
146 */
147 struct hdd_vdev_tsf {
148 uint64_t cur_target_time;
149 uint64_t cur_tsf_sync_soc_time;
150 uint64_t last_tsf_sync_soc_time;
151 uint64_t cur_target_global_tsf_time;
152 uint64_t last_target_global_tsf_time;
153 qdf_mc_timer_t host_capture_req_timer;
154 #ifdef QCA_GET_TSF_VIA_REG
155 int tsf_id;
156 int tsf_mac_id;
157 qdf_atomic_t tsf_details_valid;
158 #endif
159 #ifdef WLAN_FEATURE_TSF_PLUS
160 qdf_spinlock_t host_target_sync_lock;
161 qdf_mc_timer_t host_target_sync_timer;
162 #ifdef WLAN_FEATURE_TSF_ACCURACY
163 qdf_hrtimer_data_t host_trigger_gpio_timer;
164 #endif
165 bool enable_dynamic_tsf_sync;
166 bool host_target_sync_force;
167 uint32_t dynamic_tsf_sync_interval;
168 uint64_t cur_host_time;
169 uint64_t last_host_time;
170 uint64_t last_target_time;
171 int continuous_error_count;
172 int continuous_cap_retry_count;
173 qdf_atomic_t tsf_sync_ready_flag;
174 #ifdef WLAN_FEATURE_TSF_PLUS_EXT_GPIO_SYNC
175 qdf_work_t gpio_tsf_sync_work;
176 #endif
177 #endif /* WLAN_FEATURE_TSF_PLUS */
178 #ifdef WLAN_FEATURE_TSF_AUTO_REPORT
179 unsigned long auto_rpt_src;
180
181 #endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */
182 };
183
184 /**
185 * struct hdd_ctx_tsf - Context level tsf params
186 * @tsf_ready_flag: indicate whether tsf has been initialized.
187 * @cap_tsf_flag: indicate whether it's now capturing tsf(updating tstamp-pair).
188 * @cap_tsf_context: the context that is capturing tsf.
189 * @tsf_accuracy_context: the context that is capturing tsf accuracy.
190 * @ptp_cinfo: TSF PTP clock info.
191 * @ptp_clock: TSF PTP clock.
192 */
193 struct hdd_ctx_tsf {
194 qdf_atomic_t tsf_ready_flag;
195 qdf_atomic_t cap_tsf_flag;
196 struct hdd_adapter *cap_tsf_context;
197 #ifdef WLAN_FEATURE_TSF_ACCURACY
198 struct hdd_adapter *tsf_accuracy_context;
199 #endif
200 #ifdef WLAN_FEATURE_TSF_PTP
201 struct ptp_clock_info ptp_cinfo;
202 struct ptp_clock *ptp_clock;
203 #endif
204 };
205
206 #ifdef WLAN_FEATURE_TSF_UPLINK_DELAY
207 /**
208 * hdd_get_uplink_delay_len() - get uplink delay length
209 * @adapter: pointer to the adapter
210 *
211 * Return: uplink delay length
212 */
213 uint32_t hdd_get_uplink_delay_len(struct hdd_adapter *adapter);
214
215 /**
216 * hdd_add_uplink_delay() - add uplink delay
217 * @adapter: pointer to the adapter
218 * @skb: nbuf
219 *
220 * Return: status
221 */
222 QDF_STATUS hdd_add_uplink_delay(struct hdd_adapter *adapter,
223 struct sk_buff *skb);
224 #else /* !WLAN_FEATURE_TSF_UPLINK_DELAY */
hdd_get_uplink_delay_len(struct hdd_adapter * adapter)225 static inline uint32_t hdd_get_uplink_delay_len(struct hdd_adapter *adapter)
226 {
227 return 0;
228 }
229
hdd_add_uplink_delay(struct hdd_adapter * adapter,struct sk_buff * skb)230 static inline QDF_STATUS hdd_add_uplink_delay(struct hdd_adapter *adapter,
231 struct sk_buff *skb)
232 {
233 return QDF_STATUS_SUCCESS;
234 }
235 #endif /* WLAN_FEATURE_TSF_UPLINK_DELAY */
236 #ifdef WLAN_FEATURE_TSF
237 /**
238 * wlan_hdd_tsf_init() - set gpio and callbacks for
239 * capturing tsf and init tsf_plus
240 * @hdd_ctx: pointer to the struct hdd_context
241 *
242 * This function set the callback to sme module, the callback will be
243 * called when a tsf event is reported by firmware; set gpio number
244 * to FW, FW will toggle this gpio when received a CAP_TSF command;
245 * do tsf_plus init
246 *
247 * Return: nothing
248 */
249 void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx);
250
251 /**
252 * wlan_hdd_tsf_deinit() - reset callbacks for capturing tsf, deinit tsf_plus
253 * @hdd_ctx: pointer to the struct hdd_context
254 *
255 * This function reset the callback to sme module, and deinit tsf_plus
256 *
257 * Return: nothing
258 */
259 void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx);
260
261 /**
262 * hdd_capture_tsf() - capture tsf
263 * @adapter: pointer to adapter
264 * @buf: pointer to uplayer buf
265 * @len : the length of buf
266 *
267 * This function returns tsf value to uplayer.
268 *
269 * Return: 0 for success or non-zero negative failure code
270 */
271 int hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len);
272
273 /**
274 * hdd_indicate_tsf() - return tsf to uplayer
275 *
276 * @adapter: pointer to adapter
277 * @tsf_op_resp: pointer to struct hdd_tsf_op_response
278 *
279 * This function returns tsf value to uplayer.
280 *
281 * Return: Describe the execute result of this routine
282 */
283 int hdd_indicate_tsf(struct hdd_adapter *adapter,
284 struct hdd_tsf_op_response *tsf_op_resp);
285
286 /**
287 * wlan_hdd_cfg80211_handle_tsf_cmd(): Setup TSF operations
288 * @wiphy: Pointer to wireless phy
289 * @wdev: Pointer to wireless device
290 * @data: Pointer to data
291 * @data_len: Data length
292 *
293 * Handle TSF SET / GET operation from userspace
294 *
295 * Return: 0 on success, negative errno on failure
296 */
297 int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
298 struct wireless_dev *wdev,
299 const void *data,
300 int data_len);
301
302 int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf);
303
304 extern const struct nla_policy tsf_policy[QCA_WLAN_VENDOR_ATTR_TSF_MAX + 1];
305
306 #define FEATURE_HANDLE_TSF_VENDOR_COMMANDS \
307 { \
308 .info.vendor_id = QCA_NL80211_VENDOR_ID, \
309 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF, \
310 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \
311 WIPHY_VENDOR_CMD_NEED_NETDEV | \
312 WIPHY_VENDOR_CMD_NEED_RUNNING, \
313 .doit = wlan_hdd_cfg80211_handle_tsf_cmd, \
314 vendor_command_policy(tsf_policy, QCA_WLAN_VENDOR_ATTR_TSF_MAX)\
315 },
316 #else
wlan_hdd_tsf_init(struct hdd_context * hdd_ctx)317 static inline void wlan_hdd_tsf_init(struct hdd_context *hdd_ctx)
318 {
319 }
320
wlan_hdd_tsf_deinit(struct hdd_context * hdd_ctx)321 static inline void wlan_hdd_tsf_deinit(struct hdd_context *hdd_ctx)
322 {
323 }
324
hdd_indicate_tsf(struct hdd_adapter * adapter,struct hdd_tsf_op_response * tsf_op_resp)325 static inline int hdd_indicate_tsf(struct hdd_adapter *adapter,
326 struct hdd_tsf_op_response *tsf_op_resp)
327 {
328 return -ENOTSUPP;
329 }
330
331 static inline int
hdd_capture_tsf(struct hdd_adapter * adapter,uint32_t * buf,int len)332 hdd_capture_tsf(struct hdd_adapter *adapter, uint32_t *buf, int len)
333 {
334 return -ENOTSUPP;
335 }
336
wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,const void * data,int data_len)337 static inline int wlan_hdd_cfg80211_handle_tsf_cmd(struct wiphy *wiphy,
338 struct wireless_dev *wdev,
339 const void *data,
340 int data_len)
341 {
342 return -ENOTSUPP;
343 }
hdd_get_tsf_cb(void * pcb_cxt,struct stsf * ptsf)344 static inline int hdd_get_tsf_cb(void *pcb_cxt, struct stsf *ptsf)
345 {
346 return -ENOTSUPP;
347 }
348
349 #define FEATURE_HANDLE_TSF_VENDOR_COMMANDS
350 #endif
351
352 #if defined(WLAN_FEATURE_TSF_PLUS) && defined(WLAN_FEATURE_TSF)
353 /**
354 * hdd_tsf_is_tx_set() - check ini configuration
355 * @hdd: pointer to hdd context
356 *
357 * This function checks tsf configuration for ptp on tx
358 *
359 * Return: true on enable, false on disable
360 */
361
362 bool hdd_tsf_is_tx_set(struct hdd_context *hdd);
363 /**
364 * hdd_tsf_is_rx_set() - check ini configuration
365 * @hdd: pointer to hdd context
366 *
367 * This function checks tsf configuration for ptp on rx
368 *
369 * Return: true on enable, false on disable
370 */
371 bool hdd_tsf_is_rx_set(struct hdd_context *hdd);
372 /**
373 * hdd_tsf_is_raw_set() - check ini configuration
374 * @hdd: pointer to hdd context
375 *
376 * This function checks tsf configuration for ptp on raw
377 *
378 * Return: true on enable, false on disable
379 */
380 bool hdd_tsf_is_raw_set(struct hdd_context *hdd);
381 /**
382 * hdd_tsf_is_dbg_fs_set() - check ini configuration
383 * @hdd: pointer to hdd context
384 *
385 * This function checks tsf configuration for ptp on dbg fs
386 *
387 * Return: true on enable, false on disable
388 */
389 bool hdd_tsf_is_dbg_fs_set(struct hdd_context *hdd);
390
391 /**
392 * hdd_start_tsf_sync() - start tsf sync
393 * @adapter: pointer to adapter
394 *
395 * This function initialize and start TSF synchronization
396 *
397 * Return: Describe the execute result of this routine
398 */
399 int hdd_start_tsf_sync(struct hdd_adapter *adapter);
400
401 /**
402 * hdd_restart_tsf_sync_post_wlan_resume() - restart host TSF sync
403 * @adapter: pointer to adapter
404 *
405 * This function restarts host TSF sync immediately after wlan resume
406 *
407 * Return: none
408 */
409 void hdd_restart_tsf_sync_post_wlan_resume(struct hdd_adapter *adapter);
410
411 /**
412 * hdd_stop_tsf_sync() - stop tsf sync
413 * @adapter: pointer to adapter
414 *
415 * This function stop and de-initialize TSF synchronization
416 *
417 * Return: Describe the execute result of this routine
418 */
419 int hdd_stop_tsf_sync(struct hdd_adapter *adapter);
420
421 /**
422 * hdd_capture_req_timer_expired_handler() - capture req timer handler
423 * @arg: pointer to a adapter
424 *
425 * This function set a timeout handler for TSF capture timer.
426 *
427 * Return: none
428 */
429
430 void hdd_capture_req_timer_expired_handler(void *arg);
431
432 /**
433 * hdd_tsf_is_tsf64_tx_set() - check ini configuration
434 * @hdd: pointer to hdd context
435 *
436 * This function checks tsf configuration for ptp on tsf64 tx
437 *
438 * Return: true on enable, false on disable
439 */
440 bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd);
441
442 /**
443 * hdd_tsf_is_time_sync_enabled_cfg() - check ini configuration
444 * @hdd_ctx: pointer to hdd context
445 *
446 * This function checks tsf configuration for ptp for tsf
447 * sync period
448 * Return: true on enable, false on disable
449 */
450 bool hdd_tsf_is_time_sync_enabled_cfg(struct hdd_context *hdd_ctx);
451
452 /**
453 * hdd_update_dynamic_tsf_sync - Configure TSF mode for vdev
454 * @adapter: pointer to hdd adapter
455 *
456 * This function configures TSF mode for vdev with ini parameter
457 */
458 void hdd_update_dynamic_tsf_sync(struct hdd_adapter *adapter);
459
460 #ifdef WLAN_FEATURE_TSF_PLUS_SOCK_TS
461 /**
462 * hdd_rx_timestamp() - time stamp RX netbuf
463 *
464 * @netbuf: pointer to a RX netbuf
465 * @target_time: RX time for the netbuf
466 *
467 * This function get corresponding host time from target time,
468 * and time stamp the RX netbuf with this time
469 *
470 * Return: Describe the execute result of this routine
471 */
472 int hdd_rx_timestamp(qdf_nbuf_t netbuf, uint64_t target_time);
473 #endif
474
475 /**
476 * hdd_get_tsf_time() - get tsf time for system time
477 *
478 * @adapter_ctx: adapter context
479 * @input_time: input system time
480 * @tsf_time: tsf time for system time
481 *
482 * Return: qdf status
483 */
484 QDF_STATUS hdd_get_tsf_time(void *adapter_ctx, uint64_t input_time,
485 uint64_t *tsf_time);
486 #else
hdd_start_tsf_sync(struct hdd_adapter * adapter)487 static inline int hdd_start_tsf_sync(struct hdd_adapter *adapter)
488 {
489 return -ENOTSUPP;
490 }
491
hdd_stop_tsf_sync(struct hdd_adapter * adapter)492 static inline int hdd_stop_tsf_sync(struct hdd_adapter *adapter)
493 {
494 return -ENOTSUPP;
495 }
496
497 static inline
hdd_capture_req_timer_expired_handler(void * arg)498 void hdd_capture_req_timer_expired_handler(void *arg)
499 {
500 }
501
502 static inline
hdd_tsf_is_tsf64_tx_set(struct hdd_context * hdd)503 bool hdd_tsf_is_tsf64_tx_set(struct hdd_context *hdd)
504 {
505 return FALSE;
506 }
507
508 static inline
hdd_tsf_is_time_sync_enabled_cfg(struct hdd_context * hdd_ctx)509 bool hdd_tsf_is_time_sync_enabled_cfg(struct hdd_context *hdd_ctx)
510 {
511 return false;
512 }
513
514 static inline
hdd_update_dynamic_tsf_sync(struct hdd_adapter * adapter)515 void hdd_update_dynamic_tsf_sync(struct hdd_adapter *adapter)
516 {
517 }
518
519 static inline
hdd_restart_tsf_sync_post_wlan_resume(struct hdd_adapter * adapter)520 void hdd_restart_tsf_sync_post_wlan_resume(struct hdd_adapter *adapter)
521 {
522 }
523
524 static inline
hdd_get_tsf_time(void * adapter_ctx,uint64_t input_time,uint64_t * tsf_time)525 QDF_STATUS hdd_get_tsf_time(void *adapter_ctx, uint64_t input_time,
526 uint64_t *tsf_time)
527 {
528 *tsf_time = 0;
529 return QDF_STATUS_E_NOSUPPORT;
530 }
531 #endif
532
533 #ifdef WLAN_FEATURE_TSF_PTP
534 /**
535 * wlan_get_ts_info() - return ts info to uplayer
536 * @dev: pointer to net_device
537 * @info: pointer to ethtool_ts_info
538 *
539 * Return: Describe the execute result of this routine
540 */
541 int wlan_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);
542
543 #endif
544 #endif
545