1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 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: defines nan component os interface APIs
22 */
23
24 #include "osif_sync.h"
25 #include "qdf_str.h"
26 #include "qdf_trace.h"
27 #include "qdf_types.h"
28 #include "os_if_nan.h"
29 #include "wlan_nan_api.h"
30 #include "nan_ucfg_api.h"
31 #include "wlan_osif_priv.h"
32 #include <net/cfg80211.h>
33 #include "wlan_cfg80211.h"
34 #include "wlan_objmgr_psoc_obj.h"
35 #include "wlan_objmgr_pdev_obj.h"
36 #include "wlan_objmgr_vdev_obj.h"
37 #include "wlan_utility.h"
38 #include "wlan_osif_request_manager.h"
39 #include "wlan_mlme_ucfg_api.h"
40 #include "wlan_tdls_ucfg_api.h"
41
42 #define NAN_CMD_MAX_SIZE 2048
43
44 /* NLA policy */
45 const struct nla_policy nan_attr_policy[
46 QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX + 1] = {
47 [QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA] = {
48 .type = NLA_BINARY,
49 .len = NAN_CMD_MAX_SIZE
50 },
51 [QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE] = {
52 .type = NLA_U32,
53 .len = sizeof(uint32_t)
54 },
55 [QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ] = {
56 .type = NLA_U32,
57 .len = sizeof(uint32_t)
58 },
59 [QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ] = {
60 .type = NLA_U32,
61 .len = sizeof(uint32_t)
62 },
63 };
64
65 /* NLA policy */
66 const struct nla_policy vendor_attr_policy[
67 QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
68 [QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD] = {
69 .type = NLA_U32,
70 .len = sizeof(uint32_t)
71 },
72 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = {
73 .type = NLA_U16,
74 .len = sizeof(uint16_t)
75 },
76 [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = {
77 .type = NLA_NUL_STRING,
78 .len = IFNAMSIZ - 1
79 },
80 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = {
81 .type = NLA_U32,
82 .len = sizeof(uint32_t)
83 },
84 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = {
85 .type = NLA_U32,
86 .len = sizeof(uint32_t)
87 },
88 [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] =
89 VENDOR_NLA_POLICY_MAC_ADDR,
90 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = {
91 .type = NLA_U16,
92 .len = sizeof(uint16_t)
93 },
94 [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = {
95 .type = NLA_U32,
96 .len = sizeof(uint32_t)
97 },
98 [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = {
99 .type = NLA_BINARY,
100 .len = NDP_APP_INFO_LEN
101 },
102 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = {
103 .type = NLA_U32,
104 .len = sizeof(uint32_t)
105 },
106 [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = {
107 .type = NLA_U32,
108 .len = sizeof(uint32_t)
109 },
110 [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = {
111 .type = NLA_BINARY,
112 .len = QDF_MAC_ADDR_SIZE
113 },
114 [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = {
115 .type = NLA_BINARY,
116 .len = NDP_NUM_INSTANCE_ID
117 },
118 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG] = {
119 .type = NLA_U32,
120 .len = sizeof(uint32_t)
121 },
122 [QCA_WLAN_VENDOR_ATTR_NDP_CSID] = {
123 .type = NLA_U32,
124 .len = sizeof(uint32_t)
125 },
126 [QCA_WLAN_VENDOR_ATTR_NDP_PMK] = {
127 .type = NLA_BINARY,
128 .len = NDP_PMK_LEN
129 },
130 [QCA_WLAN_VENDOR_ATTR_NDP_SCID] = {
131 .type = NLA_BINARY,
132 .len = NDP_SCID_BUF_LEN
133 },
134 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE] = {
135 .type = NLA_U32,
136 .len = sizeof(uint32_t)
137 },
138 [QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE] = {
139 .type = NLA_U32,
140 .len = sizeof(uint32_t)
141 },
142 [QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE] = {
143 .type = NLA_BINARY,
144 .len = NAN_PASSPHRASE_MAX_LEN
145 },
146 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME] = {
147 .type = NLA_BINARY,
148 .len = NAN_MAX_SERVICE_NAME_LEN
149 },
150 [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO] = {
151 .type = NLA_BINARY,
152 .len = NAN_CH_INFO_MAX_LEN
153 },
154 [QCA_WLAN_VENDOR_ATTR_NDP_NSS] = {
155 .type = NLA_U32,
156 .len = sizeof(uint32_t)
157 },
158 [QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR] =
159 VENDOR_NLA_POLICY_IPV6_ADDR,
160 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT] = {
161 .type = NLA_U16,
162 .len = sizeof(uint16_t)
163 },
164 [QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL] = {
165 .type = NLA_U8,
166 .len = sizeof(uint8_t)
167 },
168 [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID] = {
169 .type = NLA_U8,
170 .len = NDP_SERVICE_ID_LEN
171 },
172 [QCA_WLAN_VENDOR_ATTR_NDP_CSIA_CAPABILITIES] = {
173 .type = NLA_U8,
174 .len = sizeof(uint8_t)
175 },
176 [QCA_WLAN_VENDOR_ATTR_NDP_GTK_REQUIRED] = {
177 .type = NLA_FLAG,
178 },
179 };
180
181 /**
182 * os_if_get_ndi_vdev_by_ifname_cb() - callback function to return vdev object
183 * from psoc matching given interface name
184 * @psoc: psoc object
185 * @obj: object used to iterate the callback function
186 * @arg: return argument which will be filled by the function
187 *
188 * Return : NULL
189 */
os_if_get_ndi_vdev_by_ifname_cb(struct wlan_objmgr_psoc * psoc,void * obj,void * arg)190 static void os_if_get_ndi_vdev_by_ifname_cb(struct wlan_objmgr_psoc *psoc,
191 void *obj, void *arg)
192 {
193 struct wlan_objmgr_vdev *vdev = obj;
194 struct ndi_find_vdev_filter *filter = arg;
195 struct vdev_osif_priv *osif_priv;
196
197 if (filter->found_vdev)
198 return;
199
200 wlan_vdev_obj_lock(vdev);
201
202 osif_priv = wlan_vdev_get_ospriv(vdev);
203 if (!osif_priv) {
204 wlan_vdev_obj_unlock(vdev);
205 return;
206 }
207
208 if (!osif_priv->wdev) {
209 wlan_vdev_obj_unlock(vdev);
210 return;
211 }
212
213 if (!qdf_str_cmp(osif_priv->wdev->netdev->name, filter->ifname))
214 filter->found_vdev = vdev;
215
216 wlan_vdev_obj_unlock(vdev);
217 }
218
219 /**
220 * os_if_get_ndi_vdev_by_ifname() - function to return vdev object from psoc
221 * matching given interface name
222 * @psoc: psoc object
223 * @ifname: interface name
224 *
225 * This function returns vdev object from psoc by interface name. If found this
226 * will also take reference with given ref_id
227 *
228 * Return : vdev object if found, NULL otherwise
229 */
230 static struct wlan_objmgr_vdev *
os_if_get_ndi_vdev_by_ifname(struct wlan_objmgr_psoc * psoc,const char * ifname)231 os_if_get_ndi_vdev_by_ifname(struct wlan_objmgr_psoc *psoc, const char *ifname)
232 {
233 QDF_STATUS status;
234 struct ndi_find_vdev_filter filter = {0};
235
236 filter.ifname = ifname;
237 wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
238 os_if_get_ndi_vdev_by_ifname_cb,
239 &filter, 0, WLAN_NAN_ID);
240
241 if (!filter.found_vdev)
242 return NULL;
243
244 status = wlan_objmgr_vdev_try_get_ref(filter.found_vdev, WLAN_NAN_ID);
245 if (QDF_IS_STATUS_ERROR(status))
246 return NULL;
247
248 return filter.found_vdev;
249 }
250
251 /**
252 * os_if_ndi_get_if_name() - get vdev's interface name
253 * @vdev: VDEV object
254 *
255 * API to get vdev's interface name
256 *
257 * Return: vdev's interface name
258 */
os_if_ndi_get_if_name(struct wlan_objmgr_vdev * vdev)259 static const uint8_t *os_if_ndi_get_if_name(struct wlan_objmgr_vdev *vdev)
260 {
261 struct vdev_osif_priv *osif_priv;
262
263 wlan_vdev_obj_lock(vdev);
264
265 osif_priv = wlan_vdev_get_ospriv(vdev);
266 if (!osif_priv) {
267 wlan_vdev_obj_unlock(vdev);
268 return NULL;
269 }
270
271 if (!osif_priv->wdev) {
272 wlan_vdev_obj_unlock(vdev);
273 return NULL;
274 }
275
276 wlan_vdev_obj_unlock(vdev);
277
278 return osif_priv->wdev->netdev->name;
279 }
280
281 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
os_if_nan_ndi_open(struct wlan_objmgr_psoc * psoc,const char * iface_name)282 static int os_if_nan_ndi_open(struct wlan_objmgr_psoc *psoc,
283 const char *iface_name)
284 {
285 return 0;
286 }
287 #else
os_if_nan_ndi_open(struct wlan_objmgr_psoc * psoc,const char * iface_name)288 static int os_if_nan_ndi_open(struct wlan_objmgr_psoc *psoc,
289 const char *iface_name)
290 {
291 QDF_STATUS status;
292 struct nan_callbacks cb_obj;
293 int ret;
294
295 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
296 if (QDF_IS_STATUS_ERROR(status)) {
297 osif_err("Couldn't get callback object");
298 return -EINVAL;
299 }
300
301 ret = cb_obj.ndi_open(iface_name, false);
302 if (ret)
303 osif_err("ndi_open failed");
304
305 return ret;
306 }
307 #endif
308
__os_if_nan_process_ndi_create(struct wlan_objmgr_psoc * psoc,const char * iface_name,struct nlattr ** tb)309 static int __os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
310 const char *iface_name,
311 struct nlattr **tb)
312 {
313 int ret;
314 QDF_STATUS status;
315 uint16_t transaction_id;
316 struct wlan_objmgr_vdev *nan_vdev;
317 struct nan_callbacks cb_obj;
318
319 osif_debug("enter");
320
321 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
322 if (nan_vdev) {
323 osif_err("NAN data interface %s is already present",
324 iface_name);
325 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
326 return -EEXIST;
327 }
328
329 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
330 osif_err("transaction id is unavailable");
331 return -EINVAL;
332 }
333 transaction_id =
334 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
335
336 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
337 if (QDF_IS_STATUS_ERROR(status)) {
338 osif_err("Couldn't get callback object");
339 return -EINVAL;
340 }
341
342 if (cb_obj.ndi_set_mode(iface_name)) {
343 osif_err("NDI set mode fails");
344 return -EINVAL;
345 }
346
347 ret = os_if_nan_ndi_open(psoc, iface_name);
348 if (ret)
349 return ret;
350
351 return cb_obj.ndi_start(iface_name, transaction_id);
352 }
353
354 static int
osif_nla_str(struct nlattr ** tb,size_t attr_id,const char ** out_str)355 osif_nla_str(struct nlattr **tb, size_t attr_id, const char **out_str)
356 {
357 if (!tb || !tb[attr_id])
358 return -EINVAL;
359
360 *out_str = nla_data(tb[attr_id]);
361
362 return 0;
363 }
364
osif_net_dev_from_vdev(struct wlan_objmgr_vdev * vdev,struct net_device ** out_net_dev)365 static int osif_net_dev_from_vdev(struct wlan_objmgr_vdev *vdev,
366 struct net_device **out_net_dev)
367 {
368 struct vdev_osif_priv *priv;
369
370 if (!vdev)
371 return -EINVAL;
372
373 priv = wlan_vdev_get_ospriv(vdev);
374 if (!priv || !priv->wdev || !priv->wdev->netdev)
375 return -EINVAL;
376
377 *out_net_dev = priv->wdev->netdev;
378
379 return 0;
380 }
381
osif_net_dev_from_ifname(struct wlan_objmgr_psoc * psoc,const char * iface_name,struct net_device ** out_net_dev)382 static int osif_net_dev_from_ifname(struct wlan_objmgr_psoc *psoc,
383 const char *iface_name,
384 struct net_device **out_net_dev)
385 {
386 struct wlan_objmgr_vdev *vdev;
387 struct net_device *net_dev;
388 int errno;
389
390 vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
391 if (!vdev)
392 return -EINVAL;
393
394 errno = osif_net_dev_from_vdev(vdev, &net_dev);
395
396 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
397
398 if (errno)
399 return errno;
400
401 *out_net_dev = net_dev;
402
403 return 0;
404 }
405
406 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
os_if_nan_process_ndi_create(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb,struct wireless_dev * wdev)407 static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
408 struct nlattr **tb,
409 struct wireless_dev *wdev)
410 {
411 struct osif_vdev_sync *vdev_sync;
412 const char *ifname;
413 int errno;
414
415 osif_debug("enter");
416
417 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
418 if (errno)
419 goto err;
420
421 errno = osif_vdev_sync_trans_start(wdev->netdev, &vdev_sync);
422 if (errno)
423 goto err;
424
425 errno = __os_if_nan_process_ndi_create(psoc, ifname, tb);
426 if (errno) {
427 osif_vdev_sync_trans_stop(vdev_sync);
428 goto err;
429 }
430
431 osif_vdev_sync_trans_stop(vdev_sync);
432
433 return 0;
434 err:
435 return errno;
436 }
437 #else
438
439 static int
osif_device_from_psoc(struct wlan_objmgr_psoc * psoc,struct device ** out_dev)440 osif_device_from_psoc(struct wlan_objmgr_psoc *psoc, struct device **out_dev)
441 {
442 qdf_device_t qdf_dev;
443
444 if (!psoc)
445 return -EINVAL;
446
447 qdf_dev = wlan_psoc_get_qdf_dev(psoc);
448 if (!qdf_dev || !qdf_dev->dev)
449 return -EINVAL;
450
451 *out_dev = qdf_dev->dev;
452
453 return 0;
454 }
455
os_if_nan_process_ndi_create(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb,struct wireless_dev * wdev)456 static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
457 struct nlattr **tb,
458 struct wireless_dev *wdev)
459 {
460 struct device *dev;
461 struct net_device *net_dev;
462 struct osif_vdev_sync *vdev_sync;
463 const char *ifname;
464 int errno;
465
466 osif_debug("enter");
467
468 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
469 if (errno)
470 return errno;
471
472 errno = osif_device_from_psoc(psoc, &dev);
473 if (errno)
474 return errno;
475
476 errno = osif_vdev_sync_create_and_trans(dev, &vdev_sync);
477 if (errno)
478 return errno;
479
480 errno = __os_if_nan_process_ndi_create(psoc, ifname, tb);
481 if (errno)
482 goto destroy_sync;
483
484 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
485 if (errno)
486 goto destroy_sync;
487
488 osif_vdev_sync_register(net_dev, vdev_sync);
489 osif_vdev_sync_trans_stop(vdev_sync);
490
491 return 0;
492
493 destroy_sync:
494 osif_vdev_sync_trans_stop(vdev_sync);
495 osif_vdev_sync_destroy(vdev_sync);
496
497 return errno;
498 }
499 #endif
500
__os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc * psoc,const char * iface_name,struct nlattr ** tb)501 static int __os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
502 const char *iface_name,
503 struct nlattr **tb)
504 {
505 uint8_t vdev_id;
506 QDF_STATUS status;
507 uint32_t num_peers;
508 uint16_t transaction_id;
509 struct nan_callbacks cb_obj;
510 struct wlan_objmgr_vdev *nan_vdev = NULL;
511
512 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
513 osif_err("Transaction id is unavailable");
514 return -EINVAL;
515 }
516
517 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
518 if (!nan_vdev) {
519 osif_debug("Nan datapath interface is not present");
520 return -EINVAL;
521 }
522
523 transaction_id =
524 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
525 vdev_id = wlan_vdev_get_id(nan_vdev);
526 num_peers = ucfg_nan_get_active_peers(nan_vdev);
527 /*
528 * os_if_get_ndi_vdev_by_ifname increments ref count
529 * decrement here since vdev returned by that api is not used any more
530 */
531 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
532
533 /* check if there are active peers on the adapter */
534 if (num_peers)
535 osif_err("NDP peers active: %d, active NDPs may not be terminated",
536 num_peers);
537
538 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
539 if (QDF_IS_STATUS_ERROR(status)) {
540 osif_err("Couldn't get ballback object");
541 return -EINVAL;
542 }
543
544 return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id);
545 }
546
547 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)548 static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
549 struct nlattr **tb)
550 {
551 struct net_device *net_dev;
552 struct osif_vdev_sync *vdev_sync;
553 const char *ifname;
554 int errno;
555
556 osif_debug("enter");
557
558 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
559 if (errno)
560 return errno;
561
562 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
563 if (errno)
564 return errno;
565
566 errno = osif_vdev_sync_trans_start_wait(net_dev, &vdev_sync);
567 if (errno)
568 return errno;
569
570 errno = __os_if_nan_process_ndi_delete(psoc, ifname, tb);
571 if (errno)
572 goto reregister;
573
574 osif_vdev_sync_trans_stop(vdev_sync);
575
576 return 0;
577
578 reregister:
579 osif_vdev_sync_trans_stop(vdev_sync);
580
581 return errno;
582 }
583 #else
os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)584 static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
585 struct nlattr **tb)
586 {
587 struct net_device *net_dev;
588 struct osif_vdev_sync *vdev_sync;
589 const char *ifname;
590 int errno;
591
592 osif_debug("enter");
593
594 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
595 if (errno)
596 return errno;
597
598 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
599 if (errno)
600 return errno;
601
602 errno = osif_vdev_sync_trans_start_wait(net_dev, &vdev_sync);
603 if (errno)
604 return errno;
605
606 osif_vdev_sync_unregister(net_dev);
607 osif_vdev_sync_wait_for_ops(vdev_sync);
608
609 errno = __os_if_nan_process_ndi_delete(psoc, ifname, tb);
610 if (errno)
611 goto reregister;
612
613 osif_vdev_sync_trans_stop(vdev_sync);
614 osif_vdev_sync_destroy(vdev_sync);
615
616 return 0;
617
618 reregister:
619 osif_vdev_sync_register(net_dev, vdev_sync);
620 osif_vdev_sync_trans_stop(vdev_sync);
621
622 return errno;
623 }
624 #endif
625
626 /**
627 * os_if_nan_parse_security_params() - parse vendor attributes for security
628 * params.
629 * @tb: parsed NL attribute list
630 * @ncs_sk_type: out parameter to populate ncs_sk_type
631 * @pmk: out parameter to populate pmk
632 * @passphrase: out parameter to populate passphrase
633 * @service_name: out parameter to populate service_name
634 * @ndp_add_param: parameters to populate csid and gtk
635 *
636 * Return: 0 on success or error code on failure
637 */
os_if_nan_parse_security_params(struct nlattr ** tb,uint32_t * ncs_sk_type,struct nan_datapath_pmk * pmk,struct ndp_passphrase * passphrase,struct ndp_service_name * service_name,struct ndp_additional_params * ndp_add_param)638 static int os_if_nan_parse_security_params(struct nlattr **tb,
639 uint32_t *ncs_sk_type, struct nan_datapath_pmk *pmk,
640 struct ndp_passphrase *passphrase,
641 struct ndp_service_name *service_name,
642 struct ndp_additional_params *ndp_add_param)
643 {
644 struct nlattr *attr;
645
646 if (!ncs_sk_type || !pmk || !passphrase || !service_name) {
647 osif_err("out buffers for one or more parameters is null");
648 return -EINVAL;
649 }
650
651 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]) {
652 *ncs_sk_type =
653 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CSID]);
654 }
655
656 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]) {
657 pmk->pmk_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]);
658 qdf_mem_copy(pmk->pmk,
659 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PMK]),
660 pmk->pmk_len);
661 osif_err("pmk len: %d", pmk->pmk_len);
662 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
663 pmk->pmk, pmk->pmk_len);
664 }
665
666 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]) {
667 passphrase->passphrase_len =
668 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]);
669 qdf_mem_copy(passphrase->passphrase,
670 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE]),
671 passphrase->passphrase_len);
672 osif_err("passphrase len: %d", passphrase->passphrase_len);
673 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
674 passphrase->passphrase,
675 passphrase->passphrase_len);
676 }
677
678 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]) {
679 service_name->service_name_len =
680 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]);
681 qdf_mem_copy(service_name->service_name,
682 nla_data(
683 tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME]),
684 service_name->service_name_len);
685 osif_err("service_name len: %d",
686 service_name->service_name_len);
687 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_ERROR,
688 service_name->service_name,
689 service_name->service_name_len);
690 }
691
692 attr = tb[QCA_WLAN_VENDOR_ATTR_NDP_CSIA_CAPABILITIES];
693 if (attr)
694 ndp_add_param->csid_cap = nla_get_u8(attr);
695
696 ndp_add_param->gtk =
697 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_NDP_GTK_REQUIRED]);
698
699 return 0;
700 }
701
702 /**
703 * __os_if_nan_process_ndp_initiator_req() - NDP initiator request handler
704 * @psoc: psoc object
705 * @iface_name: interface name
706 * @tb: parsed NL attribute list
707 *
708 * tb will contain following vendor attributes:
709 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
710 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
711 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL - optional
712 * QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG
713 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID
714 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR
715 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
716 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
717 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
718 * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional
719 * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
720 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
721 *
722 * Return: 0 on success or error code on failure
723 */
__os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc * psoc,const char * iface_name,struct nlattr ** tb)724 static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
725 const char *iface_name,
726 struct nlattr **tb)
727 {
728 int ret = 0;
729 QDF_STATUS status;
730 enum nan_datapath_state state;
731 struct wlan_objmgr_vdev *nan_vdev;
732 struct nan_datapath_initiator_req req = {0};
733
734 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
735 if (!nan_vdev) {
736 osif_err("NAN data interface %s not available", iface_name);
737 return -EINVAL;
738 }
739
740 if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
741 osif_err("Interface found is not NDI");
742 ret = -EINVAL;
743 goto initiator_req_failed;
744 }
745
746 state = ucfg_nan_get_ndi_state(nan_vdev);
747 if (state == NAN_DATA_NDI_DELETED_STATE ||
748 state == NAN_DATA_NDI_DELETING_STATE ||
749 state == NAN_DATA_NDI_CREATING_STATE) {
750 osif_err("Data request not allowed in NDI current state: %d",
751 state);
752 ret = -EINVAL;
753 goto initiator_req_failed;
754 }
755
756 if (!ucfg_nan_is_sta_ndp_concurrency_allowed(psoc, nan_vdev)) {
757 osif_err("NDP creation not allowed");
758 ret = -EOPNOTSUPP;
759 goto initiator_req_failed;
760 }
761
762 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
763 osif_err("Transaction ID is unavailable");
764 ret = -EINVAL;
765 goto initiator_req_failed;
766 }
767 req.transaction_id =
768 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
769
770 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]) {
771 req.channel = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]);
772
773 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]) {
774 req.channel_cfg = nla_get_u32(
775 tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_CONFIG]);
776 } else {
777 osif_err("Channel config is unavailable");
778 ret = -EINVAL;
779 goto initiator_req_failed;
780 }
781 }
782
783 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) {
784 osif_err("NDP service instance ID is unavailable");
785 ret = -EINVAL;
786 goto initiator_req_failed;
787 }
788 req.service_instance_id =
789 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]);
790
791 qdf_mem_copy(req.self_ndi_mac_addr.bytes,
792 wlan_vdev_mlme_get_macaddr(nan_vdev), QDF_MAC_ADDR_SIZE);
793
794 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) {
795 osif_err("NDI peer discovery mac addr is unavailable");
796 ret = -EINVAL;
797 goto initiator_req_failed;
798 }
799 qdf_mem_copy(req.peer_discovery_mac_addr.bytes,
800 nla_data(
801 tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]),
802 QDF_MAC_ADDR_SIZE);
803
804 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
805 req.ndp_info.ndp_app_info_len =
806 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
807 qdf_mem_copy(req.ndp_info.ndp_app_info,
808 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]),
809 req.ndp_info.ndp_app_info_len);
810 }
811
812 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
813 /* at present ndp config stores 4 bytes QOS info only */
814 req.ndp_config.ndp_cfg_len = 4;
815 *((uint32_t *)req.ndp_config.ndp_cfg) =
816 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
817 }
818
819 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) {
820 req.is_ipv6_addr_present = true;
821 qdf_mem_copy(req.ipv6_addr,
822 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]),
823 QDF_IPV6_ADDR_SIZE);
824 }
825
826 if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
827 &req.passphrase,
828 &req.service_name,
829 &req.ndp_add_params)) {
830 osif_err("inconsistent security params in request.");
831 ret = -EINVAL;
832 goto initiator_req_failed;
833 }
834
835 req.vdev = nan_vdev;
836
837 os_if_cstats_log_ndp_initiator_req_evt(&req);
838
839 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_INITIATOR_REQ);
840 ret = qdf_status_to_os_return(status);
841 initiator_req_failed:
842 if (ret)
843 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
844
845 return ret;
846 }
847
os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)848 static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
849 struct nlattr **tb)
850 {
851 struct net_device *net_dev;
852 struct osif_vdev_sync *vdev_sync;
853 const char *ifname;
854 int errno;
855
856 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
857 if (errno)
858 return errno;
859
860 errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
861 if (errno)
862 return errno;
863
864 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
865 if (errno)
866 return errno;
867
868 errno = __os_if_nan_process_ndp_initiator_req(psoc, ifname, tb);
869
870 osif_vdev_sync_op_stop(vdev_sync);
871
872 return errno;
873 }
874
875 /**
876 * __os_if_nan_process_ndp_responder_req() - NDP responder request handler
877 * @psoc: psoc object
878 * @tb: parsed NL attribute list
879 *
880 * tb includes following vendor attributes:
881 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR
882 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
883 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID
884 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE
885 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO - optional
886 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS - optional
887 * QCA_WLAN_VENDOR_ATTR_NDP_PMK - optional
888 * QCA_WLAN_VENDOR_ATTR_NDP_CSID - optional
889 * QCA_WLAN_VENDOR_ATTR_NDP_PASSPHRASE - optional
890 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_NAME - optional
891 *
892 * Return: 0 on success or error code on failure
893 */
__os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)894 static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
895 struct nlattr **tb)
896 {
897 int ret = 0;
898 QDF_STATUS status;
899 enum nan_datapath_state state;
900 struct wlan_objmgr_vdev *nan_vdev = NULL;
901 struct nan_datapath_responder_req req = {0};
902 const char *iface_name;
903 int errno;
904
905 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
906 osif_err("ndp_rsp is unavailable");
907 return -EINVAL;
908 }
909 req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
910
911 if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) {
912 errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
913 &iface_name);
914
915 if (errno) {
916 osif_err("NAN data iface not provided");
917 return errno;
918 }
919 /* Check for an existing NAN interface */
920 nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
921 if (!nan_vdev) {
922 osif_err("NAN data iface %s not available",
923 iface_name);
924 return -ENODEV;
925 }
926
927 if (nan_vdev->vdev_mlme.vdev_opmode != QDF_NDI_MODE) {
928 osif_err("Interface found is not NDI");
929 ret = -ENODEV;
930 goto responder_req_failed;
931 }
932
933 if (!ucfg_nan_is_sta_ndp_concurrency_allowed(psoc, nan_vdev)) {
934 osif_err("NDP creation not allowed");
935 ret = -EOPNOTSUPP;
936 goto responder_req_failed;
937 }
938 } else {
939 /*
940 * If the data indication is rejected, the userspace
941 * may not send the iface name. Use the first NDI
942 * in that case
943 */
944 osif_debug("ndp rsp rejected, using first NDI");
945
946 nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(
947 psoc, QDF_NDI_MODE, WLAN_NAN_ID);
948 if (!nan_vdev) {
949 osif_err("NAN data iface is not available");
950 return -ENODEV;
951 }
952 }
953
954 state = ucfg_nan_get_ndi_state(nan_vdev);
955 if (state == NAN_DATA_NDI_DELETED_STATE ||
956 state == NAN_DATA_NDI_DELETING_STATE ||
957 state == NAN_DATA_NDI_CREATING_STATE) {
958 osif_err("Data request not allowed in current NDI state:%d",
959 state);
960 ret = -EAGAIN;
961 goto responder_req_failed;
962 }
963
964 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
965 osif_err("Transaction ID is unavailable");
966 ret = -EINVAL;
967 goto responder_req_failed;
968 }
969 req.transaction_id =
970 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
971
972 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]) {
973 osif_err("Instance ID is unavailable");
974 ret = -EINVAL;
975 goto responder_req_failed;
976 }
977 req.ndp_instance_id =
978 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]);
979
980 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) {
981 req.ndp_info.ndp_app_info_len =
982 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]);
983 qdf_mem_copy(req.ndp_info.ndp_app_info,
984 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]),
985 req.ndp_info.ndp_app_info_len);
986 } else {
987 osif_debug("NDP app info is unavailable");
988 }
989
990 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) {
991 /* at present ndp config stores 4 bytes QOS info only */
992 req.ndp_config.ndp_cfg_len = 4;
993 *((uint32_t *)req.ndp_config.ndp_cfg) =
994 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]);
995 } else {
996 osif_debug("NDP config data is unavailable");
997 }
998
999 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]) {
1000 req.is_ipv6_addr_present = true;
1001 qdf_mem_copy(req.ipv6_addr,
1002 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR]),
1003 QDF_IPV6_ADDR_SIZE);
1004 }
1005 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]) {
1006 req.is_port_present = true;
1007 req.port = nla_get_u16(
1008 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT]);
1009 }
1010 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]) {
1011 req.is_protocol_present = true;
1012 req.protocol = nla_get_u8(
1013 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL]);
1014 }
1015 osif_debug("ipv6 addr present: %d, addr: %pI6",
1016 req.is_ipv6_addr_present, req.ipv6_addr);
1017 osif_debug("port %d, present: %d protocol %d, present: %d",
1018 req.port, req.is_port_present, req.protocol,
1019 req.is_protocol_present);
1020
1021 if (os_if_nan_parse_security_params(tb, &req.ncs_sk_type, &req.pmk,
1022 &req.passphrase, &req.service_name,
1023 &req.ndp_add_params)) {
1024 osif_err("inconsistent security params in request.");
1025 ret = -EINVAL;
1026 goto responder_req_failed;
1027 }
1028
1029 os_if_cstats_log_ndp_responder_req_evt(nan_vdev, &req);
1030
1031 osif_debug("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d, csid: %d",
1032 wlan_vdev_get_id(nan_vdev), req.transaction_id, req.ndp_rsp,
1033 req.ndp_instance_id, req.ndp_info.ndp_app_info_len,
1034 req.ncs_sk_type);
1035
1036 req.vdev = nan_vdev;
1037 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_RESPONDER_REQ);
1038 ret = qdf_status_to_os_return(status);
1039
1040 responder_req_failed:
1041 if (ret)
1042 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
1043
1044 return ret;
1045
1046 }
1047
os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb,struct wireless_dev * wdev)1048 static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
1049 struct nlattr **tb,
1050 struct wireless_dev *wdev)
1051 {
1052 struct osif_vdev_sync *vdev_sync;
1053 int errno;
1054
1055 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
1056 if (errno)
1057 return errno;
1058
1059 errno = __os_if_nan_process_ndp_responder_req(psoc, tb);
1060
1061 osif_vdev_sync_op_stop(vdev_sync);
1062
1063 return errno;
1064 }
1065
1066 /**
1067 * __os_if_nan_process_ndp_end_req() - NDP end request handler
1068 * @psoc: pointer to psoc object
1069 *
1070 * @tb: parsed NL attribute list
1071 * tb includes following vendor attributes:
1072 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID
1073 *
1074 * Return: 0 on success or error code on failure
1075 */
__os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)1076 static int __os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
1077 struct nlattr **tb)
1078 {
1079 int ret = 0;
1080 QDF_STATUS status;
1081 struct wlan_objmgr_vdev *nan_vdev;
1082 struct nan_datapath_end_req req = {0};
1083
1084 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
1085 osif_err("Transaction ID is unavailable");
1086 return -EINVAL;
1087 }
1088 req.transaction_id =
1089 nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1090
1091 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) {
1092 osif_err("NDP instance ID array is unavailable");
1093 return -EINVAL;
1094 }
1095
1096 req.num_ndp_instances =
1097 nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
1098 sizeof(uint32_t);
1099 if (0 >= req.num_ndp_instances) {
1100 osif_err("Num NDP instances is 0");
1101 return -EINVAL;
1102 }
1103 qdf_mem_copy(req.ndp_ids,
1104 nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]),
1105 req.num_ndp_instances * sizeof(uint32_t));
1106
1107 osif_debug("sending ndp_end_req to SME, transaction_id: %d",
1108 req.transaction_id);
1109
1110 nan_vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE,
1111 WLAN_NAN_ID);
1112 if (!nan_vdev) {
1113 osif_err("NAN data interface is not available");
1114 return -EINVAL;
1115 }
1116
1117 req.vdev = nan_vdev;
1118
1119 os_if_cstats_log_ndp_end_req_evt(nan_vdev, &req);
1120
1121 status = ucfg_nan_req_processor(nan_vdev, &req, NDP_END_REQ);
1122 ret = qdf_status_to_os_return(status);
1123 if (ret)
1124 wlan_objmgr_vdev_release_ref(nan_vdev, WLAN_NAN_ID);
1125
1126 return ret;
1127 }
1128
os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)1129 static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
1130 struct nlattr **tb)
1131 {
1132 struct wlan_objmgr_vdev *vdev;
1133 struct net_device *net_dev;
1134 struct osif_vdev_sync *vdev_sync;
1135 int errno;
1136
1137 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE,
1138 WLAN_NAN_ID);
1139 if (!vdev)
1140 return -EINVAL;
1141
1142 errno = osif_net_dev_from_vdev(vdev, &net_dev);
1143
1144 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
1145
1146 if (errno)
1147 return errno;
1148
1149 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
1150 if (errno)
1151 return errno;
1152
1153 errno = __os_if_nan_process_ndp_end_req(psoc, tb);
1154
1155 osif_vdev_sync_op_stop(vdev_sync);
1156
1157 return errno;
1158 }
1159
os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc * psoc,const void * data,int data_len,bool is_ndp_allowed,struct wireless_dev * wdev)1160 int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
1161 const void *data, int data_len,
1162 bool is_ndp_allowed,
1163 struct wireless_dev *wdev)
1164 {
1165 uint32_t ndp_cmd_type;
1166 uint16_t transaction_id;
1167 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1];
1168 char *iface_name;
1169
1170 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX,
1171 data, data_len, vendor_attr_policy)) {
1172 osif_err("Invalid NDP vendor command attributes");
1173 return -EINVAL;
1174 }
1175
1176 /* Parse and fetch NDP Command Type*/
1177 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]) {
1178 osif_err("NAN datapath cmd type failed");
1179 return -EINVAL;
1180 }
1181 ndp_cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD]);
1182
1183 if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
1184 osif_err("attr transaction id failed");
1185 return -EINVAL;
1186 }
1187 transaction_id = nla_get_u16(
1188 tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
1189
1190 if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
1191 iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
1192 osif_debug("Transaction Id: %u NDPCmd: %u iface_name: %s",
1193 transaction_id, ndp_cmd_type, iface_name);
1194 } else {
1195 osif_debug("Transaction Id: %u NDPCmd: %u iface_name: unspecified",
1196 transaction_id, ndp_cmd_type);
1197 }
1198
1199 switch (ndp_cmd_type) {
1200 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
1201 /**
1202 * NDI creation is not allowed if NAN discovery is not running.
1203 * Allowing NDI creation when NAN discovery is not enabled may
1204 * lead to issues if NDI has to be started in a
1205 * 2GHz channel and if the target is not operating in DBS mode.
1206 */
1207 if ((ucfg_is_nan_conc_control_supported(psoc)) &&
1208 (!ucfg_is_nan_disc_active(psoc))) {
1209 osif_err("NDI creation is not allowed when NAN discovery is not running");
1210 return -EOPNOTSUPP;
1211 }
1212 return os_if_nan_process_ndi_create(psoc, tb, wdev);
1213 case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE:
1214 return os_if_nan_process_ndi_delete(psoc, tb);
1215 case QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_REQUEST:
1216 if (!is_ndp_allowed) {
1217 osif_err("Unsupported concurrency for NAN datapath");
1218 return -EOPNOTSUPP;
1219 }
1220 return os_if_nan_process_ndp_initiator_req(psoc, tb);
1221 case QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_REQUEST:
1222 if (!is_ndp_allowed) {
1223 osif_err("Unsupported concurrency for NAN datapath");
1224 return -EOPNOTSUPP;
1225 }
1226 return os_if_nan_process_ndp_responder_req(psoc, tb, wdev);
1227 case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
1228 if (!is_ndp_allowed) {
1229 osif_err("Unsupported concurrency for NAN datapath");
1230 return -EOPNOTSUPP;
1231 }
1232 return os_if_nan_process_ndp_end_req(psoc, tb);
1233 default:
1234 osif_err("Unrecognized NDP vendor cmd %d", ndp_cmd_type);
1235 return -EINVAL;
1236 }
1237
1238 return -EINVAL;
1239 }
1240
osif_ndp_get_ndp_initiator_rsp_len(void)1241 static inline uint32_t osif_ndp_get_ndp_initiator_rsp_len(void)
1242 {
1243 uint32_t data_len = NLMSG_HDRLEN;
1244
1245 data_len += nla_total_size(vendor_attr_policy[
1246 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1247 data_len += nla_total_size(vendor_attr_policy[
1248 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
1249 data_len += nla_total_size(vendor_attr_policy[
1250 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
1251 data_len += nla_total_size(vendor_attr_policy[
1252 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
1253 data_len += nla_total_size(vendor_attr_policy[
1254 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
1255
1256 return data_len;
1257 }
1258
1259 /**
1260 * os_if_ndp_initiator_rsp_handler() - NDP initiator response handler
1261 * @vdev: pointer to vdev object
1262 * @rsp: response parameters
1263 *
1264 * Following vendor event is sent to cfg80211:
1265 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1266 * QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE (4 bytes)
1267 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1268 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1269 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1270 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1271 *
1272 * Return: none
1273 */
os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_initiator_rsp * rsp)1274 static void os_if_ndp_initiator_rsp_handler(struct wlan_objmgr_vdev *vdev,
1275 struct nan_datapath_initiator_rsp *rsp)
1276 {
1277 uint32_t data_len;
1278 struct sk_buff *vendor_event;
1279 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1280 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1281 enum qca_nl80211_vendor_subcmds_index index =
1282 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1283
1284 if (!rsp) {
1285 osif_err("Invalid NDP Initiator response");
1286 return;
1287 }
1288
1289 data_len = osif_ndp_get_ndp_initiator_rsp_len();
1290 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
1291 data_len, index,
1292 GFP_ATOMIC);
1293 if (!vendor_event) {
1294 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1295 return;
1296 }
1297
1298 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1299 QCA_WLAN_VENDOR_ATTR_NDP_INITIATOR_RESPONSE))
1300 goto ndp_initiator_rsp_nla_failed;
1301
1302 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1303 rsp->transaction_id))
1304 goto ndp_initiator_rsp_nla_failed;
1305
1306 if (nla_put_u32(vendor_event,
1307 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1308 rsp->ndp_instance_id))
1309 goto ndp_initiator_rsp_nla_failed;
1310
1311 if (nla_put_u32(vendor_event,
1312 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
1313 rsp->status))
1314 goto ndp_initiator_rsp_nla_failed;
1315
1316 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1317 rsp->reason))
1318 goto ndp_initiator_rsp_nla_failed;
1319
1320 os_if_cstats_log_ndp_initiator_resp_evt(vdev, rsp);
1321
1322 osif_debug("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d, reason: %d",
1323 rsp->transaction_id, rsp->ndp_instance_id, rsp->status,
1324 rsp->reason);
1325 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1326 return;
1327 ndp_initiator_rsp_nla_failed:
1328 osif_err("nla_put api failed");
1329 wlan_cfg80211_vendor_free_skb(vendor_event);
1330 }
1331
osif_ndp_get_ndp_responder_rsp_len(void)1332 static inline uint32_t osif_ndp_get_ndp_responder_rsp_len(void)
1333 {
1334 uint32_t data_len = NLMSG_HDRLEN;
1335
1336 data_len += nla_total_size(vendor_attr_policy[
1337 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1338 data_len += nla_total_size(vendor_attr_policy[
1339 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
1340 data_len += nla_total_size(vendor_attr_policy[
1341 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
1342 data_len += nla_total_size(vendor_attr_policy[
1343 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
1344
1345 return data_len;
1346 }
1347
1348 /*
1349 * os_if_ndp_responder_rsp_handler() - NDP responder response handler
1350 * @vdev: pointer to vdev object
1351 * @rsp: response parameters
1352 *
1353 * Following vendor event is sent to cfg80211:
1354 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1355 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes)
1356 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1357 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1358 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1359 *
1360 * Return: none
1361 */
os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_responder_rsp * rsp)1362 static void os_if_ndp_responder_rsp_handler(struct wlan_objmgr_vdev *vdev,
1363 struct nan_datapath_responder_rsp *rsp)
1364 {
1365 uint16_t data_len;
1366 struct sk_buff *vendor_event;
1367 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1368 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1369 enum qca_nl80211_vendor_subcmds_index index =
1370 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1371
1372 if (!rsp) {
1373 osif_err("Invalid NDP Responder response");
1374 return;
1375 }
1376
1377 data_len = osif_ndp_get_ndp_responder_rsp_len();
1378 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
1379 data_len, index,
1380 GFP_ATOMIC);
1381 if (!vendor_event) {
1382 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1383 return;
1384 }
1385
1386 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1387 QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE))
1388 goto ndp_responder_rsp_nla_failed;
1389
1390 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1391 rsp->transaction_id))
1392 goto ndp_responder_rsp_nla_failed;
1393
1394 if (nla_put_u32(vendor_event,
1395 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
1396 rsp->status))
1397 goto ndp_responder_rsp_nla_failed;
1398
1399 if (nla_put_u32(vendor_event,
1400 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1401 rsp->reason))
1402 goto ndp_responder_rsp_nla_failed;
1403
1404 os_if_cstats_log_ndp_responder_resp_evt(vdev, rsp);
1405
1406 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1407 return;
1408 ndp_responder_rsp_nla_failed:
1409 osif_err("nla_put api failed");
1410 wlan_cfg80211_vendor_free_skb(vendor_event);
1411 }
1412
osif_ndp_get_ndp_req_ind_len(struct nan_datapath_indication_event * event)1413 static inline uint32_t osif_ndp_get_ndp_req_ind_len(
1414 struct nan_datapath_indication_event *event)
1415 {
1416 uint32_t data_len = NLMSG_HDRLEN;
1417
1418 data_len += nla_total_size(vendor_attr_policy[
1419 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1420 data_len += nla_total_size(vendor_attr_policy[
1421 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID].len);
1422 data_len += nla_total_size(vendor_attr_policy[
1423 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
1424 data_len += nla_total_size(vendor_attr_policy[
1425 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS].len);
1426 data_len += nla_total_size(vendor_attr_policy[
1427 QCA_WLAN_VENDOR_ATTR_NDP_CSID].len);
1428 /* allocate space including NULL terminator */
1429 data_len += nla_total_size(vendor_attr_policy[
1430 QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1);
1431 data_len += nla_total_size(vendor_attr_policy[
1432 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len);
1433 data_len += nla_total_size(vendor_attr_policy[
1434 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len);
1435 if (event->is_ipv6_addr_present)
1436 data_len += nla_total_size(vendor_attr_policy[
1437 QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len);
1438 if (event->scid.scid_len)
1439 data_len += nla_total_size(event->scid.scid_len);
1440 if (event->ndp_info.ndp_app_info_len)
1441 data_len += nla_total_size(event->ndp_info.ndp_app_info_len);
1442 if (event->is_service_id_present)
1443 data_len += nla_total_size(vendor_attr_policy[
1444 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID].len);
1445
1446 if (event->ndp_add_params.csid_cap)
1447 data_len += nla_total_size(vendor_attr_policy[
1448 QCA_WLAN_VENDOR_ATTR_NDP_CSIA_CAPABILITIES].len);
1449 if (event->ndp_add_params.gtk)
1450 data_len += nla_total_size(vendor_attr_policy[
1451 QCA_WLAN_VENDOR_ATTR_NDP_GTK_REQUIRED].len);
1452
1453 return data_len;
1454 }
1455
1456 /**
1457 * os_if_ndp_indication_handler() - NDP indication handler
1458 * @vdev: pointer to vdev object
1459 * @event: indication parameters
1460 *
1461 * Following vendor event is sent to cfg80211:
1462 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1463 * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes)
1464 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1465 * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (4 bytes)
1466 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1467 * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes)
1468 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1469 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1470 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes)
1471 * QCA_WLAN_VENDOR_ATTR_NDP_CSID(4 bytes)
1472 * QCA_WLAN_VENDOR_ATTR_NDP_SCID(scid_len in size)
1473 * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes)
1474 *
1475 * Return: none
1476 */
os_if_ndp_indication_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_indication_event * event)1477 static void os_if_ndp_indication_handler(struct wlan_objmgr_vdev *vdev,
1478 struct nan_datapath_indication_event *event)
1479 {
1480 const uint8_t *ifname;
1481 uint16_t data_len;
1482 qdf_size_t ifname_len;
1483 uint32_t ndp_qos_config;
1484 struct sk_buff *vendor_event;
1485 enum nan_datapath_state state;
1486 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1487 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1488 enum qca_nl80211_vendor_subcmds_index index =
1489 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1490
1491 if (!event) {
1492 osif_err("Invalid NDP Indication");
1493 return;
1494 }
1495
1496 osif_debug("NDP Indication, policy: %d", event->policy);
1497 state = ucfg_nan_get_ndi_state(vdev);
1498 /* check if we are in middle of deleting/creating the interface */
1499
1500 if (state == NAN_DATA_NDI_DELETED_STATE ||
1501 state == NAN_DATA_NDI_DELETING_STATE ||
1502 state == NAN_DATA_NDI_CREATING_STATE) {
1503 osif_err("Data request not allowed in current NDI state: %d",
1504 state);
1505 return;
1506 }
1507
1508 ifname = os_if_ndi_get_if_name(vdev);
1509 if (!ifname) {
1510 osif_err("ifname is null");
1511 return;
1512 }
1513 ifname_len = qdf_str_len(ifname);
1514 if (ifname_len > IFNAMSIZ) {
1515 osif_err("ifname(%zu) too long", ifname_len);
1516 return;
1517 }
1518
1519 data_len = osif_ndp_get_ndp_req_ind_len(event);
1520 /* notify response to the upper layer */
1521 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy,
1522 NULL, data_len,
1523 index, GFP_ATOMIC);
1524 if (!vendor_event) {
1525 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1526 return;
1527 }
1528
1529 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1530 QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND))
1531 goto ndp_indication_nla_failed;
1532
1533 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1534 ifname_len, ifname))
1535 goto ndp_indication_nla_failed;
1536
1537 if (nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID,
1539 event->service_instance_id))
1540 goto ndp_indication_nla_failed;
1541
1542 if (nla_put(vendor_event,
1543 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1544 QDF_MAC_ADDR_SIZE, event->peer_mac_addr.bytes))
1545 goto ndp_indication_nla_failed;
1546
1547 if (nla_put(vendor_event,
1548 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
1549 QDF_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes))
1550 goto ndp_indication_nla_failed;
1551
1552 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1553 event->ndp_instance_id))
1554 goto ndp_indication_nla_failed;
1555
1556 if (event->ndp_info.ndp_app_info_len)
1557 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1558 event->ndp_info.ndp_app_info_len,
1559 event->ndp_info.ndp_app_info))
1560 goto ndp_indication_nla_failed;
1561
1562 if (event->ndp_config.ndp_cfg_len) {
1563 ndp_qos_config = *((uint32_t *)event->ndp_config.ndp_cfg);
1564 /* at present ndp config stores 4 bytes QOS info only */
1565 if (nla_put_u32(vendor_event,
1566 QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS,
1567 ndp_qos_config))
1568 goto ndp_indication_nla_failed;
1569 }
1570
1571 if (event->scid.scid_len) {
1572 if (nla_put_u32(vendor_event,
1573 QCA_WLAN_VENDOR_ATTR_NDP_CSID,
1574 event->ncs_sk_type))
1575 goto ndp_indication_nla_failed;
1576
1577 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SCID,
1578 event->scid.scid_len,
1579 event->scid.scid))
1580 goto ndp_indication_nla_failed;
1581
1582 osif_debug("csid: %d, scid_len: %d",
1583 event->ncs_sk_type, event->scid.scid_len);
1584
1585 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
1586 event->scid.scid, event->scid.scid_len);
1587 }
1588
1589 if (event->is_ipv6_addr_present) {
1590 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR,
1591 QDF_IPV6_ADDR_SIZE, event->ipv6_addr))
1592 goto ndp_indication_nla_failed;
1593 }
1594
1595 if (event->is_service_id_present) {
1596 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_ID,
1597 NDP_SERVICE_ID_LEN, event->service_id))
1598 goto ndp_indication_nla_failed;
1599 }
1600
1601 if (event->ndp_add_params.csid_cap) {
1602 if (nla_put_u8(vendor_event,
1603 QCA_WLAN_VENDOR_ATTR_NDP_CSIA_CAPABILITIES,
1604 event->ndp_add_params.csid_cap))
1605 goto ndp_indication_nla_failed;
1606 }
1607
1608 if (event->ndp_add_params.gtk) {
1609 if (nla_put_flag(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_NDP_GTK_REQUIRED))
1611 goto ndp_indication_nla_failed;
1612 }
1613
1614 os_if_cstats_log_ndp_indication_evt(vdev, event);
1615
1616 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1617 return;
1618 ndp_indication_nla_failed:
1619 osif_err("nla_put api failed");
1620 wlan_cfg80211_vendor_free_skb(vendor_event);
1621 }
1622
osif_ndp_get_ndp_confirm_ind_len(struct nan_datapath_confirm_event * ndp_confirm)1623 static inline uint32_t osif_ndp_get_ndp_confirm_ind_len(
1624 struct nan_datapath_confirm_event *ndp_confirm)
1625 {
1626 uint32_t ch_info_len = 0;
1627 uint32_t data_len = NLMSG_HDRLEN;
1628
1629 data_len += nla_total_size(vendor_attr_policy[
1630 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1631 data_len += nla_total_size(vendor_attr_policy[
1632 QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID].len);
1633 data_len += nla_total_size(vendor_attr_policy[
1634 QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR].len);
1635 /* allocate space including NULL terminator */
1636 data_len += nla_total_size(vendor_attr_policy[
1637 QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR].len + 1);
1638 data_len += nla_total_size(vendor_attr_policy[
1639 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE].len);
1640 data_len += nla_total_size(vendor_attr_policy[
1641 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
1642 if (ndp_confirm->ndp_info.ndp_app_info_len)
1643 data_len +=
1644 nla_total_size(ndp_confirm->ndp_info.ndp_app_info_len);
1645
1646 if (ndp_confirm->is_ipv6_addr_present)
1647 data_len += nla_total_size(vendor_attr_policy[
1648 QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR].len);
1649 if (ndp_confirm->is_port_present)
1650 data_len += nla_total_size(vendor_attr_policy[
1651 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT].len);
1652 if (ndp_confirm->is_protocol_present)
1653 data_len += nla_total_size(vendor_attr_policy[
1654 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL].len);
1655
1656 /* ch_info is a nested array of following attributes */
1657 ch_info_len += nla_total_size(
1658 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len);
1659 ch_info_len += nla_total_size(
1660 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len);
1661 ch_info_len += nla_total_size(
1662 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len);
1663
1664 if (ndp_confirm->num_channels)
1665 data_len += ndp_confirm->num_channels *
1666 nla_total_size(ch_info_len);
1667
1668 return data_len;
1669 }
1670
os_if_ndp_confirm_pack_ch_info(struct sk_buff * event,struct nan_datapath_confirm_event * ndp_confirm)1671 static QDF_STATUS os_if_ndp_confirm_pack_ch_info(struct sk_buff *event,
1672 struct nan_datapath_confirm_event *ndp_confirm)
1673 {
1674 int idx = 0;
1675 struct nlattr *ch_array, *ch_element;
1676
1677 if (!ndp_confirm->num_channels)
1678 return QDF_STATUS_SUCCESS;
1679
1680 ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO);
1681 if (!ch_array)
1682 return QDF_STATUS_E_FAULT;
1683
1684 for (idx = 0; idx < ndp_confirm->num_channels; idx++) {
1685 ch_element = nla_nest_start(event, idx);
1686 if (!ch_element)
1687 return QDF_STATUS_E_FAULT;
1688
1689 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
1690 ndp_confirm->ch[idx].freq))
1691 return QDF_STATUS_E_FAULT;
1692
1693 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH,
1694 ndp_confirm->ch[idx].ch_width))
1695 return QDF_STATUS_E_FAULT;
1696
1697 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS,
1698 ndp_confirm->ch[idx].nss))
1699 return QDF_STATUS_E_FAULT;
1700 nla_nest_end(event, ch_element);
1701 }
1702 nla_nest_end(event, ch_array);
1703
1704 return QDF_STATUS_SUCCESS;
1705 }
1706
1707 /**
1708 * os_if_ndp_confirm_ind_handler() - NDP confirm indication handler
1709 * @vdev: pointer to vdev object
1710 * @ndp_confirm: indication parameters
1711 *
1712 * Following vendor event is sent to cfg80211:
1713 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1714 * QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND (4 bytes)
1715 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes)
1716 * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes)
1717 * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ)
1718 * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size)
1719 * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes)
1720 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1721 * QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR (16 bytes)
1722 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT (2 bytes)
1723 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL (1 byte)
1724 *
1725 * Return: none
1726 */
1727 static void
os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_confirm_event * ndp_confirm)1728 os_if_ndp_confirm_ind_handler(struct wlan_objmgr_vdev *vdev,
1729 struct nan_datapath_confirm_event *ndp_confirm)
1730 {
1731 const uint8_t *ifname;
1732 uint32_t data_len;
1733 QDF_STATUS status;
1734 qdf_size_t ifname_len;
1735 struct sk_buff *vendor_event;
1736 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1737 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1738 enum qca_nl80211_vendor_subcmds_index index =
1739 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1740
1741 if (!ndp_confirm) {
1742 osif_err("Invalid NDP Initiator response");
1743 return;
1744 }
1745
1746 ifname = os_if_ndi_get_if_name(vdev);
1747 if (!ifname) {
1748 osif_err("ifname is null");
1749 return;
1750 }
1751 ifname_len = qdf_str_len(ifname);
1752 if (ifname_len > IFNAMSIZ) {
1753 osif_err("ifname(%zu) too long", ifname_len);
1754 return;
1755 }
1756
1757 data_len = osif_ndp_get_ndp_confirm_ind_len(ndp_confirm);
1758 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
1759 data_len, index,
1760 GFP_ATOMIC);
1761 if (!vendor_event) {
1762 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1763 return;
1764 }
1765
1766 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1767 QCA_WLAN_VENDOR_ATTR_NDP_CONFIRM_IND))
1768 goto ndp_confirm_nla_failed;
1769
1770 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID,
1771 ndp_confirm->ndp_instance_id))
1772 goto ndp_confirm_nla_failed;
1773
1774 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR,
1775 QDF_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes))
1776 goto ndp_confirm_nla_failed;
1777
1778 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
1779 ifname_len, ifname))
1780 goto ndp_confirm_nla_failed;
1781
1782 if (ndp_confirm->ndp_info.ndp_app_info_len &&
1783 nla_put(vendor_event,
1784 QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO,
1785 ndp_confirm->ndp_info.ndp_app_info_len,
1786 ndp_confirm->ndp_info.ndp_app_info))
1787 goto ndp_confirm_nla_failed;
1788
1789 if (nla_put_u32(vendor_event,
1790 QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE,
1791 ndp_confirm->rsp_code))
1792 goto ndp_confirm_nla_failed;
1793
1794 if (nla_put_u32(vendor_event,
1795 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1796 ndp_confirm->reason_code))
1797 goto ndp_confirm_nla_failed;
1798
1799 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS,
1800 ndp_confirm->num_channels))
1801 goto ndp_confirm_nla_failed;
1802
1803 status = os_if_ndp_confirm_pack_ch_info(vendor_event, ndp_confirm);
1804 if (QDF_IS_STATUS_ERROR(status))
1805 goto ndp_confirm_nla_failed;
1806
1807 if (ndp_confirm->is_ipv6_addr_present) {
1808 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IPV6_ADDR,
1809 QDF_IPV6_ADDR_SIZE, ndp_confirm->ipv6_addr))
1810 goto ndp_confirm_nla_failed;
1811 }
1812 if (ndp_confirm->is_port_present)
1813 if (nla_put_u16(vendor_event,
1814 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PORT,
1815 ndp_confirm->port))
1816 goto ndp_confirm_nla_failed;
1817 if (ndp_confirm->is_protocol_present)
1818 if (nla_put_u8(vendor_event,
1819 QCA_WLAN_VENDOR_ATTR_NDP_TRANSPORT_PROTOCOL,
1820 ndp_confirm->protocol))
1821 goto ndp_confirm_nla_failed;
1822
1823 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1824
1825 os_if_cstats_log_ndp_confirm_evt(vdev, ndp_confirm);
1826
1827 osif_debug("NDP confim sent, ndp instance id: %d, peer addr: "QDF_MAC_ADDR_FMT" rsp_code: %d, reason_code: %d",
1828 ndp_confirm->ndp_instance_id,
1829 QDF_MAC_ADDR_REF(ndp_confirm->peer_ndi_mac_addr.bytes),
1830 ndp_confirm->rsp_code, ndp_confirm->reason_code);
1831
1832 return;
1833 ndp_confirm_nla_failed:
1834 osif_err("nla_put api failed");
1835 wlan_cfg80211_vendor_free_skb(vendor_event);
1836 }
1837
osif_ndp_get_ndp_end_rsp_len(void)1838 static inline uint32_t osif_ndp_get_ndp_end_rsp_len(void)
1839 {
1840 uint32_t data_len = NLMSG_HDRLEN;
1841
1842 data_len += nla_total_size(vendor_attr_policy[
1843 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1844 data_len += nla_total_size(vendor_attr_policy[
1845 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
1846 data_len += nla_total_size(vendor_attr_policy[
1847 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
1848 data_len += nla_total_size(vendor_attr_policy[
1849 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
1850
1851 return data_len;
1852 }
1853
1854 /**
1855 * os_if_ndp_end_rsp_handler() - NDP end response handler
1856 * @vdev: pointer to vdev object
1857 * @rsp: response parameters
1858 *
1859 * Following vendor event is sent to cfg80211:
1860 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1861 * QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE(4 bytest)
1862 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
1863 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE (4 bytes)
1864 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
1865 *
1866 * Return: none
1867 */
os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_end_rsp_event * rsp)1868 static void os_if_ndp_end_rsp_handler(struct wlan_objmgr_vdev *vdev,
1869 struct nan_datapath_end_rsp_event *rsp)
1870 {
1871 uint32_t data_len;
1872 struct sk_buff *vendor_event;
1873 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1874 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1875 enum qca_nl80211_vendor_subcmds_index index =
1876 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1877
1878 if (!rsp) {
1879 osif_err("Invalid ndp end response");
1880 return;
1881 }
1882
1883 data_len = osif_ndp_get_ndp_end_rsp_len();
1884 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
1885 data_len, index,
1886 GFP_ATOMIC);
1887 if (!vendor_event) {
1888 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1889 return;
1890 }
1891
1892 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1893 QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE))
1894 goto ndp_end_rsp_nla_failed;
1895
1896 if (nla_put_u32(vendor_event,
1897 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
1898 rsp->status))
1899 goto ndp_end_rsp_nla_failed;
1900
1901 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
1902 rsp->reason))
1903 goto ndp_end_rsp_nla_failed;
1904
1905 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
1906 rsp->transaction_id))
1907 goto ndp_end_rsp_nla_failed;
1908
1909 os_if_cstats_log_ndp_end_rsp_evt(vdev, rsp);
1910
1911 osif_debug("NDP End rsp sent, transaction id: %u, status: %u, reason: %u",
1912 rsp->transaction_id, rsp->status, rsp->reason);
1913 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1914 return;
1915
1916 ndp_end_rsp_nla_failed:
1917 osif_err("nla_put api failed");
1918 wlan_cfg80211_vendor_free_skb(vendor_event);
1919 }
1920
osif_ndp_get_ndp_end_ind_len(struct nan_datapath_end_indication_event * end_ind)1921 static inline uint32_t osif_ndp_get_ndp_end_ind_len(
1922 struct nan_datapath_end_indication_event *end_ind)
1923 {
1924 uint32_t data_len = NLMSG_HDRLEN;
1925
1926 data_len += nla_total_size(vendor_attr_policy[
1927 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
1928 if (end_ind->num_ndp_ids)
1929 data_len += nla_total_size(end_ind->num_ndp_ids *
1930 sizeof(uint32_t));
1931
1932 return data_len;
1933 }
1934
1935 /**
1936 * os_if_ndp_end_ind_handler() - NDP end indication handler
1937 * @vdev: pointer to vdev object
1938 * @end_ind: indication parameters
1939 *
1940 * Following vendor event is sent to cfg80211:
1941 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
1942 * QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
1943 * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * num of NDP Instances)
1944 *
1945 * Return: none
1946 */
os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_end_indication_event * end_ind)1947 static void os_if_ndp_end_ind_handler(struct wlan_objmgr_vdev *vdev,
1948 struct nan_datapath_end_indication_event *end_ind)
1949 {
1950 uint32_t data_len, i;
1951 uint32_t *ndp_instance_array;
1952 struct sk_buff *vendor_event;
1953 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
1954 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
1955 enum qca_nl80211_vendor_subcmds_index index =
1956 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
1957
1958 if (!end_ind) {
1959 osif_err("Invalid ndp end indication");
1960 return;
1961 }
1962
1963 ndp_instance_array = qdf_mem_malloc(end_ind->num_ndp_ids *
1964 sizeof(*ndp_instance_array));
1965 if (!ndp_instance_array)
1966 return;
1967
1968 for (i = 0; i < end_ind->num_ndp_ids; i++)
1969 ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
1970
1971 data_len = osif_ndp_get_ndp_end_ind_len(end_ind);
1972 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
1973 data_len, index,
1974 GFP_ATOMIC);
1975 if (!vendor_event) {
1976 qdf_mem_free(ndp_instance_array);
1977 osif_err("wlan_cfg80211_vendor_event_alloc failed");
1978 return;
1979 }
1980
1981 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
1982 QCA_WLAN_VENDOR_ATTR_NDP_END_IND))
1983 goto ndp_end_ind_nla_failed;
1984
1985 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
1986 end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
1987 ndp_instance_array))
1988 goto ndp_end_ind_nla_failed;
1989
1990 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
1991 qdf_mem_free(ndp_instance_array);
1992 return;
1993
1994 ndp_end_ind_nla_failed:
1995 osif_err("nla_put api failed");
1996 wlan_cfg80211_vendor_free_skb(vendor_event);
1997 qdf_mem_free(ndp_instance_array);
1998 }
1999
2000 /**
2001 * os_if_new_peer_ind_handler() - NDP new peer indication handler
2002 * @vdev: vdev object
2003 * @peer_ind: indication parameters
2004 *
2005 * Return: none
2006 */
os_if_new_peer_ind_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_peer_ind * peer_ind)2007 static void os_if_new_peer_ind_handler(struct wlan_objmgr_vdev *vdev,
2008 struct nan_datapath_peer_ind *peer_ind)
2009 {
2010 int ret;
2011 QDF_STATUS status;
2012 uint8_t vdev_id = wlan_vdev_get_id(vdev);
2013 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
2014 uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
2015 struct nan_callbacks cb_obj;
2016
2017 if (!peer_ind) {
2018 osif_err("Invalid new NDP peer params");
2019 return;
2020 }
2021
2022 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
2023 if (QDF_IS_STATUS_ERROR(status)) {
2024 osif_err("failed to get callbacks");
2025 return;
2026 }
2027
2028 os_if_cstats_log_ndp_new_peer_evt(vdev, peer_ind);
2029
2030 osif_debug("vdev_id: %d, peer_mac: "QDF_MAC_ADDR_FMT,
2031 vdev_id, QDF_MAC_ADDR_REF(peer_ind->peer_mac_addr.bytes));
2032 ret = cb_obj.new_peer_ind(vdev_id, peer_ind->sta_id,
2033 &peer_ind->peer_mac_addr,
2034 (active_peers == 0 ? true : false));
2035 if (ret) {
2036 osif_err("new peer handling at HDD failed %d", ret);
2037 return;
2038 }
2039
2040 active_peers++;
2041 ucfg_nan_set_active_peers(vdev, active_peers);
2042 osif_debug("num_peers: %d", active_peers);
2043 }
2044
2045 /**
2046 * os_if_ndp_end_all_handler: Handler for NDP_END_ALL request cmd
2047 * @vdev: pointer to vdev object
2048 *
2049 * Return: None
2050 */
os_if_ndp_end_all_handler(struct wlan_objmgr_vdev * vdev)2051 static void os_if_ndp_end_all_handler(struct wlan_objmgr_vdev *vdev)
2052 {
2053 struct nan_vdev_priv_obj *vdev_nan_obj;
2054 struct osif_request *request;
2055
2056 vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
2057 if (!vdev_nan_obj) {
2058 osif_err("vdev_nan_obj is NULL");
2059 return;
2060 }
2061
2062 request = osif_request_get(vdev_nan_obj->disable_context);
2063 if (!request) {
2064 osif_debug("Obsolete request");
2065 return;
2066 }
2067
2068 osif_request_complete(request);
2069 osif_request_put(request);
2070 }
2071
2072 /**
2073 * os_if_peer_departed_ind_handler() - Handle NDP peer departed indication
2074 * @vdev: vdev object
2075 * @peer_ind: indication parameters
2076 *
2077 * Return: none
2078 */
os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev * vdev,struct nan_datapath_peer_ind * peer_ind)2079 static void os_if_peer_departed_ind_handler(struct wlan_objmgr_vdev *vdev,
2080 struct nan_datapath_peer_ind *peer_ind)
2081 {
2082 QDF_STATUS status;
2083 struct nan_callbacks cb_obj;
2084 uint8_t vdev_id = wlan_vdev_get_id(vdev);
2085 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
2086 uint32_t active_peers = ucfg_nan_get_active_peers(vdev);
2087
2088 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
2089 if (QDF_IS_STATUS_ERROR(status)) {
2090 osif_err("failed to get callbacks");
2091 return;
2092 }
2093
2094 if (!peer_ind) {
2095 osif_err("Invalid new NDP peer params");
2096 return;
2097 }
2098 osif_debug("vdev_id: %d, peer_mac: "QDF_MAC_ADDR_FMT,
2099 vdev_id, QDF_MAC_ADDR_REF(peer_ind->peer_mac_addr.bytes));
2100 active_peers--;
2101 ucfg_nan_set_active_peers(vdev, active_peers);
2102 cb_obj.peer_departed_ind(vdev_id, peer_ind->sta_id,
2103 &peer_ind->peer_mac_addr,
2104 (active_peers == 0 ? true : false));
2105
2106 /* if no peer left, stop wait timer for NDP_END_ALL` */
2107 if (!active_peers)
2108 os_if_ndp_end_all_handler(vdev);
2109 }
2110
osif_ndp_get_ndi_create_rsp_len(void)2111 static inline uint32_t osif_ndp_get_ndi_create_rsp_len(void)
2112 {
2113 uint32_t data_len = NLMSG_HDRLEN;
2114
2115 data_len += nla_total_size(vendor_attr_policy[
2116 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
2117 data_len += nla_total_size(vendor_attr_policy[
2118 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
2119 data_len += nla_total_size(vendor_attr_policy[
2120 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
2121 data_len += nla_total_size(vendor_attr_policy[
2122 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
2123
2124 return data_len;
2125 }
2126
2127 /**
2128 * os_if_ndp_iface_create_rsp_handler() - NDP iface create response handler
2129 * @psoc: soc object
2130 * @vdev: vdev object
2131 * @rsp_params: response parameters
2132 *
2133 * The function is expected to send a response back to the user space
2134 * even if the creation of BSS has failed
2135 *
2136 * Following vendor event is sent to cfg80211:
2137 * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD =
2138 * QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE (4 bytes)
2139 * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
2140 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE (4 bytes)
2141 * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE
2142 *
2143 * Return: none
2144 */
os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,void * rsp_params)2145 static void os_if_ndp_iface_create_rsp_handler(struct wlan_objmgr_psoc *psoc,
2146 struct wlan_objmgr_vdev *vdev,
2147 void *rsp_params)
2148 {
2149 uint32_t data_len;
2150 QDF_STATUS status;
2151 bool create_fail = false;
2152 struct nan_callbacks cb_obj;
2153 struct sk_buff *vendor_event;
2154 uint16_t create_transaction_id;
2155 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2156 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
2157 uint32_t create_status = NAN_DATAPATH_RSP_STATUS_ERROR;
2158 uint32_t create_reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
2159 struct nan_datapath_inf_create_rsp *ndi_rsp =
2160 (struct nan_datapath_inf_create_rsp *)rsp_params;
2161 enum qca_nl80211_vendor_subcmds_index index =
2162 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
2163
2164 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
2165 if (QDF_IS_STATUS_ERROR(status)) {
2166 osif_err("Couldn't get ballback object");
2167 return;
2168 }
2169
2170 if (ndi_rsp) {
2171 create_status = ndi_rsp->status;
2172 create_reason = ndi_rsp->reason;
2173 } else {
2174 osif_debug("Invalid ndi create response");
2175 create_fail = true;
2176 }
2177
2178 create_transaction_id = ucfg_nan_get_ndp_create_transaction_id(vdev);
2179 data_len = osif_ndp_get_ndi_create_rsp_len();
2180 /* notify response to the upper layer */
2181 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
2182 data_len, index,
2183 GFP_KERNEL);
2184 if (!vendor_event) {
2185 osif_err("wlan_cfg80211_vendor_event_alloc failed");
2186 create_fail = true;
2187 goto close_ndi;
2188 }
2189
2190 /* Sub vendor command */
2191 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
2192 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE)) {
2193 osif_err("QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD put fail");
2194 goto nla_put_failure;
2195 }
2196
2197 /* Transaction id */
2198 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
2199 create_transaction_id)) {
2200 osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
2201 goto nla_put_failure;
2202 }
2203
2204 /* Status code */
2205 if (nla_put_u32(vendor_event,
2206 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
2207 create_status)) {
2208 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
2209 goto nla_put_failure;
2210 }
2211
2212 /* Status return value */
2213 if (nla_put_u32(vendor_event,
2214 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
2215 create_reason)) {
2216 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
2217 goto nla_put_failure;
2218 }
2219
2220 osif_debug("transaction id: %u status code: %u Reason: %u",
2221 create_transaction_id, create_status, create_reason);
2222
2223 if (!create_fail) {
2224 /* update txrx queues and register self sta */
2225 cb_obj.drv_ndi_create_rsp_handler(wlan_vdev_get_id(vdev),
2226 ndi_rsp);
2227 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
2228 } else {
2229 osif_err("NDI interface creation failed with reason %d",
2230 create_reason);
2231 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
2232 goto close_ndi;
2233 }
2234
2235 return;
2236
2237 nla_put_failure:
2238 wlan_cfg80211_vendor_free_skb(vendor_event);
2239 close_ndi:
2240 cb_obj.ndi_close(wlan_vdev_get_id(vdev));
2241 return;
2242 }
2243
2244 /**
2245 * os_if_ndp_iface_delete_rsp_handler() - NDP iface delete response handler
2246 * @psoc: soc object
2247 * @vdev: vdev object
2248 * @rsp_params: response parameters
2249 *
2250 * Return: none
2251 */
os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,void * rsp_params)2252 static void os_if_ndp_iface_delete_rsp_handler(struct wlan_objmgr_psoc *psoc,
2253 struct wlan_objmgr_vdev *vdev,
2254 void *rsp_params)
2255 {
2256 QDF_STATUS status;
2257 uint8_t vdev_id = wlan_vdev_get_id(vdev);
2258 struct nan_datapath_inf_delete_rsp *ndi_rsp = rsp_params;
2259 struct nan_callbacks cb_obj;
2260
2261 if (!ndi_rsp) {
2262 osif_err("Invalid ndi delete response");
2263 return;
2264 }
2265
2266 status = ucfg_nan_get_callbacks(psoc, &cb_obj);
2267 if (QDF_IS_STATUS_ERROR(status)) {
2268 osif_err("Couldn't get ballback object");
2269 return;
2270 }
2271
2272 if (ndi_rsp->status == NAN_DATAPATH_RSP_STATUS_SUCCESS)
2273 osif_debug("NDI BSS successfully stopped");
2274 else
2275 osif_debug("NDI BSS stop failed with reason %d",
2276 ndi_rsp->reason);
2277
2278 os_if_cstats_log_ndi_delete_resp_evt(vdev, ndi_rsp);
2279
2280 ucfg_nan_set_ndi_delete_rsp_reason(vdev, ndi_rsp->reason);
2281 ucfg_nan_set_ndi_delete_rsp_status(vdev, ndi_rsp->status);
2282 cb_obj.drv_ndi_delete_rsp_handler(vdev_id);
2283 }
2284
osif_ndp_get_ndp_sch_update_ind_len(struct nan_datapath_sch_update_event * sch_update)2285 static inline uint32_t osif_ndp_get_ndp_sch_update_ind_len(
2286 struct nan_datapath_sch_update_event *sch_update)
2287 {
2288 uint32_t ch_info_len = 0;
2289 uint32_t data_len = NLMSG_HDRLEN;
2290
2291 data_len += nla_total_size(vendor_attr_policy[
2292 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
2293 data_len += nla_total_size(vendor_attr_policy[
2294 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR].len);
2295 if (sch_update->num_ndp_instances)
2296 data_len += nla_total_size(sch_update->num_ndp_instances *
2297 sizeof(uint32_t));
2298 data_len += nla_total_size(vendor_attr_policy[
2299 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON].len);
2300 data_len += nla_total_size(vendor_attr_policy[
2301 QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS].len);
2302 /* ch_info is a nested array of following attributes */
2303 ch_info_len += nla_total_size(
2304 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL].len);
2305 ch_info_len += nla_total_size(
2306 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH].len);
2307 ch_info_len += nla_total_size(
2308 vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_NSS].len);
2309
2310 if (sch_update->num_ndp_instances)
2311 data_len += sch_update->num_ndp_instances *
2312 nla_total_size(ch_info_len);
2313
2314 return data_len;
2315 }
2316
os_if_ndp_sch_update_pack_ch_info(struct sk_buff * event,struct nan_datapath_sch_update_event * sch_update)2317 static QDF_STATUS os_if_ndp_sch_update_pack_ch_info(struct sk_buff *event,
2318 struct nan_datapath_sch_update_event *sch_update)
2319 {
2320 int idx = 0;
2321 struct nlattr *ch_array, *ch_element;
2322
2323 osif_debug("num_ch: %d", sch_update->num_channels);
2324 if (!sch_update->num_channels)
2325 return QDF_STATUS_SUCCESS;
2326
2327 ch_array = nla_nest_start(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_INFO);
2328 if (!ch_array)
2329 return QDF_STATUS_E_FAULT;
2330
2331 for (idx = 0; idx < sch_update->num_channels; idx++) {
2332 osif_debug("ch[%d]: freq: %d, width: %d, nss: %d",
2333 idx, sch_update->ch[idx].freq,
2334 sch_update->ch[idx].ch_width,
2335 sch_update->ch[idx].nss);
2336 ch_element = nla_nest_start(event, idx);
2337 if (!ch_element)
2338 return QDF_STATUS_E_FAULT;
2339
2340 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL,
2341 sch_update->ch[idx].freq))
2342 return QDF_STATUS_E_FAULT;
2343
2344 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_WIDTH,
2345 sch_update->ch[idx].ch_width))
2346 return QDF_STATUS_E_FAULT;
2347
2348 if (nla_put_u32(event, QCA_WLAN_VENDOR_ATTR_NDP_NSS,
2349 sch_update->ch[idx].nss))
2350 return QDF_STATUS_E_FAULT;
2351 nla_nest_end(event, ch_element);
2352 }
2353 nla_nest_end(event, ch_array);
2354
2355 return QDF_STATUS_SUCCESS;
2356 }
2357
2358 /**
2359 * os_if_ndp_sch_update_ind_handler() - NDP schedule update handler
2360 * @vdev: vdev object pointer
2361 * @ind: sch update pointer
2362 *
2363 * Following vendor event is sent to cfg80211:
2364 *
2365 * Return: none
2366 */
os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev * vdev,void * ind)2367 static void os_if_ndp_sch_update_ind_handler(struct wlan_objmgr_vdev *vdev,
2368 void *ind)
2369 {
2370 int idx = 0;
2371 const uint8_t *ifname;
2372 QDF_STATUS status;
2373 uint32_t data_len;
2374 uint8_t ifname_len;
2375 struct sk_buff *vendor_event;
2376 struct nan_datapath_sch_update_event *sch_update = ind;
2377 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2378 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
2379 enum qca_nl80211_vendor_subcmds_index index =
2380 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
2381
2382 if (!sch_update) {
2383 osif_err("Invalid sch update params");
2384 return;
2385 }
2386
2387 ifname = os_if_ndi_get_if_name(vdev);
2388 if (!ifname) {
2389 osif_err("ifname is null");
2390 return;
2391 }
2392 ifname_len = qdf_str_len(ifname);
2393 if (ifname_len > IFNAMSIZ) {
2394 osif_err("ifname(%d) too long", ifname_len);
2395 return;
2396 }
2397
2398 data_len = osif_ndp_get_ndp_sch_update_ind_len(sch_update);
2399 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
2400 data_len, index,
2401 GFP_ATOMIC);
2402 if (!vendor_event) {
2403 osif_err("wlan_cfg80211_vendor_event_alloc failed");
2404 return;
2405 }
2406
2407 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
2408 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_IND))
2409 goto ndp_sch_ind_nla_failed;
2410
2411 if (nla_put(vendor_event,
2412 QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR,
2413 QDF_MAC_ADDR_SIZE, sch_update->peer_addr.bytes))
2414 goto ndp_sch_ind_nla_failed;
2415
2416 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
2417 sch_update->num_ndp_instances * sizeof(uint32_t),
2418 sch_update->ndp_instances))
2419 goto ndp_sch_ind_nla_failed;
2420
2421 if (nla_put_u32(vendor_event,
2422 QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_UPDATE_REASON,
2423 sch_update->flags))
2424 goto ndp_sch_ind_nla_failed;
2425
2426 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_CHANNELS,
2427 sch_update->num_channels))
2428 goto ndp_sch_ind_nla_failed;
2429
2430 status = os_if_ndp_sch_update_pack_ch_info(vendor_event, sch_update);
2431 if (QDF_IS_STATUS_ERROR(status))
2432 goto ndp_sch_ind_nla_failed;
2433
2434 osif_debug("Flags: %d, num_instance_id: %d", sch_update->flags,
2435 sch_update->num_ndp_instances);
2436
2437 for (idx = 0; idx < sch_update->num_ndp_instances; idx++)
2438 osif_debug("ndp_instance[%d]: %d", idx,
2439 sch_update->ndp_instances[idx]);
2440
2441 wlan_cfg80211_vendor_event(vendor_event, GFP_ATOMIC);
2442 return;
2443
2444 ndp_sch_ind_nla_failed:
2445 osif_err("nla_put api failed");
2446 wlan_cfg80211_vendor_free_skb(vendor_event);
2447 }
2448
os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev,uint32_t type,void * msg)2449 static void os_if_nan_datapath_event_handler(struct wlan_objmgr_psoc *psoc,
2450 struct wlan_objmgr_vdev *vdev,
2451 uint32_t type, void *msg)
2452 {
2453 switch (type) {
2454 case NAN_DATAPATH_INF_CREATE_RSP:
2455 os_if_ndp_iface_create_rsp_handler(psoc, vdev, msg);
2456 break;
2457 case NAN_DATAPATH_INF_DELETE_RSP:
2458 os_if_ndp_iface_delete_rsp_handler(psoc, vdev, msg);
2459 break;
2460 case NDP_CONFIRM:
2461 os_if_ndp_confirm_ind_handler(vdev, msg);
2462 break;
2463 case NDP_INITIATOR_RSP:
2464 os_if_ndp_initiator_rsp_handler(vdev, msg);
2465 break;
2466 case NDP_INDICATION:
2467 os_if_ndp_indication_handler(vdev, msg);
2468 break;
2469 case NDP_NEW_PEER:
2470 os_if_new_peer_ind_handler(vdev, msg);
2471 break;
2472 case NDP_RESPONDER_RSP:
2473 os_if_ndp_responder_rsp_handler(vdev, msg);
2474 break;
2475 case NDP_END_RSP:
2476 os_if_ndp_end_rsp_handler(vdev, msg);
2477 break;
2478 case NDP_END_IND:
2479 os_if_ndp_end_ind_handler(vdev, msg);
2480 break;
2481 case NDP_PEER_DEPARTED:
2482 os_if_peer_departed_ind_handler(vdev, msg);
2483 break;
2484 case NDP_SCHEDULE_UPDATE:
2485 os_if_ndp_sch_update_ind_handler(vdev, msg);
2486 break;
2487 default:
2488 break;
2489 }
2490 }
2491
os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)2492 int os_if_nan_register_lim_callbacks(struct wlan_objmgr_psoc *psoc,
2493 struct nan_callbacks *cb_obj)
2494 {
2495 return ucfg_nan_register_lim_callbacks(psoc, cb_obj);
2496 }
2497
os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool success)2498 void os_if_nan_post_ndi_create_rsp(struct wlan_objmgr_psoc *psoc,
2499 uint8_t vdev_id, bool success)
2500 {
2501 struct nan_datapath_inf_create_rsp rsp = {0};
2502 struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
2503 psoc, vdev_id, WLAN_NAN_ID);
2504
2505 if (!vdev) {
2506 osif_err("vdev is null");
2507 return;
2508 }
2509
2510 if (success) {
2511 rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
2512 rsp.reason = 0;
2513 os_if_nan_datapath_event_handler(psoc, vdev,
2514 NAN_DATAPATH_INF_CREATE_RSP,
2515 &rsp);
2516 } else {
2517 rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
2518 rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_CREATE_FAILED;
2519 os_if_nan_datapath_event_handler(psoc, vdev,
2520 NAN_DATAPATH_INF_CREATE_RSP,
2521 &rsp);
2522 }
2523 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
2524 }
2525
os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,bool success)2526 void os_if_nan_post_ndi_delete_rsp(struct wlan_objmgr_psoc *psoc,
2527 uint8_t vdev_id, bool success)
2528 {
2529 struct nan_datapath_inf_delete_rsp rsp = {0};
2530 struct wlan_objmgr_vdev *vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
2531 psoc, vdev_id, WLAN_NAN_ID);
2532 if (!vdev) {
2533 osif_err("vdev is null");
2534 return;
2535 }
2536
2537 if (success) {
2538 rsp.status = NAN_DATAPATH_RSP_STATUS_SUCCESS;
2539 rsp.reason = 0;
2540 os_if_nan_datapath_event_handler(psoc, vdev,
2541 NAN_DATAPATH_INF_DELETE_RSP,
2542 &rsp);
2543 } else {
2544 rsp.status = NAN_DATAPATH_RSP_STATUS_ERROR;
2545 rsp.reason = NAN_DATAPATH_NAN_DATA_IFACE_DELETE_FAILED;
2546 os_if_nan_datapath_event_handler(psoc, vdev,
2547 NAN_DATAPATH_INF_DELETE_RSP,
2548 &rsp);
2549 }
2550 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
2551 }
2552
osif_ndp_get_ndi_delete_rsp_len(void)2553 static inline uint32_t osif_ndp_get_ndi_delete_rsp_len(void)
2554 {
2555 uint32_t data_len = NLMSG_HDRLEN;
2556
2557 data_len += nla_total_size(vendor_attr_policy[
2558 QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD].len);
2559 data_len += nla_total_size(vendor_attr_policy[
2560 QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID].len);
2561 data_len += nla_total_size(vendor_attr_policy[
2562 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE].len);
2563 data_len += nla_total_size(vendor_attr_policy[
2564 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE].len);
2565
2566 return data_len;
2567 }
2568
os_if_nan_ndi_session_end(struct wlan_objmgr_vdev * vdev)2569 void os_if_nan_ndi_session_end(struct wlan_objmgr_vdev *vdev)
2570 {
2571 uint32_t data_len;
2572 struct sk_buff *vendor_event;
2573 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2574 struct pdev_osif_priv *os_priv = wlan_pdev_get_ospriv(pdev);
2575 enum nan_datapath_state state;
2576 enum qca_nl80211_vendor_subcmds_index index =
2577 QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX;
2578
2579 /*
2580 * The virtual adapters are stopped and closed even during
2581 * driver unload or stop, the service layer is not required
2582 * to be informed in that case (response is not expected)
2583 */
2584 state = ucfg_nan_get_ndi_state(vdev);
2585
2586 /*
2587 * With NDP Delete Vendor command, hdd_ndi_delete function modifies NDI
2588 * state to delete "NAN_DATA_NDI_DELETING_STATE".
2589 * But when user issues DEL Virtual Intf cmd, hdd_ndi_delete does not
2590 * call and NDI state remains to created "NAN_DATA_NDI_CREATED_STATE".
2591 */
2592 if (state == NAN_DATA_NDI_CREATED_STATE) {
2593 osif_debug("NDI interface is just created: %u", state);
2594 return;
2595 } else if (state != NAN_DATA_NDI_DELETING_STATE &&
2596 state != NAN_DATA_DISCONNECTED_STATE) {
2597 osif_err("NDI interface deleted: state: %u", state);
2598 return;
2599 }
2600
2601 data_len = osif_ndp_get_ndi_delete_rsp_len();
2602 /* notify response to the upper layer */
2603 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, NULL,
2604 data_len, index,
2605 GFP_KERNEL);
2606 if (!vendor_event) {
2607 osif_err("wlan_cfg80211_vendor_event_alloc failed");
2608 return;
2609 }
2610
2611 /* Sub vendor command goes first */
2612 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD,
2613 QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) {
2614 osif_err("VENDOR_ATTR_NDP_SUBCMD put fail");
2615 goto failure;
2616 }
2617
2618 /* Transaction id */
2619 if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
2620 ucfg_nan_get_ndp_delete_transaction_id(vdev))) {
2621 osif_err("VENDOR_ATTR_NDP_TRANSACTION_ID put fail");
2622 goto failure;
2623 }
2624
2625 /* Status code */
2626 if (nla_put_u32(vendor_event,
2627 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RESPONSE_STATUS_TYPE,
2628 ucfg_nan_get_ndi_delete_rsp_status(vdev))) {
2629 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail");
2630 goto failure;
2631 }
2632
2633 /* Status return value */
2634 if (nla_put_u32(vendor_event,
2635 QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
2636 ucfg_nan_get_ndi_delete_rsp_reason(vdev))) {
2637 osif_err("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail");
2638 goto failure;
2639 }
2640
2641 osif_debug("delete transaction id: %u, status code: %u reason: %u",
2642 ucfg_nan_get_ndp_delete_transaction_id(vdev),
2643 ucfg_nan_get_ndi_delete_rsp_status(vdev),
2644 ucfg_nan_get_ndi_delete_rsp_reason(vdev));
2645
2646 ucfg_nan_set_ndp_delete_transaction_id(vdev, 0);
2647 ucfg_nan_set_ndi_state(vdev, NAN_DATA_NDI_DELETED_STATE);
2648 ucfg_ndi_remove_entry_from_policy_mgr(vdev);
2649 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
2650
2651 return;
2652 failure:
2653 wlan_cfg80211_vendor_free_skb(vendor_event);
2654 }
2655
2656 /**
2657 * os_if_nan_handle_sr_nan_concurrency() - Handle NAN concurrency for Spatial
2658 * Reuse
2659 * @nan_evt: NAN Event parameters
2660 *
2661 * Module calls callback to send SR event to userspace.
2662 *
2663 * Return: none
2664 */
2665 #ifdef WLAN_FEATURE_SR
2666 static void
os_if_nan_handle_sr_nan_concurrency(struct nan_event_params * nan_evt)2667 os_if_nan_handle_sr_nan_concurrency(struct nan_event_params *nan_evt) {
2668 void (*nan_sr_conc_callback)(struct nan_event_params *nan_evt);
2669 struct nan_psoc_priv_obj *psoc_obj =
2670 nan_get_psoc_priv_obj(nan_evt->psoc);
2671
2672 if (!psoc_obj) {
2673 nan_err("nan psoc priv object is NULL");
2674 return;
2675 }
2676
2677 nan_sr_conc_callback = psoc_obj->cb_obj.nan_sr_concurrency_update;
2678 if (nan_sr_conc_callback)
2679 nan_sr_conc_callback(nan_evt);
2680 }
2681 #else
2682 static void
os_if_nan_handle_sr_nan_concurrency(struct nan_event_params * nan_evt)2683 os_if_nan_handle_sr_nan_concurrency(struct nan_event_params *nan_evt)
2684 {}
2685 #endif
2686
2687 /**
2688 * os_if_nan_discovery_event_handler() - NAN Discovery Interface event handler
2689 * @nan_evt: NAN Event parameters
2690 *
2691 * Module sends a NAN related vendor event to the upper layer
2692 *
2693 * Return: none
2694 */
os_if_nan_discovery_event_handler(struct nan_event_params * nan_evt)2695 static void os_if_nan_discovery_event_handler(struct nan_event_params *nan_evt)
2696 {
2697 struct sk_buff *vendor_event;
2698 struct wlan_objmgr_pdev *pdev;
2699 struct pdev_osif_priv *os_priv;
2700 enum qca_nl80211_vendor_subcmds_index index =
2701 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX;
2702 struct wireless_dev *wdev;
2703 struct vdev_osif_priv *osif_priv;
2704 struct wlan_objmgr_vdev *vdev = NULL;
2705
2706 /*
2707 * Since Partial Offload chipsets have only one pdev per psoc, the first
2708 * pdev from the pdev list is used.
2709 */
2710 pdev = wlan_objmgr_get_pdev_by_id(nan_evt->psoc, 0, WLAN_NAN_ID);
2711 if (!pdev) {
2712 osif_err("null pdev");
2713 return;
2714 }
2715 os_if_nan_handle_sr_nan_concurrency(nan_evt);
2716
2717 os_priv = wlan_pdev_get_ospriv(pdev);
2718 if (!os_priv) {
2719 osif_err(" pdev osif priv is null");
2720 goto fail;
2721 }
2722
2723 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, nan_evt->vdev_id,
2724 WLAN_NAN_ID);
2725 if (!vdev) {
2726 osif_err("vdev is null");
2727 goto fail;
2728 }
2729
2730 osif_priv = wlan_vdev_get_ospriv(vdev);
2731 if (!osif_priv) {
2732 osif_err("osif_priv is null");
2733 goto fail;
2734 }
2735
2736 wdev = osif_priv->wdev;
2737 if (!wdev) {
2738 osif_err("wireless dev is null");
2739 goto fail;
2740 }
2741
2742 vendor_event = wlan_cfg80211_vendor_event_alloc(os_priv->wiphy, wdev,
2743 nan_evt->buf_len +
2744 NLMSG_HDRLEN,
2745 index, GFP_KERNEL);
2746 if (!vendor_event) {
2747 osif_err("wlan_cfg80211_vendor_event_alloc failed");
2748 goto fail;
2749 }
2750
2751 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN, nan_evt->buf_len,
2752 nan_evt->buf)) {
2753 osif_err("QCA_WLAN_VENDOR_ATTR_NAN put failed");
2754 wlan_cfg80211_vendor_free_skb(vendor_event);
2755 goto fail;
2756 }
2757
2758 wlan_cfg80211_vendor_event(vendor_event, GFP_KERNEL);
2759 fail:
2760 if (vdev)
2761 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
2762
2763 wlan_objmgr_pdev_release_ref(pdev, WLAN_NAN_ID);
2764 }
2765
os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc * psoc,struct nan_callbacks * cb_obj)2766 int os_if_nan_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
2767 struct nan_callbacks *cb_obj)
2768 {
2769 cb_obj->os_if_ndp_event_handler = os_if_nan_datapath_event_handler;
2770 cb_obj->os_if_nan_event_handler = os_if_nan_discovery_event_handler;
2771 return ucfg_nan_register_hdd_callbacks(psoc, cb_obj);
2772 }
2773
os_if_nan_generic_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)2774 static int os_if_nan_generic_req(struct wlan_objmgr_psoc *psoc,
2775 struct nlattr **tb)
2776 {
2777 struct nan_generic_req *nan_req;
2778 uint32_t buf_len;
2779 QDF_STATUS status;
2780
2781 buf_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]);
2782
2783 nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len);
2784 if (!nan_req)
2785 return -ENOMEM;
2786 qdf_mem_zero(nan_req, sizeof(*nan_req) + buf_len);
2787
2788 nan_req->psoc = psoc;
2789 nan_req->params.request_data_len = buf_len;
2790 nla_memcpy(nan_req->params.request_data,
2791 tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len);
2792
2793 status = ucfg_nan_discovery_req(nan_req, NAN_GENERIC_REQ);
2794
2795 if (QDF_IS_STATUS_SUCCESS(status))
2796 osif_debug("Successfully sent a NAN request");
2797 else
2798 osif_err("Unable to send a NAN request");
2799
2800 qdf_mem_free(nan_req);
2801 return qdf_status_to_os_return(status);
2802 }
2803
os_if_process_nan_disable_req(struct wlan_objmgr_psoc * psoc,struct nlattr ** tb)2804 static int os_if_process_nan_disable_req(struct wlan_objmgr_psoc *psoc,
2805 struct nlattr **tb)
2806 {
2807 uint8_t *data;
2808 uint32_t data_len;
2809 QDF_STATUS status;
2810
2811 data = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]);
2812 data_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]);
2813
2814 status = ucfg_disable_nan_discovery(psoc, data, data_len);
2815
2816 return qdf_status_to_os_return(status);
2817 }
2818
os_if_process_nan_enable_req(struct wlan_objmgr_pdev * pdev,struct nlattr ** tb,uint8_t vdev_id)2819 static int os_if_process_nan_enable_req(struct wlan_objmgr_pdev *pdev,
2820 struct nlattr **tb, uint8_t vdev_id)
2821 {
2822 uint32_t chan_freq_2g, chan_freq_5g = 0;
2823 uint32_t buf_len;
2824 QDF_STATUS status;
2825 uint32_t fine_time_meas_cap;
2826 struct nan_enable_req *nan_req;
2827 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
2828
2829 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]) {
2830 osif_err("NAN Social channel for 2.4Gz is unavailable!");
2831 return -EINVAL;
2832 }
2833 chan_freq_2g =
2834 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_24GHZ_BAND_FREQ]);
2835
2836 if (tb[QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ])
2837 chan_freq_5g =
2838 nla_get_u32(tb[
2839 QCA_WLAN_VENDOR_ATTR_NAN_DISC_5GHZ_BAND_FREQ]);
2840
2841 if (!ucfg_is_nan_enable_allowed(psoc, chan_freq_2g, vdev_id)) {
2842 osif_err("NAN Enable not allowed at this moment for channel %d",
2843 chan_freq_2g);
2844 return -EINVAL;
2845 }
2846
2847 buf_len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]);
2848
2849 nan_req = qdf_mem_malloc(sizeof(*nan_req) + buf_len);
2850 if (!nan_req)
2851 return -ENOMEM;
2852
2853 nan_req->social_chan_2g_freq = chan_freq_2g;
2854 if (chan_freq_5g)
2855 nan_req->social_chan_5g_freq = chan_freq_5g;
2856 nan_req->psoc = psoc;
2857 nan_req->pdev = pdev;
2858 nan_req->params.request_data_len = buf_len;
2859
2860 ucfg_mlme_get_fine_time_meas_cap(psoc, &fine_time_meas_cap);
2861 nan_req->params.rtt_cap = fine_time_meas_cap;
2862 nan_req->params.disable_6g_nan = ucfg_get_disable_6g_nan(psoc);
2863
2864 nla_memcpy(nan_req->params.request_data,
2865 tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA], buf_len);
2866
2867 osif_debug("Sending NAN Enable Req. NAN Ch Freq: %d %d",
2868 nan_req->social_chan_2g_freq, nan_req->social_chan_5g_freq);
2869 status = ucfg_nan_discovery_req(nan_req, NAN_ENABLE_REQ);
2870
2871 if (QDF_IS_STATUS_SUCCESS(status)) {
2872 osif_debug("Successfully sent NAN Enable request");
2873 os_if_cstats_log_nan_disc_enable_req_evt(vdev_id, nan_req);
2874 } else {
2875 osif_err("Unable to send NAN Enable request");
2876 }
2877
2878 qdf_mem_free(nan_req);
2879 return qdf_status_to_os_return(status);
2880 }
2881
os_if_process_nan_req(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,const void * data,int data_len)2882 int os_if_process_nan_req(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
2883 const void *data, int data_len)
2884 {
2885 uint32_t nan_subcmd;
2886 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX + 1];
2887 struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
2888
2889 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_NAN_PARAMS_MAX,
2890 data, data_len, nan_attr_policy)) {
2891 osif_err("Invalid NAN vendor command attributes");
2892 return -EINVAL;
2893 }
2894
2895 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_CMD_DATA]) {
2896 osif_err("NAN cmd data missing!");
2897 return -EINVAL;
2898 }
2899
2900 /*
2901 * If target does not support NAN DBS, stop the opportunistic timer.
2902 * Opportunistic timer gets triggered as soon as a DBS use case is
2903 * completed and hw_mode would be set to SMM when the timer(5 seconds)
2904 * expires.
2905 * This is to make sure that HW mode is not set to DBS by NAN Enable
2906 * request. NAN state machine will remain unaffected in this case.
2907 */
2908 if (!NAN_CONCURRENCY_SUPPORTED(psoc))
2909 policy_mgr_check_and_stop_opportunistic_timer(psoc, vdev_id);
2910
2911 /*
2912 * Send all requests other than Enable/Disable as type GENERIC.
2913 * These will be treated as passthrough by the driver.
2914 */
2915 if (!tb[QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE])
2916 return os_if_nan_generic_req(psoc, tb);
2917
2918 nan_subcmd = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NAN_SUBCMD_TYPE]);
2919
2920 switch (nan_subcmd) {
2921 case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_ENABLE_REQ:
2922 return os_if_process_nan_enable_req(pdev, tb, vdev_id);
2923 case QCA_WLAN_NAN_EXT_SUBCMD_TYPE_DISABLE_REQ:
2924 os_if_cstats_log_disable_nan_disc_evt(pdev, vdev_id);
2925 return os_if_process_nan_disable_req(psoc, tb);
2926 default:
2927 osif_err("Unrecognized NAN subcmd type(%d)", nan_subcmd);
2928 return -EINVAL;
2929 }
2930 }
2931
2932 #ifdef WLAN_CHIPSET_STATS
2933 void
os_if_cstats_log_ndp_initiator_req_evt(struct nan_datapath_initiator_req * req)2934 os_if_cstats_log_ndp_initiator_req_evt(struct nan_datapath_initiator_req *req)
2935 {
2936 struct cstats_nan_ndp_initiator_req stat = {0};
2937 struct wlan_objmgr_vdev *vdev;
2938
2939 vdev = req->vdev;
2940
2941 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_INITIATOR_REQ_EVENT_ID;
2942 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_initiator_req) -
2943 sizeof(struct cstats_hdr);
2944 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
2945 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
2946 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
2947 stat.cmn.time_tick = qdf_get_log_timestamp();
2948
2949 stat.transaction_id = req->transaction_id;
2950 stat.channel = req->channel;
2951 stat.channel_cfg = req->channel_cfg;
2952 stat.service_instance_id = req->service_instance_id;
2953 CSTATS_MAC_COPY(stat.self_ndi_mac_addr, req->self_ndi_mac_addr.bytes);
2954 CSTATS_MAC_COPY(stat.peer_discovery_mac_addr,
2955 req->peer_discovery_mac_addr.bytes);
2956
2957 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_initiator_req),
2958 &stat);
2959 }
2960
2961 void
os_if_cstats_log_ndp_responder_req_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_responder_req * req)2962 os_if_cstats_log_ndp_responder_req_evt(struct wlan_objmgr_vdev *vdev,
2963 struct nan_datapath_responder_req *req)
2964 {
2965 struct cstats_nan_ndp_responder_req stat = {0};
2966
2967 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_RESPONDER_REQ_EVENT_ID;
2968 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_responder_req) -
2969 sizeof(struct cstats_hdr);
2970 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
2971 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
2972 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
2973 stat.cmn.time_tick = qdf_get_log_timestamp();
2974 stat.transaction_id = req->transaction_id;
2975 stat.ndp_instance_id = req->ndp_instance_id;
2976 stat.ndp_rsp = req->ndp_rsp;
2977 stat.ncs_sk_type = req->ncs_sk_type;
2978
2979 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_responder_req),
2980 &stat);
2981 }
2982
os_if_cstats_log_ndp_end_req_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_end_req * rq)2983 void os_if_cstats_log_ndp_end_req_evt(struct wlan_objmgr_vdev *vdev,
2984 struct nan_datapath_end_req *rq)
2985 {
2986 struct cstats_nan_ndp_end_req stat = {0};
2987
2988 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_END_REQ_EVENT_ID;
2989 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_end_req) -
2990 sizeof(struct cstats_hdr);
2991 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
2992 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
2993 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
2994 stat.cmn.time_tick = qdf_get_log_timestamp();
2995 stat.transaction_id = rq->transaction_id;
2996 stat.num_ndp_instances = rq->num_ndp_instances;
2997
2998 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_end_req), &stat);
2999 }
3000
3001 void
os_if_cstats_log_ndp_initiator_resp_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_initiator_rsp * rsp)3002 os_if_cstats_log_ndp_initiator_resp_evt(struct wlan_objmgr_vdev *vdev,
3003 struct nan_datapath_initiator_rsp *rsp)
3004 {
3005 struct cstats_nan_ndp_initiator_resp stat = {0};
3006
3007 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_INITIATOR_RSP_EVENT_ID;
3008 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_initiator_resp) -
3009 sizeof(struct cstats_hdr);
3010 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3011 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3012 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3013 stat.cmn.time_tick = qdf_get_log_timestamp();
3014 stat.status = rsp->status;
3015 stat.reason = rsp->reason;
3016 stat.transaction_id = rsp->transaction_id;
3017 stat.service_instance_id = rsp->ndp_instance_id;
3018
3019 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_initiator_resp),
3020 &stat);
3021 }
3022
3023 void
os_if_cstats_log_ndp_responder_resp_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_responder_rsp * rsp)3024 os_if_cstats_log_ndp_responder_resp_evt(struct wlan_objmgr_vdev *vdev,
3025 struct nan_datapath_responder_rsp *rsp)
3026 {
3027 struct cstats_nan_ndp_responder_resp stat = {0};
3028
3029 stat.cmn.hdr.evt_id =
3030 WLAN_CHIPSET_STATS_NAN_NDP_RESPONDER_RESP_EVENT_ID;
3031 stat.cmn.hdr.length = sizeof(struct cstats_tdls_disc_req) -
3032 sizeof(struct cstats_hdr);
3033 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3034 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3035 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3036 stat.cmn.time_tick = qdf_get_log_timestamp();
3037 stat.status = rsp->status;
3038 stat.reason = rsp->reason;
3039 stat.transaction_id = rsp->transaction_id;
3040
3041 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_responder_resp),
3042 &stat);
3043 }
3044
3045 void
os_if_cstats_log_ndp_indication_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_indication_event * evt)3046 os_if_cstats_log_ndp_indication_evt(struct wlan_objmgr_vdev *vdev,
3047 struct nan_datapath_indication_event *evt)
3048 {
3049 struct cstats_nan_ndp_ind stat = {0};
3050
3051 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_INDICATION_EVENT_ID;
3052 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_ind) -
3053 sizeof(struct cstats_hdr);
3054 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3055 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3056 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3057 stat.cmn.time_tick = qdf_get_log_timestamp();
3058 stat.ndp_instance_id = evt->ndp_instance_id;
3059 stat.service_instance_id = evt->service_instance_id;
3060 CSTATS_MAC_COPY(stat.peer_mac, evt->peer_mac_addr.bytes);
3061 CSTATS_MAC_COPY(stat.peer_discovery_mac_addr,
3062 evt->peer_discovery_mac_addr.bytes);
3063
3064 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_ind), &stat);
3065 }
3066
3067 void
os_if_cstats_log_ndp_confirm_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_confirm_event * nc)3068 os_if_cstats_log_ndp_confirm_evt(struct wlan_objmgr_vdev *vdev,
3069 struct nan_datapath_confirm_event *nc)
3070 {
3071 struct cstats_nan_ndp_confirm_ind stat = {0};
3072
3073 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_CONFIRM_EVENT_ID;
3074 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_confirm_ind) -
3075 sizeof(struct cstats_hdr);
3076 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3077 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3078 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3079 stat.cmn.time_tick = qdf_get_log_timestamp();
3080 stat.instance_id = nc->ndp_instance_id;
3081 stat.rsp_code = nc->rsp_code;
3082 stat.reason_code = nc->reason_code;
3083 CSTATS_MAC_COPY(stat.peer_addr, nc->peer_ndi_mac_addr.bytes);
3084
3085 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_confirm_ind),
3086 &stat);
3087 }
3088
3089 void
os_if_cstats_log_ndp_end_rsp_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_end_rsp_event * rsp)3090 os_if_cstats_log_ndp_end_rsp_evt(struct wlan_objmgr_vdev *vdev,
3091 struct nan_datapath_end_rsp_event *rsp)
3092 {
3093 struct cstats_nan_ndp_end_resp stat = {0};
3094
3095 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_END_RESP_EVENT_ID;
3096 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_end_resp) -
3097 sizeof(struct cstats_hdr);
3098 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3099 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3100 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3101 stat.cmn.time_tick = qdf_get_log_timestamp();
3102 stat.status = rsp->status;
3103 stat.reason = rsp->reason;
3104 stat.transaction_id = rsp->transaction_id;
3105
3106 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_end_resp), &stat);
3107 }
3108
3109 void
os_if_cstats_log_ndp_new_peer_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_peer_ind * peer_ind)3110 os_if_cstats_log_ndp_new_peer_evt(struct wlan_objmgr_vdev *vdev,
3111 struct nan_datapath_peer_ind *peer_ind)
3112 {
3113 struct cstats_nan_ndp_new_peer_ind stat = {0};
3114
3115 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDP_NEW_PEER_EVENT_ID;
3116 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndp_new_peer_ind) -
3117 sizeof(struct cstats_hdr);
3118 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3119 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3120 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3121 stat.cmn.time_tick = qdf_get_log_timestamp();
3122 stat.sta_id = peer_ind->sta_id;
3123 CSTATS_MAC_COPY(stat.peer_mac, peer_ind->peer_mac_addr.bytes);
3124
3125 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndp_new_peer_ind),
3126 &stat);
3127 }
3128
3129 void
os_if_cstats_log_ndi_delete_resp_evt(struct wlan_objmgr_vdev * vdev,struct nan_datapath_inf_delete_rsp * rsp)3130 os_if_cstats_log_ndi_delete_resp_evt(struct wlan_objmgr_vdev *vdev,
3131 struct nan_datapath_inf_delete_rsp *rsp)
3132 {
3133 struct cstats_nan_ndi_delete_resp stat = {0};
3134
3135 stat.cmn.hdr.evt_id = WLAN_CHIPSET_STATS_NAN_NDI_DELETE_RESP_EVENT_ID;
3136 stat.cmn.hdr.length = sizeof(struct cstats_nan_ndi_delete_resp) -
3137 sizeof(struct cstats_hdr);
3138 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3139 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3140 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3141 stat.cmn.time_tick = qdf_get_log_timestamp();
3142
3143 stat.status = rsp->status;
3144 stat.reason = rsp->reason;
3145 stat.transaction_id = ucfg_nan_get_ndp_delete_transaction_id(vdev);
3146
3147 wlan_cstats_host_stats(sizeof(struct cstats_nan_ndi_delete_resp),
3148 &stat);
3149 }
3150
os_if_cstats_log_nan_disc_enable_req_evt(uint8_t vdev_id,struct nan_enable_req * nan_req)3151 void os_if_cstats_log_nan_disc_enable_req_evt(uint8_t vdev_id,
3152 struct nan_enable_req *nan_req)
3153 {
3154 struct cstats_nan_disc_enable stat = {0};
3155 struct wlan_objmgr_vdev *vdev;
3156
3157 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(nan_req->pdev,
3158 vdev_id, WLAN_NAN_ID);
3159 if (!vdev) {
3160 osif_err("vdev is null");
3161 return;
3162 }
3163
3164 stat.cmn.hdr.evt_id =
3165 WLAN_CHIPSET_STATS_NAN_DISCOVERY_ENABLE_REQ_EVENT_ID;
3166 stat.cmn.hdr.length =
3167 sizeof(struct cstats_nan_disc_enable) -
3168 sizeof(struct cstats_hdr);
3169 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3170 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3171 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3172 stat.cmn.time_tick = qdf_get_log_timestamp();
3173 stat.social_chan_2g_freq = nan_req->social_chan_2g_freq;
3174 stat.social_chan_5g_freq = nan_req->social_chan_5g_freq;
3175 stat.rtt_cap = nan_req->params.rtt_cap;
3176 stat.disable_6g_nan = nan_req->params.disable_6g_nan;
3177
3178 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
3179
3180 wlan_cstats_host_stats(sizeof(struct cstats_nan_disc_enable), &stat);
3181 }
3182
3183 void
os_if_cstats_log_disable_nan_disc_evt(struct wlan_objmgr_pdev * pdev,uint8_t vdev_id)3184 os_if_cstats_log_disable_nan_disc_evt(struct wlan_objmgr_pdev *pdev,
3185 uint8_t vdev_id)
3186 {
3187 struct cstats_nan_disc_disable_req stat = {0};
3188 struct wlan_objmgr_vdev *vdev = NULL;
3189
3190 vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id, WLAN_NAN_ID);
3191 if (!vdev) {
3192 osif_err("vdev is null");
3193 return;
3194 }
3195
3196 stat.cmn.hdr.evt_id =
3197 WLAN_CHIPSET_STATS_NAN_DISCOVERY_DISABLE_REQ_EVENT_ID;
3198 stat.cmn.hdr.length = sizeof(struct cstats_nan_disc_disable_req) -
3199 sizeof(struct cstats_hdr);
3200 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
3201 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
3202 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
3203 stat.cmn.time_tick = qdf_get_log_timestamp();
3204
3205 stat.disable_2g_discovery = 1;
3206 stat.disable_5g_discovery = 1;
3207
3208 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
3209
3210 wlan_cstats_host_stats(sizeof(struct cstats_nan_disc_disable_req),
3211 &stat);
3212 }
3213 #endif /* WLAN_CHIPSET_STATS */
3214
3215