1/* 10G controller driver for Samsung SoCs
2 *
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 *		http://www.samsung.com
5 *
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
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/* DMA core initialization */
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	/* if fix_burst = 0, Set UNDEF = 1 of DMA_Sys_Mode Register.
31	 * if fix_burst = 1, Set UNDEF = 0 of DMA_Sys_Mode Register.
32	 * burst_map is bitmap for  BLEN[4, 8, 16, 32, 64, 128 and 256].
33	 * Set burst_map irrespective of fix_burst value.
34	 */
35	if (!fix_burst)
36		reg_val |= SXGBE_DMA_AXI_UNDEF_BURST;
37
38	/* write burst len map */
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	/* set the pbl */
55	if (fix_burst) {
56		reg_val |= SXGBE_DMA_PBL_X8MODE;
57		writel(reg_val, ioaddr + SXGBE_DMA_CHA_CTL_REG(cha_num));
58		/* program the TX pbl */
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		/* program the RX pbl */
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	/* program desc registers */
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	/* program tail pointers */
80	/* assumption: upper 32 bits are constant and
81	 * same as TX/RX desc list
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	/* program the ring sizes */
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	/* Enable TX/RX interrupts */
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	/* Enable TX/RX interrupts */
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	/* Disable TX/RX interrupts */
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	/* TX Normal Interrupt Summary */
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		/* TX Abnormal Interrupt Summary */
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			/* Assumption: FBE bit is the combination of
223			 * all the bus access erros and cleared when
224			 * the respective error bits cleared
225			 */
226
227			/* check for actual cause */
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		/* context descriptor error */
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	/* clear the served bits */
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	/* RX Normal Interrupt Summary */
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		/* RX Abnormal Interrupt Summary */
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			/* Assumption: FBE bit is the combination of
295			 * all the bus access erros and cleared when
296			 * the respective error bits cleared
297			 */
298
299			/* check for actual cause */
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	/* clear the served bits */
322	writel(clear_val, ioaddr + SXGBE_DMA_CHA_STATUS_REG(channel_no));
323
324	return ret_val;
325}
326
327/* Program the HW RX Watchdog */
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