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