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