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 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 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 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 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 */ 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 */ 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 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 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 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 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 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 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 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) 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 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