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 nan public API function definitions
22 */
23
24 #include "nan_main_i.h"
25 #include "wlan_nan_api.h"
26 #include "target_if_nan.h"
27 #include "nan_public_structs.h"
28 #include "wlan_objmgr_cmn.h"
29 #include "wlan_objmgr_global_obj.h"
30 #include "wlan_objmgr_psoc_obj.h"
31 #include "wlan_objmgr_pdev_obj.h"
32 #include "wlan_objmgr_vdev_obj.h"
33 #include "nan_ucfg_api.h"
34 #include <wlan_mlme_api.h>
35
nan_psoc_obj_created_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)36 static QDF_STATUS nan_psoc_obj_created_notification(
37 struct wlan_objmgr_psoc *psoc, void *arg_list)
38 {
39 QDF_STATUS status = QDF_STATUS_SUCCESS;
40 struct nan_psoc_priv_obj *nan_obj;
41
42 nan_debug("nan_psoc_create_notif called");
43 nan_obj = qdf_mem_malloc(sizeof(*nan_obj));
44 if (!nan_obj)
45 return QDF_STATUS_E_NOMEM;
46
47 qdf_spinlock_create(&nan_obj->lock);
48 status = wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_NAN,
49 nan_obj,
50 QDF_STATUS_SUCCESS);
51 if (QDF_IS_STATUS_ERROR(status)) {
52 nan_alert("obj attach with psoc failed");
53 goto nan_psoc_notif_failed;
54 }
55
56 target_if_nan_register_tx_ops(&nan_obj->tx_ops);
57 target_if_nan_register_rx_ops(&nan_obj->rx_ops);
58
59 return QDF_STATUS_SUCCESS;
60
61 nan_psoc_notif_failed:
62
63 qdf_spinlock_destroy(&nan_obj->lock);
64 qdf_mem_free(nan_obj);
65 return status;
66 }
67
nan_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)68 static QDF_STATUS nan_psoc_obj_destroyed_notification(
69 struct wlan_objmgr_psoc *psoc, void *arg_list)
70 {
71 QDF_STATUS status = QDF_STATUS_SUCCESS;
72 struct nan_psoc_priv_obj *nan_obj = nan_get_psoc_priv_obj(psoc);
73
74 nan_debug("nan_psoc_delete_notif called");
75 if (!nan_obj) {
76 nan_err("nan_obj is NULL");
77 return QDF_STATUS_E_FAULT;
78 }
79
80 status = wlan_objmgr_psoc_component_obj_detach(psoc,
81 WLAN_UMAC_COMP_NAN,
82 nan_obj);
83 if (QDF_IS_STATUS_ERROR(status))
84 nan_err("nan_obj detach failed");
85
86 nan_debug("nan_obj deleted with status %d", status);
87 qdf_spinlock_destroy(&nan_obj->lock);
88 qdf_mem_free(nan_obj);
89
90 return status;
91 }
92
nan_vdev_obj_created_notification(struct wlan_objmgr_vdev * vdev,void * arg_list)93 static QDF_STATUS nan_vdev_obj_created_notification(
94 struct wlan_objmgr_vdev *vdev, void *arg_list)
95 {
96 struct nan_vdev_priv_obj *nan_obj;
97 QDF_STATUS status = QDF_STATUS_SUCCESS;
98 struct wlan_objmgr_psoc *psoc;
99
100 nan_debug("nan_vdev_create_notif called");
101 if (ucfg_is_nan_vdev(vdev)) {
102 psoc = wlan_vdev_get_psoc(vdev);
103 if (!psoc) {
104 nan_err("psoc is NULL");
105 return QDF_STATUS_E_INVAL;
106 }
107 target_if_nan_set_vdev_feature_config(psoc,
108 wlan_vdev_get_id(vdev));
109 }
110 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_NDI_MODE) {
111 nan_debug("not a ndi vdev. do nothing");
112 return QDF_STATUS_SUCCESS;
113 }
114
115 nan_obj = qdf_mem_malloc(sizeof(*nan_obj));
116 if (!nan_obj)
117 return QDF_STATUS_E_NOMEM;
118
119 qdf_spinlock_create(&nan_obj->lock);
120 status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_NAN,
121 (void *)nan_obj,
122 QDF_STATUS_SUCCESS);
123 if (QDF_IS_STATUS_ERROR(status)) {
124 nan_alert("obj attach with vdev failed");
125 goto nan_vdev_notif_failed;
126 }
127
128 return QDF_STATUS_SUCCESS;
129
130 nan_vdev_notif_failed:
131
132 qdf_spinlock_destroy(&nan_obj->lock);
133 qdf_mem_free(nan_obj);
134 return status;
135 }
136
nan_vdev_obj_destroyed_notification(struct wlan_objmgr_vdev * vdev,void * arg_list)137 static QDF_STATUS nan_vdev_obj_destroyed_notification(
138 struct wlan_objmgr_vdev *vdev, void *arg_list)
139 {
140 struct nan_vdev_priv_obj *nan_obj;
141 QDF_STATUS status = QDF_STATUS_SUCCESS;
142
143 nan_debug("nan_vdev_delete_notif called");
144 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_NDI_MODE) {
145 nan_debug("not a ndi vdev. do nothing");
146 return QDF_STATUS_SUCCESS;
147 }
148
149 nan_obj = nan_get_vdev_priv_obj(vdev);
150 if (!nan_obj) {
151 nan_err("nan_obj is NULL");
152 return QDF_STATUS_E_FAULT;
153 }
154
155 status = wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_NAN,
156 nan_obj);
157 if (QDF_IS_STATUS_ERROR(status))
158 nan_err("nan_obj detach failed");
159
160 nan_debug("nan_obj deleted with status %d", status);
161 qdf_spinlock_destroy(&nan_obj->lock);
162 qdf_mem_free(nan_obj);
163
164 return status;
165 }
166
167 /**
168 * nan_peer_obj_created_notification() - Handler for peer object creation
169 * notification event
170 * @peer: Pointer to the PEER Object
171 * @arg_list: Pointer to private argument - NULL
172 *
173 * This function gets called from object manager when peer is being
174 * created.
175 *
176 * Return: QDF_STATUS
177 */
nan_peer_obj_created_notification(struct wlan_objmgr_peer * peer,void * arg_list)178 static QDF_STATUS nan_peer_obj_created_notification(
179 struct wlan_objmgr_peer *peer, void *arg_list)
180 {
181 struct nan_peer_priv_obj *nan_peer_obj;
182 QDF_STATUS status = QDF_STATUS_SUCCESS;
183
184 nan_peer_obj = qdf_mem_malloc(sizeof(*nan_peer_obj));
185 if (!nan_peer_obj)
186 return QDF_STATUS_E_NOMEM;
187
188 qdf_spinlock_create(&nan_peer_obj->lock);
189 status = wlan_objmgr_peer_component_obj_attach(peer, WLAN_UMAC_COMP_NAN,
190 (void *)nan_peer_obj,
191 QDF_STATUS_SUCCESS);
192 if (QDF_IS_STATUS_ERROR(status)) {
193 nan_alert("obj attach with peer failed");
194 goto nan_peer_notif_failed;
195 }
196
197 return QDF_STATUS_SUCCESS;
198
199 nan_peer_notif_failed:
200
201 qdf_spinlock_destroy(&nan_peer_obj->lock);
202 qdf_mem_free(nan_peer_obj);
203 return status;
204 }
205
206 /**
207 * nan_peer_obj_destroyed_notification() - Handler for peer object deletion
208 * notification event
209 * @peer: Pointer to the PEER Object
210 * @arg_list: Pointer to private argument - NULL
211 *
212 * This function gets called from object manager when peer is being destroyed.
213 *
214 * Return: QDF_STATUS
215 */
nan_peer_obj_destroyed_notification(struct wlan_objmgr_peer * peer,void * arg_list)216 static QDF_STATUS nan_peer_obj_destroyed_notification(
217 struct wlan_objmgr_peer *peer, void *arg_list)
218 {
219 struct nan_peer_priv_obj *nan_peer_obj;
220 QDF_STATUS status = QDF_STATUS_SUCCESS;
221
222 nan_peer_obj = nan_get_peer_priv_obj(peer);
223 if (!nan_peer_obj) {
224 nan_err("nan_peer_obj is NULL");
225 return QDF_STATUS_E_FAULT;
226 }
227
228 status = wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_NAN,
229 nan_peer_obj);
230 if (QDF_IS_STATUS_ERROR(status))
231 nan_err("nan_peer_obj detach failed");
232
233 nan_debug("nan_peer_obj deleted with status %d", status);
234 qdf_spinlock_destroy(&nan_peer_obj->lock);
235 qdf_mem_free(nan_peer_obj);
236
237 return status;
238 }
239
nan_init(void)240 QDF_STATUS nan_init(void)
241 {
242 QDF_STATUS status;
243
244 /* register psoc create handler functions. */
245 status = wlan_objmgr_register_psoc_create_handler(
246 WLAN_UMAC_COMP_NAN,
247 nan_psoc_obj_created_notification,
248 NULL);
249 if (QDF_IS_STATUS_ERROR(status)) {
250 nan_err("wlan_objmgr_register_psoc_create_handler failed");
251 return status;
252 }
253
254 /* register psoc delete handler functions. */
255 status = wlan_objmgr_register_psoc_destroy_handler(
256 WLAN_UMAC_COMP_NAN,
257 nan_psoc_obj_destroyed_notification,
258 NULL);
259 if (QDF_IS_STATUS_ERROR(status)) {
260 nan_err("wlan_objmgr_register_psoc_destroy_handler failed");
261 goto err_psoc_destroy_reg;
262 }
263
264 /* register vdev create handler functions. */
265 status = wlan_objmgr_register_vdev_create_handler(
266 WLAN_UMAC_COMP_NAN,
267 nan_vdev_obj_created_notification,
268 NULL);
269 if (QDF_IS_STATUS_ERROR(status)) {
270 nan_err("wlan_objmgr_register_psoc_create_handler failed");
271 goto err_vdev_create_reg;
272 }
273
274 /* register vdev delete handler functions. */
275 status = wlan_objmgr_register_vdev_destroy_handler(
276 WLAN_UMAC_COMP_NAN,
277 nan_vdev_obj_destroyed_notification,
278 NULL);
279 if (QDF_IS_STATUS_ERROR(status)) {
280 nan_err("wlan_objmgr_register_psoc_destroy_handler failed");
281 goto err_vdev_destroy_reg;
282 }
283
284 /* register peer create handler functions. */
285 status = wlan_objmgr_register_peer_create_handler(
286 WLAN_UMAC_COMP_NAN,
287 nan_peer_obj_created_notification,
288 NULL);
289 if (QDF_IS_STATUS_ERROR(status)) {
290 nan_err("wlan_objmgr_register_peer_create_handler failed");
291 goto err_peer_create_reg;
292 }
293
294 /* register peer delete handler functions. */
295 status = wlan_objmgr_register_peer_destroy_handler(
296 WLAN_UMAC_COMP_NAN,
297 nan_peer_obj_destroyed_notification,
298 NULL);
299 if (QDF_IS_STATUS_ERROR(status))
300 nan_err("wlan_objmgr_register_peer_destroy_handler failed");
301 else
302 return QDF_STATUS_SUCCESS;
303
304 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_NAN,
305 nan_peer_obj_created_notification,
306 NULL);
307 err_peer_create_reg:
308 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_NAN,
309 nan_vdev_obj_destroyed_notification,
310 NULL);
311 err_vdev_destroy_reg:
312 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_NAN,
313 nan_vdev_obj_created_notification,
314 NULL);
315 err_vdev_create_reg:
316 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_NAN,
317 nan_psoc_obj_destroyed_notification,
318 NULL);
319 err_psoc_destroy_reg:
320 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_NAN,
321 nan_psoc_obj_created_notification,
322 NULL);
323
324 return status;
325 }
326
nan_deinit(void)327 QDF_STATUS nan_deinit(void)
328 {
329 QDF_STATUS ret = QDF_STATUS_SUCCESS, status;
330
331 /* register psoc create handler functions. */
332 status = wlan_objmgr_unregister_psoc_create_handler(
333 WLAN_UMAC_COMP_NAN,
334 nan_psoc_obj_created_notification,
335 NULL);
336 if (QDF_IS_STATUS_ERROR(status)) {
337 nan_err("wlan_objmgr_unregister_psoc_create_handler failed");
338 ret = status;
339 }
340
341 /* register vdev create handler functions. */
342 status = wlan_objmgr_unregister_psoc_destroy_handler(
343 WLAN_UMAC_COMP_NAN,
344 nan_psoc_obj_destroyed_notification,
345 NULL);
346 if (QDF_IS_STATUS_ERROR(status)) {
347 nan_err("wlan_objmgr_deregister_psoc_destroy_handler failed");
348 ret = status;
349 }
350
351 /* de-register vdev create handler functions. */
352 status = wlan_objmgr_unregister_vdev_create_handler(
353 WLAN_UMAC_COMP_NAN,
354 nan_vdev_obj_created_notification,
355 NULL);
356 if (QDF_IS_STATUS_ERROR(status)) {
357 nan_err("wlan_objmgr_unregister_psoc_create_handler failed");
358 ret = status;
359 }
360
361 /* de-register vdev delete handler functions. */
362 status = wlan_objmgr_unregister_vdev_destroy_handler(
363 WLAN_UMAC_COMP_NAN,
364 nan_vdev_obj_destroyed_notification,
365 NULL);
366 if (QDF_IS_STATUS_ERROR(status)) {
367 nan_err("wlan_objmgr_deregister_psoc_destroy_handler failed");
368 ret = status;
369 }
370
371 /* de-register peer create handler functions. */
372 status = wlan_objmgr_unregister_peer_create_handler(
373 WLAN_UMAC_COMP_NAN,
374 nan_peer_obj_created_notification,
375 NULL);
376 if (QDF_IS_STATUS_ERROR(status)) {
377 nan_err("wlan_objmgr_unregister_peer_create_handler failed");
378 ret = status;
379 }
380
381 /* de-register peer delete handler functions. */
382 status = wlan_objmgr_unregister_peer_destroy_handler(
383 WLAN_UMAC_COMP_NAN,
384 nan_peer_obj_destroyed_notification,
385 NULL);
386 if (QDF_IS_STATUS_ERROR(status)) {
387 nan_err("wlan_objmgr_deregister_peer_destroy_handler failed");
388 ret = status;
389 }
390
391 return ret;
392 }
393
nan_psoc_enable(struct wlan_objmgr_psoc * psoc)394 QDF_STATUS nan_psoc_enable(struct wlan_objmgr_psoc *psoc)
395 {
396 QDF_STATUS status = target_if_nan_register_events(psoc);
397
398 if (QDF_IS_STATUS_ERROR(status))
399 nan_err("target_if_nan_register_events failed");
400
401 return QDF_STATUS_SUCCESS;
402 }
403
nan_psoc_disable(struct wlan_objmgr_psoc * psoc)404 QDF_STATUS nan_psoc_disable(struct wlan_objmgr_psoc *psoc)
405 {
406 QDF_STATUS status = target_if_nan_deregister_events(psoc);
407
408 if (QDF_IS_STATUS_ERROR(status))
409 nan_err("target_if_nan_deregister_events failed");
410
411 return QDF_STATUS_SUCCESS;
412 }
413
414 static bool
wlan_is_nan_allowed_on_6ghz_freq(struct wlan_objmgr_pdev * pdev,uint32_t freq)415 wlan_is_nan_allowed_on_6ghz_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq)
416 {
417 QDF_STATUS status;
418 struct regulatory_channel *chan_list;
419 uint32_t len_6g =
420 NUM_6GHZ_CHANNELS * sizeof(struct regulatory_channel);
421 uint16_t i;
422 bool ret = false;
423
424 chan_list = qdf_mem_malloc(len_6g);
425 if (!chan_list)
426 return ret;
427
428 status = wlan_reg_get_6g_ap_master_chan_list(pdev,
429 REG_VERY_LOW_POWER_AP,
430 chan_list);
431
432 for (i = 0; i < NUM_6GHZ_CHANNELS; i++) {
433 if ((freq == chan_list[i].center_freq) &&
434 (chan_list[i].state == CHANNEL_STATE_ENABLE)) {
435 ret = true;
436 goto end;
437 }
438 }
439
440 end:
441 qdf_mem_free(chan_list);
442 return ret;
443 }
444
wlan_is_nan_allowed_on_freq(struct wlan_objmgr_pdev * pdev,uint32_t freq)445 bool wlan_is_nan_allowed_on_freq(struct wlan_objmgr_pdev *pdev, uint32_t freq)
446 {
447 bool nan_allowed = true;
448
449 /* Check for 6GHz channels */
450 if (wlan_reg_is_6ghz_chan_freq(freq)) {
451 nan_allowed = wlan_is_nan_allowed_on_6ghz_freq(pdev, freq);
452 return nan_allowed;
453 }
454
455 /* Check for SRD channels */
456 if (wlan_reg_is_etsi_srd_chan_for_freq(pdev, freq))
457 wlan_mlme_get_srd_master_mode_for_vdev(wlan_pdev_get_psoc(pdev),
458 QDF_NAN_DISC_MODE,
459 &nan_allowed);
460
461 /* Check for Indoor channels */
462 if (wlan_reg_is_freq_indoor(pdev, freq))
463 wlan_mlme_get_indoor_support_for_nan(wlan_pdev_get_psoc(pdev),
464 &nan_allowed);
465 /*
466 * Check for dfs only if channel is not indoor,
467 * Check for passive channels as well
468 */
469 else if (wlan_reg_is_dfs_for_freq(pdev, freq) ||
470 wlan_reg_is_passive_for_freq(pdev, freq))
471 nan_allowed = false;
472
473 return nan_allowed;
474 }
475
476 #ifdef WLAN_FEATURE_11BE_MLO
wlan_is_mlo_sta_nan_ndi_allowed(struct wlan_objmgr_psoc * psoc)477 bool wlan_is_mlo_sta_nan_ndi_allowed(struct wlan_objmgr_psoc *psoc)
478 {
479 struct nan_psoc_priv_obj *psoc_nan_obj;
480
481 psoc_nan_obj = nan_get_psoc_priv_obj(psoc);
482 if (!psoc_nan_obj) {
483 nan_err("psoc_nan_obj is null");
484 return false;
485 }
486
487 return psoc_nan_obj->nan_caps.mlo_sta_nan_ndi_allowed;
488 }
489 #endif
490
491 #if defined(WLAN_FEATURE_NAN) && defined(WLAN_CHIPSET_STATS)
nan_cstats_log_nan_enable_resp_evt(struct nan_event_params * nan_event)492 void nan_cstats_log_nan_enable_resp_evt(struct nan_event_params *nan_event)
493 {
494 struct cstats_nan_disc_enable_resp stat = {0};
495 struct wlan_objmgr_vdev *vdev;
496
497 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(nan_event->psoc,
498 nan_event->vdev_id,
499 WLAN_NAN_ID);
500 if (!vdev) {
501 nan_err("Invalid vdev!");
502 return;
503 }
504
505 stat.cmn.hdr.evt_id =
506 WLAN_CHIPSET_STATS_NAN_DISCOVERY_ENABLE_RESP_EVENT_ID;
507 stat.cmn.hdr.length = sizeof(struct cstats_nan_disc_enable_resp) -
508 sizeof(struct cstats_hdr);
509 stat.cmn.opmode = wlan_vdev_mlme_get_opmode(vdev);
510 stat.cmn.vdev_id = wlan_vdev_get_id(vdev);
511 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
512 stat.cmn.time_tick = qdf_get_log_timestamp();
513
514 stat.is_enable_success = nan_event->is_nan_enable_success;
515 stat.mac_id = nan_event->mac_id;
516 stat.disc_state = nan_get_discovery_state(nan_event->psoc);
517
518 wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
519
520 wlan_cstats_host_stats(sizeof(struct cstats_nan_disc_enable_resp),
521 &stat);
522 }
523
nan_cstats_log_nan_disable_resp_evt(uint8_t vdev_id,struct wlan_objmgr_psoc * psoc)524 void nan_cstats_log_nan_disable_resp_evt(uint8_t vdev_id,
525 struct wlan_objmgr_psoc *psoc)
526 {
527 struct cstats_nan_disc_disable_resp stat = {0};
528
529 stat.cmn.hdr.evt_id =
530 WLAN_CHIPSET_STATS_NAN_DISCOVERY_DISABLE_RESP_EVENT_ID;
531 stat.cmn.hdr.length =
532 sizeof(struct cstats_nan_disc_disable_resp) -
533 sizeof(struct cstats_hdr);
534 stat.cmn.opmode = QDF_NAN_DISC_MODE;
535 stat.cmn.vdev_id = vdev_id;
536 stat.cmn.timestamp_us = qdf_get_time_of_the_day_us();
537 stat.cmn.time_tick = qdf_get_log_timestamp();
538 stat.disc_state = nan_get_discovery_state(psoc);
539
540 wlan_cstats_host_stats(sizeof(struct cstats_nan_disc_disable_resp),
541 &stat);
542 }
543 #endif /* WLAN_CHIPSET_STATS */
544