1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 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: target_if_vdev_mgr_rx_ops.c 22 * 23 * This file provide definition for APIs registered through events received 24 * from FW 25 */ 26 #include <target_if_vdev_mgr_rx_ops.h> 27 #include <target_if_vdev_mgr_tx_ops.h> 28 #include <wlan_vdev_mgr_tgt_if_rx_defs.h> 29 #include <wlan_vdev_mgr_tgt_if_tx_defs.h> 30 #include <wmi_unified_param.h> 31 #include <wlan_mlme_dbg.h> 32 #include <target_if.h> 33 #include <wlan_vdev_mlme_main.h> 34 #include <wmi_unified_vdev_api.h> 35 #include <target_if_psoc_wake_lock.h> 36 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 37 #include <target_if_cm_roam_offload.h> 38 #endif 39 40 static inline 41 void target_if_vdev_mgr_handle_recovery(struct wlan_objmgr_psoc *psoc, 42 uint8_t vdev_id, 43 enum qdf_hang_reason recovery_reason, 44 uint16_t rsp_pos) 45 { 46 mlme_nofl_err("PSOC_%d VDEV_%d: %s rsp timeout", wlan_psoc_get_id(psoc), 47 vdev_id, string_from_rsp_bit(rsp_pos)); 48 if (target_if_vdev_mgr_is_panic_allowed()) 49 qdf_trigger_self_recovery(psoc, recovery_reason); 50 else 51 mlme_nofl_debug("PSOC_%d VDEV_%d: Panic not allowed", 52 wlan_psoc_get_id(psoc), vdev_id); 53 } 54 55 #ifdef WLAN_FEATURE_ROAM_OFFLOAD 56 static inline QDF_STATUS 57 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc, 58 uint8_t vdev_id) 59 { 60 return target_if_cm_send_rso_stop_failure_rsp(psoc, vdev_id); 61 } 62 #else 63 static inline QDF_STATUS 64 target_if_send_rso_stop_failure_rsp(struct wlan_objmgr_psoc *psoc, 65 uint8_t vdev_id) 66 { 67 return QDF_STATUS_E_NOSUPPORT; 68 } 69 #endif 70 71 void target_if_vdev_mgr_rsp_timer_cb(void *arg) 72 { 73 struct wlan_objmgr_psoc *psoc; 74 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 75 struct vdev_start_response start_rsp = {0}; 76 struct vdev_stop_response stop_rsp = {0}; 77 struct vdev_delete_response del_rsp = {0}; 78 struct peer_delete_all_response peer_del_all_rsp = {0}; 79 struct vdev_response_timer *vdev_rsp = arg; 80 enum qdf_hang_reason recovery_reason; 81 uint8_t vdev_id; 82 uint16_t rsp_pos = RESPONSE_BIT_MAX; 83 84 if (!vdev_rsp) { 85 mlme_err("Vdev response timer is NULL"); 86 return; 87 } 88 89 psoc = vdev_rsp->psoc; 90 if (!psoc) { 91 mlme_err("PSOC is NULL"); 92 return; 93 } 94 95 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 96 if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { 97 mlme_err("No Rx Ops"); 98 return; 99 } 100 101 if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) && 102 !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) && 103 !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) && 104 !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) && 105 !qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, 106 &vdev_rsp->rsp_status) && 107 !qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT, 108 &vdev_rsp->rsp_status)) { 109 mlme_debug("No response bit is set, ignoring actions :%d", 110 vdev_rsp->vdev_id); 111 return; 112 } 113 114 vdev_id = vdev_rsp->vdev_id; 115 if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { 116 mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id, 117 wlan_psoc_get_id(psoc)); 118 return; 119 } 120 121 vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT; 122 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 123 &vdev_rsp->rsp_status) || 124 qdf_atomic_test_bit(RESTART_RESPONSE_BIT, 125 &vdev_rsp->rsp_status)) { 126 start_rsp.vdev_id = vdev_id; 127 start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT; 128 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 129 &vdev_rsp->rsp_status)) { 130 start_rsp.resp_type = 131 WMI_HOST_VDEV_START_RESP_EVENT; 132 rsp_pos = START_RESPONSE_BIT; 133 recovery_reason = QDF_VDEV_START_RESPONSE_TIMED_OUT; 134 } else { 135 start_rsp.resp_type = 136 WMI_HOST_VDEV_RESTART_RESP_EVENT; 137 rsp_pos = RESTART_RESPONSE_BIT; 138 recovery_reason = QDF_VDEV_RESTART_RESPONSE_TIMED_OUT; 139 } 140 141 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 142 target_if_vdev_mgr_handle_recovery(psoc, vdev_id, 143 recovery_reason, rsp_pos); 144 rx_ops->vdev_mgr_start_response(psoc, &start_rsp); 145 } else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT, 146 &vdev_rsp->rsp_status)) { 147 rsp_pos = STOP_RESPONSE_BIT; 148 stop_rsp.vdev_id = vdev_id; 149 recovery_reason = QDF_VDEV_STOP_RESPONSE_TIMED_OUT; 150 151 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 152 target_if_vdev_mgr_handle_recovery(psoc, vdev_id, 153 recovery_reason, rsp_pos); 154 rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp); 155 } else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT, 156 &vdev_rsp->rsp_status)) { 157 del_rsp.vdev_id = vdev_id; 158 rsp_pos = DELETE_RESPONSE_BIT; 159 recovery_reason = QDF_VDEV_DELETE_RESPONSE_TIMED_OUT; 160 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 161 target_if_vdev_mgr_handle_recovery(psoc, vdev_id, 162 recovery_reason, rsp_pos); 163 rx_ops->vdev_mgr_delete_response(psoc, &del_rsp); 164 } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, 165 &vdev_rsp->rsp_status)) { 166 peer_del_all_rsp.vdev_id = vdev_id; 167 peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap; 168 rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; 169 recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; 170 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 171 target_if_vdev_mgr_handle_recovery(psoc, vdev_id, 172 recovery_reason, rsp_pos); 173 rx_ops->vdev_mgr_peer_delete_all_response(psoc, 174 &peer_del_all_rsp); 175 } else if (qdf_atomic_test_bit(RSO_STOP_RESPONSE_BIT, 176 &vdev_rsp->rsp_status)) { 177 rsp_pos = RSO_STOP_RESPONSE_BIT; 178 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 179 /** 180 * FW did not respond to rso stop cmd, as roaming is 181 * disabled either due to race condition 182 * that happened during previous disconnect OR 183 * supplicant disabled roaming. 184 * To solve this issue, skip recovery and host will 185 * continue disconnect and cleanup rso state. 186 */ 187 mlme_debug("No rsp from FW received , continue with disconnect"); 188 target_if_send_rso_stop_failure_rsp(psoc, vdev_id); 189 } else { 190 mlme_err("PSOC_%d VDEV_%d: Unknown error", 191 wlan_psoc_get_id(psoc), vdev_id); 192 return; 193 } 194 } 195 196 #ifdef SERIALIZE_VDEV_RESP 197 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb_mc(struct scheduler_msg *msg) 198 { 199 struct vdev_response_timer *vdev_rsp; 200 struct wlan_objmgr_psoc *psoc; 201 202 if (!msg->bodyptr) { 203 mlme_err("Message bodyptr is NULL"); 204 return QDF_STATUS_E_INVAL; 205 } 206 207 vdev_rsp = scheduler_qdf_mc_timer_deinit_return_data_ptr(msg->bodyptr); 208 if (!vdev_rsp) { 209 mlme_err("vdev response timer is NULL"); 210 return QDF_STATUS_E_INVAL; 211 } 212 213 psoc = vdev_rsp->psoc; 214 if (!psoc) { 215 mlme_err("PSOC is NULL"); 216 return QDF_STATUS_E_INVAL; 217 } 218 219 if (vdev_rsp->rsp_status) 220 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); 221 222 return QDF_STATUS_SUCCESS; 223 } 224 225 static void 226 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg) 227 { 228 struct scheduler_msg msg = {0}; 229 struct vdev_response_timer *vdev_rsp = arg; 230 struct wlan_objmgr_psoc *psoc; 231 struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper; 232 233 psoc = vdev_rsp->psoc; 234 if (!psoc) { 235 mlme_err("PSOC is NULL"); 236 return; 237 } 238 239 msg.type = SYS_MSG_ID_MC_TIMER; 240 msg.reserved = SYS_MSG_COOKIE; 241 242 mc_timer_wrapper = scheduler_qdf_mc_timer_init( 243 target_if_vdev_mgr_rsp_timer_cb, 244 arg); 245 246 if (!mc_timer_wrapper) { 247 mlme_err("failed to allocate sched_qdf_mc_timer_cb_wrapper"); 248 return; 249 } 250 251 msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper; 252 msg.bodyptr = mc_timer_wrapper; 253 msg.bodyval = 0; 254 msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb_mc; 255 256 if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF, 257 QDF_MODULE_ID_TARGET_IF, 258 QDF_MODULE_ID_SYS, &msg) == 259 QDF_STATUS_SUCCESS) 260 return; 261 262 mlme_err("Could not enqueue timer to timer queue"); 263 qdf_mem_free(mc_timer_wrapper); 264 if (psoc) 265 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); 266 } 267 268 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 269 { 270 target_if_vdev_mgr_rsp_cb_mc_ctx(arg); 271 } 272 273 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX 274 #else 275 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 276 { 277 target_if_vdev_mgr_rsp_timer_cb(arg); 278 } 279 280 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX 281 #endif 282 283 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn, 284 uint8_t *data, 285 uint32_t datalen) 286 { 287 QDF_STATUS status = QDF_STATUS_E_INVAL; 288 struct wlan_objmgr_psoc *psoc; 289 struct wmi_unified *wmi_handle; 290 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 291 struct vdev_start_response vdev_start_resp = {0}; 292 uint8_t vdev_id; 293 struct vdev_response_timer *vdev_rsp; 294 295 if (!scn || !data) { 296 mlme_err("Invalid input"); 297 return -EINVAL; 298 } 299 300 psoc = target_if_get_psoc_from_scn_hdl(scn); 301 if (!psoc) { 302 mlme_err("PSOC is NULL"); 303 return -EINVAL; 304 } 305 306 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 307 if (!rx_ops || !rx_ops->vdev_mgr_start_response) { 308 mlme_err("No Rx Ops"); 309 return -EINVAL; 310 } 311 312 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 313 if (!wmi_handle) { 314 mlme_err("wmi_handle is null"); 315 return -EINVAL; 316 } 317 318 if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) { 319 mlme_err("WMI extract failed"); 320 return -EINVAL; 321 } 322 323 vdev_id = vdev_start_resp.vdev_id; 324 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); 325 if (!vdev_rsp) { 326 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 327 vdev_id, wlan_psoc_get_id(psoc)); 328 return -EINVAL; 329 } 330 331 if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT) 332 status = target_if_vdev_mgr_rsp_timer_stop( 333 psoc, vdev_rsp, 334 RESTART_RESPONSE_BIT); 335 else 336 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, 337 START_RESPONSE_BIT); 338 339 if (QDF_IS_STATUS_ERROR(status)) { 340 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 341 psoc->soc_objmgr.psoc_id, vdev_id); 342 goto err; 343 } 344 345 status = rx_ops->vdev_mgr_start_response(psoc, &vdev_start_resp); 346 347 err: 348 return qdf_status_to_os_return(status); 349 } 350 351 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn, 352 uint8_t *data, 353 uint32_t datalen) 354 { 355 QDF_STATUS status = QDF_STATUS_E_INVAL; 356 struct wlan_objmgr_psoc *psoc; 357 struct wmi_unified *wmi_handle; 358 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 359 struct vdev_stop_response rsp = {0}; 360 uint32_t vdev_id; 361 struct vdev_response_timer *vdev_rsp; 362 363 if (!scn || !data) { 364 mlme_err("Invalid input"); 365 return -EINVAL; 366 } 367 368 psoc = target_if_get_psoc_from_scn_hdl(scn); 369 if (!psoc) { 370 mlme_err("PSOC is NULL"); 371 return -EINVAL; 372 } 373 374 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 375 if (!rx_ops || !rx_ops->vdev_mgr_stop_response) { 376 mlme_err("No Rx Ops"); 377 return -EINVAL; 378 } 379 380 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 381 if (!wmi_handle) { 382 mlme_err("wmi_handle is null"); 383 return -EINVAL; 384 } 385 386 if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) { 387 mlme_err("WMI extract failed"); 388 return -EINVAL; 389 } 390 391 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); 392 if (!vdev_rsp) { 393 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 394 vdev_id, wlan_psoc_get_id(psoc)); 395 return -EINVAL; 396 } 397 398 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, 399 STOP_RESPONSE_BIT); 400 401 if (QDF_IS_STATUS_ERROR(status)) { 402 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 403 psoc->soc_objmgr.psoc_id, vdev_id); 404 goto err; 405 } 406 407 rsp.vdev_id = vdev_id; 408 status = rx_ops->vdev_mgr_stop_response(psoc, &rsp); 409 410 err: 411 return qdf_status_to_os_return(status); 412 } 413 414 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn, 415 uint8_t *data, 416 uint32_t datalen) 417 { 418 QDF_STATUS status = QDF_STATUS_E_INVAL; 419 struct wlan_objmgr_psoc *psoc; 420 struct wmi_unified *wmi_handle; 421 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 422 struct vdev_delete_response vdev_del_resp = {0}; 423 struct vdev_response_timer *vdev_rsp; 424 425 if (!scn || !data) { 426 mlme_err("Invalid input"); 427 return -EINVAL; 428 } 429 430 psoc = target_if_get_psoc_from_scn_hdl(scn); 431 if (!psoc) { 432 mlme_err("PSOC is NULL"); 433 return -EINVAL; 434 } 435 436 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 437 if (!rx_ops || !rx_ops->vdev_mgr_delete_response) { 438 mlme_err("No Rx Ops"); 439 return -EINVAL; 440 } 441 442 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 443 if (!wmi_handle) { 444 mlme_err("wmi_handle is null"); 445 return -EINVAL; 446 } 447 448 if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) { 449 mlme_err("WMI extract failed"); 450 return -EINVAL; 451 } 452 453 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 454 vdev_del_resp.vdev_id); 455 if (!vdev_rsp) { 456 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 457 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc)); 458 return -EINVAL; 459 } 460 461 status = target_if_vdev_mgr_rsp_timer_stop( 462 psoc, vdev_rsp, 463 DELETE_RESPONSE_BIT); 464 465 if (QDF_IS_STATUS_ERROR(status)) { 466 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 467 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id); 468 goto err; 469 } 470 471 status = rx_ops->vdev_mgr_delete_response(psoc, &vdev_del_resp); 472 target_if_wake_lock_timeout_release(psoc, DELETE_WAKELOCK); 473 err: 474 return qdf_status_to_os_return(status); 475 } 476 477 static int target_if_vdev_mgr_peer_delete_all_response_handler( 478 ol_scn_t scn, 479 uint8_t *data, 480 uint32_t datalen) 481 { 482 QDF_STATUS status = QDF_STATUS_E_INVAL; 483 struct wlan_objmgr_psoc *psoc; 484 struct wmi_unified *wmi_handle; 485 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 486 struct peer_delete_all_response vdev_peer_del_all_resp = {0}; 487 struct vdev_response_timer *vdev_rsp; 488 489 if (!scn || !data) { 490 mlme_err("Invalid input"); 491 return -EINVAL; 492 } 493 494 psoc = target_if_get_psoc_from_scn_hdl(scn); 495 if (!psoc) { 496 mlme_err("PSOC is NULL"); 497 return -EINVAL; 498 } 499 500 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 501 if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) { 502 mlme_err("No Rx Ops"); 503 return -EINVAL; 504 } 505 506 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 507 if (!wmi_handle) { 508 mlme_err("wmi_handle is null"); 509 return -EINVAL; 510 } 511 512 if (wmi_extract_vdev_peer_delete_all_response_event( 513 wmi_handle, data, 514 &vdev_peer_del_all_resp)) { 515 mlme_err("WMI extract failed"); 516 return -EINVAL; 517 } 518 519 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 520 vdev_peer_del_all_resp.vdev_id); 521 if (!vdev_rsp) { 522 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 523 vdev_peer_del_all_resp.vdev_id, 524 wlan_psoc_get_id(psoc)); 525 return -EINVAL; 526 } 527 528 status = target_if_vdev_mgr_rsp_timer_stop( 529 psoc, 530 vdev_rsp, 531 PEER_DELETE_ALL_RESPONSE_BIT); 532 533 if (QDF_IS_STATUS_ERROR(status)) { 534 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 535 psoc->soc_objmgr.psoc_id, 536 vdev_peer_del_all_resp.vdev_id); 537 goto err; 538 } 539 540 vdev_peer_del_all_resp.peer_type_bitmap = vdev_rsp->peer_type_bitmap; 541 542 status = rx_ops->vdev_mgr_peer_delete_all_response( 543 psoc, 544 &vdev_peer_del_all_resp); 545 546 err: 547 return qdf_status_to_os_return(status); 548 } 549 550 int target_if_vdev_mgr_offload_bcn_tx_status_handler( 551 ol_scn_t scn, 552 uint8_t *data, 553 uint32_t datalen) 554 { 555 QDF_STATUS status; 556 struct wlan_objmgr_psoc *psoc; 557 struct wmi_unified *wmi_handle; 558 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 559 uint32_t vdev_id, tx_status; 560 561 if (!scn || !data) { 562 mlme_err("Invalid input"); 563 return -EINVAL; 564 } 565 psoc = target_if_get_psoc_from_scn_hdl(scn); 566 if (!psoc) { 567 mlme_err("PSOC is NULL"); 568 return -EINVAL; 569 } 570 571 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 572 if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) { 573 mlme_err("No Rx Ops"); 574 return -EINVAL; 575 } 576 577 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 578 if (!wmi_handle) { 579 mlme_err("wmi_handle is null"); 580 return -EINVAL; 581 } 582 583 if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data, 584 &vdev_id, &tx_status)) { 585 mlme_err("WMI extract failed"); 586 return -EINVAL; 587 } 588 589 status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle( 590 vdev_id, 591 tx_status); 592 593 return qdf_status_to_os_return(status); 594 } 595 596 int target_if_vdev_mgr_tbttoffset_update_handler( 597 ol_scn_t scn, uint8_t *data, 598 uint32_t datalen) 599 { 600 QDF_STATUS status; 601 struct wlan_objmgr_psoc *psoc; 602 struct wmi_unified *wmi_handle; 603 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 604 uint32_t num_vdevs = 0; 605 606 if (!scn || !data) { 607 mlme_err("Invalid input"); 608 return -EINVAL; 609 } 610 psoc = target_if_get_psoc_from_scn_hdl(scn); 611 if (!psoc) { 612 mlme_err("PSOC is NULL"); 613 return -EINVAL; 614 } 615 616 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 617 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) { 618 mlme_err("No Rx Ops"); 619 return -EINVAL; 620 } 621 622 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 623 if (!wmi_handle) { 624 mlme_err("wmi_handle is null"); 625 return -EINVAL; 626 } 627 628 if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) { 629 mlme_err("WMI extract failed"); 630 return -EINVAL; 631 } 632 633 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 634 false); 635 636 return qdf_status_to_os_return(status); 637 } 638 639 int target_if_vdev_mgr_ext_tbttoffset_update_handler( 640 ol_scn_t scn, 641 uint8_t *data, 642 uint32_t datalen) 643 { 644 QDF_STATUS status; 645 struct wlan_objmgr_psoc *psoc; 646 struct wmi_unified *wmi_handle; 647 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 648 uint32_t num_vdevs = 0; 649 650 if (!scn || !data) { 651 mlme_err("Invalid input"); 652 return -EINVAL; 653 } 654 psoc = target_if_get_psoc_from_scn_hdl(scn); 655 if (!psoc) { 656 mlme_err("PSOC is NULL"); 657 return -EINVAL; 658 } 659 660 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 661 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) { 662 mlme_err("No Rx Ops"); 663 return -EINVAL; 664 } 665 666 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 667 if (!wmi_handle) { 668 mlme_err("wmi_handle is null"); 669 return -EINVAL; 670 } 671 672 if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data, 673 &num_vdevs)) { 674 mlme_err("WMI extract failed"); 675 return -EINVAL; 676 } 677 678 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 679 true); 680 681 return qdf_status_to_os_return(status); 682 } 683 684 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler( 685 ol_scn_t scn, 686 uint8_t *data, 687 uint32_t datalen) 688 { 689 QDF_STATUS status = QDF_STATUS_E_INVAL; 690 struct wlan_objmgr_psoc *psoc; 691 struct wmi_unified *wmi_handle; 692 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 693 struct multi_vdev_restart_resp restart_resp; 694 struct vdev_response_timer *vdev_rsp; 695 uint8_t max_vdevs, vdev_idx; 696 697 if (!scn || !data) { 698 mlme_err("Invalid input"); 699 return -EINVAL; 700 } 701 702 psoc = target_if_get_psoc_from_scn_hdl(scn); 703 if (!psoc) { 704 mlme_err("PSOC is NULL"); 705 return -EINVAL; 706 } 707 708 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 709 if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp || 710 !rx_ops->psoc_get_vdev_response_timer_info) { 711 mlme_err("No Rx Ops"); 712 return -EINVAL; 713 } 714 715 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 716 if (!wmi_handle) { 717 mlme_err("wmi_handle is null"); 718 return -EINVAL; 719 } 720 721 qdf_mem_zero(&restart_resp, sizeof(restart_resp)); 722 restart_resp.timestamp = qdf_get_log_timestamp(); 723 if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data, 724 &restart_resp)) { 725 mlme_err("WMI extract failed"); 726 return -EINVAL; 727 } 728 729 max_vdevs = wlan_psoc_get_max_vdev_count(psoc); 730 for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) { 731 if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap)) 732 continue; 733 734 mlme_debug("PSOC_%d VDEV_%d: Restart resp received", 735 wlan_psoc_get_id(psoc), vdev_idx); 736 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 737 vdev_idx); 738 if (!vdev_rsp) { 739 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 740 wlan_psoc_get_id(psoc), vdev_idx); 741 continue; 742 } 743 744 status = target_if_vdev_mgr_rsp_timer_stop( 745 psoc, vdev_rsp, RESTART_RESPONSE_BIT); 746 if (QDF_IS_STATUS_ERROR(status)) 747 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 748 wlan_psoc_get_id(psoc), vdev_idx); 749 } 750 751 status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp); 752 753 return qdf_status_to_os_return(status); 754 } 755 756 /** 757 * target_if_vdev_csa_complete - CSA complete event handler 758 * @psoc: psoc 759 * @vdev_id: vdev id 760 * 761 * Return: 0 on success 762 */ 763 static int target_if_vdev_csa_complete(struct wlan_objmgr_psoc *psoc, 764 uint8_t vdev_id) 765 { 766 QDF_STATUS status = QDF_STATUS_E_FAILURE; 767 struct vdev_mlme_obj *vdev_mlme; 768 struct wlan_objmgr_vdev *vdev; 769 int ret = 0; 770 771 if (!psoc) { 772 mlme_err("Invalid input"); 773 return -EINVAL; 774 } 775 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, 776 WLAN_VDEV_TARGET_IF_ID); 777 if (!vdev) { 778 mlme_err("VDEV is NULL"); 779 return -EINVAL; 780 } 781 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); 782 if (!vdev_mlme) { 783 mlme_err("VDEV_%d: PSOC_%d VDEV_MLME is NULL", vdev_id, 784 wlan_psoc_get_id(psoc)); 785 ret = -EINVAL; 786 goto end; 787 } 788 789 if ((vdev_mlme->ops) && vdev_mlme->ops->mlme_vdev_csa_complete) { 790 status = vdev_mlme->ops->mlme_vdev_csa_complete(vdev_mlme); 791 if (QDF_IS_STATUS_ERROR(status)) { 792 mlme_err("vdev csa complete failed"); 793 ret = -EINVAL; 794 } 795 } 796 end: 797 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 798 return ret; 799 } 800 801 /** 802 * target_if_pdev_csa_status_event_handler - CSA event handler 803 * @scn: Pointer to scn structure 804 * @data: pointer to event data 805 * @datalen: event data length 806 * 807 * Return: 0 on success 808 */ 809 static int target_if_pdev_csa_status_event_handler( 810 ol_scn_t scn, 811 uint8_t *data, 812 uint32_t datalen) 813 { 814 struct pdev_csa_switch_count_status csa_status; 815 struct wlan_objmgr_psoc *psoc; 816 struct wmi_unified *wmi_handle; 817 struct target_psoc_info *tgt_hdl; 818 int i; 819 QDF_STATUS status; 820 struct wlan_lmac_if_mlme_rx_ops *rx_ops = NULL; 821 822 if (!scn || !data) { 823 mlme_err("Invalid input"); 824 return -EINVAL; 825 } 826 827 psoc = target_if_get_psoc_from_scn_hdl(scn); 828 if (!psoc) { 829 mlme_err("PSOC is NULL"); 830 return -EINVAL; 831 } 832 833 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 834 if (!rx_ops || !rx_ops->vdev_mgr_set_max_channel_switch_time) { 835 mlme_err("No Rx Ops"); 836 return -EINVAL; 837 } 838 839 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 840 if (!wmi_handle) { 841 mlme_err("wmi_handle is null"); 842 return -EINVAL; 843 } 844 845 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); 846 if (!tgt_hdl) { 847 mlme_err("target_psoc_info is null"); 848 return -EINVAL; 849 } 850 851 qdf_mem_zero(&csa_status, sizeof(csa_status)); 852 status = wmi_extract_pdev_csa_switch_count_status( 853 wmi_handle, data, &csa_status); 854 if (QDF_IS_STATUS_ERROR(status)) { 855 mlme_err("Extracting CSA switch count status event failed"); 856 return -EINVAL; 857 } 858 859 if (csa_status.current_switch_count == 1) 860 rx_ops->vdev_mgr_set_max_channel_switch_time 861 (psoc, csa_status.vdev_ids, csa_status.num_vdevs); 862 863 if (wlan_psoc_nif_fw_ext_cap_get(psoc, WLAN_SOC_CEXT_CSA_TX_OFFLOAD)) { 864 for (i = 0; i < csa_status.num_vdevs; i++) { 865 if (!csa_status.current_switch_count) 866 target_if_vdev_csa_complete(psoc, 867 csa_status.vdev_ids[i]); 868 } 869 } 870 871 return target_if_csa_switch_count_status(psoc, tgt_hdl, csa_status); 872 } 873 874 #ifdef WLAN_FEATURE_DYNAMIC_MAC_ADDR_UPDATE 875 /** 876 * target_if_update_macaddr_conf_evt_handler() - Set MAC address confirmation 877 * event handler 878 * @scn: Pointer to scn structure 879 * @event_buff: event data 880 * @len: length 881 * 882 * Response handler for set MAC address request command. 883 * 884 * Return: 0 for success or error code 885 */ 886 static int target_if_update_macaddr_conf_evt_handler(ol_scn_t scn, 887 uint8_t *event_buff, 888 uint32_t len) 889 { 890 struct wlan_objmgr_psoc *psoc; 891 struct wmi_unified *wmi_handle; 892 uint8_t vdev_id, resp_status; 893 QDF_STATUS status; 894 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 895 896 if (!event_buff) { 897 mlme_err("Received NULL event ptr from FW"); 898 return -EINVAL; 899 } 900 901 psoc = target_if_get_psoc_from_scn_hdl(scn); 902 if (!psoc) { 903 mlme_err("PSOC is NULL"); 904 return -EINVAL; 905 } 906 907 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 908 if (!wmi_handle) { 909 mlme_err("wmi_handle is null"); 910 return -EINVAL; 911 } 912 913 status = wmi_extract_update_mac_address_event(wmi_handle, event_buff, 914 &vdev_id, &resp_status); 915 if (QDF_IS_STATUS_ERROR(status)) { 916 mlme_err("Failed to extract update MAC address event"); 917 return -EINVAL; 918 } 919 920 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 921 if (!rx_ops || !rx_ops->vdev_mgr_set_mac_addr_response) { 922 mlme_err("No Rx Ops"); 923 return -EINVAL; 924 } 925 926 rx_ops->vdev_mgr_set_mac_addr_response(vdev_id, resp_status); 927 928 return 0; 929 } 930 931 static inline void 932 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle) 933 { 934 wmi_unified_register_event_handler( 935 wmi_handle, wmi_vdev_update_mac_addr_conf_eventid, 936 target_if_update_macaddr_conf_evt_handler, VDEV_RSP_RX_CTX); 937 } 938 939 static inline void 940 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle) 941 { 942 wmi_unified_unregister_event_handler( 943 wmi_handle, wmi_vdev_update_mac_addr_conf_eventid); 944 } 945 #else 946 static inline void 947 target_if_register_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle) 948 { 949 } 950 951 static inline void 952 target_if_unregister_set_mac_addr_evt_cbk(struct wmi_unified *wmi_handle) 953 { 954 } 955 #endif 956 957 #ifdef WLAN_FEATURE_11BE_MLO 958 /** 959 * target_if_quiet_offload_event_handler() - Quiet IE offload mlo 960 * station event handler 961 * @scn: Pointer to scn structure 962 * @event_buff: event data 963 * @len: length 964 * 965 * Return: 0 for success or error code 966 */ 967 static int target_if_quiet_offload_event_handler(ol_scn_t scn, 968 uint8_t *event_buff, 969 uint32_t len) 970 { 971 struct wlan_objmgr_psoc *psoc; 972 struct wmi_unified *wmi_handle; 973 QDF_STATUS status; 974 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 975 struct vdev_sta_quiet_event sta_quiet_event = {0}; 976 977 if (!event_buff) { 978 mlme_err("Received NULL event ptr from FW"); 979 return -EINVAL; 980 } 981 982 psoc = target_if_get_psoc_from_scn_hdl(scn); 983 if (!psoc) { 984 mlme_err("PSOC is NULL"); 985 return -EINVAL; 986 } 987 988 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 989 if (!wmi_handle) { 990 mlme_err("wmi_handle is null"); 991 return -EINVAL; 992 } 993 994 status = wmi_extract_quiet_offload_event(wmi_handle, event_buff, 995 &sta_quiet_event); 996 if (QDF_IS_STATUS_ERROR(status)) { 997 mlme_err("Failed to extract quiet IE offload event"); 998 return -EINVAL; 999 } 1000 1001 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 1002 if (!rx_ops || !rx_ops->vdev_mgr_quiet_offload) { 1003 mlme_err("No Rx Ops"); 1004 return -EINVAL; 1005 } 1006 1007 rx_ops->vdev_mgr_quiet_offload(psoc, &sta_quiet_event); 1008 1009 return 0; 1010 } 1011 1012 static inline void 1013 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle) 1014 { 1015 wmi_unified_register_event_handler( 1016 wmi_handle, wmi_vdev_quiet_offload_eventid, 1017 target_if_quiet_offload_event_handler, VDEV_RSP_RX_CTX); 1018 } 1019 1020 static inline void 1021 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle) 1022 { 1023 wmi_unified_unregister_event_handler( 1024 wmi_handle, wmi_vdev_quiet_offload_eventid); 1025 } 1026 #else 1027 static inline void 1028 target_if_register_quiet_offload_event(struct wmi_unified *wmi_handle) 1029 { 1030 } 1031 1032 static inline void 1033 target_if_unregister_quiet_offload_event(struct wmi_unified *wmi_handle) 1034 { 1035 } 1036 #endif 1037 1038 QDF_STATUS target_if_vdev_mgr_wmi_event_register( 1039 struct wlan_objmgr_psoc *psoc) 1040 { 1041 QDF_STATUS retval = QDF_STATUS_SUCCESS; 1042 struct wmi_unified *wmi_handle; 1043 1044 if (!psoc) { 1045 mlme_err("PSOC is NULL"); 1046 return QDF_STATUS_E_NULL_VALUE; 1047 } 1048 1049 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 1050 if (!wmi_handle) { 1051 mlme_err("wmi_handle is null"); 1052 return QDF_STATUS_E_INVAL; 1053 } 1054 1055 retval = wmi_unified_register_event_handler( 1056 wmi_handle, 1057 wmi_vdev_stopped_event_id, 1058 target_if_vdev_mgr_stop_response_handler, 1059 VDEV_RSP_RX_CTX); 1060 if (QDF_IS_STATUS_ERROR(retval)) 1061 mlme_err("failed to register for stop response"); 1062 1063 retval = wmi_unified_register_event_handler( 1064 wmi_handle, 1065 wmi_vdev_delete_resp_event_id, 1066 target_if_vdev_mgr_delete_response_handler, 1067 VDEV_RSP_RX_CTX); 1068 if (QDF_IS_STATUS_ERROR(retval)) 1069 mlme_err("failed to register for delete response"); 1070 1071 retval = wmi_unified_register_event_handler( 1072 wmi_handle, 1073 wmi_vdev_start_resp_event_id, 1074 target_if_vdev_mgr_start_response_handler, 1075 VDEV_RSP_RX_CTX); 1076 if (QDF_IS_STATUS_ERROR(retval)) 1077 mlme_err("failed to register for start response"); 1078 1079 retval = wmi_unified_register_event_handler( 1080 wmi_handle, 1081 wmi_peer_delete_all_response_event_id, 1082 target_if_vdev_mgr_peer_delete_all_response_handler, 1083 VDEV_RSP_RX_CTX); 1084 if (QDF_IS_STATUS_ERROR(retval)) 1085 mlme_err("failed to register for peer delete all response"); 1086 1087 retval = wmi_unified_register_event_handler( 1088 wmi_handle, 1089 wmi_pdev_multi_vdev_restart_response_event_id, 1090 target_if_vdev_mgr_multi_vdev_restart_resp_handler, 1091 VDEV_RSP_RX_CTX); 1092 if (QDF_IS_STATUS_ERROR(retval)) 1093 mlme_err("failed to register for multivdev restart response"); 1094 1095 if (wmi_service_enabled(wmi_handle, wmi_service_beacon_offload)) { 1096 retval = wmi_unified_register_event_handler( 1097 wmi_handle, 1098 wmi_pdev_csa_switch_count_status_event_id, 1099 target_if_pdev_csa_status_event_handler, 1100 VDEV_RSP_RX_CTX); 1101 if (QDF_IS_STATUS_ERROR(retval)) 1102 mlme_err("failed to register for csa event handler"); 1103 } 1104 1105 target_if_register_set_mac_addr_evt_cbk(wmi_handle); 1106 1107 target_if_register_quiet_offload_event(wmi_handle); 1108 1109 return retval; 1110 } 1111 1112 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister( 1113 struct wlan_objmgr_psoc *psoc) 1114 { 1115 struct wmi_unified *wmi_handle; 1116 1117 if (!psoc) { 1118 mlme_err("PSOC is NULL"); 1119 return QDF_STATUS_E_INVAL; 1120 } 1121 1122 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 1123 if (!wmi_handle) { 1124 mlme_err("wmi_handle is null"); 1125 return QDF_STATUS_E_INVAL; 1126 } 1127 1128 target_if_unregister_quiet_offload_event(wmi_handle); 1129 1130 target_if_unregister_set_mac_addr_evt_cbk(wmi_handle); 1131 1132 wmi_unified_unregister_event_handler( 1133 wmi_handle, 1134 wmi_pdev_multi_vdev_restart_response_event_id); 1135 1136 wmi_unified_unregister_event_handler( 1137 wmi_handle, 1138 wmi_peer_delete_all_response_event_id); 1139 1140 wmi_unified_unregister_event_handler(wmi_handle, 1141 wmi_vdev_start_resp_event_id); 1142 1143 wmi_unified_unregister_event_handler(wmi_handle, 1144 wmi_vdev_delete_resp_event_id); 1145 1146 wmi_unified_unregister_event_handler(wmi_handle, 1147 wmi_vdev_stopped_event_id); 1148 1149 return QDF_STATUS_SUCCESS; 1150 } 1151