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_cmds_process.c 22 * 23 * TDLS north bound commands implementation 24 */ 25 #include <qdf_types.h> 26 #include <qdf_status.h> 27 #include <wlan_cmn.h> 28 #include <reg_services_public_struct.h> 29 #include <wlan_objmgr_psoc_obj.h> 30 #include <wlan_objmgr_pdev_obj.h> 31 #include <wlan_reg_services_api.h> 32 #include <wlan_serialization_api.h> 33 #include "wlan_tdls_main.h" 34 #include "wlan_tdls_peer.h" 35 #include "wlan_tdls_ct.h" 36 #include "wlan_tdls_mgmt.h" 37 #include "wlan_tdls_cmds_process.h" 38 #include "wlan_tdls_tgt_api.h" 39 #include "wlan_policy_mgr_api.h" 40 #include "nan_ucfg_api.h" 41 #include "wlan_mlme_main.h" 42 #include "wlan_policy_mgr_i.h" 43 44 static uint16_t tdls_get_connected_peer_count(struct tdls_soc_priv_obj *soc_obj) 45 { 46 return soc_obj->connected_peer_count; 47 } 48 49 uint16_t tdls_get_connected_peer_count_from_vdev(struct wlan_objmgr_vdev *vdev) 50 { 51 struct tdls_soc_priv_obj *soc_obj; 52 53 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 54 55 if (!soc_obj) 56 return 0; 57 58 return tdls_get_connected_peer_count(soc_obj); 59 } 60 61 #ifdef WLAN_FEATURE_11AX 62 static 63 uint8_t tdls_get_mlme_ch_power(struct vdev_mlme_obj *mlme_obj, qdf_freq_t freq) 64 { 65 uint8_t num_power = mlme_obj->reg_tpc_obj.num_pwr_levels; 66 uint8_t idx; 67 struct reg_tpc_power_info *reg_power_info; 68 69 reg_power_info = &mlme_obj->reg_tpc_obj; 70 for (idx = 0; idx < num_power; idx++) { 71 if (freq == reg_power_info->chan_power_info[idx].chan_cfreq) 72 return reg_power_info->chan_power_info[idx].tx_power; 73 } 74 75 tdls_debug("channel %d not present in reg power info", freq); 76 return 0; 77 } 78 79 static 80 void tdls_set_mlme_ch_power(struct wlan_objmgr_vdev *vdev, 81 struct vdev_mlme_obj *mlme_obj, 82 struct tdls_soc_priv_obj *tdls_soc_obj, 83 qdf_freq_t freq) 84 { 85 uint8_t num_power = mlme_obj->reg_tpc_obj.num_pwr_levels; 86 uint8_t idx, tx_power; 87 struct reg_tpc_power_info *reg_power_info = &mlme_obj->reg_tpc_obj; 88 89 if (REG_VERY_LOW_POWER_AP == reg_power_info->power_type_6g) 90 tx_power = tdls_get_6g_pwr_for_power_type(vdev, freq, 91 REG_CLI_DEF_VLP); 92 else 93 tx_power = tdls_soc_obj->bss_sta_power; 94 95 for (idx = 0; idx < num_power; idx++) { 96 if (freq == reg_power_info->chan_power_info[idx].chan_cfreq) { 97 reg_power_info->chan_power_info[idx].tx_power = 98 tx_power; 99 return; 100 } 101 } 102 103 tdls_debug("channel %d not present in reg power info", freq); 104 } 105 106 static 107 void tdls_update_6g_power(struct wlan_objmgr_vdev *vdev, 108 struct tdls_soc_priv_obj *tdls_soc_obj, 109 bool enable_link) 110 { 111 struct wlan_lmac_if_reg_tx_ops *tx_ops; 112 struct vdev_mlme_obj *mlme_obj; 113 struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev); 114 qdf_freq_t freq = wlan_get_operation_chan_freq(vdev); 115 116 if (!psoc) { 117 tdls_err("psoc is NULL"); 118 return; 119 } 120 121 /* 122 * Check whether the frequency is 6ghz and tdls connection on 6ghz freq 123 * is allowed. 124 */ 125 if (!tdls_is_6g_freq_allowed(vdev, freq)) 126 return; 127 128 /* 129 * Since, 8 TDLS peers can be connected. If connected peer already 130 * exist then no need to set the power again. 131 * Similarly, for disconnection case, this function is called after 132 * just after connected peer count is decreased. If connected peer 133 * count exist after decrement of peer count that mean another peer 134 * exist and then no need to reset the BSS power. 135 * The power should only be set/reset when 1st peer gets connected or 136 * last connected peer gets disconnected. 137 */ 138 if (tdls_soc_obj->connected_peer_count) { 139 tdls_debug("Number of connected peer %d", 140 tdls_soc_obj->connected_peer_count); 141 return; 142 } 143 144 mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev); 145 if (!mlme_obj) { 146 tdls_err("vdev component object is NULL"); 147 return; 148 } 149 150 if (enable_link) { 151 tdls_soc_obj->bss_sta_power_type = REG_VERY_LOW_POWER_AP; 152 /* 153 * No need to update power if BSS-STA link is already configured 154 * as VLP 155 */ 156 if (tdls_soc_obj->bss_sta_power_type == 157 mlme_obj->reg_tpc_obj.power_type_6g) 158 return; 159 160 tdls_soc_obj->bss_sta_power_type = 161 mlme_obj->reg_tpc_obj.power_type_6g; 162 mlme_obj->reg_tpc_obj.power_type_6g = REG_VERY_LOW_POWER_AP; 163 tdls_soc_obj->bss_sta_power = tdls_get_mlme_ch_power(mlme_obj, 164 freq); 165 tdls_debug("Updated power_type from %d to %d bss link power %d", 166 tdls_soc_obj->bss_sta_power_type, 167 mlme_obj->reg_tpc_obj.power_type_6g, 168 tdls_soc_obj->bss_sta_power); 169 } else { 170 if (REG_VERY_LOW_POWER_AP == tdls_soc_obj->bss_sta_power_type) 171 return; 172 173 tdls_debug("Updated power_type_6g from %d to %d", 174 mlme_obj->reg_tpc_obj.power_type_6g, 175 tdls_soc_obj->bss_sta_power_type); 176 mlme_obj->reg_tpc_obj.power_type_6g = 177 tdls_soc_obj->bss_sta_power_type; 178 } 179 tdls_set_mlme_ch_power(vdev, mlme_obj, tdls_soc_obj, freq); 180 181 tx_ops = wlan_reg_get_tx_ops(psoc); 182 if (tx_ops->set_tpc_power) 183 tx_ops->set_tpc_power(psoc, 184 wlan_vdev_get_id(vdev), 185 &mlme_obj->reg_tpc_obj); 186 } 187 #else 188 static 189 void tdls_update_6g_power(struct wlan_objmgr_vdev *vdev, 190 struct tdls_soc_priv_obj *tdls_soc_obj, 191 bool enable_link) 192 { 193 } 194 #endif 195 196 /** 197 * tdls_decrement_peer_count() - decrement connected TDLS peer counter 198 * @vdev: vdev object 199 * @soc_obj: TDLS soc object 200 * 201 * Used in scheduler thread context, no lock needed. 202 * 203 * Return: None. 204 */ 205 void tdls_decrement_peer_count(struct wlan_objmgr_vdev *vdev, 206 struct tdls_soc_priv_obj *soc_obj) 207 { 208 if (soc_obj->connected_peer_count) 209 soc_obj->connected_peer_count--; 210 211 tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); 212 213 /* Need to update osif params when last peer gets disconnected */ 214 if (!soc_obj->connected_peer_count && 215 soc_obj->tdls_osif_update_cb.tdls_osif_disconn_update) 216 soc_obj->tdls_osif_update_cb.tdls_osif_disconn_update(vdev); 217 tdls_update_6g_power(vdev, soc_obj, false); 218 219 /* 220 * Offchannel is allowed only when TDLS is connected with one peer. 221 * If more than one peer is connected then Offchannel is disabled by 222 * WMI_TDLS_SET_OFFCHAN_MODE_CMDID with DISABLE_CHANSWITCH. 223 * Hence, re-enable offchannel when only one connected peer is left. 224 */ 225 if (soc_obj->connected_peer_count == 1) 226 tdls_set_tdls_offchannelmode(vdev, ENABLE_CHANSWITCH); 227 } 228 229 /** 230 * tdls_increment_peer_count() - increment connected TDLS peer counter 231 * @soc_obj: TDLS soc object 232 * 233 * Used in scheduler thread context, no lock needed. 234 * 235 * Return: None. 236 */ 237 static void tdls_increment_peer_count(struct tdls_soc_priv_obj *soc_obj) 238 { 239 soc_obj->connected_peer_count++; 240 tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); 241 } 242 243 /** 244 * tdls_validate_current_mode() - check current TDL mode 245 * @soc_obj: TDLS soc object 246 * 247 * Return: QDF_STATUS_SUCCESS if TDLS enabled, other for disabled 248 */ 249 static QDF_STATUS tdls_validate_current_mode(struct tdls_soc_priv_obj *soc_obj) 250 { 251 if (soc_obj->tdls_current_mode == TDLS_SUPPORT_DISABLED || 252 soc_obj->tdls_current_mode == TDLS_SUPPORT_SUSPENDED) { 253 tdls_err("TDLS mode disabled OR not enabled, current mode %d", 254 soc_obj->tdls_current_mode); 255 return QDF_STATUS_E_NOSUPPORT; 256 } 257 return QDF_STATUS_SUCCESS; 258 } 259 260 static char *tdls_get_ser_cmd_str(enum wlan_serialization_cmd_type type) 261 { 262 switch (type) { 263 case WLAN_SER_CMD_TDLS_ADD_PEER: 264 return "TDLS_ADD_PEER_CMD"; 265 case WLAN_SER_CMD_TDLS_DEL_PEER: 266 return "TDLS_DEL_PEER_CMD"; 267 case WLAN_SER_CMD_TDLS_SEND_MGMT: 268 return "TDLS_SEND_MGMT_CMD"; 269 default: 270 return "UNKNOWN"; 271 } 272 } 273 274 void 275 tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, 276 enum wlan_serialization_cmd_type type) 277 { 278 struct wlan_serialization_queued_cmd_info cmd = {0}; 279 280 cmd.cmd_type = type; 281 cmd.cmd_id = 0; 282 cmd.vdev = vdev; 283 284 tdls_debug("release %s", tdls_get_ser_cmd_str(type)); 285 /* Inform serialization for command completion */ 286 wlan_serialization_remove_cmd(&cmd); 287 } 288 289 /** 290 * tdls_pe_add_peer() - send TDLS add peer request to PE 291 * @req: TDL add peer request 292 * 293 * Return: QDF_STATUS_SUCCESS for success; other values if failed 294 */ 295 static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) 296 { 297 struct tdls_add_sta_req *addstareq; 298 struct wlan_objmgr_vdev *vdev; 299 struct wlan_objmgr_peer *peer; 300 struct tdls_soc_priv_obj *soc_obj; 301 struct scheduler_msg msg = {0,}; 302 QDF_STATUS status; 303 304 addstareq = qdf_mem_malloc(sizeof(*addstareq)); 305 if (!addstareq) 306 return QDF_STATUS_E_NOMEM; 307 308 vdev = req->vdev; 309 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 310 if (!soc_obj) { 311 tdls_err("NULL tdls soc object"); 312 status = QDF_STATUS_E_INVAL; 313 goto error; 314 } 315 316 addstareq->tdls_oper = TDLS_OPER_ADD; 317 addstareq->transaction_id = 0; 318 319 addstareq->session_id = wlan_vdev_get_id(vdev); 320 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID); 321 if (!peer) { 322 tdls_err("bss peer is NULL"); 323 status = QDF_STATUS_E_INVAL; 324 goto error; 325 } 326 wlan_peer_obj_lock(peer); 327 qdf_mem_copy(addstareq->bssid.bytes, 328 wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); 329 wlan_peer_obj_unlock(peer); 330 wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); 331 qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, 332 QDF_MAC_ADDR_SIZE); 333 334 tdls_debug("for " QDF_MAC_ADDR_FMT, 335 QDF_MAC_ADDR_REF(addstareq->peermac.bytes)); 336 msg.type = soc_obj->tdls_add_sta_req; 337 msg.bodyptr = addstareq; 338 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 339 QDF_MODULE_ID_PE, 340 QDF_MODULE_ID_PE, &msg); 341 if (QDF_IS_STATUS_ERROR(status)) { 342 tdls_err("fail to post pe msg to add peer"); 343 goto error; 344 } 345 return status; 346 error: 347 qdf_mem_free(addstareq); 348 return status; 349 } 350 351 /** 352 * tdls_pe_del_peer() - send TDLS delete peer request to PE 353 * @req: TDLS delete peer request 354 * 355 * Return: QDF_STATUS_SUCCESS for success; other values if failed 356 */ 357 QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) 358 { 359 struct tdls_del_sta_req *delstareq; 360 struct wlan_objmgr_vdev *vdev; 361 struct wlan_objmgr_peer *peer; 362 struct tdls_soc_priv_obj *soc_obj; 363 struct scheduler_msg msg = {0,}; 364 QDF_STATUS status; 365 366 delstareq = qdf_mem_malloc(sizeof(*delstareq)); 367 if (!delstareq) 368 return QDF_STATUS_E_NOMEM; 369 370 vdev = req->vdev; 371 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 372 if (!soc_obj) { 373 tdls_err("NULL tdls soc object"); 374 status = QDF_STATUS_E_INVAL; 375 goto error; 376 } 377 378 delstareq->transaction_id = 0; 379 380 delstareq->session_id = wlan_vdev_get_id(vdev); 381 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID); 382 if (!peer) { 383 tdls_err("bss peer is NULL"); 384 status = QDF_STATUS_E_INVAL; 385 goto error; 386 } 387 388 wlan_peer_obj_lock(peer); 389 qdf_mem_copy(delstareq->bssid.bytes, 390 wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); 391 wlan_peer_obj_unlock(peer); 392 wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); 393 qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, 394 QDF_MAC_ADDR_SIZE); 395 396 tdls_debug("for " QDF_MAC_ADDR_FMT, 397 QDF_MAC_ADDR_REF(delstareq->peermac.bytes)); 398 msg.type = soc_obj->tdls_del_sta_req; 399 msg.bodyptr = delstareq; 400 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 401 QDF_MODULE_ID_PE, 402 QDF_MODULE_ID_PE, &msg); 403 if (QDF_IS_STATUS_ERROR(status)) { 404 tdls_err("fail to post pe msg to del peer"); 405 goto error; 406 } 407 return status; 408 error: 409 qdf_mem_free(delstareq); 410 return status; 411 } 412 #ifdef WLAN_FEATURE_11AX 413 static void tdls_pe_update_peer_6ghz_capa(struct tdls_add_sta_req *addstareq, 414 struct tdls_update_peer_params *update_peer) 415 { 416 qdf_mem_copy(&addstareq->he_6ghz_cap, &update_peer->he_6ghz_cap, 417 sizeof(update_peer->he_6ghz_cap)); 418 } 419 420 static void tdls_pe_update_peer_he_capa(struct tdls_add_sta_req *addstareq, 421 struct tdls_update_peer_params *update_peer) 422 { 423 addstareq->he_cap_len = update_peer->he_cap_len; 424 qdf_mem_copy(&addstareq->he_cap, 425 &update_peer->he_cap, 426 sizeof(update_peer->he_cap)); 427 428 tdls_pe_update_peer_6ghz_capa(addstareq, update_peer); 429 } 430 #else 431 static void tdls_pe_update_peer_he_capa(struct tdls_add_sta_req *addstareq, 432 struct tdls_update_peer_params *update_peer) 433 { 434 } 435 #endif 436 437 #ifdef WLAN_FEATURE_11BE 438 static inline void 439 tdls_pe_update_peer_eht_capa(struct tdls_add_sta_req *addstareq, 440 struct tdls_update_peer_params *update_peer) 441 { 442 if (update_peer->ehtcap_present) { 443 addstareq->ehtcap_present = update_peer->ehtcap_present; 444 addstareq->eht_cap_len = update_peer->eht_cap_len; 445 qdf_mem_copy(&addstareq->eht_cap, 446 &update_peer->eht_cap, 447 sizeof(update_peer->eht_cap)); 448 } 449 } 450 #else 451 static inline void 452 tdls_pe_update_peer_eht_capa(struct tdls_add_sta_req *addstareq, 453 struct tdls_update_peer_params *update_peer) 454 { 455 } 456 #endif 457 /** 458 * tdls_pe_update_peer() - send TDLS update peer request to PE 459 * @req: TDLS update peer request 460 * 461 * Return: QDF_STATUS_SUCCESS for success; other values if failed 462 */ 463 static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) 464 { 465 struct tdls_add_sta_req *addstareq; 466 struct wlan_objmgr_vdev *vdev; 467 struct wlan_objmgr_peer *peer; 468 struct tdls_soc_priv_obj *soc_obj; 469 struct scheduler_msg msg = {0,}; 470 struct tdls_update_peer_params *update_peer; 471 QDF_STATUS status; 472 473 addstareq = qdf_mem_malloc(sizeof(*addstareq)); 474 if (!addstareq) 475 return QDF_STATUS_E_NOMEM; 476 477 vdev = req->vdev; 478 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 479 if (!soc_obj) { 480 tdls_err("NULL tdls soc object"); 481 status = QDF_STATUS_E_INVAL; 482 goto error; 483 } 484 update_peer = &req->update_peer_req; 485 486 addstareq->tdls_oper = TDLS_OPER_UPDATE; 487 addstareq->transaction_id = 0; 488 489 addstareq->session_id = wlan_vdev_get_id(vdev); 490 peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID); 491 if (!peer) { 492 tdls_err("bss peer is NULL"); 493 status = QDF_STATUS_E_INVAL; 494 goto error; 495 } 496 wlan_peer_obj_lock(peer); 497 qdf_mem_copy(addstareq->bssid.bytes, 498 wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); 499 wlan_peer_obj_unlock(peer); 500 wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); 501 qdf_mem_copy(addstareq->peermac.bytes, update_peer->peer_addr, 502 QDF_MAC_ADDR_SIZE); 503 addstareq->capability = update_peer->capability; 504 addstareq->uapsd_queues = update_peer->uapsd_queues; 505 addstareq->max_sp = update_peer->max_sp; 506 507 qdf_mem_copy(addstareq->extn_capability, 508 update_peer->extn_capability, WLAN_MAC_MAX_EXTN_CAP); 509 addstareq->htcap_present = update_peer->htcap_present; 510 qdf_mem_copy(&addstareq->ht_cap, 511 &update_peer->ht_cap, 512 sizeof(update_peer->ht_cap)); 513 addstareq->vhtcap_present = update_peer->vhtcap_present; 514 qdf_mem_copy(&addstareq->vht_cap, 515 &update_peer->vht_cap, 516 sizeof(update_peer->vht_cap)); 517 tdls_pe_update_peer_he_capa(addstareq, update_peer); 518 tdls_pe_update_peer_eht_capa(addstareq, update_peer); 519 addstareq->supported_rates_length = update_peer->supported_rates_len; 520 addstareq->is_pmf = update_peer->is_pmf; 521 qdf_mem_copy(&addstareq->supported_rates, 522 update_peer->supported_rates, 523 update_peer->supported_rates_len); 524 tdls_debug("for " QDF_MAC_ADDR_FMT, 525 QDF_MAC_ADDR_REF(addstareq->peermac.bytes)); 526 527 msg.type = soc_obj->tdls_add_sta_req; 528 msg.bodyptr = addstareq; 529 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 530 QDF_MODULE_ID_PE, 531 QDF_MODULE_ID_PE, &msg); 532 if (QDF_IS_STATUS_ERROR(status)) { 533 tdls_err("fail to post pe msg to update peer"); 534 goto error; 535 } 536 return status; 537 error: 538 qdf_mem_free(addstareq); 539 return status; 540 } 541 542 static QDF_STATUS 543 tdls_internal_add_peer_rsp(struct tdls_add_peer_request *req, 544 QDF_STATUS status) 545 { 546 struct tdls_soc_priv_obj *soc_obj; 547 struct wlan_objmgr_vdev *vdev; 548 struct tdls_osif_indication ind; 549 QDF_STATUS ret; 550 551 if (!req || !req->vdev) { 552 tdls_err("req: %pK", req); 553 return QDF_STATUS_E_INVAL; 554 } 555 vdev = req->vdev; 556 ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); 557 if (QDF_IS_STATUS_ERROR(ret)) { 558 tdls_err("can't get vdev object"); 559 return ret; 560 } 561 562 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 563 if (soc_obj && soc_obj->tdls_event_cb) { 564 ind.vdev = vdev; 565 ind.status = status; 566 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 567 TDLS_EVENT_ADD_PEER, &ind); 568 } 569 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 570 571 return QDF_STATUS_SUCCESS; 572 } 573 574 static QDF_STATUS 575 tdls_internal_update_peer_rsp(struct tdls_update_peer_request *req, 576 QDF_STATUS status) 577 { 578 struct tdls_soc_priv_obj *soc_obj; 579 struct tdls_osif_indication ind; 580 struct wlan_objmgr_vdev *vdev; 581 QDF_STATUS ret; 582 583 if (!req || !req->vdev) { 584 tdls_err("req: %pK", req); 585 return QDF_STATUS_E_INVAL; 586 } 587 vdev = req->vdev; 588 ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); 589 if (QDF_IS_STATUS_ERROR(ret)) { 590 tdls_err("can't get vdev object"); 591 return ret; 592 } 593 594 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 595 if (soc_obj && soc_obj->tdls_event_cb) { 596 ind.vdev = vdev; 597 ind.status = status; 598 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 599 TDLS_EVENT_ADD_PEER, &ind); 600 } 601 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 602 603 return QDF_STATUS_SUCCESS; 604 } 605 606 static QDF_STATUS tdls_internal_del_peer_rsp(struct tdls_oper_request *req) 607 { 608 struct tdls_soc_priv_obj *soc_obj; 609 struct tdls_osif_indication ind; 610 struct wlan_objmgr_vdev *vdev; 611 QDF_STATUS status; 612 613 if (!req || !req->vdev) { 614 tdls_err("req: %pK", req); 615 return QDF_STATUS_E_INVAL; 616 } 617 vdev = req->vdev; 618 status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); 619 if (QDF_IS_STATUS_ERROR(status)) { 620 tdls_err("can't get vdev object"); 621 return status; 622 } 623 624 soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); 625 if (soc_obj && soc_obj->tdls_event_cb) { 626 ind.vdev = req->vdev; 627 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 628 TDLS_EVENT_DEL_PEER, &ind); 629 } 630 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 631 632 return QDF_STATUS_SUCCESS; 633 } 634 635 static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) 636 { 637 QDF_STATUS status; 638 struct tdls_soc_priv_obj *soc_obj; 639 struct tdls_vdev_priv_obj *vdev_obj; 640 struct tdls_peer *peer; 641 uint16_t curr_tdls_peers; 642 const uint8_t *mac; 643 struct tdls_osif_indication ind; 644 645 if (!req->vdev) { 646 tdls_err("vdev null when add tdls peer"); 647 QDF_ASSERT(0); 648 return QDF_STATUS_E_NULL_VALUE; 649 } 650 651 mac = req->add_peer_req.peer_addr; 652 soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); 653 vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); 654 655 if (!soc_obj || !vdev_obj) { 656 tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); 657 return QDF_STATUS_E_INVAL; 658 } 659 status = tdls_validate_current_mode(soc_obj); 660 if (QDF_IS_STATUS_ERROR(status)) 661 goto addrsp; 662 663 peer = tdls_get_peer(vdev_obj, mac); 664 if (!peer) { 665 tdls_err("peer: " QDF_MAC_ADDR_FMT " not exist. invalid", 666 QDF_MAC_ADDR_REF(mac)); 667 status = QDF_STATUS_E_INVAL; 668 goto addrsp; 669 } 670 671 /* in add station, we accept existing valid sta_id if there is */ 672 if ((peer->link_status > TDLS_LINK_CONNECTING) || 673 (peer->valid_entry)) { 674 tdls_notice("link_status %d add peer ignored", 675 peer->link_status); 676 status = QDF_STATUS_SUCCESS; 677 goto addrsp; 678 } 679 680 /* when others are on-going, we want to change link_status to idle */ 681 if (tdls_is_progress(vdev_obj, mac, true)) { 682 tdls_notice(QDF_MAC_ADDR_FMT " TDLS setuping. Req declined.", 683 QDF_MAC_ADDR_REF(mac)); 684 status = QDF_STATUS_E_PERM; 685 goto setlink; 686 } 687 688 /* first to check if we reached to maximum supported TDLS peer. */ 689 curr_tdls_peers = tdls_get_connected_peer_count(soc_obj); 690 if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { 691 tdls_err(QDF_MAC_ADDR_FMT 692 " Request declined. Current %d, Max allowed %d.", 693 QDF_MAC_ADDR_REF(mac), curr_tdls_peers, 694 soc_obj->max_num_tdls_sta); 695 status = QDF_STATUS_E_PERM; 696 goto setlink; 697 } 698 699 tdls_set_peer_link_status(peer, 700 TDLS_LINK_CONNECTING, TDLS_LINK_SUCCESS); 701 702 status = tdls_pe_add_peer(req); 703 if (QDF_IS_STATUS_ERROR(status)) { 704 tdls_err(QDF_MAC_ADDR_FMT " add peer failed with status %d", 705 QDF_MAC_ADDR_REF(mac), status); 706 goto setlink; 707 } 708 709 return QDF_STATUS_SUCCESS; 710 711 setlink: 712 tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, 713 TDLS_LINK_UNSPECIFIED); 714 addrsp: 715 if (soc_obj->tdls_event_cb) { 716 ind.status = status; 717 ind.vdev = req->vdev; 718 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 719 TDLS_EVENT_ADD_PEER, &ind); 720 } 721 722 return QDF_STATUS_E_PERM; 723 } 724 725 static QDF_STATUS 726 tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, 727 enum wlan_serialization_cb_reason reason) 728 { 729 struct tdls_add_peer_request *req; 730 QDF_STATUS status = QDF_STATUS_SUCCESS; 731 732 if (!cmd || !cmd->umac_cmd) { 733 tdls_err("cmd: %pK, reason: %d", cmd, reason); 734 return QDF_STATUS_E_NULL_VALUE; 735 } 736 737 req = cmd->umac_cmd; 738 739 switch (reason) { 740 case WLAN_SER_CB_ACTIVATE_CMD: 741 /* command moved to active list 742 */ 743 status = tdls_activate_add_peer(req); 744 break; 745 746 case WLAN_SER_CB_CANCEL_CMD: 747 /* command removed from pending list. 748 * notify os interface the status 749 */ 750 status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); 751 break; 752 753 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 754 /* active command time out. */ 755 status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); 756 break; 757 758 case WLAN_SER_CB_RELEASE_MEM_CMD: 759 /* command successfully completed. 760 * release memory & vdev reference count 761 */ 762 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 763 qdf_mem_free(req); 764 break; 765 766 default: 767 /* Do nothing but logging */ 768 QDF_ASSERT(0); 769 status = QDF_STATUS_E_INVAL; 770 break; 771 } 772 773 return status; 774 } 775 776 void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, 777 uint8_t action_code) 778 { 779 if (!tdls_soc) 780 return; 781 782 if (TDLS_TEARDOWN != action_code || 783 !tdls_soc->tdls_nss_switch_in_progress) 784 return; 785 786 if (tdls_soc->tdls_teardown_peers_cnt != 0) 787 tdls_soc->tdls_teardown_peers_cnt--; 788 if (tdls_soc->tdls_teardown_peers_cnt == 0) { 789 if (tdls_soc->tdls_nss_transition_mode == 790 TDLS_NSS_TRANSITION_S_1x1_to_2x2) { 791 /* TDLS NSS switch is fully completed, so 792 * reset the flags. 793 */ 794 tdls_notice("TDLS NSS switch is fully completed"); 795 tdls_soc->tdls_nss_switch_in_progress = false; 796 tdls_soc->tdls_nss_teardown_complete = false; 797 } else { 798 /* TDLS NSS switch is not yet completed, but 799 * tdls teardown is completed for all the 800 * peers. 801 */ 802 tdls_notice("teardown done & NSS switch in progress"); 803 tdls_soc->tdls_nss_teardown_complete = true; 804 } 805 tdls_soc->tdls_nss_transition_mode = 806 TDLS_NSS_TRANSITION_S_UNKNOWN; 807 } 808 809 } 810 811 /** 812 * tdls_set_cap() - set TDLS capability type 813 * @tdls_vdev: tdls vdev object 814 * @mac: peer mac address 815 * @cap: TDLS capability type 816 * 817 * Return: 0 if successful or negative errno otherwise 818 */ 819 int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, 820 enum tdls_peer_capab cap) 821 { 822 struct tdls_peer *curr_peer; 823 824 curr_peer = tdls_get_peer(tdls_vdev, mac); 825 if (!curr_peer) { 826 tdls_err("curr_peer is NULL"); 827 return -EINVAL; 828 } 829 830 curr_peer->tdls_support = cap; 831 return 0; 832 } 833 834 static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, 835 struct tdls_validate_action_req *tdls_validate) 836 { 837 /* supplicant still sends tdls_mgmt(SETUP_REQ) 838 * even after we return error code at 839 * 'add_station()'. Hence we have this check 840 * again in addition to add_station(). Anyway, 841 * there is no harm to double-check. 842 */ 843 if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { 844 tdls_err(QDF_MAC_ADDR_FMT " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", 845 QDF_MAC_ADDR_REF(tdls_validate->peer_mac), 846 tdls_validate->action_code, 847 tdls_soc->connected_peer_count, 848 tdls_soc->max_num_tdls_sta); 849 return -EINVAL; 850 } 851 /* maximum reached. tweak to send 852 * error code to peer and return error 853 * code to supplicant 854 */ 855 tdls_validate->status_code = QDF_STATUS_E_RESOURCES; 856 tdls_err(QDF_MAC_ADDR_FMT " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", 857 QDF_MAC_ADDR_REF(tdls_validate->peer_mac), 858 tdls_validate->action_code, 859 tdls_soc->connected_peer_count, 860 tdls_soc->max_num_tdls_sta); 861 862 return -EPERM; 863 } 864 865 int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) 866 { 867 struct tdls_vdev_priv_obj *tdls_vdev; 868 struct tdls_soc_priv_obj *tdls_soc; 869 struct tdls_peer *curr_peer; 870 struct tdls_peer *temp_peer; 871 QDF_STATUS status; 872 uint8_t vdev_id; 873 874 struct wlan_objmgr_vdev *vdev = tdls_mgmt_req->vdev; 875 struct tdls_validate_action_req *tdls_validate = 876 &tdls_mgmt_req->chk_frame; 877 878 if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, 879 &tdls_vdev, 880 &tdls_soc)) 881 return -ENOTSUPP; 882 883 /* 884 * STA or P2P client should be connected and authenticated before 885 * sending any TDLS frames 886 */ 887 if ((wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) || 888 !tdls_is_vdev_authenticated(vdev)) { 889 tdls_err("STA is not connected or not authenticated."); 890 return -EAGAIN; 891 } 892 893 /* other than teardown frame, mgmt frames are not sent if disabled */ 894 if (TDLS_TEARDOWN != tdls_validate->action_code) { 895 if (!tdls_check_is_tdls_allowed(vdev)) { 896 tdls_err("TDLS not allowed, reject MGMT, action = %d", 897 tdls_validate->action_code); 898 return -EPERM; 899 } 900 /* if tdls_mode is disabled, then decline the peer's request */ 901 if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || 902 TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { 903 tdls_notice(QDF_MAC_ADDR_FMT 904 " TDLS mode is disabled. action %d declined.", 905 QDF_MAC_ADDR_REF(tdls_validate->peer_mac), 906 tdls_validate->action_code); 907 return -ENOTSUPP; 908 } 909 if (tdls_soc->tdls_nss_switch_in_progress) { 910 tdls_err("nss switch in progress, action %d declined " 911 QDF_MAC_ADDR_FMT, 912 tdls_validate->action_code, 913 QDF_MAC_ADDR_REF(tdls_validate->peer_mac)); 914 return -EAGAIN; 915 } 916 } 917 /* 918 * In case another tdls request comes while tdls setup is already 919 * ongoing with one peer. Reject only when status code is 0. If status 920 * code is non-zero, it means supplicant already rejected it and 921 * the same should be notified to peer. 922 */ 923 if (TDLS_IS_SETUP_ACTION(tdls_validate->action_code)) { 924 if (tdls_is_progress(tdls_vdev, tdls_validate->peer_mac, 925 true) && 926 tdls_validate->status_code == 0) { 927 tdls_err("setup is ongoing. action %d declined for " 928 QDF_MAC_ADDR_FMT, 929 tdls_validate->action_code, 930 QDF_MAC_ADDR_REF(tdls_validate->peer_mac)); 931 return -EPERM; 932 } 933 } 934 935 /* call hdd_wmm_is_acm_allowed() */ 936 vdev_id = wlan_vdev_get_id(vdev); 937 if (!tdls_soc->tdls_wmm_cb(vdev_id)) { 938 tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d", 939 tdls_validate->action_code); 940 tdls_mgmt_req->use_default_ac = false; 941 } else { 942 tdls_mgmt_req->use_default_ac = true; 943 } 944 945 if (TDLS_SETUP_REQUEST == tdls_validate->action_code || 946 TDLS_SETUP_RESPONSE == tdls_validate->action_code) { 947 if (tdls_soc->max_num_tdls_sta <= 948 tdls_soc->connected_peer_count) { 949 status = tdls_validate_setup_frames(tdls_soc, 950 tdls_validate); 951 if (QDF_STATUS_SUCCESS != status) 952 return status; 953 /* fall through to send setup resp 954 * with failure status code 955 */ 956 } else { 957 curr_peer = 958 tdls_find_peer(tdls_vdev, 959 tdls_validate->peer_mac); 960 if (curr_peer) { 961 if (TDLS_IS_LINK_CONNECTED(curr_peer)) { 962 tdls_err(QDF_MAC_ADDR_FMT " already connected action %d declined.", 963 QDF_MAC_ADDR_REF( 964 tdls_validate->peer_mac), 965 tdls_validate->action_code); 966 967 return -EPERM; 968 } 969 } 970 } 971 } 972 973 tdls_debug("tdls_mgmt " QDF_MAC_ADDR_FMT " action %d, dialog_token %d status %d, len = %zu", 974 QDF_MAC_ADDR_REF(tdls_validate->peer_mac), 975 tdls_validate->action_code, tdls_validate->dialog_token, 976 tdls_validate->status_code, tdls_validate->len); 977 978 /*Except teardown responder will not be used so just make 0 */ 979 tdls_validate->responder = 0; 980 if (TDLS_TEARDOWN == tdls_validate->action_code) { 981 temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); 982 if (!temp_peer) { 983 tdls_err(QDF_MAC_ADDR_FMT " peer doesn't exist", 984 QDF_MAC_ADDR_REF( 985 tdls_validate->peer_mac)); 986 return -EPERM; 987 } 988 989 if (TDLS_IS_LINK_CONNECTED(temp_peer)) 990 tdls_validate->responder = temp_peer->is_responder; 991 else { 992 tdls_err(QDF_MAC_ADDR_FMT " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", 993 QDF_MAC_ADDR_REF(tdls_validate->peer_mac), 994 temp_peer->link_status, 995 tdls_validate->dialog_token, 996 tdls_validate->status_code, 997 tdls_validate->len); 998 return -EPERM; 999 } 1000 } 1001 1002 /* For explicit trigger of DIS_REQ come out of BMPS for 1003 * successfully receiving DIS_RSP from peer. 1004 */ 1005 if ((TDLS_SETUP_RESPONSE == tdls_validate->action_code) || 1006 (TDLS_SETUP_CONFIRM == tdls_validate->action_code) || 1007 (TDLS_DISCOVERY_RESPONSE == tdls_validate->action_code) || 1008 (TDLS_DISCOVERY_REQUEST == tdls_validate->action_code)) { 1009 /* Fw will take care if PS offload is enabled. */ 1010 if (TDLS_DISCOVERY_REQUEST != tdls_validate->action_code) 1011 tdls_set_cap(tdls_vdev, tdls_validate->peer_mac, 1012 TDLS_CAP_SUPPORTED); 1013 } 1014 return 0; 1015 } 1016 1017 QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) 1018 { 1019 struct wlan_serialization_command cmd = {0,}; 1020 enum wlan_serialization_status ser_cmd_status; 1021 struct wlan_objmgr_vdev *vdev; 1022 QDF_STATUS status = QDF_STATUS_E_INVAL; 1023 struct wlan_objmgr_psoc *psoc; 1024 1025 if (!req || !req->vdev) { 1026 tdls_err("req: %pK", req); 1027 goto free_req; 1028 } 1029 vdev = req->vdev; 1030 if (!tdls_check_is_tdls_allowed(vdev)) { 1031 tdls_err("TDLS not allowed, reject add station for vdev: %d", 1032 wlan_vdev_get_id(vdev)); 1033 goto error; 1034 } 1035 1036 psoc = wlan_vdev_get_psoc(vdev); 1037 if (!psoc) { 1038 tdls_err("can't get psoc"); 1039 goto error; 1040 } 1041 1042 status = QDF_STATUS_SUCCESS; 1043 1044 cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; 1045 cmd.cmd_id = 0; 1046 cmd.cmd_cb = tdls_add_peer_serialize_callback; 1047 cmd.umac_cmd = req; 1048 cmd.source = WLAN_UMAC_COMP_TDLS; 1049 cmd.is_high_priority = false; 1050 cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; 1051 cmd.vdev = vdev; 1052 cmd.is_blocking = true; 1053 1054 ser_cmd_status = wlan_serialization_request(&cmd); 1055 tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, 1056 ser_cmd_status); 1057 1058 switch (ser_cmd_status) { 1059 case WLAN_SER_CMD_PENDING: 1060 /* command moved to pending list. Do nothing */ 1061 break; 1062 case WLAN_SER_CMD_ACTIVE: 1063 /* command moved to active list. Do nothing */ 1064 break; 1065 default: 1066 goto error; 1067 } 1068 1069 return status; 1070 error: 1071 /* notify os interface about internal error*/ 1072 status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); 1073 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 1074 free_req: 1075 qdf_mem_free(req); 1076 return status; 1077 } 1078 1079 static QDF_STATUS 1080 tdls_activate_update_peer(struct tdls_update_peer_request *req) 1081 { 1082 QDF_STATUS status; 1083 struct tdls_soc_priv_obj *soc_obj; 1084 struct tdls_vdev_priv_obj *vdev_obj; 1085 struct wlan_objmgr_vdev *vdev; 1086 struct tdls_peer *curr_peer; 1087 uint16_t curr_tdls_peers; 1088 const uint8_t *mac; 1089 struct tdls_update_peer_params *update_peer; 1090 struct tdls_osif_indication ind; 1091 1092 if (!req->vdev) { 1093 tdls_err("vdev object NULL when add TDLS peer"); 1094 QDF_ASSERT(0); 1095 return QDF_STATUS_E_NULL_VALUE; 1096 } 1097 1098 mac = req->update_peer_req.peer_addr; 1099 vdev = req->vdev; 1100 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 1101 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1102 if (!soc_obj || !vdev_obj) { 1103 tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); 1104 return QDF_STATUS_E_INVAL; 1105 } 1106 1107 status = tdls_validate_current_mode(soc_obj); 1108 if (QDF_IS_STATUS_ERROR(status)) 1109 goto updatersp; 1110 1111 curr_peer = tdls_find_peer(vdev_obj, mac); 1112 if (!curr_peer) { 1113 tdls_err(QDF_MAC_ADDR_FMT " not exist. return invalid", 1114 QDF_MAC_ADDR_REF(mac)); 1115 status = QDF_STATUS_E_INVAL; 1116 goto updatersp; 1117 } 1118 1119 /* in change station, we accept only when sta_id is valid */ 1120 if (curr_peer->link_status == TDLS_LINK_TEARING || 1121 !curr_peer->valid_entry) { 1122 tdls_err(QDF_MAC_ADDR_FMT " link %d. update peer rejected", 1123 QDF_MAC_ADDR_REF(mac), curr_peer->link_status); 1124 status = QDF_STATUS_E_PERM; 1125 goto updatersp; 1126 } 1127 1128 if (curr_peer->link_status == TDLS_LINK_CONNECTED && 1129 curr_peer->valid_entry) { 1130 tdls_err(QDF_MAC_ADDR_FMT " link %d. update peer is igonored as tdls state is already connected ", 1131 QDF_MAC_ADDR_REF(mac), curr_peer->link_status); 1132 status = QDF_STATUS_SUCCESS; 1133 goto updatersp; 1134 } 1135 1136 /* when others are on-going, we want to change link_status to idle */ 1137 if (tdls_is_progress(vdev_obj, mac, true)) { 1138 tdls_notice(QDF_MAC_ADDR_FMT " TDLS setuping. Req declined.", 1139 QDF_MAC_ADDR_REF(mac)); 1140 status = QDF_STATUS_E_PERM; 1141 goto setlink; 1142 } 1143 1144 curr_tdls_peers = tdls_get_connected_peer_count(soc_obj); 1145 if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { 1146 tdls_err(QDF_MAC_ADDR_FMT 1147 " Request declined. Current: %d, Max allowed: %d.", 1148 QDF_MAC_ADDR_REF(mac), curr_tdls_peers, 1149 soc_obj->max_num_tdls_sta); 1150 status = QDF_STATUS_E_PERM; 1151 goto setlink; 1152 } 1153 update_peer = &req->update_peer_req; 1154 1155 if (update_peer->htcap_present) 1156 curr_peer->spatial_streams = update_peer->ht_cap.mcsset[1]; 1157 1158 tdls_set_peer_caps(vdev_obj, mac, &req->update_peer_req); 1159 status = tdls_pe_update_peer(req); 1160 if (QDF_IS_STATUS_ERROR(status)) { 1161 tdls_err(QDF_MAC_ADDR_FMT " update peer failed with status %d", 1162 QDF_MAC_ADDR_REF(mac), status); 1163 goto setlink; 1164 } 1165 1166 return QDF_STATUS_SUCCESS; 1167 1168 setlink: 1169 tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, 1170 TDLS_LINK_UNSPECIFIED); 1171 updatersp: 1172 if (soc_obj->tdls_event_cb) { 1173 ind.status = status; 1174 ind.vdev = vdev; 1175 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 1176 TDLS_EVENT_ADD_PEER, &ind); 1177 } 1178 1179 return QDF_STATUS_E_PERM; 1180 } 1181 1182 static QDF_STATUS 1183 tdls_update_peer_serialize_callback(struct wlan_serialization_command *cmd, 1184 enum wlan_serialization_cb_reason reason) 1185 { 1186 struct tdls_update_peer_request *req; 1187 QDF_STATUS status = QDF_STATUS_SUCCESS; 1188 1189 if (!cmd || !cmd->umac_cmd) { 1190 tdls_err("cmd: %pK, reason: %d", cmd, reason); 1191 return QDF_STATUS_E_NULL_VALUE; 1192 } 1193 1194 req = cmd->umac_cmd; 1195 1196 switch (reason) { 1197 case WLAN_SER_CB_ACTIVATE_CMD: 1198 /* command moved to active list 1199 */ 1200 status = tdls_activate_update_peer(req); 1201 break; 1202 1203 case WLAN_SER_CB_CANCEL_CMD: 1204 /* command removed from pending list. 1205 * notify os interface the status 1206 */ 1207 status = tdls_internal_update_peer_rsp(req, 1208 QDF_STATUS_E_FAILURE); 1209 break; 1210 1211 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 1212 /* active command time out. */ 1213 status = tdls_internal_update_peer_rsp(req, 1214 QDF_STATUS_E_FAILURE); 1215 break; 1216 1217 case WLAN_SER_CB_RELEASE_MEM_CMD: 1218 /* command successfully completed. 1219 * release memory & release reference count 1220 */ 1221 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 1222 qdf_mem_free(req); 1223 break; 1224 1225 default: 1226 /* Do nothing but logging */ 1227 QDF_ASSERT(0); 1228 status = QDF_STATUS_E_INVAL; 1229 break; 1230 } 1231 1232 return status; 1233 } 1234 1235 QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) 1236 { 1237 struct wlan_serialization_command cmd = {0,}; 1238 enum wlan_serialization_status ser_cmd_status; 1239 struct wlan_objmgr_vdev *vdev; 1240 QDF_STATUS status = QDF_STATUS_SUCCESS; 1241 1242 if (!req || !req->vdev) { 1243 tdls_err("req: %pK", req); 1244 status = QDF_STATUS_E_FAILURE; 1245 goto free_req; 1246 } 1247 1248 vdev = req->vdev; 1249 cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; 1250 cmd.cmd_id = 0; 1251 cmd.cmd_cb = tdls_update_peer_serialize_callback; 1252 cmd.umac_cmd = req; 1253 cmd.source = WLAN_UMAC_COMP_TDLS; 1254 cmd.is_high_priority = false; 1255 cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; 1256 cmd.vdev = req->vdev; 1257 cmd.is_blocking = true; 1258 1259 ser_cmd_status = wlan_serialization_request(&cmd); 1260 tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, 1261 ser_cmd_status); 1262 1263 switch (ser_cmd_status) { 1264 case WLAN_SER_CMD_PENDING: 1265 /* command moved to pending list. Do nothing */ 1266 break; 1267 case WLAN_SER_CMD_ACTIVE: 1268 /* command moved to active list. Do nothing */ 1269 break; 1270 default: 1271 goto error; 1272 } 1273 1274 return status; 1275 error: 1276 /* notify os interface about internal error*/ 1277 status = tdls_internal_update_peer_rsp(req, QDF_STATUS_E_FAILURE); 1278 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 1279 free_req: 1280 qdf_mem_free(req); 1281 return status; 1282 } 1283 1284 static QDF_STATUS tdls_activate_del_peer(struct tdls_oper_request *req) 1285 { 1286 struct tdls_del_peer_request request = {0,}; 1287 1288 request.vdev = req->vdev; 1289 request.del_peer_req.peer_addr = req->peer_addr; 1290 1291 return tdls_pe_del_peer(&request); 1292 } 1293 1294 static QDF_STATUS 1295 tdls_del_peer_serialize_callback(struct wlan_serialization_command *cmd, 1296 enum wlan_serialization_cb_reason reason) 1297 { 1298 struct tdls_oper_request *req; 1299 QDF_STATUS status = QDF_STATUS_SUCCESS; 1300 1301 if (!cmd || !cmd->umac_cmd) { 1302 tdls_err("cmd: %pK, reason: %d", cmd, reason); 1303 return QDF_STATUS_E_NULL_VALUE; 1304 } 1305 1306 req = cmd->umac_cmd; 1307 1308 switch (reason) { 1309 case WLAN_SER_CB_ACTIVATE_CMD: 1310 /* command moved to active list 1311 */ 1312 status = tdls_activate_del_peer(req); 1313 break; 1314 1315 case WLAN_SER_CB_CANCEL_CMD: 1316 /* command removed from pending list. 1317 * notify os interface the status 1318 */ 1319 status = tdls_internal_del_peer_rsp(req); 1320 break; 1321 1322 case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: 1323 /* active command time out. */ 1324 status = tdls_internal_del_peer_rsp(req); 1325 break; 1326 1327 case WLAN_SER_CB_RELEASE_MEM_CMD: 1328 /* command successfully completed. 1329 * release memory & vdev reference count 1330 */ 1331 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 1332 qdf_mem_free(req); 1333 break; 1334 1335 default: 1336 /* Do nothing but logging */ 1337 QDF_ASSERT(0); 1338 status = QDF_STATUS_E_INVAL; 1339 break; 1340 } 1341 1342 return status; 1343 } 1344 1345 QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) 1346 { 1347 struct wlan_serialization_command cmd = {0,}; 1348 enum wlan_serialization_status ser_cmd_status; 1349 struct wlan_objmgr_vdev *vdev; 1350 struct tdls_vdev_priv_obj *vdev_obj; 1351 struct tdls_soc_priv_obj *soc_obj; 1352 uint8_t *mac; 1353 struct tdls_peer *peer; 1354 QDF_STATUS status = QDF_STATUS_SUCCESS; 1355 1356 if (!req || !req->vdev) { 1357 tdls_err("req: %pK", req); 1358 status = QDF_STATUS_E_INVAL; 1359 goto free_req; 1360 } 1361 1362 vdev = req->vdev; 1363 1364 /* vdev reference cnt is acquired in ucfg_tdls_oper */ 1365 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1366 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 1367 1368 if (!vdev_obj || !soc_obj) { 1369 tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); 1370 status = QDF_STATUS_E_NULL_VALUE; 1371 goto error; 1372 } 1373 1374 mac = req->peer_addr; 1375 peer = tdls_find_peer(vdev_obj, mac); 1376 if (!peer) { 1377 tdls_err(QDF_MAC_ADDR_FMT 1378 " not found, ignore NL80211_TDLS_ENABLE_LINK", 1379 QDF_MAC_ADDR_REF(mac)); 1380 status = QDF_STATUS_E_INVAL; 1381 goto error; 1382 } 1383 1384 if (!peer->valid_entry) { 1385 tdls_err("invalid peer:" QDF_MAC_ADDR_FMT " link state %d", 1386 QDF_MAC_ADDR_REF(mac), peer->link_status); 1387 status = QDF_STATUS_E_INVAL; 1388 goto error; 1389 } 1390 1391 if (soc_obj->tdls_dp_vdev_update) 1392 soc_obj->tdls_dp_vdev_update(&soc_obj->soc, 1393 wlan_vdev_get_id(vdev), 1394 soc_obj->tdls_update_dp_vdev_flags, 1395 false); 1396 1397 cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; 1398 cmd.cmd_id = 0; 1399 cmd.cmd_cb = tdls_del_peer_serialize_callback; 1400 cmd.umac_cmd = req; 1401 cmd.source = WLAN_UMAC_COMP_TDLS; 1402 cmd.is_high_priority = false; 1403 cmd.cmd_timeout_duration = TDLS_DELETE_PEER_CMD_TIMEOUT; 1404 cmd.vdev = vdev; 1405 cmd.is_blocking = true; 1406 1407 ser_cmd_status = wlan_serialization_request(&cmd); 1408 tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, 1409 ser_cmd_status); 1410 1411 switch (ser_cmd_status) { 1412 case WLAN_SER_CMD_PENDING: 1413 /* command moved to pending list. Do nothing */ 1414 break; 1415 case WLAN_SER_CMD_ACTIVE: 1416 /* command moved to active list. Do nothing */ 1417 break; 1418 default: 1419 goto error; 1420 } 1421 1422 return status; 1423 error: 1424 /* notify os interface about internal error*/ 1425 status = tdls_internal_del_peer_rsp(req); 1426 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 1427 free_req: 1428 qdf_mem_free(req); 1429 return status; 1430 } 1431 1432 /** 1433 * tdls_update_peer_rsp() - handle response for update TDLS peer 1434 * @rsp: TDLS add peer response 1435 * 1436 * Return: QDF_STATUS_SUCCESS for success; other values if failed 1437 */ 1438 static QDF_STATUS tdls_update_peer_rsp(struct tdls_add_sta_rsp *rsp) 1439 { 1440 struct wlan_objmgr_vdev *vdev; 1441 struct wlan_objmgr_psoc *psoc; 1442 struct tdls_soc_priv_obj *soc_obj; 1443 QDF_STATUS status = QDF_STATUS_SUCCESS; 1444 struct tdls_osif_indication ind; 1445 1446 psoc = rsp->psoc; 1447 if (!psoc) { 1448 tdls_err("psoc is NULL"); 1449 QDF_ASSERT(0); 1450 return QDF_STATUS_E_FAILURE; 1451 } 1452 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, 1453 WLAN_TDLS_SB_ID); 1454 if (!vdev) { 1455 tdls_err("invalid vdev: %d", rsp->session_id); 1456 status = QDF_STATUS_E_INVAL; 1457 goto error; 1458 } 1459 1460 tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); 1461 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1462 error: 1463 soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); 1464 if (soc_obj && soc_obj->tdls_event_cb) { 1465 ind.status = rsp->status_code; 1466 ind.vdev = vdev; 1467 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 1468 TDLS_EVENT_ADD_PEER, &ind); 1469 } 1470 qdf_mem_free(rsp); 1471 1472 return status; 1473 } 1474 1475 /** 1476 * tdls_process_send_mgmt_rsp() - handle response for send mgmt 1477 * @rsp: TDLS send mgmt response 1478 * 1479 * Return: QDF_STATUS_SUCCESS for success; other values if failed 1480 */ 1481 QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) 1482 { 1483 struct wlan_objmgr_vdev *vdev; 1484 struct wlan_objmgr_psoc *psoc; 1485 struct tdls_vdev_priv_obj *tdls_vdev; 1486 struct tdls_soc_priv_obj *tdls_soc = NULL; 1487 QDF_STATUS status = QDF_STATUS_SUCCESS; 1488 struct tdls_osif_indication ind; 1489 1490 psoc = rsp->psoc; 1491 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->vdev_id, 1492 WLAN_TDLS_SB_ID); 1493 if (!vdev) { 1494 tdls_err("invalid vdev"); 1495 status = QDF_STATUS_E_INVAL; 1496 qdf_mem_free(rsp); 1497 return status; 1498 } 1499 tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); 1500 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1501 if (!tdls_soc || !tdls_vdev) { 1502 tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); 1503 status = QDF_STATUS_E_FAILURE; 1504 } 1505 1506 tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_SEND_MGMT); 1507 1508 if (legacy_result_success == rsp->status_code) 1509 goto free_rsp; 1510 tdls_err("send mgmt failed. status code(=%d)", rsp->status_code); 1511 status = QDF_STATUS_E_FAILURE; 1512 1513 if (tdls_soc && tdls_soc->tdls_event_cb) { 1514 ind.vdev = vdev; 1515 ind.status = status; 1516 tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, 1517 TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); 1518 } 1519 1520 free_rsp: 1521 qdf_mem_free(rsp); 1522 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1523 return status; 1524 } 1525 1526 /** 1527 * tdls_send_mgmt_tx_completion() - process tx completion 1528 * @tx_complete: TDLS mgmt completion info 1529 * 1530 * Return: QDF_STATUS_SUCCESS for success; other values if failed 1531 */ 1532 QDF_STATUS tdls_send_mgmt_tx_completion( 1533 struct tdls_mgmt_tx_completion_ind *tx_complete) 1534 { 1535 struct wlan_objmgr_vdev *vdev; 1536 struct wlan_objmgr_psoc *psoc; 1537 struct tdls_vdev_priv_obj *tdls_vdev; 1538 struct tdls_soc_priv_obj *tdls_soc = NULL; 1539 QDF_STATUS status = QDF_STATUS_SUCCESS; 1540 struct tdls_osif_indication ind; 1541 1542 psoc = tx_complete->psoc; 1543 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 1544 tx_complete->vdev_id, 1545 WLAN_TDLS_SB_ID); 1546 1547 if (!vdev) { 1548 tdls_err("invalid vdev"); 1549 status = QDF_STATUS_E_INVAL; 1550 goto free_tx_complete; 1551 } 1552 1553 tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); 1554 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1555 1556 if (!tdls_soc || !tdls_vdev) { 1557 tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); 1558 status = QDF_STATUS_E_FAILURE; 1559 } 1560 1561 if (tdls_soc && tdls_soc->tdls_event_cb) { 1562 ind.vdev = vdev; 1563 ind.status = tx_complete->tx_complete_status; 1564 tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, 1565 TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); 1566 } 1567 1568 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1569 free_tx_complete: 1570 qdf_mem_free(tx_complete); 1571 return status; 1572 } 1573 1574 /** 1575 * tdls_add_peer_rsp() - handle response for add TDLS peer 1576 * @rsp: TDLS add peer response 1577 * 1578 * Return: QDF_STATUS_SUCCESS for success; other values if failed 1579 */ 1580 static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) 1581 { 1582 uint8_t sta_idx; 1583 struct wlan_objmgr_vdev *vdev; 1584 struct wlan_objmgr_psoc *psoc; 1585 struct tdls_vdev_priv_obj *vdev_obj; 1586 struct tdls_soc_priv_obj *soc_obj = NULL; 1587 struct tdls_conn_info *conn_rec; 1588 QDF_STATUS status = QDF_STATUS_SUCCESS; 1589 struct tdls_osif_indication ind; 1590 1591 psoc = rsp->psoc; 1592 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, 1593 WLAN_TDLS_SB_ID); 1594 if (!vdev) { 1595 tdls_err("invalid vdev: %d", rsp->session_id); 1596 status = QDF_STATUS_E_INVAL; 1597 goto error; 1598 } 1599 soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); 1600 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1601 if (!soc_obj || !vdev_obj) { 1602 tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); 1603 status = QDF_STATUS_E_FAILURE; 1604 goto cmddone; 1605 } 1606 if (rsp->status_code) { 1607 tdls_err("add sta failed. status code(=%d)", rsp->status_code); 1608 status = QDF_STATUS_E_FAILURE; 1609 } else { 1610 conn_rec = soc_obj->tdls_conn_info; 1611 for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; 1612 sta_idx++) { 1613 if (!conn_rec[sta_idx].valid_entry) { 1614 conn_rec[sta_idx].session_id = rsp->session_id; 1615 conn_rec[sta_idx].valid_entry = true; 1616 conn_rec[sta_idx].index = sta_idx; 1617 qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, 1618 &rsp->peermac); 1619 tdls_debug("TDLS: Add sta mac at idx %d" 1620 QDF_MAC_ADDR_FMT, sta_idx, 1621 QDF_MAC_ADDR_REF 1622 (rsp->peermac.bytes)); 1623 break; 1624 } 1625 } 1626 1627 if (sta_idx < soc_obj->max_num_tdls_sta) { 1628 status = tdls_set_valid(vdev_obj, rsp->peermac.bytes); 1629 if (QDF_IS_STATUS_ERROR(status)) { 1630 tdls_err("set staid failed"); 1631 status = QDF_STATUS_E_FAILURE; 1632 } 1633 } else { 1634 status = QDF_STATUS_E_FAILURE; 1635 } 1636 } 1637 1638 cmddone: 1639 tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); 1640 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1641 error: 1642 if (soc_obj && soc_obj->tdls_event_cb) { 1643 ind.vdev = vdev; 1644 ind.status = rsp->status_code; 1645 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 1646 TDLS_EVENT_ADD_PEER, &ind); 1647 } 1648 qdf_mem_free(rsp); 1649 1650 return status; 1651 } 1652 1653 QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp) 1654 { 1655 tdls_debug("peer oper %d", rsp->tdls_oper); 1656 1657 if (rsp->tdls_oper == TDLS_OPER_ADD) 1658 return tdls_add_peer_rsp(rsp); 1659 else if (rsp->tdls_oper == TDLS_OPER_UPDATE) 1660 return tdls_update_peer_rsp(rsp); 1661 1662 return QDF_STATUS_E_INVAL; 1663 } 1664 1665 static void tdls_process_unforce_link_mode(struct wlan_objmgr_vdev *vdev) 1666 { 1667 struct tdls_vdev_priv_obj *tdls_vdev; 1668 struct tdls_peer *peer; 1669 qdf_list_t *head; 1670 qdf_list_node_t *p_node; 1671 QDF_STATUS status; 1672 bool unforce = true; 1673 int i; 1674 1675 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); 1676 if (!tdls_vdev) 1677 return; 1678 1679 for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { 1680 head = &tdls_vdev->peer_list[i]; 1681 status = qdf_list_peek_front(head, &p_node); 1682 while (QDF_IS_STATUS_SUCCESS(status)) { 1683 peer = qdf_container_of(p_node, struct tdls_peer, node); 1684 1685 tdls_debug("Peer: " QDF_MAC_ADDR_FMT "link status %d, vdev id %d", 1686 QDF_MAC_ADDR_REF(peer->peer_mac.bytes), 1687 peer->link_status, wlan_vdev_get_id(vdev)); 1688 1689 if (peer->link_status == TDLS_LINK_CONNECTED || 1690 peer->link_status == TDLS_LINK_CONNECTING) { 1691 unforce = false; 1692 goto unforce_exit; 1693 } 1694 1695 status = qdf_list_peek_next(head, p_node, &p_node); 1696 } 1697 } 1698 1699 unforce_exit: 1700 if (unforce) { 1701 tdls_debug("try to set vdev %d to unforce", 1702 wlan_vdev_get_id(vdev)); 1703 tdls_set_link_unforce(vdev); 1704 } 1705 } 1706 1707 QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) 1708 { 1709 uint8_t sta_idx, id; 1710 QDF_STATUS status = QDF_STATUS_E_FAILURE; 1711 struct wlan_objmgr_vdev *vdev; 1712 struct wlan_objmgr_psoc *psoc; 1713 struct tdls_vdev_priv_obj *vdev_obj; 1714 struct tdls_soc_priv_obj *soc_obj = NULL; 1715 struct tdls_conn_info *conn_rec; 1716 struct tdls_peer *curr_peer = NULL; 1717 const uint8_t *macaddr; 1718 struct tdls_osif_indication ind; 1719 1720 tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDR_FMT, 1721 rsp->session_id, QDF_MAC_ADDR_REF(rsp->peermac.bytes)); 1722 psoc = rsp->psoc; 1723 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, 1724 WLAN_TDLS_SB_ID); 1725 if (!vdev) { 1726 tdls_err("invalid vdev: %d", rsp->session_id); 1727 status = QDF_STATUS_E_INVAL; 1728 goto error; 1729 } 1730 soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); 1731 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1732 if (!soc_obj || !vdev_obj) { 1733 tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); 1734 status = QDF_STATUS_E_FAILURE; 1735 goto cmddone; 1736 } 1737 1738 conn_rec = soc_obj->tdls_conn_info; 1739 for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { 1740 if (conn_rec[sta_idx].session_id != rsp->session_id || 1741 qdf_mem_cmp(conn_rec[sta_idx].peer_mac.bytes, 1742 rsp->peermac.bytes, QDF_MAC_ADDR_SIZE)) 1743 continue; 1744 1745 macaddr = rsp->peermac.bytes; 1746 tdls_debug("TDLS: del STA with sta_idx %d", sta_idx); 1747 curr_peer = tdls_find_peer(vdev_obj, macaddr); 1748 if (curr_peer) { 1749 tdls_debug(QDF_MAC_ADDR_FMT " status is %d", 1750 QDF_MAC_ADDR_REF(macaddr), 1751 curr_peer->link_status); 1752 1753 id = wlan_vdev_get_id(vdev); 1754 1755 if (TDLS_IS_LINK_CONNECTED(curr_peer)) 1756 tdls_decrement_peer_count(vdev, soc_obj); 1757 } 1758 tdls_reset_peer(vdev_obj, macaddr); 1759 conn_rec[sta_idx].valid_entry = false; 1760 conn_rec[sta_idx].session_id = 0xff; 1761 conn_rec[sta_idx].index = INVALID_TDLS_PEER_INDEX; 1762 qdf_mem_zero(&conn_rec[sta_idx].peer_mac, 1763 QDF_MAC_ADDR_SIZE); 1764 1765 status = QDF_STATUS_SUCCESS; 1766 break; 1767 } 1768 macaddr = rsp->peermac.bytes; 1769 if (!curr_peer) { 1770 curr_peer = tdls_find_peer(vdev_obj, macaddr); 1771 1772 if (curr_peer) 1773 tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, 1774 (curr_peer->link_status == 1775 TDLS_LINK_TEARING) ? 1776 TDLS_LINK_UNSPECIFIED : 1777 TDLS_LINK_DROPPED_BY_REMOTE); 1778 } 1779 1780 tdls_process_unforce_link_mode(vdev); 1781 1782 cmddone: 1783 tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_DEL_PEER); 1784 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); 1785 error: 1786 1787 if (soc_obj && soc_obj->tdls_event_cb) { 1788 ind.vdev = vdev; 1789 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 1790 TDLS_EVENT_DEL_PEER, &ind); 1791 } 1792 qdf_mem_free(rsp); 1793 1794 return status; 1795 } 1796 1797 static QDF_STATUS 1798 tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, 1799 struct tdls_peer_update_state *peer_state) 1800 { 1801 struct scheduler_msg msg = {0,}; 1802 QDF_STATUS status; 1803 1804 tdls_debug("update TDLS peer " QDF_MAC_ADDR_FMT " vdev %d, state %d", 1805 QDF_MAC_ADDR_REF(peer_state->peer_macaddr), 1806 peer_state->vdev_id, peer_state->peer_state); 1807 msg.type = soc_obj->tdls_update_peer_state; 1808 msg.reserved = 0; 1809 msg.bodyptr = peer_state; 1810 1811 status = scheduler_post_message(QDF_MODULE_ID_TDLS, 1812 QDF_MODULE_ID_WMA, 1813 QDF_MODULE_ID_WMA, &msg); 1814 if (QDF_IS_STATUS_ERROR(status)) { 1815 tdls_err("scheduler_post_msg failed"); 1816 status = QDF_STATUS_E_FAILURE; 1817 } 1818 1819 return status; 1820 } 1821 1822 QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) 1823 { 1824 struct tdls_peer *peer; 1825 struct tdls_vdev_priv_obj *vdev_obj; 1826 struct tdls_soc_priv_obj *soc_obj; 1827 struct wlan_objmgr_vdev *vdev; 1828 uint8_t *mac; 1829 struct tdls_peer_update_state *peer_update_param; 1830 QDF_STATUS status; 1831 uint32_t feature; 1832 uint8_t id; 1833 1834 vdev = req->vdev; 1835 if (!vdev) { 1836 tdls_err("NULL vdev object"); 1837 qdf_mem_free(req); 1838 return QDF_STATUS_E_NULL_VALUE; 1839 } 1840 1841 /* vdev reference cnt is acquired in ucfg_tdls_oper */ 1842 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1843 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 1844 1845 if (!vdev_obj || !soc_obj) { 1846 tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); 1847 status = QDF_STATUS_E_NULL_VALUE; 1848 goto error; 1849 } 1850 1851 mac = req->peer_addr; 1852 peer = tdls_find_peer(vdev_obj, mac); 1853 if (!peer) { 1854 tdls_err(QDF_MAC_ADDR_FMT 1855 " not found, ignore NL80211_TDLS_ENABLE_LINK", 1856 QDF_MAC_ADDR_REF(mac)); 1857 status = QDF_STATUS_E_INVAL; 1858 goto error; 1859 } 1860 1861 tdls_debug("enable link for peer " QDF_MAC_ADDR_FMT " link state %d", 1862 QDF_MAC_ADDR_REF(mac), peer->link_status); 1863 if (!peer->valid_entry) { 1864 tdls_err("invalid entry " QDF_MAC_ADDR_FMT, 1865 QDF_MAC_ADDR_REF(mac)); 1866 status = QDF_STATUS_E_INVAL; 1867 goto error; 1868 } 1869 1870 /* 1871 * Offchannel is allowed only when TDLS is connected with one peer. 1872 * If more than one peer is connected then Disable Offchannel by sending 1873 * WMI_TDLS_SET_OFFCHAN_MODE_CMDID with DISABLE_CHANSWITCH. 1874 * So, basically when the 2nd peer enable_link is there, offchannel 1875 * should be disabled and will remain disabled for all subsequent 1876 * TDLS peer connection. 1877 * Offchannel will be re-enabled when connected peer count again 1878 * becomes 1. 1879 */ 1880 if (soc_obj->connected_peer_count == 1) 1881 tdls_set_tdls_offchannelmode(vdev, DISABLE_CHANSWITCH); 1882 1883 peer->tdls_support = TDLS_CAP_SUPPORTED; 1884 if (TDLS_LINK_CONNECTED != peer->link_status) 1885 tdls_set_peer_link_status(peer, TDLS_LINK_CONNECTED, 1886 TDLS_LINK_SUCCESS); 1887 1888 id = wlan_vdev_get_id(vdev); 1889 status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, 1890 id, mac, peer->qos); 1891 if (QDF_IS_STATUS_ERROR(status)) { 1892 tdls_err("TDLS register peer fail, status %d", status); 1893 goto error; 1894 } 1895 1896 peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); 1897 if (!peer_update_param) { 1898 status = QDF_STATUS_E_NOMEM; 1899 goto error; 1900 } 1901 1902 tdls_extract_peer_state_param(peer_update_param, peer); 1903 1904 status = tdls_wma_update_peer_state(soc_obj, peer_update_param); 1905 if (QDF_IS_STATUS_ERROR(status)) { 1906 qdf_mem_free(peer_update_param); 1907 status = QDF_STATUS_E_PERM; 1908 goto error; 1909 } 1910 1911 tdls_update_6g_power(vdev, soc_obj, true); 1912 tdls_increment_peer_count(soc_obj); 1913 /* Need to update osif params when first peer gets connected */ 1914 if (soc_obj->connected_peer_count == 1 && 1915 soc_obj->tdls_osif_update_cb.tdls_osif_conn_update) 1916 soc_obj->tdls_osif_update_cb.tdls_osif_conn_update(vdev); 1917 feature = soc_obj->tdls_configs.tdls_feature_flags; 1918 1919 if (soc_obj->tdls_dp_vdev_update) 1920 soc_obj->tdls_dp_vdev_update( 1921 &soc_obj->soc, 1922 wlan_vdev_get_id(vdev), 1923 soc_obj->tdls_update_dp_vdev_flags, 1924 ((peer->link_status == TDLS_LINK_CONNECTED) ? 1925 true : false)); 1926 1927 tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", 1928 TDLS_IS_BUFFER_STA_ENABLED(feature), 1929 soc_obj->tdls_configs.tdls_uapsd_mask); 1930 1931 error: 1932 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 1933 qdf_mem_free(req); 1934 1935 return status; 1936 } 1937 1938 /** 1939 * tdls_config_force_peer() - configure an externally controllable TDLS peer 1940 * @req: TDLS operation request 1941 * 1942 * This is not the tdls_process_cmd function. No need to acquire the reference 1943 * count, release reference count and free the request, the caller handle it 1944 * correctly. 1945 * 1946 * Return: QDF_STATUS_SUCCESS if success; other values if failed 1947 */ 1948 static QDF_STATUS tdls_config_force_peer( 1949 struct tdls_oper_config_force_peer_request *req) 1950 { 1951 struct tdls_peer *peer; 1952 struct tdls_soc_priv_obj *soc_obj; 1953 struct tdls_vdev_priv_obj *vdev_obj; 1954 struct wlan_objmgr_pdev *pdev; 1955 struct wlan_objmgr_vdev *vdev; 1956 const uint8_t *macaddr; 1957 uint32_t feature; 1958 QDF_STATUS status; 1959 uint32_t chan_freq; 1960 struct tdls_peer_update_state *peer_update_param; 1961 1962 macaddr = req->peer_addr; 1963 1964 vdev = req->vdev; 1965 pdev = wlan_vdev_get_pdev(vdev); 1966 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 1967 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 1968 if (!pdev || !vdev_obj || !soc_obj) { 1969 tdls_err("pdev: %pK, vdev_obj: %pK, soc_obj: %pK", 1970 pdev, vdev_obj, soc_obj); 1971 return QDF_STATUS_E_INVAL; 1972 } 1973 1974 feature = soc_obj->tdls_configs.tdls_feature_flags; 1975 if (!(TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || 1976 TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) || 1977 !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { 1978 tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); 1979 return QDF_STATUS_E_NOSUPPORT; 1980 } 1981 1982 /* 1983 * In case of liberal external mode, supplicant will provide peer mac 1984 * address but driver has to behave similar to implicit mode ie 1985 * establish tdls link with any peer that supports tdls and meets stats 1986 */ 1987 if (TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) { 1988 tdls_debug("liberal mode set"); 1989 return QDF_STATUS_SUCCESS; 1990 } 1991 1992 peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); 1993 if (!peer_update_param) 1994 return QDF_STATUS_E_NOMEM; 1995 1996 peer = tdls_get_peer(vdev_obj, macaddr); 1997 if (!peer) { 1998 tdls_err("peer " QDF_MAC_ADDR_FMT " does not exist", 1999 QDF_MAC_ADDR_REF(macaddr)); 2000 status = QDF_STATUS_E_NULL_VALUE; 2001 goto error; 2002 } 2003 status = tdls_set_force_peer(vdev_obj, macaddr, true); 2004 if (QDF_IS_STATUS_ERROR(status)) { 2005 tdls_err("set force peer failed"); 2006 goto error; 2007 } 2008 2009 /* Update the peer mac to firmware, so firmware could update the 2010 * connection table 2011 */ 2012 peer_update_param->vdev_id = wlan_vdev_get_id(vdev); 2013 qdf_mem_copy(peer_update_param->peer_macaddr, 2014 macaddr, QDF_MAC_ADDR_SIZE); 2015 peer_update_param->peer_state = TDLS_PEER_ADD_MAC_ADDR; 2016 2017 status = tdls_wma_update_peer_state(soc_obj, peer_update_param); 2018 if (QDF_IS_STATUS_ERROR(status)) { 2019 tdls_err("update peer state failed"); 2020 goto error; 2021 } 2022 2023 soc_obj->tdls_external_peer_count++; 2024 chan_freq = req->ch_freq; 2025 2026 /* Validate if off channel is DFS channel */ 2027 if (wlan_reg_is_dfs_for_freq(pdev, chan_freq)) { 2028 tdls_err("Resetting TDLS off-channel freq from %d to %d", 2029 req->ch_freq, WLAN_TDLS_PREFERRED_OFF_CHANNEL_FRQ_DEF); 2030 req->ch_freq = WLAN_TDLS_PREFERRED_OFF_CHANNEL_FRQ_DEF; 2031 } 2032 tdls_set_extctrl_param(peer, req->ch_freq, req->max_latency, 2033 req->op_class, req->min_bandwidth); 2034 2035 tdls_set_callback(peer, req->callback); 2036 tdls_set_ct_mode(soc_obj->soc, vdev); 2037 2038 return status; 2039 error: 2040 qdf_mem_free(peer_update_param); 2041 return status; 2042 } 2043 2044 /** 2045 * tdls_process_setup_peer() - process configure an externally 2046 * controllable TDLS peer 2047 * @req: TDLS operation request 2048 * 2049 * Return: QDF_STATUS_SUCCESS if success; other values if failed 2050 */ 2051 QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) 2052 { 2053 struct tdls_oper_config_force_peer_request peer_req; 2054 struct tdls_soc_priv_obj *soc_obj; 2055 struct wlan_objmgr_vdev *vdev; 2056 QDF_STATUS status; 2057 uint8_t reg_bw_offset = 0; 2058 qdf_freq_t pref_freq; 2059 uint32_t pref_width; 2060 struct wlan_objmgr_pdev *pdev; 2061 2062 2063 /* reference cnt is acquired in ucfg_tdls_oper */ 2064 vdev = req->vdev; 2065 if (!vdev) { 2066 tdls_err("NULL vdev object"); 2067 status = QDF_STATUS_E_NULL_VALUE; 2068 goto freereq; 2069 } 2070 2071 if (!tdls_check_is_tdls_allowed(vdev)) { 2072 tdls_err("TDLS not allowed on vdev:%d, Reject setup peer", 2073 wlan_vdev_get_id(vdev)); 2074 status = QDF_STATUS_E_INVAL; 2075 goto error; 2076 } 2077 2078 tdls_debug("vdev:%d Configure external TDLS peer " QDF_MAC_ADDR_FMT, 2079 wlan_vdev_get_id(vdev), 2080 QDF_MAC_ADDR_REF(req->peer_addr)); 2081 qdf_mem_zero(&peer_req, sizeof(peer_req)); 2082 peer_req.vdev = vdev; 2083 qdf_mem_copy(peer_req.peer_addr, req->peer_addr, QDF_MAC_ADDR_SIZE); 2084 2085 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 2086 if (!soc_obj) { 2087 tdls_err("NULL soc object"); 2088 status = QDF_STATUS_E_INVAL; 2089 goto error; 2090 } 2091 2092 pref_freq = tdls_get_offchan_freq(vdev, soc_obj); 2093 pdev = wlan_vdev_get_pdev(vdev); 2094 if (!pdev) { 2095 tdls_err("NULL pdev object"); 2096 status = QDF_STATUS_E_INVAL; 2097 goto error; 2098 } 2099 2100 peer_req.ch_freq = pref_freq; 2101 pref_width = tdls_get_offchan_bw(soc_obj, pref_freq); 2102 2103 if (!peer_req.op_class) 2104 peer_req.op_class = tdls_get_opclass_from_bandwidth(vdev, 2105 pref_freq, 2106 pref_width, 2107 ®_bw_offset); 2108 2109 tdls_debug("peer chan %d peer opclass %d reg_bw_offset %d", 2110 peer_req.ch_freq, 2111 peer_req.op_class, 2112 reg_bw_offset); 2113 status = tdls_config_force_peer(&peer_req); 2114 error: 2115 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2116 freereq: 2117 qdf_mem_free(req); 2118 2119 return status; 2120 } 2121 2122 QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) 2123 { 2124 struct tdls_peer *peer; 2125 struct tdls_soc_priv_obj *soc_obj; 2126 struct tdls_vdev_priv_obj *vdev_obj; 2127 struct wlan_objmgr_vdev *vdev; 2128 const uint8_t *macaddr; 2129 uint32_t feature; 2130 QDF_STATUS status; 2131 struct tdls_peer_update_state *peer_update_param; 2132 struct tdls_osif_indication ind; 2133 2134 macaddr = req->peer_addr; 2135 tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDR_FMT, 2136 QDF_MAC_ADDR_REF(macaddr)); 2137 2138 vdev = req->vdev; 2139 if (!vdev) { 2140 tdls_err("NULL vdev object"); 2141 qdf_mem_free(req); 2142 return QDF_STATUS_E_NULL_VALUE; 2143 } 2144 2145 /* reference cnt is acquired in ucfg_tdls_oper */ 2146 vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); 2147 soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); 2148 if (!soc_obj || !vdev_obj) { 2149 tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); 2150 status = QDF_STATUS_E_INVAL; 2151 goto error; 2152 } 2153 2154 feature = soc_obj->tdls_configs.tdls_feature_flags; 2155 if (!(TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || 2156 TDLS_IS_LIBERAL_EXTERNAL_CONTROL_ENABLED(feature)) || 2157 !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { 2158 tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); 2159 status = QDF_STATUS_E_NOSUPPORT; 2160 goto error; 2161 } 2162 2163 peer = tdls_find_peer(vdev_obj, macaddr); 2164 if (!peer) { 2165 tdls_err("peer matching " QDF_MAC_ADDR_FMT " not found", 2166 QDF_MAC_ADDR_REF(macaddr)); 2167 status = QDF_STATUS_E_NULL_VALUE; 2168 goto error; 2169 } 2170 if (peer->link_status == TDLS_LINK_CONNECTED) 2171 tdls_set_peer_link_status(peer, TDLS_LINK_TEARING, 2172 TDLS_LINK_UNSPECIFIED); 2173 2174 if (soc_obj->tdls_dp_vdev_update) 2175 soc_obj->tdls_dp_vdev_update( 2176 &soc_obj->soc, 2177 wlan_vdev_get_id(vdev), 2178 soc_obj->tdls_update_dp_vdev_flags, 2179 false); 2180 2181 if (soc_obj->tdls_event_cb) { 2182 qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); 2183 ind.vdev = vdev; 2184 ind.reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; 2185 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 2186 TDLS_EVENT_TEARDOWN_REQ, &ind); 2187 } 2188 2189 status = tdls_set_force_peer(vdev_obj, macaddr, false); 2190 if (QDF_IS_STATUS_ERROR(status)) { 2191 tdls_err("set force peer failed"); 2192 status = QDF_STATUS_E_INVAL; 2193 goto error; 2194 } 2195 2196 if (soc_obj->tdls_external_peer_count) 2197 soc_obj->tdls_external_peer_count--; 2198 2199 tdls_set_callback(peer, NULL); 2200 peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); 2201 if (!peer_update_param) { 2202 status = QDF_STATUS_E_NOMEM; 2203 goto error; 2204 } 2205 2206 peer_update_param->vdev_id = wlan_vdev_get_id(vdev); 2207 qdf_mem_copy(peer_update_param->peer_macaddr, 2208 macaddr, QDF_MAC_ADDR_SIZE); 2209 peer_update_param->peer_state = TDLS_PEER_REMOVE_MAC_ADDR; 2210 status = tdls_wma_update_peer_state(soc_obj, peer_update_param); 2211 if (QDF_IS_STATUS_ERROR(status)) { 2212 qdf_mem_free(peer_update_param); 2213 goto error; 2214 } 2215 tdls_set_ct_mode(soc_obj->soc, vdev); 2216 2217 error: 2218 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2219 qdf_mem_free(req); 2220 2221 return status; 2222 } 2223 2224 static const char *tdls_evt_to_str(enum tdls_event_msg_type type) 2225 { 2226 switch (type) { 2227 case TDLS_SHOULD_DISCOVER: 2228 return "SHOULD_DISCOVER"; 2229 case TDLS_SHOULD_TEARDOWN: 2230 return "SHOULD_TEARDOWN"; 2231 case TDLS_PEER_DISCONNECTED: 2232 return "SHOULD_PEER_DISCONNECTED"; 2233 case TDLS_CONNECTION_TRACKER_NOTIFY: 2234 return "CONNECTION_TRACKER_NOTIFICATION"; 2235 default: 2236 return "INVALID_TYPE"; 2237 } 2238 } 2239 2240 QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, 2241 struct tdls_event_info *evt) 2242 { 2243 struct tdls_soc_priv_obj *soc_obj; 2244 struct tdls_vdev_priv_obj *vdev_obj; 2245 struct tdls_peer *curr_peer; 2246 uint32_t feature; 2247 uint16_t type; 2248 2249 /*TODO ignore this if any concurrency detected*/ 2250 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 2251 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 2252 type = evt->message_type; 2253 2254 tdls_debug("TDLS %s: " QDF_MAC_ADDR_FMT "reason %d", 2255 tdls_evt_to_str(type), 2256 QDF_MAC_ADDR_REF(evt->peermac.bytes), 2257 evt->peer_reason); 2258 if (!soc_obj || !vdev_obj) { 2259 tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", 2260 soc_obj, vdev_obj, tdls_evt_to_str(type)); 2261 return QDF_STATUS_E_NULL_VALUE; 2262 } 2263 if (soc_obj->tdls_nss_switch_in_progress) { 2264 tdls_err("TDLS antenna switching, ignore %s", 2265 tdls_evt_to_str(type)); 2266 return QDF_STATUS_SUCCESS; 2267 } 2268 2269 curr_peer = tdls_get_peer(vdev_obj, evt->peermac.bytes); 2270 if (!curr_peer) { 2271 tdls_notice("curr_peer is null"); 2272 return QDF_STATUS_E_NULL_VALUE; 2273 } 2274 2275 if (TDLS_LINK_CONNECTED == curr_peer->link_status) { 2276 tdls_err("TDLS link status is connected, ignore"); 2277 return QDF_STATUS_SUCCESS; 2278 } 2279 2280 feature = soc_obj->tdls_configs.tdls_feature_flags; 2281 if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) && 2282 !curr_peer->is_forced_peer) { 2283 tdls_debug("curr_peer is not forced, ignore %s", 2284 tdls_evt_to_str(type)); 2285 return QDF_STATUS_SUCCESS; 2286 } 2287 2288 tdls_debug("initiate TDLS setup on %s, ext: %d, force: %d, reason: %d", 2289 tdls_evt_to_str(type), 2290 TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature), 2291 curr_peer->is_forced_peer, evt->peer_reason); 2292 vdev_obj->curr_candidate = curr_peer; 2293 tdls_implicit_send_discovery_request(vdev_obj); 2294 2295 return QDF_STATUS_SUCCESS; 2296 } 2297 2298 QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, 2299 struct tdls_event_info *evt) 2300 { 2301 struct tdls_soc_priv_obj *soc_obj; 2302 struct tdls_vdev_priv_obj *vdev_obj; 2303 struct tdls_peer *curr_peer; 2304 uint32_t reason; 2305 uint16_t type; 2306 2307 type = evt->message_type; 2308 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 2309 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 2310 2311 tdls_debug("TDLS %s: " QDF_MAC_ADDR_FMT "reason %d", 2312 tdls_evt_to_str(type), 2313 QDF_MAC_ADDR_REF(evt->peermac.bytes), evt->peer_reason); 2314 2315 if (!soc_obj || !vdev_obj) { 2316 tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", 2317 soc_obj, vdev_obj, tdls_evt_to_str(type)); 2318 return QDF_STATUS_E_NULL_VALUE; 2319 } 2320 2321 curr_peer = tdls_find_peer(vdev_obj, evt->peermac.bytes); 2322 if (!curr_peer) { 2323 tdls_notice("curr_peer is null"); 2324 return QDF_STATUS_E_NULL_VALUE; 2325 } 2326 2327 reason = evt->peer_reason; 2328 if (TDLS_LINK_CONNECTED == curr_peer->link_status) { 2329 tdls_err("%s reason: %d for" QDF_MAC_ADDR_FMT, 2330 tdls_evt_to_str(type), evt->peer_reason, 2331 QDF_MAC_ADDR_REF(evt->peermac.bytes)); 2332 if (reason == TDLS_TEARDOWN_RSSI || 2333 reason == TDLS_DISCONNECTED_PEER_DELETE || 2334 reason == TDLS_TEARDOWN_PTR_TIMEOUT || 2335 reason == TDLS_TEARDOWN_NO_RSP) 2336 reason = TDLS_TEARDOWN_PEER_UNREACHABLE; 2337 else 2338 reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; 2339 2340 tdls_indicate_teardown(vdev_obj, curr_peer, reason); 2341 } else { 2342 tdls_err("TDLS link is not connected, ignore %s", 2343 tdls_evt_to_str(type)); 2344 } 2345 2346 return QDF_STATUS_SUCCESS; 2347 } 2348 2349 QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, 2350 struct tdls_event_info *evt) 2351 { 2352 struct tdls_soc_priv_obj *soc_obj; 2353 struct tdls_vdev_priv_obj *vdev_obj; 2354 uint16_t type; 2355 2356 type = evt->message_type; 2357 soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); 2358 vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); 2359 2360 if (!soc_obj || !vdev_obj) { 2361 tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", 2362 soc_obj, vdev_obj, tdls_evt_to_str(type)); 2363 return QDF_STATUS_E_NULL_VALUE; 2364 } 2365 2366 /*TODO connection tracker update*/ 2367 return QDF_STATUS_SUCCESS; 2368 } 2369 2370 /** 2371 * tdls_process_set_responder() - Set/clear TDLS peer's responder role 2372 * @set_req: set responder request 2373 * 2374 * Return: 0 for success or -EINVAL otherwise 2375 */ 2376 static 2377 int tdls_process_set_responder(struct tdls_set_responder_req *set_req) 2378 { 2379 struct tdls_peer *curr_peer; 2380 struct tdls_vdev_priv_obj *tdls_vdev; 2381 struct wlan_objmgr_psoc *psoc; 2382 QDF_STATUS status; 2383 2384 tdls_vdev = wlan_vdev_get_tdls_vdev_obj(set_req->vdev); 2385 if (!tdls_vdev) { 2386 tdls_err("tdls vdev obj is NULL"); 2387 return -EINVAL; 2388 } 2389 curr_peer = tdls_get_peer(tdls_vdev, set_req->peer_mac); 2390 if (!curr_peer) { 2391 tdls_err("curr_peer is NULL"); 2392 return -EINVAL; 2393 } 2394 2395 curr_peer->is_responder = set_req->responder; 2396 2397 psoc = wlan_vdev_get_psoc(tdls_vdev->vdev); 2398 if (!psoc) { 2399 tdls_err("psoc not found"); 2400 return -EINVAL; 2401 } 2402 2403 status = policy_mgr_update_nss_req(psoc, 2404 wlan_vdev_get_id(tdls_vdev->vdev), 2405 HW_MODE_SS_2x2, HW_MODE_SS_2x2); 2406 if (QDF_IS_STATUS_ERROR(status)) { 2407 tdls_err("Unable to process NSS request"); 2408 return -EINVAL; 2409 } 2410 2411 return 0; 2412 } 2413 2414 2415 /** 2416 * tdls_set_responder() - Set/clear TDLS peer's responder role 2417 * @set_req: set responder request 2418 * 2419 * Return: 0 for success or -EINVAL otherwise 2420 */ 2421 int tdls_set_responder(struct tdls_set_responder_req *set_req) 2422 { 2423 int status; 2424 2425 if (!set_req) { 2426 tdls_err("Invalid input params"); 2427 return -EINVAL; 2428 } 2429 2430 if (!set_req->vdev) { 2431 tdls_err("Invalid input params %pK", set_req); 2432 status = -EINVAL; 2433 goto free_req; 2434 } 2435 2436 status = wlan_objmgr_vdev_try_get_ref(set_req->vdev, WLAN_TDLS_NB_ID); 2437 if (QDF_STATUS_SUCCESS != status) { 2438 tdls_err("vdev object is deleted"); 2439 status = -EINVAL; 2440 goto error; 2441 } 2442 2443 status = tdls_process_set_responder(set_req); 2444 2445 error: 2446 wlan_objmgr_vdev_release_ref(set_req->vdev, WLAN_TDLS_NB_ID); 2447 free_req: 2448 qdf_mem_free(set_req); 2449 return status; 2450 } 2451 2452 static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) 2453 { 2454 uint8_t staidx; 2455 struct tdls_peer *curr_peer; 2456 struct tdls_conn_info *conn_rec; 2457 int ret = 0; 2458 2459 conn_rec = soc_obj->tdls_conn_info; 2460 for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { 2461 if (!conn_rec[staidx].valid_entry) 2462 continue; 2463 2464 curr_peer = tdls_find_all_peer(soc_obj, 2465 conn_rec[staidx].peer_mac.bytes); 2466 if (!curr_peer) 2467 continue; 2468 2469 /* if supported only 1x1, skip it */ 2470 if (curr_peer->spatial_streams == HW_MODE_SS_1x1) 2471 continue; 2472 2473 tdls_debug("Indicate TDLS teardown peer bssid " 2474 QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF( 2475 curr_peer->peer_mac.bytes)); 2476 tdls_indicate_teardown(curr_peer->vdev_priv, curr_peer, 2477 TDLS_TEARDOWN_PEER_UNSPEC_REASON); 2478 2479 soc_obj->tdls_teardown_peers_cnt++; 2480 } 2481 2482 if (soc_obj->tdls_teardown_peers_cnt >= 1) { 2483 soc_obj->tdls_nss_switch_in_progress = true; 2484 tdls_debug("TDLS peers to be torn down = %d", 2485 soc_obj->tdls_teardown_peers_cnt); 2486 2487 /* set the antenna switch transition mode */ 2488 if (mode == HW_MODE_SS_1x1) { 2489 soc_obj->tdls_nss_transition_mode = 2490 TDLS_NSS_TRANSITION_S_2x2_to_1x1; 2491 ret = -EAGAIN; 2492 } else { 2493 soc_obj->tdls_nss_transition_mode = 2494 TDLS_NSS_TRANSITION_S_1x1_to_2x2; 2495 ret = 0; 2496 } 2497 tdls_debug("TDLS teardown for antenna switch operation starts"); 2498 } 2499 2500 return ret; 2501 } 2502 2503 QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) 2504 { 2505 QDF_STATUS status; 2506 struct tdls_soc_priv_obj *soc_obj; 2507 struct tdls_vdev_priv_obj *vdev_obj; 2508 struct wlan_objmgr_vdev *vdev = NULL; 2509 uint32_t vdev_nss; 2510 int ant_switch_state = 0; 2511 uint32_t vdev_id; 2512 enum QDF_OPMODE opmode; 2513 qdf_freq_t freq; 2514 struct tdls_osif_indication ind; 2515 enum policy_mgr_con_mode mode; 2516 2517 if (!req) { 2518 tdls_err("null req"); 2519 return QDF_STATUS_E_INVAL; 2520 } 2521 2522 vdev = req->vdev; 2523 if (!vdev) { 2524 tdls_err("null vdev"); 2525 qdf_mem_free(req); 2526 return QDF_STATUS_E_INVAL; 2527 } 2528 2529 status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); 2530 if (QDF_IS_STATUS_ERROR(status)) { 2531 tdls_err("can't get vdev_obj & soc_obj"); 2532 goto get_obj_err; 2533 } 2534 2535 if (soc_obj->connected_peer_count == 0) 2536 goto ant_sw_done; 2537 2538 if (soc_obj->tdls_nss_switch_in_progress) { 2539 if (!soc_obj->tdls_nss_teardown_complete) { 2540 tdls_err("TDLS antenna switch is in progress"); 2541 goto ant_sw_in_progress; 2542 } else { 2543 goto ant_sw_done; 2544 } 2545 } 2546 2547 vdev_id = wlan_vdev_get_id(vdev); 2548 opmode = wlan_vdev_mlme_get_opmode(vdev); 2549 mode = policy_mgr_qdf_opmode_to_pm_con_mode(wlan_vdev_get_psoc(vdev), 2550 opmode, vdev_id); 2551 freq = policy_mgr_get_channel(soc_obj->soc, 2552 mode, 2553 &vdev_id); 2554 2555 /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ 2556 if (WLAN_REG_IS_24GHZ_CH_FREQ(freq)) 2557 vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_2g; 2558 else 2559 vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_5g; 2560 2561 if (vdev_nss == HW_MODE_SS_1x1) { 2562 tdls_debug("Supported NSS is 1x1, no need to teardown TDLS links"); 2563 goto ant_sw_done; 2564 } 2565 2566 if (tdls_teardown_links(soc_obj, req->mode) == 0) 2567 goto ant_sw_done; 2568 2569 ant_sw_in_progress: 2570 ant_switch_state = -EAGAIN; 2571 ant_sw_done: 2572 if (soc_obj->tdls_event_cb) { 2573 ind.vdev = vdev; 2574 ind.status = ant_switch_state; 2575 soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, 2576 TDLS_EVENT_ANTENNA_SWITCH, &ind); 2577 } 2578 2579 if (soc_obj->tdls_nss_switch_in_progress && 2580 soc_obj->tdls_nss_teardown_complete) { 2581 soc_obj->tdls_nss_switch_in_progress = false; 2582 soc_obj->tdls_nss_teardown_complete = false; 2583 } 2584 tdls_debug("tdls_nss_switch_in_progress: %d tdls_nss_teardown_complete: %d", 2585 soc_obj->tdls_nss_switch_in_progress, 2586 soc_obj->tdls_nss_teardown_complete); 2587 2588 get_obj_err: 2589 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2590 qdf_mem_free(req); 2591 2592 return status; 2593 } 2594 2595 QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) 2596 { 2597 struct tdls_antenna_switch_request *req; 2598 2599 if (!msg || !msg->bodyptr) { 2600 tdls_err("msg: 0x%pK", msg); 2601 return QDF_STATUS_E_NULL_VALUE; 2602 } 2603 req = msg->bodyptr; 2604 wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); 2605 qdf_mem_free(req); 2606 2607 return QDF_STATUS_SUCCESS; 2608 } 2609 2610 void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev) 2611 { 2612 if (!vdev) { 2613 tdls_err("vdev is NULL"); 2614 return; 2615 } 2616 2617 wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); 2618 } 2619 2620 int tdls_process_set_offchannel(struct tdls_set_offchannel *req) 2621 { 2622 int status; 2623 struct tdls_vdev_priv_obj *tdls_vdev_obj; 2624 struct tdls_soc_priv_obj *tdls_soc_obj; 2625 2626 if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != 2627 QDF_STATUS_SUCCESS) { 2628 status = -ENOTSUPP; 2629 goto free; 2630 } 2631 2632 tdls_debug("TDLS offchannel to be configured %d", req->offchannel); 2633 2634 if (req->offchannel) 2635 status = tdls_set_tdls_offchannel(tdls_soc_obj, 2636 req->offchannel); 2637 else 2638 status = -ENOTSUPP; 2639 2640 free: 2641 2642 if (req->callback) 2643 req->callback(req->vdev); 2644 qdf_mem_free(req); 2645 2646 return status; 2647 } 2648 2649 int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req) 2650 { 2651 int status = QDF_STATUS_E_FAILURE; 2652 struct tdls_soc_priv_obj *tdls_soc_obj; 2653 2654 tdls_debug("TDLS offchan mode to be configured %d", req->offchan_mode); 2655 2656 tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); 2657 if (!tdls_soc_obj) 2658 goto free; 2659 2660 if ((tdls_get_connected_peer_count(tdls_soc_obj) > 1) && 2661 req->offchan_mode == ENABLE_CHANSWITCH) { 2662 tdls_debug("Reject off chan enable, Connected peer count %d", 2663 tdls_get_connected_peer_count(tdls_soc_obj)); 2664 goto free; 2665 } 2666 2667 status = tdls_set_tdls_offchannelmode(req->vdev, req->offchan_mode); 2668 2669 if (req->callback) 2670 req->callback(req->vdev); 2671 2672 free: 2673 qdf_mem_free(req); 2674 2675 return status; 2676 } 2677 2678 int tdls_process_set_secoffchanneloffset( 2679 struct tdls_set_secoffchanneloffset *req) 2680 { 2681 int status; 2682 struct tdls_vdev_priv_obj *tdls_vdev_obj; 2683 struct tdls_soc_priv_obj *tdls_soc_obj; 2684 2685 if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != 2686 QDF_STATUS_SUCCESS) { 2687 status = -ENOTSUPP; 2688 goto free; 2689 } 2690 2691 tdls_debug("TDLS offchannel offset to be configured %d", 2692 req->offchan_offset); 2693 status = tdls_set_tdls_secoffchanneloffset(tdls_soc_obj, 2694 req->offchan_offset); 2695 2696 free: 2697 2698 if (req->callback) 2699 req->callback(req->vdev); 2700 qdf_mem_free(req); 2701 2702 return status; 2703 } 2704