1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/ethtool.h>
14#include <linux/phy.h>
15
16#include "emac.h"
17
18static const char * const emac_ethtool_stat_strings[] = {
19 "rx_ok",
20 "rx_bcast",
21 "rx_mcast",
22 "rx_pause",
23 "rx_ctrl",
24 "rx_fcs_err",
25 "rx_len_err",
26 "rx_byte_cnt",
27 "rx_runt",
28 "rx_frag",
29 "rx_sz_64",
30 "rx_sz_65_127",
31 "rx_sz_128_255",
32 "rx_sz_256_511",
33 "rx_sz_512_1023",
34 "rx_sz_1024_1518",
35 "rx_sz_1519_max",
36 "rx_sz_ov",
37 "rx_rxf_ov",
38 "rx_align_err",
39 "rx_bcast_byte_cnt",
40 "rx_mcast_byte_cnt",
41 "rx_err_addr",
42 "rx_crc_align",
43 "rx_jabbers",
44 "tx_ok",
45 "tx_bcast",
46 "tx_mcast",
47 "tx_pause",
48 "tx_exc_defer",
49 "tx_ctrl",
50 "tx_defer",
51 "tx_byte_cnt",
52 "tx_sz_64",
53 "tx_sz_65_127",
54 "tx_sz_128_255",
55 "tx_sz_256_511",
56 "tx_sz_512_1023",
57 "tx_sz_1024_1518",
58 "tx_sz_1519_max",
59 "tx_1_col",
60 "tx_2_col",
61 "tx_late_col",
62 "tx_abort_col",
63 "tx_underrun",
64 "tx_rd_eop",
65 "tx_len_err",
66 "tx_trunc",
67 "tx_bcast_byte",
68 "tx_mcast_byte",
69 "tx_col",
70};
71
72#define EMAC_STATS_LEN ARRAY_SIZE(emac_ethtool_stat_strings)
73
74static u32 emac_get_msglevel(struct net_device *netdev)
75{
76 struct emac_adapter *adpt = netdev_priv(netdev);
77
78 return adpt->msg_enable;
79}
80
81static void emac_set_msglevel(struct net_device *netdev, u32 data)
82{
83 struct emac_adapter *adpt = netdev_priv(netdev);
84
85 adpt->msg_enable = data;
86}
87
88static int emac_get_sset_count(struct net_device *netdev, int sset)
89{
90 switch (sset) {
91 case ETH_SS_PRIV_FLAGS:
92 return 1;
93 case ETH_SS_STATS:
94 return EMAC_STATS_LEN;
95 default:
96 return -EOPNOTSUPP;
97 }
98}
99
100static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
101{
102 unsigned int i;
103
104 switch (stringset) {
105 case ETH_SS_PRIV_FLAGS:
106 strcpy(data, "single-pause-mode");
107 break;
108
109 case ETH_SS_STATS:
110 for (i = 0; i < EMAC_STATS_LEN; i++) {
111 strlcpy(data, emac_ethtool_stat_strings[i],
112 ETH_GSTRING_LEN);
113 data += ETH_GSTRING_LEN;
114 }
115 break;
116 }
117}
118
119static void emac_get_ethtool_stats(struct net_device *netdev,
120 struct ethtool_stats *stats,
121 u64 *data)
122{
123 struct emac_adapter *adpt = netdev_priv(netdev);
124
125 spin_lock(&adpt->stats.lock);
126
127 emac_update_hw_stats(adpt);
128 memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
129
130 spin_unlock(&adpt->stats.lock);
131}
132
133static int emac_nway_reset(struct net_device *netdev)
134{
135 struct phy_device *phydev = netdev->phydev;
136
137 if (!phydev)
138 return -ENODEV;
139
140 return genphy_restart_aneg(phydev);
141}
142
143static void emac_get_ringparam(struct net_device *netdev,
144 struct ethtool_ringparam *ring)
145{
146 struct emac_adapter *adpt = netdev_priv(netdev);
147
148 ring->rx_max_pending = EMAC_MAX_RX_DESCS;
149 ring->tx_max_pending = EMAC_MAX_TX_DESCS;
150 ring->rx_pending = adpt->rx_desc_cnt;
151 ring->tx_pending = adpt->tx_desc_cnt;
152}
153
154static int emac_set_ringparam(struct net_device *netdev,
155 struct ethtool_ringparam *ring)
156{
157 struct emac_adapter *adpt = netdev_priv(netdev);
158
159
160
161
162 if (ring->rx_mini_pending || ring->rx_jumbo_pending)
163 return -EINVAL;
164
165 adpt->tx_desc_cnt =
166 clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
167
168 adpt->rx_desc_cnt =
169 clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
170
171 if (netif_running(netdev))
172 return emac_reinit_locked(adpt);
173
174 return 0;
175}
176
177static void emac_get_pauseparam(struct net_device *netdev,
178 struct ethtool_pauseparam *pause)
179{
180 struct emac_adapter *adpt = netdev_priv(netdev);
181
182 pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
183 pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
184 pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
185}
186
187static int emac_set_pauseparam(struct net_device *netdev,
188 struct ethtool_pauseparam *pause)
189{
190 struct emac_adapter *adpt = netdev_priv(netdev);
191
192 adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
193 adpt->rx_flow_control = pause->rx_pause != 0;
194 adpt->tx_flow_control = pause->tx_pause != 0;
195
196 if (netif_running(netdev))
197 return emac_reinit_locked(adpt);
198
199 return 0;
200}
201
202
203static const u16 emac_regs[] = {
204 EMAC_DMA_MAS_CTRL,
205 EMAC_MAC_CTRL,
206 EMAC_TXQ_CTRL_0,
207 EMAC_RXQ_CTRL_0,
208 EMAC_DMA_CTRL,
209 EMAC_INT_MASK,
210 EMAC_AXI_MAST_CTRL,
211 EMAC_CORE_HW_VERSION,
212 EMAC_MISC_CTRL,
213};
214
215
216#define EMAC_REGS_VERSION 0
217
218#define EMAC_MAX_REG_SIZE ARRAY_SIZE(emac_regs)
219
220static void emac_get_regs(struct net_device *netdev,
221 struct ethtool_regs *regs, void *buff)
222{
223 struct emac_adapter *adpt = netdev_priv(netdev);
224 u32 *val = buff;
225 unsigned int i;
226
227 regs->version = EMAC_REGS_VERSION;
228 regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
229
230 for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
231 val[i] = readl(adpt->base + emac_regs[i]);
232}
233
234static int emac_get_regs_len(struct net_device *netdev)
235{
236 return EMAC_MAX_REG_SIZE * sizeof(u32);
237}
238
239#define EMAC_PRIV_ENABLE_SINGLE_PAUSE BIT(0)
240
241static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
242{
243 struct emac_adapter *adpt = netdev_priv(netdev);
244
245 adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
246
247 if (netif_running(netdev))
248 return emac_reinit_locked(adpt);
249
250 return 0;
251}
252
253static u32 emac_get_priv_flags(struct net_device *netdev)
254{
255 struct emac_adapter *adpt = netdev_priv(netdev);
256
257 return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
258}
259
260static const struct ethtool_ops emac_ethtool_ops = {
261 .get_link_ksettings = phy_ethtool_get_link_ksettings,
262 .set_link_ksettings = phy_ethtool_set_link_ksettings,
263
264 .get_msglevel = emac_get_msglevel,
265 .set_msglevel = emac_set_msglevel,
266
267 .get_sset_count = emac_get_sset_count,
268 .get_strings = emac_get_strings,
269 .get_ethtool_stats = emac_get_ethtool_stats,
270
271 .get_ringparam = emac_get_ringparam,
272 .set_ringparam = emac_set_ringparam,
273
274 .get_pauseparam = emac_get_pauseparam,
275 .set_pauseparam = emac_set_pauseparam,
276
277 .nway_reset = emac_nway_reset,
278
279 .get_link = ethtool_op_get_link,
280
281 .get_regs_len = emac_get_regs_len,
282 .get_regs = emac_get_regs,
283
284 .set_priv_flags = emac_set_priv_flags,
285 .get_priv_flags = emac_get_priv_flags,
286};
287
288void emac_set_ethtool_ops(struct net_device *netdev)
289{
290 netdev->ethtool_ops = &emac_ethtool_ops;
291}
292