1
2
3
4
5
6
7
8
9
10
11
12#include <linux/delay.h>
13#include <linux/export.h>
14#include <linux/io.h>
15#include <linux/netdevice.h>
16#include <linux/phy.h>
17
18#include "sxgbe_common.h"
19#include "sxgbe_dma.h"
20#include "sxgbe_reg.h"
21#include "sxgbe_desc.h"
22
23
24static int sxgbe_dma_init(void __iomem *ioaddr, int fix_burst, int burst_map)
25{
26 u32 reg_val;
27
28 reg_val = readl(ioaddr + SXGBE_DMA_SYSBUS_MODE_REG);
29
30
31
32
33
34
35 if (!fix_burst)
36 reg_val |= SXGBE_DMA_AXI_UNDEF_BURST;
37
38
39 reg_val |= (burst_map << SXGBE_DMA_BLENMAP_LSHIFT);
40
41 writel(reg_val, ioaddr + SXGBE_DMA_SYSBUS_MODE_REG);
42
43 return 0;
44}
45
46static void sxgbe_dma_channel_init(void __iomem *ioaddr, int cha_num,
47 int fix_burst, int pbl, dma_addr_t dma_tx,
48 dma_addr_t dma_rx, int t_rsize, int r_rsize)
49{
50 u32 reg_val;
51 dma_addr_t dma_addr;
52
53 reg_val = readl(ioaddr + SXGBE_DMA_CHA_CTL_REG(cha_num));
54
55 if (fix_burst) {
56 reg_val |= SXGBE_DMA_PBL_X8MODE;
57 writel(reg_val, ioaddr + SXGBE_DMA_CHA_CTL_REG(cha_num));
58
59 reg_val = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cha_num));
60 reg_val |= (pbl << SXGBE_DMA_TXPBL_LSHIFT);
61 writel(reg_val, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cha_num));
62
63 reg_val = readl(ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cha_num));
64 reg_val |= (pbl << SXGBE_DMA_RXPBL_LSHIFT);
65 writel(reg_val, ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cha_num));
66 }
67
68
69 writel(upper_32_bits(dma_tx),
70 ioaddr + SXGBE_DMA_CHA_TXDESC_HADD_REG(cha_num));
71 writel(lower_32_bits(dma_tx),
72 ioaddr + SXGBE_DMA_CHA_TXDESC_LADD_REG(cha_num));
73
74 writel(upper_32_bits(dma_rx),
75 ioaddr + SXGBE_DMA_CHA_RXDESC_HADD_REG(cha_num));
76 writel(lower_32_bits(dma_rx),
77 ioaddr + SXGBE_DMA_CHA_RXDESC_LADD_REG(cha_num));
78
79
80
81
82
83 dma_addr = dma_tx + ((t_rsize - 1) * SXGBE_DESC_SIZE_BYTES);
84 writel(lower_32_bits(dma_addr),
85 ioaddr + SXGBE_DMA_CHA_TXDESC_TAILPTR_REG(cha_num));
86
87 dma_addr = dma_rx + ((r_rsize - 1) * SXGBE_DESC_SIZE_BYTES);
88 writel(lower_32_bits(dma_addr),
89 ioaddr + SXGBE_DMA_CHA_RXDESC_LADD_REG(cha_num));
90
91 writel(t_rsize - 1, ioaddr + SXGBE_DMA_CHA_TXDESC_RINGLEN_REG(cha_num));
92 writel(r_rsize - 1, ioaddr + SXGBE_DMA_CHA_RXDESC_RINGLEN_REG(cha_num));
93
94
95 writel(SXGBE_DMA_ENA_INT,
96 ioaddr + SXGBE_DMA_CHA_INT_ENABLE_REG(cha_num));
97}
98
99static void sxgbe_enable_dma_transmission(void __iomem *ioaddr, int cha_num)
100{
101 u32 tx_config;
102
103 tx_config = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cha_num));
104 tx_config |= SXGBE_TX_START_DMA;
105 writel(tx_config, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cha_num));
106}
107
108static void sxgbe_enable_dma_irq(void __iomem *ioaddr, int dma_cnum)
109{
110
111 writel(SXGBE_DMA_ENA_INT,
112 ioaddr + SXGBE_DMA_CHA_INT_ENABLE_REG(dma_cnum));
113}
114
115static void sxgbe_disable_dma_irq(void __iomem *ioaddr, int dma_cnum)
116{
117
118 writel(0, ioaddr + SXGBE_DMA_CHA_INT_ENABLE_REG(dma_cnum));
119}
120
121static void sxgbe_dma_start_tx(void __iomem *ioaddr, int tchannels)
122{
123 int cnum;
124 u32 tx_ctl_reg;
125
126 for (cnum = 0; cnum < tchannels; cnum++) {
127 tx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cnum));
128 tx_ctl_reg |= SXGBE_TX_ENABLE;
129 writel(tx_ctl_reg,
130 ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cnum));
131 }
132}
133
134static void sxgbe_dma_start_tx_queue(void __iomem *ioaddr, int dma_cnum)
135{
136 u32 tx_ctl_reg;
137
138 tx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(dma_cnum));
139 tx_ctl_reg |= SXGBE_TX_ENABLE;
140 writel(tx_ctl_reg, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(dma_cnum));
141}
142
143static void sxgbe_dma_stop_tx_queue(void __iomem *ioaddr, int dma_cnum)
144{
145 u32 tx_ctl_reg;
146
147 tx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(dma_cnum));
148 tx_ctl_reg &= ~(SXGBE_TX_ENABLE);
149 writel(tx_ctl_reg, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(dma_cnum));
150}
151
152static void sxgbe_dma_stop_tx(void __iomem *ioaddr, int tchannels)
153{
154 int cnum;
155 u32 tx_ctl_reg;
156
157 for (cnum = 0; cnum < tchannels; cnum++) {
158 tx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cnum));
159 tx_ctl_reg &= ~(SXGBE_TX_ENABLE);
160 writel(tx_ctl_reg, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(cnum));
161 }
162}
163
164static void sxgbe_dma_start_rx(void __iomem *ioaddr, int rchannels)
165{
166 int cnum;
167 u32 rx_ctl_reg;
168
169 for (cnum = 0; cnum < rchannels; cnum++) {
170 rx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cnum));
171 rx_ctl_reg |= SXGBE_RX_ENABLE;
172 writel(rx_ctl_reg,
173 ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cnum));
174 }
175}
176
177static void sxgbe_dma_stop_rx(void __iomem *ioaddr, int rchannels)
178{
179 int cnum;
180 u32 rx_ctl_reg;
181
182 for (cnum = 0; cnum < rchannels; cnum++) {
183 rx_ctl_reg = readl(ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cnum));
184 rx_ctl_reg &= ~(SXGBE_RX_ENABLE);
185 writel(rx_ctl_reg, ioaddr + SXGBE_DMA_CHA_RXCTL_REG(cnum));
186 }
187}
188
189static int sxgbe_tx_dma_int_status(void __iomem *ioaddr, int channel_no,
190 struct sxgbe_extra_stats *x)
191{
192 u32 int_status = readl(ioaddr + SXGBE_DMA_CHA_STATUS_REG(channel_no));
193 u32 clear_val = 0;
194 u32 ret_val = 0;
195
196
197 if (likely(int_status & SXGBE_DMA_INT_STATUS_NIS)) {
198 x->normal_irq_n++;
199 if (int_status & SXGBE_DMA_INT_STATUS_TI) {
200 ret_val |= handle_tx;
201 x->tx_normal_irq_n++;
202 clear_val |= SXGBE_DMA_INT_STATUS_TI;
203 }
204
205 if (int_status & SXGBE_DMA_INT_STATUS_TBU) {
206 x->tx_underflow_irq++;
207 ret_val |= tx_bump_tc;
208 clear_val |= SXGBE_DMA_INT_STATUS_TBU;
209 }
210 } else if (unlikely(int_status & SXGBE_DMA_INT_STATUS_AIS)) {
211
212 if (int_status & SXGBE_DMA_INT_STATUS_TPS) {
213 ret_val |= tx_hard_error;
214 clear_val |= SXGBE_DMA_INT_STATUS_TPS;
215 x->tx_process_stopped_irq++;
216 }
217
218 if (int_status & SXGBE_DMA_INT_STATUS_FBE) {
219 ret_val |= tx_hard_error;
220 x->fatal_bus_error_irq++;
221
222
223
224
225
226
227
228 if (int_status & SXGBE_DMA_INT_STATUS_TEB0) {
229 x->tx_read_transfer_err++;
230 clear_val |= SXGBE_DMA_INT_STATUS_TEB0;
231 } else {
232 x->tx_write_transfer_err++;
233 }
234
235 if (int_status & SXGBE_DMA_INT_STATUS_TEB1) {
236 x->tx_desc_access_err++;
237 clear_val |= SXGBE_DMA_INT_STATUS_TEB1;
238 } else {
239 x->tx_buffer_access_err++;
240 }
241
242 if (int_status & SXGBE_DMA_INT_STATUS_TEB2) {
243 x->tx_data_transfer_err++;
244 clear_val |= SXGBE_DMA_INT_STATUS_TEB2;
245 }
246 }
247
248
249 if (int_status & SXGBE_DMA_INT_STATUS_CTXTERR) {
250 x->tx_ctxt_desc_err++;
251 clear_val |= SXGBE_DMA_INT_STATUS_CTXTERR;
252 }
253 }
254
255
256 writel(clear_val, ioaddr + SXGBE_DMA_CHA_STATUS_REG(channel_no));
257
258 return ret_val;
259}
260
261static int sxgbe_rx_dma_int_status(void __iomem *ioaddr, int channel_no,
262 struct sxgbe_extra_stats *x)
263{
264 u32 int_status = readl(ioaddr + SXGBE_DMA_CHA_STATUS_REG(channel_no));
265 u32 clear_val = 0;
266 u32 ret_val = 0;
267
268
269 if (likely(int_status & SXGBE_DMA_INT_STATUS_NIS)) {
270 x->normal_irq_n++;
271 if (int_status & SXGBE_DMA_INT_STATUS_RI) {
272 ret_val |= handle_rx;
273 x->rx_normal_irq_n++;
274 clear_val |= SXGBE_DMA_INT_STATUS_RI;
275 }
276 } else if (unlikely(int_status & SXGBE_DMA_INT_STATUS_AIS)) {
277
278 if (int_status & SXGBE_DMA_INT_STATUS_RBU) {
279 ret_val |= rx_bump_tc;
280 clear_val |= SXGBE_DMA_INT_STATUS_RBU;
281 x->rx_underflow_irq++;
282 }
283
284 if (int_status & SXGBE_DMA_INT_STATUS_RPS) {
285 ret_val |= rx_hard_error;
286 clear_val |= SXGBE_DMA_INT_STATUS_RPS;
287 x->rx_process_stopped_irq++;
288 }
289
290 if (int_status & SXGBE_DMA_INT_STATUS_FBE) {
291 ret_val |= rx_hard_error;
292 x->fatal_bus_error_irq++;
293
294
295
296
297
298
299
300 if (int_status & SXGBE_DMA_INT_STATUS_REB0) {
301 x->rx_read_transfer_err++;
302 clear_val |= SXGBE_DMA_INT_STATUS_REB0;
303 } else {
304 x->rx_write_transfer_err++;
305 }
306
307 if (int_status & SXGBE_DMA_INT_STATUS_REB1) {
308 x->rx_desc_access_err++;
309 clear_val |= SXGBE_DMA_INT_STATUS_REB1;
310 } else {
311 x->rx_buffer_access_err++;
312 }
313
314 if (int_status & SXGBE_DMA_INT_STATUS_REB2) {
315 x->rx_data_transfer_err++;
316 clear_val |= SXGBE_DMA_INT_STATUS_REB2;
317 }
318 }
319 }
320
321
322 writel(clear_val, ioaddr + SXGBE_DMA_CHA_STATUS_REG(channel_no));
323
324 return ret_val;
325}
326
327
328static void sxgbe_dma_rx_watchdog(void __iomem *ioaddr, u32 riwt)
329{
330 u32 que_num;
331
332 SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, que_num) {
333 writel(riwt,
334 ioaddr + SXGBE_DMA_CHA_INT_RXWATCHTMR_REG(que_num));
335 }
336}
337
338static void sxgbe_enable_tso(void __iomem *ioaddr, u8 chan_num)
339{
340 u32 ctrl;
341
342 ctrl = readl(ioaddr + SXGBE_DMA_CHA_TXCTL_REG(chan_num));
343 ctrl |= SXGBE_DMA_CHA_TXCTL_TSE_ENABLE;
344 writel(ctrl, ioaddr + SXGBE_DMA_CHA_TXCTL_REG(chan_num));
345}
346
347static const struct sxgbe_dma_ops sxgbe_dma_ops = {
348 .init = sxgbe_dma_init,
349 .cha_init = sxgbe_dma_channel_init,
350 .enable_dma_transmission = sxgbe_enable_dma_transmission,
351 .enable_dma_irq = sxgbe_enable_dma_irq,
352 .disable_dma_irq = sxgbe_disable_dma_irq,
353 .start_tx = sxgbe_dma_start_tx,
354 .start_tx_queue = sxgbe_dma_start_tx_queue,
355 .stop_tx = sxgbe_dma_stop_tx,
356 .stop_tx_queue = sxgbe_dma_stop_tx_queue,
357 .start_rx = sxgbe_dma_start_rx,
358 .stop_rx = sxgbe_dma_stop_rx,
359 .tx_dma_int_status = sxgbe_tx_dma_int_status,
360 .rx_dma_int_status = sxgbe_rx_dma_int_status,
361 .rx_watchdog = sxgbe_dma_rx_watchdog,
362 .enable_tso = sxgbe_enable_tso,
363};
364
365const struct sxgbe_dma_ops *sxgbe_get_dma_ops(void)
366{
367 return &sxgbe_dma_ops;
368}
369