1 /* 2 * Copyright (c) 2019 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 void target_if_vdev_mgr_rsp_timer_cb(void *arg) 36 { 37 struct wlan_objmgr_vdev *vdev = arg; 38 struct wlan_objmgr_psoc *psoc; 39 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 40 struct vdev_response_timer *vdev_rsp; 41 struct crash_inject param; 42 struct wmi_unified *wmi_handle; 43 struct vdev_start_response start_rsp = {0}; 44 struct vdev_stop_response stop_rsp = {0}; 45 struct vdev_delete_response del_rsp = {0}; 46 struct peer_delete_all_response peer_del_all_rsp = {0}; 47 uint8_t vdev_id; 48 uint16_t rsp_pos = RESPONSE_BIT_MAX; 49 50 vdev_id = wlan_vdev_get_id(vdev); 51 mlme_debug("Response timer expired for VDEV %d", vdev_id); 52 53 psoc = wlan_vdev_get_psoc(vdev); 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->vdev_mgr_get_response_timer_info) { 61 mlme_err("No Rx Ops"); 62 return; 63 } 64 65 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 66 if (!qdf_atomic_test_bit(START_RESPONSE_BIT, &vdev_rsp->rsp_status) && 67 !qdf_atomic_test_bit(RESTART_RESPONSE_BIT, &vdev_rsp->rsp_status) && 68 !qdf_atomic_test_bit(STOP_RESPONSE_BIT, &vdev_rsp->rsp_status) && 69 !qdf_atomic_test_bit(DELETE_RESPONSE_BIT, &vdev_rsp->rsp_status) && 70 !qdf_atomic_test_bit( 71 PEER_DELETE_ALL_RESPONSE_BIT, 72 &vdev_rsp->rsp_status)) { 73 mlme_debug("No response bit is set, ignoring actions"); 74 return; 75 } 76 77 vdev_rsp->timer_status = QDF_STATUS_E_TIMEOUT; 78 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 79 &vdev_rsp->rsp_status) || 80 qdf_atomic_test_bit(RESTART_RESPONSE_BIT, 81 &vdev_rsp->rsp_status)) { 82 start_rsp.vdev_id = wlan_vdev_get_id(vdev); 83 start_rsp.status = WLAN_MLME_HOST_VDEV_START_TIMEOUT; 84 if (qdf_atomic_test_bit(START_RESPONSE_BIT, 85 &vdev_rsp->rsp_status)) { 86 start_rsp.resp_type = 87 WMI_HOST_VDEV_START_RESP_EVENT; 88 rsp_pos = START_RESPONSE_BIT; 89 } else { 90 start_rsp.resp_type = 91 WMI_HOST_VDEV_RESTART_RESP_EVENT; 92 rsp_pos = RESTART_RESPONSE_BIT; 93 } 94 95 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, rsp_pos); 96 97 rx_ops->vdev_mgr_start_response(psoc, &start_rsp); 98 } else if (qdf_atomic_test_bit(STOP_RESPONSE_BIT, 99 &vdev_rsp->rsp_status)) { 100 rsp_pos = STOP_RESPONSE_BIT; 101 stop_rsp.vdev_id = wlan_vdev_get_id(vdev); 102 103 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, rsp_pos); 104 105 rx_ops->vdev_mgr_stop_response(psoc, &stop_rsp); 106 } else if (qdf_atomic_test_bit(DELETE_RESPONSE_BIT, 107 &vdev_rsp->rsp_status)) { 108 del_rsp.vdev_id = wlan_vdev_get_id(vdev); 109 rsp_pos = DELETE_RESPONSE_BIT; 110 111 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, rsp_pos); 112 113 rx_ops->vdev_mgr_delete_response(psoc, &del_rsp); 114 } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, 115 &vdev_rsp->rsp_status)) { 116 peer_del_all_rsp.vdev_id = wlan_vdev_get_id(vdev); 117 rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; 118 119 target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, rsp_pos); 120 121 rx_ops->vdev_mgr_peer_delete_all_response( 122 psoc, 123 &peer_del_all_rsp); 124 } else { 125 mlme_err("PSOC_%d VDEV_%d: Unknown error", 126 wlan_psoc_get_id(psoc), vdev_id); 127 return; 128 } 129 130 if (!target_if_vdev_mgr_is_panic_allowed()) { 131 mlme_debug("PSOC_%d VDEV_%d: Panic not allowed", 132 wlan_psoc_get_id(psoc), vdev_id); 133 return; 134 } 135 136 /* Trigger fw recovery to collect fw dump */ 137 wmi_handle = target_if_vdev_mgr_wmi_handle_get(vdev); 138 if (wmi_handle) { 139 mlme_err("PSOC_%d VDEV_%d: Self recovery, %s rsp timeout", 140 wlan_psoc_get_id(psoc), vdev_id, 141 string_from_rsp_bit(rsp_pos)); 142 qdf_mem_set(¶m, sizeof(param), 0); 143 /* RECOVERY_SIM_ASSERT */ 144 param.type = 0x01; 145 wmi_crash_inject(wmi_handle, ¶m); 146 } else if (target_if_vdev_mgr_is_panic_on_bug()) { 147 QDF_DEBUG_PANIC("PSOC_%d VDEV_%d: Panic, %s response timeout", 148 wlan_psoc_get_id(psoc), 149 vdev_id, string_from_rsp_bit(rsp_pos)); 150 } 151 } 152 153 void target_if_timer_flush_handler(struct wlan_objmgr_pdev *pdev, 154 void *object, 155 void *arg) 156 { 157 struct vdev_response_timer *vdev_rsp; 158 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 159 struct wlan_objmgr_psoc *psoc; 160 struct wlan_objmgr_vdev *vdev = object; 161 162 psoc = wlan_pdev_get_psoc(pdev); 163 if (!psoc) { 164 mlme_err("PSOC is NULL"); 165 return; 166 } 167 168 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 169 if (!rx_ops || !rx_ops->vdev_mgr_get_response_timer_info) { 170 mlme_err("No Rx Ops"); 171 return; 172 } 173 174 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 175 if (qdf_timer_sync_cancel(&vdev_rsp->rsp_timer)) 176 target_if_vdev_mgr_rsp_timer_cb(vdev); 177 } 178 179 void target_if_flush_vdev_timers(struct wlan_objmgr_pdev *pdev) 180 { 181 wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, 182 target_if_timer_flush_handler, 183 NULL, true, WLAN_VDEV_TARGET_IF_ID); 184 } 185 186 #ifdef SERIALIZE_VDEV_RESP_TIMER 187 static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg) 188 { 189 struct wlan_objmgr_vdev *vdev = msg->bodyptr; 190 191 if (vdev) 192 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 193 194 return QDF_STATUS_SUCCESS; 195 } 196 197 static void 198 target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg) 199 { 200 struct scheduler_msg msg = {0}; 201 struct wlan_objmgr_vdev *vdev = arg; 202 203 msg.type = SYS_MSG_ID_MC_TIMER; 204 msg.reserved = SYS_MSG_COOKIE; 205 msg.callback = target_if_vdev_mgr_rsp_timer_cb; 206 msg.bodyptr = arg; 207 msg.bodyval = 0; 208 msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb; 209 210 if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF, 211 QDF_MODULE_ID_TARGET_IF, 212 QDF_MODULE_ID_SYS, &msg) == 213 QDF_STATUS_SUCCESS) 214 return; 215 216 mlme_err("Could not enqueue timer to timer queue"); 217 if (vdev) 218 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 219 } 220 221 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 222 { 223 target_if_vdev_mgr_rsp_cb_mc_ctx(arg); 224 } 225 #else 226 void target_if_vdev_mgr_rsp_timer_mgmt_cb(void *arg) 227 { 228 target_if_vdev_mgr_rsp_timer_cb(arg); 229 } 230 #endif 231 232 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 struct vdev_response_timer *vdev_rsp; 243 struct wlan_objmgr_vdev *vdev; 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 = wlan_objmgr_get_vdev_by_id_from_psoc( 274 psoc, 275 vdev_start_resp.vdev_id, 276 WLAN_VDEV_TARGET_IF_ID); 277 if (!vdev) { 278 mlme_err("PSOC_%d :VDEV_%d is NULL", psoc->soc_objmgr.psoc_id, 279 vdev_start_resp.vdev_id); 280 return -EINVAL; 281 } 282 283 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 284 if (!vdev_rsp) { 285 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 286 psoc->soc_objmgr.psoc_id, vdev_start_resp.vdev_id); 287 goto release_vdev_target_if_ref; 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 vdev, vdev_rsp, 293 RESTART_RESPONSE_BIT); 294 else 295 status = target_if_vdev_mgr_rsp_timer_stop(vdev, 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_start_resp.vdev_id); 301 goto release_vdev_target_if_ref; 302 } 303 304 rsp.vdev_id = vdev_start_resp.vdev_id; 305 rsp.requestor_id = vdev_start_resp.requestor_id; 306 rsp.status = vdev_start_resp.status; 307 rsp.resp_type = vdev_start_resp.resp_type; 308 rsp.chain_mask = vdev_start_resp.chain_mask; 309 rsp.smps_mode = vdev_start_resp.smps_mode; 310 rsp.mac_id = vdev_start_resp.mac_id; 311 rsp.cfgd_tx_streams = vdev_start_resp.cfgd_tx_streams; 312 rsp.cfgd_rx_streams = vdev_start_resp.cfgd_rx_streams; 313 314 status = rx_ops->vdev_mgr_start_response(psoc, &rsp); 315 316 release_vdev_target_if_ref: 317 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 318 return qdf_status_to_os_return(status); 319 } 320 321 int target_if_vdev_mgr_stop_response_handler(ol_scn_t scn, 322 uint8_t *data, 323 uint32_t datalen) 324 { 325 QDF_STATUS status = QDF_STATUS_E_INVAL; 326 struct wlan_objmgr_psoc *psoc; 327 struct wmi_unified *wmi_handle; 328 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 329 struct vdev_stop_response rsp = {0}; 330 uint32_t vdev_id; 331 struct vdev_response_timer *vdev_rsp; 332 struct wlan_objmgr_vdev *vdev; 333 334 if (!scn || !data) { 335 mlme_err("Invalid input"); 336 return -EINVAL; 337 } 338 339 psoc = target_if_get_psoc_from_scn_hdl(scn); 340 if (!psoc) { 341 mlme_err("PSOC is NULL"); 342 return -EINVAL; 343 } 344 345 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 346 if (!rx_ops || !rx_ops->vdev_mgr_stop_response) { 347 mlme_err("No Rx Ops"); 348 return -EINVAL; 349 } 350 351 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 352 if (!wmi_handle) { 353 mlme_err("wmi_handle is null"); 354 return -EINVAL; 355 } 356 357 if (wmi_extract_vdev_stopped_param(wmi_handle, data, &vdev_id)) { 358 mlme_err("WMI extract failed"); 359 return -EINVAL; 360 } 361 362 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 363 psoc, 364 vdev_id, 365 WLAN_VDEV_TARGET_IF_ID); 366 if (!vdev) { 367 mlme_err("PSOC_%d: VDEV_%d is NULL", psoc->soc_objmgr.psoc_id, 368 vdev_id); 369 return -EINVAL; 370 } 371 372 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 373 if (!vdev_rsp) { 374 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 375 psoc->soc_objmgr.psoc_id, vdev_id); 376 goto release_vdev_target_if_ref; 377 } 378 379 status = target_if_vdev_mgr_rsp_timer_stop(vdev, vdev_rsp, 380 STOP_RESPONSE_BIT); 381 382 if (QDF_IS_STATUS_ERROR(status)) { 383 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 384 psoc->soc_objmgr.psoc_id, vdev_id); 385 goto release_vdev_target_if_ref; 386 } 387 388 rsp.vdev_id = vdev_id; 389 status = rx_ops->vdev_mgr_stop_response(psoc, &rsp); 390 391 release_vdev_target_if_ref: 392 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 393 return qdf_status_to_os_return(status); 394 } 395 396 int target_if_vdev_mgr_delete_response_handler(ol_scn_t scn, 397 uint8_t *data, 398 uint32_t datalen) 399 { 400 QDF_STATUS status = QDF_STATUS_E_INVAL; 401 struct wlan_objmgr_psoc *psoc; 402 struct wmi_unified *wmi_handle; 403 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 404 struct vdev_delete_response rsp = {0}; 405 struct wmi_host_vdev_delete_resp vdev_del_resp; 406 struct vdev_response_timer *vdev_rsp; 407 struct wlan_objmgr_vdev *vdev; 408 409 if (!scn || !data) { 410 mlme_err("Invalid input"); 411 return -EINVAL; 412 } 413 414 psoc = target_if_get_psoc_from_scn_hdl(scn); 415 if (!psoc) { 416 mlme_err("PSOC is NULL"); 417 return -EINVAL; 418 } 419 420 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 421 if (!rx_ops || !rx_ops->vdev_mgr_delete_response) { 422 mlme_err("No Rx Ops"); 423 return -EINVAL; 424 } 425 426 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 427 if (!wmi_handle) { 428 mlme_err("wmi_handle is null"); 429 return -EINVAL; 430 } 431 432 if (wmi_extract_vdev_delete_resp(wmi_handle, data, &vdev_del_resp)) { 433 mlme_err("WMI extract failed"); 434 return -EINVAL; 435 } 436 437 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 438 psoc, 439 vdev_del_resp.vdev_id, 440 WLAN_VDEV_TARGET_IF_ID); 441 if (!vdev) { 442 mlme_err("PSOC_%d: VDEV_%d is NULL", psoc->soc_objmgr.psoc_id, 443 vdev_del_resp.vdev_id); 444 return -EINVAL; 445 } 446 447 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 448 if (!vdev_rsp) { 449 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 450 psoc->soc_objmgr.psoc_id, vdev_del_resp.vdev_id); 451 goto release_vdev_target_if_ref; 452 } 453 454 status = target_if_vdev_mgr_rsp_timer_stop( 455 vdev, vdev_rsp, 456 DELETE_RESPONSE_BIT); 457 458 if (QDF_IS_STATUS_ERROR(status)) { 459 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 460 psoc->soc_objmgr.psoc_id, vdev_del_resp.vdev_id); 461 goto release_vdev_target_if_ref; 462 } 463 464 rsp.vdev_id = vdev_del_resp.vdev_id; 465 status = rx_ops->vdev_mgr_delete_response(psoc, &rsp); 466 467 release_vdev_target_if_ref: 468 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 469 return qdf_status_to_os_return(status); 470 } 471 472 static int target_if_vdev_mgr_peer_delete_all_response_handler( 473 ol_scn_t scn, 474 uint8_t *data, 475 uint32_t datalen) 476 { 477 QDF_STATUS status = QDF_STATUS_E_INVAL; 478 struct wlan_objmgr_psoc *psoc; 479 struct wmi_unified *wmi_handle; 480 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 481 struct peer_delete_all_response rsp = {0}; 482 struct wmi_host_vdev_peer_delete_all_response_event 483 vdev_peer_del_all_resp; 484 struct vdev_response_timer *vdev_rsp; 485 struct wlan_objmgr_vdev *vdev; 486 487 if (!scn || !data) { 488 mlme_err("Invalid input"); 489 return -EINVAL; 490 } 491 492 psoc = target_if_get_psoc_from_scn_hdl(scn); 493 if (!psoc) { 494 mlme_err("PSOC is NULL"); 495 return -EINVAL; 496 } 497 498 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 499 if (!rx_ops || !rx_ops->vdev_mgr_peer_delete_all_response) { 500 mlme_err("No Rx Ops"); 501 return -EINVAL; 502 } 503 504 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 505 if (!wmi_handle) { 506 mlme_err("wmi_handle is null"); 507 return -EINVAL; 508 } 509 510 if (wmi_extract_vdev_peer_delete_all_response_event( 511 wmi_handle, data, 512 &vdev_peer_del_all_resp)) { 513 mlme_err("WMI extract failed"); 514 return -EINVAL; 515 } 516 517 vdev = wlan_objmgr_get_vdev_by_id_from_psoc( 518 psoc, 519 vdev_peer_del_all_resp.vdev_id, 520 WLAN_VDEV_TARGET_IF_ID); 521 if (!vdev) { 522 mlme_err("PSOC_%d: VDEV_%d is NULL", psoc->soc_objmgr.psoc_id, 523 vdev_peer_del_all_resp.vdev_id); 524 return -EINVAL; 525 } 526 527 vdev_rsp = rx_ops->vdev_mgr_get_response_timer_info(vdev); 528 if (!vdev_rsp) { 529 mlme_err("PSOC_%d VDEV_%d: VDEV RSP is NULL", 530 psoc->soc_objmgr.psoc_id, 531 vdev_peer_del_all_resp.vdev_id); 532 goto release_vdev_target_if_ref; 533 } 534 535 status = target_if_vdev_mgr_rsp_timer_stop( 536 vdev, vdev_rsp, 537 PEER_DELETE_ALL_RESPONSE_BIT); 538 539 if (QDF_IS_STATUS_ERROR(status)) { 540 mlme_err("PSOC_%d VDEV_%d: VDE MGR RSP Timer stop failed", 541 psoc->soc_objmgr.psoc_id, 542 vdev_peer_del_all_resp.vdev_id); 543 goto release_vdev_target_if_ref; 544 } 545 546 rsp.vdev_id = vdev_peer_del_all_resp.vdev_id; 547 rsp.status = vdev_peer_del_all_resp.status; 548 status = rx_ops->vdev_mgr_peer_delete_all_response(psoc, &rsp); 549 550 release_vdev_target_if_ref: 551 wlan_objmgr_vdev_release_ref(vdev, WLAN_VDEV_TARGET_IF_ID); 552 return qdf_status_to_os_return(status); 553 } 554 555 int target_if_vdev_mgr_offload_bcn_tx_status_handler( 556 ol_scn_t scn, 557 uint8_t *data, 558 uint32_t datalen) 559 { 560 QDF_STATUS status; 561 struct wlan_objmgr_psoc *psoc; 562 struct wmi_unified *wmi_handle; 563 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 564 uint32_t vdev_id, tx_status; 565 566 if (!scn || !data) { 567 mlme_err("Invalid input"); 568 return -EINVAL; 569 } 570 psoc = target_if_get_psoc_from_scn_hdl(scn); 571 if (!psoc) { 572 mlme_err("PSOC is NULL"); 573 return -EINVAL; 574 } 575 576 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 577 if (!rx_ops || !rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle) { 578 mlme_err("No Rx Ops"); 579 return -EINVAL; 580 } 581 582 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 583 if (!wmi_handle) { 584 mlme_err("wmi_handle is null"); 585 return -EINVAL; 586 } 587 588 if (wmi_extract_offload_bcn_tx_status_evt(wmi_handle, data, 589 &vdev_id, &tx_status)) { 590 mlme_err("WMI extract failed"); 591 return -EINVAL; 592 } 593 594 status = rx_ops->vdev_mgr_offload_bcn_tx_status_event_handle( 595 vdev_id, 596 tx_status); 597 598 return qdf_status_to_os_return(status); 599 } 600 601 int target_if_vdev_mgr_tbttoffset_update_handler( 602 ol_scn_t scn, uint8_t *data, 603 uint32_t datalen) 604 { 605 QDF_STATUS status; 606 struct wlan_objmgr_psoc *psoc; 607 struct wmi_unified *wmi_handle; 608 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 609 uint32_t num_vdevs = 0; 610 611 if (!scn || !data) { 612 mlme_err("Invalid input"); 613 return -EINVAL; 614 } 615 psoc = target_if_get_psoc_from_scn_hdl(scn); 616 if (!psoc) { 617 mlme_err("PSOC is NULL"); 618 return -EINVAL; 619 } 620 621 rx_ops = target_if_vdev_mgr_get_rx_ops(psoc); 622 if (!rx_ops || !rx_ops->vdev_mgr_tbttoffset_update_handle) { 623 mlme_err("No Rx Ops"); 624 return -EINVAL; 625 } 626 627 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 628 if (!wmi_handle) { 629 mlme_err("wmi_handle is null"); 630 return -EINVAL; 631 } 632 633 if (wmi_extract_tbttoffset_num_vdevs(wmi_handle, data, &num_vdevs)) { 634 mlme_err("WMI extract failed"); 635 return -EINVAL; 636 } 637 638 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 639 false); 640 641 return qdf_status_to_os_return(status); 642 } 643 644 int target_if_vdev_mgr_ext_tbttoffset_update_handler( 645 ol_scn_t scn, 646 uint8_t *data, 647 uint32_t datalen) 648 { 649 QDF_STATUS status; 650 struct wlan_objmgr_psoc *psoc; 651 struct wmi_unified *wmi_handle; 652 struct wlan_lmac_if_mlme_rx_ops *rx_ops; 653 uint32_t num_vdevs = 0; 654 655 if (!scn || !data) { 656 mlme_err("Invalid input"); 657 return -EINVAL; 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_tbttoffset_update_handle) { 667 mlme_err("No Rx Ops"); 668 return -EINVAL; 669 } 670 671 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 672 if (!wmi_handle) { 673 mlme_err("wmi_handle is null"); 674 return -EINVAL; 675 } 676 677 if (wmi_extract_ext_tbttoffset_num_vdevs(wmi_handle, data, 678 &num_vdevs)) { 679 mlme_err("WMI extract failed"); 680 return -EINVAL; 681 } 682 683 status = rx_ops->vdev_mgr_tbttoffset_update_handle(num_vdevs, 684 true); 685 686 return qdf_status_to_os_return(status); 687 } 688 689 QDF_STATUS target_if_vdev_mgr_wmi_event_register( 690 struct wlan_objmgr_psoc *psoc) 691 { 692 int retval = 0; 693 struct wmi_unified *wmi_handle; 694 695 if (!psoc) { 696 mlme_err("PSOC is NULL"); 697 return QDF_STATUS_E_NULL_VALUE; 698 } 699 700 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 701 if (!wmi_handle) { 702 mlme_err("wmi_handle is null"); 703 return QDF_STATUS_E_INVAL; 704 } 705 706 retval = wmi_unified_register_event_handler( 707 wmi_handle, 708 wmi_vdev_stopped_event_id, 709 target_if_vdev_mgr_stop_response_handler, 710 WMI_RX_UMAC_CTX); 711 if (retval) 712 mlme_err("failed to register for stop response"); 713 714 retval = wmi_unified_register_event_handler( 715 wmi_handle, 716 wmi_vdev_delete_resp_event_id, 717 target_if_vdev_mgr_delete_response_handler, 718 WMI_RX_UMAC_CTX); 719 if (retval) 720 mlme_err("failed to register for delete response"); 721 722 retval = wmi_unified_register_event_handler( 723 wmi_handle, 724 wmi_vdev_start_resp_event_id, 725 target_if_vdev_mgr_start_response_handler, 726 WMI_RX_UMAC_CTX); 727 if (retval) 728 mlme_err("failed to register for start response"); 729 730 retval = wmi_unified_register_event_handler( 731 wmi_handle, 732 wmi_peer_delete_all_response_event_id, 733 target_if_vdev_mgr_peer_delete_all_response_handler, 734 WMI_RX_UMAC_CTX); 735 if (retval) 736 mlme_err("failed to register for peer delete all response"); 737 738 return qdf_status_from_os_return(retval); 739 } 740 741 QDF_STATUS target_if_vdev_mgr_wmi_event_unregister( 742 struct wlan_objmgr_psoc *psoc) 743 { 744 struct wmi_unified *wmi_handle; 745 746 if (!psoc) { 747 mlme_err("PSOC is NULL"); 748 return QDF_STATUS_E_INVAL; 749 } 750 751 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 752 if (!wmi_handle) { 753 mlme_err("wmi_handle is null"); 754 return QDF_STATUS_E_INVAL; 755 } 756 757 wmi_unified_unregister_event_handler(wmi_handle, 758 wmi_vdev_stopped_event_id); 759 760 wmi_unified_unregister_event_handler(wmi_handle, 761 wmi_vdev_delete_resp_event_id); 762 763 wmi_unified_unregister_event_handler(wmi_handle, 764 wmi_vdev_start_resp_event_id); 765 766 wmi_unified_unregister_event_handler( 767 wmi_handle, 768 wmi_peer_delete_all_response_event_id); 769 return QDF_STATUS_SUCCESS; 770 } 771