]> Git Repo - linux.git/blob - drivers/net/wireless/ath/ath11k/ahb.c
drm/nouveau/kms: Don't change EDID when it hasn't actually changed
[linux.git] / drivers / net / wireless / ath / ath11k / ahb.c
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/module.h>
7 #include <linux/platform_device.h>
8 #include <linux/of_device.h>
9 #include <linux/of.h>
10 #include <linux/dma-mapping.h>
11 #include "ahb.h"
12 #include "debug.h"
13 #include "hif.h"
14 #include <linux/remoteproc.h>
15
16 static const struct of_device_id ath11k_ahb_of_match[] = {
17         /* TODO: Should we change the compatible string to something similar
18          * to one that ath10k uses?
19          */
20         { .compatible = "qcom,ipq8074-wifi",
21           .data = (void *)ATH11K_HW_IPQ8074,
22         },
23         { }
24 };
25
26 MODULE_DEVICE_TABLE(of, ath11k_ahb_of_match);
27
28 /* Target firmware's Copy Engine configuration. */
29 static const struct ce_pipe_config target_ce_config_wlan[] = {
30         /* CE0: host->target HTC control and raw streams */
31         {
32                 .pipenum = __cpu_to_le32(0),
33                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
34                 .nentries = __cpu_to_le32(32),
35                 .nbytes_max = __cpu_to_le32(2048),
36                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
37                 .reserved = __cpu_to_le32(0),
38         },
39
40         /* CE1: target->host HTT + HTC control */
41         {
42                 .pipenum = __cpu_to_le32(1),
43                 .pipedir = __cpu_to_le32(PIPEDIR_IN),
44                 .nentries = __cpu_to_le32(32),
45                 .nbytes_max = __cpu_to_le32(2048),
46                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
47                 .reserved = __cpu_to_le32(0),
48         },
49
50         /* CE2: target->host WMI */
51         {
52                 .pipenum = __cpu_to_le32(2),
53                 .pipedir = __cpu_to_le32(PIPEDIR_IN),
54                 .nentries = __cpu_to_le32(32),
55                 .nbytes_max = __cpu_to_le32(2048),
56                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
57                 .reserved = __cpu_to_le32(0),
58         },
59
60         /* CE3: host->target WMI */
61         {
62                 .pipenum = __cpu_to_le32(3),
63                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
64                 .nentries = __cpu_to_le32(32),
65                 .nbytes_max = __cpu_to_le32(2048),
66                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
67                 .reserved = __cpu_to_le32(0),
68         },
69
70         /* CE4: host->target HTT */
71         {
72                 .pipenum = __cpu_to_le32(4),
73                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
74                 .nentries = __cpu_to_le32(256),
75                 .nbytes_max = __cpu_to_le32(256),
76                 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
77                 .reserved = __cpu_to_le32(0),
78         },
79
80         /* CE5: target->host Pktlog */
81         {
82                 .pipenum = __cpu_to_le32(5),
83                 .pipedir = __cpu_to_le32(PIPEDIR_IN),
84                 .nentries = __cpu_to_le32(32),
85                 .nbytes_max = __cpu_to_le32(2048),
86                 .flags = __cpu_to_le32(0),
87                 .reserved = __cpu_to_le32(0),
88         },
89
90         /* CE6: Reserved for target autonomous hif_memcpy */
91         {
92                 .pipenum = __cpu_to_le32(6),
93                 .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
94                 .nentries = __cpu_to_le32(32),
95                 .nbytes_max = __cpu_to_le32(65535),
96                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
97                 .reserved = __cpu_to_le32(0),
98         },
99
100         /* CE7 used only by Host */
101         {
102                 .pipenum = __cpu_to_le32(7),
103                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
104                 .nentries = __cpu_to_le32(32),
105                 .nbytes_max = __cpu_to_le32(2048),
106                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
107                 .reserved = __cpu_to_le32(0),
108         },
109
110         /* CE8 target->host used only by IPA */
111         {
112                 .pipenum = __cpu_to_le32(8),
113                 .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
114                 .nentries = __cpu_to_le32(32),
115                 .nbytes_max = __cpu_to_le32(65535),
116                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
117                 .reserved = __cpu_to_le32(0),
118         },
119
120         /* CE9 host->target HTT */
121         {
122                 .pipenum = __cpu_to_le32(9),
123                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),
124                 .nentries = __cpu_to_le32(32),
125                 .nbytes_max = __cpu_to_le32(2048),
126                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
127                 .reserved = __cpu_to_le32(0),
128         },
129
130         /* CE10 target->host HTT */
131         {
132                 .pipenum = __cpu_to_le32(10),
133                 .pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
134                 .nentries = __cpu_to_le32(0),
135                 .nbytes_max = __cpu_to_le32(0),
136                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
137                 .reserved = __cpu_to_le32(0),
138         },
139
140         /* CE11 Not used */
141         {
142                 .pipenum = __cpu_to_le32(0),
143                 .pipedir = __cpu_to_le32(0),
144                 .nentries = __cpu_to_le32(0),
145                 .nbytes_max = __cpu_to_le32(0),
146                 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
147                 .reserved = __cpu_to_le32(0),
148         },
149 };
150
151 /* Map from service/endpoint to Copy Engine.
152  * This table is derived from the CE_PCI TABLE, above.
153  * It is passed to the Target at startup for use by firmware.
154  */
155 static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
156         {
157                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
158                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
159                 .pipenum = __cpu_to_le32(3),
160         },
161         {
162                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
163                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
164                 .pipenum = __cpu_to_le32(2),
165         },
166         {
167                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
168                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
169                 .pipenum = __cpu_to_le32(3),
170         },
171         {
172                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
173                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
174                 .pipenum = __cpu_to_le32(2),
175         },
176         {
177                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
178                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
179                 .pipenum = __cpu_to_le32(3),
180         },
181         {
182                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
183                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
184                 .pipenum = __cpu_to_le32(2),
185         },
186         {
187                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
188                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
189                 .pipenum = __cpu_to_le32(3),
190         },
191         {
192                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
193                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
194                 .pipenum = __cpu_to_le32(2),
195         },
196         {
197                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
198                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
199                 .pipenum = __cpu_to_le32(3),
200         },
201         {
202                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
203                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
204                 .pipenum = __cpu_to_le32(2),
205         },
206         {
207                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
208                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
209                 .pipenum = __cpu_to_le32(7),
210         },
211         {
212                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
213                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
214                 .pipenum = __cpu_to_le32(2),
215         },
216         {
217                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
218                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
219                 .pipenum = __cpu_to_le32(9),
220         },
221         {
222                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
223                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
224                 .pipenum = __cpu_to_le32(2),
225         },
226         {
227                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
228                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
229                 .pipenum = __cpu_to_le32(0),
230         },
231         {
232                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
233                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
234                 .pipenum = __cpu_to_le32(1),
235         },
236         { /* not used */
237                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
238                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
239                 .pipenum = __cpu_to_le32(0),
240         },
241         { /* not used */
242                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
243                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
244                 .pipenum = __cpu_to_le32(1),
245         },
246         {
247                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
248                 .pipedir = __cpu_to_le32(PIPEDIR_OUT),  /* out = UL = host -> target */
249                 .pipenum = __cpu_to_le32(4),
250         },
251         {
252                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
253                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
254                 .pipenum = __cpu_to_le32(1),
255         },
256         {
257                 .service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
258                 .pipedir = __cpu_to_le32(PIPEDIR_IN),   /* in = DL = target -> host */
259                 .pipenum = __cpu_to_le32(5),
260         },
261
262         /* (Additions here) */
263
264         { /* terminator entry */ }
265 };
266
267 #define ATH11K_IRQ_CE0_OFFSET 4
268
269 static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
270         "misc-pulse1",
271         "misc-latch",
272         "sw-exception",
273         "watchdog",
274         "ce0",
275         "ce1",
276         "ce2",
277         "ce3",
278         "ce4",
279         "ce5",
280         "ce6",
281         "ce7",
282         "ce8",
283         "ce9",
284         "ce10",
285         "ce11",
286         "host2wbm-desc-feed",
287         "host2reo-re-injection",
288         "host2reo-command",
289         "host2rxdma-monitor-ring3",
290         "host2rxdma-monitor-ring2",
291         "host2rxdma-monitor-ring1",
292         "reo2ost-exception",
293         "wbm2host-rx-release",
294         "reo2host-status",
295         "reo2host-destination-ring4",
296         "reo2host-destination-ring3",
297         "reo2host-destination-ring2",
298         "reo2host-destination-ring1",
299         "rxdma2host-monitor-destination-mac3",
300         "rxdma2host-monitor-destination-mac2",
301         "rxdma2host-monitor-destination-mac1",
302         "ppdu-end-interrupts-mac3",
303         "ppdu-end-interrupts-mac2",
304         "ppdu-end-interrupts-mac1",
305         "rxdma2host-monitor-status-ring-mac3",
306         "rxdma2host-monitor-status-ring-mac2",
307         "rxdma2host-monitor-status-ring-mac1",
308         "host2rxdma-host-buf-ring-mac3",
309         "host2rxdma-host-buf-ring-mac2",
310         "host2rxdma-host-buf-ring-mac1",
311         "rxdma2host-destination-ring-mac3",
312         "rxdma2host-destination-ring-mac2",
313         "rxdma2host-destination-ring-mac1",
314         "host2tcl-input-ring4",
315         "host2tcl-input-ring3",
316         "host2tcl-input-ring2",
317         "host2tcl-input-ring1",
318         "wbm2host-tx-completions-ring3",
319         "wbm2host-tx-completions-ring2",
320         "wbm2host-tx-completions-ring1",
321         "tcl2host-status-ring",
322 };
323
324 #define ATH11K_TX_RING_MASK_0 0x1
325 #define ATH11K_TX_RING_MASK_1 0x2
326 #define ATH11K_TX_RING_MASK_2 0x4
327
328 #define ATH11K_RX_RING_MASK_0 0x1
329 #define ATH11K_RX_RING_MASK_1 0x2
330 #define ATH11K_RX_RING_MASK_2 0x4
331 #define ATH11K_RX_RING_MASK_3 0x8
332
333 #define ATH11K_RX_ERR_RING_MASK_0 0x1
334
335 #define ATH11K_RX_WBM_REL_RING_MASK_0 0x1
336
337 #define ATH11K_REO_STATUS_RING_MASK_0 0x1
338
339 #define ATH11K_RXDMA2HOST_RING_MASK_0 0x1
340 #define ATH11K_RXDMA2HOST_RING_MASK_1 0x2
341 #define ATH11K_RXDMA2HOST_RING_MASK_2 0x4
342
343 #define ATH11K_HOST2RXDMA_RING_MASK_0 0x1
344 #define ATH11K_HOST2RXDMA_RING_MASK_1 0x2
345 #define ATH11K_HOST2RXDMA_RING_MASK_2 0x4
346
347 #define ATH11K_RX_MON_STATUS_RING_MASK_0 0x1
348 #define ATH11K_RX_MON_STATUS_RING_MASK_1 0x2
349 #define ATH11K_RX_MON_STATUS_RING_MASK_2 0x4
350
351 const u8 ath11k_tx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
352         ATH11K_TX_RING_MASK_0,
353         ATH11K_TX_RING_MASK_1,
354         ATH11K_TX_RING_MASK_2,
355 };
356
357 const u8 rx_mon_status_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
358         0, 0, 0, 0,
359         ATH11K_RX_MON_STATUS_RING_MASK_0,
360         ATH11K_RX_MON_STATUS_RING_MASK_1,
361         ATH11K_RX_MON_STATUS_RING_MASK_2,
362 };
363
364 const u8 ath11k_rx_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
365         0, 0, 0, 0, 0, 0, 0,
366         ATH11K_RX_RING_MASK_0,
367         ATH11K_RX_RING_MASK_1,
368         ATH11K_RX_RING_MASK_2,
369         ATH11K_RX_RING_MASK_3,
370 };
371
372 const u8 ath11k_rx_err_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
373         ATH11K_RX_ERR_RING_MASK_0,
374 };
375
376 const u8 ath11k_rx_wbm_rel_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
377         ATH11K_RX_WBM_REL_RING_MASK_0,
378 };
379
380 const u8 ath11k_reo_status_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
381         ATH11K_REO_STATUS_RING_MASK_0,
382 };
383
384 const u8 ath11k_rxdma2host_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
385         ATH11K_RXDMA2HOST_RING_MASK_0,
386         ATH11K_RXDMA2HOST_RING_MASK_1,
387         ATH11K_RXDMA2HOST_RING_MASK_2,
388 };
389
390 const u8 ath11k_host2rxdma_ring_mask[ATH11K_EXT_IRQ_GRP_NUM_MAX] = {
391         ATH11K_HOST2RXDMA_RING_MASK_0,
392         ATH11K_HOST2RXDMA_RING_MASK_1,
393         ATH11K_HOST2RXDMA_RING_MASK_2,
394 };
395
396 /* enum ext_irq_num - irq numbers that can be used by external modules
397  * like datapath
398  */
399 enum ext_irq_num {
400         host2wbm_desc_feed = 16,
401         host2reo_re_injection,
402         host2reo_command,
403         host2rxdma_monitor_ring3,
404         host2rxdma_monitor_ring2,
405         host2rxdma_monitor_ring1,
406         reo2host_exception,
407         wbm2host_rx_release,
408         reo2host_status,
409         reo2host_destination_ring4,
410         reo2host_destination_ring3,
411         reo2host_destination_ring2,
412         reo2host_destination_ring1,
413         rxdma2host_monitor_destination_mac3,
414         rxdma2host_monitor_destination_mac2,
415         rxdma2host_monitor_destination_mac1,
416         ppdu_end_interrupts_mac3,
417         ppdu_end_interrupts_mac2,
418         ppdu_end_interrupts_mac1,
419         rxdma2host_monitor_status_ring_mac3,
420         rxdma2host_monitor_status_ring_mac2,
421         rxdma2host_monitor_status_ring_mac1,
422         host2rxdma_host_buf_ring_mac3,
423         host2rxdma_host_buf_ring_mac2,
424         host2rxdma_host_buf_ring_mac1,
425         rxdma2host_destination_ring_mac3,
426         rxdma2host_destination_ring_mac2,
427         rxdma2host_destination_ring_mac1,
428         host2tcl_input_ring4,
429         host2tcl_input_ring3,
430         host2tcl_input_ring2,
431         host2tcl_input_ring1,
432         wbm2host_tx_completions_ring3,
433         wbm2host_tx_completions_ring2,
434         wbm2host_tx_completions_ring1,
435         tcl2host_status_ring,
436 };
437
438 static inline u32 ath11k_ahb_read32(struct ath11k_base *ab, u32 offset)
439 {
440         return ioread32(ab->mem + offset);
441 }
442
443 static inline void ath11k_ahb_write32(struct ath11k_base *ab, u32 offset, u32 value)
444 {
445         iowrite32(value, ab->mem + offset);
446 }
447
448 static void ath11k_ahb_kill_tasklets(struct ath11k_base *ab)
449 {
450         int i;
451
452         for (i = 0; i < CE_COUNT; i++) {
453                 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
454
455                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
456                         continue;
457
458                 tasklet_kill(&ce_pipe->intr_tq);
459         }
460 }
461
462 static void ath11k_ahb_ext_grp_disable(struct ath11k_ext_irq_grp *irq_grp)
463 {
464         int i;
465
466         for (i = 0; i < irq_grp->num_irq; i++)
467                 disable_irq_nosync(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
468 }
469
470 static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
471 {
472         int i;
473
474         for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
475                 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
476
477                 ath11k_ahb_ext_grp_disable(irq_grp);
478
479                 napi_synchronize(&irq_grp->napi);
480                 napi_disable(&irq_grp->napi);
481         }
482 }
483
484 static void ath11k_ahb_ext_grp_enable(struct ath11k_ext_irq_grp *irq_grp)
485 {
486         int i;
487
488         for (i = 0; i < irq_grp->num_irq; i++)
489                 enable_irq(irq_grp->ab->irq_num[irq_grp->irqs[i]]);
490 }
491
492 static void ath11k_ahb_setbit32(struct ath11k_base *ab, u8 bit, u32 offset)
493 {
494         u32 val;
495
496         val = ath11k_ahb_read32(ab, offset);
497         ath11k_ahb_write32(ab, offset, val | BIT(bit));
498 }
499
500 static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset)
501 {
502         u32 val;
503
504         val = ath11k_ahb_read32(ab, offset);
505         ath11k_ahb_write32(ab, offset, val & ~BIT(bit));
506 }
507
508 static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
509 {
510         const struct ce_pipe_config *ce_config;
511
512         ce_config = &target_ce_config_wlan[ce_id];
513         if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT)
514                 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
515
516         if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) {
517                 ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
518                 ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
519                                     CE_HOST_IE_3_ADDRESS);
520         }
521 }
522
523 static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
524 {
525         const struct ce_pipe_config *ce_config;
526
527         ce_config = &target_ce_config_wlan[ce_id];
528         if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT)
529                 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
530
531         if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) {
532                 ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS);
533                 ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT,
534                                       CE_HOST_IE_3_ADDRESS);
535         }
536 }
537
538 static void ath11k_ahb_sync_ce_irqs(struct ath11k_base *ab)
539 {
540         int i;
541         int irq_idx;
542
543         for (i = 0; i < CE_COUNT; i++) {
544                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
545                         continue;
546
547                 irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
548                 synchronize_irq(ab->irq_num[irq_idx]);
549         }
550 }
551
552 static void ath11k_ahb_sync_ext_irqs(struct ath11k_base *ab)
553 {
554         int i, j;
555         int irq_idx;
556
557         for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
558                 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
559
560                 for (j = 0; j < irq_grp->num_irq; j++) {
561                         irq_idx = irq_grp->irqs[j];
562                         synchronize_irq(ab->irq_num[irq_idx]);
563                 }
564         }
565 }
566
567 static void ath11k_ahb_ce_irqs_enable(struct ath11k_base *ab)
568 {
569         int i;
570
571         for (i = 0; i < CE_COUNT; i++) {
572                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
573                         continue;
574                 ath11k_ahb_ce_irq_enable(ab, i);
575         }
576 }
577
578 static void ath11k_ahb_ce_irqs_disable(struct ath11k_base *ab)
579 {
580         int i;
581
582         for (i = 0; i < CE_COUNT; i++) {
583                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
584                         continue;
585                 ath11k_ahb_ce_irq_disable(ab, i);
586         }
587 }
588
589 static int ath11k_ahb_start(struct ath11k_base *ab)
590 {
591         ath11k_ahb_ce_irqs_enable(ab);
592         ath11k_ce_rx_post_buf(ab);
593
594         return 0;
595 }
596
597 static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab)
598 {
599         int i;
600
601         for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
602                 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
603
604                 napi_enable(&irq_grp->napi);
605                 ath11k_ahb_ext_grp_enable(irq_grp);
606         }
607 }
608
609 static void ath11k_ahb_ext_irq_disable(struct ath11k_base *ab)
610 {
611         __ath11k_ahb_ext_irq_disable(ab);
612         ath11k_ahb_sync_ext_irqs(ab);
613 }
614
615 static void ath11k_ahb_stop(struct ath11k_base *ab)
616 {
617         if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
618                 ath11k_ahb_ce_irqs_disable(ab);
619         ath11k_ahb_sync_ce_irqs(ab);
620         ath11k_ahb_kill_tasklets(ab);
621         del_timer_sync(&ab->rx_replenish_retry);
622         ath11k_ce_cleanup_pipes(ab);
623 }
624
625 static int ath11k_ahb_power_up(struct ath11k_base *ab)
626 {
627         int ret;
628
629         ret = rproc_boot(ab->tgt_rproc);
630         if (ret)
631                 ath11k_err(ab, "failed to boot the remote processor Q6\n");
632
633         return ret;
634 }
635
636 static void ath11k_ahb_power_down(struct ath11k_base *ab)
637 {
638         rproc_shutdown(ab->tgt_rproc);
639 }
640
641 static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
642 {
643         struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
644
645         cfg->tgt_ce_len = ARRAY_SIZE(target_ce_config_wlan) - 1;
646         cfg->tgt_ce = target_ce_config_wlan;
647         cfg->svc_to_ce_map_len = ARRAY_SIZE(target_service_to_ce_map_wlan);
648         cfg->svc_to_ce_map = target_service_to_ce_map_wlan;
649 }
650
651 static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
652 {
653         int i, j;
654
655         for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
656                 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
657
658                 for (j = 0; j < irq_grp->num_irq; j++)
659                         free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
660         }
661 }
662
663 static void ath11k_ahb_free_irq(struct ath11k_base *ab)
664 {
665         int irq_idx;
666         int i;
667
668         for (i = 0; i < CE_COUNT; i++) {
669                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
670                         continue;
671                 irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
672                 free_irq(ab->irq_num[irq_idx], &ab->ce.ce_pipe[i]);
673         }
674
675         ath11k_ahb_free_ext_irq(ab);
676 }
677
678 static void ath11k_ahb_ce_tasklet(unsigned long data)
679 {
680         struct ath11k_ce_pipe *ce_pipe = (struct ath11k_ce_pipe *)data;
681
682         ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
683
684         ath11k_ahb_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
685 }
686
687 static irqreturn_t ath11k_ahb_ce_interrupt_handler(int irq, void *arg)
688 {
689         struct ath11k_ce_pipe *ce_pipe = arg;
690
691         /* last interrupt received for this CE */
692         ce_pipe->timestamp = jiffies;
693
694         ath11k_ahb_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
695
696         tasklet_schedule(&ce_pipe->intr_tq);
697
698         return IRQ_HANDLED;
699 }
700
701 static int ath11k_ahb_ext_grp_napi_poll(struct napi_struct *napi, int budget)
702 {
703         struct ath11k_ext_irq_grp *irq_grp = container_of(napi,
704                                                 struct ath11k_ext_irq_grp,
705                                                 napi);
706         struct ath11k_base *ab = irq_grp->ab;
707         int work_done;
708
709         work_done = ath11k_dp_service_srng(ab, irq_grp, budget);
710         if (work_done < budget) {
711                 napi_complete_done(napi, work_done);
712                 ath11k_ahb_ext_grp_enable(irq_grp);
713         }
714
715         if (work_done > budget)
716                 work_done = budget;
717
718         return work_done;
719 }
720
721 static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
722 {
723         struct ath11k_ext_irq_grp *irq_grp = arg;
724
725         /* last interrupt received for this group */
726         irq_grp->timestamp = jiffies;
727
728         ath11k_ahb_ext_grp_disable(irq_grp);
729
730         napi_schedule(&irq_grp->napi);
731
732         return IRQ_HANDLED;
733 }
734
735 static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab)
736 {
737         int i, j;
738         int irq;
739         int ret;
740
741         for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
742                 struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
743                 u32 num_irq = 0;
744
745                 irq_grp->ab = ab;
746                 irq_grp->grp_id = i;
747                 init_dummy_netdev(&irq_grp->napi_ndev);
748                 netif_napi_add(&irq_grp->napi_ndev, &irq_grp->napi,
749                                ath11k_ahb_ext_grp_napi_poll, NAPI_POLL_WEIGHT);
750
751                 for (j = 0; j < ATH11K_EXT_IRQ_NUM_MAX; j++) {
752                         if (ath11k_tx_ring_mask[i] & BIT(j)) {
753                                 irq_grp->irqs[num_irq++] =
754                                         wbm2host_tx_completions_ring1 - j;
755                         }
756
757                         if (ath11k_rx_ring_mask[i] & BIT(j)) {
758                                 irq_grp->irqs[num_irq++] =
759                                         reo2host_destination_ring1 - j;
760                         }
761
762                         if (ath11k_rx_err_ring_mask[i] & BIT(j))
763                                 irq_grp->irqs[num_irq++] = reo2host_exception;
764
765                         if (ath11k_rx_wbm_rel_ring_mask[i] & BIT(j))
766                                 irq_grp->irqs[num_irq++] = wbm2host_rx_release;
767
768                         if (ath11k_reo_status_ring_mask[i] & BIT(j))
769                                 irq_grp->irqs[num_irq++] = reo2host_status;
770
771                         if (j < MAX_RADIOS) {
772                                 if (ath11k_rxdma2host_ring_mask[i] & BIT(j)) {
773                                         irq_grp->irqs[num_irq++] =
774                                                 rxdma2host_destination_ring_mac1
775                                                 - ath11k_core_get_hw_mac_id(ab, j);
776                                 }
777
778                                 if (ath11k_host2rxdma_ring_mask[i] & BIT(j)) {
779                                         irq_grp->irqs[num_irq++] =
780                                                 host2rxdma_host_buf_ring_mac1
781                                                 - ath11k_core_get_hw_mac_id(ab, j);
782                                 }
783
784                                 if (rx_mon_status_ring_mask[i] & BIT(j)) {
785                                         irq_grp->irqs[num_irq++] =
786                                                 ppdu_end_interrupts_mac1 -
787                                                 ath11k_core_get_hw_mac_id(ab, j);
788                                         irq_grp->irqs[num_irq++] =
789                                                 rxdma2host_monitor_status_ring_mac1 -
790                                                 ath11k_core_get_hw_mac_id(ab, j);
791                                 }
792                         }
793                 }
794                 irq_grp->num_irq = num_irq;
795
796                 for (j = 0; j < irq_grp->num_irq; j++) {
797                         int irq_idx = irq_grp->irqs[j];
798
799                         irq = platform_get_irq_byname(ab->pdev,
800                                                       irq_name[irq_idx]);
801                         ab->irq_num[irq_idx] = irq;
802                         irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_DISABLE_UNLAZY);
803                         ret = request_irq(irq, ath11k_ahb_ext_interrupt_handler,
804                                           IRQF_TRIGGER_RISING,
805                                           irq_name[irq_idx], irq_grp);
806                         if (ret) {
807                                 ath11k_err(ab, "failed request_irq for %d\n",
808                                            irq);
809                         }
810                 }
811         }
812
813         return 0;
814 }
815
816 static int ath11k_ahb_config_irq(struct ath11k_base *ab)
817 {
818         int irq, irq_idx, i;
819         int ret;
820
821         /* Configure CE irqs */
822         for (i = 0; i < CE_COUNT; i++) {
823                 struct ath11k_ce_pipe *ce_pipe = &ab->ce.ce_pipe[i];
824
825                 if (ath11k_ce_get_attr_flags(i) & CE_ATTR_DIS_INTR)
826                         continue;
827
828                 irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
829
830                 tasklet_init(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet,
831                              (unsigned long)ce_pipe);
832                 irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]);
833                 ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
834                                   IRQF_TRIGGER_RISING, irq_name[irq_idx],
835                                   ce_pipe);
836                 if (ret)
837                         return ret;
838
839                 ab->irq_num[irq_idx] = irq;
840         }
841
842         /* Configure external interrupts */
843         ret = ath11k_ahb_ext_irq_config(ab);
844
845         return ret;
846 }
847
848 static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id,
849                                           u8 *ul_pipe, u8 *dl_pipe)
850 {
851         const struct service_to_pipe *entry;
852         bool ul_set = false, dl_set = false;
853         int i;
854
855         for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
856                 entry = &target_service_to_ce_map_wlan[i];
857
858                 if (__le32_to_cpu(entry->service_id) != service_id)
859                         continue;
860
861                 switch (__le32_to_cpu(entry->pipedir)) {
862                 case PIPEDIR_NONE:
863                         break;
864                 case PIPEDIR_IN:
865                         WARN_ON(dl_set);
866                         *dl_pipe = __le32_to_cpu(entry->pipenum);
867                         dl_set = true;
868                         break;
869                 case PIPEDIR_OUT:
870                         WARN_ON(ul_set);
871                         *ul_pipe = __le32_to_cpu(entry->pipenum);
872                         ul_set = true;
873                         break;
874                 case PIPEDIR_INOUT:
875                         WARN_ON(dl_set);
876                         WARN_ON(ul_set);
877                         *dl_pipe = __le32_to_cpu(entry->pipenum);
878                         *ul_pipe = __le32_to_cpu(entry->pipenum);
879                         dl_set = true;
880                         ul_set = true;
881                         break;
882                 }
883         }
884
885         if (WARN_ON(!ul_set || !dl_set))
886                 return -ENOENT;
887
888         return 0;
889 }
890
891 static const struct ath11k_hif_ops ath11k_ahb_hif_ops = {
892         .start = ath11k_ahb_start,
893         .stop = ath11k_ahb_stop,
894         .read32 = ath11k_ahb_read32,
895         .write32 = ath11k_ahb_write32,
896         .irq_enable = ath11k_ahb_ext_irq_enable,
897         .irq_disable = ath11k_ahb_ext_irq_disable,
898         .map_service_to_pipe = ath11k_ahb_map_service_to_pipe,
899         .power_down = ath11k_ahb_power_down,
900         .power_up = ath11k_ahb_power_up,
901 };
902
903 static int ath11k_ahb_probe(struct platform_device *pdev)
904 {
905         struct ath11k_base *ab;
906         const struct of_device_id *of_id;
907         struct resource *mem_res;
908         void __iomem *mem;
909         int ret;
910
911         of_id = of_match_device(ath11k_ahb_of_match, &pdev->dev);
912         if (!of_id) {
913                 dev_err(&pdev->dev, "failed to find matching device tree id\n");
914                 return -EINVAL;
915         }
916
917         mem = devm_platform_get_and_ioremap_resource(pdev, 0, &mem_res);
918         if (IS_ERR(mem)) {
919                 dev_err(&pdev->dev, "ioremap error\n");
920                 return PTR_ERR(mem);
921         }
922
923         ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
924         if (ret) {
925                 dev_err(&pdev->dev, "failed to set 32-bit consistent dma\n");
926                 return ret;
927         }
928
929         ab = ath11k_core_alloc(&pdev->dev, 0, ATH11K_BUS_AHB);
930         if (!ab) {
931                 dev_err(&pdev->dev, "failed to allocate ath11k base\n");
932                 return -ENOMEM;
933         }
934
935         ab->hif.ops = &ath11k_ahb_hif_ops;
936         ab->pdev = pdev;
937         ab->hw_rev = (enum ath11k_hw_rev)of_id->data;
938         ab->mem = mem;
939         ab->mem_len = resource_size(mem_res);
940         platform_set_drvdata(pdev, ab);
941
942         ret = ath11k_hal_srng_init(ab);
943         if (ret)
944                 goto err_core_free;
945
946         ret = ath11k_ce_alloc_pipes(ab);
947         if (ret) {
948                 ath11k_err(ab, "failed to allocate ce pipes: %d\n", ret);
949                 goto err_hal_srng_deinit;
950         }
951
952         ath11k_ahb_init_qmi_ce_config(ab);
953
954         ret = ath11k_ahb_config_irq(ab);
955         if (ret) {
956                 ath11k_err(ab, "failed to configure irq: %d\n", ret);
957                 goto err_ce_free;
958         }
959
960         ret = ath11k_core_init(ab);
961         if (ret) {
962                 ath11k_err(ab, "failed to init core: %d\n", ret);
963                 goto err_ce_free;
964         }
965
966         return 0;
967
968 err_ce_free:
969         ath11k_ce_free_pipes(ab);
970
971 err_hal_srng_deinit:
972         ath11k_hal_srng_deinit(ab);
973
974 err_core_free:
975         ath11k_core_free(ab);
976         platform_set_drvdata(pdev, NULL);
977
978         return ret;
979 }
980
981 static int ath11k_ahb_remove(struct platform_device *pdev)
982 {
983         struct ath11k_base *ab = platform_get_drvdata(pdev);
984
985         reinit_completion(&ab->driver_recovery);
986
987         if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags))
988                 wait_for_completion_timeout(&ab->driver_recovery,
989                                             ATH11K_AHB_RECOVERY_TIMEOUT);
990
991         set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
992         cancel_work_sync(&ab->restart_work);
993
994         ath11k_core_deinit(ab);
995         ath11k_ahb_free_irq(ab);
996
997         ath11k_hal_srng_deinit(ab);
998         ath11k_ce_free_pipes(ab);
999         ath11k_core_free(ab);
1000         platform_set_drvdata(pdev, NULL);
1001
1002         return 0;
1003 }
1004
1005 static struct platform_driver ath11k_ahb_driver = {
1006         .driver         = {
1007                 .name   = "ath11k",
1008                 .of_match_table = ath11k_ahb_of_match,
1009         },
1010         .probe  = ath11k_ahb_probe,
1011         .remove = ath11k_ahb_remove,
1012 };
1013
1014 static int ath11k_ahb_init(void)
1015 {
1016         return platform_driver_register(&ath11k_ahb_driver);
1017 }
1018 module_init(ath11k_ahb_init);
1019
1020 static void ath11k_ahb_exit(void)
1021 {
1022         platform_driver_unregister(&ath11k_ahb_driver);
1023 }
1024 module_exit(ath11k_ahb_exit);
1025
1026 MODULE_DESCRIPTION("Driver support for Qualcomm Technologies 802.11ax wireless chip");
1027 MODULE_LICENSE("Dual BSD/GPL");
This page took 0.089404 seconds and 4 git commands to generate.