diff options
author | Jose Abreu <Jose.Abreu@synopsys.com> | 2018-08-08 04:04:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-09 14:16:28 -0400 |
commit | d6ddfacd95c79d43465d4a85dffb1c9beca343a9 (patch) | |
tree | daf1d4a5538490d1d53d74920159636c7c8db721 | |
parent | 2142754f8b9c619e22e1c9d1973cacc4a214695c (diff) |
net: stmmac: Add DMA related callbacks for XGMAC2
Add the DMA related callbacks for the new IP block XGMAC2.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | 57 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 411 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/hwif.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/hwif.h | 1 |
5 files changed, 471 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index a6cf632c9592..da40d3bba037 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile | |||
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \ | |||
5 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ | 5 | dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \ |
6 | mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ | 6 | mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \ |
7 | dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \ | 7 | dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \ |
8 | stmmac_tc.o dwxgmac2_core.o $(stmmac-y) | 8 | stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y) |
9 | 9 | ||
10 | # Ordering matters. Generic driver must be last. | 10 | # Ordering matters. Generic driver must be last. |
11 | obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o | 11 | obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h index 7832571f791f..a6992332f801 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h | |||
@@ -138,4 +138,61 @@ | |||
138 | #define XGMAC_ABPSIS BIT(1) | 138 | #define XGMAC_ABPSIS BIT(1) |
139 | #define XGMAC_TXUNFIS BIT(0) | 139 | #define XGMAC_TXUNFIS BIT(0) |
140 | 140 | ||
141 | /* DMA Registers */ | ||
142 | #define XGMAC_DMA_MODE 0x00003000 | ||
143 | #define XGMAC_SWR BIT(0) | ||
144 | #define XGMAC_DMA_SYSBUS_MODE 0x00003004 | ||
145 | #define XGMAC_WR_OSR_LMT GENMASK(29, 24) | ||
146 | #define XGMAC_WR_OSR_LMT_SHIFT 24 | ||
147 | #define XGMAC_RD_OSR_LMT GENMASK(21, 16) | ||
148 | #define XGMAC_RD_OSR_LMT_SHIFT 16 | ||
149 | #define XGMAC_EN_LPI BIT(15) | ||
150 | #define XGMAC_LPI_XIT_PKT BIT(14) | ||
151 | #define XGMAC_AAL BIT(12) | ||
152 | #define XGMAC_BLEN GENMASK(7, 1) | ||
153 | #define XGMAC_BLEN256 BIT(7) | ||
154 | #define XGMAC_BLEN128 BIT(6) | ||
155 | #define XGMAC_BLEN64 BIT(5) | ||
156 | #define XGMAC_BLEN32 BIT(4) | ||
157 | #define XGMAC_BLEN16 BIT(3) | ||
158 | #define XGMAC_BLEN8 BIT(2) | ||
159 | #define XGMAC_BLEN4 BIT(1) | ||
160 | #define XGMAC_UNDEF BIT(0) | ||
161 | #define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x))) | ||
162 | #define XGMAC_PBLx8 BIT(16) | ||
163 | #define XGMAC_DMA_CH_TX_CONTROL(x) (0x00003104 + (0x80 * (x))) | ||
164 | #define XGMAC_TxPBL GENMASK(21, 16) | ||
165 | #define XGMAC_TxPBL_SHIFT 16 | ||
166 | #define XGMAC_TSE BIT(12) | ||
167 | #define XGMAC_OSP BIT(4) | ||
168 | #define XGMAC_TXST BIT(0) | ||
169 | #define XGMAC_DMA_CH_RX_CONTROL(x) (0x00003108 + (0x80 * (x))) | ||
170 | #define XGMAC_RxPBL GENMASK(21, 16) | ||
171 | #define XGMAC_RxPBL_SHIFT 16 | ||
172 | #define XGMAC_RXST BIT(0) | ||
173 | #define XGMAC_DMA_CH_TxDESC_LADDR(x) (0x00003114 + (0x80 * (x))) | ||
174 | #define XGMAC_DMA_CH_RxDESC_LADDR(x) (0x0000311c + (0x80 * (x))) | ||
175 | #define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x) (0x00003124 + (0x80 * (x))) | ||
176 | #define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x) (0x0000312c + (0x80 * (x))) | ||
177 | #define XGMAC_DMA_CH_TxDESC_RING_LEN(x) (0x00003130 + (0x80 * (x))) | ||
178 | #define XGMAC_DMA_CH_RxDESC_RING_LEN(x) (0x00003134 + (0x80 * (x))) | ||
179 | #define XGMAC_DMA_CH_INT_EN(x) (0x00003138 + (0x80 * (x))) | ||
180 | #define XGMAC_NIE BIT(15) | ||
181 | #define XGMAC_AIE BIT(14) | ||
182 | #define XGMAC_RBUE BIT(7) | ||
183 | #define XGMAC_RIE BIT(6) | ||
184 | #define XGMAC_TIE BIT(0) | ||
185 | #define XGMAC_DMA_INT_DEFAULT_EN (XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \ | ||
186 | XGMAC_RIE | XGMAC_TIE) | ||
187 | #define XGMAC_DMA_CH_Rx_WATCHDOG(x) (0x0000313c + (0x80 * (x))) | ||
188 | #define XGMAC_RWT GENMASK(7, 0) | ||
189 | #define XGMAC_DMA_CH_STATUS(x) (0x00003160 + (0x80 * (x))) | ||
190 | #define XGMAC_NIS BIT(15) | ||
191 | #define XGMAC_AIS BIT(14) | ||
192 | #define XGMAC_FBE BIT(12) | ||
193 | #define XGMAC_RBU BIT(7) | ||
194 | #define XGMAC_RI BIT(6) | ||
195 | #define XGMAC_TPS BIT(1) | ||
196 | #define XGMAC_TI BIT(0) | ||
197 | |||
141 | #endif /* __STMMAC_DWXGMAC2_H__ */ | 198 | #endif /* __STMMAC_DWXGMAC2_H__ */ |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c new file mode 100644 index 000000000000..20909036e002 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | |||
@@ -0,0 +1,411 @@ | |||
1 | // SPDX-License-Identifier: (GPL-2.0 OR MIT) | ||
2 | /* | ||
3 | * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates. | ||
4 | * stmmac XGMAC support. | ||
5 | */ | ||
6 | |||
7 | #include <linux/iopoll.h> | ||
8 | #include "stmmac.h" | ||
9 | #include "dwxgmac2.h" | ||
10 | |||
11 | static int dwxgmac2_dma_reset(void __iomem *ioaddr) | ||
12 | { | ||
13 | u32 value = readl(ioaddr + XGMAC_DMA_MODE); | ||
14 | |||
15 | /* DMA SW reset */ | ||
16 | writel(value | XGMAC_SWR, ioaddr + XGMAC_DMA_MODE); | ||
17 | |||
18 | return readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value, | ||
19 | !(value & XGMAC_SWR), 0, 100000); | ||
20 | } | ||
21 | |||
22 | static void dwxgmac2_dma_init(void __iomem *ioaddr, | ||
23 | struct stmmac_dma_cfg *dma_cfg, int atds) | ||
24 | { | ||
25 | u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE); | ||
26 | |||
27 | if (dma_cfg->aal) | ||
28 | value |= XGMAC_AAL; | ||
29 | |||
30 | writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE); | ||
31 | } | ||
32 | |||
33 | static void dwxgmac2_dma_init_chan(void __iomem *ioaddr, | ||
34 | struct stmmac_dma_cfg *dma_cfg, u32 chan) | ||
35 | { | ||
36 | u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan)); | ||
37 | |||
38 | if (dma_cfg->pblx8) | ||
39 | value |= XGMAC_PBLx8; | ||
40 | |||
41 | writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan)); | ||
42 | writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | ||
43 | } | ||
44 | |||
45 | static void dwxgmac2_dma_init_rx_chan(void __iomem *ioaddr, | ||
46 | struct stmmac_dma_cfg *dma_cfg, | ||
47 | u32 dma_rx_phy, u32 chan) | ||
48 | { | ||
49 | u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl; | ||
50 | u32 value; | ||
51 | |||
52 | value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
53 | value &= ~XGMAC_RxPBL; | ||
54 | value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL; | ||
55 | writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
56 | |||
57 | writel(dma_rx_phy, ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan)); | ||
58 | } | ||
59 | |||
60 | static void dwxgmac2_dma_init_tx_chan(void __iomem *ioaddr, | ||
61 | struct stmmac_dma_cfg *dma_cfg, | ||
62 | u32 dma_tx_phy, u32 chan) | ||
63 | { | ||
64 | u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl; | ||
65 | u32 value; | ||
66 | |||
67 | value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
68 | value &= ~XGMAC_TxPBL; | ||
69 | value |= (txpbl << XGMAC_TxPBL_SHIFT) & XGMAC_TxPBL; | ||
70 | value |= XGMAC_OSP; | ||
71 | writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
72 | |||
73 | writel(dma_tx_phy, ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan)); | ||
74 | } | ||
75 | |||
76 | static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) | ||
77 | { | ||
78 | u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE); | ||
79 | int i; | ||
80 | |||
81 | if (axi->axi_lpi_en) | ||
82 | value |= XGMAC_EN_LPI; | ||
83 | if (axi->axi_xit_frm) | ||
84 | value |= XGMAC_LPI_XIT_PKT; | ||
85 | |||
86 | value &= ~XGMAC_WR_OSR_LMT; | ||
87 | value |= (axi->axi_wr_osr_lmt << XGMAC_WR_OSR_LMT_SHIFT) & | ||
88 | XGMAC_WR_OSR_LMT; | ||
89 | |||
90 | value &= ~XGMAC_RD_OSR_LMT; | ||
91 | value |= (axi->axi_rd_osr_lmt << XGMAC_RD_OSR_LMT_SHIFT) & | ||
92 | XGMAC_RD_OSR_LMT; | ||
93 | |||
94 | value &= ~XGMAC_BLEN; | ||
95 | for (i = 0; i < AXI_BLEN; i++) { | ||
96 | if (axi->axi_blen[i]) | ||
97 | value &= ~XGMAC_UNDEF; | ||
98 | |||
99 | switch (axi->axi_blen[i]) { | ||
100 | case 256: | ||
101 | value |= XGMAC_BLEN256; | ||
102 | break; | ||
103 | case 128: | ||
104 | value |= XGMAC_BLEN128; | ||
105 | break; | ||
106 | case 64: | ||
107 | value |= XGMAC_BLEN64; | ||
108 | break; | ||
109 | case 32: | ||
110 | value |= XGMAC_BLEN32; | ||
111 | break; | ||
112 | case 16: | ||
113 | value |= XGMAC_BLEN16; | ||
114 | break; | ||
115 | case 8: | ||
116 | value |= XGMAC_BLEN8; | ||
117 | break; | ||
118 | case 4: | ||
119 | value |= XGMAC_BLEN4; | ||
120 | break; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE); | ||
125 | } | ||
126 | |||
127 | static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode, | ||
128 | u32 channel, int fifosz, u8 qmode) | ||
129 | { | ||
130 | u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel)); | ||
131 | unsigned int rqs = fifosz / 256 - 1; | ||
132 | |||
133 | if (mode == SF_DMA_MODE) { | ||
134 | value |= XGMAC_RSF; | ||
135 | } else { | ||
136 | value &= ~XGMAC_RSF; | ||
137 | value &= ~XGMAC_RTC; | ||
138 | |||
139 | if (mode <= 64) | ||
140 | value |= 0x0 << XGMAC_RTC_SHIFT; | ||
141 | else if (mode <= 96) | ||
142 | value |= 0x2 << XGMAC_RTC_SHIFT; | ||
143 | else | ||
144 | value |= 0x3 << XGMAC_RTC_SHIFT; | ||
145 | } | ||
146 | |||
147 | value &= ~XGMAC_RQS; | ||
148 | value |= (rqs << XGMAC_RQS_SHIFT) & XGMAC_RQS; | ||
149 | |||
150 | writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel)); | ||
151 | |||
152 | /* Enable MTL RX overflow */ | ||
153 | value = readl(ioaddr + XGMAC_MTL_QINTEN(channel)); | ||
154 | writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel)); | ||
155 | } | ||
156 | |||
157 | static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode, | ||
158 | u32 channel, int fifosz, u8 qmode) | ||
159 | { | ||
160 | u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel)); | ||
161 | unsigned int tqs = fifosz / 256 - 1; | ||
162 | |||
163 | if (mode == SF_DMA_MODE) { | ||
164 | value |= XGMAC_TSF; | ||
165 | } else { | ||
166 | value &= ~XGMAC_TSF; | ||
167 | value &= ~XGMAC_TTC; | ||
168 | |||
169 | if (mode <= 64) | ||
170 | value |= 0x0 << XGMAC_TTC_SHIFT; | ||
171 | else if (mode <= 96) | ||
172 | value |= 0x2 << XGMAC_TTC_SHIFT; | ||
173 | else if (mode <= 128) | ||
174 | value |= 0x3 << XGMAC_TTC_SHIFT; | ||
175 | else if (mode <= 192) | ||
176 | value |= 0x4 << XGMAC_TTC_SHIFT; | ||
177 | else if (mode <= 256) | ||
178 | value |= 0x5 << XGMAC_TTC_SHIFT; | ||
179 | else if (mode <= 384) | ||
180 | value |= 0x6 << XGMAC_TTC_SHIFT; | ||
181 | else | ||
182 | value |= 0x7 << XGMAC_TTC_SHIFT; | ||
183 | } | ||
184 | |||
185 | value &= ~XGMAC_TXQEN; | ||
186 | if (qmode != MTL_QUEUE_AVB) | ||
187 | value |= 0x2 << XGMAC_TXQEN_SHIFT; | ||
188 | else | ||
189 | value |= 0x1 << XGMAC_TXQEN_SHIFT; | ||
190 | |||
191 | value &= ~XGMAC_TQS; | ||
192 | value |= (tqs << XGMAC_TQS_SHIFT) & XGMAC_TQS; | ||
193 | |||
194 | writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(channel)); | ||
195 | } | ||
196 | |||
197 | static void dwxgmac2_enable_dma_irq(void __iomem *ioaddr, u32 chan) | ||
198 | { | ||
199 | writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | ||
200 | } | ||
201 | |||
202 | static void dwxgmac2_disable_dma_irq(void __iomem *ioaddr, u32 chan) | ||
203 | { | ||
204 | writel(0, ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | ||
205 | } | ||
206 | |||
207 | static void dwxgmac2_dma_start_tx(void __iomem *ioaddr, u32 chan) | ||
208 | { | ||
209 | u32 value; | ||
210 | |||
211 | value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
212 | value |= XGMAC_TXST; | ||
213 | writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
214 | |||
215 | value = readl(ioaddr + XGMAC_TX_CONFIG); | ||
216 | value |= XGMAC_CONFIG_TE; | ||
217 | writel(value, ioaddr + XGMAC_TX_CONFIG); | ||
218 | } | ||
219 | |||
220 | static void dwxgmac2_dma_stop_tx(void __iomem *ioaddr, u32 chan) | ||
221 | { | ||
222 | u32 value; | ||
223 | |||
224 | value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
225 | value &= ~XGMAC_TXST; | ||
226 | writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
227 | |||
228 | value = readl(ioaddr + XGMAC_TX_CONFIG); | ||
229 | value &= ~XGMAC_CONFIG_TE; | ||
230 | writel(value, ioaddr + XGMAC_TX_CONFIG); | ||
231 | } | ||
232 | |||
233 | static void dwxgmac2_dma_start_rx(void __iomem *ioaddr, u32 chan) | ||
234 | { | ||
235 | u32 value; | ||
236 | |||
237 | value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
238 | value |= XGMAC_RXST; | ||
239 | writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
240 | |||
241 | value = readl(ioaddr + XGMAC_RX_CONFIG); | ||
242 | value |= XGMAC_CONFIG_RE; | ||
243 | writel(value, ioaddr + XGMAC_RX_CONFIG); | ||
244 | } | ||
245 | |||
246 | static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan) | ||
247 | { | ||
248 | u32 value; | ||
249 | |||
250 | value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
251 | value &= ~XGMAC_RXST; | ||
252 | writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
253 | |||
254 | value = readl(ioaddr + XGMAC_RX_CONFIG); | ||
255 | value &= ~XGMAC_CONFIG_RE; | ||
256 | writel(value, ioaddr + XGMAC_RX_CONFIG); | ||
257 | } | ||
258 | |||
259 | static int dwxgmac2_dma_interrupt(void __iomem *ioaddr, | ||
260 | struct stmmac_extra_stats *x, u32 chan) | ||
261 | { | ||
262 | u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan)); | ||
263 | int ret = 0; | ||
264 | |||
265 | /* ABNORMAL interrupts */ | ||
266 | if (unlikely(intr_status & XGMAC_AIS)) { | ||
267 | if (unlikely(intr_status & XGMAC_TPS)) { | ||
268 | x->tx_process_stopped_irq++; | ||
269 | ret |= tx_hard_error; | ||
270 | } | ||
271 | if (unlikely(intr_status & XGMAC_FBE)) { | ||
272 | x->fatal_bus_error_irq++; | ||
273 | ret |= tx_hard_error; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | /* TX/RX NORMAL interrupts */ | ||
278 | if (likely(intr_status & XGMAC_NIS)) { | ||
279 | x->normal_irq_n++; | ||
280 | |||
281 | if (likely(intr_status & XGMAC_RI)) { | ||
282 | u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan)); | ||
283 | if (likely(value & XGMAC_RIE)) { | ||
284 | x->rx_normal_irq_n++; | ||
285 | ret |= handle_rx; | ||
286 | } | ||
287 | } | ||
288 | if (likely(intr_status & XGMAC_TI)) { | ||
289 | x->tx_normal_irq_n++; | ||
290 | ret |= handle_tx; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | /* Clear interrupts */ | ||
295 | writel(~0x0, ioaddr + XGMAC_DMA_CH_STATUS(chan)); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | static void dwxgmac2_get_hw_feature(void __iomem *ioaddr, | ||
301 | struct dma_features *dma_cap) | ||
302 | { | ||
303 | u32 hw_cap; | ||
304 | |||
305 | /* MAC HW feature 0 */ | ||
306 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0); | ||
307 | dma_cap->rx_coe = (hw_cap & XGMAC_HWFEAT_RXCOESEL) >> 16; | ||
308 | dma_cap->tx_coe = (hw_cap & XGMAC_HWFEAT_TXCOESEL) >> 14; | ||
309 | dma_cap->atime_stamp = (hw_cap & XGMAC_HWFEAT_TSSEL) >> 12; | ||
310 | dma_cap->av = (hw_cap & XGMAC_HWFEAT_AVSEL) >> 11; | ||
311 | dma_cap->av &= (hw_cap & XGMAC_HWFEAT_RAVSEL) >> 10; | ||
312 | dma_cap->pmt_magic_frame = (hw_cap & XGMAC_HWFEAT_MGKSEL) >> 7; | ||
313 | dma_cap->pmt_remote_wake_up = (hw_cap & XGMAC_HWFEAT_RWKSEL) >> 6; | ||
314 | dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1; | ||
315 | |||
316 | /* MAC HW feature 1 */ | ||
317 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1); | ||
318 | dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18; | ||
319 | dma_cap->tx_fifo_size = | ||
320 | 128 << ((hw_cap & XGMAC_HWFEAT_TXFIFOSIZE) >> 6); | ||
321 | dma_cap->rx_fifo_size = | ||
322 | 128 << ((hw_cap & XGMAC_HWFEAT_RXFIFOSIZE) >> 0); | ||
323 | |||
324 | /* MAC HW feature 2 */ | ||
325 | hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2); | ||
326 | dma_cap->pps_out_num = (hw_cap & XGMAC_HWFEAT_PPSOUTNUM) >> 24; | ||
327 | dma_cap->number_tx_channel = | ||
328 | ((hw_cap & XGMAC_HWFEAT_TXCHCNT) >> 18) + 1; | ||
329 | dma_cap->number_rx_channel = | ||
330 | ((hw_cap & XGMAC_HWFEAT_RXCHCNT) >> 12) + 1; | ||
331 | dma_cap->number_tx_queues = | ||
332 | ((hw_cap & XGMAC_HWFEAT_TXQCNT) >> 6) + 1; | ||
333 | dma_cap->number_rx_queues = | ||
334 | ((hw_cap & XGMAC_HWFEAT_RXQCNT) >> 0) + 1; | ||
335 | } | ||
336 | |||
337 | static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 nchan) | ||
338 | { | ||
339 | u32 i; | ||
340 | |||
341 | for (i = 0; i < nchan; i++) | ||
342 | writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(i)); | ||
343 | } | ||
344 | |||
345 | static void dwxgmac2_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan) | ||
346 | { | ||
347 | writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan)); | ||
348 | } | ||
349 | |||
350 | static void dwxgmac2_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan) | ||
351 | { | ||
352 | writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan)); | ||
353 | } | ||
354 | |||
355 | static void dwxgmac2_set_rx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan) | ||
356 | { | ||
357 | writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan)); | ||
358 | } | ||
359 | |||
360 | static void dwxgmac2_set_tx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan) | ||
361 | { | ||
362 | writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan)); | ||
363 | } | ||
364 | |||
365 | static void dwxgmac2_enable_tso(void __iomem *ioaddr, bool en, u32 chan) | ||
366 | { | ||
367 | u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
368 | |||
369 | if (en) | ||
370 | value |= XGMAC_TSE; | ||
371 | else | ||
372 | value &= ~XGMAC_TSE; | ||
373 | |||
374 | writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)); | ||
375 | } | ||
376 | |||
377 | static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan) | ||
378 | { | ||
379 | u32 value; | ||
380 | |||
381 | value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
382 | value |= bfsize << 1; | ||
383 | writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); | ||
384 | } | ||
385 | |||
386 | const struct stmmac_dma_ops dwxgmac210_dma_ops = { | ||
387 | .reset = dwxgmac2_dma_reset, | ||
388 | .init = dwxgmac2_dma_init, | ||
389 | .init_chan = dwxgmac2_dma_init_chan, | ||
390 | .init_rx_chan = dwxgmac2_dma_init_rx_chan, | ||
391 | .init_tx_chan = dwxgmac2_dma_init_tx_chan, | ||
392 | .axi = dwxgmac2_dma_axi, | ||
393 | .dump_regs = NULL, | ||
394 | .dma_rx_mode = dwxgmac2_dma_rx_mode, | ||
395 | .dma_tx_mode = dwxgmac2_dma_tx_mode, | ||
396 | .enable_dma_irq = dwxgmac2_enable_dma_irq, | ||
397 | .disable_dma_irq = dwxgmac2_disable_dma_irq, | ||
398 | .start_tx = dwxgmac2_dma_start_tx, | ||
399 | .stop_tx = dwxgmac2_dma_stop_tx, | ||
400 | .start_rx = dwxgmac2_dma_start_rx, | ||
401 | .stop_rx = dwxgmac2_dma_stop_rx, | ||
402 | .dma_interrupt = dwxgmac2_dma_interrupt, | ||
403 | .get_hw_feature = dwxgmac2_get_hw_feature, | ||
404 | .rx_watchdog = dwxgmac2_rx_watchdog, | ||
405 | .set_rx_ring_len = dwxgmac2_set_rx_ring_len, | ||
406 | .set_tx_ring_len = dwxgmac2_set_tx_ring_len, | ||
407 | .set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr, | ||
408 | .set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr, | ||
409 | .enable_tso = dwxgmac2_enable_tso, | ||
410 | .set_bfsize = dwxgmac2_set_bfsize, | ||
411 | }; | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c index 4fa46f064720..4030199aee7b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.c +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c | |||
@@ -197,7 +197,7 @@ static const struct stmmac_hwif_entry { | |||
197 | .mmc_off = 0, | 197 | .mmc_off = 0, |
198 | }, | 198 | }, |
199 | .desc = NULL, | 199 | .desc = NULL, |
200 | .dma = NULL, | 200 | .dma = &dwxgmac210_dma_ops, |
201 | .mac = &dwxgmac210_ops, | 201 | .mac = &dwxgmac210_ops, |
202 | .hwtimestamp = NULL, | 202 | .hwtimestamp = NULL, |
203 | .mode = NULL, | 203 | .mode = NULL, |
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index ff0fd6978260..3106eaca60cd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h | |||
@@ -480,6 +480,7 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops; | |||
480 | extern const struct stmmac_ops dwmac510_ops; | 480 | extern const struct stmmac_ops dwmac510_ops; |
481 | extern const struct stmmac_tc_ops dwmac510_tc_ops; | 481 | extern const struct stmmac_tc_ops dwmac510_tc_ops; |
482 | extern const struct stmmac_ops dwxgmac210_ops; | 482 | extern const struct stmmac_ops dwxgmac210_ops; |
483 | extern const struct stmmac_dma_ops dwxgmac210_dma_ops; | ||
483 | 484 | ||
484 | #define GMAC_VERSION 0x00000020 /* GMAC CORE Version */ | 485 | #define GMAC_VERSION 0x00000020 /* GMAC CORE Version */ |
485 | #define GMAC4_VERSION 0x00000110 /* GMAC4+ CORE Version */ | 486 | #define GMAC4_VERSION 0x00000110 /* GMAC4+ CORE Version */ |