1 /*
2  * Copyright (c) 2013-2021 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: target_if_wifi_pos_tx_ops.c
22  * This file defines the functions pertinent to wifi positioning component's
23  * target if layer TX operations.
24  */
25 #include "wifi_pos_utils_pub.h"
26 
27 #include "wmi_unified_api.h"
28 #include "wlan_lmac_if_def.h"
29 #include "target_if_wifi_pos.h"
30 #include "target_if_wifi_pos_tx_ops.h"
31 #include "wifi_pos_utils_i.h"
32 #include "wifi_pos_api.h"
33 #include "wifi_pos_pasn_api.h"
34 #include "target_if.h"
35 
36 /**
37  * target_if_wifi_pos_oem_data_req() - start OEM data request to target
38  * @pdev: pointer to pdev object mgr
39  * @req: start request params
40  *
41  * Return: QDF_STATUS
42  */
43 static QDF_STATUS
target_if_wifi_pos_oem_data_req(struct wlan_objmgr_pdev * pdev,struct oem_data_req * req)44 target_if_wifi_pos_oem_data_req(struct wlan_objmgr_pdev *pdev,
45 				struct oem_data_req *req)
46 {
47 	QDF_STATUS status;
48 	wmi_unified_t wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev);
49 
50 	target_if_debug("Send oem data req to target");
51 
52 	if (!req || !req->data) {
53 		target_if_err("oem_data_req is null");
54 		return QDF_STATUS_E_INVAL;
55 	}
56 
57 	if (!wmi_hdl) {
58 		target_if_err("WMA closed, can't send oem data req cmd");
59 		return QDF_STATUS_E_INVAL;
60 	}
61 
62 	status = wmi_unified_start_oem_data_cmd(wmi_hdl, req->data_len,
63 						req->data);
64 
65 	if (!QDF_IS_STATUS_SUCCESS(status))
66 		target_if_err("wmi cmd send failed");
67 
68 	return status;
69 }
70 
71 #if !defined(CNSS_GENL) && defined(WLAN_RTT_MEASUREMENT_NOTIFICATION)
72 static QDF_STATUS
target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev * pdev,uint32_t data_len,uint8_t * data,struct rtt_channel_info * chinfo)73 target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev *pdev,
74 					   uint32_t data_len, uint8_t *data,
75 					   struct rtt_channel_info *chinfo)
76 {
77 	QDF_STATUS status;
78 	wmi_unified_t wmi_hdl = get_wmi_unified_hdl_from_pdev(pdev);
79 
80 	if (!data) {
81 		target_if_err("data is null");
82 		return QDF_STATUS_E_INVAL;
83 	}
84 
85 	if (!wmi_hdl) {
86 		target_if_err("wmi_hdl is null");
87 		return QDF_STATUS_E_INVAL;
88 	}
89 
90 	status = wmi_unified_extract_measreq_chan_info(wmi_hdl, data_len, data,
91 						       chinfo);
92 	if (!QDF_IS_STATUS_SUCCESS(status))
93 		target_if_err("wmi_unified_extract_measreq_chan_info failed");
94 
95 	return status;
96 }
97 #else
98 static inline QDF_STATUS
target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev * pdev,uint32_t data_len,uint8_t * data,struct rtt_channel_info * chinfo)99 target_if_wifi_pos_parse_measreq_chan_info(struct wlan_objmgr_pdev *pdev,
100 					   uint32_t data_len, uint8_t *data,
101 					   struct rtt_channel_info *chinfo)
102 {
103 	return QDF_STATUS_E_NOSUPPORT;
104 }
105 #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */
106 
107 #ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT
108 static QDF_STATUS
target_if_wifi_pos_send_rtt_pasn_auth_status(struct wlan_objmgr_psoc * psoc,struct wlan_pasn_auth_status * data)109 target_if_wifi_pos_send_rtt_pasn_auth_status(struct wlan_objmgr_psoc *psoc,
110 					     struct wlan_pasn_auth_status *data)
111 {
112 	QDF_STATUS status;
113 	wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc);
114 
115 	if (!psoc || !wmi) {
116 		target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle");
117 		return QDF_STATUS_E_INVAL;
118 	}
119 
120 	status = wmi_send_rtt_pasn_auth_status_cmd(wmi, data);
121 	if (QDF_IS_STATUS_ERROR(status))
122 		target_if_err("send pasn auth status cmd failed");
123 
124 	return status;
125 }
126 
127 static QDF_STATUS
target_if_wifi_pos_send_rtt_pasn_deauth(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_mac)128 target_if_wifi_pos_send_rtt_pasn_deauth(struct wlan_objmgr_psoc *psoc,
129 					struct qdf_mac_addr *peer_mac)
130 {
131 	QDF_STATUS status;
132 	wmi_unified_t wmi = GET_WMI_HDL_FROM_PSOC(psoc);
133 
134 	if (!psoc || !wmi) {
135 		target_if_err("%s is null", !psoc ? "psoc" : "wmi_handle");
136 		return QDF_STATUS_E_INVAL;
137 	}
138 
139 	status = wmi_send_rtt_pasn_deauth_cmd(wmi, peer_mac);
140 	if (QDF_IS_STATUS_ERROR(status))
141 		target_if_err("send pasn deauth cmd failed");
142 
143 	return status;
144 }
145 
target_if_wifi_pos_register_11az_ops(struct wlan_lmac_if_wifi_pos_tx_ops * tx_ops)146 static void target_if_wifi_pos_register_11az_ops(
147 			struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops)
148 {
149 	tx_ops->send_rtt_pasn_auth_status =
150 			target_if_wifi_pos_send_rtt_pasn_auth_status;
151 	tx_ops->send_rtt_pasn_deauth = target_if_wifi_pos_send_rtt_pasn_deauth;
152 }
153 #else
154 static inline
target_if_wifi_pos_register_11az_ops(struct wlan_lmac_if_wifi_pos_tx_ops * tx_ops)155 void target_if_wifi_pos_register_11az_ops(
156 			struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops)
157 {}
158 #endif
159 
160 #ifdef WIFI_POS_CONVERGED
161 #ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT
162 static QDF_STATUS
target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc * psoc)163 target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc *psoc)
164 {
165 	QDF_STATUS status = QDF_STATUS_SUCCESS;
166 
167 	status = wmi_unified_register_event_handler(
168 			get_wmi_unified_hdl_from_psoc(psoc),
169 			wmi_rtt_pasn_peer_create_req_eventid,
170 			target_if_wifi_pos_pasn_peer_create_ev_handler,
171 			WMI_RX_EXECUTION_CTX);
172 	if (QDF_IS_STATUS_ERROR(status)) {
173 		target_if_err("register pasn peer create event_handler failed");
174 		return QDF_STATUS_E_INVAL;
175 	}
176 
177 	status = wmi_unified_register_event_handler(
178 			get_wmi_unified_hdl_from_psoc(psoc),
179 			wmi_rtt_pasn_peer_delete_eventid,
180 			target_if_wifi_pos_pasn_peer_delete_ev_handler,
181 			WMI_RX_EXECUTION_CTX);
182 	if (QDF_IS_STATUS_ERROR(status)) {
183 		target_if_err("register pasn peer delete event_handler failed");
184 		return status;
185 	}
186 
187 	return status;
188 }
189 
190 static void
target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc * psoc)191 target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc *psoc)
192 {
193 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
194 		target_if_err("psoc or psoc->tgt_if_handle is null");
195 		return;
196 	}
197 
198 	wmi_unified_unregister_event_handler(
199 			get_wmi_unified_hdl_from_psoc(psoc),
200 			wmi_rtt_pasn_peer_create_req_eventid);
201 
202 	wmi_unified_unregister_event_handler(
203 			get_wmi_unified_hdl_from_psoc(psoc),
204 			wmi_rtt_pasn_peer_delete_eventid);
205 }
206 #else
207 static QDF_STATUS
target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc * psoc)208 target_if_wifi_pos_register_11az_events(struct wlan_objmgr_psoc *psoc)
209 {
210 	return QDF_STATUS_SUCCESS;
211 }
212 
213 static void
target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc * psoc)214 target_if_wifi_pos_unregister_11az_events(struct wlan_objmgr_psoc *psoc)
215 {}
216 #endif /* WLAN_FEATURE_RTT_11AZ_SUPPORT */
217 
218 static
target_if_wifi_pos_register_events(struct wlan_objmgr_psoc * psoc)219 QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc)
220 {
221 	QDF_STATUS ret;
222 
223 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
224 		target_if_err("psoc or psoc->tgt_if_handle is null");
225 		return QDF_STATUS_E_INVAL;
226 	}
227 
228 	/* wmi_oem_response_event_id is not defined for legacy targets.
229 	 * So do not check for error for this event.
230 	 */
231 	wmi_unified_register_event_handler(
232 			get_wmi_unified_hdl_from_psoc(psoc),
233 			wmi_oem_response_event_id,
234 			target_if_wifi_pos_oem_rsp_ev_handler,
235 			WMI_RX_WORK_CTX);
236 
237 	ret = wmi_unified_register_event_handler(
238 			get_wmi_unified_hdl_from_psoc(psoc),
239 			wmi_oem_cap_event_id,
240 			wifi_pos_oem_cap_ev_handler,
241 			WMI_RX_WORK_CTX);
242 	if (QDF_IS_STATUS_ERROR(ret)) {
243 		target_if_err("register_event_handler failed: err %d", ret);
244 		return QDF_STATUS_E_INVAL;
245 	}
246 
247 	ret = wmi_unified_register_event_handler(
248 			get_wmi_unified_hdl_from_psoc(psoc),
249 			wmi_oem_meas_report_event_id,
250 			wifi_pos_oem_meas_rpt_ev_handler,
251 			WMI_RX_WORK_CTX);
252 	if (QDF_IS_STATUS_ERROR(ret)) {
253 		target_if_err("register_event_handler failed: err %d", ret);
254 		return QDF_STATUS_E_INVAL;
255 	}
256 
257 	ret = wmi_unified_register_event_handler(
258 			get_wmi_unified_hdl_from_psoc(psoc),
259 			wmi_oem_report_event_id,
260 			wifi_pos_oem_err_rpt_ev_handler,
261 			WMI_RX_WORK_CTX);
262 	if (QDF_IS_STATUS_ERROR(ret)) {
263 		target_if_err("register_event_handler failed: err %d", ret);
264 		return QDF_STATUS_E_INVAL;
265 	}
266 
267 	target_if_wifi_pos_register_11az_events(psoc);
268 
269 	return QDF_STATUS_SUCCESS;
270 }
271 
272 static
target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc * psoc)273 QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc)
274 {
275 	if (!psoc || !GET_WMI_HDL_FROM_PSOC(psoc)) {
276 		target_if_err("psoc or psoc->tgt_if_handle is null");
277 		return QDF_STATUS_E_INVAL;
278 	}
279 
280 	wmi_unified_unregister_event_handler(
281 			get_wmi_unified_hdl_from_psoc(psoc),
282 			wmi_oem_response_event_id);
283 	wmi_unified_unregister_event_handler(
284 			get_wmi_unified_hdl_from_psoc(psoc),
285 			wmi_oem_cap_event_id);
286 	wmi_unified_unregister_event_handler(
287 			get_wmi_unified_hdl_from_psoc(psoc),
288 			wmi_oem_meas_report_event_id);
289 	wmi_unified_unregister_event_handler(
290 			get_wmi_unified_hdl_from_psoc(psoc),
291 			wmi_oem_report_event_id);
292 	target_if_wifi_pos_unregister_11az_events(psoc);
293 
294 	return QDF_STATUS_SUCCESS;
295 }
296 
target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops * tx_ops)297 void target_if_wifi_pos_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
298 {
299 	struct wlan_lmac_if_wifi_pos_tx_ops *wifi_pos_tx_ops;
300 
301 	wifi_pos_tx_ops = &tx_ops->wifi_pos_tx_ops;
302 	wifi_pos_tx_ops->wifi_pos_register_events =
303 			target_if_wifi_pos_register_events;
304 	wifi_pos_tx_ops->wifi_pos_deregister_events =
305 			target_if_wifi_pos_deregister_events;
306 	wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req;
307 	wifi_pos_tx_ops->wifi_pos_convert_pdev_id_host_to_target =
308 		target_if_wifi_pos_convert_pdev_id_host_to_target;
309 	wifi_pos_tx_ops->wifi_pos_convert_pdev_id_target_to_host =
310 		target_if_wifi_pos_convert_pdev_id_target_to_host;
311 	wifi_pos_tx_ops->wifi_pos_get_vht_ch_width =
312 		target_if_wifi_pos_get_vht_ch_width;
313 	wifi_pos_tx_ops->data_req_tx = target_if_wifi_pos_oem_data_req;
314 	wifi_pos_tx_ops->wifi_pos_parse_measreq_chan_info =
315 			target_if_wifi_pos_parse_measreq_chan_info;
316 
317 	target_if_wifi_pos_register_11az_ops(wifi_pos_tx_ops);
318 }
319 #endif
320