1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-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: contains nan target if functions
22 */
23
24 #include "../../../nan/core/src/nan_main_i.h"
25 #include "nan_public_structs.h"
26 #include "nan_ucfg_api.h"
27 #include "target_if_nan.h"
28 #include "wlan_nan_api.h"
29 #include "target_if.h"
30 #include "wmi_unified_api.h"
31 #include "scheduler_api.h"
32 #include <wmi_unified.h>
33
target_if_nan_event_flush_cb(struct scheduler_msg * msg)34 static QDF_STATUS target_if_nan_event_flush_cb(struct scheduler_msg *msg)
35 {
36 struct wlan_objmgr_psoc *psoc;
37
38 if (!msg || !msg->bodyptr) {
39 target_if_err("Empty message for NAN Discovery event");
40 return QDF_STATUS_E_INVAL;
41 }
42
43 psoc = ((struct nan_event_params *)msg->bodyptr)->psoc;
44 wlan_objmgr_psoc_release_ref(psoc, WLAN_NAN_ID);
45 qdf_mem_free(msg->bodyptr);
46 msg->bodyptr = NULL;
47
48 return QDF_STATUS_SUCCESS;
49 }
50
target_if_nan_event_dispatcher(struct scheduler_msg * msg)51 static QDF_STATUS target_if_nan_event_dispatcher(struct scheduler_msg *msg)
52 {
53 struct wlan_nan_rx_ops *nan_rx_ops;
54 struct nan_event_params *nan_rsp;
55 struct wlan_objmgr_psoc *psoc;
56 QDF_STATUS status;
57
58 nan_rsp = msg->bodyptr;
59 psoc = nan_rsp->psoc;
60
61 nan_rx_ops = nan_psoc_get_rx_ops(psoc);
62 if (!nan_rx_ops) {
63 target_if_err("nan_rx_ops is null");
64 status = QDF_STATUS_E_NULL_VALUE;
65 } else {
66 status = nan_rx_ops->nan_discovery_event_rx(msg);
67 }
68
69 target_if_nan_event_flush_cb(msg);
70 return status;
71 }
72
target_if_ndp_event_flush_cb(struct scheduler_msg * msg)73 static QDF_STATUS target_if_ndp_event_flush_cb(struct scheduler_msg *msg)
74 {
75 void *ptr = msg->bodyptr;
76 struct wlan_objmgr_vdev *vdev = NULL;
77
78 switch (msg->type) {
79 case NDP_INITIATOR_RSP:
80 vdev = ((struct nan_datapath_initiator_rsp *)ptr)->vdev;
81 break;
82 case NDP_INDICATION:
83 vdev = ((struct nan_datapath_indication_event *)ptr)->vdev;
84 break;
85 case NDP_CONFIRM:
86 vdev = ((struct nan_datapath_confirm_event *)ptr)->vdev;
87 break;
88 case NDP_RESPONDER_RSP:
89 vdev = ((struct nan_datapath_responder_rsp *)ptr)->vdev;
90 break;
91 case NDP_END_RSP:
92 vdev = ((struct nan_datapath_end_rsp_event *)ptr)->vdev;
93 break;
94 case NDP_END_IND:
95 vdev = ((struct nan_datapath_end_indication_event *)ptr)->vdev;
96 break;
97 case NDP_SCHEDULE_UPDATE:
98 vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
99 break;
100 case NDP_HOST_UPDATE:
101 vdev = ((struct nan_datapath_host_event *)ptr)->vdev;
102 break;
103 default:
104 break;
105 }
106
107 if (vdev)
108 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
109 qdf_mem_free(msg->bodyptr);
110 msg->bodyptr = NULL;
111
112 return QDF_STATUS_SUCCESS;
113 }
114
target_if_ndp_event_dispatcher(struct scheduler_msg * msg)115 static QDF_STATUS target_if_ndp_event_dispatcher(struct scheduler_msg *msg)
116 {
117 QDF_STATUS status;
118 void *ptr = msg->bodyptr;
119 struct wlan_objmgr_psoc *psoc;
120 struct wlan_objmgr_vdev *vdev = NULL;
121 struct wlan_nan_rx_ops *nan_rx_ops;
122
123 switch (msg->type) {
124 case NDP_INITIATOR_RSP:
125 vdev = ((struct nan_datapath_initiator_rsp *)ptr)->vdev;
126 break;
127 case NDP_INDICATION:
128 vdev = ((struct nan_datapath_indication_event *)ptr)->vdev;
129 break;
130 case NDP_CONFIRM:
131 vdev = ((struct nan_datapath_confirm_event *)ptr)->vdev;
132 break;
133 case NDP_RESPONDER_RSP:
134 vdev = ((struct nan_datapath_responder_rsp *)ptr)->vdev;
135 break;
136 case NDP_END_RSP:
137 vdev = ((struct nan_datapath_end_rsp_event *)ptr)->vdev;
138 break;
139 case NDP_END_IND:
140 vdev = ((struct nan_datapath_end_indication_event *)ptr)->vdev;
141 break;
142 case NDP_SCHEDULE_UPDATE:
143 vdev = ((struct nan_datapath_sch_update_event *)ptr)->vdev;
144 break;
145 case NDP_HOST_UPDATE:
146 vdev = ((struct nan_datapath_host_event *)ptr)->vdev;
147 break;
148 default:
149 target_if_err("invalid msg type %d", msg->type);
150 status = QDF_STATUS_E_INVAL;
151 goto free_res;
152 }
153
154 if (!vdev) {
155 target_if_err("vdev is null");
156 status = QDF_STATUS_E_NULL_VALUE;
157 goto free_res;
158 }
159
160 psoc = wlan_vdev_get_psoc(vdev);
161 if (!psoc) {
162 target_if_err("psoc is null");
163 status = QDF_STATUS_E_NULL_VALUE;
164 goto free_res;
165 }
166
167 nan_rx_ops = nan_psoc_get_rx_ops(psoc);
168 if (!nan_rx_ops) {
169 target_if_err("nan_rx_ops is null");
170 status = QDF_STATUS_E_NULL_VALUE;
171 goto free_res;
172 }
173
174 status = nan_rx_ops->nan_datapath_event_rx(msg);
175 free_res:
176 if (vdev)
177 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
178 qdf_mem_free(msg->bodyptr);
179 msg->bodyptr = NULL;
180 return status;
181 }
182
target_if_nan_ndp_initiator_req(struct nan_datapath_initiator_req * ndp_req)183 static QDF_STATUS target_if_nan_ndp_initiator_req(
184 struct nan_datapath_initiator_req *ndp_req)
185 {
186 QDF_STATUS status;
187 struct wmi_unified *wmi_handle;
188 struct wlan_objmgr_psoc *psoc;
189 struct scheduler_msg pe_msg = {0};
190 struct wlan_nan_rx_ops *nan_rx_ops;
191 struct nan_datapath_initiator_rsp ndp_rsp = {0};
192
193 if (!ndp_req) {
194 target_if_err("ndp_req is null.");
195 return QDF_STATUS_E_INVAL;
196 }
197
198 psoc = wlan_vdev_get_psoc(ndp_req->vdev);
199 if (!psoc) {
200 target_if_err("psoc is null.");
201 return QDF_STATUS_E_INVAL;
202 }
203
204 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
205 if (!wmi_handle) {
206 target_if_err("wmi_handle is null.");
207 return QDF_STATUS_E_INVAL;
208 }
209
210 nan_rx_ops = nan_psoc_get_rx_ops(psoc);
211 if (!nan_rx_ops) {
212 target_if_err("nan_rx_ops is null.");
213 return QDF_STATUS_E_INVAL;
214 }
215
216 status = wmi_unified_ndp_initiator_req_cmd_send(wmi_handle, ndp_req);
217 if (QDF_IS_STATUS_SUCCESS(status))
218 return status;
219
220 ndp_rsp.vdev = ndp_req->vdev;
221 ndp_rsp.transaction_id = ndp_req->transaction_id;
222 ndp_rsp.ndp_instance_id = ndp_req->service_instance_id;
223 ndp_rsp.status = NAN_DATAPATH_DATA_INITIATOR_REQ_FAILED;
224 pe_msg.type = NDP_INITIATOR_RSP;
225 pe_msg.bodyptr = &ndp_rsp;
226 if (nan_rx_ops->nan_datapath_event_rx)
227 nan_rx_ops->nan_datapath_event_rx(&pe_msg);
228
229 return status;
230 }
231
target_if_nan_dmesg_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)232 static int target_if_nan_dmesg_handler(ol_scn_t scn, uint8_t *data,
233 uint32_t data_len)
234 {
235 QDF_STATUS status;
236 struct nan_dump_msg msg;
237 struct wmi_unified *wmi_handle;
238 struct wlan_objmgr_psoc *psoc;
239
240 psoc = target_if_get_psoc_from_scn_hdl(scn);
241 if (!psoc) {
242 target_if_err("psoc is null");
243 return -EINVAL;
244 }
245
246 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
247 if (!wmi_handle) {
248 target_if_err("wmi_handle is null");
249 return -EINVAL;
250 }
251
252 status = wmi_extract_nan_msg(wmi_handle, data, &msg);
253 if (QDF_IS_STATUS_ERROR(status)) {
254 target_if_err("parsing of event failed, %d", status);
255 return -EINVAL;
256 }
257
258 if (!msg.msg) {
259 target_if_err("msg not present %d", msg.data_len);
260 return -EINVAL;
261 }
262
263 target_if_info("%s", msg.msg);
264
265 return 0;
266 }
267
target_if_ndp_initiator_rsp_handler(ol_scn_t scn,uint8_t * data,uint32_t len)268 static int target_if_ndp_initiator_rsp_handler(ol_scn_t scn, uint8_t *data,
269 uint32_t len)
270 {
271 QDF_STATUS status;
272 struct wmi_unified *wmi_handle;
273 struct wlan_objmgr_psoc *psoc;
274 struct scheduler_msg msg = {0};
275 struct nan_datapath_initiator_rsp *rsp;
276
277 psoc = target_if_get_psoc_from_scn_hdl(scn);
278 if (!psoc) {
279 target_if_err("psoc is null");
280 return -EINVAL;
281 }
282
283 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
284 if (!wmi_handle) {
285 target_if_err("wmi_handle is null");
286 return -EINVAL;
287 }
288
289 rsp = qdf_mem_malloc(sizeof(*rsp));
290 if (!rsp)
291 return -ENOMEM;
292
293 status = wmi_extract_ndp_initiator_rsp(wmi_handle, data, rsp);
294 if (QDF_IS_STATUS_ERROR(status)) {
295 target_if_err("parsing of event failed, %d", status);
296 qdf_mem_free(rsp);
297 return -EINVAL;
298 }
299
300 msg.bodyptr = rsp;
301 msg.type = NDP_INITIATOR_RSP;
302 msg.callback = target_if_ndp_event_dispatcher;
303 msg.flush_callback = target_if_ndp_event_flush_cb;
304 target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
305 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
306 QDF_MODULE_ID_TARGET_IF,
307 QDF_MODULE_ID_TARGET_IF, &msg);
308 if (QDF_IS_STATUS_ERROR(status)) {
309 target_if_ndp_event_flush_cb(&msg);
310 return -EINVAL;
311 }
312
313 return 0;
314 }
315
target_if_ndp_ind_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)316 static int target_if_ndp_ind_handler(ol_scn_t scn, uint8_t *data,
317 uint32_t data_len)
318 {
319 QDF_STATUS status;
320 struct wlan_objmgr_psoc *psoc;
321 struct wmi_unified *wmi_handle;
322 struct scheduler_msg msg = {0};
323 struct nan_datapath_indication_event *rsp;
324
325 psoc = target_if_get_psoc_from_scn_hdl(scn);
326 if (!psoc) {
327 target_if_err("psoc is null");
328 return -EINVAL;
329 }
330
331 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
332 if (!wmi_handle) {
333 target_if_err("wmi_handle is null");
334 return -EINVAL;
335 }
336
337 rsp = qdf_mem_malloc(sizeof(*rsp));
338 if (!rsp)
339 return -ENOMEM;
340
341 status = wmi_extract_ndp_ind(wmi_handle, data, rsp);
342 if (QDF_IS_STATUS_ERROR(status)) {
343 target_if_err("parsing of event failed, %d", status);
344 qdf_mem_free(rsp);
345 return -EINVAL;
346 }
347
348 msg.bodyptr = rsp;
349 msg.type = NDP_INDICATION;
350 msg.callback = target_if_ndp_event_dispatcher;
351 msg.flush_callback = target_if_ndp_event_flush_cb;
352 target_if_debug("NDP_INDICATION sent: %d", msg.type);
353 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
354 QDF_MODULE_ID_TARGET_IF,
355 QDF_MODULE_ID_TARGET_IF, &msg);
356 if (QDF_IS_STATUS_ERROR(status)) {
357 target_if_ndp_event_flush_cb(&msg);
358 return -EINVAL;
359 }
360
361 return 0;
362 }
363
target_if_ndp_confirm_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)364 static int target_if_ndp_confirm_handler(ol_scn_t scn, uint8_t *data,
365 uint32_t data_len)
366 {
367 QDF_STATUS status;
368 struct wlan_objmgr_psoc *psoc;
369 struct wmi_unified *wmi_handle;
370 struct scheduler_msg msg = {0};
371 struct nan_datapath_confirm_event *rsp;
372
373 psoc = target_if_get_psoc_from_scn_hdl(scn);
374 if (!psoc) {
375 target_if_err("psoc is null");
376 return -EINVAL;
377 }
378
379 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
380 if (!wmi_handle) {
381 target_if_err("wmi_handle is null");
382 return -EINVAL;
383 }
384
385 rsp = qdf_mem_malloc(sizeof(*rsp));
386 if (!rsp)
387 return -ENOMEM;
388
389 status = wmi_extract_ndp_confirm(wmi_handle, data, rsp);
390 if (QDF_IS_STATUS_ERROR(status)) {
391 target_if_err("parsing of event failed, %d", status);
392 qdf_mem_free(rsp);
393 return -EINVAL;
394 }
395
396 msg.bodyptr = rsp;
397 msg.type = NDP_CONFIRM;
398 msg.callback = target_if_ndp_event_dispatcher;
399 msg.flush_callback = target_if_ndp_event_flush_cb;
400 target_if_debug("NDP_CONFIRM sent: %d", msg.type);
401 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
402 QDF_MODULE_ID_TARGET_IF,
403 QDF_MODULE_ID_TARGET_IF, &msg);
404 if (QDF_IS_STATUS_ERROR(status)) {
405 target_if_ndp_event_flush_cb(&msg);
406 return -EINVAL;
407 }
408
409 return 0;
410 }
411
target_if_nan_ndp_responder_req(struct nan_datapath_responder_req * req)412 static QDF_STATUS target_if_nan_ndp_responder_req(
413 struct nan_datapath_responder_req *req)
414 {
415 QDF_STATUS status;
416 struct wmi_unified *wmi_handle;
417 struct wlan_objmgr_psoc *psoc;
418 struct scheduler_msg pe_msg = {0};
419 struct wlan_nan_rx_ops *nan_rx_ops;
420 struct nan_datapath_responder_rsp rsp = {0};
421
422 if (!req) {
423 target_if_err("Invalid req.");
424 return QDF_STATUS_E_INVAL;
425 }
426
427 psoc = wlan_vdev_get_psoc(req->vdev);
428 if (!psoc) {
429 target_if_err("psoc is null.");
430 return QDF_STATUS_E_NULL_VALUE;
431 }
432
433 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
434 if (!wmi_handle) {
435 target_if_err("wmi_handle is null.");
436 return QDF_STATUS_E_NULL_VALUE;
437 }
438
439 nan_rx_ops = nan_psoc_get_rx_ops(psoc);
440 if (!nan_rx_ops) {
441 target_if_err("nan_rx_ops is null.");
442 return QDF_STATUS_E_NULL_VALUE;
443 }
444
445 status = wmi_unified_ndp_responder_req_cmd_send(wmi_handle, req);
446 if (QDF_IS_STATUS_SUCCESS(status))
447 return status;
448
449 rsp.vdev = req->vdev;
450 rsp.transaction_id = req->transaction_id;
451 rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
452 rsp.reason = NAN_DATAPATH_DATA_RESPONDER_REQ_FAILED;
453 pe_msg.bodyptr = &rsp;
454 pe_msg.type = NDP_RESPONDER_RSP;
455 if (nan_rx_ops->nan_datapath_event_rx)
456 nan_rx_ops->nan_datapath_event_rx(&pe_msg);
457
458 return status;
459 }
460
target_if_ndp_responder_rsp_handler(ol_scn_t scn,uint8_t * data,uint32_t len)461 static int target_if_ndp_responder_rsp_handler(ol_scn_t scn, uint8_t *data,
462 uint32_t len)
463 {
464 QDF_STATUS status;
465 struct wlan_objmgr_psoc *psoc;
466 struct wmi_unified *wmi_handle;
467 struct scheduler_msg msg = {0};
468 struct nan_datapath_responder_rsp *rsp;
469
470 psoc = target_if_get_psoc_from_scn_hdl(scn);
471 if (!psoc) {
472 target_if_err("psoc is null");
473 return -EINVAL;
474 }
475
476 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
477 if (!wmi_handle) {
478 target_if_err("wmi_handle is null.");
479 return -EINVAL;
480 }
481
482 rsp = qdf_mem_malloc(sizeof(*rsp));
483 if (!rsp)
484 return -ENOMEM;
485
486 status = wmi_extract_ndp_responder_rsp(wmi_handle, data, rsp);
487 if (QDF_IS_STATUS_ERROR(status)) {
488 target_if_err("parsing of event failed, %d", status);
489 qdf_mem_free(rsp);
490 return -EINVAL;
491 }
492
493 msg.bodyptr = rsp;
494 msg.type = NDP_RESPONDER_RSP;
495 msg.callback = target_if_ndp_event_dispatcher;
496 msg.flush_callback = target_if_ndp_event_flush_cb;
497 target_if_debug("NDP_INITIATOR_RSP sent: %d", msg.type);
498 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
499 QDF_MODULE_ID_TARGET_IF,
500 QDF_MODULE_ID_TARGET_IF, &msg);
501 if (QDF_IS_STATUS_ERROR(status)) {
502 target_if_ndp_event_flush_cb(&msg);
503 return -EINVAL;
504 }
505
506 return 0;
507 }
508
target_if_nan_ndp_end_req(struct nan_datapath_end_req * req)509 static QDF_STATUS target_if_nan_ndp_end_req(struct nan_datapath_end_req *req)
510 {
511 QDF_STATUS status;
512 struct wmi_unified *wmi_handle;
513 struct wlan_objmgr_psoc *psoc;
514 struct scheduler_msg msg = {0};
515 struct wlan_nan_rx_ops *nan_rx_ops;
516 struct nan_datapath_end_rsp_event end_rsp = {0};
517
518 if (!req) {
519 target_if_err("req is null");
520 return QDF_STATUS_E_INVAL;
521 }
522
523 psoc = wlan_vdev_get_psoc(req->vdev);
524 if (!psoc) {
525 target_if_err("psoc is null.");
526 return QDF_STATUS_E_NULL_VALUE;
527 }
528
529 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
530 if (!wmi_handle) {
531 target_if_err("wmi_handle is null.");
532 return QDF_STATUS_E_NULL_VALUE;
533 }
534
535 nan_rx_ops = nan_psoc_get_rx_ops(psoc);
536 if (!nan_rx_ops) {
537 target_if_err("nan_rx_ops is null.");
538 return QDF_STATUS_E_NULL_VALUE;
539 }
540
541 status = wmi_unified_ndp_end_req_cmd_send(wmi_handle, req);
542 if (QDF_IS_STATUS_SUCCESS(status))
543 return status;
544
545 end_rsp.vdev = req->vdev;
546 msg.type = NDP_END_RSP;
547 end_rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
548 end_rsp.reason = NAN_DATAPATH_END_FAILED;
549 end_rsp.transaction_id = req->transaction_id;
550 msg.bodyptr = &end_rsp;
551
552 if (nan_rx_ops->nan_datapath_event_rx)
553 nan_rx_ops->nan_datapath_event_rx(&msg);
554
555 return status;
556 }
557
target_if_ndp_end_rsp_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)558 static int target_if_ndp_end_rsp_handler(ol_scn_t scn, uint8_t *data,
559 uint32_t data_len)
560 {
561 QDF_STATUS status;
562 struct wlan_objmgr_psoc *psoc;
563 struct wmi_unified *wmi_handle;
564 struct scheduler_msg msg = {0};
565 struct nan_datapath_end_rsp_event *end_rsp;
566
567 psoc = target_if_get_psoc_from_scn_hdl(scn);
568 if (!psoc) {
569 target_if_err("psoc is null");
570 return -EINVAL;
571 }
572
573 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
574 if (!wmi_handle) {
575 target_if_err("wmi_handle is null.");
576 return -EINVAL;
577 }
578
579 end_rsp = qdf_mem_malloc(sizeof(*end_rsp));
580 if (!end_rsp)
581 return -ENOMEM;
582
583 status = wmi_extract_ndp_end_rsp(wmi_handle, data, end_rsp);
584 if (QDF_IS_STATUS_ERROR(status)) {
585 target_if_err("parsing of event failed, %d", status);
586 qdf_mem_free(end_rsp);
587 return -EINVAL;
588 }
589
590 msg.bodyptr = end_rsp;
591 msg.type = NDP_END_RSP;
592 msg.callback = target_if_ndp_event_dispatcher;
593 msg.flush_callback = target_if_ndp_event_flush_cb;
594 target_if_debug("NDP_END_RSP sent: %d", msg.type);
595 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
596 QDF_MODULE_ID_TARGET_IF,
597 QDF_MODULE_ID_TARGET_IF, &msg);
598 if (QDF_IS_STATUS_ERROR(status)) {
599 target_if_ndp_event_flush_cb(&msg);
600 return -EINVAL;
601 }
602
603 return 0;
604 }
605
target_if_ndp_end_ind_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)606 static int target_if_ndp_end_ind_handler(ol_scn_t scn, uint8_t *data,
607 uint32_t data_len)
608 {
609 QDF_STATUS status;
610 struct wlan_objmgr_psoc *psoc;
611 struct wmi_unified *wmi_handle;
612 struct scheduler_msg msg = {0};
613 struct nan_datapath_end_indication_event *rsp = NULL;
614
615 psoc = target_if_get_psoc_from_scn_hdl(scn);
616 if (!psoc) {
617 target_if_err("psoc is null");
618 return -EINVAL;
619 }
620
621 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
622 if (!wmi_handle) {
623 target_if_err("wmi_handle is null.");
624 return -EINVAL;
625 }
626
627 status = wmi_extract_ndp_end_ind(wmi_handle, data, &rsp);
628 if (QDF_IS_STATUS_ERROR(status)) {
629 target_if_err("parsing of event failed, %d", status);
630 return -EINVAL;
631 }
632
633 rsp->vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
634 wmi_handle->soc->wmi_psoc, QDF_NDI_MODE, WLAN_NAN_ID);
635 if (!rsp->vdev) {
636 target_if_err("vdev is null");
637 qdf_mem_free(rsp);
638 return -EINVAL;
639 }
640
641 msg.bodyptr = rsp;
642 msg.type = NDP_END_IND;
643 msg.callback = target_if_ndp_event_dispatcher;
644 msg.flush_callback = target_if_ndp_event_flush_cb;
645 target_if_debug("NDP_END_IND sent: %d", msg.type);
646 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
647 QDF_MODULE_ID_TARGET_IF,
648 QDF_MODULE_ID_TARGET_IF, &msg);
649 if (QDF_IS_STATUS_ERROR(status)) {
650 target_if_ndp_event_flush_cb(&msg);
651 return -EINVAL;
652 }
653
654 return 0;
655 }
656
target_if_ndp_sch_update_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)657 static int target_if_ndp_sch_update_handler(ol_scn_t scn, uint8_t *data,
658 uint32_t data_len)
659 {
660 QDF_STATUS status;
661 struct wlan_objmgr_psoc *psoc;
662 struct wmi_unified *wmi_handle;
663 struct scheduler_msg msg = {0};
664 struct nan_datapath_sch_update_event *rsp;
665
666 psoc = target_if_get_psoc_from_scn_hdl(scn);
667 if (!psoc) {
668 target_if_err("psoc is null");
669 return -EINVAL;
670 }
671
672 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
673 if (!wmi_handle) {
674 target_if_err("wmi_handle is null.");
675 return -EINVAL;
676 }
677
678 rsp = qdf_mem_malloc(sizeof(*rsp));
679 if (!rsp)
680 return -ENOMEM;
681
682 status = wmi_extract_ndp_sch_update(wmi_handle, data, rsp);
683 if (QDF_IS_STATUS_ERROR(status)) {
684 target_if_err("parsing of event failed, %d", status);
685 qdf_mem_free(rsp);
686 return -EINVAL;
687 }
688
689 msg.bodyptr = rsp;
690 msg.type = NDP_SCHEDULE_UPDATE;
691 msg.callback = target_if_ndp_event_dispatcher;
692 msg.flush_callback = target_if_ndp_event_flush_cb;
693 target_if_debug("NDP_SCHEDULE_UPDATE sent: %d", msg.type);
694 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
695 QDF_MODULE_ID_TARGET_IF,
696 QDF_MODULE_ID_TARGET_IF, &msg);
697 if (QDF_IS_STATUS_ERROR(status)) {
698 target_if_ndp_event_flush_cb(&msg);
699 return -EINVAL;
700 }
701
702 return 0;
703 }
704
target_if_nan_end_all_ndps_req(void * req)705 static QDF_STATUS target_if_nan_end_all_ndps_req(void *req)
706 {
707 struct wlan_objmgr_vdev *vdev;
708 struct wlan_objmgr_psoc *psoc;
709 struct wmi_unified *wmi_handle;
710 uint8_t vdev_id;
711
712 vdev = ((struct nan_datapath_end_all_ndps *)req)->vdev;
713 if (!vdev) {
714 target_if_err("vdev object is NULL!");
715 return QDF_STATUS_E_INVAL;
716 }
717 vdev_id = wlan_vdev_get_id(vdev);
718
719 psoc = wlan_vdev_get_psoc(vdev);
720 if (!psoc) {
721 target_if_err("psoc is null.");
722 return QDF_STATUS_E_NULL_VALUE;
723 }
724
725 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
726 if (!wmi_handle) {
727 target_if_err("wmi_handle is null.");
728 return QDF_STATUS_E_NULL_VALUE;
729 }
730
731 return wmi_unified_terminate_all_ndps_req_cmd(wmi_handle, vdev_id);
732 }
733
target_if_ndp_host_event_handler(ol_scn_t scn,uint8_t * data,uint32_t data_len)734 static int target_if_ndp_host_event_handler(ol_scn_t scn, uint8_t *data,
735 uint32_t data_len)
736 {
737 QDF_STATUS status;
738 struct wlan_objmgr_psoc *psoc;
739 struct wmi_unified *wmi_handle;
740 struct scheduler_msg msg = {0};
741 struct nan_datapath_host_event *host_evt = NULL;
742
743 psoc = target_if_get_psoc_from_scn_hdl(scn);
744 if (!psoc) {
745 target_if_err("psoc is null");
746 return -EINVAL;
747 }
748
749 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
750 if (!wmi_handle) {
751 target_if_err("wmi_handle is null.");
752 return -EINVAL;
753 }
754
755 host_evt = qdf_mem_malloc(sizeof(*host_evt));
756 if (!host_evt)
757 return -ENOMEM;
758
759 status = wmi_extract_ndp_host_event(wmi_handle, data, host_evt);
760 if (QDF_IS_STATUS_ERROR(status)) {
761 target_if_err("parsing of event failed, %d", status);
762 qdf_mem_free(host_evt);
763 return -EINVAL;
764 }
765
766 if (!host_evt->vdev) {
767 target_if_err("vdev is null");
768 qdf_mem_free(host_evt);
769 return -EINVAL;
770 }
771
772 msg.bodyptr = host_evt;
773 msg.type = NDP_HOST_UPDATE;
774 msg.callback = target_if_ndp_event_dispatcher;
775 msg.flush_callback = target_if_ndp_event_flush_cb;
776 target_if_debug("NDP_HOST_UPDATE sent: %d", msg.type);
777 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
778 QDF_MODULE_ID_TARGET_IF,
779 QDF_MODULE_ID_TARGET_IF, &msg);
780 if (QDF_IS_STATUS_ERROR(status)) {
781 target_if_err("failed to post msg, status: %d", status);
782 target_if_ndp_event_flush_cb(&msg);
783 return -EINVAL;
784 }
785
786 return 0;
787 }
788
target_if_nan_datapath_req(void * req,uint32_t req_type)789 static QDF_STATUS target_if_nan_datapath_req(void *req, uint32_t req_type)
790 {
791 /* send cmd to fw */
792 switch (req_type) {
793 case NDP_INITIATOR_REQ:
794 target_if_nan_ndp_initiator_req(req);
795 break;
796 case NDP_RESPONDER_REQ:
797 target_if_nan_ndp_responder_req(req);
798 break;
799 case NDP_END_REQ:
800 target_if_nan_ndp_end_req(req);
801 break;
802 case NDP_END_ALL:
803 target_if_nan_end_all_ndps_req(req);
804 break;
805 default:
806 target_if_err("invalid req type");
807 break;
808 }
809 return QDF_STATUS_SUCCESS;
810 }
811
target_if_nan_generic_req(struct wlan_objmgr_psoc * psoc,void * nan_req)812 static QDF_STATUS target_if_nan_generic_req(struct wlan_objmgr_psoc *psoc,
813 void *nan_req)
814 {
815 struct wmi_unified *wmi_handle;
816
817 if (!psoc) {
818 target_if_err("psoc is null.");
819 return QDF_STATUS_E_NULL_VALUE;
820 }
821
822 if (!nan_req) {
823 target_if_err("Invalid req.");
824 return QDF_STATUS_E_INVAL;
825 }
826
827 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
828 if (!wmi_handle) {
829 target_if_err("wmi_handle is null.");
830 return QDF_STATUS_E_NULL_VALUE;
831 }
832
833 return wmi_unified_nan_req_cmd(wmi_handle, nan_req);
834 }
835
target_if_nan_disable_req(struct nan_disable_req * nan_req)836 static QDF_STATUS target_if_nan_disable_req(struct nan_disable_req *nan_req)
837 {
838 struct wmi_unified *wmi_handle;
839 struct wlan_objmgr_psoc *psoc;
840
841 if (!nan_req) {
842 target_if_err("Invalid req.");
843 return QDF_STATUS_E_INVAL;
844 }
845 psoc = nan_req->psoc;
846
847 if (!psoc) {
848 target_if_err("psoc is null.");
849 return QDF_STATUS_E_NULL_VALUE;
850 }
851
852 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
853 if (!wmi_handle) {
854 target_if_err("wmi_handle is null.");
855 return QDF_STATUS_E_NULL_VALUE;
856 }
857
858 return wmi_unified_nan_disable_req_cmd(wmi_handle, nan_req);
859 }
860
target_if_nan_discovery_req(void * req,uint32_t req_type)861 static QDF_STATUS target_if_nan_discovery_req(void *req, uint32_t req_type)
862 {
863 QDF_STATUS status;
864
865 if (!req) {
866 target_if_err("Invalid req.");
867 return QDF_STATUS_E_INVAL;
868 }
869
870 switch (req_type) {
871 case NAN_DISABLE_REQ:
872 status = target_if_nan_disable_req(req);
873 break;
874 case NAN_GENERIC_REQ: {
875 struct nan_generic_req *nan_req = req;
876
877 status = target_if_nan_generic_req(nan_req->psoc,
878 &nan_req->params);
879 break;
880 }
881 case NAN_ENABLE_REQ: {
882 struct nan_enable_req *nan_req = req;
883
884 status = target_if_nan_generic_req(nan_req->psoc,
885 &nan_req->params);
886 break;
887 }
888 default:
889 target_if_err("Invalid NAN req type");
890 status = QDF_STATUS_E_INVAL;
891 break;
892 }
893
894 return status;
895 }
896
target_if_nan_register_tx_ops(struct wlan_nan_tx_ops * tx_ops)897 void target_if_nan_register_tx_ops(struct wlan_nan_tx_ops *tx_ops)
898 {
899 tx_ops->nan_discovery_req_tx = target_if_nan_discovery_req;
900 tx_ops->nan_datapath_req_tx = target_if_nan_datapath_req;
901 }
902
target_if_nan_register_rx_ops(struct wlan_nan_rx_ops * rx_ops)903 void target_if_nan_register_rx_ops(struct wlan_nan_rx_ops *rx_ops)
904 {
905 rx_ops->nan_discovery_event_rx = nan_discovery_event_handler;
906 rx_ops->nan_datapath_event_rx = nan_datapath_event_handler;
907 }
908
target_if_nan_rsp_handler(ol_scn_t scn,uint8_t * data,uint32_t len)909 int target_if_nan_rsp_handler(ol_scn_t scn, uint8_t *data, uint32_t len)
910 {
911 struct nan_event_params *nan_rsp, temp_evt_params = {0};
912 struct scheduler_msg msg = {0};
913 struct wmi_unified *wmi_handle;
914 struct wlan_objmgr_psoc *psoc;
915 QDF_STATUS status;
916 uint8_t *buf_ptr;
917
918 psoc = target_if_get_psoc_from_scn_hdl(scn);
919 if (!psoc) {
920 target_if_err("psoc is null");
921 return -EINVAL;
922 }
923
924 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
925 if (!wmi_handle) {
926 target_if_err("wmi_handle is null");
927 return -EINVAL;
928 }
929
930 status = wmi_extract_nan_event_rsp(wmi_handle, data, &temp_evt_params,
931 &buf_ptr);
932 if (QDF_IS_STATUS_ERROR(status)) {
933 target_if_err("parsing of event failed, %d", status);
934 return -EINVAL;
935 }
936
937 nan_rsp = qdf_mem_malloc(sizeof(*nan_rsp) + temp_evt_params.buf_len);
938 if (!nan_rsp)
939 return -ENOMEM;
940
941 qdf_mem_copy(nan_rsp, &temp_evt_params, sizeof(*nan_rsp));
942
943 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_NAN_ID);
944 if (QDF_IS_STATUS_ERROR(status)) {
945 target_if_err("Failed to obtain psoc ref");
946 return -EACCES;
947 }
948
949 nan_rsp->psoc = psoc;
950 qdf_mem_copy(nan_rsp->buf, buf_ptr, nan_rsp->buf_len);
951
952 msg.bodyptr = nan_rsp;
953 msg.type = nan_rsp->evt_type;
954 msg.callback = target_if_nan_event_dispatcher;
955 msg.flush_callback = target_if_nan_event_flush_cb;
956 target_if_debug("NAN Event sent: %d", msg.type);
957 status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
958 QDF_MODULE_ID_TARGET_IF,
959 QDF_MODULE_ID_TARGET_IF, &msg);
960 if (QDF_IS_STATUS_ERROR(status)) {
961 target_if_err("failed to post msg, status: %d", status);
962 target_if_nan_event_flush_cb(&msg);
963 return -EINVAL;
964 }
965
966 return 0;
967 }
968
target_if_nan_register_events(struct wlan_objmgr_psoc * psoc)969 QDF_STATUS target_if_nan_register_events(struct wlan_objmgr_psoc *psoc)
970 {
971 QDF_STATUS ret;
972 wmi_unified_t handle = get_wmi_unified_hdl_from_psoc(psoc);
973
974 if (!handle) {
975 target_if_err("handle is NULL");
976 return QDF_STATUS_E_FAILURE;
977 }
978
979 /* Register for nan response event */
980 ret = wmi_unified_register_event_handler(handle, wmi_nan_event_id,
981 target_if_nan_rsp_handler,
982 WMI_RX_UMAC_CTX);
983 if (QDF_IS_STATUS_ERROR(ret)) {
984 target_if_err("wmi event registration failed, ret: %d", ret);
985 return QDF_STATUS_E_FAILURE;
986 }
987
988 ret = wmi_unified_register_event_handler(handle,
989 wmi_ndp_initiator_rsp_event_id,
990 target_if_ndp_initiator_rsp_handler,
991 WMI_RX_UMAC_CTX);
992 if (QDF_IS_STATUS_ERROR(ret)) {
993 target_if_err("wmi event registration failed, ret: %d", ret);
994 return QDF_STATUS_E_FAILURE;
995 }
996
997 ret = wmi_unified_register_event_handler(handle, wmi_nan_dmesg_event_id,
998 target_if_nan_dmesg_handler,
999 WMI_RX_WORK_CTX);
1000 if (QDF_IS_STATUS_ERROR(ret)) {
1001 target_if_err("wmi event registration failed, ret: %d", ret);
1002 target_if_nan_deregister_events(psoc);
1003 return QDF_STATUS_E_FAILURE;
1004 }
1005
1006 ret = wmi_unified_register_event_handler(handle,
1007 wmi_ndp_indication_event_id,
1008 target_if_ndp_ind_handler,
1009 WMI_RX_UMAC_CTX);
1010 if (QDF_IS_STATUS_ERROR(ret)) {
1011 target_if_err("wmi event registration failed, ret: %d", ret);
1012 target_if_nan_deregister_events(psoc);
1013 return QDF_STATUS_E_FAILURE;
1014 }
1015
1016 ret = wmi_unified_register_event_handler(handle,
1017 wmi_ndp_confirm_event_id,
1018 target_if_ndp_confirm_handler,
1019 WMI_RX_UMAC_CTX);
1020 if (QDF_IS_STATUS_ERROR(ret)) {
1021 target_if_err("wmi event registration failed, ret: %d", ret);
1022 target_if_nan_deregister_events(psoc);
1023 return QDF_STATUS_E_FAILURE;
1024 }
1025
1026 ret = wmi_unified_register_event_handler(handle,
1027 wmi_ndp_responder_rsp_event_id,
1028 target_if_ndp_responder_rsp_handler,
1029 WMI_RX_UMAC_CTX);
1030 if (QDF_IS_STATUS_ERROR(ret)) {
1031 target_if_err("wmi event registration failed, ret: %d", ret);
1032 target_if_nan_deregister_events(psoc);
1033 return QDF_STATUS_E_FAILURE;
1034 }
1035
1036 ret = wmi_unified_register_event_handler(handle,
1037 wmi_ndp_end_indication_event_id,
1038 target_if_ndp_end_ind_handler,
1039 WMI_RX_UMAC_CTX);
1040 if (QDF_IS_STATUS_ERROR(ret)) {
1041 target_if_err("wmi event registration failed, ret: %d", ret);
1042 target_if_nan_deregister_events(psoc);
1043 return QDF_STATUS_E_FAILURE;
1044 }
1045
1046 ret = wmi_unified_register_event_handler(handle,
1047 wmi_ndp_end_rsp_event_id,
1048 target_if_ndp_end_rsp_handler,
1049 WMI_RX_UMAC_CTX);
1050 if (QDF_IS_STATUS_ERROR(ret)) {
1051 target_if_err("wmi event registration failed, ret: %d", ret);
1052 target_if_nan_deregister_events(psoc);
1053 return QDF_STATUS_E_FAILURE;
1054 }
1055
1056 ret = wmi_unified_register_event_handler(handle,
1057 wmi_ndl_schedule_update_event_id,
1058 target_if_ndp_sch_update_handler,
1059 WMI_RX_UMAC_CTX);
1060 if (QDF_IS_STATUS_ERROR(ret)) {
1061 target_if_err("wmi event registration failed, ret: %d", ret);
1062 target_if_nan_deregister_events(psoc);
1063 return QDF_STATUS_E_FAILURE;
1064 }
1065
1066 ret = wmi_unified_register_event_handler(handle, wmi_ndp_event_id,
1067 target_if_ndp_host_event_handler,
1068 WMI_RX_UMAC_CTX);
1069 if (QDF_IS_STATUS_ERROR(ret)) {
1070 target_if_err("wmi event registration failed, ret: %d", ret);
1071 target_if_nan_deregister_events(psoc);
1072 return QDF_STATUS_E_FAILURE;
1073 }
1074
1075 return QDF_STATUS_SUCCESS;
1076 }
1077
target_if_nan_deregister_events(struct wlan_objmgr_psoc * psoc)1078 QDF_STATUS target_if_nan_deregister_events(struct wlan_objmgr_psoc *psoc)
1079 {
1080 QDF_STATUS ret, status = QDF_STATUS_SUCCESS;
1081 wmi_unified_t handle = get_wmi_unified_hdl_from_psoc(psoc);
1082
1083 if (!handle) {
1084 target_if_err("handle is NULL");
1085 return QDF_STATUS_E_FAILURE;
1086 }
1087 ret = wmi_unified_unregister_event_handler(handle,
1088 wmi_ndl_schedule_update_event_id);
1089 if (QDF_IS_STATUS_ERROR(ret)) {
1090 target_if_err("wmi event deregistration failed, ret: %d", ret);
1091 status = ret;
1092 }
1093
1094 ret = wmi_unified_unregister_event_handler(handle,
1095 wmi_ndp_end_rsp_event_id);
1096 if (QDF_IS_STATUS_ERROR(ret)) {
1097 target_if_err("wmi event deregistration failed, ret: %d", ret);
1098 status = ret;
1099 }
1100
1101 ret = wmi_unified_unregister_event_handler(handle,
1102 wmi_ndp_end_indication_event_id);
1103 if (QDF_IS_STATUS_ERROR(ret)) {
1104 target_if_err("wmi event deregistration failed, ret: %d", ret);
1105 status = ret;
1106 }
1107
1108 ret = wmi_unified_unregister_event_handler(handle,
1109 wmi_ndp_responder_rsp_event_id);
1110 if (QDF_IS_STATUS_ERROR(ret)) {
1111 target_if_err("wmi event deregistration failed, ret: %d", ret);
1112 status = ret;
1113 }
1114
1115 ret = wmi_unified_unregister_event_handler(handle,
1116 wmi_ndp_confirm_event_id);
1117 if (QDF_IS_STATUS_ERROR(ret)) {
1118 target_if_err("wmi event deregistration failed, ret: %d", ret);
1119 status = ret;
1120 }
1121
1122 ret = wmi_unified_unregister_event_handler(handle,
1123 wmi_ndp_indication_event_id);
1124 if (QDF_IS_STATUS_ERROR(ret)) {
1125 target_if_err("wmi event deregistration failed, ret: %d", ret);
1126 status = ret;
1127 }
1128
1129 ret = wmi_unified_unregister_event_handler(handle,
1130 wmi_nan_dmesg_event_id);
1131 if (QDF_IS_STATUS_ERROR(ret)) {
1132 target_if_err("wmi event deregistration failed, ret: %d", ret);
1133 status = ret;
1134 }
1135
1136 ret = wmi_unified_unregister_event_handler(handle,
1137 wmi_ndp_initiator_rsp_event_id);
1138 if (QDF_IS_STATUS_ERROR(ret)) {
1139 target_if_err("wmi event deregistration failed, ret: %d", ret);
1140 status = ret;
1141 }
1142
1143 ret = wmi_unified_unregister_event_handler(handle, wmi_ndp_event_id);
1144 if (QDF_IS_STATUS_ERROR(ret)) {
1145 target_if_err("wmi event deregistration failed, ret: %d", ret);
1146 status = ret;
1147 }
1148
1149 if (QDF_IS_STATUS_ERROR(status))
1150 return QDF_STATUS_E_FAILURE;
1151 else
1152 return QDF_STATUS_SUCCESS;
1153 }
1154
target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1155 void target_if_nan_set_vdev_feature_config(struct wlan_objmgr_psoc *psoc,
1156 uint8_t vdev_id)
1157 {
1158 QDF_STATUS status;
1159 uint32_t nan_features;
1160 struct vdev_set_params param;
1161 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
1162
1163 if (!wmi_handle) {
1164 target_if_err("Invalid wmi handle");
1165 return;
1166 }
1167
1168 if (!target_if_is_vdev_valid(vdev_id)) {
1169 target_if_err("vdev_id: %d is invalid, reject the req: param id %d",
1170 vdev_id,
1171 wmi_vdev_param_enable_disable_nan_config_features);
1172 return;
1173 }
1174
1175 ucfg_get_nan_feature_config(psoc, &nan_features);
1176 target_if_debug("vdev_id:%d NAN features:0x%x", vdev_id, nan_features);
1177
1178 param.vdev_id = vdev_id;
1179 param.param_id = wmi_vdev_param_enable_disable_nan_config_features;
1180 param.param_value = nan_features;
1181
1182 status = wmi_unified_vdev_set_param_send(wmi_handle, ¶m);
1183 if (QDF_IS_STATUS_ERROR(status))
1184 target_if_err("failed to set NAN_CONFIG_FEATURES(status = %d)",
1185 status);
1186 }
1187