ath10k: add support to get target info from hif ops
[linux-2.6-block.git] / drivers / net / wireless / ath / ath10k / snoc.c
1 /*
2  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include "debug.h"
20 #include "hif.h"
21 #include "htc.h"
22 #include "ce.h"
23 #include "snoc.h"
24 #include <linux/of.h>
25 #include <linux/of_device.h>
26 #include <linux/platform_device.h>
27 #define  WCN3990_CE_ATTR_FLAGS 0
28 #define ATH10K_SNOC_RX_POST_RETRY_MS 50
29 #define CE_POLL_PIPE 4
30
31 static char *const ce_name[] = {
32         "WLAN_CE_0",
33         "WLAN_CE_1",
34         "WLAN_CE_2",
35         "WLAN_CE_3",
36         "WLAN_CE_4",
37         "WLAN_CE_5",
38         "WLAN_CE_6",
39         "WLAN_CE_7",
40         "WLAN_CE_8",
41         "WLAN_CE_9",
42         "WLAN_CE_10",
43         "WLAN_CE_11",
44 };
45
46 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
47 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
48 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
49 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
50 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
51
52 static const struct ath10k_snoc_drv_priv drv_priv = {
53         .hw_rev = ATH10K_HW_WCN3990,
54         .dma_mask = DMA_BIT_MASK(37),
55 };
56
57 static struct ce_attr host_ce_config_wlan[] = {
58         /* CE0: host->target HTC control streams */
59         {
60                 .flags = CE_ATTR_FLAGS,
61                 .src_nentries = 16,
62                 .src_sz_max = 2048,
63                 .dest_nentries = 0,
64                 .send_cb = ath10k_snoc_htc_tx_cb,
65         },
66
67         /* CE1: target->host HTT + HTC control */
68         {
69                 .flags = CE_ATTR_FLAGS,
70                 .src_nentries = 0,
71                 .src_sz_max = 2048,
72                 .dest_nentries = 512,
73                 .recv_cb = ath10k_snoc_htt_htc_rx_cb,
74         },
75
76         /* CE2: target->host WMI */
77         {
78                 .flags = CE_ATTR_FLAGS,
79                 .src_nentries = 0,
80                 .src_sz_max = 2048,
81                 .dest_nentries = 64,
82                 .recv_cb = ath10k_snoc_htc_rx_cb,
83         },
84
85         /* CE3: host->target WMI */
86         {
87                 .flags = CE_ATTR_FLAGS,
88                 .src_nentries = 32,
89                 .src_sz_max = 2048,
90                 .dest_nentries = 0,
91                 .send_cb = ath10k_snoc_htc_tx_cb,
92         },
93
94         /* CE4: host->target HTT */
95         {
96                 .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR,
97                 .src_nentries = 256,
98                 .src_sz_max = 256,
99                 .dest_nentries = 0,
100                 .send_cb = ath10k_snoc_htt_tx_cb,
101         },
102
103         /* CE5: target->host HTT (ipa_uc->target ) */
104         {
105                 .flags = CE_ATTR_FLAGS,
106                 .src_nentries = 0,
107                 .src_sz_max = 512,
108                 .dest_nentries = 512,
109                 .recv_cb = ath10k_snoc_htt_rx_cb,
110         },
111
112         /* CE6: target autonomous hif_memcpy */
113         {
114                 .flags = CE_ATTR_FLAGS,
115                 .src_nentries = 0,
116                 .src_sz_max = 0,
117                 .dest_nentries = 0,
118         },
119
120         /* CE7: ce_diag, the Diagnostic Window */
121         {
122                 .flags = CE_ATTR_FLAGS,
123                 .src_nentries = 2,
124                 .src_sz_max = 2048,
125                 .dest_nentries = 2,
126         },
127
128         /* CE8: Target to uMC */
129         {
130                 .flags = CE_ATTR_FLAGS,
131                 .src_nentries = 0,
132                 .src_sz_max = 2048,
133                 .dest_nentries = 128,
134         },
135
136         /* CE9 target->host HTT */
137         {
138                 .flags = CE_ATTR_FLAGS,
139                 .src_nentries = 0,
140                 .src_sz_max = 2048,
141                 .dest_nentries = 512,
142                 .recv_cb = ath10k_snoc_htt_htc_rx_cb,
143         },
144
145         /* CE10: target->host HTT */
146         {
147                 .flags = CE_ATTR_FLAGS,
148                 .src_nentries = 0,
149                 .src_sz_max = 2048,
150                 .dest_nentries = 512,
151                 .recv_cb = ath10k_snoc_htt_htc_rx_cb,
152         },
153
154         /* CE11: target -> host PKTLOG */
155         {
156                 .flags = CE_ATTR_FLAGS,
157                 .src_nentries = 0,
158                 .src_sz_max = 2048,
159                 .dest_nentries = 512,
160                 .recv_cb = ath10k_snoc_htt_htc_rx_cb,
161         },
162 };
163
164 static struct service_to_pipe target_service_to_ce_map_wlan[] = {
165         {
166                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
167                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
168                 __cpu_to_le32(3),
169         },
170         {
171                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
172                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
173                 __cpu_to_le32(2),
174         },
175         {
176                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
177                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
178                 __cpu_to_le32(3),
179         },
180         {
181                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
182                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
183                 __cpu_to_le32(2),
184         },
185         {
186                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
187                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
188                 __cpu_to_le32(3),
189         },
190         {
191                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
192                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
193                 __cpu_to_le32(2),
194         },
195         {
196                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
197                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
198                 __cpu_to_le32(3),
199         },
200         {
201                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
202                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
203                 __cpu_to_le32(2),
204         },
205         {
206                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
207                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
208                 __cpu_to_le32(3),
209         },
210         {
211                 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL),
212                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
213                 __cpu_to_le32(2),
214         },
215         {
216                 __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
217                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
218                 __cpu_to_le32(0),
219         },
220         {
221                 __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL),
222                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
223                 __cpu_to_le32(2),
224         },
225         { /* not used */
226                 __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
227                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
228                 __cpu_to_le32(0),
229         },
230         { /* not used */
231                 __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
232                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
233                 __cpu_to_le32(2),
234         },
235         {
236                 __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
237                 __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
238                 __cpu_to_le32(4),
239         },
240         {
241                 __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG),
242                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
243                 __cpu_to_le32(1),
244         },
245         { /* not used */
246                 __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS),
247                 __cpu_to_le32(PIPEDIR_OUT),
248                 __cpu_to_le32(5),
249         },
250         { /* in = DL = target -> host */
251                 __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA2_MSG),
252                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
253                 __cpu_to_le32(9),
254         },
255         { /* in = DL = target -> host */
256                 __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA3_MSG),
257                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
258                 __cpu_to_le32(10),
259         },
260         { /* in = DL = target -> host pktlog */
261                 __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_LOG_MSG),
262                 __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
263                 __cpu_to_le32(11),
264         },
265         /* (Additions here) */
266
267         { /* must be last */
268                 __cpu_to_le32(0),
269                 __cpu_to_le32(0),
270                 __cpu_to_le32(0),
271         },
272 };
273
274 void ath10k_snoc_write32(struct ath10k *ar, u32 offset, u32 value)
275 {
276         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
277
278         iowrite32(value, ar_snoc->mem + offset);
279 }
280
281 u32 ath10k_snoc_read32(struct ath10k *ar, u32 offset)
282 {
283         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
284         u32 val;
285
286         val = ioread32(ar_snoc->mem + offset);
287
288         return val;
289 }
290
291 static int __ath10k_snoc_rx_post_buf(struct ath10k_snoc_pipe *pipe)
292 {
293         struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
294         struct ath10k *ar = pipe->hif_ce_state;
295         struct ath10k_ce *ce = ath10k_ce_priv(ar);
296         struct sk_buff *skb;
297         dma_addr_t paddr;
298         int ret;
299
300         skb = dev_alloc_skb(pipe->buf_sz);
301         if (!skb)
302                 return -ENOMEM;
303
304         WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
305
306         paddr = dma_map_single(ar->dev, skb->data,
307                                skb->len + skb_tailroom(skb),
308                                DMA_FROM_DEVICE);
309         if (unlikely(dma_mapping_error(ar->dev, paddr))) {
310                 ath10k_warn(ar, "failed to dma map snoc rx buf\n");
311                 dev_kfree_skb_any(skb);
312                 return -EIO;
313         }
314
315         ATH10K_SKB_RXCB(skb)->paddr = paddr;
316
317         spin_lock_bh(&ce->ce_lock);
318         ret = ce_pipe->ops->ce_rx_post_buf(ce_pipe, skb, paddr);
319         spin_unlock_bh(&ce->ce_lock);
320         if (ret) {
321                 dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb),
322                                  DMA_FROM_DEVICE);
323                 dev_kfree_skb_any(skb);
324                 return ret;
325         }
326
327         return 0;
328 }
329
330 static void ath10k_snoc_rx_post_pipe(struct ath10k_snoc_pipe *pipe)
331 {
332         struct ath10k *ar = pipe->hif_ce_state;
333         struct ath10k_ce *ce = ath10k_ce_priv(ar);
334         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
335         struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl;
336         int ret, num;
337
338         if (pipe->buf_sz == 0)
339                 return;
340
341         if (!ce_pipe->dest_ring)
342                 return;
343
344         spin_lock_bh(&ce->ce_lock);
345         num = __ath10k_ce_rx_num_free_bufs(ce_pipe);
346         spin_unlock_bh(&ce->ce_lock);
347         while (num--) {
348                 ret = __ath10k_snoc_rx_post_buf(pipe);
349                 if (ret) {
350                         if (ret == -ENOSPC)
351                                 break;
352                         ath10k_warn(ar, "failed to post rx buf: %d\n", ret);
353                         mod_timer(&ar_snoc->rx_post_retry, jiffies +
354                                   ATH10K_SNOC_RX_POST_RETRY_MS);
355                         break;
356                 }
357         }
358 }
359
360 static void ath10k_snoc_rx_post(struct ath10k *ar)
361 {
362         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
363         int i;
364
365         for (i = 0; i < CE_COUNT; i++)
366                 ath10k_snoc_rx_post_pipe(&ar_snoc->pipe_info[i]);
367 }
368
369 static void ath10k_snoc_process_rx_cb(struct ath10k_ce_pipe *ce_state,
370                                       void (*callback)(struct ath10k *ar,
371                                                        struct sk_buff *skb))
372 {
373         struct ath10k *ar = ce_state->ar;
374         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
375         struct ath10k_snoc_pipe *pipe_info =  &ar_snoc->pipe_info[ce_state->id];
376         struct sk_buff *skb;
377         struct sk_buff_head list;
378         void *transfer_context;
379         unsigned int nbytes, max_nbytes;
380
381         __skb_queue_head_init(&list);
382         while (ath10k_ce_completed_recv_next(ce_state, &transfer_context,
383                                              &nbytes) == 0) {
384                 skb = transfer_context;
385                 max_nbytes = skb->len + skb_tailroom(skb);
386                 dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
387                                  max_nbytes, DMA_FROM_DEVICE);
388
389                 if (unlikely(max_nbytes < nbytes)) {
390                         ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)",
391                                     nbytes, max_nbytes);
392                         dev_kfree_skb_any(skb);
393                         continue;
394                 }
395
396                 skb_put(skb, nbytes);
397                 __skb_queue_tail(&list, skb);
398         }
399
400         while ((skb = __skb_dequeue(&list))) {
401                 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc rx ce pipe %d len %d\n",
402                            ce_state->id, skb->len);
403
404                 callback(ar, skb);
405         }
406
407         ath10k_snoc_rx_post_pipe(pipe_info);
408 }
409
410 static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
411 {
412         ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
413 }
414
415 static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
416 {
417         /* CE4 polling needs to be done whenever CE pipe which transports
418          * HTT Rx (target->host) is processed.
419          */
420         ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
421
422         ath10k_snoc_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
423 }
424
425 static void ath10k_snoc_htt_rx_deliver(struct ath10k *ar, struct sk_buff *skb)
426 {
427         skb_pull(skb, sizeof(struct ath10k_htc_hdr));
428         ath10k_htt_t2h_msg_handler(ar, skb);
429 }
430
431 static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
432 {
433         ath10k_ce_per_engine_service(ce_state->ar, CE_POLL_PIPE);
434         ath10k_snoc_process_rx_cb(ce_state, ath10k_snoc_htt_rx_deliver);
435 }
436
437 static void ath10k_snoc_rx_replenish_retry(struct timer_list *t)
438 {
439         struct ath10k_pci *ar_snoc = from_timer(ar_snoc, t, rx_post_retry);
440         struct ath10k *ar = ar_snoc->ar;
441
442         ath10k_snoc_rx_post(ar);
443 }
444
445 static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
446 {
447         struct ath10k *ar = ce_state->ar;
448         struct sk_buff_head list;
449         struct sk_buff *skb;
450
451         __skb_queue_head_init(&list);
452         while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
453                 if (!skb)
454                         continue;
455
456                 __skb_queue_tail(&list, skb);
457         }
458
459         while ((skb = __skb_dequeue(&list)))
460                 ath10k_htc_tx_completion_handler(ar, skb);
461 }
462
463 static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
464 {
465         struct ath10k *ar = ce_state->ar;
466         struct sk_buff *skb;
467
468         while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
469                 if (!skb)
470                         continue;
471
472                 dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
473                                  skb->len, DMA_TO_DEVICE);
474                 ath10k_htt_hif_tx_complete(ar, skb);
475         }
476 }
477
478 static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
479                                  struct ath10k_hif_sg_item *items, int n_items)
480 {
481         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
482         struct ath10k_ce *ce = ath10k_ce_priv(ar);
483         struct ath10k_snoc_pipe *snoc_pipe;
484         struct ath10k_ce_pipe *ce_pipe;
485         int err, i = 0;
486
487         snoc_pipe = &ar_snoc->pipe_info[pipe_id];
488         ce_pipe = snoc_pipe->ce_hdl;
489         spin_lock_bh(&ce->ce_lock);
490
491         for (i = 0; i < n_items - 1; i++) {
492                 ath10k_dbg(ar, ATH10K_DBG_SNOC,
493                            "snoc tx item %d paddr %pad len %d n_items %d\n",
494                            i, &items[i].paddr, items[i].len, n_items);
495
496                 err = ath10k_ce_send_nolock(ce_pipe,
497                                             items[i].transfer_context,
498                                             items[i].paddr,
499                                             items[i].len,
500                                             items[i].transfer_id,
501                                             CE_SEND_FLAG_GATHER);
502                 if (err)
503                         goto err;
504         }
505
506         ath10k_dbg(ar, ATH10K_DBG_SNOC,
507                    "snoc tx item %d paddr %pad len %d n_items %d\n",
508                    i, &items[i].paddr, items[i].len, n_items);
509
510         err = ath10k_ce_send_nolock(ce_pipe,
511                                     items[i].transfer_context,
512                                     items[i].paddr,
513                                     items[i].len,
514                                     items[i].transfer_id,
515                                     0);
516         if (err)
517                 goto err;
518
519         spin_unlock_bh(&ce->ce_lock);
520
521         return 0;
522
523 err:
524         for (; i > 0; i--)
525                 __ath10k_ce_send_revert(ce_pipe);
526
527         spin_unlock_bh(&ce->ce_lock);
528         return err;
529 }
530
531 static int ath10k_snoc_hif_get_target_info(struct ath10k *ar,
532                                            struct bmi_target_info *target_info)
533 {
534         target_info->version = ATH10K_HW_WCN3990;
535         target_info->type = ATH10K_HW_WCN3990;
536
537         return 0;
538 }
539
540 static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
541 {
542         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
543
544         ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
545
546         return ath10k_ce_num_free_src_entries(ar_snoc->pipe_info[pipe].ce_hdl);
547 }
548
549 static void ath10k_snoc_hif_send_complete_check(struct ath10k *ar, u8 pipe,
550                                                 int force)
551 {
552         int resources;
553
554         ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif send complete check\n");
555
556         if (!force) {
557                 resources = ath10k_snoc_hif_get_free_queue_number(ar, pipe);
558
559                 if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1))
560                         return;
561         }
562         ath10k_ce_per_engine_service(ar, pipe);
563 }
564
565 static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar,
566                                                u16 service_id,
567                                                u8 *ul_pipe, u8 *dl_pipe)
568 {
569         const struct service_to_pipe *entry;
570         bool ul_set = false, dl_set = false;
571         int i;
572
573         ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif map service\n");
574
575         for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
576                 entry = &target_service_to_ce_map_wlan[i];
577
578                 if (__le32_to_cpu(entry->service_id) != service_id)
579                         continue;
580
581                 switch (__le32_to_cpu(entry->pipedir)) {
582                 case PIPEDIR_NONE:
583                         break;
584                 case PIPEDIR_IN:
585                         WARN_ON(dl_set);
586                         *dl_pipe = __le32_to_cpu(entry->pipenum);
587                         dl_set = true;
588                         break;
589                 case PIPEDIR_OUT:
590                         WARN_ON(ul_set);
591                         *ul_pipe = __le32_to_cpu(entry->pipenum);
592                         ul_set = true;
593                         break;
594                 case PIPEDIR_INOUT:
595                         WARN_ON(dl_set);
596                         WARN_ON(ul_set);
597                         *dl_pipe = __le32_to_cpu(entry->pipenum);
598                         *ul_pipe = __le32_to_cpu(entry->pipenum);
599                         dl_set = true;
600                         ul_set = true;
601                         break;
602                 }
603         }
604
605         if (WARN_ON(!ul_set || !dl_set))
606                 return -ENOENT;
607
608         return 0;
609 }
610
611 static void ath10k_snoc_hif_get_default_pipe(struct ath10k *ar,
612                                              u8 *ul_pipe, u8 *dl_pipe)
613 {
614         ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif get default pipe\n");
615
616         (void)ath10k_snoc_hif_map_service_to_pipe(ar,
617                                                  ATH10K_HTC_SVC_ID_RSVD_CTRL,
618                                                  ul_pipe, dl_pipe);
619 }
620
621 static inline void ath10k_snoc_irq_disable(struct ath10k *ar)
622 {
623         ath10k_ce_disable_interrupts(ar);
624 }
625
626 static inline void ath10k_snoc_irq_enable(struct ath10k *ar)
627 {
628         ath10k_ce_enable_interrupts(ar);
629 }
630
631 static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
632 {
633         struct ath10k_ce_pipe *ce_pipe;
634         struct ath10k_ce_ring *ce_ring;
635         struct sk_buff *skb;
636         struct ath10k *ar;
637         int i;
638
639         ar = snoc_pipe->hif_ce_state;
640         ce_pipe = snoc_pipe->ce_hdl;
641         ce_ring = ce_pipe->dest_ring;
642
643         if (!ce_ring)
644                 return;
645
646         if (!snoc_pipe->buf_sz)
647                 return;
648
649         for (i = 0; i < ce_ring->nentries; i++) {
650                 skb = ce_ring->per_transfer_context[i];
651                 if (!skb)
652                         continue;
653
654                 ce_ring->per_transfer_context[i] = NULL;
655
656                 dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
657                                  skb->len + skb_tailroom(skb),
658                                  DMA_FROM_DEVICE);
659                 dev_kfree_skb_any(skb);
660         }
661 }
662
663 static void ath10k_snoc_tx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe)
664 {
665         struct ath10k_ce_pipe *ce_pipe;
666         struct ath10k_ce_ring *ce_ring;
667         struct ath10k_snoc *ar_snoc;
668         struct sk_buff *skb;
669         struct ath10k *ar;
670         int i;
671
672         ar = snoc_pipe->hif_ce_state;
673         ar_snoc = ath10k_snoc_priv(ar);
674         ce_pipe = snoc_pipe->ce_hdl;
675         ce_ring = ce_pipe->src_ring;
676
677         if (!ce_ring)
678                 return;
679
680         if (!snoc_pipe->buf_sz)
681                 return;
682
683         for (i = 0; i < ce_ring->nentries; i++) {
684                 skb = ce_ring->per_transfer_context[i];
685                 if (!skb)
686                         continue;
687
688                 ce_ring->per_transfer_context[i] = NULL;
689
690                 ath10k_htc_tx_completion_handler(ar, skb);
691         }
692 }
693
694 static void ath10k_snoc_buffer_cleanup(struct ath10k *ar)
695 {
696         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
697         struct ath10k_snoc_pipe *pipe_info;
698         int pipe_num;
699
700         del_timer_sync(&ar_snoc->rx_post_retry);
701         for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) {
702                 pipe_info = &ar_snoc->pipe_info[pipe_num];
703                 ath10k_snoc_rx_pipe_cleanup(pipe_info);
704                 ath10k_snoc_tx_pipe_cleanup(pipe_info);
705         }
706 }
707
708 static void ath10k_snoc_hif_stop(struct ath10k *ar)
709 {
710         ath10k_snoc_irq_disable(ar);
711         ath10k_snoc_buffer_cleanup(ar);
712         napi_synchronize(&ar->napi);
713         napi_disable(&ar->napi);
714         ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
715 }
716
717 static int ath10k_snoc_hif_start(struct ath10k *ar)
718 {
719         ath10k_snoc_irq_enable(ar);
720         ath10k_snoc_rx_post(ar);
721
722         ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n");
723
724         return 0;
725 }
726
727 static int ath10k_snoc_init_pipes(struct ath10k *ar)
728 {
729         int i, ret;
730
731         for (i = 0; i < CE_COUNT; i++) {
732                 ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]);
733                 if (ret) {
734                         ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n",
735                                    i, ret);
736                         return ret;
737                 }
738         }
739
740         return 0;
741 }
742
743 static int ath10k_snoc_wlan_enable(struct ath10k *ar)
744 {
745         return 0;
746 }
747
748 static void ath10k_snoc_wlan_disable(struct ath10k *ar)
749 {
750 }
751
752 static void ath10k_snoc_hif_power_down(struct ath10k *ar)
753 {
754         ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
755
756         ath10k_snoc_wlan_disable(ar);
757 }
758
759 static int ath10k_snoc_hif_power_up(struct ath10k *ar)
760 {
761         int ret;
762
763         ath10k_dbg(ar, ATH10K_DBG_SNOC, "%s:WCN3990 driver state = %d\n",
764                    __func__, ar->state);
765
766         ret = ath10k_snoc_wlan_enable(ar);
767         if (ret) {
768                 ath10k_err(ar, "failed to enable wcn3990: %d\n", ret);
769                 return ret;
770         }
771
772         ret = ath10k_snoc_init_pipes(ar);
773         if (ret) {
774                 ath10k_err(ar, "failed to initialize CE: %d\n", ret);
775                 goto err_wlan_enable;
776         }
777
778         napi_enable(&ar->napi);
779         return 0;
780
781 err_wlan_enable:
782         ath10k_snoc_wlan_disable(ar);
783
784         return ret;
785 }
786
787 static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
788         .read32         = ath10k_snoc_read32,
789         .write32        = ath10k_snoc_write32,
790         .start          = ath10k_snoc_hif_start,
791         .stop           = ath10k_snoc_hif_stop,
792         .map_service_to_pipe    = ath10k_snoc_hif_map_service_to_pipe,
793         .get_default_pipe       = ath10k_snoc_hif_get_default_pipe,
794         .power_up               = ath10k_snoc_hif_power_up,
795         .power_down             = ath10k_snoc_hif_power_down,
796         .tx_sg                  = ath10k_snoc_hif_tx_sg,
797         .send_complete_check    = ath10k_snoc_hif_send_complete_check,
798         .get_free_queue_number  = ath10k_snoc_hif_get_free_queue_number,
799         .get_target_info        = ath10k_snoc_hif_get_target_info,
800 };
801
802 static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
803         .read32         = ath10k_snoc_read32,
804         .write32        = ath10k_snoc_write32,
805 };
806
807 int ath10k_snoc_get_ce_id_from_irq(struct ath10k *ar, int irq)
808 {
809         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
810         int i;
811
812         for (i = 0; i < CE_COUNT_MAX; i++) {
813                 if (ar_snoc->ce_irqs[i].irq_line == irq)
814                         return i;
815         }
816         ath10k_err(ar, "No matching CE id for irq %d\n", irq);
817
818         return -EINVAL;
819 }
820
821 static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
822 {
823         struct ath10k *ar = arg;
824         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
825         int ce_id = ath10k_snoc_get_ce_id_from_irq(ar, irq);
826
827         if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_snoc->pipe_info)) {
828                 ath10k_warn(ar, "unexpected/invalid irq %d ce_id %d\n", irq,
829                             ce_id);
830                 return IRQ_HANDLED;
831         }
832
833         ath10k_snoc_irq_disable(ar);
834         napi_schedule(&ar->napi);
835
836         return IRQ_HANDLED;
837 }
838
839 static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
840 {
841         struct ath10k *ar = container_of(ctx, struct ath10k, napi);
842         int done = 0;
843
844         ath10k_ce_per_engine_service_any(ar);
845         done = ath10k_htt_txrx_compl_task(ar, budget);
846
847         if (done < budget) {
848                 napi_complete(ctx);
849                 ath10k_snoc_irq_enable(ar);
850         }
851
852         return done;
853 }
854
855 void ath10k_snoc_init_napi(struct ath10k *ar)
856 {
857         netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_snoc_napi_poll,
858                        ATH10K_NAPI_BUDGET);
859 }
860
861 static int ath10k_snoc_request_irq(struct ath10k *ar)
862 {
863         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
864         int irqflags = IRQF_TRIGGER_RISING;
865         int ret, id;
866
867         for (id = 0; id < CE_COUNT_MAX; id++) {
868                 ret = request_irq(ar_snoc->ce_irqs[id].irq_line,
869                                   ath10k_snoc_per_engine_handler,
870                                   irqflags, ce_name[id], ar);
871                 if (ret) {
872                         ath10k_err(ar,
873                                    "failed to register IRQ handler for CE %d: %d",
874                                    id, ret);
875                         goto err_irq;
876                 }
877         }
878
879         return 0;
880
881 err_irq:
882         for (id -= 1; id >= 0; id--)
883                 free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
884
885         return ret;
886 }
887
888 static void ath10k_snoc_free_irq(struct ath10k *ar)
889 {
890         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
891         int id;
892
893         for (id = 0; id < CE_COUNT_MAX; id++)
894                 free_irq(ar_snoc->ce_irqs[id].irq_line, ar);
895 }
896
897 static int ath10k_snoc_resource_init(struct ath10k *ar)
898 {
899         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
900         struct platform_device *pdev;
901         struct resource *res;
902         int i, ret = 0;
903
904         pdev = ar_snoc->dev;
905         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "membase");
906         if (!res) {
907                 ath10k_err(ar, "Memory base not found in DT\n");
908                 return -EINVAL;
909         }
910
911         ar_snoc->mem_pa = res->start;
912         ar_snoc->mem = devm_ioremap(&pdev->dev, ar_snoc->mem_pa,
913                                     resource_size(res));
914         if (!ar_snoc->mem) {
915                 ath10k_err(ar, "Memory base ioremap failed with physical address %pa\n",
916                            &ar_snoc->mem_pa);
917                 return -EINVAL;
918         }
919
920         for (i = 0; i < CE_COUNT; i++) {
921                 res = platform_get_resource(ar_snoc->dev, IORESOURCE_IRQ, i);
922                 if (!res) {
923                         ath10k_err(ar, "failed to get IRQ%d\n", i);
924                         ret = -ENODEV;
925                         goto out;
926                 }
927                 ar_snoc->ce_irqs[i].irq_line = res->start;
928         }
929
930 out:
931         return ret;
932 }
933
934 static int ath10k_snoc_setup_resource(struct ath10k *ar)
935 {
936         struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
937         struct ath10k_ce *ce = ath10k_ce_priv(ar);
938         struct ath10k_snoc_pipe *pipe;
939         int i, ret;
940
941         timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0);
942         spin_lock_init(&ce->ce_lock);
943         for (i = 0; i < CE_COUNT; i++) {
944                 pipe = &ar_snoc->pipe_info[i];
945                 pipe->ce_hdl = &ce->ce_states[i];
946                 pipe->pipe_num = i;
947                 pipe->hif_ce_state = ar;
948
949                 ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]);
950                 if (ret) {
951                         ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n",
952                                    i, ret);
953                         return ret;
954                 }
955
956                 pipe->buf_sz = host_ce_config_wlan[i].src_sz_max;
957         }
958         ath10k_snoc_init_napi(ar);
959
960         return 0;
961 }
962
963 static void ath10k_snoc_release_resource(struct ath10k *ar)
964 {
965         int i;
966
967         netif_napi_del(&ar->napi);
968         for (i = 0; i < CE_COUNT; i++)
969                 ath10k_ce_free_pipe(ar, i);
970 }
971
972 static const struct of_device_id ath10k_snoc_dt_match[] = {
973         { .compatible = "qcom,wcn3990-wifi",
974          .data = &drv_priv,
975         },
976         { }
977 };
978 MODULE_DEVICE_TABLE(of, ath10k_snoc_dt_match);
979
980 static int ath10k_snoc_probe(struct platform_device *pdev)
981 {
982         const struct ath10k_snoc_drv_priv *drv_data;
983         const struct of_device_id *of_id;
984         struct ath10k_snoc *ar_snoc;
985         struct device *dev;
986         struct ath10k *ar;
987         int ret;
988
989         of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev);
990         if (!of_id) {
991                 dev_err(&pdev->dev, "failed to find matching device tree id\n");
992                 return -EINVAL;
993         }
994
995         drv_data = of_id->data;
996         dev = &pdev->dev;
997
998         ret = dma_set_mask_and_coherent(dev, drv_data->dma_mask);
999         if (ret) {
1000                 dev_err(dev, "failed to set dma mask: %d", ret);
1001                 return ret;
1002         }
1003
1004         ar = ath10k_core_create(sizeof(*ar_snoc), dev, ATH10K_BUS_SNOC,
1005                                 drv_data->hw_rev, &ath10k_snoc_hif_ops);
1006         if (!ar) {
1007                 dev_err(dev, "failed to allocate core\n");
1008                 return -ENOMEM;
1009         }
1010
1011         ar_snoc = ath10k_snoc_priv(ar);
1012         ar_snoc->dev = pdev;
1013         platform_set_drvdata(pdev, ar);
1014         ar_snoc->ar = ar;
1015         ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops;
1016         ar->ce_priv = &ar_snoc->ce;
1017
1018         ath10k_snoc_resource_init(ar);
1019         if (ret) {
1020                 ath10k_warn(ar, "failed to initialize resource: %d\n", ret);
1021                 goto err_core_destroy;
1022         }
1023
1024         ath10k_snoc_setup_resource(ar);
1025         if (ret) {
1026                 ath10k_warn(ar, "failed to setup resource: %d\n", ret);
1027                 goto err_core_destroy;
1028         }
1029         ret = ath10k_snoc_request_irq(ar);
1030         if (ret) {
1031                 ath10k_warn(ar, "failed to request irqs: %d\n", ret);
1032                 goto err_release_resource;
1033         }
1034         ret = ath10k_core_register(ar, drv_data->hw_rev);
1035         if (ret) {
1036                 ath10k_err(ar, "failed to register driver core: %d\n", ret);
1037                 goto err_free_irq;
1038         }
1039         ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n");
1040         ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!");
1041
1042         return 0;
1043
1044 err_free_irq:
1045         ath10k_snoc_free_irq(ar);
1046
1047 err_release_resource:
1048         ath10k_snoc_release_resource(ar);
1049
1050 err_core_destroy:
1051         ath10k_core_destroy(ar);
1052
1053         return ret;
1054 }
1055
1056 static int ath10k_snoc_remove(struct platform_device *pdev)
1057 {
1058         struct ath10k *ar = platform_get_drvdata(pdev);
1059
1060         ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n");
1061         ath10k_core_unregister(ar);
1062         ath10k_snoc_free_irq(ar);
1063         ath10k_snoc_release_resource(ar);
1064         ath10k_core_destroy(ar);
1065
1066         return 0;
1067 }
1068
1069 static struct platform_driver ath10k_snoc_driver = {
1070                 .probe  = ath10k_snoc_probe,
1071                 .remove = ath10k_snoc_remove,
1072                 .driver = {
1073                         .name   = "ath10k_snoc",
1074                         .owner = THIS_MODULE,
1075                         .of_match_table = ath10k_snoc_dt_match,
1076                 },
1077 };
1078
1079 static int __init ath10k_snoc_init(void)
1080 {
1081         int ret;
1082
1083         ret = platform_driver_register(&ath10k_snoc_driver);
1084         if (ret)
1085                 pr_err("failed to register ath10k snoc driver: %d\n",
1086                        ret);
1087
1088         return ret;
1089 }
1090 module_init(ath10k_snoc_init);
1091
1092 static void __exit ath10k_snoc_exit(void)
1093 {
1094         platform_driver_unregister(&ath10k_snoc_driver);
1095 }
1096 module_exit(ath10k_snoc_exit);
1097
1098 MODULE_AUTHOR("Qualcomm");
1099 MODULE_LICENSE("Dual BSD/GPL");
1100 MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices");