1 /*
2  *Copyright (c) 2020, 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 any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: Implements public API for ftm time sync to interact with target/WMI
20  */
21 
22 #include "wlan_ftm_time_sync_tgt_api.h"
23 #include "ftm_time_sync_main.h"
24 #include "wlan_ftm_time_sync_public_struct.h"
25 #include <wmi_unified_api.h>
26 
27 QDF_STATUS
tgt_ftm_ts_start_stop_evt(struct wlan_objmgr_psoc * psoc,struct ftm_time_sync_start_stop_params * param)28 tgt_ftm_ts_start_stop_evt(struct wlan_objmgr_psoc *psoc,
29 			  struct ftm_time_sync_start_stop_params *param)
30 {
31 	struct wlan_objmgr_vdev *vdev;
32 	struct ftm_time_sync_vdev_priv *vdev_priv;
33 	uint8_t vdev_id;
34 
35 	vdev_id = param->vdev_id;
36 
37 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
38 						    FTM_TIME_SYNC_ID);
39 	if (!vdev) {
40 		ftm_time_sync_err("failed to get vdev");
41 		return QDF_STATUS_E_FAILURE;
42 	}
43 
44 	vdev_priv = ftm_time_sync_vdev_get_priv(vdev);
45 
46 	qdf_mutex_acquire(&vdev_priv->ftm_time_sync_mutex);
47 
48 	vdev_priv->time_sync_interval = param->timer_interval;
49 	vdev_priv->num_reads = param->num_reads * 2;
50 
51 	if (vdev_priv->num_reads && vdev_priv->time_sync_interval) {
52 		vdev_priv->num_reads--;
53 		qdf_mutex_release(&vdev_priv->ftm_time_sync_mutex);
54 		qdf_delayed_work_start(&vdev_priv->ftm_time_sync_work,
55 				       param->timer_interval);
56 	} else if (vdev_priv->time_sync_interval == 0) {
57 		qdf_mutex_release(&vdev_priv->ftm_time_sync_mutex);
58 		vdev_priv->ftm_ts_priv.qtime_ref = param->qtime;
59 		vdev_priv->ftm_ts_priv.mac_ref = param->mac_time;
60 		qdf_delayed_work_stop_sync(&vdev_priv->ftm_time_sync_work);
61 	} else {
62 		qdf_mutex_release(&vdev_priv->ftm_time_sync_mutex);
63 	}
64 
65 	ftm_time_sync_vdev_put_ref(vdev);
66 
67 	return QDF_STATUS_SUCCESS;
68 }
69 
tgt_ftm_ts_offset_evt(struct wlan_objmgr_psoc * psoc,struct ftm_time_sync_offset * param)70 QDF_STATUS tgt_ftm_ts_offset_evt(struct wlan_objmgr_psoc *psoc,
71 				 struct ftm_time_sync_offset *param)
72 {
73 	struct ftm_time_sync_vdev_priv *vdev_priv;
74 	struct wlan_objmgr_vdev *vdev;
75 	uint8_t vdev_id;
76 	int iter;
77 
78 	vdev_id = param->vdev_id;
79 
80 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
81 						    FTM_TIME_SYNC_ID);
82 	if (!vdev) {
83 		ftm_time_sync_err("failed to get vdev");
84 		return QDF_STATUS_E_FAILURE;
85 	}
86 
87 	vdev_priv = ftm_time_sync_vdev_get_priv(vdev);
88 
89 	vdev_priv->num_qtime_pair = param->num_qtime <
90 			FTM_TIME_SYNC_QTIME_PAIR_MAX ? param->num_qtime :
91 			FTM_TIME_SYNC_QTIME_PAIR_MAX;
92 
93 	for (iter = 0; iter < vdev_priv->num_qtime_pair; iter++) {
94 		vdev_priv->ftm_ts_priv.time_pair[iter].qtime_initiator =
95 						param->pairs[iter].qtime_initiator;
96 		vdev_priv->ftm_ts_priv.time_pair[iter].qtime_target =
97 						param->pairs[iter].qtime_target;
98 	}
99 
100 	ftm_time_sync_vdev_put_ref(vdev);
101 
102 	return QDF_STATUS_SUCCESS;
103 }
104 
105