1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell Octeon EP (EndPoint) Ethernet Driver
3 *
4 * Copyright (C) 2020 Marvell.
5 *
6 */
7
8 #include <linux/pci.h>
9 #include <linux/netdevice.h>
10 #include <linux/ethtool.h>
11
12 #include "octep_config.h"
13 #include "octep_main.h"
14 #include "octep_ctrl_net.h"
15
16 static const char octep_gstrings_global_stats[][ETH_GSTRING_LEN] = {
17 "rx_packets",
18 "tx_packets",
19 "rx_bytes",
20 "tx_bytes",
21 "rx_alloc_errors",
22 "tx_busy_errors",
23 "rx_dropped",
24 "tx_dropped",
25 "tx_hw_pkts",
26 "tx_hw_octs",
27 "tx_hw_bcast",
28 "tx_hw_mcast",
29 "tx_hw_underflow",
30 "tx_hw_control",
31 "tx_less_than_64",
32 "tx_equal_64",
33 "tx_equal_65_to_127",
34 "tx_equal_128_to_255",
35 "tx_equal_256_to_511",
36 "tx_equal_512_to_1023",
37 "tx_equal_1024_to_1518",
38 "tx_greater_than_1518",
39 "rx_hw_pkts",
40 "rx_hw_bytes",
41 "rx_hw_bcast",
42 "rx_hw_mcast",
43 "rx_pause_pkts",
44 "rx_pause_bytes",
45 "rx_dropped_pkts_fifo_full",
46 "rx_dropped_bytes_fifo_full",
47 "rx_err_pkts",
48 };
49
50 #define OCTEP_GLOBAL_STATS_CNT (sizeof(octep_gstrings_global_stats) / ETH_GSTRING_LEN)
51
52 static const char octep_gstrings_tx_q_stats[][ETH_GSTRING_LEN] = {
53 "tx_packets_posted[Q-%u]",
54 "tx_packets_completed[Q-%u]",
55 "tx_bytes[Q-%u]",
56 "tx_busy[Q-%u]",
57 };
58
59 #define OCTEP_TX_Q_STATS_CNT (sizeof(octep_gstrings_tx_q_stats) / ETH_GSTRING_LEN)
60
61 static const char octep_gstrings_rx_q_stats[][ETH_GSTRING_LEN] = {
62 "rx_packets[Q-%u]",
63 "rx_bytes[Q-%u]",
64 "rx_alloc_errors[Q-%u]",
65 };
66
67 #define OCTEP_RX_Q_STATS_CNT (sizeof(octep_gstrings_rx_q_stats) / ETH_GSTRING_LEN)
68
octep_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * info)69 static void octep_get_drvinfo(struct net_device *netdev,
70 struct ethtool_drvinfo *info)
71 {
72 struct octep_device *oct = netdev_priv(netdev);
73
74 strscpy(info->driver, OCTEP_DRV_NAME, sizeof(info->driver));
75 strscpy(info->bus_info, pci_name(oct->pdev), sizeof(info->bus_info));
76 }
77
octep_get_strings(struct net_device * netdev,u32 stringset,u8 * data)78 static void octep_get_strings(struct net_device *netdev,
79 u32 stringset, u8 *data)
80 {
81 struct octep_device *oct = netdev_priv(netdev);
82 u16 num_queues = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
83 char *strings = (char *)data;
84 int i, j;
85
86 switch (stringset) {
87 case ETH_SS_STATS:
88 for (i = 0; i < OCTEP_GLOBAL_STATS_CNT; i++) {
89 snprintf(strings, ETH_GSTRING_LEN,
90 octep_gstrings_global_stats[i]);
91 strings += ETH_GSTRING_LEN;
92 }
93
94 for (i = 0; i < num_queues; i++) {
95 for (j = 0; j < OCTEP_TX_Q_STATS_CNT; j++) {
96 snprintf(strings, ETH_GSTRING_LEN,
97 octep_gstrings_tx_q_stats[j], i);
98 strings += ETH_GSTRING_LEN;
99 }
100 }
101
102 for (i = 0; i < num_queues; i++) {
103 for (j = 0; j < OCTEP_RX_Q_STATS_CNT; j++) {
104 snprintf(strings, ETH_GSTRING_LEN,
105 octep_gstrings_rx_q_stats[j], i);
106 strings += ETH_GSTRING_LEN;
107 }
108 }
109 break;
110 default:
111 break;
112 }
113 }
114
octep_get_sset_count(struct net_device * netdev,int sset)115 static int octep_get_sset_count(struct net_device *netdev, int sset)
116 {
117 struct octep_device *oct = netdev_priv(netdev);
118 u16 num_queues = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf);
119
120 switch (sset) {
121 case ETH_SS_STATS:
122 return OCTEP_GLOBAL_STATS_CNT + (num_queues *
123 (OCTEP_TX_Q_STATS_CNT + OCTEP_RX_Q_STATS_CNT));
124 break;
125 default:
126 return -EOPNOTSUPP;
127 }
128 }
129
130 static void
octep_get_ethtool_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)131 octep_get_ethtool_stats(struct net_device *netdev,
132 struct ethtool_stats *stats, u64 *data)
133 {
134 struct octep_device *oct = netdev_priv(netdev);
135 struct octep_iface_tx_stats *iface_tx_stats;
136 struct octep_iface_rx_stats *iface_rx_stats;
137 u64 rx_packets, rx_bytes;
138 u64 tx_packets, tx_bytes;
139 u64 rx_alloc_errors, tx_busy_errors;
140 int q, i;
141
142 rx_packets = 0;
143 rx_bytes = 0;
144 tx_packets = 0;
145 tx_bytes = 0;
146 rx_alloc_errors = 0;
147 tx_busy_errors = 0;
148 tx_packets = 0;
149 tx_bytes = 0;
150 rx_packets = 0;
151 rx_bytes = 0;
152
153 iface_tx_stats = &oct->iface_tx_stats;
154 iface_rx_stats = &oct->iface_rx_stats;
155 octep_ctrl_net_get_if_stats(oct,
156 OCTEP_CTRL_NET_INVALID_VFID,
157 iface_rx_stats,
158 iface_tx_stats);
159
160 for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
161 tx_packets += oct->stats_iq[q].instr_completed;
162 tx_bytes += oct->stats_iq[q].bytes_sent;
163 tx_busy_errors += oct->stats_iq[q].tx_busy;
164
165 rx_packets += oct->stats_oq[q].packets;
166 rx_bytes += oct->stats_oq[q].bytes;
167 rx_alloc_errors += oct->stats_oq[q].alloc_failures;
168 }
169 i = 0;
170 data[i++] = rx_packets;
171 data[i++] = tx_packets;
172 data[i++] = rx_bytes;
173 data[i++] = tx_bytes;
174 data[i++] = rx_alloc_errors;
175 data[i++] = tx_busy_errors;
176 data[i++] = iface_rx_stats->dropped_pkts_fifo_full +
177 iface_rx_stats->err_pkts;
178 data[i++] = iface_tx_stats->xscol +
179 iface_tx_stats->xsdef;
180 data[i++] = iface_tx_stats->pkts;
181 data[i++] = iface_tx_stats->octs;
182 data[i++] = iface_tx_stats->bcst;
183 data[i++] = iface_tx_stats->mcst;
184 data[i++] = iface_tx_stats->undflw;
185 data[i++] = iface_tx_stats->ctl;
186 data[i++] = iface_tx_stats->hist_lt64;
187 data[i++] = iface_tx_stats->hist_eq64;
188 data[i++] = iface_tx_stats->hist_65to127;
189 data[i++] = iface_tx_stats->hist_128to255;
190 data[i++] = iface_tx_stats->hist_256to511;
191 data[i++] = iface_tx_stats->hist_512to1023;
192 data[i++] = iface_tx_stats->hist_1024to1518;
193 data[i++] = iface_tx_stats->hist_gt1518;
194 data[i++] = iface_rx_stats->pkts;
195 data[i++] = iface_rx_stats->octets;
196 data[i++] = iface_rx_stats->mcast_pkts;
197 data[i++] = iface_rx_stats->bcast_pkts;
198 data[i++] = iface_rx_stats->pause_pkts;
199 data[i++] = iface_rx_stats->pause_octets;
200 data[i++] = iface_rx_stats->dropped_pkts_fifo_full;
201 data[i++] = iface_rx_stats->dropped_octets_fifo_full;
202 data[i++] = iface_rx_stats->err_pkts;
203
204 /* Per Tx Queue stats */
205 for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
206 data[i++] = oct->stats_iq[q].instr_posted;
207 data[i++] = oct->stats_iq[q].instr_completed;
208 data[i++] = oct->stats_iq[q].bytes_sent;
209 data[i++] = oct->stats_iq[q].tx_busy;
210 }
211
212 /* Per Rx Queue stats */
213 for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
214 data[i++] = oct->stats_oq[q].packets;
215 data[i++] = oct->stats_oq[q].bytes;
216 data[i++] = oct->stats_oq[q].alloc_failures;
217 }
218 }
219
220 #define OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(octep_speeds, ksettings, name) \
221 { \
222 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_T)) \
223 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseT_Full); \
224 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_R)) \
225 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseR_FEC); \
226 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_CR)) \
227 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseCR_Full); \
228 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_KR)) \
229 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseKR_Full); \
230 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_LR)) \
231 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseLR_Full); \
232 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_SR)) \
233 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseSR_Full); \
234 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_CR)) \
235 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseCR_Full); \
236 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_KR)) \
237 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseKR_Full); \
238 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_SR)) \
239 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseSR_Full); \
240 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_CR4)) \
241 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseCR4_Full); \
242 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_KR4)) \
243 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseKR4_Full); \
244 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_LR4)) \
245 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseLR4_Full); \
246 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_SR4)) \
247 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseSR4_Full); \
248 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR2)) \
249 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR2_Full); \
250 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR2)) \
251 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR2_Full); \
252 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR2)) \
253 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR2_Full); \
254 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR)) \
255 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR_Full); \
256 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR)) \
257 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR_Full); \
258 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_LR)) \
259 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseLR_ER_FR_Full); \
260 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR)) \
261 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR_Full); \
262 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_CR4)) \
263 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseCR4_Full); \
264 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_KR4)) \
265 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseKR4_Full); \
266 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_LR4)) \
267 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseLR4_ER4_Full); \
268 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_SR4)) \
269 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseSR4_Full); \
270 }
271
octep_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * cmd)272 static int octep_get_link_ksettings(struct net_device *netdev,
273 struct ethtool_link_ksettings *cmd)
274 {
275 struct octep_device *oct = netdev_priv(netdev);
276 struct octep_iface_link_info *link_info;
277 u32 advertised_modes, supported_modes;
278
279 ethtool_link_ksettings_zero_link_mode(cmd, supported);
280 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
281
282 link_info = &oct->link_info;
283 octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, link_info);
284
285 advertised_modes = oct->link_info.advertised_modes;
286 supported_modes = oct->link_info.supported_modes;
287
288 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(supported_modes, cmd, supported);
289 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(advertised_modes, cmd, advertising);
290
291 if (link_info->autoneg) {
292 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED)
293 ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
294 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_ADVERTISED) {
295 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
296 cmd->base.autoneg = AUTONEG_ENABLE;
297 } else {
298 cmd->base.autoneg = AUTONEG_DISABLE;
299 }
300 } else {
301 cmd->base.autoneg = AUTONEG_DISABLE;
302 }
303
304 if (link_info->pause) {
305 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_SUPPORTED)
306 ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
307 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_ADVERTISED)
308 ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
309 }
310
311 cmd->base.port = PORT_FIBRE;
312 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
313 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
314
315 if (netif_carrier_ok(netdev)) {
316 cmd->base.speed = link_info->speed;
317 cmd->base.duplex = DUPLEX_FULL;
318 } else {
319 cmd->base.speed = SPEED_UNKNOWN;
320 cmd->base.duplex = DUPLEX_UNKNOWN;
321 }
322 return 0;
323 }
324
octep_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * cmd)325 static int octep_set_link_ksettings(struct net_device *netdev,
326 const struct ethtool_link_ksettings *cmd)
327 {
328 struct octep_device *oct = netdev_priv(netdev);
329 struct octep_iface_link_info link_info_new;
330 struct octep_iface_link_info *link_info;
331 u64 advertised = 0;
332 u8 autoneg = 0;
333 int err;
334
335 link_info = &oct->link_info;
336 memcpy(&link_info_new, link_info, sizeof(struct octep_iface_link_info));
337
338 /* Only Full duplex is supported;
339 * Assume full duplex when duplex is unknown.
340 */
341 if (cmd->base.duplex != DUPLEX_FULL &&
342 cmd->base.duplex != DUPLEX_UNKNOWN)
343 return -EOPNOTSUPP;
344
345 if (cmd->base.autoneg == AUTONEG_ENABLE) {
346 if (!(link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED))
347 return -EOPNOTSUPP;
348 autoneg = 1;
349 }
350
351 if (!bitmap_subset(cmd->link_modes.advertising,
352 cmd->link_modes.supported,
353 __ETHTOOL_LINK_MODE_MASK_NBITS))
354 return -EINVAL;
355
356 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
357 10000baseT_Full))
358 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_T);
359 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
360 10000baseR_FEC))
361 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_R);
362 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
363 10000baseCR_Full))
364 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_CR);
365 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
366 10000baseKR_Full))
367 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_KR);
368 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
369 10000baseLR_Full))
370 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_LR);
371 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
372 10000baseSR_Full))
373 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_SR);
374 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
375 25000baseCR_Full))
376 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_CR);
377 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
378 25000baseKR_Full))
379 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_KR);
380 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
381 25000baseSR_Full))
382 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_SR);
383 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
384 40000baseCR4_Full))
385 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_CR4);
386 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
387 40000baseKR4_Full))
388 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_KR4);
389 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
390 40000baseLR4_Full))
391 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_LR4);
392 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
393 40000baseSR4_Full))
394 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_SR4);
395 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
396 50000baseCR2_Full))
397 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR2);
398 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
399 50000baseKR2_Full))
400 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR2);
401 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
402 50000baseSR2_Full))
403 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR2);
404 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
405 50000baseCR_Full))
406 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR);
407 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
408 50000baseKR_Full))
409 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR);
410 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
411 50000baseLR_ER_FR_Full))
412 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_LR);
413 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
414 50000baseSR_Full))
415 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR);
416 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
417 100000baseCR4_Full))
418 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_CR4);
419 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
420 100000baseKR4_Full))
421 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_KR4);
422 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
423 100000baseLR4_ER4_Full))
424 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_LR4);
425 if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
426 100000baseSR4_Full))
427 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_SR4);
428
429 if (advertised == link_info->advertised_modes &&
430 cmd->base.speed == link_info->speed &&
431 cmd->base.autoneg == link_info->autoneg)
432 return 0;
433
434 link_info_new.advertised_modes = advertised;
435 link_info_new.speed = cmd->base.speed;
436 link_info_new.autoneg = autoneg;
437
438 err = octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID,
439 &link_info_new, true);
440 if (err)
441 return err;
442
443 memcpy(link_info, &link_info_new, sizeof(struct octep_iface_link_info));
444 return 0;
445 }
446
447 static const struct ethtool_ops octep_ethtool_ops = {
448 .get_drvinfo = octep_get_drvinfo,
449 .get_link = ethtool_op_get_link,
450 .get_strings = octep_get_strings,
451 .get_sset_count = octep_get_sset_count,
452 .get_ethtool_stats = octep_get_ethtool_stats,
453 .get_link_ksettings = octep_get_link_ksettings,
454 .set_link_ksettings = octep_set_link_ksettings,
455 };
456
octep_set_ethtool_ops(struct net_device * netdev)457 void octep_set_ethtool_ops(struct net_device *netdev)
458 {
459 netdev->ethtool_ops = &octep_ethtool_ops;
460 }
461