xref: /linux/drivers/net/wireless/ath/ath11k/ahb.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/property.h>
10 #include <linux/of_device.h>
11 #include <linux/of.h>
12 #include <linux/of_reserved_mem.h>
13 #include <linux/dma-mapping.h>
14 #include <linux/iommu.h>
15 #include "ahb.h"
16 #include "debug.h"
17 #include "hif.h"
18 #include "qmi.h"
19 #include <linux/remoteproc.h>
20 #include "pcic.h"
21 #include <linux/soc/qcom/smem.h>
22 #include <linux/soc/qcom/smem_state.h>
23 
24 static const struct of_device_id ath11k_ahb_of_match[] = {
25 	/* TODO: Should we change the compatible string to something similar
26 	 * to one that ath10k uses?
27 	 */
28 	{ .compatible = "qcom,ipq8074-wifi",
29 	  .data = (void *)ATH11K_HW_IPQ8074,
30 	},
31 	{ .compatible = "qcom,ipq6018-wifi",
32 	  .data = (void *)ATH11K_HW_IPQ6018_HW10,
33 	},
34 	{ .compatible = "qcom,wcn6750-wifi",
35 	  .data = (void *)ATH11K_HW_WCN6750_HW10,
36 	},
37 	{ .compatible = "qcom,ipq5018-wifi",
38 	  .data = (void *)ATH11K_HW_IPQ5018_HW10,
39 	},
40 	{ }
41 };
42 
43 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match);
44 
45 #define ATH11K_IRQ_CE0_OFFSET 4
46 
47 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
48 	"misc-pulse1",
49 	"misc-latch",
50 	"sw-exception",
51 	"watchdog",
52 	"ce0",
53 	"ce1",
54 	"ce2",
55 	"ce3",
56 	"ce4",
57 	"ce5",
58 	"ce6",
59 	"ce7",
60 	"ce8",
61 	"ce9",
62 	"ce10",
63 	"ce11",
64 	"host2wbm-desc-feed",
65 	"host2reo-re-injection",
66 	"host2reo-command",
67 	"host2rxdma-monitor-ring3",
68 	"host2rxdma-monitor-ring2",
69 	"host2rxdma-monitor-ring1",
70 	"reo2ost-exception",
71 	"wbm2host-rx-release",
72 	"reo2host-status",
73 	"reo2host-destination-ring4",
74 	"reo2host-destination-ring3",
75 	"reo2host-destination-ring2",
76 	"reo2host-destination-ring1",
77 	"rxdma2host-monitor-destination-mac3",
78 	"rxdma2host-monitor-destination-mac2",
79 	"rxdma2host-monitor-destination-mac1",
80 	"ppdu-end-interrupts-mac3",
81 	"ppdu-end-interrupts-mac2",
82 	"ppdu-end-interrupts-mac1",
83 	"rxdma2host-monitor-status-ring-mac3",
84 	"rxdma2host-monitor-status-ring-mac2",
85 	"rxdma2host-monitor-status-ring-mac1",
86 	"host2rxdma-host-buf-ring-mac3",
87 	"host2rxdma-host-buf-ring-mac2",
88 	"host2rxdma-host-buf-ring-mac1",
89 	"rxdma2host-destination-ring-mac3",
90 	"rxdma2host-destination-ring-mac2",
91 	"rxdma2host-destination-ring-mac1",
92 	"host2tcl-input-ring4",
93 	"host2tcl-input-ring3",
94 	"host2tcl-input-ring2",
95 	"host2tcl-input-ring1",
96 	"wbm2host-tx-completions-ring3",
97 	"wbm2host-tx-completions-ring2",
98 	"wbm2host-tx-completions-ring1",
99 	"tcl2host-status-ring",
100 };
101 
102 /* enum ext_irq_num - irq numbers that can be used by external modules
103  * like datapath
104  */
105 enum ext_irq_num {
106 	host2wbm_desc_feed = 16,
107 	host2reo_re_injection,
108 	host2reo_command,
109 	host2rxdma_monitor_ring3,
110 	host2rxdma_monitor_ring2,
111 	host2rxdma_monitor_ring1,
112 	reo2host_exception,
113 	wbm2host_rx_release,
114 	reo2host_status,
115 	reo2host_destination_ring4,
116 	reo2host_destination_ring3,
117 	reo2host_destination_ring2,
118 	reo2host_destination_ring1,
119 	rxdma2host_monitor_destination_mac3,
120 	rxdma2host_monitor_destination_mac2,
121 	rxdma2host_monitor_destination_mac1,
122 	ppdu_end_interrupts_mac3,
123 	ppdu_end_interrupts_mac2,
124 	ppdu_end_interrupts_mac1,
125 	rxdma2host_monitor_status_ring_mac3,
126 	rxdma2host_monitor_status_ring_mac2,
127 	rxdma2host_monitor_status_ring_mac1,
128 	host2rxdma_host_buf_ring_mac3,
129 	host2rxdma_host_buf_ring_mac2,
130 	host2rxdma_host_buf_ring_mac1,
131 	rxdma2host_destination_ring_mac3,
132 	rxdma2host_destination_ring_mac2,
133 	rxdma2host_destination_ring_mac1,
134 	host2tcl_input_ring4,
135 	host2tcl_input_ring3,
136 	host2tcl_input_ring2,
137 	host2tcl_input_ring1,
138 	wbm2host_tx_completions_ring3,
139 	wbm2host_tx_completions_ring2,
140 	wbm2host_tx_completions_ring1,
141 	tcl2host_status_ring,
142 };
143 
144 static int
145 ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base *ab, unsigned int vector)
146 {
147 	return ab->pci.msi.irqs[vector];
148 }
149 
150 static inline u32
151 ath11k_ahb_get_window_start_wcn6750(struct ath11k_base *ab, u32 offset)
152 {
153 	u32 window_start = 0;
154 
155 	/* If offset lies within DP register range, use 1st window */
156 	if ((offset ^ HAL_SEQ_WCSS_UMAC_OFFSET) < ATH11K_PCI_WINDOW_RANGE_MASK)
157 		window_start = ATH11K_PCI_WINDOW_START;
158 	/* If offset lies within CE register range, use 2nd window */
159 	else if ((offset ^ HAL_SEQ_WCSS_UMAC_CE0_SRC_REG(ab)) <
160 		 ATH11K_PCI_WINDOW_RANGE_MASK)
161 		window_start = 2 * ATH11K_PCI_WINDOW_START;
162 
163 	return window_start;
164 }
165 
166 static void
167 ath11k_ahb_window_write32_wcn6750(struct ath11k_base *ab, u32 offset, u32 value)
168 {
169 	u32 window_start;
170 
171 	/* WCN6750 uses static window based register access*/
172 	window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
173 
174 	iowrite32(value, ab->mem + window_start +
175 		  (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
176 }
177 
178 static u32 ath11k_ahb_window_read32_wcn6750(struct ath11k_base *ab, u32 offset)
179 {
180 	u32 window_start;
181 	u32 val;
182 
183 	/* WCN6750 uses static window based register access */
184 	window_start = ath11k_ahb_get_window_start_wcn6750(ab, offset);
185 
186 	val = ioread32(ab->mem + window_start +
187 		       (offset & ATH11K_PCI_WINDOW_RANGE_MASK));
188 	return val;
189 }
190 
191 static const struct ath11k_pci_ops ath11k_ahb_pci_ops_wcn6750 = {
192 	.wakeup = NULL,
193 	.release = NULL,
194 	.get_msi_irq = ath11k_ahb_get_msi_irq_wcn6750,
195 	.window_write32 = ath11k_ahb_window_write32_wcn6750,
196 	.window_read32 = ath11k_ahb_window_read32_wcn6750,
197 };
198 
199 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
200 {
201 	return ioread32(ab->mem + offset);
202 }
203 
204 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
205 {
206 	iowrite32(value, ab->mem + offset);
207 }
208 
209 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab)
210 {
211 	int i;
212 
213 	for (i = 0; i < ab->hw_params.ce_count; i++) {
214 		struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
215 
216 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
217 			continue;
218 
219 		tasklet_kill(&ce_pipe->intr_tq);
220 	}
221 }
222 
223 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
224 {
225 	int i;
226 
227 	for (i = 0; i < irq_grp->num_irq; i++)
228 		disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
229 }
230 
231 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
232 {
233 	int i;
234 
235 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
236 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
237 
238 		ath11k_ahb_ext_grp_disable(irq_grp);
239 
240 		if (irq_grp->napi_enabled) {
241 			napi_synchronize(&irq_grp->napi);
242 			napi_disable(&irq_grp->napi);
243 			irq_grp->napi_enabled = false;
244 		}
245 	}
246 }
247 
248 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
249 {
250 	int i;
251 
252 	for (i = 0; i < irq_grp->num_irq; i++)
253 		enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
254 }
255 
256 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset)
257 {
258 	u32 val;
259 
260 	val = ath11k_ahb_read32(ab, offset);
261 	ath11k_ahb_write32(ab, offset, val | BIT(bit));
262 }
263 
264 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset)
265 {
266 	u32 val;
267 
268 	val = ath11k_ahb_read32(ab, offset);
269 	ath11k_ahb_write32(ab, offset, val & ~BIT(bit));
270 }
271 
272 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
273 {
274 	const struct ce_attr *ce_attr;
275 	const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
276 	u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
277 
278 	ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
279 	ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
280 	ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
281 
282 	ce_attr = &ab->hw_params.host_ce_config[ce_id];
283 	if (ce_attr->src_nentries)
284 		ath11k_ahb_setbit32(ab, ce_id, ie1_reg_addr);
285 
286 	if (ce_attr->dest_nentries) {
287 		ath11k_ahb_setbit32(ab, ce_id, ie2_reg_addr);
288 		ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
289 				    ie3_reg_addr);
290 	}
291 }
292 
293 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
294 {
295 	const struct ce_attr *ce_attr;
296 	const struct ce_ie_addr *ce_ie_addr = ab->hw_params.ce_ie_addr;
297 	u32 ie1_reg_addr, ie2_reg_addr, ie3_reg_addr;
298 
299 	ie1_reg_addr = ce_ie_addr->ie1_reg_addr + ATH11K_CE_OFFSET(ab);
300 	ie2_reg_addr = ce_ie_addr->ie2_reg_addr + ATH11K_CE_OFFSET(ab);
301 	ie3_reg_addr = ce_ie_addr->ie3_reg_addr + ATH11K_CE_OFFSET(ab);
302 
303 	ce_attr = &ab->hw_params.host_ce_config[ce_id];
304 	if (ce_attr->src_nentries)
305 		ath11k_ahb_clearbit32(ab, ce_id, ie1_reg_addr);
306 
307 	if (ce_attr->dest_nentries) {
308 		ath11k_ahb_clearbit32(ab, ce_id, ie2_reg_addr);
309 		ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
310 				      ie3_reg_addr);
311 	}
312 }
313 
314 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab)
315 {
316 	int i;
317 	int irq_idx;
318 
319 	for (i = 0; i < ab->hw_params.ce_count; i++) {
320 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
321 			continue;
322 
323 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
324 		synchronize_irq(ab->irq_num[irq_idx]);
325 	}
326 }
327 
328 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab)
329 {
330 	int i, j;
331 	int irq_idx;
332 
333 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
334 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
335 
336 		for (j = 0; j < irq_grp->num_irq; j++) {
337 			irq_idx = irq_grp->irqs[j];
338 			synchronize_irq(ab->irq_num[irq_idx]);
339 		}
340 	}
341 }
342 
343 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab)
344 {
345 	int i;
346 
347 	for (i = 0; i < ab->hw_params.ce_count; i++) {
348 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
349 			continue;
350 		ath11k_ahb_ce_irq_enable(ab, i);
351 	}
352 }
353 
354 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab)
355 {
356 	int i;
357 
358 	for (i = 0; i < ab->hw_params.ce_count; i++) {
359 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
360 			continue;
361 		ath11k_ahb_ce_irq_disable(ab, i);
362 	}
363 }
364 
365 static int ath11k_ahb_start(struct ath11k_base *ab)
366 {
367 	ath11k_ahb_ce_irqs_enable(ab);
368 	ath11k_ce_rx_post_buf(ab);
369 
370 	return 0;
371 }
372 
373 static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
374 {
375 	int i;
376 
377 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
378 		struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
379 
380 		if (!irq_grp->napi_enabled) {
381 			napi_enable(&irq_grp->napi);
382 			irq_grp->napi_enabled = true;
383 		}
384 		ath11k_ahb_ext_grp_enable(irq_grp);
385 	}
386 }
387 
388 static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
389 {
390 	__ath11k_ahb_ext_irq_disable(ab);
391 	ath11k_ahb_sync_ext_irqs(ab);
392 }
393 
394 static void ath11k_ahb_stop(struct ath11k_base *ab)
395 {
396 	if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
397 		ath11k_ahb_ce_irqs_disable(ab);
398 	ath11k_ahb_sync_ce_irqs(ab);
399 	ath11k_ahb_kill_tasklets(ab);
400 	timer_delete_sync(&ab->rx_replenish_retry);
401 	ath11k_ce_cleanup_pipes(ab);
402 }
403 
404 static int ath11k_ahb_power_up(struct ath11k_base *ab)
405 {
406 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
407 	int ret;
408 
409 	ret = rproc_boot(ab_ahb->tgt_rproc);
410 	if (ret)
411 		ath11k_err(ab, "failed to boot the remote processor Q6\n");
412 
413 	return ret;
414 }
415 
416 static void ath11k_ahb_power_down(struct ath11k_base *ab, bool is_suspend)
417 {
418 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
419 
420 	rproc_shutdown(ab_ahb->tgt_rproc);
421 }
422 
423 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
424 {
425 	struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
426 
427 	cfg->tgt_ce_len = ab->hw_params.target_ce_count;
428 	cfg->tgt_ce = ab->hw_params.target_ce_config;
429 	cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
430 	cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
431 	ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id;
432 }
433 
434 static void ath11k_ahb_free_ext_irq_grp(struct ath11k_base *ab,
435 					struct ath11k_ext_irq_grp *irq_grp)
436 {
437 	int j;
438 
439 	for (j = 0; j < irq_grp->num_irq; j++)
440 		free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
441 
442 	netif_napi_del(&irq_grp->napi);
443 	free_netdev(irq_grp->napi_ndev);
444 }
445 
446 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
447 {
448 	int i;
449 
450 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++)
451 		ath11k_ahb_free_ext_irq_grp(ab, &ab->ext_irq_grp[i]);
452 }
453 
454 static void ath11k_ahb_free_ce_irqs(struct ath11k_base *ab, int max_idx)
455 {
456 	int irq_idx, i;
457 
458 	for (i = 0; i < max_idx; i++) {
459 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
460 			continue;
461 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
462 		free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
463 	}
464 }
465 
466 static void ath11k_ahb_free_irq(struct ath11k_base *ab)
467 {
468 	if (ab->hw_params.hybrid_bus_type)
469 		return ath11k_pcic_free_irq(ab);
470 
471 	ath11k_ahb_free_ce_irqs(ab, ab->hw_params.ce_count);
472 	ath11k_ahb_free_ext_irq(ab);
473 }
474 
475 static void ath11k_ahb_ce_tasklet(struct tasklet_struct *t)
476 {
477 	struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
478 
479 	ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
480 
481 	ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
482 }
483 
484 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
485 {
486 	struct ath11k_ce_pipe *ce_pipe = arg;
487 
488 	/* last interrupt received for this CE */
489 	ce_pipe->timestamp = jiffies;
490 
491 	ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
492 
493 	tasklet_schedule(&ce_pipe->intr_tq);
494 
495 	return IRQ_HANDLED;
496 }
497 
498 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget)
499 {
500 	struct ath11k_ext_irq_grp *irq_grp = container_of(napi,
501 						struct ath11k_ext_irq_grp,
502 						napi);
503 	struct ath11k_base *ab = irq_grp->ab;
504 	int work_done;
505 
506 	work_done = ath11k_dp_service_srng(ab, irq_grp, budget);
507 	if (work_done < budget) {
508 		napi_complete_done(napi, work_done);
509 		ath11k_ahb_ext_grp_enable(irq_grp);
510 	}
511 
512 	if (work_done > budget)
513 		work_done = budget;
514 
515 	return work_done;
516 }
517 
518 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
519 {
520 	struct ath11k_ext_irq_grp *irq_grp = arg;
521 
522 	/* last interrupt received for this group */
523 	irq_grp->timestamp = jiffies;
524 
525 	ath11k_ahb_ext_grp_disable(irq_grp);
526 
527 	napi_schedule(&irq_grp->napi);
528 
529 	return IRQ_HANDLED;
530 }
531 
532 static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
533 {
534 	struct ath11k_hw_params *hw = &ab->hw_params;
535 	struct ath11k_ext_irq_grp *irq_grp;
536 	int i, j;
537 	int irq;
538 	int ret;
539 
540 	for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
541 		u32 num_irq = 0;
542 
543 		irq_grp = &ab->ext_irq_grp[i];
544 
545 		irq_grp->ab = ab;
546 		irq_grp->grp_id = i;
547 
548 		irq_grp->napi_ndev = alloc_netdev_dummy(0);
549 		if (!irq_grp->napi_ndev) {
550 			ret = -ENOMEM;
551 			irq_grp->num_irq = 0;
552 			goto err_request_irq;
553 		}
554 
555 		netif_napi_add(irq_grp->napi_ndev, &irq_grp->napi,
556 			       ath11k_ahb_ext_grp_napi_poll);
557 
558 		for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
559 			if (ab->hw_params.ring_mask->tx[i] & BIT(j)) {
560 				irq_grp->irqs[num_irq++] =
561 					wbm2host_tx_completions_ring1 - j;
562 			}
563 
564 			if (ab->hw_params.ring_mask->rx[i] & BIT(j)) {
565 				irq_grp->irqs[num_irq++] =
566 					reo2host_destination_ring1 - j;
567 			}
568 
569 			if (ab->hw_params.ring_mask->rx_err[i] & BIT(j))
570 				irq_grp->irqs[num_irq++] = reo2host_exception;
571 
572 			if (ab->hw_params.ring_mask->rx_wbm_rel[i] & BIT(j))
573 				irq_grp->irqs[num_irq++] = wbm2host_rx_release;
574 
575 			if (ab->hw_params.ring_mask->reo_status[i] & BIT(j))
576 				irq_grp->irqs[num_irq++] = reo2host_status;
577 
578 			if (j < ab->hw_params.max_radios) {
579 				if (ab->hw_params.ring_mask->rxdma2host[i] & BIT(j)) {
580 					irq_grp->irqs[num_irq++] =
581 						rxdma2host_destination_ring_mac1 -
582 						ath11k_hw_get_mac_from_pdev_id(hw, j);
583 				}
584 
585 				if (ab->hw_params.ring_mask->host2rxdma[i] & BIT(j)) {
586 					irq_grp->irqs[num_irq++] =
587 						host2rxdma_host_buf_ring_mac1 -
588 						ath11k_hw_get_mac_from_pdev_id(hw, j);
589 				}
590 
591 				if (ab->hw_params.ring_mask->rx_mon_status[i] & BIT(j)) {
592 					irq_grp->irqs[num_irq++] =
593 						ppdu_end_interrupts_mac1 -
594 						ath11k_hw_get_mac_from_pdev_id(hw, j);
595 					irq_grp->irqs[num_irq++] =
596 						rxdma2host_monitor_status_ring_mac1 -
597 						ath11k_hw_get_mac_from_pdev_id(hw, j);
598 				}
599 			}
600 		}
601 		for (j = 0; j < num_irq; j++) {
602 			int irq_idx = irq_grp->irqs[j];
603 
604 			irq = platform_get_irq_byname(ab->pdev,
605 						      irq_name[irq_idx]);
606 			irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
607 			ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
608 					  IRQF_TRIGGER_RISING,
609 					  irq_name[irq_idx], irq_grp);
610 			if (ret) {
611 				ath11k_err(ab, "failed request_irq for %d\n",
612 					   irq);
613 				irq_grp->num_irq = j;
614 				ath11k_ahb_free_ext_irq_grp(ab, irq_grp);
615 				goto err_request_irq;
616 			}
617 			ab->irq_num[irq_idx] = irq;
618 		}
619 
620 		irq_grp->num_irq = num_irq;
621 	}
622 
623 	return 0;
624 
625 err_request_irq:
626 	for (i--; i >= 0; i--) {
627 		irq_grp = &ab->ext_irq_grp[i];
628 		ath11k_ahb_free_ext_irq_grp(ab, irq_grp);
629 	}
630 	return ret;
631 }
632 
633 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
634 {
635 	int irq, irq_idx, i;
636 	int ret;
637 
638 	if (ab->hw_params.hybrid_bus_type)
639 		return ath11k_pcic_config_irq(ab);
640 
641 	/* Configure CE irqs */
642 	for (i = 0; i < ab->hw_params.ce_count; i++) {
643 		struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
644 
645 		if (ath11k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)
646 			continue;
647 
648 		irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
649 
650 		tasklet_setup(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet);
651 		irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]);
652 		ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
653 				  IRQF_TRIGGER_RISING, irq_name[irq_idx],
654 				  ce_pipe);
655 		if (ret) {
656 			ath11k_err(ab, "failed request_irq for %d\n", irq);
657 			ath11k_ahb_free_ce_irqs(ab, i);
658 			return ret;
659 		}
660 
661 		ab->irq_num[irq_idx] = irq;
662 	}
663 
664 	/* Configure external interrupts */
665 	ret = ath11k_ahb_config_ext_irq(ab);
666 	if (ret) {
667 		ath11k_err(ab, "failed to configure ext irq: %d\n", ret);
668 		ath11k_ahb_free_ce_irqs(ab, ab->hw_params.ce_count);
669 		return ret;
670 	}
671 
672 	return 0;
673 }
674 
675 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
676 					  u8 *ul_pipe, u8 *dl_pipe)
677 {
678 	const struct service_to_pipe *entry;
679 	bool ul_set = false, dl_set = false;
680 	int i;
681 
682 	for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) {
683 		entry = &ab->hw_params.svc_to_ce_map[i];
684 
685 		if (__le32_to_cpu(entry->service_id) != service_id)
686 			continue;
687 
688 		switch (__le32_to_cpu(entry->pipedir)) {
689 		case PIPEDIR_NONE:
690 			break;
691 		case PIPEDIR_IN:
692 			WARN_ON(dl_set);
693 			*dl_pipe = __le32_to_cpu(entry->pipenum);
694 			dl_set = true;
695 			break;
696 		case PIPEDIR_OUT:
697 			WARN_ON(ul_set);
698 			*ul_pipe = __le32_to_cpu(entry->pipenum);
699 			ul_set = true;
700 			break;
701 		case PIPEDIR_INOUT:
702 			WARN_ON(dl_set);
703 			WARN_ON(ul_set);
704 			*dl_pipe = __le32_to_cpu(entry->pipenum);
705 			*ul_pipe = __le32_to_cpu(entry->pipenum);
706 			dl_set = true;
707 			ul_set = true;
708 			break;
709 		}
710 	}
711 
712 	if (WARN_ON(!ul_set || !dl_set))
713 		return -ENOENT;
714 
715 	return 0;
716 }
717 
718 static int ath11k_ahb_hif_suspend(struct ath11k_base *ab)
719 {
720 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
721 	u32 wake_irq;
722 	u32 value = 0;
723 	int ret;
724 
725 	if (!device_may_wakeup(ab->dev))
726 		return -EPERM;
727 
728 	wake_irq = ab->irq_num[ATH11K_PCI_IRQ_CE0_OFFSET + ATH11K_PCI_CE_WAKE_IRQ];
729 
730 	ret = enable_irq_wake(wake_irq);
731 	if (ret) {
732 		ath11k_err(ab, "failed to enable wakeup irq :%d\n", ret);
733 		return ret;
734 	}
735 
736 	value = u32_encode_bits(ab_ahb->smp2p_info.seq_no++,
737 				ATH11K_AHB_SMP2P_SMEM_SEQ_NO);
738 	value |= u32_encode_bits(ATH11K_AHB_POWER_SAVE_ENTER,
739 				 ATH11K_AHB_SMP2P_SMEM_MSG);
740 
741 	ret = qcom_smem_state_update_bits(ab_ahb->smp2p_info.smem_state,
742 					  ATH11K_AHB_SMP2P_SMEM_VALUE_MASK, value);
743 	if (ret) {
744 		ath11k_err(ab, "failed to send smp2p power save enter cmd :%d\n", ret);
745 		return ret;
746 	}
747 
748 	ath11k_dbg(ab, ATH11K_DBG_AHB, "device suspended\n");
749 
750 	return ret;
751 }
752 
753 static int ath11k_ahb_hif_resume(struct ath11k_base *ab)
754 {
755 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
756 	u32 wake_irq;
757 	u32 value = 0;
758 	int ret;
759 
760 	if (!device_may_wakeup(ab->dev))
761 		return -EPERM;
762 
763 	wake_irq = ab->irq_num[ATH11K_PCI_IRQ_CE0_OFFSET + ATH11K_PCI_CE_WAKE_IRQ];
764 
765 	ret = disable_irq_wake(wake_irq);
766 	if (ret) {
767 		ath11k_err(ab, "failed to disable wakeup irq: %d\n", ret);
768 		return ret;
769 	}
770 
771 	reinit_completion(&ab->wow.wakeup_completed);
772 
773 	value = u32_encode_bits(ab_ahb->smp2p_info.seq_no++,
774 				ATH11K_AHB_SMP2P_SMEM_SEQ_NO);
775 	value |= u32_encode_bits(ATH11K_AHB_POWER_SAVE_EXIT,
776 				 ATH11K_AHB_SMP2P_SMEM_MSG);
777 
778 	ret = qcom_smem_state_update_bits(ab_ahb->smp2p_info.smem_state,
779 					  ATH11K_AHB_SMP2P_SMEM_VALUE_MASK, value);
780 	if (ret) {
781 		ath11k_err(ab, "failed to send smp2p power save enter cmd :%d\n", ret);
782 		return ret;
783 	}
784 
785 	ret = wait_for_completion_timeout(&ab->wow.wakeup_completed, 3 * HZ);
786 	if (ret == 0) {
787 		ath11k_warn(ab, "timed out while waiting for wow wakeup completion\n");
788 		return -ETIMEDOUT;
789 	}
790 
791 	ath11k_dbg(ab, ATH11K_DBG_AHB, "device resumed\n");
792 
793 	return 0;
794 }
795 
796 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_ipq8074 = {
797 	.start = ath11k_ahb_start,
798 	.stop = ath11k_ahb_stop,
799 	.read32 = ath11k_ahb_read32,
800 	.write32 = ath11k_ahb_write32,
801 	.read = NULL,
802 	.irq_enable = ath11k_ahb_ext_irq_enable,
803 	.irq_disable = ath11k_ahb_ext_irq_disable,
804 	.map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
805 	.power_down = ath11k_ahb_power_down,
806 	.power_up = ath11k_ahb_power_up,
807 };
808 
809 static const struct ath11k_hif_ops ath11k_ahb_hif_ops_wcn6750 = {
810 	.start = ath11k_pcic_start,
811 	.stop = ath11k_pcic_stop,
812 	.read32 = ath11k_pcic_read32,
813 	.write32 = ath11k_pcic_write32,
814 	.read = NULL,
815 	.irq_enable = ath11k_pcic_ext_irq_enable,
816 	.irq_disable = ath11k_pcic_ext_irq_disable,
817 	.get_msi_address =  ath11k_pcic_get_msi_address,
818 	.get_user_msi_vector = ath11k_pcic_get_user_msi_assignment,
819 	.map_service_to_pipe = ath11k_pcic_map_service_to_pipe,
820 	.power_down = ath11k_ahb_power_down,
821 	.power_up = ath11k_ahb_power_up,
822 	.suspend = ath11k_ahb_hif_suspend,
823 	.resume = ath11k_ahb_hif_resume,
824 	.ce_irq_enable = ath11k_pci_enable_ce_irqs_except_wake_irq,
825 	.ce_irq_disable = ath11k_pci_disable_ce_irqs_except_wake_irq,
826 };
827 
828 static int ath11k_core_get_rproc(struct ath11k_base *ab)
829 {
830 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
831 	struct device *dev = ab->dev;
832 	struct rproc *prproc;
833 	phandle rproc_phandle;
834 
835 	if (of_property_read_u32(dev->of_node, "qcom,rproc", &rproc_phandle)) {
836 		ath11k_err(ab, "failed to get q6_rproc handle\n");
837 		return -ENOENT;
838 	}
839 
840 	prproc = rproc_get_by_phandle(rproc_phandle);
841 	if (!prproc)
842 		return dev_err_probe(&ab->pdev->dev, -EPROBE_DEFER, "failed to get rproc\n");
843 	ab_ahb->tgt_rproc = prproc;
844 
845 	return 0;
846 }
847 
848 static int ath11k_ahb_setup_msi_resources(struct ath11k_base *ab)
849 {
850 	struct platform_device *pdev = ab->pdev;
851 	phys_addr_t msi_addr_pa;
852 	dma_addr_t msi_addr_iova;
853 	struct resource *res;
854 	int int_prop;
855 	int ret;
856 	int i;
857 
858 	ret = ath11k_pcic_init_msi_config(ab);
859 	if (ret) {
860 		ath11k_err(ab, "failed to init msi config: %d\n", ret);
861 		return ret;
862 	}
863 
864 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
865 	if (!res) {
866 		ath11k_err(ab, "failed to fetch msi_addr\n");
867 		return -ENOENT;
868 	}
869 
870 	msi_addr_pa = res->start;
871 	msi_addr_iova = dma_map_resource(ab->dev, msi_addr_pa, PAGE_SIZE,
872 					 DMA_FROM_DEVICE, 0);
873 	if (dma_mapping_error(ab->dev, msi_addr_iova))
874 		return -ENOMEM;
875 
876 	ab->pci.msi.addr_lo = lower_32_bits(msi_addr_iova);
877 	ab->pci.msi.addr_hi = upper_32_bits(msi_addr_iova);
878 
879 	ret = of_property_read_u32_index(ab->dev->of_node, "interrupts", 1, &int_prop);
880 	if (ret)
881 		return ret;
882 
883 	ab->pci.msi.ep_base_data = int_prop + 32;
884 
885 	for (i = 0; i < ab->pci.msi.config->total_vectors; i++) {
886 		ret = platform_get_irq(pdev, i);
887 		if (ret < 0)
888 			return ret;
889 
890 		ab->pci.msi.irqs[i] = ret;
891 	}
892 
893 	set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags);
894 
895 	return 0;
896 }
897 
898 static int ath11k_ahb_setup_smp2p_handle(struct ath11k_base *ab)
899 {
900 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
901 
902 	if (!ab->hw_params.smp2p_wow_exit)
903 		return 0;
904 
905 	ab_ahb->smp2p_info.smem_state = qcom_smem_state_get(ab->dev, "wlan-smp2p-out",
906 							    &ab_ahb->smp2p_info.smem_bit);
907 	if (IS_ERR(ab_ahb->smp2p_info.smem_state)) {
908 		ath11k_err(ab, "failed to fetch smem state: %ld\n",
909 			   PTR_ERR(ab_ahb->smp2p_info.smem_state));
910 		return PTR_ERR(ab_ahb->smp2p_info.smem_state);
911 	}
912 
913 	return 0;
914 }
915 
916 static void ath11k_ahb_release_smp2p_handle(struct ath11k_base *ab)
917 {
918 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
919 
920 	if (!ab->hw_params.smp2p_wow_exit)
921 		return;
922 
923 	qcom_smem_state_put(ab_ahb->smp2p_info.smem_state);
924 }
925 
926 static int ath11k_ahb_setup_resources(struct ath11k_base *ab)
927 {
928 	struct platform_device *pdev = ab->pdev;
929 	struct resource *mem_res;
930 	void __iomem *mem;
931 
932 	if (ab->hw_params.hybrid_bus_type)
933 		return ath11k_ahb_setup_msi_resources(ab);
934 
935 	mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res);
936 	if (IS_ERR(mem)) {
937 		dev_err(&pdev->dev, "ioremap error\n");
938 		return PTR_ERR(mem);
939 	}
940 
941 	ab->mem = mem;
942 	ab->mem_len = resource_size(mem_res);
943 
944 	return 0;
945 }
946 
947 static int ath11k_ahb_setup_msa_resources(struct ath11k_base *ab)
948 {
949 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
950 	struct device *dev = ab->dev;
951 	struct resource r;
952 	int ret;
953 
954 	ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &r);
955 	if (ret) {
956 		dev_err(dev, "failed to resolve msa fixed region\n");
957 		return ret;
958 	}
959 
960 	ab_ahb->fw.msa_paddr = r.start;
961 	ab_ahb->fw.msa_size = resource_size(&r);
962 
963 	ret = of_reserved_mem_region_to_resource(dev->of_node, 1, &r);
964 	if (ret) {
965 		dev_err(dev, "failed to resolve ce fixed region\n");
966 		return ret;
967 	}
968 
969 	ab_ahb->fw.ce_paddr = r.start;
970 	ab_ahb->fw.ce_size = resource_size(&r);
971 
972 	return 0;
973 }
974 
975 static int ath11k_ahb_ce_remap(struct ath11k_base *ab)
976 {
977 	const struct ce_remap *ce_remap = ab->hw_params.ce_remap;
978 	struct platform_device *pdev = ab->pdev;
979 
980 	if (!ce_remap) {
981 		/* no separate CE register space */
982 		ab->mem_ce = ab->mem;
983 		return 0;
984 	}
985 
986 	/* ce register space is moved out of wcss unlike ipq8074 or ipq6018
987 	 * and the space is not contiguous, hence remapping the CE registers
988 	 * to a new space for accessing them.
989 	 */
990 	ab->mem_ce = ioremap(ce_remap->base, ce_remap->size);
991 	if (!ab->mem_ce) {
992 		dev_err(&pdev->dev, "ce ioremap error\n");
993 		return -ENOMEM;
994 	}
995 
996 	return 0;
997 }
998 
999 static void ath11k_ahb_ce_unmap(struct ath11k_base *ab)
1000 {
1001 	if (ab->hw_params.ce_remap)
1002 		iounmap(ab->mem_ce);
1003 }
1004 
1005 static int ath11k_ahb_fw_resources_init(struct ath11k_base *ab)
1006 {
1007 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
1008 	struct device *host_dev = ab->dev;
1009 	struct platform_device_info info = {};
1010 	struct iommu_domain *iommu_dom;
1011 	struct platform_device *pdev;
1012 	struct device_node *node;
1013 	int ret;
1014 
1015 	/* Chipsets not requiring MSA need not initialize
1016 	 * MSA resources, return success in such cases.
1017 	 */
1018 	if (!ab->hw_params.fixed_fw_mem)
1019 		return 0;
1020 
1021 	node = of_get_child_by_name(host_dev->of_node, "wifi-firmware");
1022 	if (!node) {
1023 		ab_ahb->fw.use_tz = true;
1024 		return 0;
1025 	}
1026 
1027 	ret = ath11k_ahb_setup_msa_resources(ab);
1028 	if (ret) {
1029 		ath11k_err(ab, "failed to setup msa resources\n");
1030 		of_node_put(node);
1031 		return ret;
1032 	}
1033 
1034 	info.fwnode = &node->fwnode;
1035 	info.parent = host_dev;
1036 	info.name = node->name;
1037 	info.dma_mask = DMA_BIT_MASK(32);
1038 
1039 	pdev = platform_device_register_full(&info);
1040 	if (IS_ERR(pdev)) {
1041 		of_node_put(node);
1042 		return PTR_ERR(pdev);
1043 	}
1044 
1045 	ret = of_dma_configure(&pdev->dev, node, true);
1046 	if (ret) {
1047 		ath11k_err(ab, "dma configure fail: %d\n", ret);
1048 		goto err_unregister;
1049 	}
1050 
1051 	ab_ahb->fw.dev = &pdev->dev;
1052 
1053 	iommu_dom = iommu_paging_domain_alloc(ab_ahb->fw.dev);
1054 	if (IS_ERR(iommu_dom)) {
1055 		ath11k_err(ab, "failed to allocate iommu domain\n");
1056 		ret = PTR_ERR(iommu_dom);
1057 		goto err_unregister;
1058 	}
1059 
1060 	ret = iommu_attach_device(iommu_dom, ab_ahb->fw.dev);
1061 	if (ret) {
1062 		ath11k_err(ab, "could not attach device: %d\n", ret);
1063 		goto err_iommu_free;
1064 	}
1065 
1066 	ret = iommu_map(iommu_dom, ab_ahb->fw.msa_paddr,
1067 			ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size,
1068 			IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
1069 	if (ret) {
1070 		ath11k_err(ab, "failed to map firmware region: %d\n", ret);
1071 		goto err_iommu_detach;
1072 	}
1073 
1074 	ret = iommu_map(iommu_dom, ab_ahb->fw.ce_paddr,
1075 			ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size,
1076 			IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
1077 	if (ret) {
1078 		ath11k_err(ab, "failed to map firmware CE region: %d\n", ret);
1079 		goto err_iommu_unmap;
1080 	}
1081 
1082 	ab_ahb->fw.use_tz = false;
1083 	ab_ahb->fw.iommu_domain = iommu_dom;
1084 	of_node_put(node);
1085 
1086 	return 0;
1087 
1088 err_iommu_unmap:
1089 	iommu_unmap(iommu_dom, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
1090 
1091 err_iommu_detach:
1092 	iommu_detach_device(iommu_dom, ab_ahb->fw.dev);
1093 
1094 err_iommu_free:
1095 	iommu_domain_free(iommu_dom);
1096 
1097 err_unregister:
1098 	platform_device_unregister(pdev);
1099 	of_node_put(node);
1100 
1101 	return ret;
1102 }
1103 
1104 static int ath11k_ahb_fw_resource_deinit(struct ath11k_base *ab)
1105 {
1106 	struct ath11k_ahb *ab_ahb = ath11k_ahb_priv(ab);
1107 	struct iommu_domain *iommu;
1108 	size_t unmapped_size;
1109 
1110 	/* Chipsets not requiring MSA would have not initialized
1111 	 * MSA resources, return success in such cases.
1112 	 */
1113 	if (!ab->hw_params.fixed_fw_mem)
1114 		return 0;
1115 
1116 	if (ab_ahb->fw.use_tz)
1117 		return 0;
1118 
1119 	iommu = ab_ahb->fw.iommu_domain;
1120 
1121 	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.msa_paddr, ab_ahb->fw.msa_size);
1122 	if (unmapped_size != ab_ahb->fw.msa_size)
1123 		ath11k_err(ab, "failed to unmap firmware: %zu\n",
1124 			   unmapped_size);
1125 
1126 	unmapped_size = iommu_unmap(iommu, ab_ahb->fw.ce_paddr, ab_ahb->fw.ce_size);
1127 	if (unmapped_size != ab_ahb->fw.ce_size)
1128 		ath11k_err(ab, "failed to unmap firmware CE memory: %zu\n",
1129 			   unmapped_size);
1130 
1131 	iommu_detach_device(iommu, ab_ahb->fw.dev);
1132 	iommu_domain_free(iommu);
1133 
1134 	platform_device_unregister(to_platform_device(ab_ahb->fw.dev));
1135 
1136 	return 0;
1137 }
1138 
1139 static int ath11k_ahb_probe(struct platform_device *pdev)
1140 {
1141 	struct ath11k_base *ab;
1142 	const struct ath11k_hif_ops *hif_ops;
1143 	const struct ath11k_pci_ops *pci_ops;
1144 	enum ath11k_hw_rev hw_rev;
1145 	int ret;
1146 
1147 	hw_rev = (uintptr_t)device_get_match_data(&pdev->dev);
1148 
1149 	switch (hw_rev) {
1150 	case ATH11K_HW_IPQ8074:
1151 	case ATH11K_HW_IPQ6018_HW10:
1152 	case ATH11K_HW_IPQ5018_HW10:
1153 		hif_ops = &ath11k_ahb_hif_ops_ipq8074;
1154 		pci_ops = NULL;
1155 		break;
1156 	case ATH11K_HW_WCN6750_HW10:
1157 		hif_ops = &ath11k_ahb_hif_ops_wcn6750;
1158 		pci_ops = &ath11k_ahb_pci_ops_wcn6750;
1159 		break;
1160 	default:
1161 		dev_err(&pdev->dev, "unsupported device type %d\n", hw_rev);
1162 		return -EOPNOTSUPP;
1163 	}
1164 
1165 	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1166 	if (ret) {
1167 		dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
1168 		return ret;
1169 	}
1170 
1171 	ab = ath11k_core_alloc(&pdev->dev, sizeof(struct ath11k_ahb),
1172 			       ATH11K_BUS_AHB);
1173 	if (!ab) {
1174 		dev_err(&pdev->dev, "failed to allocate ath11k base\n");
1175 		return -ENOMEM;
1176 	}
1177 
1178 	ab->hif.ops = hif_ops;
1179 	ab->pdev = pdev;
1180 	ab->hw_rev = hw_rev;
1181 	ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL;
1182 	platform_set_drvdata(pdev, ab);
1183 
1184 	ret = ath11k_pcic_register_pci_ops(ab, pci_ops);
1185 	if (ret) {
1186 		ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
1187 		goto err_core_free;
1188 	}
1189 
1190 	ret = ath11k_core_pre_init(ab);
1191 	if (ret)
1192 		goto err_core_free;
1193 
1194 	ret = ath11k_ahb_setup_resources(ab);
1195 	if (ret)
1196 		goto err_core_free;
1197 
1198 	ret = ath11k_ahb_ce_remap(ab);
1199 	if (ret)
1200 		goto err_core_free;
1201 
1202 	ret = ath11k_ahb_fw_resources_init(ab);
1203 	if (ret)
1204 		goto err_ce_unmap;
1205 
1206 	ret = ath11k_ahb_setup_smp2p_handle(ab);
1207 	if (ret)
1208 		goto err_fw_deinit;
1209 
1210 	ret = ath11k_hal_srng_init(ab);
1211 	if (ret)
1212 		goto err_release_smp2p_handle;
1213 
1214 	ret = ath11k_ce_alloc_pipes(ab);
1215 	if (ret) {
1216 		ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
1217 		goto err_hal_srng_deinit;
1218 	}
1219 
1220 	ath11k_ahb_init_qmi_ce_config(ab);
1221 
1222 	ret = ath11k_core_get_rproc(ab);
1223 	if (ret)
1224 		goto err_ce_free;
1225 
1226 	ret = ath11k_core_init(ab);
1227 	if (ret) {
1228 		ath11k_err(ab, "failed to init core: %d\n", ret);
1229 		goto err_ce_free;
1230 	}
1231 
1232 	ret = ath11k_ahb_config_irq(ab);
1233 	if (ret) {
1234 		ath11k_err(ab, "failed to configure irq: %d\n", ret);
1235 		goto err_ce_free;
1236 	}
1237 
1238 	ath11k_qmi_fwreset_from_cold_boot(ab);
1239 
1240 	return 0;
1241 
1242 err_ce_free:
1243 	ath11k_ce_free_pipes(ab);
1244 
1245 err_hal_srng_deinit:
1246 	ath11k_hal_srng_deinit(ab);
1247 
1248 err_release_smp2p_handle:
1249 	ath11k_ahb_release_smp2p_handle(ab);
1250 
1251 err_fw_deinit:
1252 	ath11k_ahb_fw_resource_deinit(ab);
1253 
1254 err_ce_unmap:
1255 	ath11k_ahb_ce_unmap(ab);
1256 
1257 err_core_free:
1258 	ath11k_core_free(ab);
1259 	platform_set_drvdata(pdev, NULL);
1260 
1261 	return ret;
1262 }
1263 
1264 static void ath11k_ahb_remove_prepare(struct ath11k_base *ab)
1265 {
1266 	unsigned long left;
1267 
1268 	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags)) {
1269 		left = wait_for_completion_timeout(&ab->driver_recovery,
1270 						   ATH11K_AHB_RECOVERY_TIMEOUT);
1271 		if (!left)
1272 			ath11k_warn(ab, "failed to receive recovery response completion\n");
1273 	}
1274 
1275 	set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
1276 	cancel_work_sync(&ab->restart_work);
1277 	cancel_work_sync(&ab->qmi.event_work);
1278 }
1279 
1280 static void ath11k_ahb_free_resources(struct ath11k_base *ab)
1281 {
1282 	struct platform_device *pdev = ab->pdev;
1283 
1284 	ath11k_ahb_free_irq(ab);
1285 	ath11k_hal_srng_deinit(ab);
1286 	ath11k_ahb_release_smp2p_handle(ab);
1287 	ath11k_ahb_fw_resource_deinit(ab);
1288 	ath11k_ce_free_pipes(ab);
1289 	ath11k_ahb_ce_unmap(ab);
1290 
1291 	ath11k_core_free(ab);
1292 	platform_set_drvdata(pdev, NULL);
1293 }
1294 
1295 static void ath11k_ahb_remove(struct platform_device *pdev)
1296 {
1297 	struct ath11k_base *ab = platform_get_drvdata(pdev);
1298 
1299 	if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
1300 		ath11k_ahb_power_down(ab, false);
1301 		ath11k_debugfs_soc_destroy(ab);
1302 		ath11k_qmi_deinit_service(ab);
1303 		goto qmi_fail;
1304 	}
1305 
1306 	ath11k_ahb_remove_prepare(ab);
1307 	ath11k_core_deinit(ab);
1308 
1309 qmi_fail:
1310 	ath11k_fw_destroy(ab);
1311 	ath11k_ahb_free_resources(ab);
1312 }
1313 
1314 static void ath11k_ahb_shutdown(struct platform_device *pdev)
1315 {
1316 	struct ath11k_base *ab = platform_get_drvdata(pdev);
1317 
1318 	/* platform shutdown() & remove() are mutually exclusive.
1319 	 * remove() is invoked during rmmod & shutdown() during
1320 	 * system reboot/shutdown.
1321 	 */
1322 	ath11k_ahb_remove_prepare(ab);
1323 
1324 	if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)))
1325 		goto free_resources;
1326 
1327 	ath11k_core_deinit(ab);
1328 
1329 free_resources:
1330 	ath11k_fw_destroy(ab);
1331 	ath11k_ahb_free_resources(ab);
1332 }
1333 
1334 static struct platform_driver ath11k_ahb_driver = {
1335 	.driver = {
1336 		.name = "ath11k",
1337 		.of_match_table = ath11k_ahb_of_match,
1338 	},
1339 	.probe = ath11k_ahb_probe,
1340 	.remove = ath11k_ahb_remove,
1341 	.shutdown = ath11k_ahb_shutdown,
1342 };
1343 
1344 module_platform_driver(ath11k_ahb_driver);
1345 
1346 MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax WLAN AHB devices");
1347 MODULE_LICENSE("Dual BSD/GPL");
1348