1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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: wlan_tdls_main.c 22 * 23 * TDLS core function definitions 24 */ 25 26 #include "wlan_tdls_main.h" 27 #include "wlan_tdls_peer.h" 28 #include "wlan_tdls_ct.h" 29 #include "wlan_tdls_mgmt.h" 30 #include "wlan_tdls_api.h" 31 #include "wlan_tdls_tgt_api.h" 32 #include "wlan_policy_mgr_public_struct.h" 33 #include "wlan_policy_mgr_api.h" 34 #include "wlan_scan_ucfg_api.h" 35 #include "wlan_tdls_ucfg_api.h" 36 #include "wlan_cm_roam_api.h" 37 #include "wlan_cfg80211_tdls.h" 38 #include "wlan_nan_api_i.h" 39 #include "wlan_mlme_vdev_mgr_interface.h" 40 41 /* Global tdls soc pvt object 42 * this is useful for some functions which does not receive either vdev or psoc 43 * objects. 44 */ 45 static struct tdls_soc_priv_obj *tdls_soc_global; 46 47 #ifdef WLAN_DEBUG 48 /** 49 * tdls_get_cmd_type_str() - parse cmd to string 50 * @cmd_type: tdls cmd type 51 * 52 * This function parse tdls cmd to string. 53 * 54 * Return: command string 55 */ 56 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type) 57 { 58 switch (cmd_type) { 59 CASE_RETURN_STRING(TDLS_CMD_TX_ACTION); 60 CASE_RETURN_STRING(TDLS_CMD_ADD_STA); 61 CASE_RETURN_STRING(TDLS_CMD_CHANGE_STA); 62 CASE_RETURN_STRING(TDLS_CMD_ENABLE_LINK); 63 CASE_RETURN_STRING(TDLS_CMD_DISABLE_LINK); 64 CASE_RETURN_STRING(TDLS_CMD_CONFIG_FORCE_PEER); 65 CASE_RETURN_STRING(TDLS_CMD_REMOVE_FORCE_PEER); 66 CASE_RETURN_STRING(TDLS_CMD_STATS_UPDATE); 67 CASE_RETURN_STRING(TDLS_CMD_CONFIG_UPDATE); 68 CASE_RETURN_STRING(TDLS_CMD_SCAN_DONE); 69 CASE_RETURN_STRING(TDLS_CMD_SET_RESPONDER); 70 CASE_RETURN_STRING(TDLS_NOTIFY_STA_CONNECTION); 71 CASE_RETURN_STRING(TDLS_NOTIFY_STA_DISCONNECTION); 72 CASE_RETURN_STRING(TDLS_CMD_SET_TDLS_MODE); 73 CASE_RETURN_STRING(TDLS_CMD_SESSION_INCREMENT); 74 CASE_RETURN_STRING(TDLS_CMD_SESSION_DECREMENT); 75 CASE_RETURN_STRING(TDLS_CMD_TEARDOWN_LINKS); 76 CASE_RETURN_STRING(TDLS_NOTIFY_RESET_ADAPTERS); 77 CASE_RETURN_STRING(TDLS_CMD_ANTENNA_SWITCH); 78 CASE_RETURN_STRING(TDLS_CMD_SET_OFFCHANMODE); 79 CASE_RETURN_STRING(TDLS_CMD_SET_OFFCHANNEL); 80 CASE_RETURN_STRING(TDLS_CMD_SET_SECOFFCHANOFFSET); 81 CASE_RETURN_STRING(TDLS_DELETE_ALL_PEERS_INDICATION); 82 CASE_RETURN_STRING(TDLS_CMD_START_BSS); 83 CASE_RETURN_STRING(TDLS_CMD_SET_LINK_UNFORCE); 84 default: 85 return "Invalid TDLS command"; 86 } 87 } 88 89 /** 90 * tdls_get_event_type_str() - parase event to string 91 * @event_type: tdls event type 92 * 93 * This function parse tdls event to string. 94 * 95 * Return: event string 96 */ 97 static char *tdls_get_event_type_str(enum tdls_event_type event_type) 98 { 99 switch (event_type) { 100 case TDLS_SHOULD_DISCOVER: 101 return "TDLS_SHOULD_DISCOVER"; 102 case TDLS_SHOULD_TEARDOWN: 103 return "TDLS_SHOULD_TEARDOWN"; 104 case TDLS_PEER_DISCONNECTED: 105 return "TDLS_PEER_DISCONNECTED"; 106 case TDLS_CONNECTION_TRACKER_NOTIFY: 107 return "TDLS_CONNECTION_TRACKER_NOTIFY"; 108 109 default: 110 return "Invalid TDLS event"; 111 } 112 } 113 #else 114 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type) 115 { 116 return ""; 117 } 118 119 static char *tdls_get_event_type_str(enum tdls_event_type event_type) 120 { 121 return ""; 122 } 123 #endif 124 125 QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, 126 void *arg_list) 127 { 128 QDF_STATUS status; 129 struct tdls_soc_priv_obj *tdls_soc_obj; 130 131 tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj)); 132 if (!tdls_soc_obj) 133 return QDF_STATUS_E_NOMEM; 134 135 tdls_soc_obj->soc = psoc; 136 137 status = wlan_objmgr_psoc_component_obj_attach(psoc, 138 WLAN_UMAC_COMP_TDLS, 139 (void *)tdls_soc_obj, 140 QDF_STATUS_SUCCESS); 141 142 if (QDF_IS_STATUS_ERROR(status)) { 143 tdls_err("Failed to attach psoc tdls component"); 144 qdf_mem_free(tdls_soc_obj); 145 return status; 146 } 147 148 tdls_soc_global = tdls_soc_obj; 149 tdls_notice("TDLS obj attach to psoc successfully"); 150 151 return status; 152 } 153 154 QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, 155 void *arg_list) 156 { 157 QDF_STATUS status; 158 struct tdls_soc_priv_obj *tdls_soc_obj; 159 160 tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, 161 WLAN_UMAC_COMP_TDLS); 162 if (!tdls_soc_obj) { 163 tdls_err("Failed to get tdls obj in psoc"); 164 return QDF_STATUS_E_FAILURE; 165 } 166 167 status = wlan_objmgr_psoc_component_obj_detach(psoc, 168 WLAN_UMAC_COMP_TDLS, 169 tdls_soc_obj); 170 171 if (QDF_IS_STATUS_ERROR(status)) 172 tdls_err("Failed to detach psoc tdls component"); 173 qdf_mem_free(tdls_soc_obj); 174 175 return status; 176 } 177 178 static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) 179 { 180 uint8_t i; 181 struct tdls_config_params *config; 182 struct tdls_user_config *user_config; 183 struct tdls_soc_priv_obj *soc_obj; 184 185 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); 186 if (!soc_obj) { 187 tdls_err("tdls soc obj NULL"); 188 return QDF_STATUS_E_FAILURE; 189 } 190 191 config = &vdev_obj->threshold_config; 192 user_config = &soc_obj->tdls_configs; 193 config->tx_period_t = user_config->tdls_tx_states_period; 194 config->tx_packet_n = user_config->tdls_tx_pkt_threshold; 195 config->discovery_tries_n = user_config->tdls_max_discovery_attempt; 196 config->idle_timeout_t = user_config->tdls_idle_timeout; 197 config->idle_packet_n = user_config->tdls_idle_pkt_threshold; 198 config->rssi_trigger_threshold = 199 user_config->tdls_rssi_trigger_threshold; 200 config->rssi_teardown_threshold = 201 user_config->tdls_rssi_teardown_threshold; 202 config->rssi_delta = user_config->tdls_rssi_delta; 203 204 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 205 qdf_list_create(&vdev_obj->peer_list[i], 206 WLAN_TDLS_PEER_SUB_LIST_SIZE); 207 } 208 qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, 209 tdls_ct_handler, vdev_obj->vdev); 210 qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, 211 tdls_discovery_timeout_peer_cb, vdev_obj->vdev); 212 213 return QDF_STATUS_SUCCESS; 214 } 215 216 static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj) 217 { 218 qdf_mc_timer_stop_sync(&vdev_obj->peer_update_timer); 219 qdf_mc_timer_stop_sync(&vdev_obj->peer_discovery_timer); 220 221 qdf_mc_timer_destroy(&vdev_obj->peer_update_timer); 222 qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer); 223 224 tdls_peer_idle_timers_destroy(vdev_obj); 225 tdls_free_peer_list(vdev_obj); 226 } 227 228 QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, 229 void *arg) 230 { 231 QDF_STATUS status; 232 struct tdls_vdev_priv_obj *tdls_vdev_obj; 233 struct wlan_objmgr_pdev *pdev; 234 struct tdls_soc_priv_obj *tdls_soc_obj; 235 uint32_t tdls_feature_flags; 236 237 tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); 238 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && 239 wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) 240 return QDF_STATUS_SUCCESS; 241 242 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 243 if (!tdls_soc_obj) { 244 tdls_err("get soc by vdev failed"); 245 return QDF_STATUS_E_NOMEM; 246 } 247 248 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 249 if (!TDLS_IS_ENABLED(tdls_feature_flags)) { 250 tdls_debug("disabled in ini"); 251 return QDF_STATUS_E_NOSUPPORT; 252 } 253 254 if (tdls_soc_obj->tdls_osif_init_cb) { 255 status = tdls_soc_obj->tdls_osif_init_cb(vdev); 256 if (QDF_IS_STATUS_ERROR(status)) 257 return status; 258 } 259 260 /* TODO: Add concurrency check */ 261 262 tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); 263 if (!tdls_vdev_obj) { 264 status = QDF_STATUS_E_NOMEM; 265 goto err_attach; 266 } 267 268 status = wlan_objmgr_vdev_component_obj_attach(vdev, 269 WLAN_UMAC_COMP_TDLS, 270 (void *)tdls_vdev_obj, 271 QDF_STATUS_SUCCESS); 272 if (QDF_IS_STATUS_ERROR(status)) { 273 tdls_err("Failed to attach vdev tdls component"); 274 goto err_attach; 275 } 276 tdls_vdev_obj->vdev = vdev; 277 status = tdls_vdev_init(tdls_vdev_obj); 278 if (QDF_IS_STATUS_ERROR(status)) 279 goto err_vdev_init; 280 281 status = qdf_event_create(&tdls_vdev_obj->tdls_teardown_comp); 282 if (QDF_IS_STATUS_ERROR(status)) 283 goto err_event_create; 284 285 pdev = wlan_vdev_get_pdev(vdev); 286 287 status = ucfg_scan_register_event_handler(pdev, 288 tdls_scan_complete_event_handler, 289 tdls_soc_obj); 290 291 if (QDF_STATUS_SUCCESS != status) { 292 tdls_err("scan event register failed "); 293 goto err_register; 294 } 295 296 tdls_debug("tdls object attach to vdev successfully"); 297 return status; 298 299 err_register: 300 qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp); 301 err_event_create: 302 tdls_vdev_deinit(tdls_vdev_obj); 303 err_vdev_init: 304 wlan_objmgr_vdev_component_obj_detach(vdev, 305 WLAN_UMAC_COMP_TDLS, 306 (void *)tdls_vdev_obj); 307 err_attach: 308 if (tdls_soc_obj->tdls_osif_deinit_cb) 309 tdls_soc_obj->tdls_osif_deinit_cb(vdev); 310 if (tdls_vdev_obj) { 311 qdf_mem_free(tdls_vdev_obj); 312 tdls_vdev_obj = NULL; 313 } 314 315 return status; 316 } 317 318 QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, 319 void *arg) 320 { 321 QDF_STATUS status; 322 struct tdls_vdev_priv_obj *tdls_vdev_obj; 323 struct tdls_soc_priv_obj *tdls_soc_obj; 324 uint32_t tdls_feature_flags; 325 326 tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); 327 if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && 328 wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) 329 return QDF_STATUS_SUCCESS; 330 331 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 332 if (!tdls_soc_obj) { 333 tdls_err("get soc by vdev failed"); 334 return QDF_STATUS_E_NOMEM; 335 } 336 337 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 338 if (!TDLS_IS_ENABLED(tdls_feature_flags)) { 339 tdls_debug("disabled in ini"); 340 return QDF_STATUS_E_NOSUPPORT; 341 } 342 343 tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, 344 WLAN_UMAC_COMP_TDLS); 345 if (!tdls_vdev_obj) { 346 tdls_err("Failed to get tdls vdev object"); 347 return QDF_STATUS_E_FAILURE; 348 } 349 350 if (wlan_vdev_mlme_is_mlo_vdev(vdev)) { 351 if (QDF_TIMER_STATE_STOPPED != 352 qdf_mc_timer_get_current_state( 353 &tdls_vdev_obj->peer_discovery_timer)) 354 qdf_mc_timer_stop(&tdls_vdev_obj->peer_discovery_timer); 355 } 356 357 qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp); 358 tdls_vdev_deinit(tdls_vdev_obj); 359 360 status = wlan_objmgr_vdev_component_obj_detach(vdev, 361 WLAN_UMAC_COMP_TDLS, 362 tdls_vdev_obj); 363 if (QDF_IS_STATUS_ERROR(status)) 364 tdls_err("Failed to detach vdev tdls component"); 365 366 if (tdls_soc_obj->tdls_osif_deinit_cb) 367 tdls_soc_obj->tdls_osif_deinit_cb(vdev); 368 qdf_mem_free(tdls_vdev_obj); 369 370 return status; 371 } 372 373 /** 374 * __tdls_get_all_peers_from_list() - get all the tdls peers from the list 375 * @get_tdls_peers: get_tdls_peers object 376 * 377 * Return: int 378 */ 379 static int __tdls_get_all_peers_from_list( 380 struct tdls_get_all_peers *get_tdls_peers) 381 { 382 int i; 383 int len, init_len; 384 qdf_list_t *head; 385 qdf_list_node_t *p_node; 386 struct tdls_peer *curr_peer; 387 char *buf; 388 int buf_len; 389 struct tdls_vdev_priv_obj *tdls_vdev; 390 QDF_STATUS status; 391 392 tdls_notice("Enter "); 393 394 buf = get_tdls_peers->buf; 395 buf_len = get_tdls_peers->buf_len; 396 397 if (wlan_vdev_is_up(get_tdls_peers->vdev) != QDF_STATUS_SUCCESS) { 398 len = qdf_scnprintf(buf, buf_len, 399 "\nSTA is not associated\n"); 400 return len; 401 } 402 403 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); 404 405 if (!tdls_vdev) { 406 len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); 407 return len; 408 } 409 410 init_len = buf_len; 411 len = qdf_scnprintf(buf, buf_len, 412 "\n%-18s%-3s%-4s%-3s%-5s\n", 413 "MAC", "Id", "cap", "up", "RSSI"); 414 buf += len; 415 buf_len -= len; 416 len = qdf_scnprintf(buf, buf_len, 417 "---------------------------------\n"); 418 buf += len; 419 buf_len -= len; 420 421 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 422 head = &tdls_vdev->peer_list[i]; 423 status = qdf_list_peek_front(head, &p_node); 424 while (QDF_IS_STATUS_SUCCESS(status)) { 425 curr_peer = qdf_container_of(p_node, 426 struct tdls_peer, node); 427 if (buf_len < 32 + 1) 428 break; 429 len = qdf_scnprintf(buf, buf_len, 430 QDF_MAC_ADDR_FMT "%4s%3s%5d\n", 431 QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes), 432 (curr_peer->tdls_support == 433 TDLS_CAP_SUPPORTED) ? "Y" : "N", 434 TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : 435 "N", curr_peer->rssi); 436 buf += len; 437 buf_len -= len; 438 status = qdf_list_peek_next(head, p_node, &p_node); 439 } 440 } 441 442 tdls_notice("Exit "); 443 return init_len - buf_len; 444 } 445 446 /** 447 * tdls_get_all_peers_from_list() - get all the tdls peers from the list 448 * @get_tdls_peers: get_tdls_peers object 449 * 450 * Return: None 451 */ 452 static void tdls_get_all_peers_from_list( 453 struct tdls_get_all_peers *get_tdls_peers) 454 { 455 int32_t len; 456 struct tdls_soc_priv_obj *tdls_soc_obj; 457 struct tdls_osif_indication indication; 458 459 if (!get_tdls_peers->vdev) { 460 qdf_mem_free(get_tdls_peers); 461 return; 462 } 463 len = __tdls_get_all_peers_from_list(get_tdls_peers); 464 465 indication.status = len; 466 indication.vdev = get_tdls_peers->vdev; 467 468 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); 469 if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) 470 tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, 471 TDLS_EVENT_USER_CMD, &indication); 472 473 qdf_mem_free(get_tdls_peers); 474 } 475 476 /** 477 * tdls_process_reset_all_peers() - Reset all tdls peers 478 * @vdev: vdev object 479 * 480 * This function is called to reset all tdls peers and 481 * notify upper layers of teardown inidcation 482 * 483 * Return: QDF_STATUS 484 */ 485 486 static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) 487 { 488 QDF_STATUS status = QDF_STATUS_SUCCESS; 489 uint8_t staidx; 490 struct tdls_peer *curr_peer = NULL; 491 struct tdls_vdev_priv_obj *tdls_vdev; 492 struct tdls_soc_priv_obj *tdls_soc; 493 uint8_t reset_session_id; 494 495 status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); 496 if (QDF_STATUS_SUCCESS != status) { 497 tdls_err("tdls objects are NULL "); 498 return status; 499 } 500 501 reset_session_id = tdls_vdev->session_id; 502 for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; 503 staidx++) { 504 if (!tdls_soc->tdls_conn_info[staidx].valid_entry) 505 continue; 506 if (tdls_soc->tdls_conn_info[staidx].session_id != 507 reset_session_id) 508 continue; 509 510 curr_peer = 511 tdls_find_all_peer(tdls_soc, 512 tdls_soc->tdls_conn_info[staidx]. 513 peer_mac.bytes); 514 if (!curr_peer) 515 continue; 516 517 tdls_notice("indicate TDLS teardown "QDF_MAC_ADDR_FMT, 518 QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes)); 519 520 /* Indicate teardown to supplicant */ 521 tdls_indicate_teardown(tdls_vdev, 522 curr_peer, 523 TDLS_TEARDOWN_PEER_UNSPEC_REASON); 524 525 tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); 526 527 tdls_decrement_peer_count(vdev, tdls_soc); 528 tdls_soc->tdls_conn_info[staidx].valid_entry = false; 529 tdls_soc->tdls_conn_info[staidx].session_id = 255; 530 tdls_soc->tdls_conn_info[staidx].index = 531 INVALID_TDLS_PEER_INDEX; 532 533 qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, 534 sizeof(struct qdf_mac_addr)); 535 } 536 return status; 537 } 538 539 /** 540 * tdls_reset_all_peers() - Reset all tdls peers 541 * @delete_all_peers_ind: Delete all peers indication 542 * 543 * This function is called to reset all tdls peers and 544 * notify upper layers of teardown inidcation 545 * 546 * Return: QDF_STATUS 547 */ 548 static QDF_STATUS tdls_reset_all_peers( 549 struct tdls_delete_all_peers_params *delete_all_peers_ind) 550 { 551 QDF_STATUS status; 552 553 if (!delete_all_peers_ind || !delete_all_peers_ind->vdev) { 554 tdls_err("invalid param"); 555 qdf_mem_free(delete_all_peers_ind); 556 return QDF_STATUS_E_INVAL; 557 } 558 559 status = tdls_process_reset_all_peers(delete_all_peers_ind->vdev); 560 561 wlan_objmgr_vdev_release_ref(delete_all_peers_ind->vdev, 562 WLAN_TDLS_SB_ID); 563 qdf_mem_free(delete_all_peers_ind); 564 565 return status; 566 } 567 568 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES 569 QDF_STATUS tdls_handle_start_bss(struct wlan_objmgr_psoc *psoc) 570 { 571 struct wlan_objmgr_vdev *tdls_vdev; 572 573 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); 574 if (!tdls_vdev) { 575 tdls_err("Unable get the tdls vdev"); 576 return QDF_STATUS_E_FAILURE; 577 } 578 579 tdls_set_tdls_offchannelmode(tdls_vdev, DISABLE_ACTIVE_CHANSWITCH); 580 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 581 582 return QDF_STATUS_SUCCESS; 583 } 584 #endif 585 586 static void tdls_handle_link_unforce(struct wlan_objmgr_vdev *vdev) 587 { 588 struct tdls_action_frame_request req = {0}; 589 590 req.vdev = vdev; 591 req.tdls_mgmt.frame_type = TDLS_MAX_ACTION_CODE; 592 593 tdls_debug("set vdev %d unforce", wlan_vdev_get_id(vdev)); 594 tdls_set_link_mode(&req); 595 } 596 597 QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) 598 { 599 QDF_STATUS status = QDF_STATUS_SUCCESS; 600 601 if (!msg || !msg->bodyptr) { 602 tdls_err("msg: 0x%pK", msg); 603 QDF_ASSERT(0); 604 return QDF_STATUS_E_NULL_VALUE; 605 } 606 tdls_debug("TDLS process command: %s(%d)", 607 tdls_get_cmd_type_str(msg->type), msg->type); 608 609 switch (msg->type) { 610 case TDLS_CMD_TX_ACTION: 611 tdls_process_mgmt_req(msg->bodyptr); 612 break; 613 case TDLS_CMD_ADD_STA: 614 tdls_process_add_peer(msg->bodyptr); 615 break; 616 case TDLS_CMD_CHANGE_STA: 617 tdls_process_update_peer(msg->bodyptr); 618 break; 619 case TDLS_CMD_ENABLE_LINK: 620 tdls_process_enable_link(msg->bodyptr); 621 break; 622 case TDLS_CMD_DISABLE_LINK: 623 tdls_process_del_peer(msg->bodyptr); 624 break; 625 case TDLS_CMD_CONFIG_FORCE_PEER: 626 tdls_process_setup_peer(msg->bodyptr); 627 break; 628 case TDLS_CMD_REMOVE_FORCE_PEER: 629 tdls_process_remove_force_peer(msg->bodyptr); 630 break; 631 case TDLS_CMD_STATS_UPDATE: 632 break; 633 case TDLS_CMD_CONFIG_UPDATE: 634 break; 635 case TDLS_CMD_SET_RESPONDER: 636 tdls_set_responder(msg->bodyptr); 637 break; 638 case TDLS_CMD_SCAN_DONE: 639 tdls_scan_done_callback(msg->bodyptr); 640 break; 641 case TDLS_NOTIFY_STA_CONNECTION: 642 tdls_notify_sta_connect(msg->bodyptr); 643 break; 644 case TDLS_NOTIFY_STA_DISCONNECTION: 645 tdls_notify_sta_disconnect(msg->bodyptr); 646 break; 647 case TDLS_CMD_SET_TDLS_MODE: 648 tdls_set_operation_mode(msg->bodyptr); 649 break; 650 case TDLS_CMD_SESSION_DECREMENT: 651 tdls_process_decrement_active_session(msg->bodyptr); 652 break; 653 case TDLS_CMD_SESSION_INCREMENT: 654 tdls_process_policy_mgr_notification(msg->bodyptr); 655 break; 656 case TDLS_CMD_TEARDOWN_LINKS: 657 tdls_teardown_connections(msg->bodyptr); 658 break; 659 case TDLS_NOTIFY_RESET_ADAPTERS: 660 tdls_notify_reset_adapter(msg->bodyptr); 661 break; 662 case TDLS_CMD_ANTENNA_SWITCH: 663 tdls_process_antenna_switch(msg->bodyptr); 664 break; 665 case TDLS_CMD_GET_ALL_PEERS: 666 tdls_get_all_peers_from_list(msg->bodyptr); 667 break; 668 case TDLS_CMD_SET_OFFCHANNEL: 669 tdls_process_set_offchannel(msg->bodyptr); 670 break; 671 case TDLS_CMD_SET_OFFCHANMODE: 672 tdls_process_set_offchan_mode(msg->bodyptr); 673 break; 674 case TDLS_CMD_SET_SECOFFCHANOFFSET: 675 tdls_process_set_secoffchanneloffset(msg->bodyptr); 676 break; 677 case TDLS_DELETE_ALL_PEERS_INDICATION: 678 tdls_reset_all_peers(msg->bodyptr); 679 break; 680 case TDLS_CMD_START_BSS: 681 tdls_handle_start_bss(msg->bodyptr); 682 break; 683 case TDLS_CMD_SET_LINK_UNFORCE: 684 tdls_handle_link_unforce(msg->bodyptr); 685 break; 686 default: 687 break; 688 } 689 690 return status; 691 } 692 693 QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) 694 { 695 struct wlan_objmgr_vdev *vdev; 696 struct tdls_event_notify *notify; 697 struct tdls_event_info *event; 698 699 if (!msg || !msg->bodyptr) { 700 tdls_err("msg is not valid: %pK", msg); 701 return QDF_STATUS_E_NULL_VALUE; 702 } 703 notify = msg->bodyptr; 704 vdev = notify->vdev; 705 if (!vdev) { 706 tdls_err("NULL vdev object"); 707 qdf_mem_free(notify); 708 return QDF_STATUS_E_NULL_VALUE; 709 } 710 event = ¬ify->event; 711 712 tdls_debug("evt type: %s(%d)", 713 tdls_get_event_type_str(event->message_type), 714 event->message_type); 715 716 switch (event->message_type) { 717 case TDLS_SHOULD_DISCOVER: 718 tdls_process_should_discover(vdev, event); 719 break; 720 case TDLS_SHOULD_TEARDOWN: 721 case TDLS_PEER_DISCONNECTED: 722 tdls_process_should_teardown(vdev, event); 723 break; 724 case TDLS_CONNECTION_TRACKER_NOTIFY: 725 tdls_process_connection_tracker_notify(vdev, event); 726 break; 727 default: 728 break; 729 } 730 731 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 732 qdf_mem_free(notify); 733 734 return QDF_STATUS_SUCCESS; 735 } 736 737 void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, 738 qdf_mc_timer_t *timer, 739 uint32_t expiration_time) 740 { 741 if (QDF_TIMER_STATE_RUNNING != 742 qdf_mc_timer_get_current_state(timer)) 743 qdf_mc_timer_start(timer, expiration_time); 744 } 745 746 /** 747 * tdls_monitor_timers_stop() - stop all monitoring timers 748 * @tdls_vdev: TDLS vdev object 749 * 750 * Return: none 751 */ 752 static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 753 { 754 if (!wlan_vdev_mlme_is_mlo_vdev(tdls_vdev->vdev)) 755 qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); 756 } 757 758 /** 759 * tdls_peer_idle_timers_stop() - stop peer idle timers 760 * @tdls_vdev: TDLS vdev object 761 * 762 * Loop through the idle peer list and stop their timers 763 * 764 * Return: None 765 */ 766 static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 767 { 768 int i; 769 qdf_list_t *head; 770 qdf_list_node_t *p_node; 771 struct tdls_peer *curr_peer; 772 QDF_STATUS status; 773 774 tdls_vdev->discovery_peer_cnt = 0; 775 776 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 777 head = &tdls_vdev->peer_list[i]; 778 status = qdf_list_peek_front(head, &p_node); 779 while (QDF_IS_STATUS_SUCCESS(status)) { 780 curr_peer = qdf_container_of(p_node, struct tdls_peer, 781 node); 782 if (curr_peer->is_peer_idle_timer_initialised) 783 qdf_mc_timer_stop(&curr_peer->peer_idle_timer); 784 status = qdf_list_peek_next(head, p_node, &p_node); 785 } 786 } 787 788 } 789 790 /** 791 * tdls_ct_timers_stop() - stop tdls connection tracker timers 792 * @tdls_vdev: TDLS vdev 793 * 794 * Return: None 795 */ 796 static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 797 { 798 qdf_mc_timer_stop(&tdls_vdev->peer_update_timer); 799 tdls_peer_idle_timers_stop(tdls_vdev); 800 } 801 802 /** 803 * tdls_timers_stop() - stop all the tdls timers running 804 * @tdls_vdev: TDLS vdev 805 * 806 * Return: none 807 */ 808 void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 809 { 810 tdls_monitor_timers_stop(tdls_vdev); 811 tdls_ct_timers_stop(tdls_vdev); 812 } 813 814 QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, 815 struct tdls_vdev_priv_obj **tdls_vdev_obj, 816 struct tdls_soc_priv_obj **tdls_soc_obj) 817 { 818 enum QDF_OPMODE device_mode; 819 820 if (!vdev) 821 return QDF_STATUS_E_FAILURE; 822 823 *tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 824 if (NULL == (*tdls_vdev_obj)) 825 return QDF_STATUS_E_FAILURE; 826 827 *tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 828 if (NULL == (*tdls_soc_obj)) 829 return QDF_STATUS_E_FAILURE; 830 831 device_mode = wlan_vdev_mlme_get_opmode(vdev); 832 833 if (device_mode != QDF_STA_MODE && 834 device_mode != QDF_P2P_CLIENT_MODE) 835 return QDF_STATUS_E_FAILURE; 836 837 return QDF_STATUS_SUCCESS; 838 } 839 840 #ifdef WLAN_FEATURE_11AX 841 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev, 842 qdf_freq_t freq, 843 enum supported_6g_pwr_types pwr_typ) 844 { 845 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 846 struct regulatory_channel *chan; 847 uint8_t chn_idx, num_chan; 848 uint8_t band_mask = BIT(REG_BAND_6G); 849 uint32_t tx_power = 0; 850 851 if (!pdev) 852 return 0; 853 854 /* No power check is required for non 6 Ghz channel */ 855 if (!wlan_reg_is_6ghz_chan_freq(freq)) 856 return 0; 857 858 chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS); 859 if (!chan) 860 return 0; 861 862 num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev, 863 band_mask, 864 chan, 865 REG_CLI_DEF_VLP); 866 867 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 868 if (chan[chn_idx].center_freq == freq) { 869 tdls_debug("VLP power for channel %d is %d", 870 chan[chn_idx].center_freq, 871 chan[chn_idx].tx_power); 872 tx_power = chan[chn_idx].tx_power; 873 } 874 } 875 876 qdf_mem_free(chan); 877 return tx_power; 878 } 879 880 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev, 881 qdf_freq_t freq) 882 { 883 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 884 struct regulatory_channel *chan; 885 bool is_allowed = false; 886 uint8_t country_code[REG_ALPHA2_LEN + 1]; 887 uint8_t chn_idx, num_chan = 0; 888 uint8_t band_mask = BIT(REG_BAND_6G); 889 890 /* Return if freq is not 6 Ghz freq */ 891 if (!wlan_reg_is_6ghz_chan_freq(freq)) 892 return false; 893 894 if (!wlan_cfg80211_tdls_is_fw_6ghz_capable(vdev)) 895 return false; 896 897 if (!pdev) 898 return false; 899 900 wlan_cm_get_country_code(pdev, wlan_vdev_get_id(vdev), country_code); 901 if (!wlan_reg_ctry_support_vlp(country_code)) 902 return false; 903 904 chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS); 905 if (!chan) 906 return false; 907 908 num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev, 909 band_mask, 910 chan, 911 REG_CLI_DEF_VLP); 912 tdls_debug("Country IE:%c%c freq %d num_chan %d", country_code[0], 913 country_code[1], freq, num_chan); 914 if (!num_chan) 915 goto error; 916 917 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 918 if (chan[chn_idx].center_freq == freq) { 919 tdls_debug("TDLS 6ghz freq: %d supports VLP power", 920 chan[chn_idx].center_freq); 921 is_allowed = true; 922 break; 923 } 924 } 925 926 error: 927 qdf_mem_free(chan); 928 return is_allowed; 929 } 930 #else 931 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev, 932 qdf_freq_t freq) 933 { 934 return false; 935 } 936 937 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev, 938 qdf_freq_t freq, 939 enum supported_6g_pwr_types pwr_typ) 940 { 941 return 0; 942 } 943 #endif 944 945 bool tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj *tdls_soc_obj) 946 { 947 return tdls_soc_obj->is_user_tdls_enable; 948 } 949 950 bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) 951 { 952 struct tdls_vdev_priv_obj *tdls_vdev_obj; 953 struct tdls_soc_priv_obj *tdls_soc_obj; 954 bool state = false; 955 qdf_freq_t ch_freq; 956 QDF_STATUS status; 957 uint32_t connection_count; 958 uint8_t sta_count, p2p_cli_count; 959 960 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); 961 if (QDF_IS_STATUS_ERROR(status)) 962 return state; 963 964 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 965 if (QDF_IS_STATUS_ERROR(status)) { 966 tdls_err("Failed to get TDLS objects"); 967 goto exit; 968 } 969 970 if (wlan_vdev_mlme_is_mlo_vdev(vdev) && 971 !wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc)) { 972 tdls_debug("TDLS not supported on MLO vdev"); 973 goto exit; 974 } 975 976 if (wlan_nan_is_disc_active(tdls_soc_obj->soc)) { 977 tdls_err("NAN active. NAN+TDLS not supported"); 978 goto exit; 979 } 980 981 if (!tdls_check_is_user_tdls_enable(tdls_soc_obj)) { 982 tdls_err("TDLS Disabled from userspace"); 983 goto exit; 984 } 985 986 connection_count = 987 policy_mgr_get_connection_count_with_mlo(tdls_soc_obj->soc); 988 sta_count = 989 policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, 990 PM_STA_MODE, NULL); 991 p2p_cli_count = 992 policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, 993 PM_P2P_CLIENT_MODE, 994 NULL); 995 if ((connection_count == 1 && (sta_count || p2p_cli_count)) || 996 (connection_count > 1 && 997 tdls_is_concurrency_allowed(tdls_soc_obj->soc))) { 998 state = true; 999 } else { 1000 tdls_warn("Concurrent sessions exist disable TDLS"); 1001 goto exit; 1002 } 1003 1004 ch_freq = wlan_get_operation_chan_freq(vdev); 1005 if (wlan_reg_is_6ghz_chan_freq(ch_freq) && 1006 !tdls_is_6g_freq_allowed(vdev, ch_freq)) { 1007 tdls_debug("6GHz freq:%d not allowed for TDLS", ch_freq); 1008 state = false; 1009 } 1010 1011 exit: 1012 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1013 1014 return state; 1015 } 1016 1017 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES 1018 bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) 1019 { 1020 if (!wlan_psoc_nif_fw_ext2_cap_get(psoc, 1021 WLAN_TDLS_CONCURRENCIES_SUPPORT)) { 1022 tdls_debug("fw cap is not advertised"); 1023 return false; 1024 } 1025 1026 if (policy_mgr_get_connection_count_with_mlo(psoc) > 1027 WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED) 1028 return false; 1029 1030 if (policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1031 NULL) > 1) { 1032 tdls_debug("More than one STA exist. Don't allow TDLS"); 1033 return false; 1034 } 1035 1036 if (policy_mgr_is_mcc_on_any_sta_vdev(psoc)) { 1037 tdls_debug("Base channel MCC. Don't allow TDLS"); 1038 return false; 1039 } 1040 1041 /* 1042 * Don't enable TDLS for P2P_CLI in concurrency cases 1043 */ 1044 if (policy_mgr_get_connection_count_with_mlo(psoc) > 1 && 1045 !policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1046 NULL)) 1047 return false; 1048 1049 return true; 1050 } 1051 #endif 1052 1053 void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc, 1054 struct wlan_objmgr_vdev *vdev) 1055 { 1056 struct tdls_soc_priv_obj *tdls_soc_obj; 1057 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1058 uint32_t tdls_feature_flags = 0, sta_count, p2p_count; 1059 bool state = false; 1060 bool tdls_mlo; 1061 QDF_STATUS status; 1062 1063 if (!tdls_check_is_tdls_allowed(vdev)) 1064 return; 1065 1066 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1067 if (QDF_IS_STATUS_ERROR(status)) { 1068 tdls_err("Failed to get TDLS objects"); 1069 return; 1070 } 1071 1072 qdf_atomic_set(&tdls_soc_obj->timer_cnt, 0); 1073 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 1074 if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode || 1075 TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode || 1076 !TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) { 1077 state = false; 1078 goto set_state; 1079 } 1080 1081 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1082 NULL); 1083 p2p_count = 1084 policy_mgr_mode_specific_connection_count(psoc, 1085 PM_P2P_CLIENT_MODE, 1086 NULL); 1087 tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(psoc); 1088 if (sta_count == 1 || (sta_count >= 2 && tdls_mlo) || 1089 (policy_mgr_get_connection_count_with_mlo(psoc) == 1 && 1090 p2p_count == 1)) { 1091 state = true; 1092 /* 1093 * In case of TDLS external control, peer should be added 1094 * by the user space to start connection tracker. 1095 */ 1096 if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags) && 1097 !tdls_soc_obj->tdls_external_peer_count) 1098 state = false; 1099 1100 goto set_state; 1101 } 1102 1103 state = false; 1104 1105 set_state: 1106 tdls_soc_obj->enable_tdls_connection_tracker = state; 1107 if (tdls_soc_obj->enable_tdls_connection_tracker) 1108 tdls_implicit_enable(tdls_vdev_obj); 1109 else 1110 tdls_implicit_disable(tdls_vdev_obj); 1111 1112 tdls_debug("vdev:%d enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x", 1113 wlan_vdev_get_id(vdev), 1114 tdls_soc_obj->enable_tdls_connection_tracker, 1115 tdls_soc_obj->tdls_current_mode, tdls_feature_flags); 1116 } 1117 1118 void tdls_set_user_tdls_enable(struct wlan_objmgr_vdev *vdev, 1119 bool is_user_tdls_enable) 1120 { 1121 QDF_STATUS status; 1122 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1123 struct tdls_soc_priv_obj *tdls_soc_obj; 1124 1125 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); 1126 if (QDF_IS_STATUS_ERROR(status)) 1127 return; 1128 1129 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1130 if (QDF_IS_STATUS_ERROR(status)) { 1131 tdls_err("Failed to get TDLS objects"); 1132 goto exit; 1133 } 1134 1135 tdls_soc_obj->is_user_tdls_enable = is_user_tdls_enable; 1136 tdls_debug("TDLS enable:%d via userspace", 1137 tdls_soc_obj->is_user_tdls_enable); 1138 1139 exit: 1140 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1141 } 1142 1143 QDF_STATUS 1144 tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) 1145 { 1146 struct wlan_objmgr_vdev *tdls_vdev; 1147 struct tdls_vdev_priv_obj *tdls_priv_vdev; 1148 struct tdls_soc_priv_obj *tdls_priv_soc; 1149 QDF_STATUS status; 1150 1151 if (!psoc) { 1152 tdls_err("psoc is NULL"); 1153 return QDF_STATUS_E_NULL_VALUE; 1154 } 1155 1156 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); 1157 if (!tdls_vdev) { 1158 tdls_debug("No TDLS vdev"); 1159 return QDF_STATUS_E_NULL_VALUE; 1160 } 1161 1162 status = tdls_get_vdev_objects(tdls_vdev, &tdls_priv_vdev, 1163 &tdls_priv_soc); 1164 if (QDF_IS_STATUS_ERROR(status)) { 1165 tdls_debug("TDLS vdev objects NULL"); 1166 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1167 return QDF_STATUS_E_NULL_VALUE; 1168 } 1169 1170 if (!tdls_check_is_tdls_allowed(tdls_vdev)) { 1171 tdls_disable_offchan_and_teardown_links(tdls_vdev); 1172 tdls_debug("Disable the tdls in FW due to concurrency"); 1173 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1174 return QDF_STATUS_E_NULL_VALUE; 1175 } 1176 1177 tdls_debug("vdev:%d enter", wlan_vdev_get_id(tdls_vdev)); 1178 1179 tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH); 1180 tdls_set_ct_mode(psoc, tdls_vdev); 1181 1182 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1183 tdls_debug("exit "); 1184 1185 return QDF_STATUS_SUCCESS; 1186 } 1187 1188 QDF_STATUS 1189 tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc) 1190 { 1191 struct tdls_soc_priv_obj *tdls_priv_soc; 1192 struct tdls_vdev_priv_obj *tdls_priv_vdev; 1193 struct wlan_objmgr_vdev *tdls_obj_vdev; 1194 uint8_t vdev_id; 1195 QDF_STATUS status; 1196 1197 tdls_debug("Enter"); 1198 if (!psoc) 1199 return QDF_STATUS_E_NULL_VALUE; 1200 1201 if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) && 1202 !policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) && 1203 policy_mgr_is_current_hwmode_dbs(psoc)) { 1204 tdls_debug("Current HW mode is 1*1 DBS. Wait for Opportunistic timer to expire to enable TDLS in FW"); 1205 return QDF_STATUS_SUCCESS; 1206 } 1207 1208 tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); 1209 if (!tdls_obj_vdev) 1210 return QDF_STATUS_E_FAILURE; 1211 1212 if (!tdls_check_is_tdls_allowed(tdls_obj_vdev)) 1213 goto release_ref; 1214 1215 /* 1216 * 2 Port MCC -> 1 port scenario or 1217 * 3 Port MCC -> 2 port SCC scenario or 1218 * 4 Port -> 3 Port SCC scenario 1219 * So enable TDLS in firmware 1220 */ 1221 tdls_debug("Enable TDLS in FW and host as active sta/p2p_cli interface is present"); 1222 vdev_id = wlan_vdev_get_id(tdls_obj_vdev); 1223 status = tdls_get_vdev_objects(tdls_obj_vdev, &tdls_priv_vdev, 1224 &tdls_priv_soc); 1225 if (QDF_IS_STATUS_ERROR(status)) 1226 goto release_ref; 1227 1228 tdls_send_update_to_fw(tdls_priv_vdev, tdls_priv_soc, 1229 mlme_get_tdls_prohibited(tdls_obj_vdev), 1230 mlme_get_tdls_chan_switch_prohibited(tdls_obj_vdev), 1231 true, vdev_id); 1232 if (tdls_priv_soc->connected_peer_count == 1) 1233 tdls_set_tdls_offchannelmode(tdls_obj_vdev, ENABLE_CHANSWITCH); 1234 1235 release_ref: 1236 wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); 1237 1238 return QDF_STATUS_SUCCESS; 1239 } 1240 1241 #ifdef WLAN_FEATURE_11BE_MLO 1242 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1243 uint8_t index, 1244 wlan_objmgr_ref_dbgid dbg_id) 1245 { 1246 struct wlan_mlo_dev_context *mlo_dev_ctx; 1247 struct wlan_objmgr_vdev *mlo_vdev; 1248 1249 if (!vdev) 1250 return NULL; 1251 1252 mlo_dev_ctx = vdev->mlo_dev_ctx; 1253 if (!mlo_dev_ctx) 1254 return NULL; 1255 1256 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[index]; 1257 if (mlo_vdev && 1258 wlan_objmgr_vdev_try_get_ref(mlo_vdev, dbg_id) == 1259 QDF_STATUS_SUCCESS) 1260 return mlo_vdev; 1261 1262 return NULL; 1263 } 1264 1265 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1266 wlan_objmgr_ref_dbgid dbg_id) 1267 { 1268 if (!vdev) 1269 return; 1270 1271 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 1272 } 1273 #else 1274 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1275 uint8_t index, 1276 wlan_objmgr_ref_dbgid dbg_id) 1277 { 1278 return NULL; 1279 } 1280 1281 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1282 wlan_objmgr_ref_dbgid dbg_id) 1283 { 1284 } 1285 #endif 1286 /** 1287 * tdls_get_vdev() - Get tdls specific vdev object manager 1288 * @psoc: wlan psoc object manager 1289 * @dbg_id: debug id 1290 * 1291 * If TDLS possible, return the corresponding vdev 1292 * to enable TDLS in the system. 1293 * 1294 * Return: vdev manager pointer or NULL. 1295 */ 1296 struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, 1297 wlan_objmgr_ref_dbgid dbg_id) 1298 { 1299 uint32_t vdev_id; 1300 1301 vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); 1302 if (WLAN_INVALID_VDEV_ID != vdev_id) 1303 return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1304 dbg_id); 1305 /* 1306 * For P2P_Client mode, TDLS is not supported on concurrency 1307 * so return P2P_client vdev only if P2P client mode exists without 1308 * any concurreny 1309 */ 1310 vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); 1311 if (WLAN_INVALID_VDEV_ID != vdev_id && 1312 policy_mgr_get_connection_count_with_mlo(psoc) == 1) 1313 return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1314 dbg_id); 1315 1316 return NULL; 1317 } 1318 1319 static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg) 1320 { 1321 void *ptr = msg->bodyptr; 1322 struct wlan_objmgr_vdev *vdev = NULL; 1323 1324 switch (msg->type) { 1325 case TDLS_NOTIFY_STA_DISCONNECTION: 1326 vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; 1327 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1328 qdf_mem_free(ptr); 1329 break; 1330 1331 case TDLS_DELETE_ALL_PEERS_INDICATION: 1332 vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev; 1333 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1334 qdf_mem_free(ptr); 1335 break; 1336 1337 case TDLS_CMD_SCAN_DONE: 1338 case TDLS_CMD_SESSION_INCREMENT: 1339 case TDLS_CMD_SESSION_DECREMENT: 1340 break; 1341 } 1342 1343 return QDF_STATUS_SUCCESS; 1344 } 1345 1346 /** 1347 * tdls_process_session_update() - update session count information 1348 * @psoc: soc object 1349 * @cmd_type: type of command 1350 * 1351 * update the session information in connection tracker 1352 * 1353 * Return: None 1354 */ 1355 static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, 1356 enum tdls_command_type cmd_type) 1357 { 1358 struct scheduler_msg msg = {0}; 1359 QDF_STATUS status; 1360 1361 msg.bodyptr = psoc; 1362 msg.callback = tdls_process_cmd; 1363 msg.flush_callback = tdls_post_msg_flush_cb; 1364 msg.type = (uint16_t)cmd_type; 1365 1366 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1367 QDF_MODULE_ID_TDLS, 1368 QDF_MODULE_ID_OS_IF, &msg); 1369 if (QDF_IS_STATUS_ERROR(status)) 1370 tdls_alert("message post failed "); 1371 } 1372 1373 void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc) 1374 { 1375 tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT); 1376 } 1377 1378 void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) 1379 { 1380 tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); 1381 } 1382 1383 void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, 1384 struct tdls_soc_priv_obj *tdls_soc_obj, 1385 bool tdls_prohibited, 1386 bool tdls_chan_swit_prohibited, 1387 bool sta_connect_event, 1388 uint8_t session_id) 1389 { 1390 struct tdls_info *tdls_info_to_fw; 1391 struct tdls_config_params *threshold_params; 1392 uint32_t tdls_feature_flags; 1393 QDF_STATUS status; 1394 bool tdls_mlo; 1395 1396 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 1397 if (!TDLS_IS_ENABLED(tdls_feature_flags)) { 1398 tdls_debug("TDLS mode is not enabled"); 1399 return; 1400 } 1401 1402 tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc); 1403 1404 /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ 1405 if (sta_connect_event) { 1406 if (tdls_prohibited) { 1407 tdls_soc_obj->tdls_current_mode = 1408 TDLS_SUPPORT_DISABLED; 1409 } else { 1410 if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) 1411 tdls_soc_obj->tdls_current_mode = 1412 TDLS_SUPPORT_EXP_TRIG_ONLY; 1413 else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( 1414 tdls_feature_flags)) 1415 tdls_soc_obj->tdls_current_mode = 1416 TDLS_SUPPORT_EXT_CONTROL; 1417 else 1418 tdls_soc_obj->tdls_current_mode = 1419 TDLS_SUPPORT_IMP_MODE; 1420 } 1421 } else { 1422 tdls_soc_obj->tdls_current_mode = 1423 TDLS_SUPPORT_DISABLED; 1424 } 1425 1426 tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); 1427 if (!tdls_info_to_fw) 1428 return; 1429 1430 threshold_params = &tdls_vdev_obj->threshold_config; 1431 1432 tdls_info_to_fw->notification_interval_ms = 1433 threshold_params->tx_period_t; 1434 tdls_info_to_fw->tx_discovery_threshold = 1435 threshold_params->tx_packet_n; 1436 tdls_info_to_fw->tx_teardown_threshold = 1437 threshold_params->idle_packet_n; 1438 tdls_info_to_fw->rssi_teardown_threshold = 1439 threshold_params->rssi_teardown_threshold; 1440 tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta; 1441 tdls_info_to_fw->vdev_id = session_id; 1442 1443 /* record the session id in vdev context */ 1444 tdls_vdev_obj->session_id = session_id; 1445 tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; 1446 tdls_info_to_fw->tdls_options = 0; 1447 1448 /* 1449 * Do not enable TDLS offchannel, if AP prohibited TDLS 1450 * channel switch 1451 */ 1452 if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && 1453 (!tdls_chan_swit_prohibited)) 1454 tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN; 1455 1456 if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags)) 1457 tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA; 1458 if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags)) 1459 tdls_info_to_fw->tdls_options |= ENA_TDLS_SLEEP_STA; 1460 1461 1462 tdls_info_to_fw->peer_traffic_ind_window = 1463 tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window; 1464 tdls_info_to_fw->peer_traffic_response_timeout = 1465 tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout; 1466 tdls_info_to_fw->puapsd_mask = 1467 tdls_soc_obj->tdls_configs.tdls_uapsd_mask; 1468 tdls_info_to_fw->puapsd_inactivity_time = 1469 tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time; 1470 tdls_info_to_fw->puapsd_rx_frame_threshold = 1471 tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold; 1472 tdls_info_to_fw->teardown_notification_ms = 1473 tdls_soc_obj->tdls_configs.tdls_idle_timeout; 1474 tdls_info_to_fw->tdls_peer_kickout_threshold = 1475 tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold; 1476 tdls_info_to_fw->tdls_discovery_wake_timeout = 1477 tdls_soc_obj->tdls_configs.tdls_discovery_wake_timeout; 1478 1479 status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw); 1480 if (QDF_IS_STATUS_ERROR(status)) 1481 goto done; 1482 1483 if (sta_connect_event) { 1484 tdls_soc_obj->set_state_info.vdev_id = session_id; 1485 } 1486 1487 tdls_debug("FW tdls state sent for vdev id %d", session_id); 1488 done: 1489 qdf_mem_free(tdls_info_to_fw); 1490 return; 1491 } 1492 1493 void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev) 1494 { 1495 struct wlan_objmgr_psoc *psoc; 1496 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1497 struct tdls_soc_priv_obj *tdls_soc_obj; 1498 enum QDF_OPMODE opmode; 1499 QDF_STATUS status; 1500 uint8_t sta_count; 1501 1502 psoc = wlan_vdev_get_psoc(vdev); 1503 if (!psoc) 1504 return; 1505 1506 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1507 NULL); 1508 opmode = wlan_vdev_mlme_get_opmode(vdev); 1509 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1510 tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev"); 1511 return; 1512 } 1513 1514 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1515 if (QDF_IS_STATUS_ERROR(status)) 1516 return; 1517 1518 tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, 1519 mlme_get_tdls_prohibited(vdev), 1520 mlme_get_tdls_chan_switch_prohibited(vdev), 1521 true, wlan_vdev_get_id(vdev)); 1522 1523 /* check and set the connection tracker */ 1524 tdls_set_ct_mode(tdls_soc_obj->soc, vdev); 1525 } 1526 1527 static QDF_STATUS 1528 tdls_process_sta_connect(struct tdls_sta_notify_params *notify) 1529 { 1530 if (!tdls_check_is_tdls_allowed(notify->vdev)) 1531 return QDF_STATUS_E_NOSUPPORT; 1532 1533 tdls_process_enable_for_vdev(notify->vdev); 1534 1535 return QDF_STATUS_SUCCESS; 1536 } 1537 1538 QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) 1539 { 1540 QDF_STATUS status; 1541 1542 if (!notify) { 1543 tdls_err("invalid param"); 1544 return QDF_STATUS_E_INVAL; 1545 } 1546 1547 if (!notify->vdev) { 1548 tdls_err("invalid param"); 1549 qdf_mem_free(notify); 1550 return QDF_STATUS_E_INVAL; 1551 } 1552 1553 status = tdls_process_sta_connect(notify); 1554 1555 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1556 qdf_mem_free(notify); 1557 1558 return status; 1559 } 1560 1561 static QDF_STATUS 1562 tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) 1563 { 1564 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1565 struct tdls_soc_priv_obj *tdls_soc_obj; 1566 struct wlan_objmgr_vdev *temp_vdev = NULL; 1567 uint8_t vdev_id; 1568 QDF_STATUS status; 1569 1570 status = tdls_get_vdev_objects(notify->vdev, &tdls_vdev_obj, 1571 &tdls_soc_obj); 1572 if (QDF_IS_STATUS_ERROR(status)) 1573 return status; 1574 1575 /* if the disconnect comes from user space, we have to delete all the 1576 * tdls peers before sending the set state cmd. 1577 */ 1578 if (notify->user_disconnect) 1579 return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj); 1580 1581 tdls_debug("Check and update TDLS state for vdev:%d", 1582 notify->session_id); 1583 1584 /* Disassociation event */ 1585 tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false, 1586 false, false, notify->session_id); 1587 1588 /* If concurrency is not marked, then we have to 1589 * check, whether TDLS could be enabled in the 1590 * system after this disassoc event. 1591 */ 1592 if (notify->lfr_roam) 1593 return status; 1594 1595 temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID); 1596 if (!temp_vdev) 1597 return status; 1598 1599 vdev_id = wlan_vdev_get_id(temp_vdev); 1600 status = tdls_get_vdev_objects(temp_vdev, &tdls_vdev_obj, 1601 &tdls_soc_obj); 1602 if (QDF_IS_STATUS_ERROR(status)) { 1603 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID); 1604 return status; 1605 } 1606 1607 tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, 1608 mlme_get_tdls_prohibited(temp_vdev), 1609 mlme_get_tdls_chan_switch_prohibited(temp_vdev), 1610 true, vdev_id); 1611 1612 /* Check and set the connection tracker and implicit timers */ 1613 tdls_set_ct_mode(tdls_soc_obj->soc, temp_vdev); 1614 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID); 1615 1616 wlan_vdev_mlme_feat_ext2_cap_clear(notify->vdev, 1617 WLAN_VDEV_FEXT2_MLO_STA_TDLS); 1618 1619 return status; 1620 } 1621 1622 QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) 1623 { 1624 QDF_STATUS status; 1625 struct wlan_objmgr_vdev *vdev; 1626 enum QDF_OPMODE opmode; 1627 struct wlan_objmgr_psoc *psoc; 1628 uint8_t sta_count; 1629 1630 if (!notify) { 1631 tdls_err("invalid param"); 1632 return QDF_STATUS_E_INVAL; 1633 } 1634 1635 vdev = notify->vdev; 1636 if (!vdev) { 1637 tdls_err("invalid param"); 1638 qdf_mem_free(notify); 1639 return QDF_STATUS_E_INVAL; 1640 } 1641 1642 psoc = wlan_vdev_get_psoc(vdev); 1643 if (!psoc) { 1644 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1645 qdf_mem_free(notify); 1646 return QDF_STATUS_E_INVAL; 1647 } 1648 1649 opmode = wlan_vdev_mlme_get_opmode(vdev); 1650 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1651 NULL); 1652 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1653 tdls_debug("STA + P2P concurrency. No action on P2P vdev"); 1654 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1655 qdf_mem_free(notify); 1656 return QDF_STATUS_E_INVAL; 1657 } 1658 1659 status = tdls_process_sta_disconnect(notify); 1660 1661 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1662 qdf_mem_free(notify); 1663 1664 return status; 1665 } 1666 1667 static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) 1668 { 1669 struct tdls_vdev_priv_obj *tdls_vdev; 1670 1671 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1672 if (!tdls_vdev) 1673 return; 1674 tdls_timers_stop(tdls_vdev); 1675 } 1676 1677 void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) 1678 { 1679 if (!vdev) { 1680 QDF_ASSERT(0); 1681 return; 1682 } 1683 1684 if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, 1685 WLAN_TDLS_NB_ID)) 1686 return; 1687 1688 tdls_process_reset_adapter(vdev); 1689 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1690 } 1691 1692 QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, 1693 uint8_t vdev_id) 1694 { 1695 struct scheduler_msg msg = {0, }; 1696 struct tdls_sta_notify_params *notify; 1697 QDF_STATUS status; 1698 struct wlan_objmgr_vdev *vdev; 1699 1700 notify = qdf_mem_malloc(sizeof(*notify)); 1701 if (!notify) 1702 return QDF_STATUS_E_NULL_VALUE; 1703 1704 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 1705 vdev_id, 1706 WLAN_TDLS_NB_ID); 1707 1708 if (!vdev) { 1709 tdls_err("vdev not exist for the vdev id %d", 1710 vdev_id); 1711 qdf_mem_free(notify); 1712 return QDF_STATUS_E_INVAL; 1713 } 1714 1715 notify->lfr_roam = true; 1716 notify->tdls_chan_swit_prohibited = false; 1717 notify->tdls_prohibited = false; 1718 notify->session_id = vdev_id; 1719 notify->vdev = vdev; 1720 notify->user_disconnect = false; 1721 1722 msg.bodyptr = notify; 1723 msg.callback = tdls_process_cmd; 1724 msg.flush_callback = tdls_post_msg_flush_cb; 1725 msg.type = TDLS_NOTIFY_STA_DISCONNECTION; 1726 1727 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1728 QDF_MODULE_ID_TDLS, 1729 QDF_MODULE_ID_OS_IF, &msg); 1730 if (QDF_IS_STATUS_ERROR(status)) { 1731 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1732 qdf_mem_free(notify); 1733 tdls_alert("message post failed "); 1734 1735 return QDF_STATUS_E_FAILURE; 1736 } 1737 1738 return QDF_STATUS_SUCCESS; 1739 } 1740 1741 static 1742 QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, 1743 uint8_t vdev_id) 1744 { 1745 struct scheduler_msg msg = {0, }; 1746 struct tdls_delete_all_peers_params *indication; 1747 QDF_STATUS status; 1748 struct wlan_objmgr_vdev *vdev; 1749 1750 indication = qdf_mem_malloc(sizeof(*indication)); 1751 if (!indication) 1752 return QDF_STATUS_E_NULL_VALUE; 1753 1754 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1755 WLAN_TDLS_SB_ID); 1756 if (!vdev) { 1757 tdls_err("vdev:%d does not exist", vdev_id); 1758 qdf_mem_free(indication); 1759 return QDF_STATUS_E_INVAL; 1760 } 1761 1762 indication->vdev = vdev; 1763 1764 msg.bodyptr = indication; 1765 msg.callback = tdls_process_cmd; 1766 msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; 1767 msg.flush_callback = tdls_post_msg_flush_cb; 1768 1769 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1770 QDF_MODULE_ID_TDLS, 1771 QDF_MODULE_ID_OS_IF, &msg); 1772 if (QDF_IS_STATUS_ERROR(status)) { 1773 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1774 qdf_mem_free(indication); 1775 tdls_alert("message post failed "); 1776 return QDF_STATUS_E_FAILURE; 1777 } 1778 1779 return QDF_STATUS_SUCCESS; 1780 } 1781 1782 QDF_STATUS 1783 tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc, 1784 uint8_t vdev_id) 1785 { 1786 struct wlan_objmgr_pdev *pdev; 1787 uint32_t pdev_id; 1788 enum QDF_OPMODE opmode; 1789 uint8_t sta_count = 1790 policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1791 NULL); 1792 1793 pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, vdev_id, WLAN_TDLS_SB_ID); 1794 if (pdev_id == WLAN_INVALID_PDEV_ID) { 1795 tdls_debug("Invalid pdev id"); 1796 return QDF_STATUS_E_INVAL; 1797 } 1798 1799 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_TDLS_SB_ID); 1800 if (!pdev) { 1801 tdls_debug("pdev is NULL"); 1802 return QDF_STATUS_E_INVAL; 1803 } 1804 1805 opmode = wlan_get_opmode_from_vdev_id(pdev, vdev_id); 1806 wlan_objmgr_pdev_release_ref(pdev, WLAN_TDLS_SB_ID); 1807 1808 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1809 tdls_debug("STA + P2P concurrency. No action on P2P vdev"); 1810 return QDF_STATUS_E_INVAL; 1811 } 1812 1813 return tdls_delete_all_peers_indication(psoc, vdev_id); 1814 } 1815 1816 /** 1817 * tdls_set_mode_in_vdev() - set TDLS mode 1818 * @tdls_vdev: tdls vdev object 1819 * @tdls_soc: tdls soc object 1820 * @tdls_mode: TDLS mode 1821 * @source: TDLS disable source enum values 1822 * 1823 * Return: Void 1824 */ 1825 static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, 1826 struct tdls_soc_priv_obj *tdls_soc, 1827 enum tdls_feature_mode tdls_mode, 1828 enum tdls_disable_sources source) 1829 { 1830 if (!tdls_vdev) 1831 return; 1832 tdls_debug("enter tdls mode is %d", tdls_mode); 1833 1834 if (TDLS_SUPPORT_IMP_MODE == tdls_mode || 1835 TDLS_SUPPORT_EXT_CONTROL == tdls_mode) { 1836 clear_bit((unsigned long)source, 1837 &tdls_soc->tdls_source_bitmap); 1838 /* 1839 * Check if any TDLS source bit is set and if 1840 * bitmap is not zero then we should not 1841 * enable TDLS 1842 */ 1843 if (tdls_soc->tdls_source_bitmap) { 1844 tdls_notice("Don't enable TDLS, source bitmap: %lu", 1845 tdls_soc->tdls_source_bitmap); 1846 return; 1847 } 1848 tdls_implicit_enable(tdls_vdev); 1849 /* tdls implicit mode is enabled, so 1850 * enable the connection tracker 1851 */ 1852 tdls_soc->enable_tdls_connection_tracker = 1853 true; 1854 } else if (TDLS_SUPPORT_DISABLED == tdls_mode) { 1855 set_bit((unsigned long)source, 1856 &tdls_soc->tdls_source_bitmap); 1857 tdls_implicit_disable(tdls_vdev); 1858 /* If tdls implicit mode is disabled, then 1859 * stop the connection tracker. 1860 */ 1861 tdls_soc->enable_tdls_connection_tracker = false; 1862 } else if (TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_mode) { 1863 clear_bit((unsigned long)source, 1864 &tdls_soc->tdls_source_bitmap); 1865 tdls_implicit_disable(tdls_vdev); 1866 /* If tdls implicit mode is disabled, then 1867 * stop the connection tracker. 1868 */ 1869 tdls_soc->enable_tdls_connection_tracker = false; 1870 1871 /* 1872 * Check if any TDLS source bit is set and if 1873 * bitmap is not zero then we should not 1874 * enable TDLS 1875 */ 1876 if (tdls_soc->tdls_source_bitmap) 1877 return; 1878 } 1879 tdls_debug("exit "); 1880 } 1881 1882 /** 1883 * tdls_set_current_mode() - set TDLS mode 1884 * @tdls_soc: tdls soc object 1885 * @tdls_mode: TDLS mode 1886 * @update_last: indicate to record the last tdls mode 1887 * @source: TDLS disable source enum values 1888 * 1889 * Return: Void 1890 */ 1891 static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, 1892 enum tdls_feature_mode tdls_mode, 1893 bool update_last, 1894 enum tdls_disable_sources source) 1895 { 1896 struct wlan_objmgr_vdev *vdev; 1897 struct tdls_vdev_priv_obj *tdls_vdev; 1898 1899 if (!tdls_soc) 1900 return; 1901 1902 tdls_debug("mode %d", (int)tdls_mode); 1903 1904 if (update_last) 1905 tdls_soc->tdls_last_mode = tdls_mode; 1906 1907 if (tdls_soc->tdls_current_mode == tdls_mode) { 1908 tdls_debug("already in mode %d", tdls_mode); 1909 1910 switch (tdls_mode) { 1911 /* TDLS is already enabled hence clear source mask, return */ 1912 case TDLS_SUPPORT_IMP_MODE: 1913 case TDLS_SUPPORT_EXP_TRIG_ONLY: 1914 case TDLS_SUPPORT_EXT_CONTROL: 1915 clear_bit((unsigned long)source, 1916 &tdls_soc->tdls_source_bitmap); 1917 tdls_debug("clear source mask:%d", source); 1918 return; 1919 /* TDLS is already disabled hence set source mask, return */ 1920 case TDLS_SUPPORT_DISABLED: 1921 set_bit((unsigned long)source, 1922 &tdls_soc->tdls_source_bitmap); 1923 tdls_debug("set source mask:%d", source); 1924 return; 1925 default: 1926 return; 1927 } 1928 } 1929 1930 /* get sta vdev */ 1931 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, 1932 QDF_STA_MODE, 1933 WLAN_TDLS_NB_ID); 1934 if (vdev) { 1935 tdls_debug("set mode in tdls vdev "); 1936 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1937 if (tdls_vdev) 1938 tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, 1939 tdls_mode, source); 1940 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1941 } 1942 1943 /* get p2p client vdev */ 1944 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, 1945 QDF_P2P_CLIENT_MODE, 1946 WLAN_TDLS_NB_ID); 1947 if (vdev) { 1948 tdls_debug("set mode in tdls vdev "); 1949 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1950 if (tdls_vdev) 1951 tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, 1952 tdls_mode, source); 1953 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1954 } 1955 1956 if (!update_last) 1957 tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode; 1958 1959 tdls_soc->tdls_current_mode = tdls_mode; 1960 1961 } 1962 1963 QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) 1964 { 1965 struct tdls_soc_priv_obj *tdls_soc; 1966 struct tdls_vdev_priv_obj *tdls_vdev; 1967 QDF_STATUS status; 1968 1969 if (!tdls_set_mode) 1970 return QDF_STATUS_E_INVAL; 1971 1972 if (!tdls_set_mode->vdev) { 1973 qdf_mem_free(tdls_set_mode); 1974 return QDF_STATUS_E_INVAL; 1975 } 1976 1977 status = tdls_get_vdev_objects(tdls_set_mode->vdev, 1978 &tdls_vdev, &tdls_soc); 1979 1980 if (QDF_IS_STATUS_ERROR(status)) 1981 goto release_mode_ref; 1982 1983 tdls_set_current_mode(tdls_soc, 1984 tdls_set_mode->tdls_mode, 1985 tdls_set_mode->update_last, 1986 tdls_set_mode->source); 1987 1988 release_mode_ref: 1989 wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID); 1990 qdf_mem_free(tdls_set_mode); 1991 return status; 1992 } 1993 1994 /** 1995 * tdls_scan_done_callback() - callback for tdls scan done event 1996 * @tdls_soc: tdls soc object 1997 * 1998 * Return: Void 1999 */ 2000 void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) 2001 { 2002 if (!tdls_soc) 2003 return; 2004 2005 /* if tdls was enabled before scan, re-enable tdls mode */ 2006 if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || 2007 TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || 2008 TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) 2009 tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, 2010 false, TDLS_SET_MODE_SOURCE_SCAN); 2011 } 2012 2013 /** 2014 * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue 2015 * @tdls_soc: tdls soc object 2016 * 2017 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE 2018 */ 2019 static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) 2020 { 2021 struct scheduler_msg msg = {0, }; 2022 2023 if (!tdls_soc) { 2024 tdls_err("tdls_soc: %pK ", tdls_soc); 2025 return QDF_STATUS_E_NULL_VALUE; 2026 } 2027 2028 msg.bodyptr = tdls_soc; 2029 msg.callback = tdls_process_cmd; 2030 msg.flush_callback = tdls_post_msg_flush_cb; 2031 msg.type = TDLS_CMD_SCAN_DONE; 2032 2033 return scheduler_post_message(QDF_MODULE_ID_TDLS, 2034 QDF_MODULE_ID_TDLS, 2035 QDF_MODULE_ID_OS_IF, &msg); 2036 } 2037 2038 void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, 2039 struct scan_event *event, 2040 void *arg) 2041 { 2042 enum QDF_OPMODE device_mode; 2043 struct tdls_soc_priv_obj *tdls_soc; 2044 2045 if (!vdev || !event || !arg) 2046 return; 2047 2048 if (SCAN_EVENT_TYPE_COMPLETED != event->type) 2049 return; 2050 2051 device_mode = wlan_vdev_mlme_get_opmode(vdev); 2052 2053 tdls_soc = (struct tdls_soc_priv_obj *) arg; 2054 tdls_post_scan_done_msg(tdls_soc); 2055 } 2056 2057 void tdls_set_link_unforce(struct wlan_objmgr_vdev *vdev) 2058 { 2059 QDF_STATUS status; 2060 struct scheduler_msg msg = {0}; 2061 2062 msg.callback = tdls_process_cmd; 2063 msg.type = TDLS_CMD_SET_LINK_UNFORCE; 2064 msg.bodyptr = vdev; 2065 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 2066 QDF_MODULE_ID_TDLS, 2067 QDF_MODULE_ID_OS_IF, &msg); 2068 if (QDF_IS_STATUS_ERROR(status)) 2069 tdls_err("failed to set tdls link mode"); 2070 } 2071 2072 /** 2073 * tdls_check_peer_buf_capable() - Check buffer sta capable of tdls peers 2074 * @tdls_vdev: TDLS vdev object 2075 * 2076 * Used in scheduler thread context, no lock needed. 2077 * 2078 * Return: false if there is connected peer and not support buffer sta. 2079 */ 2080 static bool tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj *tdls_vdev) 2081 { 2082 uint16_t i; 2083 struct tdls_peer *peer; 2084 qdf_list_t *head; 2085 qdf_list_node_t *p_node; 2086 QDF_STATUS status; 2087 2088 if (!tdls_vdev) { 2089 tdls_err("invalid tdls vdev object"); 2090 return false; 2091 } 2092 2093 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 2094 head = &tdls_vdev->peer_list[i]; 2095 2096 status = qdf_list_peek_front(head, &p_node); 2097 while (QDF_IS_STATUS_SUCCESS(status)) { 2098 peer = qdf_container_of(p_node, struct tdls_peer, node); 2099 2100 if (peer && 2101 (TDLS_LINK_CONNECTED == peer->link_status) && 2102 (!peer->buf_sta_capable)) 2103 return false; 2104 2105 status = qdf_list_peek_next(head, p_node, &p_node); 2106 } 2107 } 2108 2109 return true; 2110 } 2111 2112 QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) 2113 { 2114 struct tdls_vdev_priv_obj *tdls_vdev; 2115 struct wlan_objmgr_vdev *vdev; 2116 uint16_t tdls_peer_count; 2117 uint32_t feature; 2118 bool peer_buf_capable; 2119 QDF_STATUS status = QDF_STATUS_SUCCESS; 2120 2121 /* if tdls is not enabled, then continue scan */ 2122 if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) 2123 return status; 2124 2125 /* Get the vdev based on vdev operating mode*/ 2126 vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID); 2127 if (!vdev) 2128 return status; 2129 2130 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 2131 if (!tdls_vdev) 2132 goto return_success; 2133 2134 if (tdls_is_progress(tdls_vdev, NULL, 0)) { 2135 if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { 2136 tdls_notice("Allow this scan req. as already max no of scan's are rejected"); 2137 tdls_soc->scan_reject_count = 0; 2138 status = QDF_STATUS_SUCCESS; 2139 2140 } else { 2141 tdls_warn("tdls in progress. scan rejected %d", 2142 tdls_soc->scan_reject_count); 2143 status = QDF_STATUS_E_BUSY; 2144 } 2145 } 2146 2147 tdls_peer_count = tdls_soc->connected_peer_count; 2148 if (!tdls_peer_count) 2149 goto disable_tdls; 2150 2151 feature = tdls_soc->tdls_configs.tdls_feature_flags; 2152 if (TDLS_IS_SCAN_ENABLED(feature)) { 2153 tdls_debug("TDLS Scan enabled, keep tdls link and allow scan, connected tdls peers: %d", 2154 tdls_peer_count); 2155 goto disable_tdls; 2156 } 2157 2158 if (TDLS_IS_BUFFER_STA_ENABLED(feature) && 2159 (tdls_peer_count <= TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN)) { 2160 peer_buf_capable = tdls_check_peer_buf_capable(tdls_vdev); 2161 if (peer_buf_capable) { 2162 tdls_debug("All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d", 2163 tdls_peer_count, 2164 tdls_soc->tdls_current_mode); 2165 goto disable_tdls; 2166 } 2167 } 2168 2169 tdls_disable_offchan_and_teardown_links(vdev); 2170 2171 disable_tdls: 2172 tdls_set_current_mode(tdls_soc, TDLS_SUPPORT_DISABLED, 2173 false, TDLS_SET_MODE_SOURCE_SCAN); 2174 2175 return_success: 2176 wlan_objmgr_vdev_release_ref(vdev, 2177 WLAN_TDLS_NB_ID); 2178 return status; 2179 } 2180 2181 void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, 2182 union wlan_serialization_rules_info *comp_info, 2183 struct wlan_serialization_command *cmd) 2184 { 2185 struct tdls_soc_priv_obj *tdls_soc; 2186 QDF_STATUS status; 2187 if (!comp_info) 2188 return; 2189 2190 tdls_soc = tdls_soc_global; 2191 comp_info->scan_info.is_tdls_in_progress = false; 2192 status = tdls_scan_callback(tdls_soc); 2193 if (QDF_STATUS_E_BUSY == status) 2194 comp_info->scan_info.is_tdls_in_progress = true; 2195 } 2196 2197 static uint8_t tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev *vdev, 2198 qdf_freq_t ch_freq, uint8_t bw_offset, 2199 uint16_t behav_limit) 2200 { 2201 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 2202 uint8_t channel, opclass; 2203 2204 if (!pdev) { 2205 tdls_err("pdev is NULL"); 2206 return 0; 2207 } 2208 2209 wlan_reg_freq_width_to_chan_op_class(pdev, ch_freq, bw_offset, false, 2210 BIT(behav_limit), &opclass, 2211 &channel); 2212 2213 return opclass; 2214 } 2215 2216 uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev, 2217 qdf_freq_t freq, uint8_t bw_offset, 2218 uint8_t *reg_bw_offset) 2219 { 2220 uint8_t opclass; 2221 2222 if (bw_offset & (1 << BW_160_OFFSET_BIT)) { 2223 opclass = tdls_find_opclass_frm_freq(vdev, 2224 freq, BW_160_MHZ, 2225 BEHAV_NONE); 2226 *reg_bw_offset = BWALL; 2227 } else if (bw_offset & (1 << BW_80_OFFSET_BIT)) { 2228 opclass = tdls_find_opclass_frm_freq(vdev, 2229 freq, BW_80_MHZ, 2230 BEHAV_NONE); 2231 *reg_bw_offset = BW80; 2232 } else if (bw_offset & (1 << BW_40_OFFSET_BIT)) { 2233 opclass = tdls_find_opclass_frm_freq(vdev, 2234 freq, BW_40_MHZ, 2235 BEHAV_BW40_LOW_PRIMARY); 2236 *reg_bw_offset = BW40_LOW_PRIMARY; 2237 if (!opclass) { 2238 opclass = tdls_find_opclass_frm_freq(vdev, 2239 freq, 2240 BW_40_MHZ, 2241 BEHAV_BW40_HIGH_PRIMARY); 2242 *reg_bw_offset = BW40_HIGH_PRIMARY; 2243 } 2244 } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { 2245 opclass = tdls_find_opclass_frm_freq(vdev, 2246 freq, BW_20_MHZ, 2247 BEHAV_NONE); 2248 *reg_bw_offset = BW20; 2249 } else { 2250 opclass = tdls_find_opclass_frm_freq(vdev, 2251 freq, BW_160_MHZ, 2252 BEHAV_NONE); 2253 *reg_bw_offset = BWALL; 2254 } 2255 2256 return opclass; 2257 } 2258