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