GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / ethernet / marvell / octeon_ep / octep_ethtool.c
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
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
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
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
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 < oct->num_oqs; q++) {
161                 struct octep_iq *iq = oct->iq[q];
162                 struct octep_oq *oq = oct->oq[q];
163
164                 tx_packets += iq->stats.instr_completed;
165                 tx_bytes += iq->stats.bytes_sent;
166                 tx_busy_errors += iq->stats.tx_busy;
167
168                 rx_packets += oq->stats.packets;
169                 rx_bytes += oq->stats.bytes;
170                 rx_alloc_errors += oq->stats.alloc_failures;
171         }
172         i = 0;
173         data[i++] = rx_packets;
174         data[i++] = tx_packets;
175         data[i++] = rx_bytes;
176         data[i++] = tx_bytes;
177         data[i++] = rx_alloc_errors;
178         data[i++] = tx_busy_errors;
179         data[i++] = iface_rx_stats->dropped_pkts_fifo_full +
180                     iface_rx_stats->err_pkts;
181         data[i++] = iface_tx_stats->xscol +
182                     iface_tx_stats->xsdef;
183         data[i++] = iface_tx_stats->pkts;
184         data[i++] = iface_tx_stats->octs;
185         data[i++] = iface_tx_stats->bcst;
186         data[i++] = iface_tx_stats->mcst;
187         data[i++] = iface_tx_stats->undflw;
188         data[i++] = iface_tx_stats->ctl;
189         data[i++] = iface_tx_stats->hist_lt64;
190         data[i++] = iface_tx_stats->hist_eq64;
191         data[i++] = iface_tx_stats->hist_65to127;
192         data[i++] = iface_tx_stats->hist_128to255;
193         data[i++] = iface_tx_stats->hist_256to511;
194         data[i++] = iface_tx_stats->hist_512to1023;
195         data[i++] = iface_tx_stats->hist_1024to1518;
196         data[i++] = iface_tx_stats->hist_gt1518;
197         data[i++] = iface_rx_stats->pkts;
198         data[i++] = iface_rx_stats->octets;
199         data[i++] = iface_rx_stats->mcast_pkts;
200         data[i++] = iface_rx_stats->bcast_pkts;
201         data[i++] = iface_rx_stats->pause_pkts;
202         data[i++] = iface_rx_stats->pause_octets;
203         data[i++] = iface_rx_stats->dropped_pkts_fifo_full;
204         data[i++] = iface_rx_stats->dropped_octets_fifo_full;
205         data[i++] = iface_rx_stats->err_pkts;
206
207         /* Per Tx Queue stats */
208         for (q = 0; q < oct->num_iqs; q++) {
209                 struct octep_iq *iq = oct->iq[q];
210
211                 data[i++] = iq->stats.instr_posted;
212                 data[i++] = iq->stats.instr_completed;
213                 data[i++] = iq->stats.bytes_sent;
214                 data[i++] = iq->stats.tx_busy;
215         }
216
217         /* Per Rx Queue stats */
218         for (q = 0; q < oct->num_oqs; q++) {
219                 struct octep_oq *oq = oct->oq[q];
220
221                 data[i++] = oq->stats.packets;
222                 data[i++] = oq->stats.bytes;
223                 data[i++] = oq->stats.alloc_failures;
224         }
225 }
226
227 #define OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(octep_speeds, ksettings, name) \
228 { \
229         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_T)) \
230                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseT_Full); \
231         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_R)) \
232                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseR_FEC); \
233         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_CR)) \
234                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseCR_Full); \
235         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_KR)) \
236                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseKR_Full); \
237         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_LR)) \
238                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseLR_Full); \
239         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_SR)) \
240                 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseSR_Full); \
241         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_CR)) \
242                 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseCR_Full); \
243         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_KR)) \
244                 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseKR_Full); \
245         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_SR)) \
246                 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseSR_Full); \
247         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_CR4)) \
248                 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseCR4_Full); \
249         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_KR4)) \
250                 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseKR4_Full); \
251         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_LR4)) \
252                 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseLR4_Full); \
253         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_SR4)) \
254                 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseSR4_Full); \
255         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR2)) \
256                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR2_Full); \
257         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR2)) \
258                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR2_Full); \
259         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR2)) \
260                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR2_Full); \
261         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR)) \
262                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR_Full); \
263         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR)) \
264                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR_Full); \
265         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_LR)) \
266                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseLR_ER_FR_Full); \
267         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR)) \
268                 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR_Full); \
269         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_CR4)) \
270                 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseCR4_Full); \
271         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_KR4)) \
272                 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseKR4_Full); \
273         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_LR4)) \
274                 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseLR4_ER4_Full); \
275         if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_SR4)) \
276                 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseSR4_Full); \
277 }
278
279 static int octep_get_link_ksettings(struct net_device *netdev,
280                                     struct ethtool_link_ksettings *cmd)
281 {
282         struct octep_device *oct = netdev_priv(netdev);
283         struct octep_iface_link_info *link_info;
284         u32 advertised_modes, supported_modes;
285
286         ethtool_link_ksettings_zero_link_mode(cmd, supported);
287         ethtool_link_ksettings_zero_link_mode(cmd, advertising);
288
289         link_info = &oct->link_info;
290         octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, link_info);
291
292         advertised_modes = oct->link_info.advertised_modes;
293         supported_modes = oct->link_info.supported_modes;
294
295         OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(supported_modes, cmd, supported);
296         OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(advertised_modes, cmd, advertising);
297
298         if (link_info->autoneg) {
299                 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED)
300                         ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
301                 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_ADVERTISED) {
302                         ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
303                         cmd->base.autoneg = AUTONEG_ENABLE;
304                 } else {
305                         cmd->base.autoneg = AUTONEG_DISABLE;
306                 }
307         } else {
308                 cmd->base.autoneg = AUTONEG_DISABLE;
309         }
310
311         if (link_info->pause) {
312                 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_SUPPORTED)
313                         ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
314                 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_ADVERTISED)
315                         ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
316         }
317
318         cmd->base.port = PORT_FIBRE;
319         ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
320         ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
321
322         if (netif_carrier_ok(netdev)) {
323                 cmd->base.speed = link_info->speed;
324                 cmd->base.duplex = DUPLEX_FULL;
325         } else {
326                 cmd->base.speed = SPEED_UNKNOWN;
327                 cmd->base.duplex = DUPLEX_UNKNOWN;
328         }
329         return 0;
330 }
331
332 static int octep_set_link_ksettings(struct net_device *netdev,
333                                     const struct ethtool_link_ksettings *cmd)
334 {
335         struct octep_device *oct = netdev_priv(netdev);
336         struct octep_iface_link_info link_info_new;
337         struct octep_iface_link_info *link_info;
338         u64 advertised = 0;
339         u8 autoneg = 0;
340         int err;
341
342         link_info = &oct->link_info;
343         memcpy(&link_info_new, link_info, sizeof(struct octep_iface_link_info));
344
345         /* Only Full duplex is supported;
346          * Assume full duplex when duplex is unknown.
347          */
348         if (cmd->base.duplex != DUPLEX_FULL &&
349             cmd->base.duplex != DUPLEX_UNKNOWN)
350                 return -EOPNOTSUPP;
351
352         if (cmd->base.autoneg == AUTONEG_ENABLE) {
353                 if (!(link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED))
354                         return -EOPNOTSUPP;
355                 autoneg = 1;
356         }
357
358         if (!bitmap_subset(cmd->link_modes.advertising,
359                            cmd->link_modes.supported,
360                            __ETHTOOL_LINK_MODE_MASK_NBITS))
361                 return -EINVAL;
362
363         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
364                                                   10000baseT_Full))
365                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_T);
366         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
367                                                   10000baseR_FEC))
368                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_R);
369         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
370                                                   10000baseCR_Full))
371                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_CR);
372         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
373                                                   10000baseKR_Full))
374                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_KR);
375         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
376                                                   10000baseLR_Full))
377                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_LR);
378         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
379                                                   10000baseSR_Full))
380                 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_SR);
381         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
382                                                   25000baseCR_Full))
383                 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_CR);
384         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
385                                                   25000baseKR_Full))
386                 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_KR);
387         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
388                                                   25000baseSR_Full))
389                 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_SR);
390         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
391                                                   40000baseCR4_Full))
392                 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_CR4);
393         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
394                                                   40000baseKR4_Full))
395                 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_KR4);
396         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
397                                                   40000baseLR4_Full))
398                 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_LR4);
399         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
400                                                   40000baseSR4_Full))
401                 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_SR4);
402         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
403                                                   50000baseCR2_Full))
404                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR2);
405         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
406                                                   50000baseKR2_Full))
407                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR2);
408         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
409                                                   50000baseSR2_Full))
410                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR2);
411         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
412                                                   50000baseCR_Full))
413                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR);
414         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
415                                                   50000baseKR_Full))
416                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR);
417         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
418                                                   50000baseLR_ER_FR_Full))
419                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_LR);
420         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
421                                                   50000baseSR_Full))
422                 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR);
423         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
424                                                   100000baseCR4_Full))
425                 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_CR4);
426         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
427                                                   100000baseKR4_Full))
428                 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_KR4);
429         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
430                                                   100000baseLR4_ER4_Full))
431                 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_LR4);
432         if (ethtool_link_ksettings_test_link_mode(cmd, advertising,
433                                                   100000baseSR4_Full))
434                 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_SR4);
435
436         if (advertised == link_info->advertised_modes &&
437             cmd->base.speed == link_info->speed &&
438             cmd->base.autoneg == link_info->autoneg)
439                 return 0;
440
441         link_info_new.advertised_modes = advertised;
442         link_info_new.speed = cmd->base.speed;
443         link_info_new.autoneg = autoneg;
444
445         err = octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID,
446                                            &link_info_new, true);
447         if (err)
448                 return err;
449
450         memcpy(link_info, &link_info_new, sizeof(struct octep_iface_link_info));
451         return 0;
452 }
453
454 static const struct ethtool_ops octep_ethtool_ops = {
455         .get_drvinfo = octep_get_drvinfo,
456         .get_link = ethtool_op_get_link,
457         .get_strings = octep_get_strings,
458         .get_sset_count = octep_get_sset_count,
459         .get_ethtool_stats = octep_get_ethtool_stats,
460         .get_link_ksettings = octep_get_link_ksettings,
461         .set_link_ksettings = octep_set_link_ksettings,
462 };
463
464 void octep_set_ethtool_ops(struct net_device *netdev)
465 {
466         netdev->ethtool_ops = &octep_ethtool_ops;
467 }