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 
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.*/
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  */
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