1 /* 2 * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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 /* Include Files */ 21 #include "qdf_delayed_work.h" 22 #include "wlan_ipa_core.h" 23 #include "wlan_ipa_main.h" 24 #include "cdp_txrx_ipa.h" 25 #include "host_diag_core_event.h" 26 #include "wlan_reg_services_api.h" 27 28 QDF_STATUS wlan_ipa_set_perf_level(struct wlan_ipa_priv *ipa_ctx, 29 uint64_t tx_packets, 30 uint64_t rx_packets) 31 { 32 int ret; 33 uint32_t next_bw; 34 uint64_t total_packets = tx_packets + rx_packets; 35 36 if ((!wlan_ipa_is_enabled(ipa_ctx->config)) || 37 (!wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config))) 38 return 0; 39 40 if (total_packets > (ipa_ctx->config->bus_bw_high / 2)) 41 next_bw = ipa_ctx->config->ipa_bw_high; 42 else if (total_packets > (ipa_ctx->config->bus_bw_medium / 2)) 43 next_bw = ipa_ctx->config->ipa_bw_medium; 44 else 45 next_bw = ipa_ctx->config->ipa_bw_low; 46 47 if (ipa_ctx->curr_cons_bw != next_bw) { 48 ipa_debug("Requesting IPA perf curr: %d, next: %d", 49 ipa_ctx->curr_cons_bw, next_bw); 50 ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc, 51 QDF_IPA_CLIENT_WLAN1_CONS, 52 next_bw, ipa_ctx->hdl); 53 if (ret) { 54 ipa_err("RM CONS set perf profile failed: %d", ret); 55 56 return QDF_STATUS_E_FAILURE; 57 } 58 ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc, 59 QDF_IPA_CLIENT_WLAN1_PROD, 60 next_bw, ipa_ctx->hdl); 61 if (ret) { 62 ipa_err("RM PROD set perf profile failed: %d", ret); 63 return QDF_STATUS_E_FAILURE; 64 } 65 ipa_ctx->curr_cons_bw = next_bw; 66 ipa_ctx->stats.num_cons_perf_req++; 67 } 68 69 return QDF_STATUS_SUCCESS; 70 } 71 72 #ifdef QCA_IPA_LL_TX_FLOW_CONTROL 73 static inline 74 QDF_STATUS wlan_ipa_update_perf_level(struct wlan_ipa_priv *ipa_ctx, int client) 75 { 76 struct wlan_objmgr_pdev *pdev = ipa_ctx->pdev; 77 qdf_freq_t low_2g, high_2g; 78 79 wlan_reg_get_freq_range(pdev, &low_2g, &high_2g, NULL, NULL); 80 81 if (low_2g != 0 || high_2g != 0) { 82 return cdp_ipa_set_perf_level( 83 ipa_ctx->dp_soc, 84 client, 85 WLAN_IPA_MAX_BANDWIDTH_2G, ipa_ctx->hdl); 86 } else { 87 return cdp_ipa_set_perf_level( 88 ipa_ctx->dp_soc, 89 client, 90 WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl); 91 } 92 } 93 #else 94 static inline 95 QDF_STATUS wlan_ipa_update_perf_level(struct wlan_ipa_priv *ipa_ctx, int client) 96 { 97 return cdp_ipa_set_perf_level(ipa_ctx->dp_soc, client, 98 WLAN_IPA_MAX_BANDWIDTH, ipa_ctx->hdl); 99 } 100 #endif 101 102 QDF_STATUS wlan_ipa_init_perf_level(struct wlan_ipa_priv *ipa_ctx) 103 { 104 int ret; 105 106 /* Set lowest bandwidth to start with */ 107 if (wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config)) 108 return wlan_ipa_set_perf_level(ipa_ctx, 0, 0); 109 110 ipa_debug("IPA clk scaling disabled. Set perf level to maximum %d", 111 WLAN_IPA_MAX_BANDWIDTH); 112 113 ret = wlan_ipa_update_perf_level(ipa_ctx, QDF_IPA_CLIENT_WLAN1_CONS); 114 if (ret) { 115 ipa_err("CONS set perf profile failed: %d", ret); 116 return QDF_STATUS_E_FAILURE; 117 } 118 119 ret = wlan_ipa_update_perf_level(ipa_ctx, QDF_IPA_CLIENT_WLAN1_PROD); 120 if (ret) { 121 ipa_err("PROD set perf profile failed: %d", ret); 122 return QDF_STATUS_E_FAILURE; 123 } 124 125 return QDF_STATUS_SUCCESS; 126 } 127 128 bool wlan_ipa_set_perf_level_bw_enabled(struct wlan_ipa_priv *ipa_ctx) 129 { 130 /* 131 * Do bandwidth-based IPA perf vote only when all below are met. 132 * a. IPA is enabled. 133 * b. IPA clk scaling is _not_ enabled. 134 * c. IPA force voting is enabled. 135 */ 136 return wlan_ipa_is_enabled(ipa_ctx->config) && 137 !wlan_ipa_is_clk_scaling_enabled(ipa_ctx->config) && 138 ipa_ctx->config->ipa_force_voting; 139 } 140 141 void wlan_ipa_set_perf_level_bw(struct wlan_ipa_priv *ipa_ctx, 142 enum wlan_ipa_bw_level lvl) 143 { 144 uint32_t max_mbps; 145 int ret; 146 147 if (!wlan_ipa_set_perf_level_bw_enabled(ipa_ctx)) 148 return; 149 150 ipa_debug("Set perf level to %d", lvl); 151 152 if (lvl == WLAN_IPA_BW_LEVEL_HIGH) 153 max_mbps = ipa_ctx->config->ipa_bw_high; 154 else if (lvl == WLAN_IPA_BW_LEVEL_MEDIUM) 155 max_mbps = ipa_ctx->config->ipa_bw_medium; 156 else 157 max_mbps = ipa_ctx->config->ipa_bw_low; 158 159 ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc, 160 QDF_IPA_CLIENT_WLAN1_CONS, 161 max_mbps, 162 ipa_ctx->hdl); 163 if (ret) { 164 ipa_err("CONS set perf profile failed: %d", ret); 165 return; 166 } 167 168 ret = cdp_ipa_set_perf_level(ipa_ctx->dp_soc, 169 QDF_IPA_CLIENT_WLAN1_PROD, 170 max_mbps, 171 ipa_ctx->hdl); 172 if (ret) 173 ipa_err("PROD set perf profile failed: %d", ret); 174 } 175 176 #ifdef FEATURE_METERING 177 void wlan_ipa_init_metering(struct wlan_ipa_priv *ipa_ctx) 178 { 179 qdf_event_create(&ipa_ctx->ipa_uc_sharing_stats_comp); 180 qdf_event_create(&ipa_ctx->ipa_uc_set_quota_comp); 181 } 182 #endif 183 184 #ifdef IPA_OPT_WIFI_DP 185 void wlan_ipa_add_rem_flt_cb_event(struct wlan_ipa_priv *ipa_ctx) 186 { 187 qdf_event_create(&ipa_ctx->ipa_flt_evnt); 188 } 189 #endif 190 191 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0)) && \ 192 !defined(CONFIG_IPA_WDI_UNIFIED_API) 193 /** 194 * wlan_ipa_rm_cons_release() - WLAN consumer resource release handler 195 * 196 * Callback function registered with IPA that is called when IPA wants 197 * to release the WLAN consumer resource 198 * 199 * Return: 0 if the request is granted, negative errno otherwise 200 */ 201 static int wlan_ipa_rm_cons_release(void) 202 { 203 return 0; 204 } 205 206 /** 207 * wlan_ipa_wdi_rm_request() - Request resource from IPA 208 * @ipa_ctx: IPA context 209 * 210 * Return: QDF_STATUS 211 */ 212 QDF_STATUS wlan_ipa_wdi_rm_request(struct wlan_ipa_priv *ipa_ctx) 213 { 214 int ret; 215 216 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 217 return QDF_STATUS_SUCCESS; 218 219 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 220 221 switch (ipa_ctx->rm_state) { 222 case WLAN_IPA_RM_GRANTED: 223 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 224 return QDF_STATUS_SUCCESS; 225 case WLAN_IPA_RM_GRANT_PENDING: 226 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 227 return QDF_STATUS_E_PENDING; 228 case WLAN_IPA_RM_RELEASED: 229 ipa_ctx->rm_state = WLAN_IPA_RM_GRANT_PENDING; 230 break; 231 } 232 233 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 234 235 ret = qdf_ipa_rm_inactivity_timer_request_resource( 236 QDF_IPA_RM_RESOURCE_WLAN_PROD); 237 238 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 239 if (ret == 0) { 240 ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED; 241 ipa_ctx->stats.num_rm_grant_imm++; 242 } 243 244 if (ipa_ctx->wake_lock_released) { 245 qdf_wake_lock_acquire(&ipa_ctx->wake_lock, 246 WIFI_POWER_EVENT_WAKELOCK_IPA); 247 ipa_ctx->wake_lock_released = false; 248 } 249 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 250 251 qdf_delayed_work_stop_sync(&ipa_ctx->wake_lock_work); 252 253 return QDF_STATUS_SUCCESS; 254 } 255 256 QDF_STATUS wlan_ipa_wdi_rm_try_release(struct wlan_ipa_priv *ipa_ctx) 257 { 258 int ret; 259 260 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 261 return QDF_STATUS_SUCCESS; 262 263 if (qdf_atomic_read(&ipa_ctx->tx_ref_cnt)) 264 return QDF_STATUS_E_AGAIN; 265 266 qdf_spin_lock_bh(&ipa_ctx->pm_lock); 267 268 if (!qdf_nbuf_is_queue_empty(&ipa_ctx->pm_queue_head)) { 269 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 270 return QDF_STATUS_E_AGAIN; 271 } 272 qdf_spin_unlock_bh(&ipa_ctx->pm_lock); 273 274 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 275 switch (ipa_ctx->rm_state) { 276 case WLAN_IPA_RM_GRANTED: 277 break; 278 case WLAN_IPA_RM_GRANT_PENDING: 279 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 280 return QDF_STATUS_E_PENDING; 281 case WLAN_IPA_RM_RELEASED: 282 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 283 return QDF_STATUS_SUCCESS; 284 } 285 286 /* IPA driver returns immediately so set the state here to avoid any 287 * race condition. 288 */ 289 ipa_ctx->rm_state = WLAN_IPA_RM_RELEASED; 290 ipa_ctx->stats.num_rm_release++; 291 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 292 293 ret = qdf_ipa_rm_inactivity_timer_release_resource( 294 QDF_IPA_RM_RESOURCE_WLAN_PROD); 295 296 if (qdf_unlikely(ret != 0)) { 297 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 298 ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED; 299 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 300 QDF_ASSERT(0); 301 ipa_warn("rm_inactivity_timer_release_resource ret fail"); 302 } 303 304 /* 305 * If wake_lock is released immediately, kernel would try to suspend 306 * immediately as well, Just avoid ping-pong between suspend-resume 307 * while there is healthy amount of data transfer going on by 308 * releasing the wake_lock after some delay. 309 */ 310 qdf_delayed_work_start(&ipa_ctx->wake_lock_work, 311 WLAN_IPA_RX_INACTIVITY_MSEC_DELAY); 312 313 return QDF_STATUS_SUCCESS; 314 } 315 316 /** 317 * wlan_ipa_uc_rm_notify_handler() - IPA uC resource notification handler 318 * @ipa_ctx: IPA context 319 * @event: IPA RM event 320 * 321 * Return: None 322 */ 323 static void 324 wlan_ipa_uc_rm_notify_handler(struct wlan_ipa_priv *ipa_ctx, 325 qdf_ipa_rm_event_t event) 326 { 327 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 328 return; 329 330 ipa_debug("event code %d", event); 331 332 switch (event) { 333 case QDF_IPA_RM_RESOURCE_GRANTED: 334 /* Differed RM Granted */ 335 qdf_mutex_acquire(&ipa_ctx->ipa_lock); 336 if ((!ipa_ctx->resource_unloading) && 337 (!ipa_ctx->activated_fw_pipe)) { 338 wlan_ipa_uc_enable_pipes(ipa_ctx); 339 ipa_ctx->resource_loading = false; 340 } 341 qdf_mutex_release(&ipa_ctx->ipa_lock); 342 break; 343 344 case QDF_IPA_RM_RESOURCE_RELEASED: 345 /* Differed RM Released */ 346 ipa_ctx->resource_unloading = false; 347 break; 348 349 default: 350 ipa_err("invalid event code %d", event); 351 break; 352 } 353 } 354 355 /** 356 * wlan_ipa_uc_rm_notify_defer() - Defer IPA uC notification 357 * * @data: IPA context 358 * 359 * This function is called when a resource manager event is received 360 * from firmware in interrupt context. This function will defer the 361 * handling to the OL RX thread 362 * 363 * Return: None 364 */ 365 static void wlan_ipa_uc_rm_notify_defer(void *data) 366 { 367 struct wlan_ipa_priv *ipa_ctx = data; 368 qdf_ipa_rm_event_t event; 369 struct uc_rm_work_struct *uc_rm_work = &ipa_ctx->uc_rm_work; 370 371 event = uc_rm_work->event; 372 373 wlan_ipa_uc_rm_notify_handler(ipa_ctx, event); 374 } 375 376 /** 377 * wlan_ipa_wake_lock_timer_func() - Wake lock work handler 378 * @data: IPA context 379 * 380 * When IPA resources are released in wlan_ipa_wdi_rm_try_release() we do 381 * not want to immediately release the wake lock since the system 382 * would then potentially try to suspend when there is a healthy data 383 * rate. Deferred work is scheduled and this function handles the 384 * work. When this function is called, if the IPA resource is still 385 * released then we release the wake lock. 386 * 387 * Return: None 388 */ 389 static void wlan_ipa_wake_lock_timer_func(void *data) 390 { 391 struct wlan_ipa_priv *ipa_ctx = data; 392 393 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 394 395 if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED) 396 goto end; 397 398 ipa_ctx->wake_lock_released = true; 399 qdf_wake_lock_release(&ipa_ctx->wake_lock, 400 WIFI_POWER_EVENT_WAKELOCK_IPA); 401 402 end: 403 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 404 } 405 406 /** 407 * wlan_ipa_rm_cons_request() - WLAN consumer resource request handler 408 * 409 * Callback function registered with IPA that is called when IPA wants 410 * to access the WLAN consumer resource 411 * 412 * Return: 0 if the request is granted, negative errno otherwise 413 */ 414 static int wlan_ipa_rm_cons_request(void) 415 { 416 struct wlan_ipa_priv *ipa_ctx; 417 QDF_STATUS status = QDF_STATUS_SUCCESS; 418 419 ipa_ctx = wlan_ipa_get_obj_context(); 420 421 if (ipa_ctx->resource_loading) { 422 ipa_err("IPA resource loading in progress"); 423 ipa_ctx->pending_cons_req = true; 424 status = QDF_STATUS_E_PENDING; 425 } else if (ipa_ctx->resource_unloading) { 426 ipa_err("IPA resource unloading in progress"); 427 ipa_ctx->pending_cons_req = true; 428 status = QDF_STATUS_E_PERM; 429 } 430 431 return qdf_status_to_os_return(status); 432 } 433 434 /** 435 * wlan_ipa_rm_notify() - IPA resource manager notifier callback 436 * @user_data: user data registered with IPA 437 * @event: the IPA resource manager event that occurred 438 * @data: the data associated with the event 439 * 440 * Return: None 441 */ 442 static void wlan_ipa_rm_notify(void *user_data, qdf_ipa_rm_event_t event, 443 unsigned long data) 444 { 445 struct wlan_ipa_priv *ipa_ctx = user_data; 446 447 if (qdf_unlikely(!ipa_ctx)) 448 return; 449 450 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 451 return; 452 453 ipa_debug("Evt: %d", event); 454 455 switch (event) { 456 case QDF_IPA_RM_RESOURCE_GRANTED: 457 if (wlan_ipa_uc_is_enabled(ipa_ctx->config)) { 458 /* RM Notification comes with ISR context 459 * it should be serialized into work queue to avoid 460 * ISR sleep problem 461 */ 462 ipa_ctx->uc_rm_work.event = event; 463 qdf_sched_work(0, &ipa_ctx->uc_rm_work.work); 464 break; 465 } 466 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 467 ipa_ctx->rm_state = WLAN_IPA_RM_GRANTED; 468 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 469 ipa_ctx->stats.num_rm_grant++; 470 break; 471 472 case QDF_IPA_RM_RESOURCE_RELEASED: 473 ipa_debug("RM Release"); 474 ipa_ctx->resource_unloading = false; 475 break; 476 477 default: 478 ipa_err("Unknown RM Evt: %d", event); 479 break; 480 } 481 } 482 483 QDF_STATUS wlan_ipa_wdi_setup_rm(struct wlan_ipa_priv *ipa_ctx) 484 { 485 qdf_ipa_rm_create_params_t create_params; 486 QDF_STATUS status; 487 int ret; 488 489 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 490 return 0; 491 492 qdf_create_work(0, &ipa_ctx->uc_rm_work.work, 493 wlan_ipa_uc_rm_notify_defer, ipa_ctx); 494 qdf_mem_zero(&create_params, sizeof(create_params)); 495 create_params.name = QDF_IPA_RM_RESOURCE_WLAN_PROD; 496 create_params.reg_params.user_data = ipa_ctx; 497 create_params.reg_params.notify_cb = wlan_ipa_rm_notify; 498 create_params.floor_voltage = QDF_IPA_VOLTAGE_LEVEL; 499 500 ret = qdf_ipa_rm_create_resource(&create_params); 501 if (ret) { 502 ipa_err("Create RM resource failed: %d", ret); 503 goto setup_rm_fail; 504 } 505 506 qdf_mem_zero(&create_params, sizeof(create_params)); 507 create_params.name = QDF_IPA_RM_RESOURCE_WLAN_CONS; 508 create_params.request_resource = wlan_ipa_rm_cons_request; 509 create_params.release_resource = wlan_ipa_rm_cons_release; 510 create_params.floor_voltage = QDF_IPA_VOLTAGE_LEVEL; 511 512 ret = qdf_ipa_rm_create_resource(&create_params); 513 if (ret) { 514 ipa_err("Create RM CONS resource failed: %d", ret); 515 goto delete_prod; 516 } 517 518 qdf_ipa_rm_add_dependency(QDF_IPA_RM_RESOURCE_WLAN_PROD, 519 QDF_IPA_RM_RESOURCE_APPS_CONS); 520 521 ret = qdf_ipa_rm_inactivity_timer_init(QDF_IPA_RM_RESOURCE_WLAN_PROD, 522 WLAN_IPA_RX_INACTIVITY_MSEC_DELAY); 523 if (ret) { 524 ipa_err("Timer init failed: %d", ret); 525 goto timer_init_failed; 526 } 527 528 status = qdf_delayed_work_create(&ipa_ctx->wake_lock_work, 529 wlan_ipa_wake_lock_timer_func, 530 ipa_ctx); 531 if (QDF_IS_STATUS_ERROR(status)) 532 goto timer_destroy; 533 534 qdf_wake_lock_create(&ipa_ctx->wake_lock, "wlan_ipa"); 535 qdf_spinlock_create(&ipa_ctx->rm_lock); 536 ipa_ctx->rm_state = WLAN_IPA_RM_RELEASED; 537 ipa_ctx->wake_lock_released = true; 538 qdf_atomic_set(&ipa_ctx->tx_ref_cnt, 0); 539 540 return QDF_STATUS_SUCCESS; 541 542 timer_destroy: 543 qdf_ipa_rm_inactivity_timer_destroy(QDF_IPA_RM_RESOURCE_WLAN_PROD); 544 545 timer_init_failed: 546 qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_APPS_CONS); 547 548 delete_prod: 549 qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_PROD); 550 551 setup_rm_fail: 552 return QDF_STATUS_E_FAILURE; 553 } 554 555 void wlan_ipa_wdi_destroy_rm(struct wlan_ipa_priv *ipa_ctx) 556 { 557 int ret; 558 559 if (!wlan_ipa_is_rm_enabled(ipa_ctx->config)) 560 return; 561 562 qdf_wake_lock_destroy(&ipa_ctx->wake_lock); 563 qdf_delayed_work_destroy(&ipa_ctx->wake_lock_work); 564 qdf_cancel_work(&ipa_ctx->uc_rm_work.work); 565 qdf_spinlock_destroy(&ipa_ctx->rm_lock); 566 567 qdf_ipa_rm_inactivity_timer_destroy(QDF_IPA_RM_RESOURCE_WLAN_PROD); 568 569 ret = qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_CONS); 570 if (ret) 571 ipa_err("RM CONS resource delete failed %d", ret); 572 573 ret = qdf_ipa_rm_delete_resource(QDF_IPA_RM_RESOURCE_WLAN_PROD); 574 if (ret) 575 ipa_err("RM PROD resource delete failed %d", ret); 576 } 577 578 bool wlan_ipa_is_rm_released(struct wlan_ipa_priv *ipa_ctx) 579 { 580 qdf_spin_lock_bh(&ipa_ctx->rm_lock); 581 582 if (ipa_ctx->rm_state != WLAN_IPA_RM_RELEASED) { 583 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 584 return false; 585 } 586 587 qdf_spin_unlock_bh(&ipa_ctx->rm_lock); 588 589 return true; 590 } 591 #endif /* CONFIG_IPA_WDI_UNIFIED_API */ 592