1 /*
2  * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021, 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: This file defines the important dispatcher APIs pertinent to
22  * wifi positioning.
23  */
24 #include <wlan_lmac_if_def.h>
25 #include "wifi_pos_utils_i.h"
26 #include "wifi_pos_api.h"
27 #include "wifi_pos_ucfg_i.h"
28 #include "wlan_ptt_sock_svc.h"
29 #ifndef CNSS_GENL
30 #include <wlan_objmgr_psoc_obj.h>
31 #include "wifi_pos_main_i.h"
32 #endif
33 
34 #ifndef CNSS_GENL
ucfg_wifi_psoc_get_pdev_id_by_dev_name(char * dev_name,uint8_t * pdev_id,struct wlan_objmgr_psoc ** psoc)35 QDF_STATUS ucfg_wifi_psoc_get_pdev_id_by_dev_name(
36 		char *dev_name, uint8_t *pdev_id,
37 		struct wlan_objmgr_psoc **psoc)
38 {
39 	struct wlan_objmgr_psoc *tmp_psoc = wifi_pos_get_psoc();
40 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj;
41 
42 	if (!tmp_psoc) {
43 		wifi_pos_err("psoc is null");
44 		return QDF_STATUS_E_NULL_VALUE;
45 	}
46 
47 	wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(tmp_psoc);
48 	if (!wifi_pos_psoc_obj) {
49 		wifi_pos_err("wifi_pos_psoc_obj is null");
50 		return QDF_STATUS_E_NULL_VALUE;
51 	}
52 
53 	if (!wifi_pos_psoc_obj->wifi_pos_get_pdev_id_by_dev_name) {
54 		wifi_pos_err("wifi_pos_get_pdev_id_by_dev_name is null");
55 		return QDF_STATUS_E_NULL_VALUE;
56 	}
57 
58 	return wifi_pos_psoc_obj->wifi_pos_get_pdev_id_by_dev_name(
59 			dev_name, pdev_id, psoc);
60 }
61 
62 #ifdef WLAN_RTT_MEASUREMENT_NOTIFICATION
ucfg_wifi_pos_measurement_request_notification(struct wlan_objmgr_pdev * pdev,struct wifi_pos_req_msg * req)63 QDF_STATUS ucfg_wifi_pos_measurement_request_notification(
64 		struct wlan_objmgr_pdev *pdev,
65 		struct wifi_pos_req_msg *req)
66 {
67 	struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc();
68 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj;
69 	struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops;
70 	struct rtt_channel_info chinfo = {0};
71 
72 	if (!psoc) {
73 		wifi_pos_err("psoc is null");
74 		return QDF_STATUS_E_NULL_VALUE;
75 	}
76 
77 	wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(psoc);
78 	if (!wifi_pos_psoc_obj) {
79 		wifi_pos_err("wifi_pos_psoc_obj is null");
80 		return QDF_STATUS_E_NULL_VALUE;
81 	}
82 
83 	if (!wifi_pos_psoc_obj->wifi_pos_measurement_request_notification) {
84 		wifi_pos_debug("wifi_pos_measurement_request_notification is not registered");
85 		return QDF_STATUS_SUCCESS;
86 	}
87 
88 	tx_ops = wifi_pos_get_tx_ops(psoc);
89 	if (!tx_ops) {
90 		wifi_pos_err("tx_ops null");
91 		return QDF_STATUS_E_NULL_VALUE;
92 	}
93 
94 	if (!tx_ops->wifi_pos_parse_measreq_chan_info) {
95 		wifi_pos_err("wifi_pos_parse_measreq_chan_info is null");
96 		return QDF_STATUS_E_NULL_VALUE;
97 	}
98 
99 	tx_ops->wifi_pos_parse_measreq_chan_info(pdev, req->buf_len, req->buf,
100 						 &chinfo);
101 	if (!chinfo.freq) {
102 		wifi_pos_debug("Not a measurement request buffer, proceed");
103 		return QDF_STATUS_SUCCESS;
104 	}
105 
106 	return wifi_pos_psoc_obj->wifi_pos_measurement_request_notification(
107 			pdev, &chinfo);
108 }
109 #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */
110 #endif
111 
ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc * psoc,struct wifi_pos_req_msg * req,wifi_pos_send_rsp_handler send_rsp_cb)112 QDF_STATUS ucfg_wifi_pos_process_req(struct wlan_objmgr_psoc *psoc,
113 				     struct wifi_pos_req_msg *req,
114 				     wifi_pos_send_rsp_handler send_rsp_cb)
115 {
116 	uint8_t err;
117 	uint32_t app_pid;
118 	bool is_app_registered;
119 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc_obj;
120 
121 	wifi_pos_debug("enter");
122 
123 	wifi_pos_psoc_obj = wifi_pos_get_psoc_priv_obj(wifi_pos_get_psoc());
124 	if (!wifi_pos_psoc_obj) {
125 		wifi_pos_err("wifi_pos_psoc_obj is null");
126 		return QDF_STATUS_E_NULL_VALUE;
127 	}
128 
129 	qdf_spin_lock_bh(&wifi_pos_psoc_obj->wifi_pos_lock);
130 	wifi_pos_psoc_obj->wifi_pos_send_rsp = send_rsp_cb;
131 	is_app_registered = wifi_pos_psoc_obj->is_app_registered;
132 	app_pid = wifi_pos_psoc_obj->app_pid;
133 	wifi_pos_psoc_obj->rsp_version = req->rsp_version;
134 	qdf_spin_unlock_bh(&wifi_pos_psoc_obj->wifi_pos_lock);
135 
136 	if (!wifi_pos_psoc_obj->wifi_pos_req_handler) {
137 		wifi_pos_err("wifi_pos_psoc_obj->wifi_pos_req_handler is null");
138 		err = OEM_ERR_NULL_CONTEXT;
139 		send_rsp_cb(psoc, app_pid, WIFI_POS_CMD_ERROR, sizeof(err),
140 			    &err);
141 		return QDF_STATUS_E_NULL_VALUE;
142 	}
143 
144 	if (req->msg_type != WIFI_POS_CMD_REGISTRATION &&
145 		(!is_app_registered || app_pid != req->pid)) {
146 		wifi_pos_err("requesting app is not registered, app_registered: %d, requesting pid: %d, stored pid: %d",
147 			is_app_registered, req->pid, app_pid);
148 		err = OEM_ERR_APP_NOT_REGISTERED;
149 		send_rsp_cb(psoc, app_pid, WIFI_POS_CMD_ERROR, sizeof(err),
150 			    &err);
151 		return QDF_STATUS_E_INVAL;
152 	}
153 
154 	return wifi_pos_psoc_obj->wifi_pos_req_handler(psoc, req);
155 }
156 
157 
ucfg_wifi_pos_get_ftm_cap(struct wlan_objmgr_psoc * psoc)158 uint32_t ucfg_wifi_pos_get_ftm_cap(struct wlan_objmgr_psoc *psoc)
159 {
160 	uint32_t val = 0;
161 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc =
162 			wifi_pos_get_psoc_priv_obj(psoc);
163 
164 	if (!wifi_pos_psoc) {
165 		wifi_pos_alert("unable to get wifi_pos psoc obj");
166 		return val;
167 	}
168 
169 	qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock);
170 	val = wifi_pos_psoc->fine_time_meas_cap;
171 	qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock);
172 
173 	return val;
174 }
175 
ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc * psoc,uint32_t val)176 void ucfg_wifi_pos_set_ftm_cap(struct wlan_objmgr_psoc *psoc, uint32_t val)
177 {
178 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc =
179 			wifi_pos_get_psoc_priv_obj(psoc);
180 
181 	if (!wifi_pos_psoc) {
182 		wifi_pos_alert("unable to get wifi_pos psoc obj");
183 		return;
184 	}
185 
186 	qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock);
187 	wifi_pos_psoc->fine_time_meas_cap = val;
188 	qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock);
189 }
190 
ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc * psoc,bool val)191 void ucfg_wifi_pos_set_oem_6g_supported(struct wlan_objmgr_psoc *psoc,
192 					bool val)
193 {
194 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc =
195 			wifi_pos_get_psoc_priv_obj(psoc);
196 	if (!wifi_pos_psoc) {
197 		wifi_pos_alert("unable to get wifi_pos psoc obj");
198 		return;
199 	}
200 
201 	qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock);
202 	wifi_pos_psoc->oem_6g_support_disable = val;
203 	qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock);
204 }
205 
ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc * psoc)206 bool ucfg_wifi_pos_is_nl_rsp(struct wlan_objmgr_psoc *psoc)
207 {
208 	uint32_t val = 0;
209 	struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = NULL;
210 	struct wlan_objmgr_psoc *tmp_psoc = wifi_pos_get_psoc();
211 
212 	if (tmp_psoc)
213 		wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(tmp_psoc);
214 
215 	if (!wifi_pos_psoc) {
216 		wifi_pos_alert("unable to get wifi_pos psoc obj");
217 		return false;
218 	}
219 
220 	qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock);
221 	val = wifi_pos_psoc->rsp_version;
222 	qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock);
223 
224 	if (val == WIFI_POS_RSP_V2_NL)
225 		return true;
226 	else
227 		return false;
228 
229 }
230 
231