xref: /wlan-driver/qcacld-3.0/components/nan/core/src/nan_main.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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: contains core nan function definitions
22  */
23 
24 #include "wlan_utility.h"
25 #include "nan_ucfg_api.h"
26 #include "wlan_nan_api.h"
27 #include "target_if_nan.h"
28 #include "scheduler_api.h"
29 #include "wlan_policy_mgr_api.h"
30 #include "wlan_osif_request_manager.h"
31 #include "wlan_serialization_api.h"
32 #include "wlan_objmgr_cmn.h"
33 #include "wlan_tdls_ucfg_api.h"
34 #include "wlan_objmgr_global_obj.h"
35 #include "wlan_objmgr_psoc_obj.h"
36 #include "wlan_objmgr_pdev_obj.h"
37 #include "wlan_objmgr_vdev_obj.h"
38 #include "qdf_platform.h"
39 #include "wlan_osif_request_manager.h"
40 #include "wlan_p2p_api.h"
41 #include "wlan_mlme_vdev_mgr_interface.h"
42 
nan_set_discovery_state(struct wlan_objmgr_psoc * psoc,enum nan_disc_state new_state)43 QDF_STATUS nan_set_discovery_state(struct wlan_objmgr_psoc *psoc,
44 				   enum nan_disc_state new_state)
45 {
46 	enum nan_disc_state cur_state;
47 	struct nan_psoc_priv_obj *psoc_priv = nan_get_psoc_priv_obj(psoc);
48 	bool nan_state_change_allowed = false;
49 	QDF_STATUS status = QDF_STATUS_E_INVAL;
50 
51 	if (!psoc_priv) {
52 		nan_err("nan psoc priv object is NULL");
53 		return QDF_STATUS_E_INVAL;
54 	}
55 
56 	qdf_spin_lock_bh(&psoc_priv->lock);
57 	cur_state = psoc_priv->disc_state;
58 	if (cur_state == new_state) {
59 		qdf_spin_unlock_bh(&psoc_priv->lock);
60 		nan_err("curr_state: %u and new state: %u are same",
61 			cur_state, new_state);
62 		return status;
63 	}
64 
65 	switch (new_state) {
66 	case NAN_DISC_DISABLED:
67 		nan_state_change_allowed = true;
68 		break;
69 	case NAN_DISC_ENABLE_IN_PROGRESS:
70 		if (cur_state == NAN_DISC_DISABLED)
71 			nan_state_change_allowed = true;
72 		break;
73 	case NAN_DISC_ENABLED:
74 		if (cur_state == NAN_DISC_ENABLE_IN_PROGRESS)
75 			nan_state_change_allowed = true;
76 		break;
77 	case NAN_DISC_DISABLE_IN_PROGRESS:
78 		if (cur_state == NAN_DISC_ENABLE_IN_PROGRESS ||
79 		    cur_state == NAN_DISC_ENABLED)
80 			nan_state_change_allowed = true;
81 		break;
82 	default:
83 		break;
84 	}
85 
86 	if (nan_state_change_allowed) {
87 		psoc_priv->disc_state = new_state;
88 		status = QDF_STATUS_SUCCESS;
89 	}
90 
91 	qdf_spin_unlock_bh(&psoc_priv->lock);
92 
93 	nan_debug("NAN State transitioned from %d -> %d", cur_state,
94 		  psoc_priv->disc_state);
95 
96 	return status;
97 }
98 
nan_get_discovery_state(struct wlan_objmgr_psoc * psoc)99 enum nan_disc_state nan_get_discovery_state(struct wlan_objmgr_psoc *psoc)
100 {
101 	struct nan_psoc_priv_obj *psoc_priv = nan_get_psoc_priv_obj(psoc);
102 
103 	if (!psoc_priv) {
104 		nan_err("nan psoc priv object is NULL");
105 		return NAN_DISC_DISABLED;
106 	}
107 
108 	return psoc_priv->disc_state;
109 }
110 
nan_release_cmd(void * in_req,uint32_t cmdtype)111 void nan_release_cmd(void *in_req, uint32_t cmdtype)
112 {
113 	struct wlan_objmgr_vdev *vdev = NULL;
114 
115 	if (!in_req)
116 		return;
117 
118 	switch (cmdtype) {
119 	case WLAN_SER_CMD_NDP_INIT_REQ: {
120 		struct nan_datapath_initiator_req *req = in_req;
121 
122 		vdev = req->vdev;
123 		break;
124 	}
125 	case WLAN_SER_CMD_NDP_RESP_REQ: {
126 		struct nan_datapath_responder_req *req = in_req;
127 
128 		vdev = req->vdev;
129 		break;
130 	}
131 	case WLAN_SER_CMD_NDP_DATA_END_INIT_REQ: {
132 		struct nan_datapath_end_req *req = in_req;
133 
134 		vdev = req->vdev;
135 		break;
136 	}
137 	case WLAN_SER_CMD_NDP_END_ALL_REQ: {
138 		struct nan_datapath_end_all_ndps *req = in_req;
139 
140 		vdev = req->vdev;
141 		break;
142 	}
143 	default:
144 		nan_err("invalid req type: %d", cmdtype);
145 		break;
146 	}
147 
148 	if (vdev)
149 		wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
150 	else
151 		nan_err("vdev is null");
152 
153 	qdf_mem_free(in_req);
154 }
155 
nan_req_incomplete(void * req,uint32_t cmdtype)156 static void nan_req_incomplete(void *req, uint32_t cmdtype)
157 {
158 	/* send msg to userspace if needed that cmd got incomplete */
159 }
160 
nan_req_activated(void * in_req,uint32_t cmdtype)161 static void nan_req_activated(void *in_req, uint32_t cmdtype)
162 {
163 	uint32_t req_type;
164 	struct wlan_objmgr_psoc *psoc;
165 	struct wlan_objmgr_vdev *vdev;
166 	struct wlan_nan_tx_ops *tx_ops;
167 	struct nan_psoc_priv_obj *psoc_nan_obj;
168 
169 	switch (cmdtype) {
170 	case WLAN_SER_CMD_NDP_INIT_REQ: {
171 		struct nan_datapath_initiator_req *req = in_req;
172 
173 		vdev = req->vdev;
174 		req_type = NDP_INITIATOR_REQ;
175 		break;
176 	}
177 	case WLAN_SER_CMD_NDP_RESP_REQ: {
178 		struct nan_datapath_responder_req *req = in_req;
179 
180 		vdev = req->vdev;
181 		req_type = NDP_RESPONDER_REQ;
182 		break;
183 	}
184 	case WLAN_SER_CMD_NDP_DATA_END_INIT_REQ: {
185 		struct nan_datapath_end_req *req = in_req;
186 
187 		vdev = req->vdev;
188 		req_type = NDP_END_REQ;
189 		break;
190 	}
191 	case WLAN_SER_CMD_NDP_END_ALL_REQ: {
192 		struct nan_datapath_end_all_ndps *req = in_req;
193 
194 		vdev = req->vdev;
195 		req_type = NDP_END_ALL;
196 		break;
197 	}
198 	default:
199 		nan_alert("in correct cmdtype: %d", cmdtype);
200 		return;
201 	}
202 
203 	if (!vdev) {
204 		nan_alert("vdev is null");
205 		return;
206 	}
207 
208 	psoc = wlan_vdev_get_psoc(vdev);
209 	if (!psoc) {
210 		nan_alert("psoc is null");
211 		return;
212 	}
213 
214 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
215 	if (!psoc_nan_obj) {
216 		nan_err("psoc_nan_obj is null");
217 		return;
218 	}
219 
220 	tx_ops = &psoc_nan_obj->tx_ops;
221 	if (!tx_ops) {
222 		nan_alert("tx_ops is null");
223 		return;
224 	}
225 
226 	/* send ndp_intiator_req/responder_req/end_req to FW */
227 	tx_ops->nan_datapath_req_tx(in_req, req_type);
228 }
229 
nan_serialized_cb(struct wlan_serialization_command * ser_cmd,enum wlan_serialization_cb_reason reason)230 static QDF_STATUS nan_serialized_cb(struct wlan_serialization_command *ser_cmd,
231 				    enum wlan_serialization_cb_reason reason)
232 {
233 	void *req;
234 
235 	if (!ser_cmd || !ser_cmd->umac_cmd) {
236 		nan_alert("cmd or umac_cmd is null");
237 		return QDF_STATUS_E_NULL_VALUE;
238 	}
239 	req = ser_cmd->umac_cmd;
240 
241 	switch (reason) {
242 	case WLAN_SER_CB_ACTIVATE_CMD:
243 		nan_req_activated(req, ser_cmd->cmd_type);
244 		break;
245 	case WLAN_SER_CB_CANCEL_CMD:
246 	case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
247 		nan_req_incomplete(req, ser_cmd->cmd_type);
248 		break;
249 	case WLAN_SER_CB_RELEASE_MEM_CMD:
250 		nan_release_cmd(req, ser_cmd->cmd_type);
251 		break;
252 	default:
253 		/* Do nothing but logging */
254 		nan_alert("invalid serialized cb reason: %d", reason);
255 		break;
256 	}
257 
258 	return QDF_STATUS_SUCCESS;
259 }
260 
nan_scheduled_msg_handler(struct scheduler_msg * msg)261 QDF_STATUS nan_scheduled_msg_handler(struct scheduler_msg *msg)
262 {
263 	enum wlan_serialization_status status = 0;
264 	struct wlan_serialization_command cmd = {0};
265 
266 	if (!msg || !msg->bodyptr) {
267 		nan_alert("msg or bodyptr is null");
268 		return QDF_STATUS_E_NULL_VALUE;
269 	}
270 	switch (msg->type) {
271 	case NDP_INITIATOR_REQ: {
272 		struct nan_datapath_initiator_req *req = msg->bodyptr;
273 
274 		cmd.cmd_type = WLAN_SER_CMD_NDP_INIT_REQ;
275 		cmd.vdev = req->vdev;
276 		break;
277 	}
278 	case NDP_RESPONDER_REQ: {
279 		struct nan_datapath_responder_req *req = msg->bodyptr;
280 
281 		cmd.cmd_type = WLAN_SER_CMD_NDP_RESP_REQ;
282 		cmd.vdev = req->vdev;
283 		break;
284 	}
285 	case NDP_END_REQ: {
286 		struct nan_datapath_end_req *req = msg->bodyptr;
287 
288 		cmd.cmd_type = WLAN_SER_CMD_NDP_DATA_END_INIT_REQ;
289 		cmd.vdev = req->vdev;
290 		break;
291 	}
292 	case NDP_END_ALL: {
293 		struct nan_datapath_end_all_ndps *req = msg->bodyptr;
294 
295 		cmd.cmd_type = WLAN_SER_CMD_NDP_END_ALL_REQ;
296 		cmd.vdev = req->vdev;
297 		break;
298 	}
299 	default:
300 		nan_err("wrong request type: %d", msg->type);
301 		return QDF_STATUS_E_INVAL;
302 	}
303 
304 	/* TBD - support more than one req of same type or avoid */
305 	cmd.cmd_id = 0;
306 	cmd.cmd_cb = nan_serialized_cb;
307 	cmd.umac_cmd = msg->bodyptr;
308 	cmd.source = WLAN_UMAC_COMP_NAN;
309 	cmd.is_high_priority = false;
310 	cmd.cmd_timeout_duration = NAN_SER_CMD_TIMEOUT;
311 	nan_debug("cmd_type: %d", cmd.cmd_type);
312 	cmd.is_blocking = true;
313 
314 	status = wlan_serialization_request(&cmd);
315 	/* following is TBD */
316 	if (status != WLAN_SER_CMD_ACTIVE && status != WLAN_SER_CMD_PENDING) {
317 		nan_err("unable to serialize command");
318 		wlan_objmgr_vdev_release_ref(cmd.vdev, WLAN_NAN_ID);
319 		qdf_mem_free(msg->bodyptr);
320 		msg->bodyptr = NULL;
321 		return QDF_STATUS_E_INVAL;
322 	}
323 	return QDF_STATUS_SUCCESS;
324 }
325 
326 static QDF_STATUS
nan_increment_ndp_sessions(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_ndi_mac,struct nan_datapath_channel_info * ndp_chan_info)327 nan_increment_ndp_sessions(struct wlan_objmgr_psoc *psoc,
328 			   struct qdf_mac_addr *peer_ndi_mac,
329 			   struct nan_datapath_channel_info *ndp_chan_info)
330 {
331 	struct wlan_objmgr_peer *peer;
332 	struct nan_peer_priv_obj *peer_nan_obj;
333 
334 	peer = wlan_objmgr_get_peer_by_mac(psoc,
335 					   peer_ndi_mac->bytes,
336 					   WLAN_NAN_ID);
337 
338 	if (!peer) {
339 		nan_err("peer object is null");
340 		return QDF_STATUS_E_NULL_VALUE;
341 	}
342 
343 	peer_nan_obj = nan_get_peer_priv_obj(peer);
344 	if (!peer_nan_obj) {
345 		nan_err("peer_nan_obj is null");
346 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
347 		return QDF_STATUS_E_NULL_VALUE;
348 	}
349 	qdf_spin_lock_bh(&peer_nan_obj->lock);
350 
351 	/*
352 	 * Store the first channel info in NDP Confirm as the home channel info
353 	 * and store it in the peer private object.
354 	 */
355 	if (!peer_nan_obj->active_ndp_sessions)
356 		qdf_mem_copy(&peer_nan_obj->home_chan_info, ndp_chan_info,
357 			     sizeof(struct nan_datapath_channel_info));
358 
359 	peer_nan_obj->active_ndp_sessions++;
360 	nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT,
361 		  peer_nan_obj->active_ndp_sessions,
362 		  QDF_MAC_ADDR_REF(peer_ndi_mac->bytes));
363 	qdf_spin_unlock_bh(&peer_nan_obj->lock);
364 	wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
365 
366 	return QDF_STATUS_SUCCESS;
367 }
368 
nan_decrement_ndp_sessions(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * peer_ndi_mac)369 static QDF_STATUS nan_decrement_ndp_sessions(struct wlan_objmgr_psoc *psoc,
370 					     struct qdf_mac_addr *peer_ndi_mac)
371 {
372 	struct wlan_objmgr_peer *peer;
373 	struct nan_peer_priv_obj *peer_nan_obj;
374 
375 	peer = wlan_objmgr_get_peer_by_mac(psoc,
376 					   peer_ndi_mac->bytes,
377 					   WLAN_NAN_ID);
378 
379 	if (!peer) {
380 		nan_err("peer object is null");
381 		return QDF_STATUS_E_NULL_VALUE;
382 	}
383 
384 	peer_nan_obj = nan_get_peer_priv_obj(peer);
385 	if (!peer_nan_obj) {
386 		nan_err("peer_nan_obj is null");
387 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
388 		return QDF_STATUS_E_NULL_VALUE;
389 	}
390 
391 	qdf_spin_lock_bh(&peer_nan_obj->lock);
392 	if (!peer_nan_obj->active_ndp_sessions) {
393 		qdf_spin_unlock_bh(&peer_nan_obj->lock);
394 		nan_err("Active NDP sessions already zero!");
395 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
396 		return QDF_STATUS_E_FAILURE;
397 	}
398 	peer_nan_obj->active_ndp_sessions--;
399 	nan_debug("Number of active session = %d for peer:"QDF_MAC_ADDR_FMT,
400 		  peer_nan_obj->active_ndp_sessions,
401 		  QDF_MAC_ADDR_REF(peer_ndi_mac->bytes));
402 	qdf_spin_unlock_bh(&peer_nan_obj->lock);
403 	wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
404 
405 	return QDF_STATUS_SUCCESS;
406 }
407 
408 static QDF_STATUS
ndi_remove_and_update_primary_connection(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)409 ndi_remove_and_update_primary_connection(struct wlan_objmgr_psoc *psoc,
410 					 struct wlan_objmgr_vdev *vdev)
411 {
412 	struct nan_vdev_priv_obj *vdev_nan_obj;
413 	struct nan_psoc_priv_obj *psoc_nan_obj;
414 	struct nan_peer_priv_obj *peer_nan_obj = NULL;
415 	struct wlan_objmgr_peer *peer, *peer_next;
416 	qdf_list_t *peer_list;
417 	void (*nan_conc_callback)(void);
418 
419 
420 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
421 	if (!psoc_nan_obj) {
422 		nan_err("Invalid psoc nan private obj");
423 		return QDF_STATUS_E_NULL_VALUE;
424 	}
425 
426 	vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
427 	if (!vdev_nan_obj) {
428 		nan_err("Invalid vdev nan private obj");
429 		return QDF_STATUS_E_NULL_VALUE;
430 	}
431 
432 	peer_list = &vdev->vdev_objmgr.wlan_peer_list;
433 	if (!peer_list) {
434 		nan_err("Peer list for vdev obj is NULL");
435 		return QDF_STATUS_E_NULL_VALUE;
436 	}
437 
438 	peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
439 						    WLAN_NAN_ID);
440 
441 	while (peer) {
442 		peer_nan_obj = nan_get_peer_priv_obj(peer);
443 		if (!peer_nan_obj)
444 			nan_err("NAN peer object for Peer " QDF_MAC_ADDR_FMT " is NULL",
445 				QDF_MAC_ADDR_REF(wlan_peer_get_macaddr(peer)));
446 		else if (peer_nan_obj->active_ndp_sessions)
447 			break;
448 
449 		peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
450 								   peer_list,
451 								   peer,
452 								   WLAN_NAN_ID);
453 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
454 		peer = peer_next;
455 	}
456 
457 	if (!peer && NDI_CONCURRENCY_SUPPORTED(psoc)) {
458 		policy_mgr_decr_session_set_pcl(psoc, QDF_NDI_MODE,
459 						wlan_vdev_get_id(vdev));
460 		vdev_nan_obj->ndp_init_done = false;
461 
462 		nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
463 		if (nan_conc_callback)
464 			nan_conc_callback();
465 
466 		return QDF_STATUS_SUCCESS;
467 	}
468 
469 	if (peer_nan_obj && NDI_CONCURRENCY_SUPPORTED(psoc)) {
470 		psoc_nan_obj->cb_obj.update_ndi_conn(wlan_vdev_get_id(vdev),
471 						 &peer_nan_obj->home_chan_info);
472 		policy_mgr_update_connection_info(psoc, wlan_vdev_get_id(vdev));
473 		qdf_mem_copy(vdev_nan_obj->primary_peer_mac.bytes,
474 			     wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
475 		policy_mgr_check_n_start_opportunistic_timer(psoc);
476 	}
477 
478 	if (peer)
479 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
480 
481 	return QDF_STATUS_SUCCESS;
482 }
483 
484 static QDF_STATUS
ndi_update_ndp_session(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * peer_ndi_mac,struct nan_datapath_channel_info * ndp_chan_info)485 ndi_update_ndp_session(struct wlan_objmgr_vdev *vdev,
486 		       struct qdf_mac_addr *peer_ndi_mac,
487 		       struct nan_datapath_channel_info *ndp_chan_info)
488 {
489 	struct wlan_objmgr_psoc *psoc;
490 	struct wlan_objmgr_peer *peer;
491 	struct nan_psoc_priv_obj *psoc_nan_obj;
492 	struct nan_vdev_priv_obj *vdev_nan_obj;
493 	struct nan_peer_priv_obj *peer_nan_obj;
494 
495 	psoc = wlan_vdev_get_psoc(vdev);
496 
497 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
498 	if (!psoc_nan_obj) {
499 		nan_err("psoc_nan_obj is null");
500 		return QDF_STATUS_E_NULL_VALUE;
501 	}
502 
503 	vdev_nan_obj = nan_get_vdev_priv_obj(vdev);
504 	if (!vdev_nan_obj) {
505 		nan_err("NAN vdev private object is NULL");
506 		return QDF_STATUS_E_NULL_VALUE;
507 	}
508 
509 	peer = wlan_objmgr_get_peer_by_mac(psoc,
510 					   peer_ndi_mac->bytes,
511 					   WLAN_NAN_ID);
512 
513 	if (!peer) {
514 		nan_err("peer object is null");
515 		return QDF_STATUS_E_NULL_VALUE;
516 	}
517 
518 	peer_nan_obj = nan_get_peer_priv_obj(peer);
519 	if (!peer_nan_obj) {
520 		nan_err("peer_nan_obj is null");
521 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
522 		return QDF_STATUS_E_NULL_VALUE;
523 	}
524 
525 	qdf_spin_lock_bh(&peer_nan_obj->lock);
526 	qdf_mem_copy(&peer_nan_obj->home_chan_info, ndp_chan_info,
527 		     sizeof(*ndp_chan_info));
528 	psoc_nan_obj->cb_obj.update_ndi_conn(wlan_vdev_get_id(vdev),
529 					     &peer_nan_obj->home_chan_info);
530 	qdf_spin_unlock_bh(&peer_nan_obj->lock);
531 	wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
532 
533 	if (qdf_is_macaddr_equal(&vdev_nan_obj->primary_peer_mac,
534 				 peer_ndi_mac)) {
535 		/* TODO: Update policy mgr with connection info */
536 	}
537 	return QDF_STATUS_SUCCESS;
538 }
539 
540 static QDF_STATUS
ndi_update_policy_mgr_conn_table(struct nan_datapath_confirm_event * confirm,struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)541 ndi_update_policy_mgr_conn_table(struct nan_datapath_confirm_event *confirm,
542 				 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
543 {
544 	QDF_STATUS status = QDF_STATUS_SUCCESS;
545 
546 	if (policy_mgr_is_hw_dbs_capable(psoc)) {
547 		status = policy_mgr_update_and_wait_for_connection_update(psoc,
548 					vdev_id, confirm->ch[0].freq,
549 					POLICY_MGR_UPDATE_REASON_NDP_UPDATE);
550 		if (QDF_IS_STATUS_ERROR(status)) {
551 			nan_err("Failed to set or wait for HW mode change");
552 			return status;
553 		}
554 	}
555 
556 	policy_mgr_incr_active_session(psoc, QDF_NDI_MODE, vdev_id);
557 
558 	return status;
559 }
560 
nan_handle_confirm(struct nan_datapath_confirm_event * confirm)561 static QDF_STATUS nan_handle_confirm(struct nan_datapath_confirm_event *confirm)
562 {
563 	uint8_t vdev_id;
564 	struct wlan_objmgr_psoc *psoc;
565 	struct nan_psoc_priv_obj *psoc_nan_obj;
566 	struct nan_vdev_priv_obj *vdev_nan_obj;
567 	struct wlan_objmgr_peer *peer;
568 	void (*nan_conc_callback)(void);
569 
570 	vdev_id = wlan_vdev_get_id(confirm->vdev);
571 	psoc = wlan_vdev_get_psoc(confirm->vdev);
572 	if (!psoc) {
573 		nan_err("psoc is null");
574 		return QDF_STATUS_E_NULL_VALUE;
575 	}
576 
577 	peer = wlan_objmgr_get_peer_by_mac(psoc,
578 					   confirm->peer_ndi_mac_addr.bytes,
579 					   WLAN_NAN_ID);
580 	if (!peer && confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT) {
581 		nan_debug("Drop NDP confirm as peer isn't available");
582 		return QDF_STATUS_E_NULL_VALUE;
583 	}
584 
585 	if (peer)
586 		wlan_objmgr_peer_release_ref(peer, WLAN_NAN_ID);
587 
588 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
589 	if (!psoc_nan_obj) {
590 		nan_err("psoc_nan_obj is null");
591 		return QDF_STATUS_E_NULL_VALUE;
592 	}
593 
594 	vdev_nan_obj = nan_get_vdev_priv_obj(confirm->vdev);
595 	if (!vdev_nan_obj) {
596 		nan_err("vdev_nan_obj is null");
597 		return QDF_STATUS_E_NULL_VALUE;
598 	}
599 
600 	if (confirm->rsp_code != NAN_DATAPATH_RESPONSE_ACCEPT &&
601 	    confirm->num_active_ndps_on_peer == 0) {
602 		/*
603 		 * This peer was created at ndp_indication but
604 		 * confirm failed, so it needs to be deleted
605 		 */
606 		nan_err("NDP confirm with reject and no active ndp sessions. deleting peer: "QDF_MAC_ADDR_FMT" on vdev_id: %d",
607 			QDF_MAC_ADDR_REF(confirm->peer_ndi_mac_addr.bytes),
608 			vdev_id);
609 		psoc_nan_obj->cb_obj.delete_peers_by_addr(vdev_id,
610 						confirm->peer_ndi_mac_addr);
611 	}
612 
613 	/* Increment NDP sessions for the Peer */
614 	if (confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT)
615 		nan_increment_ndp_sessions(psoc, &confirm->peer_ndi_mac_addr,
616 					   &confirm->ch[0]);
617 
618 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, confirm->vdev,
619 						     NDP_CONFIRM, confirm);
620 
621 	if (confirm->rsp_code == NAN_DATAPATH_RESPONSE_ACCEPT &&
622 	    !vdev_nan_obj->ndp_init_done) {
623 		/*
624 		 * If this is the NDI's first NDP, store the NDP instance in
625 		 * vdev object as its primary connection. If this instance ends
626 		 * the second NDP should take its place.
627 		 */
628 		qdf_mem_copy(vdev_nan_obj->primary_peer_mac.bytes,
629 			     &confirm->peer_ndi_mac_addr, QDF_MAC_ADDR_SIZE);
630 
631 		psoc_nan_obj->cb_obj.update_ndi_conn(vdev_id, &confirm->ch[0]);
632 
633 		if (NAN_CONCURRENCY_SUPPORTED(psoc)) {
634 			ndi_update_policy_mgr_conn_table(confirm, psoc,
635 							 vdev_id);
636 			vdev_nan_obj->ndp_init_done = true;
637 
638 			nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
639 			if (nan_conc_callback)
640 				nan_conc_callback();
641 		}
642 	}
643 
644 	return QDF_STATUS_SUCCESS;
645 }
646 
nan_handle_initiator_rsp(struct nan_datapath_initiator_rsp * rsp,struct wlan_objmgr_vdev ** vdev)647 static QDF_STATUS nan_handle_initiator_rsp(
648 				struct nan_datapath_initiator_rsp *rsp,
649 				struct wlan_objmgr_vdev **vdev)
650 {
651 	struct wlan_objmgr_psoc *psoc;
652 	struct nan_psoc_priv_obj *psoc_nan_obj;
653 
654 	*vdev = rsp->vdev;
655 	psoc = wlan_vdev_get_psoc(rsp->vdev);
656 	if (!psoc) {
657 		nan_err("psoc is null");
658 		return QDF_STATUS_E_NULL_VALUE;
659 	}
660 
661 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
662 	if (!psoc_nan_obj) {
663 		nan_err("psoc_nan_obj is null");
664 		return QDF_STATUS_E_NULL_VALUE;
665 	}
666 
667 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
668 						     NDP_INITIATOR_RSP, rsp);
669 
670 	return QDF_STATUS_SUCCESS;
671 }
672 
nan_handle_ndp_ind(struct nan_datapath_indication_event * ndp_ind)673 static QDF_STATUS nan_handle_ndp_ind(
674 				struct nan_datapath_indication_event *ndp_ind)
675 {
676 	uint8_t vdev_id;
677 	struct wlan_objmgr_psoc *psoc;
678 	QDF_STATUS status = QDF_STATUS_SUCCESS;
679 	struct nan_psoc_priv_obj *psoc_nan_obj;
680 
681 	vdev_id = wlan_vdev_get_id(ndp_ind->vdev);
682 	psoc = wlan_vdev_get_psoc(ndp_ind->vdev);
683 	if (!psoc) {
684 		nan_err("psoc is null");
685 		return QDF_STATUS_E_NULL_VALUE;
686 	}
687 
688 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
689 	if (!psoc_nan_obj) {
690 		nan_err("psoc_nan_obj is null");
691 		return QDF_STATUS_E_NULL_VALUE;
692 	}
693 
694 	nan_debug("role: %d, vdev: %d, csid: %d, peer_mac_addr "
695 		QDF_MAC_ADDR_FMT,
696 		ndp_ind->role, vdev_id, ndp_ind->ncs_sk_type,
697 		QDF_MAC_ADDR_REF(ndp_ind->peer_mac_addr.bytes));
698 
699 	if ((ndp_ind->role == NAN_DATAPATH_ROLE_INITIATOR) ||
700 	    ((NAN_DATAPATH_ROLE_RESPONDER == ndp_ind->role) &&
701 	    (NAN_DATAPATH_ACCEPT_POLICY_ALL == ndp_ind->policy))) {
702 		status = psoc_nan_obj->cb_obj.add_ndi_peer(vdev_id,
703 						ndp_ind->peer_mac_addr);
704 		if (QDF_IS_STATUS_ERROR(status)) {
705 			nan_err("Couldn't add ndi peer, ndp_role: %d",
706 				ndp_ind->role);
707 			return status;
708 		}
709 	}
710 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc,
711 						     ndp_ind->vdev,
712 						     NDP_INDICATION,
713 						     ndp_ind);
714 
715 	return status;
716 }
717 
nan_handle_responder_rsp(struct nan_datapath_responder_rsp * rsp,struct wlan_objmgr_vdev ** vdev)718 static QDF_STATUS nan_handle_responder_rsp(
719 				struct nan_datapath_responder_rsp *rsp,
720 				struct wlan_objmgr_vdev **vdev)
721 {
722 	struct wlan_objmgr_psoc *psoc;
723 	QDF_STATUS status = QDF_STATUS_SUCCESS;
724 	struct nan_psoc_priv_obj *psoc_nan_obj;
725 
726 	*vdev = rsp->vdev;
727 	psoc = wlan_vdev_get_psoc(rsp->vdev);
728 	if (!psoc) {
729 		nan_err("psoc is null");
730 		return QDF_STATUS_E_NULL_VALUE;
731 	}
732 
733 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
734 	if (!psoc_nan_obj) {
735 		nan_err("psoc_nan_obj is null");
736 		return QDF_STATUS_E_NULL_VALUE;
737 	}
738 
739 	if (QDF_IS_STATUS_SUCCESS(rsp->status) && rsp->create_peer) {
740 		status = psoc_nan_obj->cb_obj.add_ndi_peer(
741 						wlan_vdev_get_id(rsp->vdev),
742 						rsp->peer_mac_addr);
743 		if (QDF_IS_STATUS_ERROR(status)) {
744 			nan_err("Couldn't add ndi peer");
745 			rsp->status = QDF_STATUS_E_FAILURE;
746 		}
747 	}
748 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
749 						     NDP_RESPONDER_RSP, rsp);
750 
751 	return QDF_STATUS_SUCCESS;
752 }
753 
nan_handle_ndp_end_rsp(struct nan_datapath_end_rsp_event * rsp,struct wlan_objmgr_vdev ** vdev)754 static QDF_STATUS nan_handle_ndp_end_rsp(
755 			struct nan_datapath_end_rsp_event *rsp,
756 			struct wlan_objmgr_vdev **vdev)
757 {
758 	struct wlan_objmgr_psoc *psoc;
759 	struct nan_psoc_priv_obj *psoc_nan_obj;
760 	struct osif_request *request;
761 
762 	*vdev = rsp->vdev;
763 	psoc = wlan_vdev_get_psoc(rsp->vdev);
764 	if (!psoc) {
765 		nan_err("psoc is NULL");
766 		return QDF_STATUS_E_NULL_VALUE;
767 	}
768 
769 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
770 	if (!psoc_nan_obj) {
771 		nan_err("psoc_nan_obj is NULL");
772 		return QDF_STATUS_E_NULL_VALUE;
773 	}
774 
775 	/* Unblock the wait here if NDP_END request is a failure */
776 	if (rsp->status != 0) {
777 		request = osif_request_get(psoc_nan_obj->ndp_request_ctx);
778 		if (request) {
779 			osif_request_complete(request);
780 			osif_request_put(request);
781 		}
782 	}
783 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, rsp->vdev,
784 						     NDP_END_RSP, rsp);
785 
786 	return QDF_STATUS_SUCCESS;
787 }
788 
nan_handle_end_ind(struct nan_datapath_end_indication_event * ind)789 static QDF_STATUS nan_handle_end_ind(
790 				struct nan_datapath_end_indication_event *ind)
791 {
792 	uint32_t i;
793 	struct wlan_objmgr_psoc *psoc;
794 	struct nan_psoc_priv_obj *psoc_nan_obj;
795 	struct wlan_objmgr_vdev *vdev_itr;
796 	struct nan_vdev_priv_obj *vdev_nan_obj;
797 	struct osif_request *request;
798 
799 	psoc = wlan_vdev_get_psoc(ind->vdev);
800 	if (!psoc) {
801 		nan_err("psoc is NULL");
802 		return QDF_STATUS_E_NULL_VALUE;
803 	}
804 
805 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
806 	if (!psoc_nan_obj) {
807 		nan_err("psoc_nan_obj is NULL");
808 		return QDF_STATUS_E_NULL_VALUE;
809 	}
810 
811 	/* Decrement NDP sessions for all Peers in the event */
812 	for (i = 0; i < ind->num_ndp_ids; i++)
813 		nan_decrement_ndp_sessions(psoc,
814 					   &ind->ndp_map[i].peer_ndi_mac_addr);
815 
816 	for (i = 0; i < ind->num_ndp_ids; i++) {
817 		vdev_itr = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
818 							ind->ndp_map[i].vdev_id,
819 							WLAN_NAN_ID);
820 		if (!vdev_itr) {
821 			nan_err("NAN vdev object is NULL");
822 			continue;
823 		}
824 
825 		vdev_nan_obj = nan_get_vdev_priv_obj(vdev_itr);
826 		if (!vdev_nan_obj) {
827 			wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
828 			nan_err("NAN vdev private object is NULL");
829 			continue;
830 		}
831 
832 		if (qdf_is_macaddr_equal(&vdev_nan_obj->primary_peer_mac,
833 					 &ind->ndp_map[i].peer_ndi_mac_addr))
834 			ndi_remove_and_update_primary_connection(psoc,
835 								 vdev_itr);
836 
837 		wlan_objmgr_vdev_release_ref(vdev_itr, WLAN_NAN_ID);
838 	}
839 
840 	psoc_nan_obj->cb_obj.ndp_delete_peers(ind->ndp_map, ind->num_ndp_ids);
841 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
842 						     NDP_END_IND, ind);
843 
844 	/* Unblock the NDP_END wait */
845 	request = osif_request_get(psoc_nan_obj->ndp_request_ctx);
846 	if (request) {
847 		osif_request_complete(request);
848 		osif_request_put(request);
849 	}
850 
851 	return QDF_STATUS_SUCCESS;
852 }
853 
nan_handle_enable_rsp(struct nan_event_params * nan_event)854 static QDF_STATUS nan_handle_enable_rsp(struct nan_event_params *nan_event)
855 {
856 	struct nan_psoc_priv_obj *psoc_nan_obj;
857 	struct wlan_objmgr_psoc *psoc;
858 	QDF_STATUS status;
859 	void (*call_back)(void *cookie);
860 	uint8_t vdev_id;
861 	void (*nan_conc_callback)(void);
862 
863 	psoc = nan_event->psoc;
864 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
865 	if (!psoc_nan_obj) {
866 		nan_err("psoc_nan_obj is NULL");
867 		return QDF_STATUS_E_NULL_VALUE;
868 	}
869 
870 	if (nan_event->is_nan_enable_success) {
871 		status = nan_set_discovery_state(psoc, NAN_DISC_ENABLED);
872 
873 		if (QDF_IS_STATUS_SUCCESS(status)) {
874 			psoc_nan_obj->nan_disc_mac_id = nan_event->mac_id;
875 			vdev_id = nan_event->vdev_id;
876 			if (!ucfg_nan_is_vdev_creation_allowed(psoc)) {
877 				vdev_id = NAN_PSEUDO_VDEV_ID;
878 			} else if (vdev_id >= WLAN_MAX_VDEVS) {
879 				nan_err("Invalid NAN vdev_id: %u", vdev_id);
880 				goto fail;
881 			}
882 			nan_debug("NAN vdev_id: %u", vdev_id);
883 			policy_mgr_incr_active_session(psoc, QDF_NAN_DISC_MODE,
884 						       vdev_id);
885 			policy_mgr_process_force_scc_for_nan(psoc);
886 
887 		} else {
888 			/*
889 			 * State set to DISABLED OR DISABLE_IN_PROGRESS, try to
890 			 * restore the single MAC mode.
891 			 */
892 			psoc_nan_obj->nan_social_ch_2g_freq = 0;
893 			psoc_nan_obj->nan_social_ch_5g_freq = 0;
894 			policy_mgr_check_n_start_opportunistic_timer(psoc);
895 		}
896 		goto done;
897 	} else {
898 		nan_info("NAN enable has failed");
899 		/* NAN Enable has failed, restore changes */
900 		goto fail;
901 	}
902 
903 fail:
904 	psoc_nan_obj->nan_social_ch_2g_freq = 0;
905 	psoc_nan_obj->nan_social_ch_5g_freq = 0;
906 	nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
907 	if (ucfg_is_nan_dbs_supported(psoc))
908 		policy_mgr_check_n_start_opportunistic_timer(psoc);
909 
910 	/*
911 	 * If FW respond with NAN enable failure, then TDLS should be enable
912 	 * again if there is TDLS connection exist earlier.
913 	 * decrement the active TDLS session.
914 	 */
915 	ucfg_tdls_notify_connect_failure(psoc);
916 
917 done:
918 	nan_cstats_log_nan_enable_resp_evt(nan_event);
919 
920 	nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
921 	if (nan_conc_callback)
922 		nan_conc_callback();
923 	call_back = psoc_nan_obj->cb_obj.ucfg_nan_request_process_cb;
924 	if (call_back)
925 		call_back(psoc_nan_obj->nan_disc_request_ctx);
926 
927 	return QDF_STATUS_SUCCESS;
928 }
929 
nan_disable_cleanup(struct wlan_objmgr_psoc * psoc)930 QDF_STATUS nan_disable_cleanup(struct wlan_objmgr_psoc *psoc)
931 {
932 	struct nan_psoc_priv_obj *psoc_nan_obj;
933 	QDF_STATUS status;
934 	uint8_t vdev_id;
935 	void (*nan_conc_callback)(void);
936 
937 	if (!psoc) {
938 		nan_err("psoc is NULL");
939 		return QDF_STATUS_E_NULL_VALUE;
940 	}
941 
942 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
943 	if (!psoc_nan_obj) {
944 		nan_err("psoc_nan_obj is NULL");
945 		return QDF_STATUS_E_NULL_VALUE;
946 	}
947 
948 	status = nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
949 	if (QDF_IS_STATUS_SUCCESS(status)) {
950 		void (*call_back)(void *cookie);
951 
952 		call_back = psoc_nan_obj->cb_obj.ucfg_nan_request_process_cb;
953 		vdev_id = policy_mgr_mode_specific_vdev_id(psoc,
954 							   PM_NAN_DISC_MODE);
955 		nan_debug("NAN vdev_id: %u", vdev_id);
956 		policy_mgr_decr_session_set_pcl(psoc, QDF_NAN_DISC_MODE,
957 						vdev_id);
958 		if (psoc_nan_obj->is_explicit_disable && call_back)
959 			call_back(psoc_nan_obj->nan_disc_request_ctx);
960 
961 		nan_handle_emlsr_concurrency(psoc, false);
962 		policy_mgr_nan_sap_post_disable_conc_check(psoc);
963 		nan_cstats_log_nan_disable_resp_evt(vdev_id, psoc);
964 	} else {
965 		/* Should not happen, NAN state can always be disabled */
966 		nan_err("Cannot set NAN state to disabled!");
967 		return QDF_STATUS_E_FAILURE;
968 	}
969 	nan_conc_callback = psoc_nan_obj->cb_obj.nan_concurrency_update;
970 	if (nan_conc_callback)
971 		nan_conc_callback();
972 
973 	return status;
974 }
975 
nan_handle_disable_ind(struct nan_event_params * nan_event)976 static QDF_STATUS nan_handle_disable_ind(struct nan_event_params *nan_event)
977 {
978 	return nan_disable_cleanup(nan_event->psoc);
979 }
980 
nan_handle_schedule_update(struct nan_datapath_sch_update_event * ind)981 static QDF_STATUS nan_handle_schedule_update(
982 				struct nan_datapath_sch_update_event *ind)
983 {
984 	struct wlan_objmgr_psoc *psoc;
985 	struct nan_psoc_priv_obj *psoc_nan_obj;
986 
987 	psoc = wlan_vdev_get_psoc(ind->vdev);
988 	if (!psoc) {
989 		nan_err("psoc is NULL");
990 		return QDF_STATUS_E_NULL_VALUE;
991 	}
992 
993 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
994 	if (!psoc_nan_obj) {
995 		nan_err("psoc_nan_obj is NULL");
996 		return QDF_STATUS_E_NULL_VALUE;
997 	}
998 
999 	ndi_update_ndp_session(ind->vdev, &ind->peer_addr, &ind->ch[0]);
1000 	psoc_nan_obj->cb_obj.os_if_ndp_event_handler(psoc, ind->vdev,
1001 						     NDP_SCHEDULE_UPDATE, ind);
1002 
1003 	return QDF_STATUS_SUCCESS;
1004 }
1005 
1006 /**
1007  * nan_handle_host_update() - extract the vdev from host event
1008  * @evt: Event data received from firmware
1009  * @vdev: pointer to vdev
1010  *
1011  * Return: none
1012  */
nan_handle_host_update(struct nan_datapath_host_event * evt,struct wlan_objmgr_vdev ** vdev)1013 static void nan_handle_host_update(struct nan_datapath_host_event *evt,
1014 					 struct wlan_objmgr_vdev **vdev)
1015 {
1016 	*vdev = evt->vdev;
1017 }
1018 
nan_discovery_event_handler(struct scheduler_msg * msg)1019 QDF_STATUS nan_discovery_event_handler(struct scheduler_msg *msg)
1020 {
1021 	struct nan_event_params *nan_event;
1022 	struct nan_psoc_priv_obj *psoc_nan_obj;
1023 
1024 	if (!msg || !msg->bodyptr) {
1025 		nan_err("msg body is null");
1026 		return QDF_STATUS_E_NULL_VALUE;
1027 	}
1028 
1029 	nan_event = msg->bodyptr;
1030 	if (!nan_event->psoc) {
1031 		nan_err("psoc is NULL");
1032 		return QDF_STATUS_E_NULL_VALUE;
1033 	}
1034 
1035 	psoc_nan_obj = nan_get_psoc_priv_obj(nan_event->psoc);
1036 	if (!psoc_nan_obj) {
1037 		nan_err("psoc_nan_obj is null");
1038 		return QDF_STATUS_E_NULL_VALUE;
1039 	}
1040 
1041 	switch (msg->type) {
1042 	case nan_event_id_enable_rsp:
1043 		nan_handle_enable_rsp(nan_event);
1044 		break;
1045 	case nan_event_id_disable_ind:
1046 		nan_handle_disable_ind(nan_event);
1047 		break;
1048 	case nan_event_id_generic_rsp:
1049 	case nan_event_id_error_rsp:
1050 		break;
1051 	default:
1052 		nan_err("Unknown event ID type - %d", msg->type);
1053 		break;
1054 	}
1055 
1056 	psoc_nan_obj->cb_obj.os_if_nan_event_handler(nan_event);
1057 
1058 	return QDF_STATUS_SUCCESS;
1059 }
1060 
nan_datapath_event_handler(struct scheduler_msg * pe_msg)1061 QDF_STATUS nan_datapath_event_handler(struct scheduler_msg *pe_msg)
1062 {
1063 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1064 	struct wlan_serialization_queued_cmd_info cmd;
1065 
1066 	cmd.requestor = WLAN_UMAC_COMP_NAN;
1067 	cmd.cmd_id = 0;
1068 	cmd.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
1069 	cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
1070 
1071 	if (!pe_msg->bodyptr) {
1072 		nan_err("msg body is null");
1073 		return QDF_STATUS_E_NULL_VALUE;
1074 	}
1075 
1076 	switch (pe_msg->type) {
1077 	case NDP_CONFIRM: {
1078 		nan_handle_confirm(pe_msg->bodyptr);
1079 		break;
1080 	}
1081 	case NDP_INITIATOR_RSP: {
1082 		nan_handle_initiator_rsp(pe_msg->bodyptr, &cmd.vdev);
1083 		cmd.cmd_type = WLAN_SER_CMD_NDP_INIT_REQ;
1084 		wlan_serialization_remove_cmd(&cmd);
1085 		break;
1086 	}
1087 	case NDP_INDICATION: {
1088 		nan_handle_ndp_ind(pe_msg->bodyptr);
1089 		break;
1090 	}
1091 	case NDP_RESPONDER_RSP:
1092 		nan_handle_responder_rsp(pe_msg->bodyptr, &cmd.vdev);
1093 		cmd.cmd_type = WLAN_SER_CMD_NDP_RESP_REQ;
1094 		wlan_serialization_remove_cmd(&cmd);
1095 		break;
1096 	case NDP_END_RSP:
1097 		nan_handle_ndp_end_rsp(pe_msg->bodyptr, &cmd.vdev);
1098 		cmd.cmd_type = WLAN_SER_CMD_NDP_DATA_END_INIT_REQ;
1099 		wlan_serialization_remove_cmd(&cmd);
1100 		break;
1101 	case NDP_END_IND:
1102 		nan_handle_end_ind(pe_msg->bodyptr);
1103 		break;
1104 	case NDP_SCHEDULE_UPDATE:
1105 		nan_handle_schedule_update(pe_msg->bodyptr);
1106 		break;
1107 	case NDP_HOST_UPDATE:
1108 		nan_handle_host_update(pe_msg->bodyptr, &cmd.vdev);
1109 		cmd.cmd_type = WLAN_SER_CMD_NDP_END_ALL_REQ;
1110 		wlan_serialization_remove_cmd(&cmd);
1111 		break;
1112 	default:
1113 		nan_alert("Unhandled NDP event: %d", pe_msg->type);
1114 		status = QDF_STATUS_E_NOSUPPORT;
1115 		break;
1116 	}
1117 	return status;
1118 }
1119 
nan_is_enable_allowed(struct wlan_objmgr_psoc * psoc,uint32_t nan_ch_freq,uint8_t vdev_id)1120 bool nan_is_enable_allowed(struct wlan_objmgr_psoc *psoc, uint32_t nan_ch_freq,
1121 			   uint8_t vdev_id)
1122 {
1123 	if (!psoc) {
1124 		nan_err("psoc object object is NULL");
1125 		return false;
1126 	}
1127 
1128 	return (NAN_DISC_DISABLED == nan_get_discovery_state(psoc) &&
1129 		policy_mgr_allow_concurrency(psoc, PM_NAN_DISC_MODE,
1130 					     nan_ch_freq, HW_MODE_20_MHZ,
1131 					     0, vdev_id));
1132 }
1133 
nan_is_disc_active(struct wlan_objmgr_psoc * psoc)1134 bool nan_is_disc_active(struct wlan_objmgr_psoc *psoc)
1135 {
1136 	if (!psoc) {
1137 		nan_err("psoc object object is NULL");
1138 		return false;
1139 	}
1140 
1141 	return (NAN_DISC_ENABLED == nan_get_discovery_state(psoc) ||
1142 		NAN_DISC_ENABLE_IN_PROGRESS == nan_get_discovery_state(psoc));
1143 }
1144 
nan_set_hw_mode(struct wlan_objmgr_psoc * psoc,uint32_t nan_ch_freq)1145 static QDF_STATUS nan_set_hw_mode(struct wlan_objmgr_psoc *psoc,
1146 				  uint32_t nan_ch_freq)
1147 {
1148 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1149 	struct wlan_objmgr_pdev *pdev = NULL;
1150 	struct wlan_objmgr_vdev *vdev = NULL;
1151 	uint8_t vdev_id;
1152 
1153 	policy_mgr_stop_opportunistic_timer(psoc);
1154 
1155 	if (policy_mgr_is_hw_mode_change_in_progress(psoc)) {
1156 		status = policy_mgr_wait_for_connection_update(psoc);
1157 		if (!QDF_IS_STATUS_SUCCESS(status)) {
1158 			nan_err("Failed to wait for connection update");
1159 			goto pre_enable_failure;
1160 		}
1161 	}
1162 
1163 	pdev = wlan_objmgr_get_pdev_by_id(psoc, 0, WLAN_NAN_ID);
1164 	if (!pdev) {
1165 		nan_err("null pdev");
1166 		status = QDF_STATUS_E_INVAL;
1167 		goto pre_enable_failure;
1168 	}
1169 
1170 	/* Piggyback on any available vdev for policy manager update */
1171 	vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_NAN_ID);
1172 	if (!vdev) {
1173 		nan_err("No vdev is up yet, unable to proceed!");
1174 		status = QDF_STATUS_E_INVAL;
1175 		goto pre_enable_failure;
1176 	}
1177 	vdev_id = wlan_vdev_get_id(vdev);
1178 	wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
1179 
1180 	status = policy_mgr_update_and_wait_for_connection_update(psoc, vdev_id,
1181 								  nan_ch_freq,
1182 					POLICY_MGR_UPDATE_REASON_NAN_DISCOVERY);
1183 	if (QDF_IS_STATUS_ERROR(status)) {
1184 		nan_err("Failed to set or wait for HW mode change");
1185 		goto pre_enable_failure;
1186 	}
1187 
1188 	if (wlan_util_is_vdev_in_cac_wait(pdev, WLAN_NAN_ID)) {
1189 		nan_err_rl("cac is in progress");
1190 		status = QDF_STATUS_E_FAILURE;
1191 		goto pre_enable_failure;
1192 	}
1193 
1194 pre_enable_failure:
1195 	if (pdev)
1196 		wlan_objmgr_pdev_release_ref(pdev, WLAN_NAN_ID);
1197 
1198 	return status;
1199 }
1200 
nan_handle_emlsr_concurrency(struct wlan_objmgr_psoc * psoc,bool nan_enable)1201 void nan_handle_emlsr_concurrency(struct wlan_objmgr_psoc *psoc,
1202 				  bool nan_enable)
1203 {
1204 	if (nan_enable) {
1205 		/*
1206 		 * Check if any set link is already progress,
1207 		 * wait for it to complete
1208 		 */
1209 		policy_mgr_wait_for_set_link_update(psoc);
1210 
1211 		wlan_handle_emlsr_sta_concurrency(psoc, true, false);
1212 
1213 		/* Wait till rsp is received if NAN enable causes a set link */
1214 		policy_mgr_wait_for_set_link_update(psoc);
1215 	} else {
1216 		wlan_handle_emlsr_sta_concurrency(psoc, false, true);
1217 	}
1218 }
1219 
nan_is_sta_sta_concurrency_present(struct wlan_objmgr_psoc * psoc)1220 bool nan_is_sta_sta_concurrency_present(struct wlan_objmgr_psoc *psoc)
1221 {
1222 	uint32_t sta_cnt;
1223 
1224 	sta_cnt = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
1225 							    NULL);
1226 	/* Allow if STA is not in connected state */
1227 	if (!sta_cnt)
1228 		return false;
1229 
1230 	/*
1231 	 * sta > 2 : (STA + STA + STA) or (ML STA + STA) or (ML STA + ML STA),
1232 	 * STA concurrency will be present.
1233 	 *
1234 	 * ML STA: Although both links would be treated as separate STAs
1235 	 * (sta cnt = 2) from policy mgr perspective, but it is not considered
1236 	 * as STA concurrency
1237 	 */
1238 	if (sta_cnt > 2 ||
1239 	    (sta_cnt == 2 && policy_mgr_is_non_ml_sta_present(psoc)))
1240 		return true;
1241 
1242 	return false;
1243 }
1244 
nan_discovery_pre_enable(struct wlan_objmgr_pdev * pdev,uint32_t nan_ch_freq)1245 QDF_STATUS nan_discovery_pre_enable(struct wlan_objmgr_pdev *pdev,
1246 				    uint32_t nan_ch_freq)
1247 {
1248 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1249 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
1250 
1251 	if (!psoc) {
1252 		nan_err("psoc is null");
1253 		return QDF_STATUS_E_INVAL;
1254 	}
1255 
1256 	status = nan_set_discovery_state(psoc, NAN_DISC_ENABLE_IN_PROGRESS);
1257 
1258 	if (QDF_IS_STATUS_ERROR(status)) {
1259 		nan_err("Unable to set NAN Disc State to ENABLE_IN_PROGRESS");
1260 		goto pre_enable_failure;
1261 	}
1262 
1263 	if ((policy_mgr_get_sap_mode_count(psoc, NULL)) &&
1264 	    !policy_mgr_nan_sap_pre_enable_conc_check(psoc, PM_NAN_DISC_MODE,
1265 						      nan_ch_freq)) {
1266 		nan_debug("NAN not enabled due to concurrency constraints");
1267 		status = QDF_STATUS_E_INVAL;
1268 		goto pre_enable_failure;
1269 	}
1270 
1271 	/*
1272 	 * Reject STA+STA in below case
1273 	 * Non-ML STA: STA+STA+NAN concurrency is not supported
1274 	 */
1275 	if (nan_is_sta_sta_concurrency_present(psoc)) {
1276 		nan_err("STA+STA+NAN concurrency is not allowed");
1277 		status = QDF_STATUS_E_FAILURE;
1278 		goto pre_enable_failure;
1279 	}
1280 
1281 	wlan_p2p_abort_scan(pdev);
1282 
1283 	if (policy_mgr_is_hw_dbs_capable(psoc)) {
1284 		status = nan_set_hw_mode(psoc, nan_ch_freq);
1285 		if (QDF_IS_STATUS_ERROR(status))
1286 			goto pre_enable_failure;
1287 	}
1288 
1289 	nan_handle_emlsr_concurrency(psoc, true);
1290 
1291 	/* Try to teardown TDLS links, but do not wait */
1292 	status = ucfg_tdls_teardown_links(psoc);
1293 	if (QDF_IS_STATUS_ERROR(status))
1294 		nan_err("Failed to teardown TDLS links");
1295 
1296 pre_enable_failure:
1297 	if (QDF_IS_STATUS_ERROR(status))
1298 		nan_set_discovery_state(psoc, NAN_DISC_DISABLED);
1299 
1300 	return status;
1301 }
1302 
nan_discovery_disable_req(struct nan_disable_req * req)1303 static QDF_STATUS nan_discovery_disable_req(struct nan_disable_req *req)
1304 {
1305 	struct nan_psoc_priv_obj *psoc_nan_obj;
1306 	struct wlan_nan_tx_ops *tx_ops;
1307 
1308 	/*
1309 	 * State was already set to Disabled by failed Enable
1310 	 * request OR by the Disable Indication event, drop the
1311 	 * Disable request.
1312 	 */
1313 	if (NAN_DISC_DISABLED == nan_get_discovery_state(req->psoc))
1314 		return QDF_STATUS_SUCCESS;
1315 
1316 	psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1317 	if (!psoc_nan_obj) {
1318 		nan_err("psoc_nan_obj is null");
1319 		return QDF_STATUS_E_NULL_VALUE;
1320 	}
1321 
1322 	tx_ops = &psoc_nan_obj->tx_ops;
1323 	if (!tx_ops->nan_discovery_req_tx) {
1324 		nan_err("NAN Discovery tx op is NULL");
1325 		return QDF_STATUS_E_NULL_VALUE;
1326 	}
1327 
1328 	return tx_ops->nan_discovery_req_tx(req, NAN_DISABLE_REQ);
1329 }
1330 
nan_discovery_enable_req(struct nan_enable_req * req)1331 static QDF_STATUS nan_discovery_enable_req(struct nan_enable_req *req)
1332 {
1333 	struct nan_psoc_priv_obj *psoc_nan_obj;
1334 	struct wlan_nan_tx_ops *tx_ops;
1335 
1336 	/*
1337 	 * State was already set to Disable in progress by a disable request,
1338 	 * drop the Enable request, start opportunistic timer and move back to
1339 	 * the Disabled state.
1340 	 */
1341 	if (NAN_DISC_DISABLE_IN_PROGRESS ==
1342 			nan_get_discovery_state(req->psoc)) {
1343 		policy_mgr_check_n_start_opportunistic_timer(req->psoc);
1344 		return nan_set_discovery_state(req->psoc, NAN_DISC_DISABLED);
1345 	}
1346 
1347 	psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1348 	if (!psoc_nan_obj) {
1349 		nan_err("psoc_nan_obj is null");
1350 		return QDF_STATUS_E_NULL_VALUE;
1351 	}
1352 
1353 	psoc_nan_obj->nan_social_ch_2g_freq = req->social_chan_2g_freq;
1354 	psoc_nan_obj->nan_social_ch_5g_freq = req->social_chan_5g_freq;
1355 
1356 	tx_ops = &psoc_nan_obj->tx_ops;
1357 	if (!tx_ops->nan_discovery_req_tx) {
1358 		nan_err("NAN Discovery tx op is NULL");
1359 		return QDF_STATUS_E_NULL_VALUE;
1360 	}
1361 
1362 	return tx_ops->nan_discovery_req_tx(req, NAN_ENABLE_REQ);
1363 }
1364 
nan_discovery_generic_req(struct nan_generic_req * req)1365 static QDF_STATUS nan_discovery_generic_req(struct nan_generic_req *req)
1366 {
1367 	struct nan_psoc_priv_obj *psoc_nan_obj;
1368 	struct wlan_nan_tx_ops *tx_ops;
1369 
1370 	psoc_nan_obj = nan_get_psoc_priv_obj(req->psoc);
1371 	if (!psoc_nan_obj) {
1372 		nan_err("psoc_nan_obj is null");
1373 		return QDF_STATUS_E_NULL_VALUE;
1374 	}
1375 
1376 	tx_ops = &psoc_nan_obj->tx_ops;
1377 	if (!tx_ops->nan_discovery_req_tx) {
1378 		nan_err("NAN Discovery tx op is NULL");
1379 		return QDF_STATUS_E_NULL_VALUE;
1380 	}
1381 
1382 	return tx_ops->nan_discovery_req_tx(req, NAN_GENERIC_REQ);
1383 }
1384 
nan_discovery_flush_callback(struct scheduler_msg * msg)1385 QDF_STATUS nan_discovery_flush_callback(struct scheduler_msg *msg)
1386 {
1387 	struct wlan_objmgr_psoc *psoc;
1388 
1389 	if (!msg || !msg->bodyptr) {
1390 		nan_err("Null pointer for NAN Discovery message");
1391 		return QDF_STATUS_E_INVAL;
1392 	}
1393 
1394 	switch (msg->type) {
1395 	case NAN_ENABLE_REQ:
1396 		psoc = ((struct nan_enable_req *)msg->bodyptr)->psoc;
1397 		break;
1398 	case NAN_DISABLE_REQ:
1399 		psoc = ((struct nan_disable_req *)msg->bodyptr)->psoc;
1400 		break;
1401 	case NAN_GENERIC_REQ:
1402 		psoc = ((struct nan_generic_req *)msg->bodyptr)->psoc;
1403 		break;
1404 	default:
1405 		nan_err("Unsupported request type: %d", msg->type);
1406 		qdf_mem_free(msg->bodyptr);
1407 		return QDF_STATUS_E_INVAL;
1408 	}
1409 
1410 	wlan_objmgr_psoc_release_ref(psoc, WLAN_NAN_ID);
1411 	qdf_mem_free(msg->bodyptr);
1412 
1413 	return QDF_STATUS_SUCCESS;
1414 }
1415 
nan_discovery_scheduled_handler(struct scheduler_msg * msg)1416 QDF_STATUS nan_discovery_scheduled_handler(struct scheduler_msg *msg)
1417 {
1418 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1419 
1420 	if (!msg || !msg->bodyptr) {
1421 		nan_alert("msg or bodyptr is null");
1422 		return QDF_STATUS_E_NULL_VALUE;
1423 	}
1424 
1425 	switch (msg->type) {
1426 	case NAN_ENABLE_REQ:
1427 		status = nan_discovery_enable_req(msg->bodyptr);
1428 		break;
1429 	case NAN_DISABLE_REQ:
1430 		status = nan_discovery_disable_req(msg->bodyptr);
1431 		break;
1432 	case NAN_GENERIC_REQ:
1433 		status = nan_discovery_generic_req(msg->bodyptr);
1434 		break;
1435 	default:
1436 		nan_err("Unsupported request type: %d", msg->type);
1437 		qdf_mem_free(msg->bodyptr);
1438 		return QDF_STATUS_E_FAILURE;
1439 	}
1440 
1441 	nan_discovery_flush_callback(msg);
1442 	return status;
1443 }
1444 
1445 QDF_STATUS
wlan_nan_get_connection_info(struct wlan_objmgr_psoc * psoc,struct policy_mgr_vdev_entry_info * conn_info)1446 wlan_nan_get_connection_info(struct wlan_objmgr_psoc *psoc,
1447 			     struct policy_mgr_vdev_entry_info *conn_info)
1448 {
1449 	struct nan_psoc_priv_obj *psoc_nan_obj;
1450 
1451 	if (!psoc) {
1452 		nan_err("psoc obj is NULL");
1453 		return QDF_STATUS_E_NULL_VALUE;
1454 	}
1455 
1456 	if (nan_get_discovery_state(psoc) != NAN_DISC_ENABLED) {
1457 		nan_err("NAN State needs to be Enabled");
1458 		return QDF_STATUS_E_INVAL;
1459 	}
1460 
1461 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1462 	if (!psoc_nan_obj) {
1463 		nan_err("psoc_nan_obj is null");
1464 		return QDF_STATUS_E_NULL_VALUE;
1465 	}
1466 
1467 	/* For policy_mgr use NAN mandatory Social ch 6 */
1468 	conn_info->mhz = psoc_nan_obj->nan_social_ch_2g_freq;
1469 	conn_info->mac_id = psoc_nan_obj->nan_disc_mac_id;
1470 	conn_info->chan_width = CH_WIDTH_20MHZ;
1471 	conn_info->type = WMI_VDEV_TYPE_NAN;
1472 
1473 	return QDF_STATUS_SUCCESS;
1474 }
1475 
wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc * psoc)1476 uint32_t wlan_nan_get_disc_5g_ch_freq(struct wlan_objmgr_psoc *psoc)
1477 {
1478 	struct nan_psoc_priv_obj *psoc_nan_obj;
1479 
1480 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1481 	if (!psoc_nan_obj) {
1482 		nan_err("psoc_nan_obj is null");
1483 		return 0;
1484 	}
1485 
1486 	if (nan_get_discovery_state(psoc) != NAN_DISC_ENABLED)
1487 		return 0;
1488 
1489 	return psoc_nan_obj->nan_social_ch_5g_freq;
1490 }
1491 
wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc * psoc)1492 bool wlan_nan_get_sap_conc_support(struct wlan_objmgr_psoc *psoc)
1493 {
1494 	struct nan_psoc_priv_obj *psoc_nan_obj;
1495 
1496 	psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
1497 	if (!psoc_nan_obj) {
1498 		nan_err("psoc_nan_obj is null");
1499 		return 0;
1500 	}
1501 
1502 	return (psoc_nan_obj->nan_caps.nan_sap_supported &&
1503 		ucfg_is_nan_conc_control_supported(psoc));
1504 }
1505 
wlan_nan_is_beamforming_supported(struct wlan_objmgr_psoc * psoc)1506 bool wlan_nan_is_beamforming_supported(struct wlan_objmgr_psoc *psoc)
1507 {
1508 	return ucfg_nan_is_beamforming_supported(psoc);
1509 }
1510 
1511 /*
1512  * The NAN Cluster ID is a MAC address that takes a value from
1513  * 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF and is carried in the A3 field of
1514  * some of the NAN frames. The NAN Cluster ID is randomly chosen by the device
1515  * that initiates the NAN Cluster.
1516  */
1517 #define NAN_CLUSTER_MATCH      "\x50\x6F\x9A\x01"
1518 #define NAN_CLUSTER_MATCH_SIZE 4
1519 
1520 /**
1521  * wlan_nan_is_bssid_in_cluster() - to check whether BSSID is a part of NAN
1522  * cluster
1523  * @bssid: BSSID present in mgmt frame
1524  *
1525  * Return: true if BSSID is part of NAN cluster
1526  */
1527 static
wlan_nan_is_bssid_in_cluster(tSirMacAddr bssid)1528 bool wlan_nan_is_bssid_in_cluster(tSirMacAddr bssid)
1529 {
1530 	if (qdf_mem_cmp(bssid, NAN_CLUSTER_MATCH, NAN_CLUSTER_MATCH_SIZE) == 0)
1531 		return true;
1532 
1533 	return false;
1534 }
1535 
1536 /**
1537  * wlan_nan_extract_vdev_id_from_vdev_list() -retrieve vdev from vdev list in
1538  * pdev and check for nan vdev_id
1539  * @pdev: PDEV object
1540  * @dbg_id: Object Manager ref debug id
1541  *
1542  * API to get NAN vdev_id for only NAN BSSID.
1543  *
1544  * Return: NAN vdev_id
1545  */
1546 static
wlan_nan_extract_vdev_id_from_vdev_list(struct wlan_objmgr_pdev * pdev,wlan_objmgr_ref_dbgid dbg_id)1547 uint8_t wlan_nan_extract_vdev_id_from_vdev_list(struct wlan_objmgr_pdev *pdev,
1548 						wlan_objmgr_ref_dbgid dbg_id)
1549 {
1550 	struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1551 	qdf_list_t *vdev_list = NULL;
1552 	struct wlan_objmgr_vdev *vdev;
1553 	qdf_list_node_t *node = NULL;
1554 	qdf_list_node_t *prev_node = NULL;
1555 	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1556 
1557 	wlan_pdev_obj_lock(pdev);
1558 
1559 	vdev_list = &objmgr->wlan_vdev_list;
1560 	if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS)
1561 		goto end;
1562 
1563 	do {
1564 		vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1565 					vdev_node);
1566 		if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
1567 		    QDF_STATUS_SUCCESS) {
1568 			if (wlan_vdev_mlme_get_opmode(vdev) ==
1569 			    QDF_NAN_DISC_MODE) {
1570 				vdev_id = wlan_vdev_get_id(vdev);
1571 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1572 				goto end;
1573 			}
1574 
1575 			wlan_objmgr_vdev_release_ref(vdev, dbg_id);
1576 		}
1577 
1578 		prev_node = node;
1579 	} while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1580 		 QDF_STATUS_SUCCESS);
1581 end:
1582 	wlan_pdev_obj_unlock(pdev);
1583 
1584 	return vdev_id;
1585 }
1586 
nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev * pdev,tSirMacAddr bssid,wlan_objmgr_ref_dbgid dbg_id)1587 uint8_t nan_get_vdev_id_from_bssid(struct wlan_objmgr_pdev *pdev,
1588 				   tSirMacAddr bssid,
1589 				   wlan_objmgr_ref_dbgid dbg_id)
1590 {
1591 	uint8_t vdev_id = WLAN_UMAC_VDEV_ID_MAX;
1592 
1593 	if (wlan_nan_is_bssid_in_cluster(bssid))
1594 		vdev_id = wlan_nan_extract_vdev_id_from_vdev_list(pdev, dbg_id);
1595 
1596 	return vdev_id;
1597 }
1598