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