1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: 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 */ tdls_get_cmd_type_str(enum tdls_command_type cmd_type)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 */ tdls_get_event_type_str(enum tdls_event_type event_type)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 tdls_get_cmd_type_str(enum tdls_command_type cmd_type)114 static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type) 115 { 116 return ""; 117 } 118 tdls_get_event_type_str(enum tdls_event_type event_type)119 static char *tdls_get_event_type_str(enum tdls_event_type event_type) 120 { 121 return ""; 122 } 123 #endif 124 tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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 tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)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 tdls_vdev_init(struct tdls_vdev_priv_obj * vdev_obj)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 tdls_vdev_deinit(struct tdls_vdev_priv_obj * vdev_obj)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 tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev * vdev,void * arg)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 tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev * vdev,void * arg)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 */ __tdls_get_all_peers_from_list(struct tdls_get_all_peers * get_tdls_peers)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 */ tdls_get_all_peers_from_list(struct tdls_get_all_peers * get_tdls_peers)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 tdls_process_reset_all_peers(struct wlan_objmgr_vdev * vdev)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 */ tdls_reset_all_peers(struct tdls_delete_all_peers_params * delete_all_peers_ind)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 tdls_handle_start_bss(struct wlan_objmgr_psoc * psoc)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 tdls_handle_link_unforce(struct wlan_objmgr_vdev * vdev)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 tdls_process_cmd(struct scheduler_msg * msg)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 %s is NULL", !msg ? "" : "body ptr"); 603 QDF_ASSERT(0); 604 return QDF_STATUS_E_NULL_VALUE; 605 } 606 607 tdls_debug(" %s(%d)", 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 tdls_process_evt(struct scheduler_msg * msg)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(" %s(%d)", tdls_get_event_type_str(event->message_type), 713 event->message_type); 714 715 switch (event->message_type) { 716 case TDLS_SHOULD_DISCOVER: 717 tdls_process_should_discover(vdev, event); 718 break; 719 case TDLS_SHOULD_TEARDOWN: 720 case TDLS_PEER_DISCONNECTED: 721 tdls_process_should_teardown(vdev, event); 722 break; 723 case TDLS_CONNECTION_TRACKER_NOTIFY: 724 tdls_process_connection_tracker_notify(vdev, event); 725 break; 726 default: 727 break; 728 } 729 730 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 731 qdf_mem_free(notify); 732 733 return QDF_STATUS_SUCCESS; 734 } 735 tdls_timer_restart(struct wlan_objmgr_vdev * vdev,qdf_mc_timer_t * timer,uint32_t expiration_time)736 void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, 737 qdf_mc_timer_t *timer, uint32_t expiration_time) 738 { 739 if (!wlan_cm_is_vdev_connected(vdev)) { 740 tdls_debug("vdev:%d is not connected. Can't restart timer", 741 wlan_vdev_get_id(vdev)); 742 return; 743 } 744 745 if (QDF_TIMER_STATE_RUNNING != 746 qdf_mc_timer_get_current_state(timer)) 747 qdf_mc_timer_start(timer, expiration_time); 748 } 749 750 /** 751 * tdls_monitor_timers_stop() - stop all monitoring timers 752 * @tdls_vdev: TDLS vdev object 753 * 754 * Return: none 755 */ tdls_monitor_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)756 static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 757 { 758 if (!wlan_vdev_mlme_is_mlo_vdev(tdls_vdev->vdev)) 759 qdf_mc_timer_stop_sync(&tdls_vdev->peer_discovery_timer); 760 } 761 762 /** 763 * tdls_peer_idle_timers_stop() - stop peer idle timers 764 * @tdls_vdev: TDLS vdev object 765 * 766 * Loop through the idle peer list and stop their timers 767 * 768 * Return: None 769 */ tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)770 static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 771 { 772 int i; 773 qdf_list_t *head; 774 qdf_list_node_t *p_node; 775 struct tdls_peer *curr_peer; 776 QDF_STATUS status; 777 778 tdls_vdev->discovery_peer_cnt = 0; 779 780 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 781 head = &tdls_vdev->peer_list[i]; 782 status = qdf_list_peek_front(head, &p_node); 783 while (QDF_IS_STATUS_SUCCESS(status)) { 784 curr_peer = qdf_container_of(p_node, struct tdls_peer, 785 node); 786 if (curr_peer->is_peer_idle_timer_initialised) 787 qdf_mc_timer_stop_sync(&curr_peer->peer_idle_timer); 788 status = qdf_list_peek_next(head, p_node, &p_node); 789 } 790 } 791 792 } 793 794 /** 795 * tdls_ct_timers_stop() - stop tdls connection tracker timers 796 * @tdls_vdev: TDLS vdev 797 * 798 * Return: None 799 */ tdls_ct_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)800 static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 801 { 802 qdf_mc_timer_stop_sync(&tdls_vdev->peer_update_timer); 803 804 tdls_peer_idle_timers_stop(tdls_vdev); 805 } 806 807 /** 808 * tdls_timers_stop() - stop all the tdls timers running 809 * @tdls_vdev: TDLS vdev 810 * 811 * Return: none 812 */ tdls_timers_stop(struct tdls_vdev_priv_obj * tdls_vdev)813 void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) 814 { 815 tdls_debug("Stop TDLS timers"); 816 tdls_monitor_timers_stop(tdls_vdev); 817 tdls_ct_timers_stop(tdls_vdev); 818 } 819 tdls_get_vdev_objects(struct wlan_objmgr_vdev * vdev,struct tdls_vdev_priv_obj ** tdls_vdev_obj,struct tdls_soc_priv_obj ** tdls_soc_obj)820 QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, 821 struct tdls_vdev_priv_obj **tdls_vdev_obj, 822 struct tdls_soc_priv_obj **tdls_soc_obj) 823 { 824 enum QDF_OPMODE device_mode; 825 826 if (!vdev) 827 return QDF_STATUS_E_FAILURE; 828 829 *tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 830 if (NULL == (*tdls_vdev_obj)) 831 return QDF_STATUS_E_FAILURE; 832 833 *tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 834 if (NULL == (*tdls_soc_obj)) 835 return QDF_STATUS_E_FAILURE; 836 837 device_mode = wlan_vdev_mlme_get_opmode(vdev); 838 839 if (device_mode != QDF_STA_MODE && 840 device_mode != QDF_P2P_CLIENT_MODE) 841 return QDF_STATUS_E_FAILURE; 842 843 return QDF_STATUS_SUCCESS; 844 } 845 846 #ifdef WLAN_FEATURE_11AX tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,enum supported_6g_pwr_types pwr_typ)847 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev, 848 qdf_freq_t freq, 849 enum supported_6g_pwr_types pwr_typ) 850 { 851 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 852 struct regulatory_channel *chan; 853 uint8_t chn_idx, num_chan; 854 uint8_t band_mask = BIT(REG_BAND_6G); 855 uint32_t tx_power = 0; 856 857 if (!pdev) 858 return 0; 859 860 /* No power check is required for non 6 Ghz channel */ 861 if (!wlan_reg_is_6ghz_chan_freq(freq)) 862 return 0; 863 864 chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS); 865 if (!chan) 866 return 0; 867 868 num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev, 869 band_mask, 870 chan, 871 REG_CLI_DEF_VLP); 872 873 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 874 if (chan[chn_idx].center_freq == freq) { 875 tdls_debug("VLP power for channel %d is %d", 876 chan[chn_idx].center_freq, 877 chan[chn_idx].tx_power); 878 tx_power = chan[chn_idx].tx_power; 879 } 880 } 881 882 qdf_mem_free(chan); 883 return tx_power; 884 } 885 tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)886 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev, 887 qdf_freq_t freq) 888 { 889 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 890 struct regulatory_channel *chan; 891 bool is_allowed = false; 892 uint8_t country_code[REG_ALPHA2_LEN + 1]; 893 uint8_t chn_idx, num_chan = 0; 894 uint8_t band_mask = BIT(REG_BAND_6G); 895 896 /* Return if freq is not 6 Ghz freq */ 897 if (!wlan_reg_is_6ghz_chan_freq(freq)) 898 return false; 899 900 if (!wlan_cfg80211_tdls_is_fw_6ghz_capable(vdev)) 901 return false; 902 903 if (!pdev) 904 return false; 905 906 wlan_cm_get_country_code(pdev, wlan_vdev_get_id(vdev), country_code); 907 if (!wlan_reg_ctry_support_vlp(country_code)) 908 return false; 909 910 chan = qdf_mem_malloc(sizeof(struct regulatory_channel) * NUM_CHANNELS); 911 if (!chan) 912 return false; 913 914 num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev, 915 band_mask, 916 chan, 917 REG_CLI_DEF_VLP); 918 tdls_debug("Country IE:%c%c freq %d num_chan %d", country_code[0], 919 country_code[1], freq, num_chan); 920 if (!num_chan) 921 goto error; 922 923 for (chn_idx = 0; chn_idx < num_chan; chn_idx++) { 924 if (chan[chn_idx].center_freq == freq) { 925 tdls_debug("TDLS 6ghz freq: %d supports VLP power", 926 chan[chn_idx].center_freq); 927 is_allowed = true; 928 break; 929 } 930 } 931 932 error: 933 qdf_mem_free(chan); 934 return is_allowed; 935 } 936 #else tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)937 bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev, 938 qdf_freq_t freq) 939 { 940 return false; 941 } 942 tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,enum supported_6g_pwr_types pwr_typ)943 uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev, 944 qdf_freq_t freq, 945 enum supported_6g_pwr_types pwr_typ) 946 { 947 return 0; 948 } 949 #endif 950 tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj * tdls_soc_obj)951 bool tdls_check_is_user_tdls_enable(struct tdls_soc_priv_obj *tdls_soc_obj) 952 { 953 return tdls_soc_obj->is_user_tdls_enable; 954 } 955 tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev * vdev)956 bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) 957 { 958 struct tdls_vdev_priv_obj *tdls_vdev_obj; 959 struct tdls_soc_priv_obj *tdls_soc_obj; 960 bool state = false; 961 qdf_freq_t ch_freq; 962 QDF_STATUS status; 963 uint32_t connection_count; 964 uint8_t sta_count, p2p_cli_count; 965 966 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); 967 if (QDF_IS_STATUS_ERROR(status)) 968 return state; 969 970 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 971 if (QDF_IS_STATUS_ERROR(status)) { 972 tdls_err("Failed to get TDLS objects"); 973 goto exit; 974 } 975 976 if (wlan_vdev_mlme_is_mlo_vdev(vdev) && 977 !wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc)) { 978 tdls_debug("TDLS not supported on MLO vdev"); 979 goto exit; 980 } 981 982 if (wlan_nan_is_disc_active(tdls_soc_obj->soc)) { 983 tdls_err("NAN active. NAN+TDLS not supported"); 984 goto exit; 985 } 986 987 if (!tdls_check_is_user_tdls_enable(tdls_soc_obj)) { 988 tdls_err("TDLS Disabled from userspace"); 989 goto exit; 990 } 991 992 connection_count = 993 policy_mgr_get_connection_count_with_mlo(tdls_soc_obj->soc); 994 sta_count = 995 policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, 996 PM_STA_MODE, NULL); 997 p2p_cli_count = 998 policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, 999 PM_P2P_CLIENT_MODE, 1000 NULL); 1001 if ((connection_count == 1 && (sta_count || p2p_cli_count)) || 1002 (connection_count > 1 && 1003 tdls_is_concurrency_allowed(tdls_soc_obj->soc))) { 1004 state = true; 1005 } else { 1006 tdls_warn("vdev:%d Concurrent sessions exist disable TDLS", 1007 wlan_vdev_get_id(vdev)); 1008 state = false; 1009 goto exit; 1010 } 1011 1012 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE && sta_count) { 1013 tdls_warn("vdev:%d Concurrent STA exists. TDLS not allowed for P2P vdev", 1014 wlan_vdev_get_id(vdev)); 1015 state = false; 1016 goto exit; 1017 } 1018 1019 ch_freq = wlan_get_operation_chan_freq(vdev); 1020 if (wlan_reg_is_6ghz_chan_freq(ch_freq) && 1021 !tdls_is_6g_freq_allowed(vdev, ch_freq)) { 1022 tdls_debug("6GHz freq:%d not allowed for TDLS", ch_freq); 1023 state = false; 1024 } 1025 1026 exit: 1027 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1028 1029 return state; 1030 } 1031 1032 #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES tdls_is_concurrency_allowed(struct wlan_objmgr_psoc * psoc)1033 bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) 1034 { 1035 if (policy_mgr_is_mlo_in_mode_emlsr(psoc, NULL, NULL)) { 1036 tdls_debug("eMLSR STA present. Don't allow TDLS"); 1037 return false; 1038 } 1039 1040 if (!wlan_psoc_nif_fw_ext2_cap_get(psoc, 1041 WLAN_TDLS_CONCURRENCIES_SUPPORT)) { 1042 tdls_debug("fw cap is not advertised"); 1043 return false; 1044 } 1045 1046 if (policy_mgr_get_connection_count_with_mlo(psoc) > 1047 WLAN_TDLS_MAX_CONCURRENT_VDEV_SUPPORTED) 1048 return false; 1049 1050 if (policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1051 NULL) > 1) { 1052 tdls_debug("More than one STA exist. Don't allow TDLS"); 1053 return false; 1054 } 1055 1056 if (policy_mgr_is_mcc_on_any_sta_vdev(psoc)) { 1057 tdls_debug("Base channel MCC. Don't allow TDLS"); 1058 return false; 1059 } 1060 1061 /* 1062 * Don't enable TDLS for P2P_CLI in concurrency cases 1063 */ 1064 if (policy_mgr_get_connection_count_with_mlo(psoc) > 1 && 1065 !policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1066 NULL)) 1067 return false; 1068 1069 return true; 1070 } 1071 #endif 1072 tdls_set_ct_mode(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_vdev * vdev)1073 void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc, 1074 struct wlan_objmgr_vdev *vdev) 1075 { 1076 struct tdls_soc_priv_obj *tdls_soc_obj; 1077 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1078 uint32_t tdls_feature_flags = 0, sta_count, p2p_count; 1079 bool state = false; 1080 bool tdls_mlo; 1081 QDF_STATUS status; 1082 1083 if (!tdls_check_is_tdls_allowed(vdev)) 1084 return; 1085 1086 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1087 if (QDF_IS_STATUS_ERROR(status)) { 1088 tdls_err("Failed to get TDLS objects"); 1089 return; 1090 } 1091 1092 qdf_atomic_set(&tdls_soc_obj->timer_cnt, 0); 1093 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 1094 if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode || 1095 TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode || 1096 !TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) { 1097 state = false; 1098 goto set_state; 1099 } 1100 1101 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1102 NULL); 1103 p2p_count = 1104 policy_mgr_mode_specific_connection_count(psoc, 1105 PM_P2P_CLIENT_MODE, 1106 NULL); 1107 tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(psoc); 1108 if (sta_count == 1 || (sta_count >= 2 && tdls_mlo) || 1109 (policy_mgr_get_connection_count_with_mlo(psoc) == 1 && 1110 p2p_count == 1)) { 1111 state = true; 1112 /* 1113 * In case of TDLS external control, peer should be added 1114 * by the user space to start connection tracker. 1115 */ 1116 if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags) && 1117 !tdls_soc_obj->tdls_external_peer_count) 1118 state = false; 1119 1120 goto set_state; 1121 } 1122 1123 state = false; 1124 1125 set_state: 1126 tdls_soc_obj->enable_tdls_connection_tracker = state; 1127 if (tdls_soc_obj->enable_tdls_connection_tracker) 1128 tdls_implicit_enable(tdls_vdev_obj); 1129 else 1130 tdls_implicit_disable(tdls_vdev_obj); 1131 1132 tdls_debug("vdev:%d enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x", 1133 wlan_vdev_get_id(vdev), 1134 tdls_soc_obj->enable_tdls_connection_tracker, 1135 tdls_soc_obj->tdls_current_mode, tdls_feature_flags); 1136 } 1137 tdls_set_user_tdls_enable(struct wlan_objmgr_vdev * vdev,bool is_user_tdls_enable)1138 void tdls_set_user_tdls_enable(struct wlan_objmgr_vdev *vdev, 1139 bool is_user_tdls_enable) 1140 { 1141 QDF_STATUS status; 1142 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1143 struct tdls_soc_priv_obj *tdls_soc_obj; 1144 1145 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); 1146 if (QDF_IS_STATUS_ERROR(status)) 1147 return; 1148 1149 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1150 if (QDF_IS_STATUS_ERROR(status)) { 1151 tdls_err("Failed to get TDLS objects"); 1152 goto exit; 1153 } 1154 1155 tdls_soc_obj->is_user_tdls_enable = is_user_tdls_enable; 1156 tdls_debug("TDLS enable:%d via userspace", 1157 tdls_soc_obj->is_user_tdls_enable); 1158 1159 exit: 1160 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1161 } 1162 1163 QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc * psoc)1164 tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) 1165 { 1166 struct wlan_objmgr_vdev *tdls_vdev; 1167 struct tdls_vdev_priv_obj *tdls_priv_vdev; 1168 struct tdls_soc_priv_obj *tdls_priv_soc; 1169 QDF_STATUS status; 1170 1171 if (!psoc) { 1172 tdls_err("psoc is NULL"); 1173 return QDF_STATUS_E_NULL_VALUE; 1174 } 1175 1176 tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); 1177 if (!tdls_vdev) { 1178 tdls_debug("No TDLS vdev"); 1179 return QDF_STATUS_E_NULL_VALUE; 1180 } 1181 1182 status = tdls_get_vdev_objects(tdls_vdev, &tdls_priv_vdev, 1183 &tdls_priv_soc); 1184 if (QDF_IS_STATUS_ERROR(status)) { 1185 tdls_debug("TDLS vdev objects NULL"); 1186 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1187 return QDF_STATUS_E_NULL_VALUE; 1188 } 1189 1190 if (!tdls_check_is_tdls_allowed(tdls_vdev)) { 1191 tdls_debug("Disable the tdls in FW due to concurrency"); 1192 if (wlan_vdev_mlme_is_mlo_vdev(tdls_vdev)) 1193 tdls_process_enable_disable_for_ml_vdev(tdls_vdev, 1194 false); 1195 else 1196 tdls_disable_offchan_and_teardown_links(tdls_vdev); 1197 1198 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1199 return QDF_STATUS_E_NULL_VALUE; 1200 } 1201 1202 tdls_debug("vdev:%d enter", wlan_vdev_get_id(tdls_vdev)); 1203 1204 tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH); 1205 tdls_set_ct_mode(psoc, tdls_vdev); 1206 1207 wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); 1208 tdls_debug("exit "); 1209 1210 return QDF_STATUS_SUCCESS; 1211 } 1212 1213 QDF_STATUS tdls_process_decrement_active_session(struct wlan_objmgr_psoc * psoc)1214 tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc) 1215 { 1216 struct wlan_objmgr_vdev *tdls_obj_vdev; 1217 1218 tdls_debug("Enter"); 1219 if (!psoc) 1220 return QDF_STATUS_E_NULL_VALUE; 1221 1222 if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) && 1223 !policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) && 1224 policy_mgr_is_current_hwmode_dbs(psoc)) { 1225 tdls_debug("Current HW mode is 1*1 DBS. Wait for Opportunistic timer to expire to enable TDLS in FW"); 1226 return QDF_STATUS_SUCCESS; 1227 } 1228 1229 tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); 1230 if (!tdls_obj_vdev) 1231 return QDF_STATUS_E_FAILURE; 1232 1233 if (!tdls_check_is_tdls_allowed(tdls_obj_vdev)) 1234 goto release_ref; 1235 1236 /* 1237 * 2 Port MCC -> 1 port scenario or 1238 * 3 Port MCC -> 2 port SCC scenario or 1239 * 4 Port -> 3 Port SCC scenario 1240 * So enable TDLS in firmware 1241 */ 1242 tdls_debug("Enable TDLS as active sta/p2p_cli interface is present"); 1243 if (wlan_vdev_mlme_is_mlo_vdev(tdls_obj_vdev)) 1244 tdls_process_enable_disable_for_ml_vdev(tdls_obj_vdev, true); 1245 else 1246 tdls_process_enable_for_vdev(tdls_obj_vdev); 1247 1248 release_ref: 1249 wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); 1250 1251 return QDF_STATUS_SUCCESS; 1252 } 1253 1254 #ifdef WLAN_FEATURE_11BE_MLO wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev * vdev,uint8_t index,wlan_objmgr_ref_dbgid dbg_id)1255 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1256 uint8_t index, 1257 wlan_objmgr_ref_dbgid dbg_id) 1258 { 1259 struct wlan_mlo_dev_context *mlo_dev_ctx; 1260 struct wlan_objmgr_vdev *mlo_vdev; 1261 1262 if (!vdev) 1263 return NULL; 1264 1265 mlo_dev_ctx = vdev->mlo_dev_ctx; 1266 if (!mlo_dev_ctx) 1267 return NULL; 1268 1269 mlo_vdev = mlo_dev_ctx->wlan_vdev_list[index]; 1270 if (mlo_vdev && 1271 wlan_objmgr_vdev_try_get_ref(mlo_vdev, dbg_id) == 1272 QDF_STATUS_SUCCESS) 1273 return mlo_vdev; 1274 1275 return NULL; 1276 } 1277 wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1278 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1279 wlan_objmgr_ref_dbgid dbg_id) 1280 { 1281 if (!vdev) 1282 return; 1283 1284 wlan_objmgr_vdev_release_ref(vdev, dbg_id); 1285 } 1286 #else wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev * vdev,uint8_t index,wlan_objmgr_ref_dbgid dbg_id)1287 struct wlan_objmgr_vdev *wlan_tdls_get_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1288 uint8_t index, 1289 wlan_objmgr_ref_dbgid dbg_id) 1290 { 1291 return NULL; 1292 } 1293 wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid dbg_id)1294 void wlan_tdls_release_mlo_vdev(struct wlan_objmgr_vdev *vdev, 1295 wlan_objmgr_ref_dbgid dbg_id) 1296 { 1297 } 1298 #endif 1299 /** 1300 * tdls_get_vdev() - Get tdls specific vdev object manager 1301 * @psoc: wlan psoc object manager 1302 * @dbg_id: debug id 1303 * 1304 * If TDLS possible, return the corresponding vdev 1305 * to enable TDLS in the system. 1306 * 1307 * Return: vdev manager pointer or NULL. 1308 */ tdls_get_vdev(struct wlan_objmgr_psoc * psoc,wlan_objmgr_ref_dbgid dbg_id)1309 struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, 1310 wlan_objmgr_ref_dbgid dbg_id) 1311 { 1312 uint32_t vdev_id; 1313 1314 vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); 1315 if (WLAN_INVALID_VDEV_ID != vdev_id) 1316 return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1317 dbg_id); 1318 /* 1319 * For P2P_Client mode, TDLS is not supported on concurrency 1320 * so return P2P_client vdev only if P2P client mode exists without 1321 * any concurreny 1322 */ 1323 vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); 1324 if (WLAN_INVALID_VDEV_ID != vdev_id && 1325 policy_mgr_get_connection_count_with_mlo(psoc) == 1) 1326 return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1327 dbg_id); 1328 1329 return NULL; 1330 } 1331 tdls_post_msg_flush_cb(struct scheduler_msg * msg)1332 static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg) 1333 { 1334 void *ptr = msg->bodyptr; 1335 struct wlan_objmgr_vdev *vdev = NULL; 1336 1337 switch (msg->type) { 1338 case TDLS_NOTIFY_STA_DISCONNECTION: 1339 vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; 1340 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1341 qdf_mem_free(ptr); 1342 break; 1343 1344 case TDLS_DELETE_ALL_PEERS_INDICATION: 1345 vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev; 1346 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1347 qdf_mem_free(ptr); 1348 break; 1349 1350 case TDLS_CMD_SCAN_DONE: 1351 case TDLS_CMD_SESSION_INCREMENT: 1352 case TDLS_CMD_SESSION_DECREMENT: 1353 break; 1354 } 1355 1356 return QDF_STATUS_SUCCESS; 1357 } 1358 1359 /** 1360 * tdls_process_session_update() - update session count information 1361 * @psoc: soc object 1362 * @cmd_type: type of command 1363 * 1364 * update the session information in connection tracker 1365 * 1366 * Return: None 1367 */ tdls_process_session_update(struct wlan_objmgr_psoc * psoc,enum tdls_command_type cmd_type)1368 static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, 1369 enum tdls_command_type cmd_type) 1370 { 1371 struct scheduler_msg msg = {0}; 1372 QDF_STATUS status; 1373 1374 msg.bodyptr = psoc; 1375 msg.callback = tdls_process_cmd; 1376 msg.flush_callback = tdls_post_msg_flush_cb; 1377 msg.type = (uint16_t)cmd_type; 1378 1379 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1380 QDF_MODULE_ID_TDLS, 1381 QDF_MODULE_ID_OS_IF, &msg); 1382 if (QDF_IS_STATUS_ERROR(status)) 1383 tdls_alert("message post failed "); 1384 } 1385 tdls_notify_increment_session(struct wlan_objmgr_psoc * psoc)1386 void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc) 1387 { 1388 tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT); 1389 } 1390 tdls_notify_decrement_session(struct wlan_objmgr_psoc * psoc)1391 void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) 1392 { 1393 tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); 1394 } 1395 tdls_send_update_to_fw(struct tdls_vdev_priv_obj * tdls_vdev_obj,struct tdls_soc_priv_obj * tdls_soc_obj,bool tdls_prohibited,bool tdls_chan_swit_prohibited,bool sta_connect_event,uint8_t session_id)1396 void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, 1397 struct tdls_soc_priv_obj *tdls_soc_obj, 1398 bool tdls_prohibited, 1399 bool tdls_chan_swit_prohibited, 1400 bool sta_connect_event, 1401 uint8_t session_id) 1402 { 1403 struct tdls_info *tdls_info_to_fw; 1404 struct tdls_config_params *threshold_params; 1405 uint32_t tdls_feature_flags; 1406 QDF_STATUS status; 1407 bool tdls_mlo; 1408 1409 tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; 1410 if (!TDLS_IS_ENABLED(tdls_feature_flags)) { 1411 tdls_debug("TDLS mode is not enabled"); 1412 return; 1413 } 1414 1415 tdls_mlo = wlan_tdls_is_fw_11be_mlo_capable(tdls_soc_obj->soc); 1416 1417 /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ 1418 if (sta_connect_event) { 1419 if (tdls_prohibited) { 1420 tdls_soc_obj->tdls_current_mode = 1421 TDLS_SUPPORT_DISABLED; 1422 } else { 1423 if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) 1424 tdls_soc_obj->tdls_current_mode = 1425 TDLS_SUPPORT_EXP_TRIG_ONLY; 1426 else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( 1427 tdls_feature_flags)) 1428 tdls_soc_obj->tdls_current_mode = 1429 TDLS_SUPPORT_EXT_CONTROL; 1430 else 1431 tdls_soc_obj->tdls_current_mode = 1432 TDLS_SUPPORT_IMP_MODE; 1433 } 1434 } else { 1435 tdls_soc_obj->tdls_current_mode = 1436 TDLS_SUPPORT_DISABLED; 1437 } 1438 1439 tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); 1440 if (!tdls_info_to_fw) 1441 return; 1442 1443 threshold_params = &tdls_vdev_obj->threshold_config; 1444 1445 tdls_info_to_fw->notification_interval_ms = 1446 threshold_params->tx_period_t; 1447 tdls_info_to_fw->tx_discovery_threshold = 1448 threshold_params->tx_packet_n; 1449 tdls_info_to_fw->tx_teardown_threshold = 1450 threshold_params->idle_packet_n; 1451 tdls_info_to_fw->rssi_teardown_threshold = 1452 threshold_params->rssi_teardown_threshold; 1453 tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta; 1454 tdls_info_to_fw->vdev_id = session_id; 1455 1456 /* record the session id in vdev context */ 1457 tdls_vdev_obj->session_id = session_id; 1458 tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; 1459 tdls_info_to_fw->tdls_options = 0; 1460 1461 /* 1462 * Do not enable TDLS offchannel, if AP prohibited TDLS 1463 * channel switch 1464 */ 1465 if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && 1466 (!tdls_chan_swit_prohibited)) 1467 tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN; 1468 1469 if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags)) 1470 tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA; 1471 if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags)) 1472 tdls_info_to_fw->tdls_options |= ENA_TDLS_SLEEP_STA; 1473 1474 1475 tdls_info_to_fw->peer_traffic_ind_window = 1476 tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window; 1477 tdls_info_to_fw->peer_traffic_response_timeout = 1478 tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout; 1479 tdls_info_to_fw->puapsd_mask = 1480 tdls_soc_obj->tdls_configs.tdls_uapsd_mask; 1481 tdls_info_to_fw->puapsd_inactivity_time = 1482 tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time; 1483 tdls_info_to_fw->puapsd_rx_frame_threshold = 1484 tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold; 1485 tdls_info_to_fw->teardown_notification_ms = 1486 tdls_soc_obj->tdls_configs.tdls_idle_timeout; 1487 tdls_info_to_fw->tdls_peer_kickout_threshold = 1488 tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold; 1489 tdls_info_to_fw->tdls_discovery_wake_timeout = 1490 tdls_soc_obj->tdls_configs.tdls_discovery_wake_timeout; 1491 1492 status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw); 1493 if (QDF_IS_STATUS_ERROR(status)) 1494 goto done; 1495 1496 if (sta_connect_event) { 1497 tdls_soc_obj->set_state_info.vdev_id = session_id; 1498 } 1499 1500 tdls_debug("FW tdls state sent for vdev id %d", session_id); 1501 done: 1502 qdf_mem_free(tdls_info_to_fw); 1503 return; 1504 } 1505 tdls_process_enable_for_vdev(struct wlan_objmgr_vdev * vdev)1506 void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev) 1507 { 1508 struct wlan_objmgr_psoc *psoc; 1509 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1510 struct tdls_soc_priv_obj *tdls_soc_obj; 1511 enum QDF_OPMODE opmode; 1512 QDF_STATUS status; 1513 uint8_t sta_count; 1514 1515 psoc = wlan_vdev_get_psoc(vdev); 1516 if (!psoc) 1517 return; 1518 1519 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1520 NULL); 1521 opmode = wlan_vdev_mlme_get_opmode(vdev); 1522 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1523 tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev:%d", 1524 wlan_vdev_get_id(vdev)); 1525 return; 1526 } 1527 1528 status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj); 1529 if (QDF_IS_STATUS_ERROR(status)) 1530 return; 1531 1532 tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, 1533 mlme_get_tdls_prohibited(vdev), 1534 mlme_get_tdls_chan_switch_prohibited(vdev), 1535 true, wlan_vdev_get_id(vdev)); 1536 1537 /* check and set the connection tracker */ 1538 tdls_set_ct_mode(tdls_soc_obj->soc, vdev); 1539 } 1540 1541 #ifdef WLAN_FEATURE_11BE_MLO tdls_process_enable_disable_for_ml_vdev(struct wlan_objmgr_vdev * vdev,bool is_enable)1542 void tdls_process_enable_disable_for_ml_vdev(struct wlan_objmgr_vdev *vdev, 1543 bool is_enable) 1544 { 1545 struct wlan_mlo_dev_context *ml_dev_ctx; 1546 QDF_STATUS status; 1547 uint8_t i; 1548 struct wlan_objmgr_vdev *vdev_iter; 1549 1550 if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) 1551 return; 1552 1553 ml_dev_ctx = vdev->mlo_dev_ctx; 1554 if (!ml_dev_ctx) 1555 return; 1556 1557 for (i = 0; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) { 1558 if (!ml_dev_ctx->wlan_vdev_list[i]) 1559 continue; 1560 1561 vdev_iter = ml_dev_ctx->wlan_vdev_list[i]; 1562 status = wlan_objmgr_vdev_try_get_ref(vdev_iter, 1563 WLAN_TDLS_NB_ID); 1564 if (QDF_IS_STATUS_ERROR(status)) 1565 continue; 1566 1567 if (is_enable) 1568 tdls_process_enable_for_vdev(vdev_iter); 1569 else 1570 tdls_disable_offchan_and_teardown_links(vdev_iter); 1571 1572 wlan_objmgr_vdev_release_ref(vdev_iter, WLAN_TDLS_NB_ID); 1573 } 1574 } 1575 #endif 1576 1577 static QDF_STATUS tdls_process_sta_connect(struct tdls_sta_notify_params * notify)1578 tdls_process_sta_connect(struct tdls_sta_notify_params *notify) 1579 { 1580 if (!tdls_check_is_tdls_allowed(notify->vdev)) 1581 return QDF_STATUS_E_NOSUPPORT; 1582 1583 tdls_process_enable_for_vdev(notify->vdev); 1584 1585 return QDF_STATUS_SUCCESS; 1586 } 1587 1588 static void tdls_update_discovery_tries(struct wlan_objmgr_vdev * vdev)1589 tdls_update_discovery_tries(struct wlan_objmgr_vdev *vdev) 1590 { 1591 struct tdls_soc_priv_obj *soc_obj; 1592 struct tdls_vdev_priv_obj *vdev_obj; 1593 struct tdls_user_config *tdls_config; 1594 struct tdls_config_params *vdev_config; 1595 QDF_STATUS status; 1596 1597 status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); 1598 if (QDF_IS_STATUS_ERROR(status)) { 1599 tdls_err("can't get vdev_obj & soc_obj"); 1600 return; 1601 } 1602 1603 vdev_config = &vdev_obj->threshold_config; 1604 tdls_config = &soc_obj->tdls_configs; 1605 1606 vdev_config->discovery_tries_n = 1607 tdls_config->tdls_max_discovery_attempt; 1608 } 1609 tdls_notify_sta_connect(struct tdls_sta_notify_params * notify)1610 QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) 1611 { 1612 QDF_STATUS status; 1613 1614 if (!notify) { 1615 tdls_err("invalid param"); 1616 return QDF_STATUS_E_INVAL; 1617 } 1618 1619 if (!notify->vdev) { 1620 tdls_err("invalid param"); 1621 qdf_mem_free(notify); 1622 return QDF_STATUS_E_INVAL; 1623 } 1624 1625 status = tdls_process_sta_connect(notify); 1626 if (QDF_IS_STATUS_SUCCESS(status)) 1627 tdls_update_discovery_tries(notify->vdev); 1628 1629 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1630 qdf_mem_free(notify); 1631 1632 return status; 1633 } 1634 1635 static QDF_STATUS tdls_process_sta_disconnect(struct tdls_sta_notify_params * notify)1636 tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) 1637 { 1638 struct tdls_vdev_priv_obj *tdls_vdev_obj; 1639 struct tdls_soc_priv_obj *tdls_soc_obj; 1640 struct wlan_objmgr_vdev *temp_vdev = NULL; 1641 QDF_STATUS status; 1642 1643 status = tdls_get_vdev_objects(notify->vdev, &tdls_vdev_obj, 1644 &tdls_soc_obj); 1645 if (QDF_IS_STATUS_ERROR(status)) 1646 return status; 1647 1648 /* if the disconnect comes from user space, we have to delete all the 1649 * tdls peers before sending the set state cmd. 1650 */ 1651 if (notify->user_disconnect) 1652 return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj); 1653 1654 tdls_debug("Check and update TDLS state for vdev:%d", 1655 notify->session_id); 1656 1657 /* Disassociation event */ 1658 tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false, 1659 false, false, notify->session_id); 1660 1661 tdls_timers_stop(tdls_vdev_obj); 1662 1663 /* 1664 * If concurrency is not marked, then we have to 1665 * check, whether TDLS could be enabled in the 1666 * system after this disassoc event. 1667 */ 1668 if (notify->lfr_roam) 1669 return status; 1670 1671 temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID); 1672 if (!temp_vdev) 1673 return status; 1674 1675 if (wlan_vdev_mlme_is_mlo_vdev(temp_vdev)) 1676 tdls_process_enable_disable_for_ml_vdev(temp_vdev, true); 1677 else 1678 tdls_process_enable_for_vdev(temp_vdev); 1679 1680 wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_TDLS_NB_ID); 1681 1682 wlan_vdev_mlme_feat_ext2_cap_clear(notify->vdev, 1683 WLAN_VDEV_FEXT2_MLO_STA_TDLS); 1684 1685 return status; 1686 } 1687 tdls_notify_sta_disconnect(struct tdls_sta_notify_params * notify)1688 QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) 1689 { 1690 QDF_STATUS status; 1691 struct wlan_objmgr_vdev *vdev; 1692 enum QDF_OPMODE opmode; 1693 struct wlan_objmgr_psoc *psoc; 1694 uint8_t sta_count; 1695 1696 if (!notify) { 1697 tdls_err("invalid param"); 1698 return QDF_STATUS_E_INVAL; 1699 } 1700 1701 vdev = notify->vdev; 1702 if (!vdev) { 1703 tdls_err("invalid param"); 1704 qdf_mem_free(notify); 1705 return QDF_STATUS_E_INVAL; 1706 } 1707 1708 psoc = wlan_vdev_get_psoc(vdev); 1709 if (!psoc) { 1710 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1711 qdf_mem_free(notify); 1712 return QDF_STATUS_E_INVAL; 1713 } 1714 1715 opmode = wlan_vdev_mlme_get_opmode(vdev); 1716 sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1717 NULL); 1718 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1719 tdls_debug("STA + P2P concurrency. No action on P2P vdev"); 1720 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1721 qdf_mem_free(notify); 1722 return QDF_STATUS_E_INVAL; 1723 } 1724 1725 status = tdls_process_sta_disconnect(notify); 1726 1727 wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); 1728 qdf_mem_free(notify); 1729 1730 return status; 1731 } 1732 tdls_process_reset_adapter(struct wlan_objmgr_vdev * vdev)1733 static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) 1734 { 1735 struct tdls_vdev_priv_obj *tdls_vdev; 1736 1737 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1738 if (!tdls_vdev) 1739 return; 1740 tdls_timers_stop(tdls_vdev); 1741 } 1742 tdls_notify_reset_adapter(struct wlan_objmgr_vdev * vdev)1743 void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) 1744 { 1745 if (!vdev) { 1746 QDF_ASSERT(0); 1747 return; 1748 } 1749 1750 if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, 1751 WLAN_TDLS_NB_ID)) 1752 return; 1753 1754 tdls_process_reset_adapter(vdev); 1755 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1756 } 1757 tdls_peers_deleted_notification(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1758 QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, 1759 uint8_t vdev_id) 1760 { 1761 struct scheduler_msg msg = {0, }; 1762 struct tdls_sta_notify_params *notify; 1763 QDF_STATUS status; 1764 struct wlan_objmgr_vdev *vdev; 1765 1766 notify = qdf_mem_malloc(sizeof(*notify)); 1767 if (!notify) 1768 return QDF_STATUS_E_NULL_VALUE; 1769 1770 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 1771 vdev_id, 1772 WLAN_TDLS_NB_ID); 1773 1774 if (!vdev) { 1775 tdls_err("vdev not exist for the vdev id %d", 1776 vdev_id); 1777 qdf_mem_free(notify); 1778 return QDF_STATUS_E_INVAL; 1779 } 1780 1781 notify->lfr_roam = true; 1782 notify->tdls_chan_swit_prohibited = false; 1783 notify->tdls_prohibited = false; 1784 notify->session_id = vdev_id; 1785 notify->vdev = vdev; 1786 notify->user_disconnect = false; 1787 1788 msg.bodyptr = notify; 1789 msg.callback = tdls_process_cmd; 1790 msg.flush_callback = tdls_post_msg_flush_cb; 1791 msg.type = TDLS_NOTIFY_STA_DISCONNECTION; 1792 1793 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1794 QDF_MODULE_ID_TDLS, 1795 QDF_MODULE_ID_OS_IF, &msg); 1796 if (QDF_IS_STATUS_ERROR(status)) { 1797 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1798 qdf_mem_free(notify); 1799 tdls_alert("message post failed "); 1800 1801 return QDF_STATUS_E_FAILURE; 1802 } 1803 1804 return QDF_STATUS_SUCCESS; 1805 } 1806 1807 static tdls_delete_all_peers_indication(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1808 QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, 1809 uint8_t vdev_id) 1810 { 1811 struct scheduler_msg msg = {0, }; 1812 struct tdls_delete_all_peers_params *indication; 1813 QDF_STATUS status; 1814 struct wlan_objmgr_vdev *vdev; 1815 1816 indication = qdf_mem_malloc(sizeof(*indication)); 1817 if (!indication) 1818 return QDF_STATUS_E_NULL_VALUE; 1819 1820 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 1821 WLAN_TDLS_SB_ID); 1822 if (!vdev) { 1823 tdls_err("vdev:%d does not exist", vdev_id); 1824 qdf_mem_free(indication); 1825 return QDF_STATUS_E_INVAL; 1826 } 1827 1828 indication->vdev = vdev; 1829 1830 msg.bodyptr = indication; 1831 msg.callback = tdls_process_cmd; 1832 msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; 1833 msg.flush_callback = tdls_post_msg_flush_cb; 1834 1835 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1836 QDF_MODULE_ID_TDLS, 1837 QDF_MODULE_ID_OS_IF, &msg); 1838 if (QDF_IS_STATUS_ERROR(status)) { 1839 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1840 qdf_mem_free(indication); 1841 tdls_alert("message post failed "); 1842 return QDF_STATUS_E_FAILURE; 1843 } 1844 1845 return QDF_STATUS_SUCCESS; 1846 } 1847 1848 QDF_STATUS tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id)1849 tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc, 1850 uint8_t vdev_id) 1851 { 1852 struct wlan_objmgr_pdev *pdev; 1853 uint32_t pdev_id; 1854 enum QDF_OPMODE opmode; 1855 uint8_t sta_count = 1856 policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, 1857 NULL); 1858 1859 pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, vdev_id, WLAN_TDLS_SB_ID); 1860 if (pdev_id == WLAN_INVALID_PDEV_ID) { 1861 tdls_debug("Invalid pdev id"); 1862 return QDF_STATUS_E_INVAL; 1863 } 1864 1865 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_TDLS_SB_ID); 1866 if (!pdev) { 1867 tdls_debug("pdev is NULL"); 1868 return QDF_STATUS_E_INVAL; 1869 } 1870 1871 opmode = wlan_get_opmode_from_vdev_id(pdev, vdev_id); 1872 wlan_objmgr_pdev_release_ref(pdev, WLAN_TDLS_SB_ID); 1873 1874 if (opmode == QDF_P2P_CLIENT_MODE && sta_count) { 1875 tdls_debug("STA + P2P concurrency. No action on P2P vdev"); 1876 return QDF_STATUS_E_INVAL; 1877 } 1878 1879 return tdls_delete_all_peers_indication(psoc, vdev_id); 1880 } 1881 1882 /** 1883 * tdls_set_mode_in_vdev() - set TDLS mode 1884 * @tdls_vdev: tdls vdev object 1885 * @tdls_soc: tdls soc object 1886 * @tdls_mode: TDLS mode 1887 * @source: TDLS disable source enum values 1888 * 1889 * Return: Void 1890 */ tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj * tdls_vdev,struct tdls_soc_priv_obj * tdls_soc,enum tdls_feature_mode tdls_mode,enum tdls_disable_sources source)1891 static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, 1892 struct tdls_soc_priv_obj *tdls_soc, 1893 enum tdls_feature_mode tdls_mode, 1894 enum tdls_disable_sources source) 1895 { 1896 tdls_debug("set tdls mode: %d source:%d", tdls_mode, 1897 source); 1898 1899 switch (tdls_mode) { 1900 case TDLS_SUPPORT_IMP_MODE: 1901 fallthrough; 1902 case TDLS_SUPPORT_EXT_CONTROL: 1903 clear_bit((unsigned long)source, &tdls_soc->tdls_source_bitmap); 1904 /* 1905 * Check if any TDLS source bit is set and if 1906 * bitmap is not zero then we should not enable TDLS 1907 */ 1908 if (tdls_soc->tdls_source_bitmap) { 1909 tdls_notice("Don't enable TDLS, source bitmap: %lu", 1910 tdls_soc->tdls_source_bitmap); 1911 return; 1912 } 1913 tdls_implicit_enable(tdls_vdev); 1914 /* 1915 * tdls implicit mode is enabled, so enable the connection 1916 * tracker 1917 */ 1918 tdls_soc->enable_tdls_connection_tracker = true; 1919 1920 return; 1921 1922 case TDLS_SUPPORT_DISABLED: 1923 set_bit((unsigned long)source, 1924 &tdls_soc->tdls_source_bitmap); 1925 tdls_implicit_disable(tdls_vdev); 1926 /* If tdls implicit mode is disabled, then 1927 * stop the connection tracker. 1928 */ 1929 tdls_soc->enable_tdls_connection_tracker = false; 1930 1931 return; 1932 1933 case TDLS_SUPPORT_EXP_TRIG_ONLY: 1934 clear_bit((unsigned long)source, 1935 &tdls_soc->tdls_source_bitmap); 1936 tdls_implicit_disable(tdls_vdev); 1937 /* If tdls implicit mode is disabled, then 1938 * stop the connection tracker. 1939 */ 1940 tdls_soc->enable_tdls_connection_tracker = false; 1941 1942 /* 1943 * Check if any TDLS source bit is set and if 1944 * bitmap is not zero then we should not 1945 * enable TDLS 1946 */ 1947 if (tdls_soc->tdls_source_bitmap) 1948 return; 1949 1950 return; 1951 default: 1952 return; 1953 } 1954 } 1955 1956 /** 1957 * tdls_set_current_mode() - set TDLS mode 1958 * @tdls_soc: tdls soc object 1959 * @tdls_mode: TDLS mode 1960 * @update_last: indicate to record the last tdls mode 1961 * @source: TDLS disable source enum values 1962 * 1963 * Return: Void 1964 */ tdls_set_current_mode(struct tdls_soc_priv_obj * tdls_soc,enum tdls_feature_mode tdls_mode,bool update_last,enum tdls_disable_sources source)1965 static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, 1966 enum tdls_feature_mode tdls_mode, 1967 bool update_last, 1968 enum tdls_disable_sources source) 1969 { 1970 struct wlan_objmgr_vdev *vdev; 1971 struct tdls_vdev_priv_obj *tdls_vdev; 1972 1973 if (!tdls_soc) 1974 return; 1975 1976 tdls_debug("mode %d", (int)tdls_mode); 1977 1978 if (update_last) 1979 tdls_soc->tdls_last_mode = tdls_mode; 1980 1981 if (tdls_soc->tdls_current_mode == tdls_mode) { 1982 tdls_debug("already in mode %d", tdls_mode); 1983 1984 switch (tdls_mode) { 1985 /* TDLS is already enabled hence clear source mask, return */ 1986 case TDLS_SUPPORT_IMP_MODE: 1987 case TDLS_SUPPORT_EXP_TRIG_ONLY: 1988 case TDLS_SUPPORT_EXT_CONTROL: 1989 clear_bit((unsigned long)source, 1990 &tdls_soc->tdls_source_bitmap); 1991 tdls_debug("clear source mask:%d", source); 1992 return; 1993 /* TDLS is already disabled hence set source mask, return */ 1994 case TDLS_SUPPORT_DISABLED: 1995 set_bit((unsigned long)source, 1996 &tdls_soc->tdls_source_bitmap); 1997 tdls_debug("set source mask:%d", source); 1998 return; 1999 default: 2000 return; 2001 } 2002 } 2003 2004 /* get sta vdev */ 2005 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, 2006 QDF_STA_MODE, 2007 WLAN_TDLS_NB_ID); 2008 if (vdev) { 2009 tdls_debug("set mode in tdls STA vdev:%d", 2010 wlan_vdev_get_id(vdev)); 2011 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 2012 if (tdls_vdev) 2013 tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, 2014 tdls_mode, source); 2015 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2016 2017 goto exit; 2018 } 2019 2020 /* get p2p client vdev */ 2021 vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, 2022 QDF_P2P_CLIENT_MODE, 2023 WLAN_TDLS_NB_ID); 2024 if (vdev) { 2025 tdls_debug("set mode in tdls P2P cli vdev:%d", 2026 wlan_vdev_get_id(vdev)); 2027 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 2028 if (tdls_vdev) 2029 tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, 2030 tdls_mode, source); 2031 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2032 } 2033 2034 exit: 2035 if (!update_last) 2036 tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode; 2037 2038 tdls_soc->tdls_current_mode = tdls_mode; 2039 } 2040 tdls_set_operation_mode(struct tdls_set_mode_params * tdls_set_mode)2041 QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) 2042 { 2043 struct tdls_soc_priv_obj *tdls_soc; 2044 struct tdls_vdev_priv_obj *tdls_vdev; 2045 QDF_STATUS status; 2046 2047 if (!tdls_set_mode) 2048 return QDF_STATUS_E_INVAL; 2049 2050 if (!tdls_set_mode->vdev) { 2051 qdf_mem_free(tdls_set_mode); 2052 return QDF_STATUS_E_INVAL; 2053 } 2054 2055 status = tdls_get_vdev_objects(tdls_set_mode->vdev, 2056 &tdls_vdev, &tdls_soc); 2057 2058 if (QDF_IS_STATUS_ERROR(status)) 2059 goto release_mode_ref; 2060 2061 tdls_set_current_mode(tdls_soc, 2062 tdls_set_mode->tdls_mode, 2063 tdls_set_mode->update_last, 2064 tdls_set_mode->source); 2065 2066 release_mode_ref: 2067 wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID); 2068 qdf_mem_free(tdls_set_mode); 2069 return status; 2070 } 2071 2072 /** 2073 * tdls_scan_done_callback() - callback for tdls scan done event 2074 * @tdls_soc: tdls soc object 2075 * 2076 * Return: Void 2077 */ tdls_scan_done_callback(struct tdls_soc_priv_obj * tdls_soc)2078 void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) 2079 { 2080 if (!tdls_soc) 2081 return; 2082 2083 /* if tdls was enabled before scan, re-enable tdls mode */ 2084 if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || 2085 TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || 2086 TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) 2087 tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, 2088 false, TDLS_SET_MODE_SOURCE_SCAN); 2089 } 2090 2091 /** 2092 * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue 2093 * @tdls_soc: tdls soc object 2094 * 2095 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE 2096 */ tdls_post_scan_done_msg(struct tdls_soc_priv_obj * tdls_soc)2097 static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) 2098 { 2099 struct scheduler_msg msg = {0, }; 2100 2101 if (!tdls_soc) { 2102 tdls_err("tdls_soc: %pK ", tdls_soc); 2103 return QDF_STATUS_E_NULL_VALUE; 2104 } 2105 2106 msg.bodyptr = tdls_soc; 2107 msg.callback = tdls_process_cmd; 2108 msg.flush_callback = tdls_post_msg_flush_cb; 2109 msg.type = TDLS_CMD_SCAN_DONE; 2110 2111 return scheduler_post_message(QDF_MODULE_ID_TDLS, 2112 QDF_MODULE_ID_TDLS, 2113 QDF_MODULE_ID_OS_IF, &msg); 2114 } 2115 tdls_scan_complete_event_handler(struct wlan_objmgr_vdev * vdev,struct scan_event * event,void * arg)2116 void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, 2117 struct scan_event *event, 2118 void *arg) 2119 { 2120 enum QDF_OPMODE device_mode; 2121 struct tdls_soc_priv_obj *tdls_soc; 2122 2123 if (!vdev || !event || !arg) 2124 return; 2125 2126 if (SCAN_EVENT_TYPE_COMPLETED != event->type) 2127 return; 2128 2129 device_mode = wlan_vdev_mlme_get_opmode(vdev); 2130 2131 tdls_soc = (struct tdls_soc_priv_obj *) arg; 2132 tdls_post_scan_done_msg(tdls_soc); 2133 } 2134 tdls_set_link_unforce(struct wlan_objmgr_vdev * vdev)2135 void tdls_set_link_unforce(struct wlan_objmgr_vdev *vdev) 2136 { 2137 QDF_STATUS status; 2138 struct scheduler_msg msg = {0}; 2139 2140 msg.callback = tdls_process_cmd; 2141 msg.type = TDLS_CMD_SET_LINK_UNFORCE; 2142 msg.bodyptr = vdev; 2143 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 2144 QDF_MODULE_ID_TDLS, 2145 QDF_MODULE_ID_OS_IF, &msg); 2146 if (QDF_IS_STATUS_ERROR(status)) 2147 tdls_err("failed to set tdls link mode"); 2148 } 2149 2150 /** 2151 * tdls_check_peer_buf_capable() - Check buffer sta capable of tdls peers 2152 * @tdls_vdev: TDLS vdev object 2153 * 2154 * Used in scheduler thread context, no lock needed. 2155 * 2156 * Return: false if there is connected peer and not support buffer sta. 2157 */ tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj * tdls_vdev)2158 static bool tdls_check_peer_buf_capable(struct tdls_vdev_priv_obj *tdls_vdev) 2159 { 2160 uint16_t i; 2161 struct tdls_peer *peer; 2162 qdf_list_t *head; 2163 qdf_list_node_t *p_node; 2164 QDF_STATUS status; 2165 2166 if (!tdls_vdev) { 2167 tdls_err("invalid tdls vdev object"); 2168 return false; 2169 } 2170 2171 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 2172 head = &tdls_vdev->peer_list[i]; 2173 2174 status = qdf_list_peek_front(head, &p_node); 2175 while (QDF_IS_STATUS_SUCCESS(status)) { 2176 peer = qdf_container_of(p_node, struct tdls_peer, node); 2177 2178 if (peer && 2179 (TDLS_LINK_CONNECTED == peer->link_status) && 2180 (!peer->buf_sta_capable)) 2181 return false; 2182 2183 status = qdf_list_peek_next(head, p_node, &p_node); 2184 } 2185 } 2186 2187 return true; 2188 } 2189 tdls_scan_callback(struct tdls_soc_priv_obj * tdls_soc)2190 QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) 2191 { 2192 struct tdls_vdev_priv_obj *tdls_vdev; 2193 struct wlan_objmgr_vdev *vdev; 2194 uint16_t tdls_peer_count; 2195 uint32_t feature; 2196 bool peer_buf_capable; 2197 QDF_STATUS status = QDF_STATUS_SUCCESS; 2198 2199 /* if tdls is not enabled, then continue scan */ 2200 if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) 2201 return status; 2202 2203 /* Get the vdev based on vdev operating mode*/ 2204 vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID); 2205 if (!vdev) 2206 return status; 2207 2208 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 2209 if (!tdls_vdev) 2210 goto return_success; 2211 2212 if (tdls_is_progress(tdls_vdev, NULL, 0)) { 2213 if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { 2214 tdls_notice("Allow this scan req. as already max no of scan's are rejected"); 2215 tdls_soc->scan_reject_count = 0; 2216 status = QDF_STATUS_SUCCESS; 2217 2218 } else { 2219 tdls_warn("tdls in progress. scan rejected %d", 2220 tdls_soc->scan_reject_count); 2221 status = QDF_STATUS_E_BUSY; 2222 } 2223 } 2224 2225 tdls_peer_count = tdls_soc->connected_peer_count; 2226 if (!tdls_peer_count) 2227 goto disable_tdls; 2228 2229 feature = tdls_soc->tdls_configs.tdls_feature_flags; 2230 if (TDLS_IS_SCAN_ENABLED(feature)) { 2231 tdls_debug("TDLS Scan enabled, keep tdls link and allow scan, connected tdls peers: %d", 2232 tdls_peer_count); 2233 goto disable_tdls; 2234 } 2235 2236 if (TDLS_IS_BUFFER_STA_ENABLED(feature) && 2237 (tdls_peer_count <= TDLS_MAX_CONNECTED_PEERS_TO_ALLOW_SCAN)) { 2238 peer_buf_capable = tdls_check_peer_buf_capable(tdls_vdev); 2239 if (peer_buf_capable) { 2240 tdls_debug("All peers (num %d) bufSTAs, we can be sleep sta, so allow scan, tdls mode changed to %d", 2241 tdls_peer_count, 2242 tdls_soc->tdls_current_mode); 2243 goto disable_tdls; 2244 } 2245 } 2246 2247 tdls_disable_offchan_and_teardown_links(vdev); 2248 2249 disable_tdls: 2250 tdls_set_current_mode(tdls_soc, TDLS_SUPPORT_DISABLED, 2251 false, TDLS_SET_MODE_SOURCE_SCAN); 2252 2253 return_success: 2254 wlan_objmgr_vdev_release_ref(vdev, 2255 WLAN_TDLS_NB_ID); 2256 return status; 2257 } 2258 tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev * vdev,union wlan_serialization_rules_info * comp_info,struct wlan_serialization_command * cmd)2259 void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, 2260 union wlan_serialization_rules_info *comp_info, 2261 struct wlan_serialization_command *cmd) 2262 { 2263 struct tdls_soc_priv_obj *tdls_soc; 2264 QDF_STATUS status; 2265 if (!comp_info) 2266 return; 2267 2268 tdls_soc = tdls_soc_global; 2269 comp_info->scan_info.is_tdls_in_progress = false; 2270 status = tdls_scan_callback(tdls_soc); 2271 if (QDF_STATUS_E_BUSY == status) 2272 comp_info->scan_info.is_tdls_in_progress = true; 2273 } 2274 tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev * vdev,qdf_freq_t ch_freq,uint8_t bw_offset,uint16_t behav_limit)2275 static uint8_t tdls_find_opclass_frm_freq(struct wlan_objmgr_vdev *vdev, 2276 qdf_freq_t ch_freq, uint8_t bw_offset, 2277 uint16_t behav_limit) 2278 { 2279 struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev); 2280 uint8_t channel, opclass; 2281 2282 if (!pdev) { 2283 tdls_err("pdev is NULL"); 2284 return 0; 2285 } 2286 2287 wlan_reg_freq_width_to_chan_op_class(pdev, ch_freq, bw_offset, false, 2288 BIT(behav_limit), &opclass, 2289 &channel); 2290 2291 return opclass; 2292 } 2293 tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq,uint8_t bw_offset,uint8_t * reg_bw_offset)2294 uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev, 2295 qdf_freq_t freq, uint8_t bw_offset, 2296 uint8_t *reg_bw_offset) 2297 { 2298 uint8_t opclass; 2299 2300 if (bw_offset & (1 << BW_160_OFFSET_BIT)) { 2301 opclass = tdls_find_opclass_frm_freq(vdev, 2302 freq, BW_160_MHZ, 2303 BEHAV_NONE); 2304 *reg_bw_offset = BWALL; 2305 } else if (bw_offset & (1 << BW_80_OFFSET_BIT)) { 2306 opclass = tdls_find_opclass_frm_freq(vdev, 2307 freq, BW_80_MHZ, 2308 BEHAV_NONE); 2309 *reg_bw_offset = BW80; 2310 } else if (bw_offset & (1 << BW_40_OFFSET_BIT)) { 2311 opclass = tdls_find_opclass_frm_freq(vdev, 2312 freq, BW_40_MHZ, 2313 BEHAV_BW40_LOW_PRIMARY); 2314 *reg_bw_offset = BW40_LOW_PRIMARY; 2315 if (!opclass) { 2316 opclass = tdls_find_opclass_frm_freq(vdev, 2317 freq, 2318 BW_40_MHZ, 2319 BEHAV_BW40_HIGH_PRIMARY); 2320 *reg_bw_offset = BW40_HIGH_PRIMARY; 2321 } 2322 } else if (bw_offset & (1 << BW_20_OFFSET_BIT)) { 2323 opclass = tdls_find_opclass_frm_freq(vdev, 2324 freq, BW_20_MHZ, 2325 BEHAV_NONE); 2326 *reg_bw_offset = BW20; 2327 } else { 2328 opclass = tdls_find_opclass_frm_freq(vdev, 2329 freq, BW_160_MHZ, 2330 BEHAV_NONE); 2331 *reg_bw_offset = BWALL; 2332 } 2333 2334 return opclass; 2335 } 2336