Merge tag '5.7-rc-smb3-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
[linux-2.6-microblaze.git] / drivers / net / ethernet / altera / altera_tse_ethtool.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Ethtool support for Altera Triple-Speed Ethernet MAC driver
3  * Copyright (C) 2008-2014 Altera Corporation. All rights reserved
4  *
5  * Contributors:
6  *   Dalon Westergreen
7  *   Thomas Chou
8  *   Ian Abbott
9  *   Yuriy Kozlov
10  *   Tobias Klauser
11  *   Andriy Smolskyy
12  *   Roman Bulgakov
13  *   Dmytro Mytarchuk
14  *
15  * Original driver contributed by SLS.
16  * Major updates contributed by GlobalLogic
17  */
18
19 #include <linux/ethtool.h>
20 #include <linux/kernel.h>
21 #include <linux/netdevice.h>
22 #include <linux/phy.h>
23
24 #include "altera_tse.h"
25
26 #define TSE_STATS_LEN   31
27 #define TSE_NUM_REGS    128
28
29 static char const stat_gstrings[][ETH_GSTRING_LEN] = {
30         "tx_packets",
31         "rx_packets",
32         "rx_crc_errors",
33         "rx_align_errors",
34         "tx_bytes",
35         "rx_bytes",
36         "tx_pause",
37         "rx_pause",
38         "rx_errors",
39         "tx_errors",
40         "rx_unicast",
41         "rx_multicast",
42         "rx_broadcast",
43         "tx_discards",
44         "tx_unicast",
45         "tx_multicast",
46         "tx_broadcast",
47         "ether_drops",
48         "rx_total_bytes",
49         "rx_total_packets",
50         "rx_undersize",
51         "rx_oversize",
52         "rx_64_bytes",
53         "rx_65_127_bytes",
54         "rx_128_255_bytes",
55         "rx_256_511_bytes",
56         "rx_512_1023_bytes",
57         "rx_1024_1518_bytes",
58         "rx_gte_1519_bytes",
59         "rx_jabbers",
60         "rx_runts",
61 };
62
63 static void tse_get_drvinfo(struct net_device *dev,
64                             struct ethtool_drvinfo *info)
65 {
66         struct altera_tse_private *priv = netdev_priv(dev);
67         u32 rev = ioread32(&priv->mac_dev->megacore_revision);
68
69         strcpy(info->driver, "altera_tse");
70         snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d",
71                  rev & 0xFFFF, (rev & 0xFFFF0000) >> 16);
72         sprintf(info->bus_info, "platform");
73 }
74
75 /* Fill in a buffer with the strings which correspond to the
76  * stats
77  */
78 static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf)
79 {
80         memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN);
81 }
82
83 static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
84                            u64 *buf)
85 {
86         struct altera_tse_private *priv = netdev_priv(dev);
87         u64 ext;
88
89         buf[0] = csrrd32(priv->mac_dev,
90                          tse_csroffs(frames_transmitted_ok));
91         buf[1] = csrrd32(priv->mac_dev,
92                          tse_csroffs(frames_received_ok));
93         buf[2] = csrrd32(priv->mac_dev,
94                          tse_csroffs(frames_check_sequence_errors));
95         buf[3] = csrrd32(priv->mac_dev,
96                          tse_csroffs(alignment_errors));
97
98         /* Extended aOctetsTransmittedOK counter */
99         ext = (u64) csrrd32(priv->mac_dev,
100                             tse_csroffs(msb_octets_transmitted_ok)) << 32;
101
102         ext |= csrrd32(priv->mac_dev,
103                        tse_csroffs(octets_transmitted_ok));
104         buf[4] = ext;
105
106         /* Extended aOctetsReceivedOK counter */
107         ext = (u64) csrrd32(priv->mac_dev,
108                             tse_csroffs(msb_octets_received_ok)) << 32;
109
110         ext |= csrrd32(priv->mac_dev,
111                        tse_csroffs(octets_received_ok));
112         buf[5] = ext;
113
114         buf[6] = csrrd32(priv->mac_dev,
115                          tse_csroffs(tx_pause_mac_ctrl_frames));
116         buf[7] = csrrd32(priv->mac_dev,
117                          tse_csroffs(rx_pause_mac_ctrl_frames));
118         buf[8] = csrrd32(priv->mac_dev,
119                          tse_csroffs(if_in_errors));
120         buf[9] = csrrd32(priv->mac_dev,
121                          tse_csroffs(if_out_errors));
122         buf[10] = csrrd32(priv->mac_dev,
123                           tse_csroffs(if_in_ucast_pkts));
124         buf[11] = csrrd32(priv->mac_dev,
125                           tse_csroffs(if_in_multicast_pkts));
126         buf[12] = csrrd32(priv->mac_dev,
127                           tse_csroffs(if_in_broadcast_pkts));
128         buf[13] = csrrd32(priv->mac_dev,
129                           tse_csroffs(if_out_discards));
130         buf[14] = csrrd32(priv->mac_dev,
131                           tse_csroffs(if_out_ucast_pkts));
132         buf[15] = csrrd32(priv->mac_dev,
133                           tse_csroffs(if_out_multicast_pkts));
134         buf[16] = csrrd32(priv->mac_dev,
135                           tse_csroffs(if_out_broadcast_pkts));
136         buf[17] = csrrd32(priv->mac_dev,
137                           tse_csroffs(ether_stats_drop_events));
138
139         /* Extended etherStatsOctets counter */
140         ext = (u64) csrrd32(priv->mac_dev,
141                             tse_csroffs(msb_ether_stats_octets)) << 32;
142         ext |= csrrd32(priv->mac_dev,
143                        tse_csroffs(ether_stats_octets));
144         buf[18] = ext;
145
146         buf[19] = csrrd32(priv->mac_dev,
147                           tse_csroffs(ether_stats_pkts));
148         buf[20] = csrrd32(priv->mac_dev,
149                           tse_csroffs(ether_stats_undersize_pkts));
150         buf[21] = csrrd32(priv->mac_dev,
151                           tse_csroffs(ether_stats_oversize_pkts));
152         buf[22] = csrrd32(priv->mac_dev,
153                           tse_csroffs(ether_stats_pkts_64_octets));
154         buf[23] = csrrd32(priv->mac_dev,
155                           tse_csroffs(ether_stats_pkts_65to127_octets));
156         buf[24] = csrrd32(priv->mac_dev,
157                           tse_csroffs(ether_stats_pkts_128to255_octets));
158         buf[25] = csrrd32(priv->mac_dev,
159                           tse_csroffs(ether_stats_pkts_256to511_octets));
160         buf[26] = csrrd32(priv->mac_dev,
161                           tse_csroffs(ether_stats_pkts_512to1023_octets));
162         buf[27] = csrrd32(priv->mac_dev,
163                           tse_csroffs(ether_stats_pkts_1024to1518_octets));
164         buf[28] = csrrd32(priv->mac_dev,
165                           tse_csroffs(ether_stats_pkts_1519tox_octets));
166         buf[29] = csrrd32(priv->mac_dev,
167                           tse_csroffs(ether_stats_jabbers));
168         buf[30] = csrrd32(priv->mac_dev,
169                           tse_csroffs(ether_stats_fragments));
170 }
171
172 static int tse_sset_count(struct net_device *dev, int sset)
173 {
174         switch (sset) {
175         case ETH_SS_STATS:
176                 return TSE_STATS_LEN;
177         default:
178                 return -EOPNOTSUPP;
179         }
180 }
181
182 static u32 tse_get_msglevel(struct net_device *dev)
183 {
184         struct altera_tse_private *priv = netdev_priv(dev);
185         return priv->msg_enable;
186 }
187
188 static void tse_set_msglevel(struct net_device *dev, uint32_t data)
189 {
190         struct altera_tse_private *priv = netdev_priv(dev);
191         priv->msg_enable = data;
192 }
193
194 static int tse_reglen(struct net_device *dev)
195 {
196         return TSE_NUM_REGS * sizeof(u32);
197 }
198
199 static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs,
200                          void *regbuf)
201 {
202         int i;
203         struct altera_tse_private *priv = netdev_priv(dev);
204         u32 *buf = regbuf;
205
206         /* Set version to a known value, so ethtool knows
207          * how to do any special formatting of this data.
208          * This version number will need to change if and
209          * when this register table is changed.
210          *
211          * version[31:0] = 1: Dump the first 128 TSE Registers
212          *      Upper bits are all 0 by default
213          *
214          * Upper 16-bits will indicate feature presence for
215          * Ethtool register decoding in future version.
216          */
217
218         regs->version = 1;
219
220         for (i = 0; i < TSE_NUM_REGS; i++)
221                 buf[i] = csrrd32(priv->mac_dev, i * 4);
222 }
223
224 static const struct ethtool_ops tse_ethtool_ops = {
225         .get_drvinfo = tse_get_drvinfo,
226         .get_regs_len = tse_reglen,
227         .get_regs = tse_get_regs,
228         .get_link = ethtool_op_get_link,
229         .get_strings = tse_gstrings,
230         .get_sset_count = tse_sset_count,
231         .get_ethtool_stats = tse_fill_stats,
232         .get_msglevel = tse_get_msglevel,
233         .set_msglevel = tse_set_msglevel,
234         .get_link_ksettings = phy_ethtool_get_link_ksettings,
235         .set_link_ksettings = phy_ethtool_set_link_ksettings,
236 };
237
238 void altera_tse_set_ethtool_ops(struct net_device *netdev)
239 {
240         netdev->ethtool_ops = &tse_ethtool_ops;
241 }