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