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