1 /* 2 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 /** 17 * DOC: wifi_pos_pasn_api.c 18 * This file defines the 11az PASN authentication related APIs for wifi_pos 19 * component. 20 */ 21 22 #include <wlan_lmac_if_def.h> 23 #include "wifi_pos_api.h" 24 #include "wifi_pos_pasn_api.h" 25 #include "wifi_pos_utils_i.h" 26 #include "wifi_pos_main_i.h" 27 #include "os_if_wifi_pos.h" 28 #include "os_if_wifi_pos_utils.h" 29 #include "target_if_wifi_pos.h" 30 #include "target_if_wifi_pos_rx_ops.h" 31 #include "wlan_objmgr_cmn.h" 32 #include "wlan_objmgr_global_obj.h" 33 #include "wlan_objmgr_psoc_obj.h" 34 #include "wlan_objmgr_peer_obj.h" 35 #include "wlan_lmac_if_def.h" 36 #include "wlan_vdev_mgr_tgt_if_tx_api.h" 37 38 #if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT) 39 uint8_t wifi_pos_get_pasn_peer_count(struct wlan_objmgr_vdev *vdev) 40 { 41 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 42 43 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 44 if (!vdev_pos_obj) { 45 wifi_pos_err("Wifi pos vdev priv obj is null"); 46 return 0; 47 } 48 49 return vdev_pos_obj->num_pasn_peers; 50 } 51 52 void wifi_pos_update_pasn_peer_count(struct wlan_objmgr_vdev *vdev, 53 bool is_increment) 54 { 55 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 56 57 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 58 if (!vdev_pos_obj) { 59 wifi_pos_err("Wifi pos vdev priv obj is null"); 60 return; 61 } 62 63 if (is_increment) 64 vdev_pos_obj->num_pasn_peers++; 65 else 66 vdev_pos_obj->num_pasn_peers--; 67 } 68 #endif 69 70 void wifi_pos_set_11az_failed_peers(struct wlan_objmgr_vdev *vdev, 71 struct qdf_mac_addr *mac_addr) 72 { 73 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 74 struct wifi_pos_11az_context *pasn_context; 75 uint8_t i; 76 77 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 78 if (!vdev_pos_obj) { 79 wifi_pos_err("Wifi pos vdev priv obj is null"); 80 return; 81 } 82 83 pasn_context = &vdev_pos_obj->pasn_context; 84 if (!pasn_context->num_failed_peers) 85 goto add_failed_peer; 86 87 for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { 88 if (qdf_is_macaddr_equal(mac_addr, 89 &pasn_context->failed_peer_list[i])) { 90 wifi_pos_debug("Peer: " QDF_MAC_ADDR_FMT " already exists in failed list", 91 QDF_MAC_ADDR_REF(mac_addr->bytes)); 92 return; 93 } 94 } 95 96 add_failed_peer: 97 for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { 98 if (qdf_is_macaddr_broadcast( 99 &pasn_context->failed_peer_list[i])) { 100 qdf_copy_macaddr(&pasn_context->failed_peer_list[i], 101 mac_addr); 102 pasn_context->num_failed_peers++; 103 wifi_pos_debug("Added failed peer: " QDF_MAC_ADDR_FMT " at idx[%d]", 104 QDF_MAC_ADDR_REF(mac_addr->bytes), i); 105 106 return; 107 } 108 } 109 110 wifi_pos_debug("Not able to set failed peer"); 111 } 112 113 void wifi_pos_add_peer_to_list(struct wlan_objmgr_vdev *vdev, 114 struct wlan_pasn_request *req, 115 bool is_peer_create_required) 116 { 117 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 118 struct wifi_pos_11az_context *pasn_context; 119 struct wlan_pasn_request *secure_list, *unsecure_list, *dst_entry; 120 uint8_t i; 121 122 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 123 return; 124 125 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 126 if (!vdev_pos_obj) { 127 wifi_pos_err("Wifi pos vdev priv obj is null"); 128 return; 129 } 130 131 pasn_context = &vdev_pos_obj->pasn_context; 132 secure_list = pasn_context->secure_peer_list; 133 unsecure_list = pasn_context->unsecure_peer_list; 134 135 /* Find the 1st empty slot and copy the entry to peer list */ 136 for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { 137 if (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) 138 dst_entry = &secure_list[i]; 139 else 140 dst_entry = &unsecure_list[i]; 141 142 /* Current slot is not empty */ 143 if (!qdf_is_macaddr_broadcast(&dst_entry->peer_mac)) 144 continue; 145 146 *dst_entry = *req; 147 if (is_peer_create_required) 148 pasn_context->num_pending_peer_creation++; 149 150 if (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) 151 pasn_context->num_secure_peers++; 152 else 153 pasn_context->num_unsecure_peers++; 154 155 wifi_pos_debug("Added %s peer: " QDF_MAC_ADDR_FMT " at idx[%d]", 156 (req->peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) ? "secure" : "unsecure", 157 QDF_MAC_ADDR_REF(dst_entry->peer_mac.bytes), i); 158 159 break; 160 } 161 } 162 163 /** 164 * wifi_pos_move_peers_to_fail_list - Move the peers in secure/unsecure list 165 * to failed peer list 166 * @vdev: Vdev pointer 167 * @peer_mac: Peer mac address 168 * @peer_type: Secure or unsecure PASN peer 169 * 170 * Return: None 171 */ 172 static 173 void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev, 174 struct qdf_mac_addr *peer_mac, 175 enum wifi_pos_pasn_peer_type peer_type) 176 { 177 uint8_t i; 178 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 179 struct wifi_pos_11az_context *pasn_context; 180 struct wlan_pasn_request *secure_list, *unsecure_list, *list = NULL; 181 struct qdf_mac_addr entry_to_copy; 182 183 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 184 return; 185 186 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 187 if (!vdev_pos_obj) { 188 wifi_pos_err("Wifi pos vdev priv obj is null"); 189 return; 190 } 191 192 pasn_context = &vdev_pos_obj->pasn_context; 193 194 /* 195 * Broadcast mac address will be sent by caller when initiate 196 * external auth fails and to move the entire list to failed 197 * peers list 198 */ 199 if (qdf_is_macaddr_broadcast(peer_mac)) { 200 /* Clear the entire list and move it to failed peers list */ 201 if (peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) 202 list = pasn_context->secure_peer_list; 203 else if (peer_type == WLAN_WIFI_POS_PASN_UNSECURE_PEER) 204 list = pasn_context->unsecure_peer_list; 205 206 if (!list) { 207 wifi_pos_err("No Valid list exists"); 208 return; 209 } 210 211 for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { 212 /* 213 * if valid entry exist in the list, set that mac 214 * address to failed list and clear that mac from the 215 * secure/unsecure list 216 */ 217 if (!qdf_is_macaddr_broadcast(&list[i].peer_mac)) { 218 wifi_pos_set_11az_failed_peers( 219 vdev, &list[i].peer_mac); 220 qdf_set_macaddr_broadcast(&list[i].peer_mac); 221 } 222 } 223 224 return; 225 } 226 227 secure_list = pasn_context->secure_peer_list; 228 unsecure_list = pasn_context->unsecure_peer_list; 229 /* 230 * This condition is hit when peer create confirm for a pasn 231 * peer is received with failure status 232 */ 233 for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { 234 /* 235 * Clear the individual entry that exist for the given 236 * mac address in secure/unsecure list 237 */ 238 if (qdf_is_macaddr_equal(peer_mac, &secure_list[i].peer_mac)) { 239 entry_to_copy = secure_list[i].peer_mac; 240 qdf_set_macaddr_broadcast(&secure_list[i].peer_mac); 241 pasn_context->num_secure_peers--; 242 } else if (qdf_is_macaddr_equal(peer_mac, 243 &unsecure_list[i].peer_mac)) { 244 entry_to_copy = unsecure_list[i].peer_mac; 245 qdf_set_macaddr_broadcast(&unsecure_list[i].peer_mac); 246 pasn_context->num_unsecure_peers--; 247 } else { 248 continue; 249 } 250 251 wifi_pos_set_11az_failed_peers(vdev, &entry_to_copy); 252 break; 253 } 254 } 255 256 static QDF_STATUS 257 wifi_pos_request_external_pasn_auth(struct wlan_objmgr_psoc *psoc, 258 struct wlan_objmgr_vdev *vdev, 259 struct wlan_pasn_request *peer_list, 260 uint8_t num_peers) 261 { 262 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 263 struct wifi_pos_osif_ops *osif_cb; 264 QDF_STATUS status; 265 266 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 267 return QDF_STATUS_E_INVAL; 268 269 osif_cb = wifi_pos_get_osif_callbacks(); 270 if (!osif_cb || !osif_cb->osif_initiate_pasn_cb) { 271 wifi_pos_err("OSIF %s cb is NULL", 272 !osif_cb ? "" : "PASN"); 273 return QDF_STATUS_E_FAILURE; 274 } 275 276 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 277 if (!vdev_pos_obj) { 278 wifi_pos_err("Wifi pos vdev priv obj is null"); 279 return QDF_STATUS_E_FAILURE; 280 } 281 282 status = osif_cb->osif_initiate_pasn_cb(vdev, peer_list, 283 num_peers, true); 284 if (QDF_IS_STATUS_ERROR(status)) 285 wifi_pos_err("Initiate PASN auth failed"); 286 287 return status; 288 } 289 290 static QDF_STATUS 291 wifi_pos_request_flush_pasn_keys(struct wlan_objmgr_psoc *psoc, 292 struct wlan_objmgr_vdev *vdev, 293 struct wlan_pasn_request *peer_list, 294 uint8_t num_peers) 295 { 296 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 297 struct wifi_pos_osif_ops *osif_cb; 298 QDF_STATUS status; 299 300 osif_cb = wifi_pos_get_osif_callbacks(); 301 if (!osif_cb || !osif_cb->osif_initiate_pasn_cb) { 302 wifi_pos_err("OSIF %s cb is NULL", 303 !osif_cb ? "" : "PASN"); 304 return QDF_STATUS_E_FAILURE; 305 } 306 307 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 308 if (!vdev_pos_obj) { 309 wifi_pos_err("Wifi pos vdev priv obj is null"); 310 return QDF_STATUS_E_FAILURE; 311 } 312 313 status = osif_cb->osif_initiate_pasn_cb(vdev, peer_list, num_peers, 314 false); 315 316 return status; 317 } 318 319 static QDF_STATUS 320 wifi_pos_check_and_initiate_pasn_authentication(struct wlan_objmgr_psoc *psoc, 321 struct wlan_objmgr_vdev *vdev, 322 struct wifi_pos_11az_context *pasn_ctx) 323 { 324 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT; 325 QDF_STATUS status; 326 327 if (pasn_ctx->num_pending_peer_creation || 328 !pasn_ctx->num_secure_peers) 329 return QDF_STATUS_SUCCESS; 330 331 status = wifi_pos_request_external_pasn_auth(psoc, vdev, 332 pasn_ctx->secure_peer_list, 333 pasn_ctx->num_secure_peers); 334 if (QDF_IS_STATUS_ERROR(status)) { 335 wifi_pos_err("Initiate Pasn Authentication failed"); 336 wifi_pos_move_peers_to_fail_list(vdev, &bcast_mac, 337 WLAN_WIFI_POS_PASN_SECURE_PEER); 338 /* TODO send PASN_STATUS cmd from here */ 339 } 340 341 return status; 342 } 343 344 QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, 345 struct wlan_pasn_request *req, 346 uint8_t vdev_id, 347 uint8_t total_entries) 348 { 349 struct wifi_pos_legacy_ops *legacy_cb; 350 struct wlan_objmgr_peer *peer; 351 struct wlan_objmgr_vdev *vdev; 352 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 353 struct wifi_pos_11az_context *pasn_context; 354 QDF_STATUS status = QDF_STATUS_SUCCESS; 355 uint8_t i; 356 357 legacy_cb = wifi_pos_get_legacy_ops(); 358 if (!legacy_cb || !legacy_cb->pasn_peer_create_cb) { 359 wifi_pos_err("legacy callbacks is not registered"); 360 return QDF_STATUS_E_FAILURE; 361 } 362 363 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 364 WLAN_WIFI_POS_CORE_ID); 365 if (!vdev) { 366 wifi_pos_err("Vdev object is null"); 367 return QDF_STATUS_E_FAILURE; 368 } 369 370 wifi_pos_debug("PASN peer create request received. Num peers:%d", 371 total_entries); 372 for (i = 0; i < total_entries; i++) { 373 peer = wlan_objmgr_get_peer_by_mac(psoc, req[i].peer_mac.bytes, 374 WLAN_WIFI_POS_CORE_ID); 375 /* 376 * If already PASN peer is found, then this is a request to 377 * initiate PASN authentication alone and not to send 378 * peer create to fw 379 */ 380 if (peer && 381 (wlan_peer_get_peer_type(peer) == WLAN_PEER_RTT_PASN)) { 382 wifi_pos_debug("PASN Peer: " QDF_MAC_ADDR_FMT "already exists", 383 QDF_MAC_ADDR_REF(req[i].peer_mac.bytes)); 384 wifi_pos_add_peer_to_list(vdev, &req[i], false); 385 wlan_objmgr_peer_release_ref(peer, 386 WLAN_WIFI_POS_CORE_ID); 387 continue; 388 } else if (peer) { 389 /* 390 * If a peer with given mac address already exists which 391 * is not a PASN peer, then move this peer to failed 392 * list 393 */ 394 wifi_pos_debug("Peer: " QDF_MAC_ADDR_FMT "of type:%d already exist", 395 QDF_MAC_ADDR_REF(req[i].peer_mac.bytes), 396 wlan_peer_get_peer_type(peer)); 397 wifi_pos_set_11az_failed_peers(vdev, &req[i].peer_mac); 398 wlan_objmgr_peer_release_ref(peer, 399 WLAN_WIFI_POS_CORE_ID); 400 continue; 401 } 402 403 status = legacy_cb->pasn_peer_create_cb(psoc, &req[i].peer_mac, 404 vdev_id); 405 if (QDF_IS_STATUS_ERROR(status)) { 406 wifi_pos_set_11az_failed_peers(vdev, &req[i].peer_mac); 407 continue; 408 } 409 410 wifi_pos_update_pasn_peer_count(vdev, true); 411 if (req[i].is_ltf_keyseed_required) { 412 peer = wlan_objmgr_get_peer_by_mac(psoc, 413 req[i].peer_mac.bytes, 414 WLAN_WIFI_POS_CORE_ID); 415 if (peer) { 416 wifi_pos_set_peer_ltf_keyseed_required(peer, 417 true); 418 wlan_objmgr_peer_release_ref(peer, 419 WLAN_WIFI_POS_CORE_ID); 420 } 421 } 422 423 /* Track the peers only for I-STA mode */ 424 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) 425 wifi_pos_add_peer_to_list(vdev, &req[i], true); 426 } 427 428 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) 429 goto end; 430 431 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 432 if (!vdev_pos_obj) { 433 wifi_pos_err("Wifi pos vdev priv obj is null"); 434 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 435 return QDF_STATUS_E_FAILURE; 436 } 437 438 /* 439 * If peer already exists for all the entries provided in the request, 440 * then fw peer create will not be sent again. Just the secure list 441 * will be updated and num_pending_peer_creation will be 0. 442 * In this case initiate the PASN auth directly without waiting for 443 * peer create response. 444 */ 445 pasn_context = &vdev_pos_obj->pasn_context; 446 status = wifi_pos_check_and_initiate_pasn_authentication(psoc, vdev, 447 pasn_context); 448 end: 449 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 450 451 return status; 452 } 453 454 QDF_STATUS 455 wifi_pos_handle_ranging_peer_create_rsp(struct wlan_objmgr_psoc *psoc, 456 uint8_t vdev_id, 457 struct qdf_mac_addr *peer_mac, 458 uint8_t peer_create_status) 459 { 460 struct wlan_objmgr_vdev *vdev; 461 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 462 struct wifi_pos_11az_context *pasn_context; 463 QDF_STATUS status = QDF_STATUS_SUCCESS; 464 465 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 466 WLAN_WIFI_POS_CORE_ID); 467 if (!vdev) { 468 wifi_pos_err("Vdev object is null"); 469 return QDF_STATUS_E_FAILURE; 470 } 471 472 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 473 if (!vdev_pos_obj) { 474 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 475 wifi_pos_err("Wifi pos vdev priv obj is null"); 476 return QDF_STATUS_E_FAILURE; 477 } 478 479 pasn_context = &vdev_pos_obj->pasn_context; 480 if (pasn_context->num_pending_peer_creation) 481 pasn_context->num_pending_peer_creation--; 482 483 wifi_pos_debug("Received peer create response for " QDF_MAC_ADDR_FMT " status:%d pending_count:%d", 484 QDF_MAC_ADDR_REF(peer_mac->bytes), peer_create_status, 485 pasn_context->num_pending_peer_creation); 486 487 if (peer_create_status) { 488 wifi_pos_move_peers_to_fail_list(vdev, peer_mac, 489 WLAN_WIFI_POS_PASN_PEER_TYPE_MAX); 490 wifi_pos_update_pasn_peer_count(vdev, false); 491 } 492 493 status = wifi_pos_check_and_initiate_pasn_authentication(psoc, vdev, 494 pasn_context); 495 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 496 497 return QDF_STATUS_SUCCESS; 498 } 499 500 QDF_STATUS wifi_pos_handle_ranging_peer_delete(struct wlan_objmgr_psoc *psoc, 501 struct wlan_pasn_request *req, 502 uint8_t vdev_id, 503 uint8_t total_entries) 504 { 505 struct wifi_pos_legacy_ops *legacy_cb; 506 struct wlan_objmgr_peer *peer; 507 struct wlan_pasn_request *del_peer_list; 508 struct wlan_objmgr_vdev *vdev; 509 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 510 bool no_fw_peer_delete; 511 uint8_t peer_count = 0, i; 512 QDF_STATUS status = QDF_STATUS_SUCCESS; 513 514 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 515 WLAN_WIFI_POS_CORE_ID); 516 if (!vdev) { 517 wifi_pos_err("Vdev object is null"); 518 return QDF_STATUS_E_FAILURE; 519 } 520 521 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 522 if (!vdev_pos_obj) { 523 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 524 wifi_pos_err("Wifi pos vdev priv obj is null"); 525 return QDF_STATUS_E_FAILURE; 526 } 527 528 if (vdev_pos_obj->is_delete_all_pasn_peer_in_progress) { 529 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 530 wifi_pos_err("Vdev delete all peer in progress. Ignore individual peer delete"); 531 return QDF_STATUS_SUCCESS; 532 } 533 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 534 535 legacy_cb = wifi_pos_get_legacy_ops(); 536 if (!legacy_cb || !legacy_cb->pasn_peer_delete_cb) { 537 wifi_pos_err("legacy callback is not registered"); 538 return QDF_STATUS_E_FAILURE; 539 } 540 541 del_peer_list = qdf_mem_malloc(sizeof(*del_peer_list) * total_entries); 542 if (!del_peer_list) 543 return QDF_STATUS_E_NOMEM; 544 545 for (i = 0; i < total_entries; i++) { 546 peer = wlan_objmgr_get_peer_by_mac(psoc, req[i].peer_mac.bytes, 547 WLAN_WIFI_POS_CORE_ID); 548 if (peer && 549 (wlan_peer_get_peer_type(peer) == WLAN_PEER_RTT_PASN)) { 550 no_fw_peer_delete = WIFI_POS_IS_PEER_ALREADY_DELETED( 551 req[i].control_flags); 552 wifi_pos_debug("Delete PASN Peer: " QDF_MAC_ADDR_FMT, 553 QDF_MAC_ADDR_REF(req[i].peer_mac.bytes)); 554 555 del_peer_list[peer_count] = req[i]; 556 peer_count++; 557 558 status = legacy_cb->pasn_peer_delete_cb( 559 psoc, &req[i].peer_mac, 560 vdev_id, no_fw_peer_delete); 561 562 wlan_objmgr_peer_release_ref(peer, 563 WLAN_WIFI_POS_CORE_ID); 564 continue; 565 } else { 566 wifi_pos_debug("PASN Peer: " QDF_MAC_ADDR_FMT "doesn't exist", 567 QDF_MAC_ADDR_REF(req[i].peer_mac.bytes)); 568 if (peer) 569 wlan_objmgr_peer_release_ref( 570 peer, WLAN_WIFI_POS_CORE_ID); 571 572 continue; 573 } 574 } 575 576 if (!peer_count) { 577 wifi_pos_debug("No Peers to delete "); 578 goto no_peer; 579 } 580 581 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 582 WLAN_WIFI_POS_CORE_ID); 583 if (!vdev) { 584 wifi_pos_err("Vdev object is null"); 585 qdf_mem_free(del_peer_list); 586 return QDF_STATUS_E_FAILURE; 587 } 588 589 status = wifi_pos_request_flush_pasn_keys(psoc, vdev, 590 del_peer_list, 591 peer_count); 592 if (QDF_IS_STATUS_ERROR(status)) 593 wifi_pos_err("Failed to indicate peer deauth to userspace"); 594 595 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 596 597 no_peer: 598 qdf_mem_free(del_peer_list); 599 600 return status; 601 } 602 603 QDF_STATUS 604 wifi_pos_send_pasn_auth_status(struct wlan_objmgr_psoc *psoc, 605 struct wlan_pasn_auth_status *data) 606 { 607 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 608 QDF_STATUS status; 609 uint8_t vdev_id = data->vdev_id; 610 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 611 struct wifi_pos_11az_context *pasn_context; 612 struct wlan_objmgr_vdev *vdev; 613 uint8_t i, failed_peers_counter = 0, total_peers_to_fill = 0; 614 615 tx_ops = wifi_pos_get_tx_ops(psoc); 616 if (!tx_ops || !tx_ops->send_rtt_pasn_auth_status) { 617 wifi_pos_err("%s is null", 618 tx_ops ? "Tx_ops" : "send_auth_status cb"); 619 return QDF_STATUS_E_FAILURE; 620 } 621 622 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 623 WLAN_WIFI_POS_CORE_ID); 624 if (!vdev) { 625 wifi_pos_err("vdev obj is null"); 626 return QDF_STATUS_E_FAILURE; 627 } 628 629 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 630 if (!vdev_pos_obj) { 631 wifi_pos_err("Wifi pos vdev priv obj is null"); 632 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 633 return QDF_STATUS_E_FAILURE; 634 } 635 636 pasn_context = &vdev_pos_obj->pasn_context; 637 total_peers_to_fill = data->num_peers + pasn_context->num_failed_peers; 638 for (i = data->num_peers; i < total_peers_to_fill; i++) { 639 data->auth_status[i].peer_mac = 640 pasn_context->failed_peer_list[failed_peers_counter]; 641 data->auth_status[i].status = 642 WLAN_PASN_AUTH_STATUS_PEER_CREATE_FAILED; 643 644 failed_peers_counter++; 645 if (failed_peers_counter >= pasn_context->num_failed_peers) 646 break; 647 } 648 649 status = tx_ops->send_rtt_pasn_auth_status(psoc, data); 650 if (QDF_IS_STATUS_ERROR(status)) 651 wifi_pos_err("Failed to send PASN authentication status"); 652 653 wifi_pos_init_11az_context(vdev_pos_obj); 654 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 655 656 return status; 657 } 658 659 QDF_STATUS 660 wifi_pos_send_pasn_peer_deauth(struct wlan_objmgr_psoc *psoc, 661 struct qdf_mac_addr *peer_mac) 662 { 663 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 664 QDF_STATUS status; 665 666 tx_ops = wifi_pos_get_tx_ops(psoc); 667 if (!tx_ops || !tx_ops->send_rtt_pasn_deauth) { 668 wifi_pos_err("%s is null", 669 tx_ops ? "Tx_ops" : "send_pasn deauth cb"); 670 return QDF_STATUS_E_FAILURE; 671 } 672 673 status = tx_ops->send_rtt_pasn_deauth(psoc, peer_mac); 674 675 return status; 676 } 677 678 QDF_STATUS 679 wifi_pos_set_peer_ltf_keyseed_required(struct wlan_objmgr_peer *peer, 680 bool value) 681 { 682 struct wlan_wifi_pos_peer_priv_obj *peer_priv; 683 684 peer_priv = wifi_pos_get_peer_private_object(peer); 685 if (!peer_priv) { 686 wifi_pos_err("peer private object is null"); 687 return QDF_STATUS_E_FAILURE; 688 } 689 690 peer_priv->is_ltf_keyseed_required = value; 691 692 return QDF_STATUS_SUCCESS; 693 } 694 695 bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer) 696 { 697 struct wlan_wifi_pos_peer_priv_obj *peer_priv; 698 699 peer_priv = wifi_pos_get_peer_private_object(peer); 700 if (!peer_priv) { 701 wifi_pos_err("peer private object is null"); 702 return QDF_STATUS_E_FAILURE; 703 } 704 705 return peer_priv->is_ltf_keyseed_required; 706 } 707 708 static 709 void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_psoc *psoc, 710 void *object, void *arg) 711 { 712 struct wlan_objmgr_peer *peer = object; 713 struct wlan_objmgr_vdev *vdev = arg; 714 uint8_t vdev_id, peer_vdev_id; 715 enum wlan_peer_type peer_type; 716 QDF_STATUS status; 717 718 if (!peer) { 719 wifi_pos_err("Peer is NULL"); 720 return; 721 } 722 723 peer_type = wlan_peer_get_peer_type(peer); 724 if (peer_type != WLAN_PEER_RTT_PASN) 725 return; 726 727 if (!vdev) { 728 wifi_pos_err("VDEV is NULL"); 729 return; 730 } 731 732 vdev_id = wlan_vdev_get_id(vdev); 733 peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer)); 734 if (vdev_id != peer_vdev_id) 735 return; 736 737 status = wlan_objmgr_peer_obj_delete(peer); 738 if (QDF_IS_STATUS_ERROR(status)) 739 wifi_pos_err("Failed to delete peer"); 740 741 wifi_pos_update_pasn_peer_count(vdev, false); 742 } 743 744 QDF_STATUS 745 wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc, 746 struct wlan_objmgr_vdev *vdev) 747 { 748 QDF_STATUS status; 749 750 wifi_pos_debug("Iterate and delete PASN peers"); 751 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP, 752 wifi_pos_delete_objmgr_ranging_peer, 753 vdev, 0, WLAN_WIFI_POS_CORE_ID); 754 if (QDF_IS_STATUS_ERROR(status)) 755 wifi_pos_err("Delete objmgr peers failed"); 756 757 return status; 758 } 759 760 QDF_STATUS 761 wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev) 762 { 763 QDF_STATUS status; 764 struct vdev_mlme_obj *vdev_mlme; 765 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 766 struct peer_delete_all_params param; 767 768 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 769 if (!vdev_pos_obj) { 770 wifi_pos_err("Wifi pos vdev priv obj is null"); 771 return QDF_STATUS_E_FAILURE; 772 } 773 774 if (!vdev_pos_obj->num_pasn_peers) 775 return QDF_STATUS_SUCCESS; 776 777 vdev_pos_obj->is_delete_all_pasn_peer_in_progress = true; 778 779 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 780 if (!vdev_mlme) { 781 wifi_pos_err(" VDEV MLME component object is NULL"); 782 return QDF_STATUS_E_FAILURE; 783 } 784 785 param.vdev_id = wlan_vdev_get_id(vdev); 786 param.peer_type_bitmap = BIT(WLAN_PEER_RTT_PASN); 787 788 status = tgt_vdev_mgr_peer_delete_all_send(vdev_mlme, ¶m); 789 if (QDF_IS_STATUS_ERROR(status)) 790 wifi_pos_err("Send vdev delete all peers failed"); 791 792 return status; 793 } 794 795 QDF_STATUS 796 wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc, 797 uint8_t vdev_id) 798 { 799 struct wifi_pos_legacy_ops *legacy_cb; 800 struct wlan_objmgr_vdev *vdev; 801 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 802 QDF_STATUS status; 803 804 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 805 WLAN_WIFI_POS_CORE_ID); 806 if (!vdev) { 807 wifi_pos_err(" VDEV is NULL"); 808 return QDF_STATUS_E_FAILURE; 809 } 810 811 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 812 if (!vdev_pos_obj) { 813 wifi_pos_err("Wifi pos vdev priv obj is null"); 814 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 815 return QDF_STATUS_E_FAILURE; 816 } 817 818 status = wifi_pos_cleanup_pasn_peers(psoc, vdev); 819 if (QDF_IS_STATUS_ERROR(status)) { 820 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 821 return status; 822 } 823 824 vdev_pos_obj->is_delete_all_pasn_peer_in_progress = false; 825 826 legacy_cb = wifi_pos_get_legacy_ops(); 827 if (!legacy_cb || !legacy_cb->pasn_vdev_delete_resume_cb) { 828 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 829 wifi_pos_err("legacy callbacks is not registered"); 830 return QDF_STATUS_E_FAILURE; 831 } 832 833 status = legacy_cb->pasn_vdev_delete_resume_cb(vdev); 834 if (QDF_IS_STATUS_ERROR(status)) 835 wifi_pos_err("Delete all PASN peer failed"); 836 837 wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID); 838 839 return status; 840 } 841 842 bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev) 843 { 844 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 845 846 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 847 if (!vdev_pos_obj) { 848 wifi_pos_err("Wifi pos vdev priv obj is null"); 849 return false; 850 } 851 852 return vdev_pos_obj->is_delete_all_pasn_peer_in_progress; 853 } 854 855 void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev, 856 bool flag) 857 { 858 struct wifi_pos_vdev_priv_obj *vdev_pos_obj; 859 860 vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev); 861 if (!vdev_pos_obj) { 862 wifi_pos_err("Wifi pos vdev priv obj is null"); 863 return; 864 } 865 866 vdev_pos_obj->is_delete_all_pasn_peer_in_progress = flag; 867 } 868