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