Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / net / wireless / mediatek / mt76 / mt7615 / dma.c
1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2019 MediaTek Inc.
3  *
4  * Author: Ryder Lee <ryder.lee@mediatek.com>
5  *         Roy Luo <royluo@google.com>
6  *         Lorenzo Bianconi <lorenzo@kernel.org>
7  *         Felix Fietkau <nbd@nbd.name>
8  */
9
10 #include "mt7615.h"
11 #include "../dma.h"
12 #include "mac.h"
13
14 static int
15 mt7615_init_tx_queues(struct mt7615_dev *dev, int n_desc)
16 {
17         struct mt76_sw_queue *q;
18         struct mt76_queue *hwq;
19         int err, i;
20
21         hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
22         if (!hwq)
23                 return -ENOMEM;
24
25         err = mt76_queue_alloc(dev, hwq, 0, n_desc, 0, MT_TX_RING_BASE);
26         if (err < 0)
27                 return err;
28
29         for (i = 0; i < MT_TXQ_MCU; i++) {
30                 q = &dev->mt76.q_tx[i];
31                 INIT_LIST_HEAD(&q->swq);
32                 q->q = hwq;
33         }
34
35         return 0;
36 }
37
38 static int
39 mt7615_init_mcu_queue(struct mt7615_dev *dev, struct mt76_sw_queue *q,
40                       int idx, int n_desc)
41 {
42         struct mt76_queue *hwq;
43         int err;
44
45         hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
46         if (!hwq)
47                 return -ENOMEM;
48
49         err = mt76_queue_alloc(dev, hwq, idx, n_desc, 0, MT_TX_RING_BASE);
50         if (err < 0)
51                 return err;
52
53         INIT_LIST_HEAD(&q->swq);
54         q->q = hwq;
55
56         return 0;
57 }
58
59 void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
60                          struct sk_buff *skb)
61 {
62         struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
63         __le32 *rxd = (__le32 *)skb->data;
64         __le32 *end = (__le32 *)&skb->data[skb->len];
65         enum rx_pkt_type type;
66
67         type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
68
69         switch (type) {
70         case PKT_TYPE_TXS:
71                 for (rxd++; rxd + 7 <= end; rxd += 7)
72                         mt7615_mac_add_txs(dev, rxd);
73                 dev_kfree_skb(skb);
74                 break;
75         case PKT_TYPE_TXRX_NOTIFY:
76                 mt7615_mac_tx_free(dev, skb);
77                 break;
78         case PKT_TYPE_RX_EVENT:
79                 mt76_mcu_rx_event(&dev->mt76, skb);
80                 break;
81         case PKT_TYPE_NORMAL:
82                 if (!mt7615_mac_fill_rx(dev, skb)) {
83                         mt76_rx(&dev->mt76, q, skb);
84                         return;
85                 }
86                 /* fall through */
87         default:
88                 dev_kfree_skb(skb);
89                 break;
90         }
91 }
92
93 static void mt7615_tx_tasklet(unsigned long data)
94 {
95         struct mt7615_dev *dev = (struct mt7615_dev *)data;
96
97         mt76_txq_schedule_all(&dev->mt76);
98 }
99
100 static int mt7615_poll_tx(struct napi_struct *napi, int budget)
101 {
102         static const u8 queue_map[] = {
103                 MT_TXQ_MCU,
104                 MT_TXQ_BE
105         };
106         struct mt7615_dev *dev;
107         int i;
108
109         dev = container_of(napi, struct mt7615_dev, mt76.tx_napi);
110
111         for (i = 0; i < ARRAY_SIZE(queue_map); i++)
112                 mt76_queue_tx_cleanup(dev, queue_map[i], false);
113
114         if (napi_complete_done(napi, 0))
115                 mt7615_irq_enable(dev, MT_INT_TX_DONE_ALL);
116
117         for (i = 0; i < ARRAY_SIZE(queue_map); i++)
118                 mt76_queue_tx_cleanup(dev, queue_map[i], false);
119
120         tasklet_schedule(&dev->mt76.tx_tasklet);
121
122         return 0;
123 }
124
125 int mt7615_dma_init(struct mt7615_dev *dev)
126 {
127         int ret;
128
129         mt76_dma_attach(&dev->mt76);
130
131         tasklet_init(&dev->mt76.tx_tasklet, mt7615_tx_tasklet,
132                      (unsigned long)dev);
133
134         mt76_wr(dev, MT_WPDMA_GLO_CFG,
135                 MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE |
136                 MT_WPDMA_GLO_CFG_FIFO_LITTLE_ENDIAN |
137                 MT_WPDMA_GLO_CFG_FIRST_TOKEN_ONLY |
138                 MT_WPDMA_GLO_CFG_OMIT_TX_INFO);
139
140         mt76_rmw_field(dev, MT_WPDMA_GLO_CFG,
141                        MT_WPDMA_GLO_CFG_TX_BT_SIZE_BIT0, 0x1);
142
143         mt76_rmw_field(dev, MT_WPDMA_GLO_CFG,
144                        MT_WPDMA_GLO_CFG_TX_BT_SIZE_BIT21, 0x1);
145
146         mt76_rmw_field(dev, MT_WPDMA_GLO_CFG,
147                        MT_WPDMA_GLO_CFG_DMA_BURST_SIZE, 0x3);
148
149         mt76_rmw_field(dev, MT_WPDMA_GLO_CFG,
150                        MT_WPDMA_GLO_CFG_MULTI_DMA_EN, 0x3);
151
152         mt76_wr(dev, MT_WPDMA_GLO_CFG1, 0x1);
153         mt76_wr(dev, MT_WPDMA_TX_PRE_CFG, 0xf0000);
154         mt76_wr(dev, MT_WPDMA_RX_PRE_CFG, 0xf7f0000);
155         mt76_wr(dev, MT_WPDMA_ABT_CFG, 0x4000026);
156         mt76_wr(dev, MT_WPDMA_ABT_CFG1, 0x18811881);
157         mt76_set(dev, 0x7158, BIT(16));
158         mt76_clear(dev, 0x7000, BIT(23));
159         mt76_wr(dev, MT_WPDMA_RST_IDX, ~0);
160
161         ret = mt7615_init_tx_queues(dev, MT7615_TX_RING_SIZE);
162         if (ret)
163                 return ret;
164
165         ret = mt7615_init_mcu_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU],
166                                     MT7615_TXQ_MCU,
167                                     MT7615_TX_MCU_RING_SIZE);
168         if (ret)
169                 return ret;
170
171         ret = mt7615_init_mcu_queue(dev, &dev->mt76.q_tx[MT_TXQ_FWDL],
172                                     MT7615_TXQ_FWDL,
173                                     MT7615_TX_FWDL_RING_SIZE);
174         if (ret)
175                 return ret;
176
177         /* init rx queues */
178         ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1,
179                                MT7615_RX_MCU_RING_SIZE, MT_RX_BUF_SIZE,
180                                MT_RX_RING_BASE);
181         if (ret)
182                 return ret;
183
184         ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0,
185                                MT7615_RX_RING_SIZE, MT_RX_BUF_SIZE,
186                                MT_RX_RING_BASE);
187         if (ret)
188                 return ret;
189
190         mt76_wr(dev, MT_DELAY_INT_CFG, 0);
191
192         ret = mt76_init_queues(dev);
193         if (ret < 0)
194                 return ret;
195
196         netif_tx_napi_add(&dev->mt76.napi_dev, &dev->mt76.tx_napi,
197                           mt7615_poll_tx, NAPI_POLL_WEIGHT);
198         napi_enable(&dev->mt76.tx_napi);
199
200         mt76_poll(dev, MT_WPDMA_GLO_CFG,
201                   MT_WPDMA_GLO_CFG_TX_DMA_BUSY |
202                   MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 1000);
203
204         /* start dma engine */
205         mt76_set(dev, MT_WPDMA_GLO_CFG,
206                  MT_WPDMA_GLO_CFG_TX_DMA_EN |
207                  MT_WPDMA_GLO_CFG_RX_DMA_EN);
208
209         /* enable interrupts for TX/RX rings */
210         mt7615_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL);
211
212         return 0;
213 }
214
215 void mt7615_dma_cleanup(struct mt7615_dev *dev)
216 {
217         mt76_clear(dev, MT_WPDMA_GLO_CFG,
218                    MT_WPDMA_GLO_CFG_TX_DMA_EN |
219                    MT_WPDMA_GLO_CFG_RX_DMA_EN);
220         mt76_set(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_SW_RESET);
221
222         tasklet_kill(&dev->mt76.tx_tasklet);
223         mt76_dma_cleanup(&dev->mt76);
224 }