1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /******************************************************************************* |
3 | DWMAC Management Counters |
4 | |
5 | Copyright (C) 2011 STMicroelectronics Ltd |
6 | |
7 | |
8 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
9 | *******************************************************************************/ |
10 | |
11 | #include <linux/kernel.h> |
12 | #include <linux/io.h> |
13 | #include "hwif.h" |
14 | #include "mmc.h" |
15 | |
16 | /* MAC Management Counters register offset */ |
17 | |
18 | #define MMC_CNTRL 0x00 /* MMC Control */ |
19 | #define MMC_RX_INTR 0x04 /* MMC RX Interrupt */ |
20 | #define MMC_TX_INTR 0x08 /* MMC TX Interrupt */ |
21 | #define MMC_RX_INTR_MASK 0x0c /* MMC Interrupt Mask */ |
22 | #define MMC_TX_INTR_MASK 0x10 /* MMC Interrupt Mask */ |
23 | #define MMC_DEFAULT_MASK 0xffffffff |
24 | |
25 | /* MMC TX counter registers */ |
26 | |
27 | /* Note: |
28 | * _GB register stands for good and bad frames |
29 | * _G is for good only. |
30 | */ |
31 | #define MMC_TX_OCTETCOUNT_GB 0x14 |
32 | #define MMC_TX_FRAMECOUNT_GB 0x18 |
33 | #define MMC_TX_BROADCASTFRAME_G 0x1c |
34 | #define MMC_TX_MULTICASTFRAME_G 0x20 |
35 | #define MMC_TX_64_OCTETS_GB 0x24 |
36 | #define MMC_TX_65_TO_127_OCTETS_GB 0x28 |
37 | #define MMC_TX_128_TO_255_OCTETS_GB 0x2c |
38 | #define MMC_TX_256_TO_511_OCTETS_GB 0x30 |
39 | #define MMC_TX_512_TO_1023_OCTETS_GB 0x34 |
40 | #define MMC_TX_1024_TO_MAX_OCTETS_GB 0x38 |
41 | #define MMC_TX_UNICAST_GB 0x3c |
42 | #define MMC_TX_MULTICAST_GB 0x40 |
43 | #define MMC_TX_BROADCAST_GB 0x44 |
44 | #define MMC_TX_UNDERFLOW_ERROR 0x48 |
45 | #define MMC_TX_SINGLECOL_G 0x4c |
46 | #define MMC_TX_MULTICOL_G 0x50 |
47 | #define MMC_TX_DEFERRED 0x54 |
48 | #define MMC_TX_LATECOL 0x58 |
49 | #define MMC_TX_EXESSCOL 0x5c |
50 | #define MMC_TX_CARRIER_ERROR 0x60 |
51 | #define MMC_TX_OCTETCOUNT_G 0x64 |
52 | #define MMC_TX_FRAMECOUNT_G 0x68 |
53 | #define MMC_TX_EXCESSDEF 0x6c |
54 | #define MMC_TX_PAUSE_FRAME 0x70 |
55 | #define MMC_TX_VLAN_FRAME_G 0x74 |
56 | #define MMC_TX_OVERSIZE_G 0x78 |
57 | |
58 | /* MMC RX counter registers */ |
59 | #define MMC_RX_FRAMECOUNT_GB 0x80 |
60 | #define MMC_RX_OCTETCOUNT_GB 0x84 |
61 | #define MMC_RX_OCTETCOUNT_G 0x88 |
62 | #define MMC_RX_BROADCASTFRAME_G 0x8c |
63 | #define MMC_RX_MULTICASTFRAME_G 0x90 |
64 | #define MMC_RX_CRC_ERROR 0x94 |
65 | #define MMC_RX_ALIGN_ERROR 0x98 |
66 | #define MMC_RX_RUN_ERROR 0x9C |
67 | #define MMC_RX_JABBER_ERROR 0xA0 |
68 | #define MMC_RX_UNDERSIZE_G 0xA4 |
69 | #define MMC_RX_OVERSIZE_G 0xA8 |
70 | #define MMC_RX_64_OCTETS_GB 0xAC |
71 | #define MMC_RX_65_TO_127_OCTETS_GB 0xb0 |
72 | #define MMC_RX_128_TO_255_OCTETS_GB 0xb4 |
73 | #define MMC_RX_256_TO_511_OCTETS_GB 0xb8 |
74 | #define MMC_RX_512_TO_1023_OCTETS_GB 0xbc |
75 | #define MMC_RX_1024_TO_MAX_OCTETS_GB 0xc0 |
76 | #define MMC_RX_UNICAST_G 0xc4 |
77 | #define MMC_RX_LENGTH_ERROR 0xc8 |
78 | #define MMC_RX_AUTOFRANGETYPE 0xcc |
79 | #define MMC_RX_PAUSE_FRAMES 0xd0 |
80 | #define MMC_RX_FIFO_OVERFLOW 0xd4 |
81 | #define MMC_RX_VLAN_FRAMES_GB 0xd8 |
82 | #define MMC_RX_WATCHDOG_ERROR 0xdc |
83 | #define MMC_RX_ERROR 0xe0 |
84 | |
85 | #define MMC_TX_LPI_USEC 0xec |
86 | #define MMC_TX_LPI_TRAN 0xf0 |
87 | #define MMC_RX_LPI_USEC 0xf4 |
88 | #define MMC_RX_LPI_TRAN 0xf8 |
89 | |
90 | /* IPC*/ |
91 | #define MMC_RX_IPC_INTR_MASK 0x100 |
92 | #define MMC_RX_IPC_INTR 0x108 |
93 | /* IPv4*/ |
94 | #define MMC_RX_IPV4_GD 0x110 |
95 | #define MMC_RX_IPV4_HDERR 0x114 |
96 | #define MMC_RX_IPV4_NOPAY 0x118 |
97 | #define MMC_RX_IPV4_FRAG 0x11C |
98 | #define MMC_RX_IPV4_UDSBL 0x120 |
99 | |
100 | #define MMC_RX_IPV4_GD_OCTETS 0x150 |
101 | #define MMC_RX_IPV4_HDERR_OCTETS 0x154 |
102 | #define MMC_RX_IPV4_NOPAY_OCTETS 0x158 |
103 | #define MMC_RX_IPV4_FRAG_OCTETS 0x15c |
104 | #define MMC_RX_IPV4_UDSBL_OCTETS 0x160 |
105 | |
106 | /* IPV6*/ |
107 | #define MMC_RX_IPV6_GD_OCTETS 0x164 |
108 | #define MMC_RX_IPV6_HDERR_OCTETS 0x168 |
109 | #define MMC_RX_IPV6_NOPAY_OCTETS 0x16c |
110 | |
111 | #define MMC_RX_IPV6_GD 0x124 |
112 | #define MMC_RX_IPV6_HDERR 0x128 |
113 | #define MMC_RX_IPV6_NOPAY 0x12c |
114 | |
115 | /* Protocols*/ |
116 | #define MMC_RX_UDP_GD 0x130 |
117 | #define MMC_RX_UDP_ERR 0x134 |
118 | #define MMC_RX_TCP_GD 0x138 |
119 | #define MMC_RX_TCP_ERR 0x13c |
120 | #define MMC_RX_ICMP_GD 0x140 |
121 | #define MMC_RX_ICMP_ERR 0x144 |
122 | |
123 | #define MMC_RX_UDP_GD_OCTETS 0x170 |
124 | #define MMC_RX_UDP_ERR_OCTETS 0x174 |
125 | #define MMC_RX_TCP_GD_OCTETS 0x178 |
126 | #define MMC_RX_TCP_ERR_OCTETS 0x17c |
127 | #define MMC_RX_ICMP_GD_OCTETS 0x180 |
128 | #define MMC_RX_ICMP_ERR_OCTETS 0x184 |
129 | |
130 | #define MMC_TX_FPE_FRAG 0x1a8 |
131 | #define MMC_TX_HOLD_REQ 0x1ac |
132 | #define MMC_RX_PKT_ASSEMBLY_ERR 0x1c8 |
133 | #define MMC_RX_PKT_SMD_ERR 0x1cc |
134 | #define MMC_RX_PKT_ASSEMBLY_OK 0x1d0 |
135 | #define MMC_RX_FPE_FRAG 0x1d4 |
136 | |
137 | /* XGMAC MMC Registers */ |
138 | #define MMC_XGMAC_TX_OCTET_GB 0x14 |
139 | #define MMC_XGMAC_TX_PKT_GB 0x1c |
140 | #define MMC_XGMAC_TX_BROAD_PKT_G 0x24 |
141 | #define MMC_XGMAC_TX_MULTI_PKT_G 0x2c |
142 | #define MMC_XGMAC_TX_64OCT_GB 0x34 |
143 | #define MMC_XGMAC_TX_65OCT_GB 0x3c |
144 | #define MMC_XGMAC_TX_128OCT_GB 0x44 |
145 | #define MMC_XGMAC_TX_256OCT_GB 0x4c |
146 | #define MMC_XGMAC_TX_512OCT_GB 0x54 |
147 | #define MMC_XGMAC_TX_1024OCT_GB 0x5c |
148 | #define MMC_XGMAC_TX_UNI_PKT_GB 0x64 |
149 | #define MMC_XGMAC_TX_MULTI_PKT_GB 0x6c |
150 | #define MMC_XGMAC_TX_BROAD_PKT_GB 0x74 |
151 | #define MMC_XGMAC_TX_UNDER 0x7c |
152 | #define MMC_XGMAC_TX_OCTET_G 0x84 |
153 | #define MMC_XGMAC_TX_PKT_G 0x8c |
154 | #define MMC_XGMAC_TX_PAUSE 0x94 |
155 | #define MMC_XGMAC_TX_VLAN_PKT_G 0x9c |
156 | #define MMC_XGMAC_TX_LPI_USEC 0xa4 |
157 | #define MMC_XGMAC_TX_LPI_TRAN 0xa8 |
158 | |
159 | #define MMC_XGMAC_RX_PKT_GB 0x100 |
160 | #define MMC_XGMAC_RX_OCTET_GB 0x108 |
161 | #define MMC_XGMAC_RX_OCTET_G 0x110 |
162 | #define MMC_XGMAC_RX_BROAD_PKT_G 0x118 |
163 | #define MMC_XGMAC_RX_MULTI_PKT_G 0x120 |
164 | #define MMC_XGMAC_RX_CRC_ERR 0x128 |
165 | #define MMC_XGMAC_RX_RUNT_ERR 0x130 |
166 | #define MMC_XGMAC_RX_JABBER_ERR 0x134 |
167 | #define MMC_XGMAC_RX_UNDER 0x138 |
168 | #define MMC_XGMAC_RX_OVER 0x13c |
169 | #define MMC_XGMAC_RX_64OCT_GB 0x140 |
170 | #define MMC_XGMAC_RX_65OCT_GB 0x148 |
171 | #define MMC_XGMAC_RX_128OCT_GB 0x150 |
172 | #define MMC_XGMAC_RX_256OCT_GB 0x158 |
173 | #define MMC_XGMAC_RX_512OCT_GB 0x160 |
174 | #define MMC_XGMAC_RX_1024OCT_GB 0x168 |
175 | #define MMC_XGMAC_RX_UNI_PKT_G 0x170 |
176 | #define MMC_XGMAC_RX_LENGTH_ERR 0x178 |
177 | #define MMC_XGMAC_RX_RANGE 0x180 |
178 | #define MMC_XGMAC_RX_PAUSE 0x188 |
179 | #define MMC_XGMAC_RX_FIFOOVER_PKT 0x190 |
180 | #define MMC_XGMAC_RX_VLAN_PKT_GB 0x198 |
181 | #define MMC_XGMAC_RX_WATCHDOG_ERR 0x1a0 |
182 | #define MMC_XGMAC_RX_LPI_USEC 0x1a4 |
183 | #define MMC_XGMAC_RX_LPI_TRAN 0x1a8 |
184 | #define MMC_XGMAC_RX_DISCARD_PKT_GB 0x1ac |
185 | #define MMC_XGMAC_RX_DISCARD_OCT_GB 0x1b4 |
186 | #define MMC_XGMAC_RX_ALIGN_ERR_PKT 0x1bc |
187 | |
188 | #define MMC_XGMAC_SGF_PASS_PKT 0x1f0 |
189 | #define MMC_XGMAC_SGF_FAIL_PKT 0x1f4 |
190 | #define MMC_XGMAC_TX_FPE_INTR_MASK 0x204 |
191 | #define MMC_XGMAC_TX_FPE_FRAG 0x208 |
192 | #define MMC_XGMAC_TX_HOLD_REQ 0x20c |
193 | #define MMC_XGMAC_TX_GATE_OVERRUN 0x210 |
194 | #define MMC_XGMAC_RX_FPE_INTR_MASK 0x224 |
195 | #define MMC_XGMAC_RX_PKT_ASSEMBLY_ERR 0x228 |
196 | #define MMC_XGMAC_RX_PKT_SMD_ERR 0x22c |
197 | #define MMC_XGMAC_RX_PKT_ASSEMBLY_OK 0x230 |
198 | #define MMC_XGMAC_RX_FPE_FRAG 0x234 |
199 | #define MMC_XGMAC_RX_IPC_INTR_MASK 0x25c |
200 | |
201 | #define MMC_XGMAC_RX_IPV4_GD 0x264 |
202 | #define MMC_XGMAC_RX_IPV4_HDERR 0x26c |
203 | #define MMC_XGMAC_RX_IPV4_NOPAY 0x274 |
204 | #define MMC_XGMAC_RX_IPV4_FRAG 0x27c |
205 | #define MMC_XGMAC_RX_IPV4_UDSBL 0x284 |
206 | |
207 | #define MMC_XGMAC_RX_IPV6_GD 0x28c |
208 | #define MMC_XGMAC_RX_IPV6_HDERR 0x294 |
209 | #define MMC_XGMAC_RX_IPV6_NOPAY 0x29c |
210 | |
211 | #define MMC_XGMAC_RX_UDP_GD 0x2a4 |
212 | #define MMC_XGMAC_RX_UDP_ERR 0x2ac |
213 | #define MMC_XGMAC_RX_TCP_GD 0x2b4 |
214 | #define MMC_XGMAC_RX_TCP_ERR 0x2bc |
215 | #define MMC_XGMAC_RX_ICMP_GD 0x2c4 |
216 | #define MMC_XGMAC_RX_ICMP_ERR 0x2cc |
217 | |
218 | #define MMC_XGMAC_RX_IPV4_GD_OCTETS 0x2d4 |
219 | #define MMC_XGMAC_RX_IPV4_HDERR_OCTETS 0x2dc |
220 | #define MMC_XGMAC_RX_IPV4_NOPAY_OCTETS 0x2e4 |
221 | #define MMC_XGMAC_RX_IPV4_FRAG_OCTETS 0x2ec |
222 | #define MMC_XGMAC_RX_IPV4_UDSBL_OCTETS 0x2f4 |
223 | |
224 | #define MMC_XGMAC_RX_IPV6_GD_OCTETS 0x2fc |
225 | #define MMC_XGMAC_RX_IPV6_HDERR_OCTETS 0x304 |
226 | #define MMC_XGMAC_RX_IPV6_NOPAY_OCTETS 0x30c |
227 | |
228 | #define MMC_XGMAC_RX_UDP_GD_OCTETS 0x314 |
229 | #define MMC_XGMAC_RX_UDP_ERR_OCTETS 0x31c |
230 | #define MMC_XGMAC_RX_TCP_GD_OCTETS 0x324 |
231 | #define MMC_XGMAC_RX_TCP_ERR_OCTETS 0x32c |
232 | #define MMC_XGMAC_RX_ICMP_GD_OCTETS 0x334 |
233 | #define MMC_XGMAC_RX_ICMP_ERR_OCTETS 0x33c |
234 | |
235 | static void dwmac_mmc_ctrl(void __iomem *mmcaddr, unsigned int mode) |
236 | { |
237 | u32 value = readl(addr: mmcaddr + MMC_CNTRL); |
238 | |
239 | value |= (mode & 0x3F); |
240 | |
241 | writel(val: value, addr: mmcaddr + MMC_CNTRL); |
242 | |
243 | pr_debug("stmmac: MMC ctrl register (offset 0x%x): 0x%08x\n" , |
244 | MMC_CNTRL, value); |
245 | } |
246 | |
247 | /* To mask all interrupts.*/ |
248 | static void dwmac_mmc_intr_all_mask(void __iomem *mmcaddr) |
249 | { |
250 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_RX_INTR_MASK); |
251 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_TX_INTR_MASK); |
252 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_RX_IPC_INTR_MASK); |
253 | } |
254 | |
255 | /* This reads the MAC core counters (if actaully supported). |
256 | * by default the MMC core is programmed to reset each |
257 | * counter after a read. So all the field of the mmc struct |
258 | * have to be incremented. |
259 | */ |
260 | static void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc) |
261 | { |
262 | mmc->mmc_tx_octetcount_gb += readl(addr: mmcaddr + MMC_TX_OCTETCOUNT_GB); |
263 | mmc->mmc_tx_framecount_gb += readl(addr: mmcaddr + MMC_TX_FRAMECOUNT_GB); |
264 | mmc->mmc_tx_broadcastframe_g += readl(addr: mmcaddr + |
265 | MMC_TX_BROADCASTFRAME_G); |
266 | mmc->mmc_tx_multicastframe_g += readl(addr: mmcaddr + |
267 | MMC_TX_MULTICASTFRAME_G); |
268 | mmc->mmc_tx_64_octets_gb += readl(addr: mmcaddr + MMC_TX_64_OCTETS_GB); |
269 | mmc->mmc_tx_65_to_127_octets_gb += |
270 | readl(addr: mmcaddr + MMC_TX_65_TO_127_OCTETS_GB); |
271 | mmc->mmc_tx_128_to_255_octets_gb += |
272 | readl(addr: mmcaddr + MMC_TX_128_TO_255_OCTETS_GB); |
273 | mmc->mmc_tx_256_to_511_octets_gb += |
274 | readl(addr: mmcaddr + MMC_TX_256_TO_511_OCTETS_GB); |
275 | mmc->mmc_tx_512_to_1023_octets_gb += |
276 | readl(addr: mmcaddr + MMC_TX_512_TO_1023_OCTETS_GB); |
277 | mmc->mmc_tx_1024_to_max_octets_gb += |
278 | readl(addr: mmcaddr + MMC_TX_1024_TO_MAX_OCTETS_GB); |
279 | mmc->mmc_tx_unicast_gb += readl(addr: mmcaddr + MMC_TX_UNICAST_GB); |
280 | mmc->mmc_tx_multicast_gb += readl(addr: mmcaddr + MMC_TX_MULTICAST_GB); |
281 | mmc->mmc_tx_broadcast_gb += readl(addr: mmcaddr + MMC_TX_BROADCAST_GB); |
282 | mmc->mmc_tx_underflow_error += readl(addr: mmcaddr + MMC_TX_UNDERFLOW_ERROR); |
283 | mmc->mmc_tx_singlecol_g += readl(addr: mmcaddr + MMC_TX_SINGLECOL_G); |
284 | mmc->mmc_tx_multicol_g += readl(addr: mmcaddr + MMC_TX_MULTICOL_G); |
285 | mmc->mmc_tx_deferred += readl(addr: mmcaddr + MMC_TX_DEFERRED); |
286 | mmc->mmc_tx_latecol += readl(addr: mmcaddr + MMC_TX_LATECOL); |
287 | mmc->mmc_tx_exesscol += readl(addr: mmcaddr + MMC_TX_EXESSCOL); |
288 | mmc->mmc_tx_carrier_error += readl(addr: mmcaddr + MMC_TX_CARRIER_ERROR); |
289 | mmc->mmc_tx_octetcount_g += readl(addr: mmcaddr + MMC_TX_OCTETCOUNT_G); |
290 | mmc->mmc_tx_framecount_g += readl(addr: mmcaddr + MMC_TX_FRAMECOUNT_G); |
291 | mmc->mmc_tx_excessdef += readl(addr: mmcaddr + MMC_TX_EXCESSDEF); |
292 | mmc->mmc_tx_pause_frame += readl(addr: mmcaddr + MMC_TX_PAUSE_FRAME); |
293 | mmc->mmc_tx_vlan_frame_g += readl(addr: mmcaddr + MMC_TX_VLAN_FRAME_G); |
294 | mmc->mmc_tx_oversize_g += readl(addr: mmcaddr + MMC_TX_OVERSIZE_G); |
295 | mmc->mmc_tx_lpi_usec += readl(addr: mmcaddr + MMC_TX_LPI_USEC); |
296 | mmc->mmc_tx_lpi_tran += readl(addr: mmcaddr + MMC_TX_LPI_TRAN); |
297 | |
298 | /* MMC RX counter registers */ |
299 | mmc->mmc_rx_framecount_gb += readl(addr: mmcaddr + MMC_RX_FRAMECOUNT_GB); |
300 | mmc->mmc_rx_octetcount_gb += readl(addr: mmcaddr + MMC_RX_OCTETCOUNT_GB); |
301 | mmc->mmc_rx_octetcount_g += readl(addr: mmcaddr + MMC_RX_OCTETCOUNT_G); |
302 | mmc->mmc_rx_broadcastframe_g += readl(addr: mmcaddr + |
303 | MMC_RX_BROADCASTFRAME_G); |
304 | mmc->mmc_rx_multicastframe_g += readl(addr: mmcaddr + |
305 | MMC_RX_MULTICASTFRAME_G); |
306 | mmc->mmc_rx_crc_error += readl(addr: mmcaddr + MMC_RX_CRC_ERROR); |
307 | mmc->mmc_rx_align_error += readl(addr: mmcaddr + MMC_RX_ALIGN_ERROR); |
308 | mmc->mmc_rx_run_error += readl(addr: mmcaddr + MMC_RX_RUN_ERROR); |
309 | mmc->mmc_rx_jabber_error += readl(addr: mmcaddr + MMC_RX_JABBER_ERROR); |
310 | mmc->mmc_rx_undersize_g += readl(addr: mmcaddr + MMC_RX_UNDERSIZE_G); |
311 | mmc->mmc_rx_oversize_g += readl(addr: mmcaddr + MMC_RX_OVERSIZE_G); |
312 | mmc->mmc_rx_64_octets_gb += readl(addr: mmcaddr + MMC_RX_64_OCTETS_GB); |
313 | mmc->mmc_rx_65_to_127_octets_gb += |
314 | readl(addr: mmcaddr + MMC_RX_65_TO_127_OCTETS_GB); |
315 | mmc->mmc_rx_128_to_255_octets_gb += |
316 | readl(addr: mmcaddr + MMC_RX_128_TO_255_OCTETS_GB); |
317 | mmc->mmc_rx_256_to_511_octets_gb += |
318 | readl(addr: mmcaddr + MMC_RX_256_TO_511_OCTETS_GB); |
319 | mmc->mmc_rx_512_to_1023_octets_gb += |
320 | readl(addr: mmcaddr + MMC_RX_512_TO_1023_OCTETS_GB); |
321 | mmc->mmc_rx_1024_to_max_octets_gb += |
322 | readl(addr: mmcaddr + MMC_RX_1024_TO_MAX_OCTETS_GB); |
323 | mmc->mmc_rx_unicast_g += readl(addr: mmcaddr + MMC_RX_UNICAST_G); |
324 | mmc->mmc_rx_length_error += readl(addr: mmcaddr + MMC_RX_LENGTH_ERROR); |
325 | mmc->mmc_rx_autofrangetype += readl(addr: mmcaddr + MMC_RX_AUTOFRANGETYPE); |
326 | mmc->mmc_rx_pause_frames += readl(addr: mmcaddr + MMC_RX_PAUSE_FRAMES); |
327 | mmc->mmc_rx_fifo_overflow += readl(addr: mmcaddr + MMC_RX_FIFO_OVERFLOW); |
328 | mmc->mmc_rx_vlan_frames_gb += readl(addr: mmcaddr + MMC_RX_VLAN_FRAMES_GB); |
329 | mmc->mmc_rx_watchdog_error += readl(addr: mmcaddr + MMC_RX_WATCHDOG_ERROR); |
330 | mmc->mmc_rx_error += readl(addr: mmcaddr + MMC_RX_ERROR); |
331 | mmc->mmc_rx_lpi_usec += readl(addr: mmcaddr + MMC_RX_LPI_USEC); |
332 | mmc->mmc_rx_lpi_tran += readl(addr: mmcaddr + MMC_RX_LPI_TRAN); |
333 | |
334 | /* IPv4 */ |
335 | mmc->mmc_rx_ipv4_gd += readl(addr: mmcaddr + MMC_RX_IPV4_GD); |
336 | mmc->mmc_rx_ipv4_hderr += readl(addr: mmcaddr + MMC_RX_IPV4_HDERR); |
337 | mmc->mmc_rx_ipv4_nopay += readl(addr: mmcaddr + MMC_RX_IPV4_NOPAY); |
338 | mmc->mmc_rx_ipv4_frag += readl(addr: mmcaddr + MMC_RX_IPV4_FRAG); |
339 | mmc->mmc_rx_ipv4_udsbl += readl(addr: mmcaddr + MMC_RX_IPV4_UDSBL); |
340 | |
341 | mmc->mmc_rx_ipv4_gd_octets += readl(addr: mmcaddr + MMC_RX_IPV4_GD_OCTETS); |
342 | mmc->mmc_rx_ipv4_hderr_octets += |
343 | readl(addr: mmcaddr + MMC_RX_IPV4_HDERR_OCTETS); |
344 | mmc->mmc_rx_ipv4_nopay_octets += |
345 | readl(addr: mmcaddr + MMC_RX_IPV4_NOPAY_OCTETS); |
346 | mmc->mmc_rx_ipv4_frag_octets += readl(addr: mmcaddr + |
347 | MMC_RX_IPV4_FRAG_OCTETS); |
348 | mmc->mmc_rx_ipv4_udsbl_octets += |
349 | readl(addr: mmcaddr + MMC_RX_IPV4_UDSBL_OCTETS); |
350 | |
351 | /* IPV6 */ |
352 | mmc->mmc_rx_ipv6_gd_octets += readl(addr: mmcaddr + MMC_RX_IPV6_GD_OCTETS); |
353 | mmc->mmc_rx_ipv6_hderr_octets += |
354 | readl(addr: mmcaddr + MMC_RX_IPV6_HDERR_OCTETS); |
355 | mmc->mmc_rx_ipv6_nopay_octets += |
356 | readl(addr: mmcaddr + MMC_RX_IPV6_NOPAY_OCTETS); |
357 | |
358 | mmc->mmc_rx_ipv6_gd += readl(addr: mmcaddr + MMC_RX_IPV6_GD); |
359 | mmc->mmc_rx_ipv6_hderr += readl(addr: mmcaddr + MMC_RX_IPV6_HDERR); |
360 | mmc->mmc_rx_ipv6_nopay += readl(addr: mmcaddr + MMC_RX_IPV6_NOPAY); |
361 | |
362 | /* Protocols */ |
363 | mmc->mmc_rx_udp_gd += readl(addr: mmcaddr + MMC_RX_UDP_GD); |
364 | mmc->mmc_rx_udp_err += readl(addr: mmcaddr + MMC_RX_UDP_ERR); |
365 | mmc->mmc_rx_tcp_gd += readl(addr: mmcaddr + MMC_RX_TCP_GD); |
366 | mmc->mmc_rx_tcp_err += readl(addr: mmcaddr + MMC_RX_TCP_ERR); |
367 | mmc->mmc_rx_icmp_gd += readl(addr: mmcaddr + MMC_RX_ICMP_GD); |
368 | mmc->mmc_rx_icmp_err += readl(addr: mmcaddr + MMC_RX_ICMP_ERR); |
369 | |
370 | mmc->mmc_rx_udp_gd_octets += readl(addr: mmcaddr + MMC_RX_UDP_GD_OCTETS); |
371 | mmc->mmc_rx_udp_err_octets += readl(addr: mmcaddr + MMC_RX_UDP_ERR_OCTETS); |
372 | mmc->mmc_rx_tcp_gd_octets += readl(addr: mmcaddr + MMC_RX_TCP_GD_OCTETS); |
373 | mmc->mmc_rx_tcp_err_octets += readl(addr: mmcaddr + MMC_RX_TCP_ERR_OCTETS); |
374 | mmc->mmc_rx_icmp_gd_octets += readl(addr: mmcaddr + MMC_RX_ICMP_GD_OCTETS); |
375 | mmc->mmc_rx_icmp_err_octets += readl(addr: mmcaddr + MMC_RX_ICMP_ERR_OCTETS); |
376 | |
377 | mmc->mmc_tx_fpe_fragment_cntr += readl(addr: mmcaddr + MMC_TX_FPE_FRAG); |
378 | mmc->mmc_tx_hold_req_cntr += readl(addr: mmcaddr + MMC_TX_HOLD_REQ); |
379 | mmc->mmc_rx_packet_assembly_err_cntr += |
380 | readl(addr: mmcaddr + MMC_RX_PKT_ASSEMBLY_ERR); |
381 | mmc->mmc_rx_packet_smd_err_cntr += readl(addr: mmcaddr + MMC_RX_PKT_SMD_ERR); |
382 | mmc->mmc_rx_packet_assembly_ok_cntr += |
383 | readl(addr: mmcaddr + MMC_RX_PKT_ASSEMBLY_OK); |
384 | mmc->mmc_rx_fpe_fragment_cntr += readl(addr: mmcaddr + MMC_RX_FPE_FRAG); |
385 | } |
386 | |
387 | const struct stmmac_mmc_ops dwmac_mmc_ops = { |
388 | .ctrl = dwmac_mmc_ctrl, |
389 | .intr_all_mask = dwmac_mmc_intr_all_mask, |
390 | .read = dwmac_mmc_read, |
391 | }; |
392 | |
393 | static void dwxgmac_mmc_ctrl(void __iomem *mmcaddr, unsigned int mode) |
394 | { |
395 | u32 value = readl(addr: mmcaddr + MMC_CNTRL); |
396 | |
397 | value |= (mode & 0x3F); |
398 | |
399 | writel(val: value, addr: mmcaddr + MMC_CNTRL); |
400 | } |
401 | |
402 | static void dwxgmac_mmc_intr_all_mask(void __iomem *mmcaddr) |
403 | { |
404 | writel(val: 0x0, addr: mmcaddr + MMC_RX_INTR_MASK); |
405 | writel(val: 0x0, addr: mmcaddr + MMC_TX_INTR_MASK); |
406 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_XGMAC_TX_FPE_INTR_MASK); |
407 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_XGMAC_RX_FPE_INTR_MASK); |
408 | writel(MMC_DEFAULT_MASK, addr: mmcaddr + MMC_XGMAC_RX_IPC_INTR_MASK); |
409 | } |
410 | |
411 | static void dwxgmac_read_mmc_reg(void __iomem *addr, u32 reg, u32 *dest) |
412 | { |
413 | u64 tmp = 0; |
414 | |
415 | tmp += readl(addr: addr + reg); |
416 | tmp += ((u64 )readl(addr: addr + reg + 0x4)) << 32; |
417 | if (tmp > GENMASK(31, 0)) |
418 | *dest = ~0x0; |
419 | else |
420 | *dest = *dest + tmp; |
421 | } |
422 | |
423 | /* This reads the MAC core counters (if actaully supported). |
424 | * by default the MMC core is programmed to reset each |
425 | * counter after a read. So all the field of the mmc struct |
426 | * have to be incremented. |
427 | */ |
428 | static void dwxgmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc) |
429 | { |
430 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_OCTET_GB, |
431 | dest: &mmc->mmc_tx_octetcount_gb); |
432 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_PKT_GB, |
433 | dest: &mmc->mmc_tx_framecount_gb); |
434 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_BROAD_PKT_G, |
435 | dest: &mmc->mmc_tx_broadcastframe_g); |
436 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_MULTI_PKT_G, |
437 | dest: &mmc->mmc_tx_multicastframe_g); |
438 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_64OCT_GB, |
439 | dest: &mmc->mmc_tx_64_octets_gb); |
440 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_65OCT_GB, |
441 | dest: &mmc->mmc_tx_65_to_127_octets_gb); |
442 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_128OCT_GB, |
443 | dest: &mmc->mmc_tx_128_to_255_octets_gb); |
444 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_256OCT_GB, |
445 | dest: &mmc->mmc_tx_256_to_511_octets_gb); |
446 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_512OCT_GB, |
447 | dest: &mmc->mmc_tx_512_to_1023_octets_gb); |
448 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_1024OCT_GB, |
449 | dest: &mmc->mmc_tx_1024_to_max_octets_gb); |
450 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_UNI_PKT_GB, |
451 | dest: &mmc->mmc_tx_unicast_gb); |
452 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_MULTI_PKT_GB, |
453 | dest: &mmc->mmc_tx_multicast_gb); |
454 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_BROAD_PKT_GB, |
455 | dest: &mmc->mmc_tx_broadcast_gb); |
456 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_UNDER, |
457 | dest: &mmc->mmc_tx_underflow_error); |
458 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_OCTET_G, |
459 | dest: &mmc->mmc_tx_octetcount_g); |
460 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_PKT_G, |
461 | dest: &mmc->mmc_tx_framecount_g); |
462 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_PAUSE, |
463 | dest: &mmc->mmc_tx_pause_frame); |
464 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_VLAN_PKT_G, |
465 | dest: &mmc->mmc_tx_vlan_frame_g); |
466 | mmc->mmc_tx_lpi_usec += readl(addr: mmcaddr + MMC_XGMAC_TX_LPI_USEC); |
467 | mmc->mmc_tx_lpi_tran += readl(addr: mmcaddr + MMC_XGMAC_TX_LPI_TRAN); |
468 | |
469 | /* MMC RX counter registers */ |
470 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_PKT_GB, |
471 | dest: &mmc->mmc_rx_framecount_gb); |
472 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_OCTET_GB, |
473 | dest: &mmc->mmc_rx_octetcount_gb); |
474 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_OCTET_G, |
475 | dest: &mmc->mmc_rx_octetcount_g); |
476 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_BROAD_PKT_G, |
477 | dest: &mmc->mmc_rx_broadcastframe_g); |
478 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_MULTI_PKT_G, |
479 | dest: &mmc->mmc_rx_multicastframe_g); |
480 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_CRC_ERR, |
481 | dest: &mmc->mmc_rx_crc_error); |
482 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_CRC_ERR, |
483 | dest: &mmc->mmc_rx_crc_error); |
484 | mmc->mmc_rx_run_error += readl(addr: mmcaddr + MMC_XGMAC_RX_RUNT_ERR); |
485 | mmc->mmc_rx_jabber_error += readl(addr: mmcaddr + MMC_XGMAC_RX_JABBER_ERR); |
486 | mmc->mmc_rx_undersize_g += readl(addr: mmcaddr + MMC_XGMAC_RX_UNDER); |
487 | mmc->mmc_rx_oversize_g += readl(addr: mmcaddr + MMC_XGMAC_RX_OVER); |
488 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_64OCT_GB, |
489 | dest: &mmc->mmc_rx_64_octets_gb); |
490 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_65OCT_GB, |
491 | dest: &mmc->mmc_rx_65_to_127_octets_gb); |
492 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_128OCT_GB, |
493 | dest: &mmc->mmc_rx_128_to_255_octets_gb); |
494 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_256OCT_GB, |
495 | dest: &mmc->mmc_rx_256_to_511_octets_gb); |
496 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_512OCT_GB, |
497 | dest: &mmc->mmc_rx_512_to_1023_octets_gb); |
498 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_1024OCT_GB, |
499 | dest: &mmc->mmc_rx_1024_to_max_octets_gb); |
500 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_UNI_PKT_G, |
501 | dest: &mmc->mmc_rx_unicast_g); |
502 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_LENGTH_ERR, |
503 | dest: &mmc->mmc_rx_length_error); |
504 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_RANGE, |
505 | dest: &mmc->mmc_rx_autofrangetype); |
506 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_PAUSE, |
507 | dest: &mmc->mmc_rx_pause_frames); |
508 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_FIFOOVER_PKT, |
509 | dest: &mmc->mmc_rx_fifo_overflow); |
510 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_VLAN_PKT_GB, |
511 | dest: &mmc->mmc_rx_vlan_frames_gb); |
512 | mmc->mmc_rx_watchdog_error += readl(addr: mmcaddr + MMC_XGMAC_RX_WATCHDOG_ERR); |
513 | mmc->mmc_rx_lpi_usec += readl(addr: mmcaddr + MMC_XGMAC_RX_LPI_USEC); |
514 | mmc->mmc_rx_lpi_tran += readl(addr: mmcaddr + MMC_XGMAC_RX_LPI_TRAN); |
515 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_DISCARD_PKT_GB, |
516 | dest: &mmc->mmc_rx_discard_frames_gb); |
517 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_DISCARD_OCT_GB, |
518 | dest: &mmc->mmc_rx_discard_octets_gb); |
519 | mmc->mmc_rx_align_err_frames += |
520 | readl(addr: mmcaddr + MMC_XGMAC_RX_ALIGN_ERR_PKT); |
521 | |
522 | mmc->mmc_sgf_pass_fragment_cntr += |
523 | readl(addr: mmcaddr + MMC_XGMAC_SGF_PASS_PKT); |
524 | mmc->mmc_sgf_fail_fragment_cntr += |
525 | readl(addr: mmcaddr + MMC_XGMAC_SGF_FAIL_PKT); |
526 | mmc->mmc_tx_fpe_fragment_cntr += readl(addr: mmcaddr + MMC_XGMAC_TX_FPE_FRAG); |
527 | mmc->mmc_tx_hold_req_cntr += readl(addr: mmcaddr + MMC_XGMAC_TX_HOLD_REQ); |
528 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_TX_GATE_OVERRUN, |
529 | dest: &mmc->mmc_tx_gate_overrun_cntr); |
530 | mmc->mmc_rx_packet_assembly_err_cntr += |
531 | readl(addr: mmcaddr + MMC_XGMAC_RX_PKT_ASSEMBLY_ERR); |
532 | mmc->mmc_rx_packet_smd_err_cntr += |
533 | readl(addr: mmcaddr + MMC_XGMAC_RX_PKT_SMD_ERR); |
534 | mmc->mmc_rx_packet_assembly_ok_cntr += |
535 | readl(addr: mmcaddr + MMC_XGMAC_RX_PKT_ASSEMBLY_OK); |
536 | mmc->mmc_rx_fpe_fragment_cntr += |
537 | readl(addr: mmcaddr + MMC_XGMAC_RX_FPE_FRAG); |
538 | |
539 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_GD, |
540 | dest: &mmc->mmc_rx_ipv4_gd); |
541 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_HDERR, |
542 | dest: &mmc->mmc_rx_ipv4_hderr); |
543 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_NOPAY, |
544 | dest: &mmc->mmc_rx_ipv4_nopay); |
545 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_FRAG, |
546 | dest: &mmc->mmc_rx_ipv4_frag); |
547 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_UDSBL, |
548 | dest: &mmc->mmc_rx_ipv4_udsbl); |
549 | |
550 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_GD, |
551 | dest: &mmc->mmc_rx_ipv6_gd); |
552 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_HDERR, |
553 | dest: &mmc->mmc_rx_ipv6_hderr); |
554 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_NOPAY, |
555 | dest: &mmc->mmc_rx_ipv6_nopay); |
556 | |
557 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_UDP_GD, |
558 | dest: &mmc->mmc_rx_udp_gd); |
559 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_UDP_ERR, |
560 | dest: &mmc->mmc_rx_udp_err); |
561 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_TCP_GD, |
562 | dest: &mmc->mmc_rx_tcp_gd); |
563 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_TCP_ERR, |
564 | dest: &mmc->mmc_rx_tcp_err); |
565 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_ICMP_GD, |
566 | dest: &mmc->mmc_rx_icmp_gd); |
567 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_ICMP_ERR, |
568 | dest: &mmc->mmc_rx_icmp_err); |
569 | |
570 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_GD_OCTETS, |
571 | dest: &mmc->mmc_rx_ipv4_gd_octets); |
572 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_HDERR_OCTETS, |
573 | dest: &mmc->mmc_rx_ipv4_hderr_octets); |
574 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_NOPAY_OCTETS, |
575 | dest: &mmc->mmc_rx_ipv4_nopay_octets); |
576 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_FRAG_OCTETS, |
577 | dest: &mmc->mmc_rx_ipv4_frag_octets); |
578 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV4_UDSBL_OCTETS, |
579 | dest: &mmc->mmc_rx_ipv4_udsbl_octets); |
580 | |
581 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_GD_OCTETS, |
582 | dest: &mmc->mmc_rx_ipv6_gd_octets); |
583 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_HDERR_OCTETS, |
584 | dest: &mmc->mmc_rx_ipv6_hderr_octets); |
585 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_IPV6_NOPAY_OCTETS, |
586 | dest: &mmc->mmc_rx_ipv6_nopay_octets); |
587 | |
588 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_UDP_GD_OCTETS, |
589 | dest: &mmc->mmc_rx_udp_gd_octets); |
590 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_UDP_ERR_OCTETS, |
591 | dest: &mmc->mmc_rx_udp_err_octets); |
592 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_TCP_GD_OCTETS, |
593 | dest: &mmc->mmc_rx_tcp_gd_octets); |
594 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_TCP_ERR_OCTETS, |
595 | dest: &mmc->mmc_rx_tcp_err_octets); |
596 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_ICMP_GD_OCTETS, |
597 | dest: &mmc->mmc_rx_icmp_gd_octets); |
598 | dwxgmac_read_mmc_reg(addr: mmcaddr, MMC_XGMAC_RX_ICMP_ERR_OCTETS, |
599 | dest: &mmc->mmc_rx_icmp_err_octets); |
600 | } |
601 | |
602 | const struct stmmac_mmc_ops dwxgmac_mmc_ops = { |
603 | .ctrl = dwxgmac_mmc_ctrl, |
604 | .intr_all_mask = dwxgmac_mmc_intr_all_mask, |
605 | .read = dwxgmac_mmc_read, |
606 | }; |
607 | |