1 /* 2 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: target_if_vdev_mgr_rx_ops.c 21 * 22 * This file provide definition for APIs registered through events received 23 * from FW 24 */ 25 #include <target_if_vdev_mgr_rx_ops.h> 26 #include <target_if_vdev_mgr_tx_ops.h> 27 #include <wlan_vdev_mgr_tgt_if_rx_defs.h> 28 #include <wlan_vdev_mgr_tgt_if_tx_defs.h> 29 #include <wmi_unified_param.h> 30 #include <wlan_mlme_dbg.h> 31 #include <target_if.h> 32 #include <wlan_vdev_mlme_main.h> 33 #include <wmi_unified_vdev_api.h> 34 35 void target_if_vdev_mgr_rsp_timer_cb(struct vdev_response_timer *vdev_rsp) 36 { 37 struct wlan_objmgr_psoc *psoc; 38 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 39 struct crash_inject param; 40 struct wmi_unified *wmi_handle; 41 struct vdev_start_response start_rsp = {0}; 42 struct vdev_stop_response stop_rsp = {0}; 43 struct vdev_delete_response del_rsp = {0}; 44 struct peer_delete_all_response peer_del_all_rsp = {0}; 45 uint8_t vdev_id; 46 uint16_t rsp_pos = RESPONSE_BIT_MAX; 47 48 if (!vdev_rsp) { 49 mlme_err("Vdev response timer is NULL"); 50 return; 51 } 52 53 psoc = vdev_rsp->psoc; 54 if (!psoc) { 55 mlme_err("PSOC is NULL"); 56 return; 57 } 58 59 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 60 if (!rx_ops || !rx_ops->psoc_get_vdev_response_timer_info) { 61 mlme_err("No Rx Ops"); 62 return; 63 } 64 65 if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) && 66 !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) && 67 !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) && 68 !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) && 69 !qdf_atomic_test_bit( 70 PEER_DELETE_ALL_RESPONSE_BIT, 71 &vdev_rsp->rsp_status)) { 72 mlme_debug("No response bit is set, ignoring actions :%d", 73 vdev_rsp->vdev_id); 74 return; 75 } 76 77 vdev_id = vdev_rsp->vdev_id; 78 if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { 79 mlme_err("Invalid VDEV_%d PSOC_%d", vdev_id, 80 wlan_psoc_get_id(psoc)); 81 return; 82 } 83 84 vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT; 85 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 86 &vdev_rsp->rsp_status) || 87 qdf_atomic_test_bit(RESTART_RESPONSE_BIT, 88 &vdev_rsp->rsp_status)) { 89 start_rsp.vdev_id = vdev_id; 90 start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT; 91 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 92 &vdev_rsp->rsp_status)) { 93 start_rsp.resp_type = 94 WMI_HOST_VDEV_START_RESP_EVENT; 95 rsp_pos = START_RESPONSE_BIT; 96 } else { 97 start_rsp.resp_type = 98 WMI_HOST_VDEV_RESTART_RESP_EVENT; 99 rsp_pos = RESTART_RESPONSE_BIT; 100 } 101 102 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 103 104 rx_ops->vdev_mgr_start_response(psoc, &start_rsp); 105 } else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT, 106 &vdev_rsp->rsp_status)) { 107 rsp_pos = STOP_RESPONSE_BIT; 108 stop_rsp.vdev_id = vdev_id; 109 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 110 111 rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp); 112 } else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT, 113 &vdev_rsp->rsp_status)) { 114 del_rsp.vdev_id = vdev_id; 115 rsp_pos = DELETE_RESPONSE_BIT; 116 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 117 118 rx_ops->vdev_mgr_delete_response(psoc, &del_rsp); 119 } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, 120 &vdev_rsp->rsp_status)) { 121 peer_del_all_rsp.vdev_id = vdev_id; 122 rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; 123 target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); 124 125 rx_ops->vdev_mgr_peer_delete_all_response( 126 psoc, 127 &peer_del_all_rsp); 128 } else { 129 mlme_err("PSOC_%d VDEV_%d: Unknown error", 130 wlan_psoc_get_id(psoc), vdev_id); 131 return; 132 } 133 134 if (!target_if_vdev_mgr_is_panic_allowed()) { 135 mlme_debug("PSOC_%d VDEV_%d: Panic not allowed", 136 wlan_psoc_get_id(psoc), vdev_id); 137 return; 138 } 139 140 /* Trigger fw recovery to collect fw dump */ 141 wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); 142 if (wmi_handle) { 143 mlme_err("PSOC_%d VDEV_%d: Self recovery, %s rsp timeout", 144 wlan_psoc_get_id(psoc), vdev_id, 145 string_from_rsp_bit(rsp_pos)); 146 qdf_mem_set(¶m, sizeof(param), 0); 147 /* RECOVERY_SIM_ASSERT */ 148 param.type = 0x01; 149 wmi_crash_inject(wmi_handle, ¶m); 150 } else if (target_if_vdev_mgr_is_panic_on_bug()) { 151 QDF_DEBUG_PANIC("PSOC_%d VDEV_%d: Panic, %s response timeout", 152 wlan_psoc_get_id(psoc), 153 vdev_id, string_from_rsp_bit(rsp_pos)); 154 } 155 } 156 157 #ifdef SERIALIZE_VDEV_RESP 158 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg) 159 { 160 struct vdev_response_timer *vdev_rsp; 161 struct wlan_objmgr_psoc *psoc; 162 163 if (!msg->bodyptr) { 164 mlme_err("Message bodyptr is NULL"); 165 return QDF_STATUS_E_INVAL; 166 } 167 168 vdev_rsp = msg->bodyptr; 169 if (!vdev_rsp) { 170 mlme_err("vdev response timer is NULL"); 171 return QDF_STATUS_E_INVAL; 172 } 173 174 psoc = vdev_rsp->psoc; 175 if (!psoc) { 176 mlme_err("PSOC is NULL"); 177 return QDF_STATUS_E_INVAL; 178 } 179 180 if (vdev_rsp->rsp_status) 181 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); 182 183 return QDF_STATUS_SUCCESS; 184 } 185 186 static void 187 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg) 188 { 189 struct scheduler_msg msg = {0}; 190 struct vdev_response_timer *vdev_rsp = arg; 191 struct wlan_objmgr_psoc *psoc; 192 193 psoc = vdev_rsp->psoc; 194 if (!psoc) { 195 mlme_err("PSOC is NULL"); 196 return; 197 } 198 199 msg.type = SYS_MSG_ID_MC_TIMER; 200 msg.reserved = SYS_MSG_COOKIE; 201 msg.callback = target_if_vdev_mgr_rsp_timer_cb; 202 msg.bodyptr = vdev_rsp; 203 msg.bodyval = 0; 204 msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb; 205 206 if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF, 207 QDF_MODULE_ID_TARGET_IF, 208 QDF_MODULE_ID_SYS, &msg) == 209 QDF_STATUS_SUCCESS) 210 return; 211 212 mlme_err("Could not enqueue timer to timer queue"); 213 if (psoc) 214 wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID); 215 } 216 217 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 218 { 219 target_if_vdev_mgr_rsp_cb_mc_ctx(arg); 220 } 221 222 #define VDEV_RSP_RX_CTX WMI_RX_SERIALIZER_CTX 223 #else 224 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 225 { 226 target_if_vdev_mgr_rsp_timer_cb(arg); 227 } 228 229 #define VDEV_RSP_RX_CTX WMI_RX_UMAC_CTX 230 #endif 231 232 static int target_if_vdev_mgr_start_response_handler(ol_scn_t scn, 233 uint8_t *data, 234 uint32_t datalen) 235 { 236 QDF_STATUS status = QDF_STATUS_E_INVAL; 237 struct wlan_objmgr_psoc *psoc; 238 struct wmi_unified *wmi_handle; 239 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 240 struct vdev_start_response rsp = {0}; 241 wmi_host_vdev_start_resp vdev_start_resp; 242 uint8_t vdev_id; 243 struct vdev_response_timer *vdev_rsp; 244 245 if (!scn || !data) { 246 mlme_err("Invalid input"); 247 return -EINVAL; 248 } 249 250 psoc = target_if_get_psoc_from_scn_hdl(scn); 251 if (!psoc) { 252 mlme_err("PSOC is NULL"); 253 return -EINVAL; 254 } 255 256 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 257 if (!rx_ops || !rx_ops->vdev_mgr_start_response) { 258 mlme_err("No Rx Ops"); 259 return -EINVAL; 260 } 261 262 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 263 if (!wmi_handle) { 264 mlme_err("wmi_handle is null"); 265 return -EINVAL; 266 } 267 268 if (wmi_extract_vdev_start_resp(wmi_handle, data, &vdev_start_resp)) { 269 mlme_err("WMI extract failed"); 270 return -EINVAL; 271 } 272 273 vdev_id = vdev_start_resp.vdev_id; 274 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); 275 if (!vdev_rsp) { 276 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 277 vdev_id, wlan_psoc_get_id(psoc)); 278 return -EINVAL; 279 } 280 281 if (vdev_start_resp.resp_type == WMI_HOST_VDEV_RESTART_RESP_EVENT) 282 status = target_if_vdev_mgr_rsp_timer_stop( 283 psoc, vdev_rsp, 284 RESTART_RESPONSE_BIT); 285 else 286 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, 287 START_RESPONSE_BIT); 288 289 if (QDF_IS_STATUS_ERROR(status)) { 290 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 291 psoc->soc_objmgr.psoc_id, vdev_id); 292 goto err; 293 } 294 295 rsp.vdev_id = vdev_start_resp.vdev_id; 296 rsp.requestor_id = vdev_start_resp.requestor_id; 297 rsp.status = vdev_start_resp.status; 298 rsp.resp_type = vdev_start_resp.resp_type; 299 rsp.chain_mask = vdev_start_resp.chain_mask; 300 rsp.smps_mode = vdev_start_resp.smps_mode; 301 rsp.mac_id = vdev_start_resp.mac_id; 302 rsp.cfgd_tx_streams = vdev_start_resp.cfgd_tx_streams; 303 rsp.cfgd_rx_streams = vdev_start_resp.cfgd_rx_streams; 304 305 status = rx_ops->vdev_mgr_start_response(psoc, &rsp); 306 307 err: 308 return qdf_status_to_os_return(status); 309 } 310 311 static int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn, 312 uint8_t *data, 313 uint32_t datalen) 314 { 315 QDF_STATUS status = QDF_STATUS_E_INVAL; 316 struct wlan_objmgr_psoc *psoc; 317 struct wmi_unified *wmi_handle; 318 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 319 struct vdev_stop_response rsp = {0}; 320 uint32_t vdev_id; 321 struct vdev_response_timer *vdev_rsp; 322 323 if (!scn || !data) { 324 mlme_err("Invalid input"); 325 return -EINVAL; 326 } 327 328 psoc = target_if_get_psoc_from_scn_hdl(scn); 329 if (!psoc) { 330 mlme_err("PSOC is NULL"); 331 return -EINVAL; 332 } 333 334 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 335 if (!rx_ops || !rx_ops->vdev_mgr_stop_response) { 336 mlme_err("No Rx Ops"); 337 return -EINVAL; 338 } 339 340 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 341 if (!wmi_handle) { 342 mlme_err("wmi_handle is null"); 343 return -EINVAL; 344 } 345 346 if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) { 347 mlme_err("WMI extract failed"); 348 return -EINVAL; 349 } 350 351 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, vdev_id); 352 if (!vdev_rsp) { 353 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 354 vdev_id, wlan_psoc_get_id(psoc)); 355 return -EINVAL; 356 } 357 358 status = target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, 359 STOP_RESPONSE_BIT); 360 361 if (QDF_IS_STATUS_ERROR(status)) { 362 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 363 psoc->soc_objmgr.psoc_id, vdev_id); 364 goto err; 365 } 366 367 rsp.vdev_id = vdev_id; 368 status = rx_ops->vdev_mgr_stop_response(psoc, &rsp); 369 370 err: 371 return qdf_status_to_os_return(status); 372 } 373 374 static int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn, 375 uint8_t *data, 376 uint32_t datalen) 377 { 378 QDF_STATUS status = QDF_STATUS_E_INVAL; 379 struct wlan_objmgr_psoc *psoc; 380 struct wmi_unified *wmi_handle; 381 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 382 struct vdev_delete_response rsp = {0}; 383 struct wmi_host_vdev_delete_resp vdev_del_resp; 384 struct vdev_response_timer *vdev_rsp; 385 386 if (!scn || !data) { 387 mlme_err("Invalid input"); 388 return -EINVAL; 389 } 390 391 psoc = target_if_get_psoc_from_scn_hdl(scn); 392 if (!psoc) { 393 mlme_err("PSOC is NULL"); 394 return -EINVAL; 395 } 396 397 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 398 if (!rx_ops || !rx_ops->vdev_mgr_delete_response) { 399 mlme_err("No Rx Ops"); 400 return -EINVAL; 401 } 402 403 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 404 if (!wmi_handle) { 405 mlme_err("wmi_handle is null"); 406 return -EINVAL; 407 } 408 409 if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) { 410 mlme_err("WMI extract failed"); 411 return -EINVAL; 412 } 413 414 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 415 vdev_del_resp.vdev_id); 416 if (!vdev_rsp) { 417 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 418 vdev_del_resp.vdev_id, wlan_psoc_get_id(psoc)); 419 return -EINVAL; 420 } 421 422 status = target_if_vdev_mgr_rsp_timer_stop( 423 psoc, vdev_rsp, 424 DELETE_RESPONSE_BIT); 425 426 if (QDF_IS_STATUS_ERROR(status)) { 427 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 428 wlan_psoc_get_id(psoc), vdev_del_resp.vdev_id); 429 goto err; 430 } 431 432 rsp.vdev_id = vdev_del_resp.vdev_id; 433 status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); 434 435 err: 436 return qdf_status_to_os_return(status); 437 } 438 439 static int target_if_vdev_mgr_peer_delete_all_response_handler( 440 ol_scn_t scn, 441 uint8_t *data, 442 uint32_t datalen) 443 { 444 QDF_STATUS status = QDF_STATUS_E_INVAL; 445 struct wlan_objmgr_psoc *psoc; 446 struct wmi_unified *wmi_handle; 447 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 448 struct peer_delete_all_response rsp = {0}; 449 struct wmi_host_vdev_peer_delete_all_response_event 450 vdev_peer_del_all_resp; 451 struct vdev_response_timer *vdev_rsp; 452 453 if (!scn || !data) { 454 mlme_err("Invalid input"); 455 return -EINVAL; 456 } 457 458 psoc = target_if_get_psoc_from_scn_hdl(scn); 459 if (!psoc) { 460 mlme_err("PSOC is NULL"); 461 return -EINVAL; 462 } 463 464 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 465 if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) { 466 mlme_err("No Rx Ops"); 467 return -EINVAL; 468 } 469 470 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 471 if (!wmi_handle) { 472 mlme_err("wmi_handle is null"); 473 return -EINVAL; 474 } 475 476 if (wmi_extract_vdev_peer_delete_all_response_event( 477 wmi_handle, data, 478 &vdev_peer_del_all_resp)) { 479 mlme_err("WMI extract failed"); 480 return -EINVAL; 481 } 482 483 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 484 vdev_peer_del_all_resp.vdev_id); 485 if (!vdev_rsp) { 486 mlme_err("vdev response timer is null VDEV_%d PSOC_%d", 487 vdev_peer_del_all_resp.vdev_id, 488 wlan_psoc_get_id(psoc)); 489 return -EINVAL; 490 } 491 492 status = target_if_vdev_mgr_rsp_timer_stop( 493 psoc, 494 vdev_rsp, 495 PEER_DELETE_ALL_RESPONSE_BIT); 496 497 if (QDF_IS_STATUS_ERROR(status)) { 498 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 499 psoc->soc_objmgr.psoc_id, 500 vdev_peer_del_all_resp.vdev_id); 501 goto err; 502 } 503 504 rsp.vdev_id = vdev_peer_del_all_resp.vdev_id; 505 rsp.status = vdev_peer_del_all_resp.status; 506 status = rx_ops->vdev_mgr_peer_delete_all_response(psoc, &rsp); 507 508 err: 509 return qdf_status_to_os_return(status); 510 } 511 512 int target_if_vdev_mgr_offload_bcn_tx_status_handler( 513 ol_scn_t scn, 514 uint8_t *data, 515 uint32_t datalen) 516 { 517 QDF_STATUS status; 518 struct wlan_objmgr_psoc *psoc; 519 struct wmi_unified *wmi_handle; 520 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 521 uint32_t vdev_id, tx_status; 522 523 if (!scn || !data) { 524 mlme_err("Invalid input"); 525 return -EINVAL; 526 } 527 psoc = target_if_get_psoc_from_scn_hdl(scn); 528 if (!psoc) { 529 mlme_err("PSOC is NULL"); 530 return -EINVAL; 531 } 532 533 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 534 if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) { 535 mlme_err("No Rx Ops"); 536 return -EINVAL; 537 } 538 539 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 540 if (!wmi_handle) { 541 mlme_err("wmi_handle is null"); 542 return -EINVAL; 543 } 544 545 if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data, 546 &vdev_id, &tx_status)) { 547 mlme_err("WMI extract failed"); 548 return -EINVAL; 549 } 550 551 status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle( 552 vdev_id, 553 tx_status); 554 555 return qdf_status_to_os_return(status); 556 } 557 558 int target_if_vdev_mgr_tbttoffset_update_handler( 559 ol_scn_t scn, uint8_t *data, 560 uint32_t datalen) 561 { 562 QDF_STATUS status; 563 struct wlan_objmgr_psoc *psoc; 564 struct wmi_unified *wmi_handle; 565 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 566 uint32_t num_vdevs = 0; 567 568 if (!scn || !data) { 569 mlme_err("Invalid input"); 570 return -EINVAL; 571 } 572 psoc = target_if_get_psoc_from_scn_hdl(scn); 573 if (!psoc) { 574 mlme_err("PSOC is NULL"); 575 return -EINVAL; 576 } 577 578 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 579 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) { 580 mlme_err("No Rx Ops"); 581 return -EINVAL; 582 } 583 584 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 585 if (!wmi_handle) { 586 mlme_err("wmi_handle is null"); 587 return -EINVAL; 588 } 589 590 if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) { 591 mlme_err("WMI extract failed"); 592 return -EINVAL; 593 } 594 595 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 596 false); 597 598 return qdf_status_to_os_return(status); 599 } 600 601 int target_if_vdev_mgr_ext_tbttoffset_update_handler( 602 ol_scn_t scn, 603 uint8_t *data, 604 uint32_t datalen) 605 { 606 QDF_STATUS status; 607 struct wlan_objmgr_psoc *psoc; 608 struct wmi_unified *wmi_handle; 609 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 610 uint32_t num_vdevs = 0; 611 612 if (!scn || !data) { 613 mlme_err("Invalid input"); 614 return -EINVAL; 615 } 616 psoc = target_if_get_psoc_from_scn_hdl(scn); 617 if (!psoc) { 618 mlme_err("PSOC is NULL"); 619 return -EINVAL; 620 } 621 622 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 623 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) { 624 mlme_err("No Rx Ops"); 625 return -EINVAL; 626 } 627 628 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 629 if (!wmi_handle) { 630 mlme_err("wmi_handle is null"); 631 return -EINVAL; 632 } 633 634 if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data, 635 &num_vdevs)) { 636 mlme_err("WMI extract failed"); 637 return -EINVAL; 638 } 639 640 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 641 true); 642 643 return qdf_status_to_os_return(status); 644 } 645 646 static int target_if_vdev_mgr_multi_vdev_restart_resp_handler( 647 ol_scn_t scn, 648 uint8_t *data, 649 uint32_t datalen) 650 { 651 QDF_STATUS status = QDF_STATUS_E_INVAL; 652 struct wlan_objmgr_psoc *psoc; 653 struct wmi_unified *wmi_handle; 654 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 655 struct multi_vdev_restart_resp restart_resp; 656 struct vdev_response_timer *vdev_rsp; 657 uint8_t max_vdevs, vdev_idx; 658 659 if (!scn || !data) { 660 mlme_err("Invalid input"); 661 return -EINVAL; 662 } 663 664 psoc = target_if_get_psoc_from_scn_hdl(scn); 665 if (!psoc) { 666 mlme_err("PSOC is NULL"); 667 return -EINVAL; 668 } 669 670 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 671 if (!rx_ops || !rx_ops->vdev_mgr_multi_vdev_restart_resp || 672 !rx_ops->psoc_get_vdev_response_timer_info) { 673 mlme_err("No Rx Ops"); 674 return -EINVAL; 675 } 676 677 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 678 if (!wmi_handle) { 679 mlme_err("wmi_handle is null"); 680 return -EINVAL; 681 } 682 683 qdf_mem_zero(&restart_resp, sizeof(restart_resp)); 684 if (wmi_extract_multi_vdev_restart_resp_event(wmi_handle, data, 685 &restart_resp)) { 686 mlme_err("WMI extract failed"); 687 return -EINVAL; 688 } 689 690 max_vdevs = wlan_psoc_get_max_vdev_count(psoc); 691 for (vdev_idx = 0; vdev_idx < max_vdevs; vdev_idx++) { 692 if (!qdf_test_bit(vdev_idx, restart_resp.vdev_id_bmap)) 693 continue; 694 695 mlme_debug("PSOC_%d VDEV_%d: Restart resp received", 696 wlan_psoc_get_id(psoc), vdev_idx); 697 vdev_rsp = rx_ops->psoc_get_vdev_response_timer_info(psoc, 698 vdev_idx); 699 if (!vdev_rsp) { 700 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 701 wlan_psoc_get_id(psoc), vdev_idx); 702 continue; 703 } 704 705 status = target_if_vdev_mgr_rsp_timer_stop( 706 psoc, vdev_rsp, RESTART_RESPONSE_BIT); 707 if (QDF_IS_STATUS_ERROR(status)) 708 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 709 wlan_psoc_get_id(psoc), vdev_idx); 710 } 711 712 status = rx_ops->vdev_mgr_multi_vdev_restart_resp(psoc, &restart_resp); 713 714 return qdf_status_to_os_return(status); 715 } 716 717 QDF_STATUS target_if_vdev_mgr_wmi_event_register( 718 struct wlan_objmgr_psoc *psoc) 719 { 720 int retval = 0; 721 struct wmi_unified *wmi_handle; 722 723 if (!psoc) { 724 mlme_err("PSOC is NULL"); 725 return QDF_STATUS_E_NULL_VALUE; 726 } 727 728 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 729 if (!wmi_handle) { 730 mlme_err("wmi_handle is null"); 731 return QDF_STATUS_E_INVAL; 732 } 733 734 retval = wmi_unified_register_event_handler( 735 wmi_handle, 736 wmi_vdev_stopped_event_id, 737 target_if_vdev_mgr_stop_response_handler, 738 VDEV_RSP_RX_CTX); 739 if (retval) 740 mlme_err("failed to register for stop response"); 741 742 retval = wmi_unified_register_event_handler( 743 wmi_handle, 744 wmi_vdev_delete_resp_event_id, 745 target_if_vdev_mgr_delete_response_handler, 746 VDEV_RSP_RX_CTX); 747 if (retval) 748 mlme_err("failed to register for delete response"); 749 750 retval = wmi_unified_register_event_handler( 751 wmi_handle, 752 wmi_vdev_start_resp_event_id, 753 target_if_vdev_mgr_start_response_handler, 754 VDEV_RSP_RX_CTX); 755 if (retval) 756 mlme_err("failed to register for start response"); 757 758 retval = wmi_unified_register_event_handler( 759 wmi_handle, 760 wmi_peer_delete_all_response_event_id, 761 target_if_vdev_mgr_peer_delete_all_response_handler, 762 VDEV_RSP_RX_CTX); 763 if (retval) 764 mlme_err("failed to register for peer delete all response"); 765 766 retval = wmi_unified_register_event_handler( 767 wmi_handle, 768 wmi_pdev_multi_vdev_restart_response_event_id, 769 target_if_vdev_mgr_multi_vdev_restart_resp_handler, 770 VDEV_RSP_RX_CTX); 771 if (retval) 772 mlme_err("failed to register for multivdev restart response"); 773 774 return qdf_status_from_os_return(retval); 775 } 776 777 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister( 778 struct wlan_objmgr_psoc *psoc) 779 { 780 struct wmi_unified *wmi_handle; 781 782 if (!psoc) { 783 mlme_err("PSOC is NULL"); 784 return QDF_STATUS_E_INVAL; 785 } 786 787 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 788 if (!wmi_handle) { 789 mlme_err("wmi_handle is null"); 790 return QDF_STATUS_E_INVAL; 791 } 792 793 wmi_unified_unregister_event_handler( 794 wmi_handle, 795 wmi_pdev_multi_vdev_restart_response_event_id); 796 797 wmi_unified_unregister_event_handler( 798 wmi_handle, 799 wmi_peer_delete_all_response_event_id); 800 801 wmi_unified_unregister_event_handler(wmi_handle, 802 wmi_vdev_start_resp_event_id); 803 804 wmi_unified_unregister_event_handler(wmi_handle, 805 wmi_vdev_delete_resp_event_id); 806 807 wmi_unified_unregister_event_handler(wmi_handle, 808 wmi_vdev_stopped_event_id); 809 810 return QDF_STATUS_SUCCESS; 811 } 812