]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
d7447b05f7a5fd2b1240f4f7e37ede7040dec7e9
[thirdparty/kernel/stable.git] / drivers / net / ethernet / stmicro / stmmac / dwmac1000_dma.c
1 /*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
6 This contains the functions to handle the dma.
7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23 *******************************************************************************/
24
25 #include <asm/io.h>
26 #include "dwmac1000.h"
27 #include "dwmac_dma.h"
28
29 static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
30 {
31 u32 value = readl(ioaddr + DMA_AXI_BUS_MODE);
32 int i;
33
34 pr_info("dwmac1000: Master AXI performs %s burst length\n",
35 !(value & DMA_AXI_UNDEF) ? "fixed" : "any");
36
37 if (axi->axi_lpi_en)
38 value |= DMA_AXI_EN_LPI;
39 if (axi->axi_xit_frm)
40 value |= DMA_AXI_LPI_XIT_FRM;
41
42 value &= ~DMA_AXI_WR_OSR_LMT;
43 value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) <<
44 DMA_AXI_WR_OSR_LMT_SHIFT;
45
46 value &= ~DMA_AXI_RD_OSR_LMT;
47 value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) <<
48 DMA_AXI_RD_OSR_LMT_SHIFT;
49
50 /* Depending on the UNDEF bit the Master AXI will perform any burst
51 * length according to the BLEN programmed (by default all BLEN are
52 * set).
53 */
54 for (i = 0; i < AXI_BLEN; i++) {
55 switch (axi->axi_blen[i]) {
56 case 256:
57 value |= DMA_AXI_BLEN256;
58 break;
59 case 128:
60 value |= DMA_AXI_BLEN128;
61 break;
62 case 64:
63 value |= DMA_AXI_BLEN64;
64 break;
65 case 32:
66 value |= DMA_AXI_BLEN32;
67 break;
68 case 16:
69 value |= DMA_AXI_BLEN16;
70 break;
71 case 8:
72 value |= DMA_AXI_BLEN8;
73 break;
74 case 4:
75 value |= DMA_AXI_BLEN4;
76 break;
77 }
78 }
79
80 writel(value, ioaddr + DMA_AXI_BUS_MODE);
81 }
82
83 static void dwmac1000_dma_init(void __iomem *ioaddr,
84 struct stmmac_dma_cfg *dma_cfg,
85 u32 dma_tx, u32 dma_rx, int atds)
86 {
87 u32 value = readl(ioaddr + DMA_BUS_MODE);
88 int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
89 int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
90
91 /*
92 * Set the DMA PBL (Programmable Burst Length) mode.
93 *
94 * Note: before stmmac core 3.50 this mode bit was 4xPBL, and
95 * post 3.5 mode bit acts as 8*PBL.
96 */
97 if (dma_cfg->pblx8)
98 value |= DMA_BUS_MODE_MAXPBL;
99 value |= DMA_BUS_MODE_USP;
100 value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
101 value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
102 value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
103
104 /* Set the Fixed burst mode */
105 if (dma_cfg->fixed_burst)
106 value |= DMA_BUS_MODE_FB;
107
108 /* Mixed Burst has no effect when fb is set */
109 if (dma_cfg->mixed_burst)
110 value |= DMA_BUS_MODE_MB;
111
112 if (atds)
113 value |= DMA_BUS_MODE_ATDS;
114
115 if (dma_cfg->aal)
116 value |= DMA_BUS_MODE_AAL;
117
118 writel(value, ioaddr + DMA_BUS_MODE);
119
120 /* Mask interrupts by writing to CSR7 */
121 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
122
123 /* RX/TX descriptor base address lists must be written into
124 * DMA CSR3 and CSR4, respectively
125 */
126 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
127 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
128 }
129
130 static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz)
131 {
132 csr6 &= ~DMA_CONTROL_RFA_MASK;
133 csr6 &= ~DMA_CONTROL_RFD_MASK;
134
135 /* Leave flow control disabled if receive fifo size is less than
136 * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full,
137 * and send XON when 2K less than full.
138 */
139 if (rxfifosz < 4096) {
140 csr6 &= ~DMA_CONTROL_EFC;
141 pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n",
142 rxfifosz);
143 } else {
144 csr6 |= DMA_CONTROL_EFC;
145 csr6 |= RFA_FULL_MINUS_1K;
146 csr6 |= RFD_FULL_MINUS_2K;
147 }
148 return csr6;
149 }
150
151 static void dwmac1000_dma_operation_mode_rx(void __iomem *ioaddr, int mode,
152 u32 channel, int fifosz, u8 qmode)
153 {
154 u32 csr6 = readl(ioaddr + DMA_CONTROL);
155
156 if (mode == SF_DMA_MODE) {
157 pr_debug("GMAC: enable RX store and forward mode\n");
158 csr6 |= DMA_CONTROL_RSF;
159 } else {
160 pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
161 csr6 &= ~DMA_CONTROL_RSF;
162 csr6 &= DMA_CONTROL_TC_RX_MASK;
163 if (mode <= 32)
164 csr6 |= DMA_CONTROL_RTC_32;
165 else if (mode <= 64)
166 csr6 |= DMA_CONTROL_RTC_64;
167 else if (mode <= 96)
168 csr6 |= DMA_CONTROL_RTC_96;
169 else
170 csr6 |= DMA_CONTROL_RTC_128;
171 }
172
173 /* Configure flow control based on rx fifo size */
174 csr6 = dwmac1000_configure_fc(csr6, fifosz);
175
176 writel(csr6, ioaddr + DMA_CONTROL);
177 }
178
179 static void dwmac1000_dma_operation_mode_tx(void __iomem *ioaddr, int mode,
180 u32 channel, int fifosz, u8 qmode)
181 {
182 u32 csr6 = readl(ioaddr + DMA_CONTROL);
183
184 if (mode == SF_DMA_MODE) {
185 pr_debug("GMAC: enable TX store and forward mode\n");
186 /* Transmit COE type 2 cannot be done in cut-through mode. */
187 csr6 |= DMA_CONTROL_TSF;
188 /* Operating on second frame increase the performance
189 * especially when transmit store-and-forward is used.
190 */
191 csr6 |= DMA_CONTROL_OSF;
192 } else {
193 pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
194 csr6 &= ~DMA_CONTROL_TSF;
195 csr6 &= DMA_CONTROL_TC_TX_MASK;
196 /* Set the transmit threshold */
197 if (mode <= 32)
198 csr6 |= DMA_CONTROL_TTC_32;
199 else if (mode <= 64)
200 csr6 |= DMA_CONTROL_TTC_64;
201 else if (mode <= 128)
202 csr6 |= DMA_CONTROL_TTC_128;
203 else if (mode <= 192)
204 csr6 |= DMA_CONTROL_TTC_192;
205 else
206 csr6 |= DMA_CONTROL_TTC_256;
207 }
208
209 writel(csr6, ioaddr + DMA_CONTROL);
210 }
211
212 static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
213 {
214 int i;
215
216 for (i = 0; i < NUM_DWMAC1000_DMA_REGS; i++)
217 if ((i < 12) || (i > 17))
218 reg_space[DMA_BUS_MODE / 4 + i] =
219 readl(ioaddr + DMA_BUS_MODE + i * 4);
220 }
221
222 static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
223 struct dma_features *dma_cap)
224 {
225 u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
226
227 dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
228 dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
229 dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
230 dma_cap->hash_filter = (hw_cap & DMA_HW_FEAT_HASHSEL) >> 4;
231 dma_cap->multi_addr = (hw_cap & DMA_HW_FEAT_ADDMAC) >> 5;
232 dma_cap->pcs = (hw_cap & DMA_HW_FEAT_PCSSEL) >> 6;
233 dma_cap->sma_mdio = (hw_cap & DMA_HW_FEAT_SMASEL) >> 8;
234 dma_cap->pmt_remote_wake_up = (hw_cap & DMA_HW_FEAT_RWKSEL) >> 9;
235 dma_cap->pmt_magic_frame = (hw_cap & DMA_HW_FEAT_MGKSEL) >> 10;
236 /* MMC */
237 dma_cap->rmon = (hw_cap & DMA_HW_FEAT_MMCSEL) >> 11;
238 /* IEEE 1588-2002 */
239 dma_cap->time_stamp =
240 (hw_cap & DMA_HW_FEAT_TSVER1SEL) >> 12;
241 /* IEEE 1588-2008 */
242 dma_cap->atime_stamp = (hw_cap & DMA_HW_FEAT_TSVER2SEL) >> 13;
243 /* 802.3az - Energy-Efficient Ethernet (EEE) */
244 dma_cap->eee = (hw_cap & DMA_HW_FEAT_EEESEL) >> 14;
245 dma_cap->av = (hw_cap & DMA_HW_FEAT_AVSEL) >> 15;
246 /* TX and RX csum */
247 dma_cap->tx_coe = (hw_cap & DMA_HW_FEAT_TXCOESEL) >> 16;
248 dma_cap->rx_coe_type1 = (hw_cap & DMA_HW_FEAT_RXTYP1COE) >> 17;
249 dma_cap->rx_coe_type2 = (hw_cap & DMA_HW_FEAT_RXTYP2COE) >> 18;
250 dma_cap->rxfifo_over_2048 = (hw_cap & DMA_HW_FEAT_RXFIFOSIZE) >> 19;
251 /* TX and RX number of channels */
252 dma_cap->number_rx_channel = (hw_cap & DMA_HW_FEAT_RXCHCNT) >> 20;
253 dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
254 /* Alternate (enhanced) DESC mode */
255 dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
256 }
257
258 static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
259 u32 number_chan)
260 {
261 writel(riwt, ioaddr + DMA_RX_WATCHDOG);
262 }
263
264 const struct stmmac_dma_ops dwmac1000_dma_ops = {
265 .reset = dwmac_dma_reset,
266 .init = dwmac1000_dma_init,
267 .axi = dwmac1000_dma_axi,
268 .dump_regs = dwmac1000_dump_dma_regs,
269 .dma_rx_mode = dwmac1000_dma_operation_mode_rx,
270 .dma_tx_mode = dwmac1000_dma_operation_mode_tx,
271 .enable_dma_transmission = dwmac_enable_dma_transmission,
272 .enable_dma_irq = dwmac_enable_dma_irq,
273 .disable_dma_irq = dwmac_disable_dma_irq,
274 .start_tx = dwmac_dma_start_tx,
275 .stop_tx = dwmac_dma_stop_tx,
276 .start_rx = dwmac_dma_start_rx,
277 .stop_rx = dwmac_dma_stop_rx,
278 .dma_interrupt = dwmac_dma_interrupt,
279 .get_hw_feature = dwmac1000_get_hw_feature,
280 .rx_watchdog = dwmac1000_rx_watchdog,
281 };