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
ath11k_ahb_get_msi_irq_wcn6750(struct ath11k_base * ab,unsigned int vector)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
ath11k_ahb_get_window_start_wcn6750(struct ath11k_base * ab,u32 offset)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
ath11k_ahb_window_write32_wcn6750(struct ath11k_base * ab,u32 offset,u32 value)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
ath11k_ahb_window_read32_wcn6750(struct ath11k_base * ab,u32 offset)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
ath11k_ahb_read32(struct ath11k_base * ab,u32 offset)199 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
200 {
201 return ioread32(ab->mem + offset);
202 }
203
ath11k_ahb_write32(struct ath11k_base * ab,u32 offset,u32 value)204 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
205 {
206 iowrite32(value, ab->mem + offset);
207 }
208
ath11k_ahb_kill_tasklets(struct ath11k_base * ab)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
ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp * irq_grp)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
__ath11k_ahb_ext_irq_disable(struct ath11k_base * ab)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
ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp * irq_grp)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
ath11k_ahb_setbit32(struct ath11k_base * ab,u8 bit,u32 offset)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
ath11k_ahb_clearbit32(struct ath11k_base * ab,u8 bit,u32 offset)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
ath11k_ahb_ce_irq_enable(struct ath11k_base * ab,u16 ce_id)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
ath11k_ahb_ce_irq_disable(struct ath11k_base * ab,u16 ce_id)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
ath11k_ahb_sync_ce_irqs(struct ath11k_base * ab)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
ath11k_ahb_sync_ext_irqs(struct ath11k_base * ab)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
ath11k_ahb_ce_irqs_enable(struct ath11k_base * ab)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
ath11k_ahb_ce_irqs_disable(struct ath11k_base * ab)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
ath11k_ahb_start(struct ath11k_base * ab)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
ath11k_ahb_ext_irq_enable(struct ath11k_base * ab)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
ath11k_ahb_ext_irq_disable(struct ath11k_base * ab)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
ath11k_ahb_stop(struct ath11k_base * ab)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
ath11k_ahb_power_up(struct ath11k_base * ab)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
ath11k_ahb_power_down(struct ath11k_base * ab,bool is_suspend)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
ath11k_ahb_init_qmi_ce_config(struct ath11k_base * ab)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
ath11k_ahb_free_ext_irq_grp(struct ath11k_base * ab,struct ath11k_ext_irq_grp * irq_grp)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
ath11k_ahb_free_ext_irq(struct ath11k_base * ab)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
ath11k_ahb_free_ce_irqs(struct ath11k_base * ab,int max_idx)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
ath11k_ahb_free_irq(struct ath11k_base * ab)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
ath11k_ahb_ce_tasklet(struct tasklet_struct * t)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
ath11k_ahb_ce_interrupt_handler(int irq,void * arg)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
ath11k_ahb_ext_grp_napi_poll(struct napi_struct * napi,int budget)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
ath11k_ahb_ext_interrupt_handler(int irq,void * arg)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
ath11k_ahb_config_ext_irq(struct ath11k_base * ab)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
ath11k_ahb_config_irq(struct ath11k_base * ab)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
ath11k_ahb_map_service_to_pipe(struct ath11k_base * ab,u16 service_id,u8 * ul_pipe,u8 * dl_pipe)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
ath11k_ahb_hif_suspend(struct ath11k_base * ab)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
ath11k_ahb_hif_resume(struct ath11k_base * ab)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
ath11k_core_get_rproc(struct ath11k_base * ab)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
ath11k_ahb_setup_msi_resources(struct ath11k_base * ab)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
ath11k_ahb_setup_smp2p_handle(struct ath11k_base * ab)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
ath11k_ahb_release_smp2p_handle(struct ath11k_base * ab)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
ath11k_ahb_setup_resources(struct ath11k_base * ab)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
ath11k_ahb_setup_msa_resources(struct ath11k_base * ab)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
ath11k_ahb_ce_remap(struct ath11k_base * ab)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
ath11k_ahb_ce_unmap(struct ath11k_base * ab)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
ath11k_ahb_fw_resources_init(struct ath11k_base * ab)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
ath11k_ahb_fw_resource_deinit(struct ath11k_base * ab)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
ath11k_ahb_probe(struct platform_device * pdev)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
ath11k_ahb_remove_prepare(struct ath11k_base * ab)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
ath11k_ahb_free_resources(struct ath11k_base * ab)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
ath11k_ahb_remove(struct platform_device * pdev)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
ath11k_ahb_shutdown(struct platform_device * pdev)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