aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/stmicro
diff options
context:
space:
mode:
authorGiuseppe CAVALLARO <peppe.cavallaro@st.com>2011-09-01 17:51:38 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-15 15:40:01 -0400
commit1c901a46d576926287b05fc145bd3fd31a3e65de (patch)
tree058be60cafd52cb138277ba658b6959519bbb203 /drivers/net/ethernet/stmicro
parent3172d3afa998ffb8f1971746ca960cbe98d62444 (diff)
stmmac: add MMC support exported via ethtool (v3)
This patch adds the MMC management counters support. MMC module is an extension of the register address space and all the hardware counters can be accessed via ethtoo -S ethX. Note that, the MMC interrupts remain masked and the logic to handle this kind of interrupt will be added later (if actually useful). Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/Makefile3
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/common.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c8
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/mmc.h131
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/mmc_core.c265
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac.h1
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c140
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c13
8 files changed, 540 insertions, 22 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 9691733ddb8e..0f23d95746b7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o 2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \ 3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \ 4 dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
5 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o $(stmmac-y) 5 dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
6 mmc_core.o $(stmmac-y)
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 290b97a19254..e08fee880f14 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -29,6 +29,7 @@
29#endif 29#endif
30 30
31#include "descs.h" 31#include "descs.h"
32#include "mmc.h"
32 33
33#undef CHIP_DEBUG_PRINT 34#undef CHIP_DEBUG_PRINT
34/* Turn-on extra printk debug for MAC core, dma and descriptors */ 35/* Turn-on extra printk debug for MAC core, dma and descriptors */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
index 3dbeea619085..a89384c07513 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -118,13 +118,6 @@ static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode,
118 writel(csr6, ioaddr + DMA_CONTROL); 118 writel(csr6, ioaddr + DMA_CONTROL);
119} 119}
120 120
121/* Not yet implemented --- no RMON module */
122static void dwmac1000_dma_diagnostic_fr(void *data,
123 struct stmmac_extra_stats *x, void __iomem *ioaddr)
124{
125 return;
126}
127
128static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) 121static void dwmac1000_dump_dma_regs(void __iomem *ioaddr)
129{ 122{
130 int i; 123 int i;
@@ -143,7 +136,6 @@ const struct stmmac_dma_ops dwmac1000_dma_ops = {
143 .init = dwmac1000_dma_init, 136 .init = dwmac1000_dma_init,
144 .dump_regs = dwmac1000_dump_dma_regs, 137 .dump_regs = dwmac1000_dump_dma_regs,
145 .dma_mode = dwmac1000_dma_operation_mode, 138 .dma_mode = dwmac1000_dma_operation_mode,
146 .dma_diagnostic_fr = dwmac1000_dma_diagnostic_fr,
147 .enable_dma_transmission = dwmac_enable_dma_transmission, 139 .enable_dma_transmission = dwmac_enable_dma_transmission,
148 .enable_dma_irq = dwmac_enable_dma_irq, 140 .enable_dma_irq = dwmac_enable_dma_irq,
149 .disable_dma_irq = dwmac_disable_dma_irq, 141 .disable_dma_irq = dwmac_disable_dma_irq,
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc.h b/drivers/net/ethernet/stmicro/stmmac/mmc.h
new file mode 100644
index 000000000000..a38352024cb8
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc.h
@@ -0,0 +1,131 @@
1/*******************************************************************************
2 MMC Header file
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 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25/* MMC control register */
26/* When set, all counter are reset */
27#define MMC_CNTRL_COUNTER_RESET 0x1
28/* When set, do not roll over zero
29 * after reaching the max value*/
30#define MMC_CNTRL_COUNTER_STOP_ROLLOVER 0x2
31#define MMC_CNTRL_RESET_ON_READ 0x4 /* Reset after reading */
32#define MMC_CNTRL_COUNTER_FREEZER 0x8 /* Freeze counter values to the
33 * current value.*/
34#define MMC_CNTRL_PRESET 0x10
35#define MMC_CNTRL_FULL_HALF_PRESET 0x20
36struct stmmac_counters {
37 unsigned int mmc_tx_octetcount_gb;
38 unsigned int mmc_tx_framecount_gb;
39 unsigned int mmc_tx_broadcastframe_g;
40 unsigned int mmc_tx_multicastframe_g;
41 unsigned int mmc_tx_64_octets_gb;
42 unsigned int mmc_tx_65_to_127_octets_gb;
43 unsigned int mmc_tx_128_to_255_octets_gb;
44 unsigned int mmc_tx_256_to_511_octets_gb;
45 unsigned int mmc_tx_512_to_1023_octets_gb;
46 unsigned int mmc_tx_1024_to_max_octets_gb;
47 unsigned int mmc_tx_unicast_gb;
48 unsigned int mmc_tx_multicast_gb;
49 unsigned int mmc_tx_broadcast_gb;
50 unsigned int mmc_tx_underflow_error;
51 unsigned int mmc_tx_singlecol_g;
52 unsigned int mmc_tx_multicol_g;
53 unsigned int mmc_tx_deferred;
54 unsigned int mmc_tx_latecol;
55 unsigned int mmc_tx_exesscol;
56 unsigned int mmc_tx_carrier_error;
57 unsigned int mmc_tx_octetcount_g;
58 unsigned int mmc_tx_framecount_g;
59 unsigned int mmc_tx_excessdef;
60 unsigned int mmc_tx_pause_frame;
61 unsigned int mmc_tx_vlan_frame_g;
62
63 /* MMC RX counter registers */
64 unsigned int mmc_rx_framecount_gb;
65 unsigned int mmc_rx_octetcount_gb;
66 unsigned int mmc_rx_octetcount_g;
67 unsigned int mmc_rx_broadcastframe_g;
68 unsigned int mmc_rx_multicastframe_g;
69 unsigned int mmc_rx_crc_errror;
70 unsigned int mmc_rx_align_error;
71 unsigned int mmc_rx_run_error;
72 unsigned int mmc_rx_jabber_error;
73 unsigned int mmc_rx_undersize_g;
74 unsigned int mmc_rx_oversize_g;
75 unsigned int mmc_rx_64_octets_gb;
76 unsigned int mmc_rx_65_to_127_octets_gb;
77 unsigned int mmc_rx_128_to_255_octets_gb;
78 unsigned int mmc_rx_256_to_511_octets_gb;
79 unsigned int mmc_rx_512_to_1023_octets_gb;
80 unsigned int mmc_rx_1024_to_max_octets_gb;
81 unsigned int mmc_rx_unicast_g;
82 unsigned int mmc_rx_length_error;
83 unsigned int mmc_rx_autofrangetype;
84 unsigned int mmc_rx_pause_frames;
85 unsigned int mmc_rx_fifo_overflow;
86 unsigned int mmc_rx_vlan_frames_gb;
87 unsigned int mmc_rx_watchdog_error;
88 /* IPC */
89 unsigned int mmc_rx_ipc_intr_mask;
90 unsigned int mmc_rx_ipc_intr;
91 /* IPv4 */
92 unsigned int mmc_rx_ipv4_gd;
93 unsigned int mmc_rx_ipv4_hderr;
94 unsigned int mmc_rx_ipv4_nopay;
95 unsigned int mmc_rx_ipv4_frag;
96 unsigned int mmc_rx_ipv4_udsbl;
97
98 unsigned int mmc_rx_ipv4_gd_octets;
99 unsigned int mmc_rx_ipv4_hderr_octets;
100 unsigned int mmc_rx_ipv4_nopay_octets;
101 unsigned int mmc_rx_ipv4_frag_octets;
102 unsigned int mmc_rx_ipv4_udsbl_octets;
103
104 /* IPV6 */
105 unsigned int mmc_rx_ipv6_gd_octets;
106 unsigned int mmc_rx_ipv6_hderr_octets;
107 unsigned int mmc_rx_ipv6_nopay_octets;
108
109 unsigned int mmc_rx_ipv6_gd;
110 unsigned int mmc_rx_ipv6_hderr;
111 unsigned int mmc_rx_ipv6_nopay;
112
113 /* Protocols */
114 unsigned int mmc_rx_udp_gd;
115 unsigned int mmc_rx_udp_err;
116 unsigned int mmc_rx_tcp_gd;
117 unsigned int mmc_rx_tcp_err;
118 unsigned int mmc_rx_icmp_gd;
119 unsigned int mmc_rx_icmp_err;
120
121 unsigned int mmc_rx_udp_gd_octets;
122 unsigned int mmc_rx_udp_err_octets;
123 unsigned int mmc_rx_tcp_gd_octets;
124 unsigned int mmc_rx_tcp_err_octets;
125 unsigned int mmc_rx_icmp_gd_octets;
126 unsigned int mmc_rx_icmp_err_octets;
127};
128
129extern void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode);
130extern void dwmac_mmc_intr_all_mask(void __iomem *ioaddr);
131extern void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc);
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
new file mode 100644
index 000000000000..41e6b33e1b08
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -0,0 +1,265 @@
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 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/io.h>
26#include "mmc.h"
27
28/* MAC Management Counters register offset */
29
30#define MMC_CNTRL 0x00000100 /* MMC Control */
31#define MMC_RX_INTR 0x00000104 /* MMC RX Interrupt */
32#define MMC_TX_INTR 0x00000108 /* MMC TX Interrupt */
33#define MMC_RX_INTR_MASK 0x0000010c /* MMC Interrupt Mask */
34#define MMC_TX_INTR_MASK 0x00000110 /* MMC Interrupt Mask */
35#define MMC_DEFAUL_MASK 0xffffffff
36
37/* MMC TX counter registers */
38
39/* Note:
40 * _GB register stands for good and bad frames
41 * _G is for good only.
42 */
43#define MMC_TX_OCTETCOUNT_GB 0x00000114
44#define MMC_TX_FRAMECOUNT_GB 0x00000118
45#define MMC_TX_BROADCASTFRAME_G 0x0000011c
46#define MMC_TX_MULTICASTFRAME_G 0x00000120
47#define MMC_TX_64_OCTETS_GB 0x00000124
48#define MMC_TX_65_TO_127_OCTETS_GB 0x00000128
49#define MMC_TX_128_TO_255_OCTETS_GB 0x0000012c
50#define MMC_TX_256_TO_511_OCTETS_GB 0x00000130
51#define MMC_TX_512_TO_1023_OCTETS_GB 0x00000134
52#define MMC_TX_1024_TO_MAX_OCTETS_GB 0x00000138
53#define MMC_TX_UNICAST_GB 0x0000013c
54#define MMC_TX_MULTICAST_GB 0x00000140
55#define MMC_TX_BROADCAST_GB 0x00000144
56#define MMC_TX_UNDERFLOW_ERROR 0x00000148
57#define MMC_TX_SINGLECOL_G 0x0000014c
58#define MMC_TX_MULTICOL_G 0x00000150
59#define MMC_TX_DEFERRED 0x00000154
60#define MMC_TX_LATECOL 0x00000158
61#define MMC_TX_EXESSCOL 0x0000015c
62#define MMC_TX_CARRIER_ERROR 0x00000160
63#define MMC_TX_OCTETCOUNT_G 0x00000164
64#define MMC_TX_FRAMECOUNT_G 0x00000168
65#define MMC_TX_EXCESSDEF 0x0000016c
66#define MMC_TX_PAUSE_FRAME 0x00000170
67#define MMC_TX_VLAN_FRAME_G 0x00000174
68
69/* MMC RX counter registers */
70#define MMC_RX_FRAMECOUNT_GB 0x00000180
71#define MMC_RX_OCTETCOUNT_GB 0x00000184
72#define MMC_RX_OCTETCOUNT_G 0x00000188
73#define MMC_RX_BROADCASTFRAME_G 0x0000018c
74#define MMC_RX_MULTICASTFRAME_G 0x00000190
75#define MMC_RX_CRC_ERRROR 0x00000194
76#define MMC_RX_ALIGN_ERROR 0x00000198
77#define MMC_RX_RUN_ERROR 0x0000019C
78#define MMC_RX_JABBER_ERROR 0x000001A0
79#define MMC_RX_UNDERSIZE_G 0x000001A4
80#define MMC_RX_OVERSIZE_G 0x000001A8
81#define MMC_RX_64_OCTETS_GB 0x000001AC
82#define MMC_RX_65_TO_127_OCTETS_GB 0x000001b0
83#define MMC_RX_128_TO_255_OCTETS_GB 0x000001b4
84#define MMC_RX_256_TO_511_OCTETS_GB 0x000001b8
85#define MMC_RX_512_TO_1023_OCTETS_GB 0x000001bc
86#define MMC_RX_1024_TO_MAX_OCTETS_GB 0x000001c0
87#define MMC_RX_UNICAST_G 0x000001c4
88#define MMC_RX_LENGTH_ERROR 0x000001c8
89#define MMC_RX_AUTOFRANGETYPE 0x000001cc
90#define MMC_RX_PAUSE_FRAMES 0x000001d0
91#define MMC_RX_FIFO_OVERFLOW 0x000001d4
92#define MMC_RX_VLAN_FRAMES_GB 0x000001d8
93#define MMC_RX_WATCHDOG_ERROR 0x000001dc
94/* IPC*/
95#define MMC_RX_IPC_INTR_MASK 0x00000200
96#define MMC_RX_IPC_INTR 0x00000208
97/* IPv4*/
98#define MMC_RX_IPV4_GD 0x00000210
99#define MMC_RX_IPV4_HDERR 0x00000214
100#define MMC_RX_IPV4_NOPAY 0x00000218
101#define MMC_RX_IPV4_FRAG 0x0000021C
102#define MMC_RX_IPV4_UDSBL 0x00000220
103
104#define MMC_RX_IPV4_GD_OCTETS 0x00000250
105#define MMC_RX_IPV4_HDERR_OCTETS 0x00000254
106#define MMC_RX_IPV4_NOPAY_OCTETS 0x00000258
107#define MMC_RX_IPV4_FRAG_OCTETS 0x0000025c
108#define MMC_RX_IPV4_UDSBL_OCTETS 0x00000260
109
110/* IPV6*/
111#define MMC_RX_IPV6_GD_OCTETS 0x00000264
112#define MMC_RX_IPV6_HDERR_OCTETS 0x00000268
113#define MMC_RX_IPV6_NOPAY_OCTETS 0x0000026c
114
115#define MMC_RX_IPV6_GD 0x00000224
116#define MMC_RX_IPV6_HDERR 0x00000228
117#define MMC_RX_IPV6_NOPAY 0x0000022c
118
119/* Protocols*/
120#define MMC_RX_UDP_GD 0x00000230
121#define MMC_RX_UDP_ERR 0x00000234
122#define MMC_RX_TCP_GD 0x00000238
123#define MMC_RX_TCP_ERR 0x0000023c
124#define MMC_RX_ICMP_GD 0x00000240
125#define MMC_RX_ICMP_ERR 0x00000244
126
127#define MMC_RX_UDP_GD_OCTETS 0x00000270
128#define MMC_RX_UDP_ERR_OCTETS 0x00000274
129#define MMC_RX_TCP_GD_OCTETS 0x00000278
130#define MMC_RX_TCP_ERR_OCTETS 0x0000027c
131#define MMC_RX_ICMP_GD_OCTETS 0x00000280
132#define MMC_RX_ICMP_ERR_OCTETS 0x00000284
133
134void dwmac_mmc_ctrl(void __iomem *ioaddr, unsigned int mode)
135{
136 u32 value = readl(ioaddr + MMC_CNTRL);
137
138 value |= (mode & 0x3F);
139
140 writel(value, ioaddr + MMC_CNTRL);
141
142 pr_debug("stmmac: MMC ctrl register (offset 0x%x): 0x%08x\n",
143 MMC_CNTRL, value);
144}
145
146/* To mask all all interrupts.*/
147void dwmac_mmc_intr_all_mask(void __iomem *ioaddr)
148{
149 writel(MMC_DEFAUL_MASK, ioaddr + MMC_RX_INTR_MASK);
150 writel(MMC_DEFAUL_MASK, ioaddr + MMC_TX_INTR_MASK);
151}
152
153/* This reads the MAC core counters (if actaully supported).
154 * by default the MMC core is programmed to reset each
155 * counter after a read. So all the field of the mmc struct
156 * have to be incremented.
157 */
158void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc)
159{
160 mmc->mmc_tx_octetcount_gb += readl(ioaddr + MMC_TX_OCTETCOUNT_GB);
161 mmc->mmc_tx_framecount_gb += readl(ioaddr + MMC_TX_FRAMECOUNT_GB);
162 mmc->mmc_tx_broadcastframe_g += readl(ioaddr + MMC_TX_BROADCASTFRAME_G);
163 mmc->mmc_tx_multicastframe_g += readl(ioaddr + MMC_TX_MULTICASTFRAME_G);
164 mmc->mmc_tx_64_octets_gb += readl(ioaddr + MMC_TX_64_OCTETS_GB);
165 mmc->mmc_tx_65_to_127_octets_gb +=
166 readl(ioaddr + MMC_TX_65_TO_127_OCTETS_GB);
167 mmc->mmc_tx_128_to_255_octets_gb +=
168 readl(ioaddr + MMC_TX_128_TO_255_OCTETS_GB);
169 mmc->mmc_tx_256_to_511_octets_gb +=
170 readl(ioaddr + MMC_TX_256_TO_511_OCTETS_GB);
171 mmc->mmc_tx_512_to_1023_octets_gb +=
172 readl(ioaddr + MMC_TX_512_TO_1023_OCTETS_GB);
173 mmc->mmc_tx_1024_to_max_octets_gb +=
174 readl(ioaddr + MMC_TX_1024_TO_MAX_OCTETS_GB);
175 mmc->mmc_tx_unicast_gb += readl(ioaddr + MMC_TX_UNICAST_GB);
176 mmc->mmc_tx_multicast_gb += readl(ioaddr + MMC_TX_MULTICAST_GB);
177 mmc->mmc_tx_broadcast_gb += readl(ioaddr + MMC_TX_BROADCAST_GB);
178 mmc->mmc_tx_underflow_error += readl(ioaddr + MMC_TX_UNDERFLOW_ERROR);
179 mmc->mmc_tx_singlecol_g += readl(ioaddr + MMC_TX_SINGLECOL_G);
180 mmc->mmc_tx_multicol_g += readl(ioaddr + MMC_TX_MULTICOL_G);
181 mmc->mmc_tx_deferred += readl(ioaddr + MMC_TX_DEFERRED);
182 mmc->mmc_tx_latecol += readl(ioaddr + MMC_TX_LATECOL);
183 mmc->mmc_tx_exesscol += readl(ioaddr + MMC_TX_EXESSCOL);
184 mmc->mmc_tx_carrier_error += readl(ioaddr + MMC_TX_CARRIER_ERROR);
185 mmc->mmc_tx_octetcount_g += readl(ioaddr + MMC_TX_OCTETCOUNT_G);
186 mmc->mmc_tx_framecount_g += readl(ioaddr + MMC_TX_FRAMECOUNT_G);
187 mmc->mmc_tx_excessdef += readl(ioaddr + MMC_TX_EXCESSDEF);
188 mmc->mmc_tx_pause_frame += readl(ioaddr + MMC_TX_PAUSE_FRAME);
189 mmc->mmc_tx_vlan_frame_g += readl(ioaddr + MMC_TX_VLAN_FRAME_G);
190
191 /* MMC RX counter registers */
192 mmc->mmc_rx_framecount_gb += readl(ioaddr + MMC_RX_FRAMECOUNT_GB);
193 mmc->mmc_rx_octetcount_gb += readl(ioaddr + MMC_RX_OCTETCOUNT_GB);
194 mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
195 mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
196 mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
197 mmc->mmc_rx_crc_errror += readl(ioaddr + MMC_RX_CRC_ERRROR);
198 mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
199 mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
200 mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
201 mmc->mmc_rx_undersize_g += readl(ioaddr + MMC_RX_UNDERSIZE_G);
202 mmc->mmc_rx_oversize_g += readl(ioaddr + MMC_RX_OVERSIZE_G);
203 mmc->mmc_rx_64_octets_gb += readl(ioaddr + MMC_RX_64_OCTETS_GB);
204 mmc->mmc_rx_65_to_127_octets_gb +=
205 readl(ioaddr + MMC_RX_65_TO_127_OCTETS_GB);
206 mmc->mmc_rx_128_to_255_octets_gb +=
207 readl(ioaddr + MMC_RX_128_TO_255_OCTETS_GB);
208 mmc->mmc_rx_256_to_511_octets_gb +=
209 readl(ioaddr + MMC_RX_256_TO_511_OCTETS_GB);
210 mmc->mmc_rx_512_to_1023_octets_gb +=
211 readl(ioaddr + MMC_RX_512_TO_1023_OCTETS_GB);
212 mmc->mmc_rx_1024_to_max_octets_gb +=
213 readl(ioaddr + MMC_RX_1024_TO_MAX_OCTETS_GB);
214 mmc->mmc_rx_unicast_g += readl(ioaddr + MMC_RX_UNICAST_G);
215 mmc->mmc_rx_length_error += readl(ioaddr + MMC_RX_LENGTH_ERROR);
216 mmc->mmc_rx_autofrangetype += readl(ioaddr + MMC_RX_AUTOFRANGETYPE);
217 mmc->mmc_rx_pause_frames += readl(ioaddr + MMC_RX_PAUSE_FRAMES);
218 mmc->mmc_rx_fifo_overflow += readl(ioaddr + MMC_RX_FIFO_OVERFLOW);
219 mmc->mmc_rx_vlan_frames_gb += readl(ioaddr + MMC_RX_VLAN_FRAMES_GB);
220 mmc->mmc_rx_watchdog_error += readl(ioaddr + MMC_RX_WATCHDOG_ERROR);
221 /* IPC */
222 mmc->mmc_rx_ipc_intr_mask += readl(ioaddr + MMC_RX_IPC_INTR_MASK);
223 mmc->mmc_rx_ipc_intr += readl(ioaddr + MMC_RX_IPC_INTR);
224 /* IPv4 */
225 mmc->mmc_rx_ipv4_gd += readl(ioaddr + MMC_RX_IPV4_GD);
226 mmc->mmc_rx_ipv4_hderr += readl(ioaddr + MMC_RX_IPV4_HDERR);
227 mmc->mmc_rx_ipv4_nopay += readl(ioaddr + MMC_RX_IPV4_NOPAY);
228 mmc->mmc_rx_ipv4_frag += readl(ioaddr + MMC_RX_IPV4_FRAG);
229 mmc->mmc_rx_ipv4_udsbl += readl(ioaddr + MMC_RX_IPV4_UDSBL);
230
231 mmc->mmc_rx_ipv4_gd_octets += readl(ioaddr + MMC_RX_IPV4_GD_OCTETS);
232 mmc->mmc_rx_ipv4_hderr_octets +=
233 readl(ioaddr + MMC_RX_IPV4_HDERR_OCTETS);
234 mmc->mmc_rx_ipv4_nopay_octets +=
235 readl(ioaddr + MMC_RX_IPV4_NOPAY_OCTETS);
236 mmc->mmc_rx_ipv4_frag_octets += readl(ioaddr + MMC_RX_IPV4_FRAG_OCTETS);
237 mmc->mmc_rx_ipv4_udsbl_octets +=
238 readl(ioaddr + MMC_RX_IPV4_UDSBL_OCTETS);
239
240 /* IPV6 */
241 mmc->mmc_rx_ipv6_gd_octets += readl(ioaddr + MMC_RX_IPV6_GD_OCTETS);
242 mmc->mmc_rx_ipv6_hderr_octets +=
243 readl(ioaddr + MMC_RX_IPV6_HDERR_OCTETS);
244 mmc->mmc_rx_ipv6_nopay_octets +=
245 readl(ioaddr + MMC_RX_IPV6_NOPAY_OCTETS);
246
247 mmc->mmc_rx_ipv6_gd += readl(ioaddr + MMC_RX_IPV6_GD);
248 mmc->mmc_rx_ipv6_hderr += readl(ioaddr + MMC_RX_IPV6_HDERR);
249 mmc->mmc_rx_ipv6_nopay += readl(ioaddr + MMC_RX_IPV6_NOPAY);
250
251 /* Protocols */
252 mmc->mmc_rx_udp_gd += readl(ioaddr + MMC_RX_UDP_GD);
253 mmc->mmc_rx_udp_err += readl(ioaddr + MMC_RX_UDP_ERR);
254 mmc->mmc_rx_tcp_gd += readl(ioaddr + MMC_RX_TCP_GD);
255 mmc->mmc_rx_tcp_err += readl(ioaddr + MMC_RX_TCP_ERR);
256 mmc->mmc_rx_icmp_gd += readl(ioaddr + MMC_RX_ICMP_GD);
257 mmc->mmc_rx_icmp_err += readl(ioaddr + MMC_RX_ICMP_ERR);
258
259 mmc->mmc_rx_udp_gd_octets += readl(ioaddr + MMC_RX_UDP_GD_OCTETS);
260 mmc->mmc_rx_udp_err_octets += readl(ioaddr + MMC_RX_UDP_ERR_OCTETS);
261 mmc->mmc_rx_tcp_gd_octets += readl(ioaddr + MMC_RX_TCP_GD_OCTETS);
262 mmc->mmc_rx_tcp_err_octets += readl(ioaddr + MMC_RX_TCP_ERR_OCTETS);
263 mmc->mmc_rx_icmp_gd_octets += readl(ioaddr + MMC_RX_ICMP_GD_OCTETS);
264 mmc->mmc_rx_icmp_err_octets += readl(ioaddr + MMC_RX_ICMP_ERR_OCTETS);
265}
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 619e3af97404..ef037965493d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -77,6 +77,7 @@ struct stmmac_priv {
77 struct stmmac_timer *tm; 77 struct stmmac_timer *tm;
78#endif 78#endif
79 struct plat_stmmacenet_data *plat; 79 struct plat_stmmacenet_data *plat;
80 struct stmmac_counters mmc;
80}; 81};
81 82
82extern int stmmac_mdio_unregister(struct net_device *ndev); 83extern int stmmac_mdio_unregister(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 79df79dc6a69..aedff9a90ebc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -46,7 +46,7 @@ struct stmmac_stats {
46 { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \ 46 { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \
47 offsetof(struct stmmac_priv, xstats.m)} 47 offsetof(struct stmmac_priv, xstats.m)}
48 48
49static const struct stmmac_stats stmmac_gstrings_stats[] = { 49static const struct stmmac_stats stmmac_gstrings_stats[] = {
50 STMMAC_STAT(tx_underflow), 50 STMMAC_STAT(tx_underflow),
51 STMMAC_STAT(tx_carrier), 51 STMMAC_STAT(tx_carrier),
52 STMMAC_STAT(tx_losscarrier), 52 STMMAC_STAT(tx_losscarrier),
@@ -91,19 +91,106 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
91}; 91};
92#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) 92#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
93 93
94/* HW MAC Management counters (if supported) */
95#define STMMAC_MMC_STAT(m) \
96 { #m, FIELD_SIZEOF(struct stmmac_counters, m), \
97 offsetof(struct stmmac_priv, mmc.m)}
98
99static const struct stmmac_stats stmmac_gstr_mmc[] = {
100 STMMAC_MMC_STAT(mmc_tx_octetcount_gb),
101 STMMAC_MMC_STAT(mmc_tx_framecount_gb),
102 STMMAC_MMC_STAT(mmc_tx_broadcastframe_g),
103 STMMAC_MMC_STAT(mmc_tx_multicastframe_g),
104 STMMAC_MMC_STAT(mmc_tx_64_octets_gb),
105 STMMAC_MMC_STAT(mmc_tx_65_to_127_octets_gb),
106 STMMAC_MMC_STAT(mmc_tx_128_to_255_octets_gb),
107 STMMAC_MMC_STAT(mmc_tx_256_to_511_octets_gb),
108 STMMAC_MMC_STAT(mmc_tx_512_to_1023_octets_gb),
109 STMMAC_MMC_STAT(mmc_tx_1024_to_max_octets_gb),
110 STMMAC_MMC_STAT(mmc_tx_unicast_gb),
111 STMMAC_MMC_STAT(mmc_tx_multicast_gb),
112 STMMAC_MMC_STAT(mmc_tx_broadcast_gb),
113 STMMAC_MMC_STAT(mmc_tx_underflow_error),
114 STMMAC_MMC_STAT(mmc_tx_singlecol_g),
115 STMMAC_MMC_STAT(mmc_tx_multicol_g),
116 STMMAC_MMC_STAT(mmc_tx_deferred),
117 STMMAC_MMC_STAT(mmc_tx_latecol),
118 STMMAC_MMC_STAT(mmc_tx_exesscol),
119 STMMAC_MMC_STAT(mmc_tx_carrier_error),
120 STMMAC_MMC_STAT(mmc_tx_octetcount_g),
121 STMMAC_MMC_STAT(mmc_tx_framecount_g),
122 STMMAC_MMC_STAT(mmc_tx_excessdef),
123 STMMAC_MMC_STAT(mmc_tx_pause_frame),
124 STMMAC_MMC_STAT(mmc_tx_vlan_frame_g),
125 STMMAC_MMC_STAT(mmc_rx_framecount_gb),
126 STMMAC_MMC_STAT(mmc_rx_octetcount_gb),
127 STMMAC_MMC_STAT(mmc_rx_octetcount_g),
128 STMMAC_MMC_STAT(mmc_rx_broadcastframe_g),
129 STMMAC_MMC_STAT(mmc_rx_multicastframe_g),
130 STMMAC_MMC_STAT(mmc_rx_crc_errror),
131 STMMAC_MMC_STAT(mmc_rx_align_error),
132 STMMAC_MMC_STAT(mmc_rx_run_error),
133 STMMAC_MMC_STAT(mmc_rx_jabber_error),
134 STMMAC_MMC_STAT(mmc_rx_undersize_g),
135 STMMAC_MMC_STAT(mmc_rx_oversize_g),
136 STMMAC_MMC_STAT(mmc_rx_64_octets_gb),
137 STMMAC_MMC_STAT(mmc_rx_65_to_127_octets_gb),
138 STMMAC_MMC_STAT(mmc_rx_128_to_255_octets_gb),
139 STMMAC_MMC_STAT(mmc_rx_256_to_511_octets_gb),
140 STMMAC_MMC_STAT(mmc_rx_512_to_1023_octets_gb),
141 STMMAC_MMC_STAT(mmc_rx_1024_to_max_octets_gb),
142 STMMAC_MMC_STAT(mmc_rx_unicast_g),
143 STMMAC_MMC_STAT(mmc_rx_length_error),
144 STMMAC_MMC_STAT(mmc_rx_autofrangetype),
145 STMMAC_MMC_STAT(mmc_rx_pause_frames),
146 STMMAC_MMC_STAT(mmc_rx_fifo_overflow),
147 STMMAC_MMC_STAT(mmc_rx_vlan_frames_gb),
148 STMMAC_MMC_STAT(mmc_rx_watchdog_error),
149 STMMAC_MMC_STAT(mmc_rx_ipc_intr_mask),
150 STMMAC_MMC_STAT(mmc_rx_ipc_intr),
151 STMMAC_MMC_STAT(mmc_rx_ipv4_gd),
152 STMMAC_MMC_STAT(mmc_rx_ipv4_hderr),
153 STMMAC_MMC_STAT(mmc_rx_ipv4_nopay),
154 STMMAC_MMC_STAT(mmc_rx_ipv4_frag),
155 STMMAC_MMC_STAT(mmc_rx_ipv4_udsbl),
156 STMMAC_MMC_STAT(mmc_rx_ipv4_gd_octets),
157 STMMAC_MMC_STAT(mmc_rx_ipv4_hderr_octets),
158 STMMAC_MMC_STAT(mmc_rx_ipv4_nopay_octets),
159 STMMAC_MMC_STAT(mmc_rx_ipv4_frag_octets),
160 STMMAC_MMC_STAT(mmc_rx_ipv4_udsbl_octets),
161 STMMAC_MMC_STAT(mmc_rx_ipv6_gd_octets),
162 STMMAC_MMC_STAT(mmc_rx_ipv6_hderr_octets),
163 STMMAC_MMC_STAT(mmc_rx_ipv6_nopay_octets),
164 STMMAC_MMC_STAT(mmc_rx_ipv6_gd),
165 STMMAC_MMC_STAT(mmc_rx_ipv6_hderr),
166 STMMAC_MMC_STAT(mmc_rx_ipv6_nopay),
167 STMMAC_MMC_STAT(mmc_rx_udp_gd),
168 STMMAC_MMC_STAT(mmc_rx_udp_err),
169 STMMAC_MMC_STAT(mmc_rx_tcp_gd),
170 STMMAC_MMC_STAT(mmc_rx_tcp_err),
171 STMMAC_MMC_STAT(mmc_rx_icmp_gd),
172 STMMAC_MMC_STAT(mmc_rx_icmp_err),
173 STMMAC_MMC_STAT(mmc_rx_udp_gd_octets),
174 STMMAC_MMC_STAT(mmc_rx_udp_err_octets),
175 STMMAC_MMC_STAT(mmc_rx_tcp_gd_octets),
176 STMMAC_MMC_STAT(mmc_rx_tcp_err_octets),
177 STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),
178 STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),
179};
180#define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_gstr_mmc)
181
94static void stmmac_ethtool_getdrvinfo(struct net_device *dev, 182static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
95 struct ethtool_drvinfo *info) 183 struct ethtool_drvinfo *info)
96{ 184{
97 struct stmmac_priv *priv = netdev_priv(dev); 185 struct stmmac_priv *priv = netdev_priv(dev);
98 186
99 if (!priv->plat->has_gmac) 187 if (priv->plat->has_gmac)
100 strcpy(info->driver, MAC100_ETHTOOL_NAME);
101 else
102 strcpy(info->driver, GMAC_ETHTOOL_NAME); 188 strcpy(info->driver, GMAC_ETHTOOL_NAME);
189 else
190 strcpy(info->driver, MAC100_ETHTOOL_NAME);
103 191
104 strcpy(info->version, DRV_MODULE_VERSION); 192 strcpy(info->version, DRV_MODULE_VERSION);
105 info->fw_version[0] = '\0'; 193 info->fw_version[0] = '\0';
106 info->n_stats = STMMAC_STATS_LEN;
107} 194}
108 195
109static int stmmac_ethtool_getsettings(struct net_device *dev, 196static int stmmac_ethtool_getsettings(struct net_device *dev,
@@ -252,24 +339,44 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
252 struct ethtool_stats *dummy, u64 *data) 339 struct ethtool_stats *dummy, u64 *data)
253{ 340{
254 struct stmmac_priv *priv = netdev_priv(dev); 341 struct stmmac_priv *priv = netdev_priv(dev);
255 int i; 342 int i, j = 0;
256
257 /* Update HW stats if supported */
258 priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
259 priv->ioaddr);
260 343
344 /* Update the DMA HW counters for dwmac10/100 */
345 if (!priv->plat->has_gmac)
346 priv->hw->dma->dma_diagnostic_fr(&dev->stats,
347 (void *) &priv->xstats,
348 priv->ioaddr);
349 else {
350 /* If supported, for new GMAC chips expose the MMC counters */
351 dwmac_mmc_read(priv->ioaddr, &priv->mmc);
352
353 for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
354 char *p = (char *)priv + stmmac_gstr_mmc[i].stat_offset;
355
356 data[j++] = (stmmac_gstr_mmc[i].sizeof_stat ==
357 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
358 }
359 }
261 for (i = 0; i < STMMAC_STATS_LEN; i++) { 360 for (i = 0; i < STMMAC_STATS_LEN; i++) {
262 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; 361 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
263 data[i] = (stmmac_gstrings_stats[i].sizeof_stat == 362 data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==
264 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p); 363 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
265 } 364 }
266} 365}
267 366
268static int stmmac_get_sset_count(struct net_device *netdev, int sset) 367static int stmmac_get_sset_count(struct net_device *netdev, int sset)
269{ 368{
369 struct stmmac_priv *priv = netdev_priv(netdev);
370 int len;
371
270 switch (sset) { 372 switch (sset) {
271 case ETH_SS_STATS: 373 case ETH_SS_STATS:
272 return STMMAC_STATS_LEN; 374 len = STMMAC_STATS_LEN;
375
376 if (priv->plat->has_gmac)
377 len += STMMAC_MMC_STATS_LEN;
378
379 return len;
273 default: 380 default:
274 return -EOPNOTSUPP; 381 return -EOPNOTSUPP;
275 } 382 }
@@ -279,9 +386,16 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
279{ 386{
280 int i; 387 int i;
281 u8 *p = data; 388 u8 *p = data;
389 struct stmmac_priv *priv = netdev_priv(dev);
282 390
283 switch (stringset) { 391 switch (stringset) {
284 case ETH_SS_STATS: 392 case ETH_SS_STATS:
393 if (priv->plat->has_gmac)
394 for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
395 memcpy(p, stmmac_gstr_mmc[i].stat_string,
396 ETH_GSTRING_LEN);
397 p += ETH_GSTRING_LEN;
398 }
285 for (i = 0; i < STMMAC_STATS_LEN; i++) { 399 for (i = 0; i < STMMAC_STATS_LEN; i++) {
286 memcpy(p, stmmac_gstrings_stats[i].stat_string, 400 memcpy(p, stmmac_gstrings_stats[i].stat_string,
287 ETH_GSTRING_LEN); 401 ETH_GSTRING_LEN);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 5aea21e587dd..c28b90d35007 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -748,6 +748,17 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
748 stmmac_tx_err(priv); 748 stmmac_tx_err(priv);
749} 749}
750 750
751static void stmmac_mmc_setup(struct stmmac_priv *priv)
752{
753 unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
754 MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
755
756 /* Do not manage MMC IRQ (FIXME) */
757 dwmac_mmc_intr_all_mask(priv->ioaddr);
758 dwmac_mmc_ctrl(priv->ioaddr, mode);
759 memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
760}
761
751/** 762/**
752 * stmmac_open - open entry point of the driver 763 * stmmac_open - open entry point of the driver
753 * @dev : pointer to the device structure. 764 * @dev : pointer to the device structure.
@@ -846,6 +857,8 @@ static int stmmac_open(struct net_device *dev)
846 memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); 857 memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
847 priv->xstats.threshold = tc; 858 priv->xstats.threshold = tc;
848 859
860 stmmac_mmc_setup(priv);
861
849 /* Start the ball rolling... */ 862 /* Start the ball rolling... */
850 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); 863 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
851 priv->hw->dma->start_tx(priv->ioaddr); 864 priv->hw->dma->start_tx(priv->ioaddr);