xref: /wlan-dirver/qca-wifi-host-cmn/target_if/wifi_pos/src/target_if_wifi_pos_rx_ops.c (revision d0c05845839e5f2ba5a8dcebe0cd3e4cd4e8dfcf)
1 /*
2  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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_rx_ops.c
22  * This file defines the functions pertinent to wifi positioning component's
23  * target if layer.
24  */
25 #include "wifi_pos_utils_pub.h"
26 #include "wifi_pos_api.h"
27 #include "wifi_pos_pasn_api.h"
28 
29 #include "wmi_unified_api.h"
30 #include "wlan_lmac_if_def.h"
31 #include "target_if_wifi_pos.h"
32 #include "target_if_wifi_pos_rx_ops.h"
33 #include "wifi_pos_utils_i.h"
34 #include "target_if.h"
35 
36 static struct wlan_lmac_if_wifi_pos_rx_ops *
37 target_if_wifi_pos_get_rxops(struct wlan_objmgr_psoc *psoc)
38 {
39 	struct wlan_lmac_if_rx_ops *rx_ops;
40 
41 	if (!psoc) {
42 		target_if_err("passed psoc is NULL");
43 		return NULL;
44 	}
45 
46 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
47 	if (!rx_ops) {
48 		target_if_err("rx_ops is NULL");
49 		return NULL;
50 	}
51 
52 	return &rx_ops->wifi_pos_rx_ops;
53 }
54 
55 int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn,
56 					  uint8_t *data_buf,
57 					  uint32_t data_len)
58 {
59 	int ret;
60 	uint8_t ring_idx = 0;
61 	QDF_STATUS status;
62 	uint32_t cookie = 0;
63 	struct wmi_host_oem_indirect_data *indirect;
64 	struct oem_data_rsp oem_rsp = {0};
65 	struct wifi_pos_psoc_priv_obj *priv_obj;
66 	struct wlan_objmgr_psoc *psoc;
67 	struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops;
68 	struct wmi_oem_response_param oem_resp_param = {0};
69 	wmi_unified_t wmi_handle;
70 
71 	psoc = target_if_get_psoc_from_scn_hdl(scn);
72 	if (!psoc) {
73 		target_if_err("psoc is null");
74 		return QDF_STATUS_NOT_INITIALIZED;
75 	}
76 
77 	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
78 
79 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
80 	if (!wmi_handle) {
81 		target_if_err("wmi_handle is null");
82 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
83 		return QDF_STATUS_NOT_INITIALIZED;
84 	}
85 
86 	priv_obj = wifi_pos_get_psoc_priv_obj(wifi_pos_get_psoc());
87 	if (!priv_obj) {
88 		target_if_err("priv_obj is null");
89 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
90 		return QDF_STATUS_NOT_INITIALIZED;
91 	}
92 
93 	wifi_pos_rx_ops = target_if_wifi_pos_get_rxops(psoc);
94 	if (!wifi_pos_rx_ops || !wifi_pos_rx_ops->oem_rsp_event_rx) {
95 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
96 		target_if_err("lmac callbacks not registered");
97 		return QDF_STATUS_NOT_INITIALIZED;
98 	}
99 
100 	ret = wmi_extract_oem_response_param(wmi_handle,
101 					     data_buf,
102 					     &oem_resp_param);
103 
104 	oem_rsp.rsp_len_1 = oem_resp_param.num_data1;
105 	oem_rsp.data_1    = oem_resp_param.data_1;
106 
107 	if (oem_resp_param.num_data2) {
108 		oem_rsp.rsp_len_2 = oem_resp_param.num_data2;
109 		oem_rsp.data_2    = oem_resp_param.data_2;
110 	}
111 
112 	indirect = &oem_resp_param.indirect_data;
113 	status = target_if_wifi_pos_get_indirect_data(priv_obj, indirect,
114 						      &oem_rsp, &cookie);
115 	if (QDF_IS_STATUS_ERROR(status)) {
116 		target_if_err("get indirect data failed status: %d", status);
117 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
118 		return QDF_STATUS_E_INVAL;
119 	}
120 
121 	ret = wifi_pos_rx_ops->oem_rsp_event_rx(psoc, &oem_rsp);
122 	if (indirect)
123 		ring_idx = indirect->pdev_id - 1;
124 	status = target_if_wifi_pos_replenish_ring(priv_obj, ring_idx,
125 						   oem_rsp.vaddr, cookie);
126 	if (QDF_IS_STATUS_ERROR(status)) {
127 		target_if_err("replenish failed status: %d", status);
128 		ret = QDF_STATUS_E_FAILURE;
129 	}
130 
131 	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
132 
133 	return ret;
134 }
135 
136 int wifi_pos_oem_cap_ev_handler(ol_scn_t scn, uint8_t *buf, uint32_t len)
137 {
138 	/* TBD */
139 	return 0;
140 }
141 
142 int wifi_pos_oem_meas_rpt_ev_handler(ol_scn_t scn, uint8_t *buf,
143 				     uint32_t len)
144 {
145 	/* TBD */
146 	return 0;
147 }
148 
149 int wifi_pos_oem_err_rpt_ev_handler(ol_scn_t scn, uint8_t *buf,
150 				    uint32_t len)
151 {
152 	/* TBD */
153 	return 0;
154 }
155 
156 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
157 int target_if_wifi_pos_pasn_peer_create_ev_handler(ol_scn_t scn,
158 						   uint8_t *buf,
159 						   uint32_t len)
160 {
161 	wmi_unified_t wmi_handle;
162 	struct wlan_objmgr_psoc *psoc;
163 	struct wlan_lmac_if_wifi_pos_rx_ops *rx_ops;
164 	struct wifi_pos_pasn_peer_data *data = NULL;
165 	QDF_STATUS status;
166 
167 	data = qdf_mem_malloc(sizeof(*data));
168 	if (!data)
169 		return -ENOMEM;
170 
171 	psoc = target_if_get_psoc_from_scn_hdl(scn);
172 	if (!psoc) {
173 		target_if_err("psoc is null");
174 		qdf_mem_free(data);
175 		return -EINVAL;
176 	}
177 
178 	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
179 
180 	if (!wlan_psoc_nif_fw_ext2_cap_get(psoc,
181 					   WLAN_VDEV_DELETE_ALL_PEER_SUPPORT)) {
182 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
183 		qdf_mem_free(data);
184 		target_if_debug("Firmware doesn't support Peer delete all");
185 		return -EPERM;
186 	}
187 
188 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
189 	if (!wmi_handle) {
190 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
191 		qdf_mem_free(data);
192 		target_if_err("wmi_handle is null");
193 		return -EINVAL;
194 	}
195 
196 	status = wmi_extract_pasn_peer_create_req(wmi_handle, buf, data);
197 	if (QDF_IS_STATUS_ERROR(status)) {
198 		wifi_pos_err("Extract PASN peer create failed");
199 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
200 		qdf_mem_free(data);
201 		return -EINVAL;
202 	}
203 
204 	rx_ops = wifi_pos_get_rx_ops(psoc);
205 	if (!rx_ops || !rx_ops->wifi_pos_ranging_peer_create_cb) {
206 		wifi_pos_err("%s is null",
207 			     !rx_ops ? "rx_ops" : "rx_ops_cb");
208 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
209 		qdf_mem_free(data);
210 		return -EINVAL;
211 	}
212 
213 	rx_ops->wifi_pos_ranging_peer_create_cb(psoc, data->peer_info,
214 						data->vdev_id,
215 						data->num_peers);
216 
217 	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
218 	qdf_mem_free(data);
219 
220 	return 0;
221 }
222 
223 int target_if_wifi_pos_pasn_peer_delete_ev_handler(ol_scn_t scn,
224 						   uint8_t *buf,
225 						   uint32_t len)
226 {
227 	wmi_unified_t wmi_handle;
228 	struct wlan_objmgr_psoc *psoc;
229 	struct wlan_lmac_if_wifi_pos_rx_ops *rx_ops;
230 	struct wifi_pos_pasn_peer_data *data = NULL;
231 	QDF_STATUS status;
232 
233 	psoc = target_if_get_psoc_from_scn_hdl(scn);
234 	if (!psoc) {
235 		target_if_err("psoc is null");
236 		return QDF_STATUS_NOT_INITIALIZED;
237 	}
238 
239 	wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
240 
241 	wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
242 	if (!wmi_handle) {
243 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
244 		target_if_err("wmi_handle is null");
245 		return QDF_STATUS_NOT_INITIALIZED;
246 	}
247 
248 	data = qdf_mem_malloc(sizeof(*data));
249 	if (!data) {
250 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
251 		return QDF_STATUS_E_NOMEM;
252 	}
253 
254 	status = wmi_extract_pasn_peer_delete_req(wmi_handle, buf, data);
255 	if (QDF_IS_STATUS_ERROR(status)) {
256 		wifi_pos_err("Extract PASN peer delete failed");
257 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
258 		qdf_mem_free(data);
259 		return QDF_STATUS_E_NULL_VALUE;
260 	}
261 
262 	rx_ops = wifi_pos_get_rx_ops(psoc);
263 	if (!rx_ops || !rx_ops->wifi_pos_ranging_peer_delete_cb) {
264 		wifi_pos_err("%s is null",
265 			     !rx_ops ? "rx_ops" : "rx_ops_cb");
266 		wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
267 		qdf_mem_free(data);
268 		return QDF_STATUS_E_NULL_VALUE;
269 	}
270 
271 	rx_ops->wifi_pos_ranging_peer_delete_cb(psoc, data->peer_info,
272 						data->vdev_id,
273 						data->num_peers);
274 
275 	wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_TGT_IF_ID);
276 	qdf_mem_free(data);
277 
278 	return 0;
279 }
280 
281 void target_if_wifi_pos_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
282 {
283 	struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops =
284 					&rx_ops->wifi_pos_rx_ops;
285 
286 	wifi_pos_rx_ops->wifi_pos_ranging_peer_create_cb =
287 			wifi_pos_handle_ranging_peer_create;
288 	wifi_pos_rx_ops->wifi_pos_ranging_peer_create_rsp_cb =
289 			wifi_pos_handle_ranging_peer_create_rsp;
290 	wifi_pos_rx_ops->wifi_pos_ranging_peer_delete_cb =
291 			wifi_pos_handle_ranging_peer_delete;
292 	wifi_pos_rx_ops->wifi_pos_vdev_delete_all_ranging_peers_rsp_cb =
293 			wifi_pos_vdev_delete_all_ranging_peers_rsp;
294 }
295 #endif
296 
297