1 /*******************************************************************************
2 DWMAC Management Counters
3
4 Copyright (C) 2011 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 The full GNU General Public License is included in this distribution in
16 the file called "COPYING".
17
18 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
19 *******************************************************************************/
20
21 #include <linux/kernel.h>
22 #include <linux/io.h>
23 #include "mmc.h"
24
25 /* MAC Management Counters register offset */
26
27 #define MMC_CNTRL 0x00 /* MMC Control */
28 #define MMC_RX_INTR 0x04 /* MMC RX Interrupt */
29 #define MMC_TX_INTR 0x08 /* MMC TX Interrupt */
30 #define MMC_RX_INTR_MASK 0x0c /* MMC Interrupt Mask */
31 #define MMC_TX_INTR_MASK 0x10 /* MMC Interrupt Mask */
32 #define MMC_DEFAULT_MASK 0xffffffff
33
34 /* MMC TX counter registers */
35
36 /* Note:
37 * _GB register stands for good and bad frames
38 * _G is for good only.
39 */
40 #define MMC_TX_OCTETCOUNT_GB 0x14
41 #define MMC_TX_FRAMECOUNT_GB 0x18
42 #define MMC_TX_BROADCASTFRAME_G 0x1c
43 #define MMC_TX_MULTICASTFRAME_G 0x20
44 #define MMC_TX_64_OCTETS_GB 0x24
45 #define MMC_TX_65_TO_127_OCTETS_GB 0x28
46 #define MMC_TX_128_TO_255_OCTETS_GB 0x2c
47 #define MMC_TX_256_TO_511_OCTETS_GB 0x30
48 #define MMC_TX_512_TO_1023_OCTETS_GB 0x34
49 #define MMC_TX_1024_TO_MAX_OCTETS_GB 0x38
50 #define MMC_TX_UNICAST_GB 0x3c
51 #define MMC_TX_MULTICAST_GB 0x40
52 #define MMC_TX_BROADCAST_GB 0x44
53 #define MMC_TX_UNDERFLOW_ERROR 0x48
54 #define MMC_TX_SINGLECOL_G 0x4c
55 #define MMC_TX_MULTICOL_G 0x50
56 #define MMC_TX_DEFERRED 0x54
57 #define MMC_TX_LATECOL 0x58
58 #define MMC_TX_EXESSCOL 0x5c
59 #define MMC_TX_CARRIER_ERROR 0x60
60 #define MMC_TX_OCTETCOUNT_G 0x64
61 #define MMC_TX_FRAMECOUNT_G 0x68
62 #define MMC_TX_EXCESSDEF 0x6c
63 #define MMC_TX_PAUSE_FRAME 0x70
64 #define MMC_TX_VLAN_FRAME_G 0x74
65
66 /* MMC RX counter registers */
67 #define MMC_RX_FRAMECOUNT_GB 0x80
68 #define MMC_RX_OCTETCOUNT_GB 0x84
69 #define MMC_RX_OCTETCOUNT_G 0x88
70 #define MMC_RX_BROADCASTFRAME_G 0x8c
71 #define MMC_RX_MULTICASTFRAME_G 0x90
72 #define MMC_RX_CRC_ERROR 0x94
73 #define MMC_RX_ALIGN_ERROR 0x98
74 #define MMC_RX_RUN_ERROR 0x9C
75 #define MMC_RX_JABBER_ERROR 0xA0
76 #define MMC_RX_UNDERSIZE_G 0xA4
77 #define MMC_RX_OVERSIZE_G 0xA8
78 #define MMC_RX_64_OCTETS_GB 0xAC
79 #define MMC_RX_65_TO_127_OCTETS_GB 0xb0
80 #define MMC_RX_128_TO_255_OCTETS_GB 0xb4
81 #define MMC_RX_256_TO_511_OCTETS_GB 0xb8
82 #define MMC_RX_512_TO_1023_OCTETS_GB 0xbc
83 #define MMC_RX_1024_TO_MAX_OCTETS_GB 0xc0
84 #define MMC_RX_UNICAST_G 0xc4
85 #define MMC_RX_LENGTH_ERROR 0xc8
86 #define MMC_RX_AUTOFRANGETYPE 0xcc
87 #define MMC_RX_PAUSE_FRAMES 0xd0
88 #define MMC_RX_FIFO_OVERFLOW 0xd4
89 #define MMC_RX_VLAN_FRAMES_GB 0xd8
90 #define MMC_RX_WATCHDOG_ERROR 0xdc
91 /* IPC*/
92 #define MMC_RX_IPC_INTR_MASK 0x100
93 #define MMC_RX_IPC_INTR 0x108
94 /* IPv4*/
95 #define MMC_RX_IPV4_GD 0x110
96 #define MMC_RX_IPV4_HDERR 0x114
97 #define MMC_RX_IPV4_NOPAY 0x118
98 #define MMC_RX_IPV4_FRAG 0x11C
99 #define MMC_RX_IPV4_UDSBL 0x120
100
101 #define MMC_RX_IPV4_GD_OCTETS 0x150
102 #define MMC_RX_IPV4_HDERR_OCTETS 0x154
103 #define MMC_RX_IPV4_NOPAY_OCTETS 0x158
104 #define MMC_RX_IPV4_FRAG_OCTETS 0x15c
105 #define MMC_RX_IPV4_UDSBL_OCTETS 0x160
106
107 /* IPV6*/
108 #define MMC_RX_IPV6_GD_OCTETS 0x164
109 #define MMC_RX_IPV6_HDERR_OCTETS 0x168
110 #define MMC_RX_IPV6_NOPAY_OCTETS 0x16c
111
112 #define MMC_RX_IPV6_GD 0x124
113 #define MMC_RX_IPV6_HDERR 0x128
114 #define MMC_RX_IPV6_NOPAY 0x12c
115
116 /* Protocols*/
117 #define MMC_RX_UDP_GD 0x130
118 #define MMC_RX_UDP_ERR 0x134
119 #define MMC_RX_TCP_GD 0x138
120 #define MMC_RX_TCP_ERR 0x13c
121 #define MMC_RX_ICMP_GD 0x140
122 #define MMC_RX_ICMP_ERR 0x144
123
124 #define MMC_RX_UDP_GD_OCTETS 0x170
125 #define MMC_RX_UDP_ERR_OCTETS 0x174
126 #define MMC_RX_TCP_GD_OCTETS 0x178
127 #define MMC_RX_TCP_ERR_OCTETS 0x17c
128 #define MMC_RX_ICMP_GD_OCTETS 0x180
129 #define MMC_RX_ICMP_ERR_OCTETS 0x184
130
dwmac_mmc_ctrl(void __iomem * mmcaddr,unsigned int mode)131 void dwmac_mmc_ctrl(void __iomem *mmcaddr, unsigned int mode)
132 {
133 u32 value = readl(mmcaddr + MMC_CNTRL);
134
135 value |= (mode & 0x3F);
136
137 writel(value, mmcaddr + MMC_CNTRL);
138
139 pr_debug("stmmac: MMC ctrl register (offset 0x%x): 0x%08x\n",
140 MMC_CNTRL, value);
141 }
142
143 /* To mask all all interrupts.*/
dwmac_mmc_intr_all_mask(void __iomem * mmcaddr)144 void dwmac_mmc_intr_all_mask(void __iomem *mmcaddr)
145 {
146 writel(MMC_DEFAULT_MASK, mmcaddr + MMC_RX_INTR_MASK);
147 writel(MMC_DEFAULT_MASK, mmcaddr + MMC_TX_INTR_MASK);
148 writel(MMC_DEFAULT_MASK, mmcaddr + MMC_RX_IPC_INTR_MASK);
149 }
150
151 /* This reads the MAC core counters (if actaully supported).
152 * by default the MMC core is programmed to reset each
153 * counter after a read. So all the field of the mmc struct
154 * have to be incremented.
155 */
dwmac_mmc_read(void __iomem * mmcaddr,struct stmmac_counters * mmc)156 void dwmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
157 {
158 mmc->mmc_tx_octetcount_gb += readl(mmcaddr + MMC_TX_OCTETCOUNT_GB);
159 mmc->mmc_tx_framecount_gb += readl(mmcaddr + MMC_TX_FRAMECOUNT_GB);
160 mmc->mmc_tx_broadcastframe_g += readl(mmcaddr +
161 MMC_TX_BROADCASTFRAME_G);
162 mmc->mmc_tx_multicastframe_g += readl(mmcaddr +
163 MMC_TX_MULTICASTFRAME_G);
164 mmc->mmc_tx_64_octets_gb += readl(mmcaddr + MMC_TX_64_OCTETS_GB);
165 mmc->mmc_tx_65_to_127_octets_gb +=
166 readl(mmcaddr + MMC_TX_65_TO_127_OCTETS_GB);
167 mmc->mmc_tx_128_to_255_octets_gb +=
168 readl(mmcaddr + MMC_TX_128_TO_255_OCTETS_GB);
169 mmc->mmc_tx_256_to_511_octets_gb +=
170 readl(mmcaddr + MMC_TX_256_TO_511_OCTETS_GB);
171 mmc->mmc_tx_512_to_1023_octets_gb +=
172 readl(mmcaddr + MMC_TX_512_TO_1023_OCTETS_GB);
173 mmc->mmc_tx_1024_to_max_octets_gb +=
174 readl(mmcaddr + MMC_TX_1024_TO_MAX_OCTETS_GB);
175 mmc->mmc_tx_unicast_gb += readl(mmcaddr + MMC_TX_UNICAST_GB);
176 mmc->mmc_tx_multicast_gb += readl(mmcaddr + MMC_TX_MULTICAST_GB);
177 mmc->mmc_tx_broadcast_gb += readl(mmcaddr + MMC_TX_BROADCAST_GB);
178 mmc->mmc_tx_underflow_error += readl(mmcaddr + MMC_TX_UNDERFLOW_ERROR);
179 mmc->mmc_tx_singlecol_g += readl(mmcaddr + MMC_TX_SINGLECOL_G);
180 mmc->mmc_tx_multicol_g += readl(mmcaddr + MMC_TX_MULTICOL_G);
181 mmc->mmc_tx_deferred += readl(mmcaddr + MMC_TX_DEFERRED);
182 mmc->mmc_tx_latecol += readl(mmcaddr + MMC_TX_LATECOL);
183 mmc->mmc_tx_exesscol += readl(mmcaddr + MMC_TX_EXESSCOL);
184 mmc->mmc_tx_carrier_error += readl(mmcaddr + MMC_TX_CARRIER_ERROR);
185 mmc->mmc_tx_octetcount_g += readl(mmcaddr + MMC_TX_OCTETCOUNT_G);
186 mmc->mmc_tx_framecount_g += readl(mmcaddr + MMC_TX_FRAMECOUNT_G);
187 mmc->mmc_tx_excessdef += readl(mmcaddr + MMC_TX_EXCESSDEF);
188 mmc->mmc_tx_pause_frame += readl(mmcaddr + MMC_TX_PAUSE_FRAME);
189 mmc->mmc_tx_vlan_frame_g += readl(mmcaddr + MMC_TX_VLAN_FRAME_G);
190
191 /* MMC RX counter registers */
192 mmc->mmc_rx_framecount_gb += readl(mmcaddr + MMC_RX_FRAMECOUNT_GB);
193 mmc->mmc_rx_octetcount_gb += readl(mmcaddr + MMC_RX_OCTETCOUNT_GB);
194 mmc->mmc_rx_octetcount_g += readl(mmcaddr + MMC_RX_OCTETCOUNT_G);
195 mmc->mmc_rx_broadcastframe_g += readl(mmcaddr +
196 MMC_RX_BROADCASTFRAME_G);
197 mmc->mmc_rx_multicastframe_g += readl(mmcaddr +
198 MMC_RX_MULTICASTFRAME_G);
199 mmc->mmc_rx_crc_error += readl(mmcaddr + MMC_RX_CRC_ERROR);
200 mmc->mmc_rx_align_error += readl(mmcaddr + MMC_RX_ALIGN_ERROR);
201 mmc->mmc_rx_run_error += readl(mmcaddr + MMC_RX_RUN_ERROR);
202 mmc->mmc_rx_jabber_error += readl(mmcaddr + MMC_RX_JABBER_ERROR);
203 mmc->mmc_rx_undersize_g += readl(mmcaddr + MMC_RX_UNDERSIZE_G);
204 mmc->mmc_rx_oversize_g += readl(mmcaddr + MMC_RX_OVERSIZE_G);
205 mmc->mmc_rx_64_octets_gb += readl(mmcaddr + MMC_RX_64_OCTETS_GB);
206 mmc->mmc_rx_65_to_127_octets_gb +=
207 readl(mmcaddr + MMC_RX_65_TO_127_OCTETS_GB);
208 mmc->mmc_rx_128_to_255_octets_gb +=
209 readl(mmcaddr + MMC_RX_128_TO_255_OCTETS_GB);
210 mmc->mmc_rx_256_to_511_octets_gb +=
211 readl(mmcaddr + MMC_RX_256_TO_511_OCTETS_GB);
212 mmc->mmc_rx_512_to_1023_octets_gb +=
213 readl(mmcaddr + MMC_RX_512_TO_1023_OCTETS_GB);
214 mmc->mmc_rx_1024_to_max_octets_gb +=
215 readl(mmcaddr + MMC_RX_1024_TO_MAX_OCTETS_GB);
216 mmc->mmc_rx_unicast_g += readl(mmcaddr + MMC_RX_UNICAST_G);
217 mmc->mmc_rx_length_error += readl(mmcaddr + MMC_RX_LENGTH_ERROR);
218 mmc->mmc_rx_autofrangetype += readl(mmcaddr + MMC_RX_AUTOFRANGETYPE);
219 mmc->mmc_rx_pause_frames += readl(mmcaddr + MMC_RX_PAUSE_FRAMES);
220 mmc->mmc_rx_fifo_overflow += readl(mmcaddr + MMC_RX_FIFO_OVERFLOW);
221 mmc->mmc_rx_vlan_frames_gb += readl(mmcaddr + MMC_RX_VLAN_FRAMES_GB);
222 mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_RX_WATCHDOG_ERROR);
223 /* IPC */
224 mmc->mmc_rx_ipc_intr_mask += readl(mmcaddr + MMC_RX_IPC_INTR_MASK);
225 mmc->mmc_rx_ipc_intr += readl(mmcaddr + MMC_RX_IPC_INTR);
226 /* IPv4 */
227 mmc->mmc_rx_ipv4_gd += readl(mmcaddr + MMC_RX_IPV4_GD);
228 mmc->mmc_rx_ipv4_hderr += readl(mmcaddr + MMC_RX_IPV4_HDERR);
229 mmc->mmc_rx_ipv4_nopay += readl(mmcaddr + MMC_RX_IPV4_NOPAY);
230 mmc->mmc_rx_ipv4_frag += readl(mmcaddr + MMC_RX_IPV4_FRAG);
231 mmc->mmc_rx_ipv4_udsbl += readl(mmcaddr + MMC_RX_IPV4_UDSBL);
232
233 mmc->mmc_rx_ipv4_gd_octets += readl(mmcaddr + MMC_RX_IPV4_GD_OCTETS);
234 mmc->mmc_rx_ipv4_hderr_octets +=
235 readl(mmcaddr + MMC_RX_IPV4_HDERR_OCTETS);
236 mmc->mmc_rx_ipv4_nopay_octets +=
237 readl(mmcaddr + MMC_RX_IPV4_NOPAY_OCTETS);
238 mmc->mmc_rx_ipv4_frag_octets += readl(mmcaddr +
239 MMC_RX_IPV4_FRAG_OCTETS);
240 mmc->mmc_rx_ipv4_udsbl_octets +=
241 readl(mmcaddr + MMC_RX_IPV4_UDSBL_OCTETS);
242
243 /* IPV6 */
244 mmc->mmc_rx_ipv6_gd_octets += readl(mmcaddr + MMC_RX_IPV6_GD_OCTETS);
245 mmc->mmc_rx_ipv6_hderr_octets +=
246 readl(mmcaddr + MMC_RX_IPV6_HDERR_OCTETS);
247 mmc->mmc_rx_ipv6_nopay_octets +=
248 readl(mmcaddr + MMC_RX_IPV6_NOPAY_OCTETS);
249
250 mmc->mmc_rx_ipv6_gd += readl(mmcaddr + MMC_RX_IPV6_GD);
251 mmc->mmc_rx_ipv6_hderr += readl(mmcaddr + MMC_RX_IPV6_HDERR);
252 mmc->mmc_rx_ipv6_nopay += readl(mmcaddr + MMC_RX_IPV6_NOPAY);
253
254 /* Protocols */
255 mmc->mmc_rx_udp_gd += readl(mmcaddr + MMC_RX_UDP_GD);
256 mmc->mmc_rx_udp_err += readl(mmcaddr + MMC_RX_UDP_ERR);
257 mmc->mmc_rx_tcp_gd += readl(mmcaddr + MMC_RX_TCP_GD);
258 mmc->mmc_rx_tcp_err += readl(mmcaddr + MMC_RX_TCP_ERR);
259 mmc->mmc_rx_icmp_gd += readl(mmcaddr + MMC_RX_ICMP_GD);
260 mmc->mmc_rx_icmp_err += readl(mmcaddr + MMC_RX_ICMP_ERR);
261
262 mmc->mmc_rx_udp_gd_octets += readl(mmcaddr + MMC_RX_UDP_GD_OCTETS);
263 mmc->mmc_rx_udp_err_octets += readl(mmcaddr + MMC_RX_UDP_ERR_OCTETS);
264 mmc->mmc_rx_tcp_gd_octets += readl(mmcaddr + MMC_RX_TCP_GD_OCTETS);
265 mmc->mmc_rx_tcp_err_octets += readl(mmcaddr + MMC_RX_TCP_ERR_OCTETS);
266 mmc->mmc_rx_icmp_gd_octets += readl(mmcaddr + MMC_RX_ICMP_GD_OCTETS);
267 mmc->mmc_rx_icmp_err_octets += readl(mmcaddr + MMC_RX_ICMP_ERR_OCTETS);
268 }
269