1 /* 2 * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-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 /* this file dispatches functions to bus specific definitions */ 21 #include "hif_debug.h" 22 #include "hif.h" 23 #include "hif_main.h" 24 #include "hif_io32.h" 25 #include "multibus.h" 26 #include "dummy.h" 27 #if defined(HIF_PCI) || defined(HIF_SNOC) || defined(HIF_AHB) || \ 28 defined(HIF_IPCI) 29 #include "ce_main.h" 30 #include "ce_api.h" 31 #include "ce_internal.h" 32 #endif 33 #include "htc_services.h" 34 #include "a_types.h" 35 #include "dummy.h" 36 #include "qdf_module.h" 37 38 /** 39 * hif_initialize_default_ops() - initializes default operations values 40 * @hif_sc: hif_context 41 * 42 * bus specific features should assign their dummy implementations here. 43 */ 44 static void hif_initialize_default_ops(struct hif_softc *hif_sc) 45 { 46 struct hif_bus_ops *bus_ops = &hif_sc->bus_ops; 47 48 /* must be filled in by hif_bus_open */ 49 bus_ops->hif_bus_close = NULL; 50 /* dummy implementations */ 51 bus_ops->hif_display_stats = 52 &hif_dummy_display_stats; 53 bus_ops->hif_clear_stats = 54 &hif_dummy_clear_stats; 55 bus_ops->hif_set_bundle_mode = &hif_dummy_set_bundle_mode; 56 bus_ops->hif_bus_reset_resume = &hif_dummy_bus_reset_resume; 57 bus_ops->hif_bus_suspend_noirq = &hif_dummy_bus_suspend_noirq; 58 bus_ops->hif_bus_resume_noirq = &hif_dummy_bus_resume_noirq; 59 bus_ops->hif_bus_early_suspend = &hif_dummy_bus_suspend; 60 bus_ops->hif_bus_late_resume = &hif_dummy_bus_resume; 61 bus_ops->hif_map_ce_to_irq = &hif_dummy_map_ce_to_irq; 62 bus_ops->hif_grp_irq_configure = &hif_dummy_grp_irq_configure; 63 bus_ops->hif_grp_irq_deconfigure = &hif_dummy_grp_irq_deconfigure; 64 bus_ops->hif_config_irq_affinity = 65 &hif_dummy_config_irq_affinity; 66 bus_ops->hif_config_irq_by_ceid = &hif_dummy_config_irq_by_ceid; 67 bus_ops->hif_enable_grp_irqs = &hif_dummy_enable_grp_irqs; 68 bus_ops->hif_disable_grp_irqs = &hif_dummy_enable_grp_irqs; 69 bus_ops->hif_config_irq_clear_cpu_affinity = 70 &hif_dummy_config_irq_clear_cpu_affinity; 71 #ifdef FEATURE_IRQ_AFFINITY 72 bus_ops->hif_set_grp_intr_affinity = &hif_dummy_set_grp_intr_affinity; 73 #endif 74 bus_ops->hif_affinity_mgr_set_affinity = 75 &hif_dummy_affinity_mgr_set_affinity; 76 } 77 78 #define NUM_OPS (sizeof(struct hif_bus_ops) / sizeof(void *)) 79 80 /** 81 * hif_verify_basic_ops() - ensure required bus apis are defined 82 * @hif_sc: hif_context 83 * 84 * all bus operations must be defined to avoid crashes 85 * iterate over the structure and ensure all function pointers 86 * are non null. 87 * 88 * Return: QDF_STATUS_SUCCESS if all the operations are defined 89 */ 90 static QDF_STATUS hif_verify_basic_ops(struct hif_softc *hif_sc) 91 { 92 struct hif_bus_ops *bus_ops = &hif_sc->bus_ops; 93 void **ops_array = (void *)bus_ops; 94 QDF_STATUS status = QDF_STATUS_SUCCESS; 95 int i; 96 97 for (i = 0; i < NUM_OPS; i++) { 98 if (!ops_array[i]) { 99 hif_err("ops_array[%d] is null", i); 100 status = QDF_STATUS_E_NOSUPPORT; 101 } 102 } 103 return status; 104 } 105 106 /** 107 * hif_bus_get_context_size - API to return size of the bus specific structure 108 * @bus_type: bus type 109 * 110 * Return: sizeof of hif_pci_softc 111 */ 112 int hif_bus_get_context_size(enum qdf_bus_type bus_type) 113 { 114 switch (bus_type) { 115 case QDF_BUS_TYPE_PCI: 116 return hif_pci_get_context_size(); 117 case QDF_BUS_TYPE_IPCI: 118 return hif_ipci_get_context_size(); 119 case QDF_BUS_TYPE_AHB: 120 return hif_ahb_get_context_size(); 121 case QDF_BUS_TYPE_SNOC: 122 return hif_snoc_get_context_size(); 123 case QDF_BUS_TYPE_SDIO: 124 return hif_sdio_get_context_size(); 125 case QDF_BUS_TYPE_USB: 126 return hif_usb_get_context_size(); 127 default: 128 return 0; 129 } 130 } 131 132 /** 133 * hif_bus_open() - initialize the bus_ops and call the bus specific open 134 * @hif_sc: hif_context 135 * @bus_type: type of bus being enumerated 136 * 137 * Return: QDF_STATUS_SUCCESS or error 138 */ 139 QDF_STATUS hif_bus_open(struct hif_softc *hif_sc, 140 enum qdf_bus_type bus_type) 141 { 142 QDF_STATUS status = QDF_STATUS_E_INVAL; 143 144 hif_initialize_default_ops(hif_sc); 145 146 switch (bus_type) { 147 case QDF_BUS_TYPE_PCI: 148 status = hif_initialize_pci_ops(hif_sc); 149 break; 150 case QDF_BUS_TYPE_IPCI: 151 status = hif_initialize_ipci_ops(hif_sc); 152 break; 153 case QDF_BUS_TYPE_SNOC: 154 status = hif_initialize_snoc_ops(&hif_sc->bus_ops); 155 break; 156 case QDF_BUS_TYPE_AHB: 157 status = hif_initialize_ahb_ops(&hif_sc->bus_ops); 158 break; 159 case QDF_BUS_TYPE_SDIO: 160 status = hif_initialize_sdio_ops(hif_sc); 161 break; 162 case QDF_BUS_TYPE_USB: 163 status = hif_initialize_usb_ops(&hif_sc->bus_ops); 164 break; 165 default: 166 status = QDF_STATUS_E_NOSUPPORT; 167 break; 168 } 169 170 if (status != QDF_STATUS_SUCCESS) { 171 hif_err("bus_type: %d not supported", bus_type); 172 return status; 173 } 174 175 status = hif_verify_basic_ops(hif_sc); 176 if (status != QDF_STATUS_SUCCESS) 177 return status; 178 179 return hif_sc->bus_ops.hif_bus_open(hif_sc, bus_type); 180 } 181 182 /** 183 * hif_bus_close() - close the bus 184 * @hif_sc: hif_context 185 */ 186 void hif_bus_close(struct hif_softc *hif_sc) 187 { 188 hif_sc->bus_ops.hif_bus_close(hif_sc); 189 } 190 191 /** 192 * hif_bus_prevent_linkdown() - prevent linkdown 193 * @hif_sc: hif context 194 * @flag: true = keep bus alive false = let bus go to sleep 195 * 196 * Keeps the bus awake during suspend. 197 */ 198 void hif_bus_prevent_linkdown(struct hif_softc *hif_sc, bool flag) 199 { 200 hif_sc->bus_ops.hif_bus_prevent_linkdown(hif_sc, flag); 201 } 202 203 204 void hif_reset_soc(struct hif_opaque_softc *hif_ctx) 205 { 206 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 207 208 hif_sc->bus_ops.hif_reset_soc(hif_sc); 209 } 210 211 int hif_bus_early_suspend(struct hif_opaque_softc *hif_ctx) 212 { 213 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 214 215 return hif_sc->bus_ops.hif_bus_early_suspend(hif_sc); 216 } 217 218 int hif_bus_late_resume(struct hif_opaque_softc *hif_ctx) 219 { 220 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 221 222 return hif_sc->bus_ops.hif_bus_late_resume(hif_sc); 223 } 224 225 int hif_bus_suspend(struct hif_opaque_softc *hif_ctx) 226 { 227 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 228 229 return hif_sc->bus_ops.hif_bus_suspend(hif_sc); 230 } 231 232 int hif_bus_resume(struct hif_opaque_softc *hif_ctx) 233 { 234 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 235 236 return hif_sc->bus_ops.hif_bus_resume(hif_sc); 237 } 238 239 int hif_bus_suspend_noirq(struct hif_opaque_softc *hif_ctx) 240 { 241 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 242 243 return hif_sc->bus_ops.hif_bus_suspend_noirq(hif_sc); 244 } 245 246 int hif_bus_resume_noirq(struct hif_opaque_softc *hif_ctx) 247 { 248 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 249 250 return hif_sc->bus_ops.hif_bus_resume_noirq(hif_sc); 251 } 252 253 int hif_target_sleep_state_adjust(struct hif_softc *hif_sc, 254 bool sleep_ok, bool wait_for_it) 255 { 256 return hif_sc->bus_ops.hif_target_sleep_state_adjust(hif_sc, 257 sleep_ok, wait_for_it); 258 } 259 qdf_export_symbol(hif_target_sleep_state_adjust); 260 261 void hif_disable_isr(struct hif_opaque_softc *hif_hdl) 262 { 263 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 264 265 hif_sc->bus_ops.hif_disable_isr(hif_sc); 266 } 267 268 void hif_nointrs(struct hif_softc *hif_sc) 269 { 270 hif_sc->bus_ops.hif_nointrs(hif_sc); 271 } 272 273 QDF_STATUS hif_enable_bus(struct hif_softc *hif_sc, struct device *dev, 274 void *bdev, const struct hif_bus_id *bid, 275 enum hif_enable_type type) 276 { 277 return hif_sc->bus_ops.hif_enable_bus(hif_sc, dev, bdev, bid, type); 278 } 279 280 void hif_disable_bus(struct hif_softc *hif_sc) 281 { 282 hif_sc->bus_ops.hif_disable_bus(hif_sc); 283 } 284 285 int hif_bus_configure(struct hif_softc *hif_sc) 286 { 287 return hif_sc->bus_ops.hif_bus_configure(hif_sc); 288 } 289 290 QDF_STATUS hif_get_config_item(struct hif_opaque_softc *hif_ctx, 291 int opcode, void *config, uint32_t config_len) 292 { 293 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 294 295 return hif_sc->bus_ops.hif_get_config_item(hif_sc, opcode, config, 296 config_len); 297 } 298 299 void hif_set_mailbox_swap(struct hif_opaque_softc *hif_ctx) 300 { 301 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 302 303 hif_sc->bus_ops.hif_set_mailbox_swap(hif_sc); 304 } 305 306 void hif_claim_device(struct hif_opaque_softc *hif_ctx) 307 { 308 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 309 310 hif_sc->bus_ops.hif_claim_device(hif_sc); 311 } 312 313 void hif_shutdown_device(struct hif_opaque_softc *hif_ctx) 314 { 315 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 316 317 hif_sc->bus_ops.hif_shutdown_device(hif_sc); 318 } 319 320 void hif_stop(struct hif_opaque_softc *hif_ctx) 321 { 322 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_ctx); 323 324 hif_sc->bus_ops.hif_stop(hif_sc); 325 } 326 327 void hif_cancel_deferred_target_sleep(struct hif_softc *hif_sc) 328 { 329 return hif_sc->bus_ops.hif_cancel_deferred_target_sleep(hif_sc); 330 } 331 332 void hif_irq_enable(struct hif_softc *hif_sc, int irq_id) 333 { 334 hif_sc->bus_ops.hif_irq_enable(hif_sc, irq_id); 335 } 336 qdf_export_symbol(hif_irq_enable); 337 338 void hif_irq_disable(struct hif_softc *hif_sc, int irq_id) 339 { 340 hif_sc->bus_ops.hif_irq_disable(hif_sc, irq_id); 341 } 342 343 int hif_grp_irq_configure(struct hif_softc *hif_sc, 344 struct hif_exec_context *hif_exec) 345 { 346 return hif_sc->bus_ops.hif_grp_irq_configure(hif_sc, hif_exec); 347 } 348 349 void hif_grp_irq_deconfigure(struct hif_softc *hif_sc) 350 { 351 hif_sc->bus_ops.hif_grp_irq_deconfigure(hif_sc); 352 } 353 354 int hif_dump_registers(struct hif_opaque_softc *hif_hdl) 355 { 356 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 357 358 return hif_sc->bus_ops.hif_dump_registers(hif_sc); 359 } 360 361 void hif_dump_target_memory(struct hif_opaque_softc *hif_hdl, 362 void *ramdump_base, 363 uint32_t address, uint32_t size) 364 { 365 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 366 367 hif_sc->bus_ops.hif_dump_target_memory(hif_sc, ramdump_base, 368 address, size); 369 } 370 371 void hif_ipa_get_ce_resource(struct hif_opaque_softc *hif_hdl, 372 qdf_shared_mem_t **ce_sr, 373 uint32_t *ce_sr_ring_size, 374 qdf_dma_addr_t *ce_reg_paddr) 375 { 376 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 377 378 hif_sc->bus_ops.hif_ipa_get_ce_resource(hif_sc, ce_sr, 379 ce_sr_ring_size, ce_reg_paddr); 380 } 381 382 void hif_mask_interrupt_call(struct hif_opaque_softc *hif_hdl) 383 { 384 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 385 386 hif_sc->bus_ops.hif_mask_interrupt_call(hif_sc); 387 } 388 389 void hif_display_bus_stats(struct hif_opaque_softc *scn) 390 { 391 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 392 393 hif_sc->bus_ops.hif_display_stats(hif_sc); 394 } 395 396 void hif_clear_bus_stats(struct hif_opaque_softc *scn) 397 { 398 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 399 400 hif_sc->bus_ops.hif_clear_stats(hif_sc); 401 } 402 403 /** 404 * hif_enable_power_management() - enable power management after driver load 405 * @hif_hdl: opaque pointer to the hif context 406 * @is_packet_log_enabled: true if packet log is enabled 407 * 408 * Driver load and firmware download are done in a high performance mode. 409 * Enable power management after the driver is loaded. 410 * packet log can require fewer power management features to be enabled. 411 */ 412 void hif_enable_power_management(struct hif_opaque_softc *hif_hdl, 413 bool is_packet_log_enabled) 414 { 415 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 416 417 hif_sc->bus_ops.hif_enable_power_management(hif_sc, 418 is_packet_log_enabled); 419 } 420 421 /** 422 * hif_disable_power_management() - reset the bus power management 423 * @hif_hdl: opaque pointer to the hif context 424 * 425 * return the power management of the bus to its default state. 426 * This isn't necessarily a complete reversal of its counterpart. 427 * This should be called when unloading the driver. 428 */ 429 void hif_disable_power_management(struct hif_opaque_softc *hif_hdl) 430 { 431 struct hif_softc *hif_sc = HIF_GET_SOFTC(hif_hdl); 432 433 hif_sc->bus_ops.hif_disable_power_management(hif_sc); 434 } 435 436 /** 437 * hif_set_bundle_mode() - enable bundling and set default rx bundle cnt 438 * @scn: pointer to hif_opaque_softc structure 439 * @enabled: flag to enable/disable bundling 440 * @rx_bundle_cnt: bundle count to be used for RX 441 * 442 * Return: none 443 */ 444 void hif_set_bundle_mode(struct hif_opaque_softc *scn, bool enabled, 445 int rx_bundle_cnt) 446 { 447 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 448 449 hif_sc->bus_ops.hif_set_bundle_mode(hif_sc, enabled, rx_bundle_cnt); 450 } 451 452 /** 453 * hif_bus_reset_resume() - resume the bus after reset 454 * @scn: struct hif_opaque_softc 455 * 456 * This function is called to tell the driver that USB device has been resumed 457 * and it has also been reset. The driver should redo any necessary 458 * initialization. This function resets WLAN SOC. 459 * 460 * Return: int 0 for success, non zero for failure 461 */ 462 int hif_bus_reset_resume(struct hif_opaque_softc *scn) 463 { 464 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 465 466 return hif_sc->bus_ops.hif_bus_reset_resume(hif_sc); 467 } 468 469 int hif_apps_irqs_disable(struct hif_opaque_softc *hif_ctx) 470 { 471 struct hif_softc *scn; 472 int i; 473 474 QDF_BUG(hif_ctx); 475 scn = HIF_GET_SOFTC(hif_ctx); 476 if (!scn) 477 return -EINVAL; 478 479 if (pld_is_one_msi(scn->qdf_dev->dev)) 480 return 0; 481 482 /* if the wake_irq is shared, don't disable it twice */ 483 for (i = 0; i < scn->ce_count; ++i) { 484 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 485 486 if (irq != scn->wake_irq) 487 disable_irq(irq); 488 } 489 490 return 0; 491 } 492 493 int hif_apps_irqs_enable(struct hif_opaque_softc *hif_ctx) 494 { 495 struct hif_softc *scn; 496 int i; 497 498 QDF_BUG(hif_ctx); 499 scn = HIF_GET_SOFTC(hif_ctx); 500 if (!scn) 501 return -EINVAL; 502 503 if (pld_is_one_msi(scn->qdf_dev->dev)) 504 return 0; 505 506 /* if the wake_irq is shared, don't enable it twice */ 507 for (i = 0; i < scn->ce_count; ++i) { 508 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 509 510 if (irq != scn->wake_irq) 511 enable_irq(irq); 512 } 513 514 return 0; 515 } 516 517 int hif_apps_wake_irq_disable(struct hif_opaque_softc *hif_ctx) 518 { 519 struct hif_softc *scn; 520 521 QDF_BUG(hif_ctx); 522 scn = HIF_GET_SOFTC(hif_ctx); 523 if (!scn) 524 return -EINVAL; 525 526 disable_irq(scn->wake_irq); 527 528 return 0; 529 } 530 531 int hif_apps_wake_irq_enable(struct hif_opaque_softc *hif_ctx) 532 { 533 struct hif_softc *scn; 534 535 QDF_BUG(hif_ctx); 536 scn = HIF_GET_SOFTC(hif_ctx); 537 if (!scn) 538 return -EINVAL; 539 540 enable_irq(scn->wake_irq); 541 542 return 0; 543 } 544 545 int hif_apps_disable_irq_wake(struct hif_opaque_softc *hif_ctx) 546 { 547 struct hif_softc *scn; 548 549 QDF_BUG(hif_ctx); 550 scn = HIF_GET_SOFTC(hif_ctx); 551 if (!scn) 552 return -EINVAL; 553 554 return disable_irq_wake(scn->wake_irq); 555 } 556 557 int hif_apps_enable_irq_wake(struct hif_opaque_softc *hif_ctx) 558 { 559 struct hif_softc *scn; 560 561 QDF_BUG(hif_ctx); 562 scn = HIF_GET_SOFTC(hif_ctx); 563 if (!scn) 564 return -EINVAL; 565 566 return enable_irq_wake(scn->wake_irq); 567 } 568 569 int hif_apps_disable_irqs_except_wake_irq(struct hif_opaque_softc *hif_ctx) 570 { 571 struct hif_softc *scn; 572 int i; 573 574 QDF_BUG(hif_ctx); 575 scn = HIF_GET_SOFTC(hif_ctx); 576 if (!scn) 577 return -EINVAL; 578 579 for (i = 0; i < scn->ce_count; ++i) { 580 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 581 582 if (irq != scn->wake_irq) 583 disable_irq(irq); 584 } 585 586 return 0; 587 } 588 589 int hif_apps_enable_irqs_except_wake_irq(struct hif_opaque_softc *hif_ctx) 590 { 591 struct hif_softc *scn; 592 int i; 593 594 QDF_BUG(hif_ctx); 595 scn = HIF_GET_SOFTC(hif_ctx); 596 if (!scn) 597 return -EINVAL; 598 599 for (i = 0; i < scn->ce_count; ++i) { 600 int irq = scn->bus_ops.hif_map_ce_to_irq(scn, i); 601 602 if (irq != scn->wake_irq) 603 enable_irq(irq); 604 } 605 606 return 0; 607 } 608 609 #ifdef WLAN_FEATURE_BMI 610 bool hif_needs_bmi(struct hif_opaque_softc *scn) 611 { 612 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 613 614 return hif_sc->bus_ops.hif_needs_bmi(hif_sc); 615 } 616 qdf_export_symbol(hif_needs_bmi); 617 #endif /* WLAN_FEATURE_BMI */ 618 619 void hif_config_irq_affinity(struct hif_softc *hif_sc) 620 { 621 hif_sc->bus_ops.hif_config_irq_affinity(hif_sc); 622 } 623 624 int hif_config_irq_by_ceid(struct hif_softc *hif_sc, int ce_id) 625 { 626 return hif_sc->bus_ops.hif_config_irq_by_ceid(hif_sc, ce_id); 627 } 628 629 #ifdef HIF_CPU_CLEAR_AFFINITY 630 void hif_config_irq_clear_cpu_affinity(struct hif_opaque_softc *scn, 631 int intr_ctxt_id, int cpu) 632 { 633 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 634 635 hif_sc->bus_ops.hif_config_irq_clear_cpu_affinity(hif_sc, 636 intr_ctxt_id, cpu); 637 } 638 639 qdf_export_symbol(hif_config_irq_clear_cpu_affinity); 640 #endif 641 642 #ifdef HIF_BUS_LOG_INFO 643 bool hif_log_bus_info(struct hif_softc *hif_sc, uint8_t *data, 644 unsigned int *offset) 645 { 646 if (hif_sc->bus_ops.hif_log_bus_info) 647 return hif_sc->bus_ops.hif_log_bus_info(hif_sc, data, offset); 648 649 return false; 650 } 651 #endif 652 653 int hif_apps_grp_irqs_enable(struct hif_opaque_softc *hif_ctx) 654 { 655 struct hif_exec_context *hif_exec; 656 struct hif_softc *scn; 657 int i, j; 658 659 QDF_BUG(hif_ctx); 660 scn = HIF_GET_SOFTC(hif_ctx); 661 if (!scn) 662 return -EINVAL; 663 664 for (i = 0 ; i < HIF_MAX_GROUP; i++) { 665 hif_exec = hif_exec_get_ctx(hif_ctx, i); 666 if (!hif_exec) 667 continue; 668 669 for (j = 0; j < hif_exec->numirq; j++) 670 pfrm_enable_irq(scn->qdf_dev->dev, 671 hif_exec->os_irq[j]); 672 } 673 674 return 0; 675 } 676 677 int hif_apps_grp_irqs_disable(struct hif_opaque_softc *hif_ctx) 678 { 679 struct hif_exec_context *hif_exec; 680 struct hif_softc *scn; 681 int i, j; 682 683 QDF_BUG(hif_ctx); 684 scn = HIF_GET_SOFTC(hif_ctx); 685 if (!scn) 686 return -EINVAL; 687 688 for (i = 0 ; i < HIF_MAX_GROUP; i++) { 689 hif_exec = hif_exec_get_ctx(hif_ctx, i); 690 if (!hif_exec) 691 continue; 692 693 for (j = 0; j < hif_exec->numirq; j++) 694 pfrm_disable_irq(scn->qdf_dev->dev, 695 hif_exec->os_irq[j]); 696 } 697 698 return 0; 699 } 700 701 int hif_disable_grp_irqs(struct hif_opaque_softc *scn) 702 { 703 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 704 705 return hif_sc->bus_ops.hif_disable_grp_irqs(hif_sc); 706 } 707 708 int hif_enable_grp_irqs(struct hif_opaque_softc *scn) 709 { 710 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 711 712 return hif_sc->bus_ops.hif_enable_grp_irqs(hif_sc); 713 } 714 715 #ifdef FEATURE_IRQ_AFFINITY 716 void hif_set_grp_intr_affinity(struct hif_opaque_softc *scn, 717 uint32_t grp_intr_bitmask, bool perf) 718 { 719 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 720 721 if (!hif_sc) 722 return; 723 724 hif_sc->bus_ops.hif_set_grp_intr_affinity(hif_sc, grp_intr_bitmask, 725 perf); 726 } 727 #endif 728 729 void hif_affinity_mgr_set_affinity(struct hif_opaque_softc *scn) 730 { 731 struct hif_softc *hif_sc = HIF_GET_SOFTC(scn); 732 733 if (!hif_sc) 734 return; 735 736 if (!hif_sc->bus_ops.hif_affinity_mgr_set_affinity) 737 return; 738 739 hif_sc->bus_ops.hif_affinity_mgr_set_affinity(hif_sc); 740 } 741