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