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