Merge branch 'for-5.4/ish' into for-linus
[sfrench/cifs-2.6.git] / drivers / net / ethernet / netronome / nfp / nfp_net_ethtool.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2015-2018 Netronome Systems, Inc. */
3
4 /*
5  * nfp_net_ethtool.c
6  * Netronome network device driver: ethtool support
7  * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
8  *          Jason McMullan <jason.mcmullan@netronome.com>
9  *          Rolf Neugebauer <rolf.neugebauer@netronome.com>
10  *          Brad Petrus <brad.petrus@netronome.com>
11  */
12
13 #include <linux/bitfield.h>
14 #include <linux/kernel.h>
15 #include <linux/netdevice.h>
16 #include <linux/etherdevice.h>
17 #include <linux/interrupt.h>
18 #include <linux/pci.h>
19 #include <linux/ethtool.h>
20 #include <linux/firmware.h>
21 #include <linux/sfp.h>
22
23 #include "nfpcore/nfp.h"
24 #include "nfpcore/nfp_nsp.h"
25 #include "nfp_app.h"
26 #include "nfp_main.h"
27 #include "nfp_net_ctrl.h"
28 #include "nfp_net.h"
29 #include "nfp_port.h"
30
31 struct nfp_et_stat {
32         char name[ETH_GSTRING_LEN];
33         int off;
34 };
35
36 static const struct nfp_et_stat nfp_net_et_stats[] = {
37         /* Stats from the device */
38         { "dev_rx_discards",    NFP_NET_CFG_STATS_RX_DISCARDS },
39         { "dev_rx_errors",      NFP_NET_CFG_STATS_RX_ERRORS },
40         { "dev_rx_bytes",       NFP_NET_CFG_STATS_RX_OCTETS },
41         { "dev_rx_uc_bytes",    NFP_NET_CFG_STATS_RX_UC_OCTETS },
42         { "dev_rx_mc_bytes",    NFP_NET_CFG_STATS_RX_MC_OCTETS },
43         { "dev_rx_bc_bytes",    NFP_NET_CFG_STATS_RX_BC_OCTETS },
44         { "dev_rx_pkts",        NFP_NET_CFG_STATS_RX_FRAMES },
45         { "dev_rx_mc_pkts",     NFP_NET_CFG_STATS_RX_MC_FRAMES },
46         { "dev_rx_bc_pkts",     NFP_NET_CFG_STATS_RX_BC_FRAMES },
47
48         { "dev_tx_discards",    NFP_NET_CFG_STATS_TX_DISCARDS },
49         { "dev_tx_errors",      NFP_NET_CFG_STATS_TX_ERRORS },
50         { "dev_tx_bytes",       NFP_NET_CFG_STATS_TX_OCTETS },
51         { "dev_tx_uc_bytes",    NFP_NET_CFG_STATS_TX_UC_OCTETS },
52         { "dev_tx_mc_bytes",    NFP_NET_CFG_STATS_TX_MC_OCTETS },
53         { "dev_tx_bc_bytes",    NFP_NET_CFG_STATS_TX_BC_OCTETS },
54         { "dev_tx_pkts",        NFP_NET_CFG_STATS_TX_FRAMES },
55         { "dev_tx_mc_pkts",     NFP_NET_CFG_STATS_TX_MC_FRAMES },
56         { "dev_tx_bc_pkts",     NFP_NET_CFG_STATS_TX_BC_FRAMES },
57
58         { "bpf_pass_pkts",      NFP_NET_CFG_STATS_APP0_FRAMES },
59         { "bpf_pass_bytes",     NFP_NET_CFG_STATS_APP0_BYTES },
60         /* see comments in outro functions in nfp_bpf_jit.c to find out
61          * how different BPF modes use app-specific counters
62          */
63         { "bpf_app1_pkts",      NFP_NET_CFG_STATS_APP1_FRAMES },
64         { "bpf_app1_bytes",     NFP_NET_CFG_STATS_APP1_BYTES },
65         { "bpf_app2_pkts",      NFP_NET_CFG_STATS_APP2_FRAMES },
66         { "bpf_app2_bytes",     NFP_NET_CFG_STATS_APP2_BYTES },
67         { "bpf_app3_pkts",      NFP_NET_CFG_STATS_APP3_FRAMES },
68         { "bpf_app3_bytes",     NFP_NET_CFG_STATS_APP3_BYTES },
69 };
70
71 static const struct nfp_et_stat nfp_mac_et_stats[] = {
72         { "rx_octets",                  NFP_MAC_STATS_RX_IN_OCTETS, },
73         { "rx_frame_too_long_errors",
74                         NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS, },
75         { "rx_range_length_errors",     NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS, },
76         { "rx_vlan_received_ok",        NFP_MAC_STATS_RX_VLAN_RECEIVED_OK, },
77         { "rx_errors",                  NFP_MAC_STATS_RX_IN_ERRORS, },
78         { "rx_broadcast_pkts",          NFP_MAC_STATS_RX_IN_BROADCAST_PKTS, },
79         { "rx_drop_events",             NFP_MAC_STATS_RX_DROP_EVENTS, },
80         { "rx_alignment_errors",        NFP_MAC_STATS_RX_ALIGNMENT_ERRORS, },
81         { "rx_pause_mac_ctrl_frames",
82                         NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES, },
83         { "rx_frames_received_ok",      NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK, },
84         { "rx_frame_check_sequence_errors",
85                         NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS, },
86         { "rx_unicast_pkts",            NFP_MAC_STATS_RX_UNICAST_PKTS, },
87         { "rx_multicast_pkts",          NFP_MAC_STATS_RX_MULTICAST_PKTS, },
88         { "rx_pkts",                    NFP_MAC_STATS_RX_PKTS, },
89         { "rx_undersize_pkts",          NFP_MAC_STATS_RX_UNDERSIZE_PKTS, },
90         { "rx_pkts_64_octets",          NFP_MAC_STATS_RX_PKTS_64_OCTETS, },
91         { "rx_pkts_65_to_127_octets",
92                         NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS, },
93         { "rx_pkts_128_to_255_octets",
94                         NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS, },
95         { "rx_pkts_256_to_511_octets",
96                         NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS, },
97         { "rx_pkts_512_to_1023_octets",
98                         NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS, },
99         { "rx_pkts_1024_to_1518_octets",
100                         NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS, },
101         { "rx_pkts_1519_to_max_octets",
102                         NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS, },
103         { "rx_jabbers",                 NFP_MAC_STATS_RX_JABBERS, },
104         { "rx_fragments",               NFP_MAC_STATS_RX_FRAGMENTS, },
105         { "rx_oversize_pkts",           NFP_MAC_STATS_RX_OVERSIZE_PKTS, },
106         { "rx_pause_frames_class0",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0, },
107         { "rx_pause_frames_class1",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1, },
108         { "rx_pause_frames_class2",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2, },
109         { "rx_pause_frames_class3",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3, },
110         { "rx_pause_frames_class4",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS4, },
111         { "rx_pause_frames_class5",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS5, },
112         { "rx_pause_frames_class6",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS6, },
113         { "rx_pause_frames_class7",     NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7, },
114         { "rx_mac_ctrl_frames_received",
115                         NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED, },
116         { "rx_mac_head_drop",           NFP_MAC_STATS_RX_MAC_HEAD_DROP, },
117         { "tx_queue_drop",              NFP_MAC_STATS_TX_QUEUE_DROP, },
118         { "tx_octets",                  NFP_MAC_STATS_TX_OUT_OCTETS, },
119         { "tx_vlan_transmitted_ok",     NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, },
120         { "tx_errors",                  NFP_MAC_STATS_TX_OUT_ERRORS, },
121         { "tx_broadcast_pkts",          NFP_MAC_STATS_TX_BROADCAST_PKTS, },
122         { "tx_pause_mac_ctrl_frames",
123                         NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES, },
124         { "tx_frames_transmitted_ok",
125                         NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK, },
126         { "tx_unicast_pkts",            NFP_MAC_STATS_TX_UNICAST_PKTS, },
127         { "tx_multicast_pkts",          NFP_MAC_STATS_TX_MULTICAST_PKTS, },
128         { "tx_pkts_64_octets",          NFP_MAC_STATS_TX_PKTS_64_OCTETS, },
129         { "tx_pkts_65_to_127_octets",
130                         NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS, },
131         { "tx_pkts_128_to_255_octets",
132                         NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS, },
133         { "tx_pkts_256_to_511_octets",
134                         NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS, },
135         { "tx_pkts_512_to_1023_octets",
136                         NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS, },
137         { "tx_pkts_1024_to_1518_octets",
138                         NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS, },
139         { "tx_pkts_1519_to_max_octets",
140                         NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS, },
141         { "tx_pause_frames_class0",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0, },
142         { "tx_pause_frames_class1",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1, },
143         { "tx_pause_frames_class2",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2, },
144         { "tx_pause_frames_class3",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3, },
145         { "tx_pause_frames_class4",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4, },
146         { "tx_pause_frames_class5",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5, },
147         { "tx_pause_frames_class6",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6, },
148         { "tx_pause_frames_class7",     NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7, },
149 };
150
151 #define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
152 #define NN_ET_SWITCH_STATS_LEN 9
153 #define NN_RVEC_GATHER_STATS    13
154 #define NN_RVEC_PER_Q_STATS     3
155 #define NN_CTRL_PATH_STATS      1
156
157 #define SFP_SFF_REV_COMPLIANCE  1
158
159 static void nfp_net_get_nspinfo(struct nfp_app *app, char *version)
160 {
161         struct nfp_nsp *nsp;
162
163         if (!app)
164                 return;
165
166         nsp = nfp_nsp_open(app->cpp);
167         if (IS_ERR(nsp))
168                 return;
169
170         snprintf(version, ETHTOOL_FWVERS_LEN, "%hu.%hu",
171                  nfp_nsp_get_abi_ver_major(nsp),
172                  nfp_nsp_get_abi_ver_minor(nsp));
173
174         nfp_nsp_close(nsp);
175 }
176
177 static void
178 nfp_get_drvinfo(struct nfp_app *app, struct pci_dev *pdev,
179                 const char *vnic_version, struct ethtool_drvinfo *drvinfo)
180 {
181         char nsp_version[ETHTOOL_FWVERS_LEN] = {};
182
183         strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver));
184         strlcpy(drvinfo->version, nfp_driver_version, sizeof(drvinfo->version));
185
186         nfp_net_get_nspinfo(app, nsp_version);
187         snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
188                  "%s %s %s %s", vnic_version, nsp_version,
189                  nfp_app_mip_name(app), nfp_app_name(app));
190 }
191
192 static void
193 nfp_net_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
194 {
195         char vnic_version[ETHTOOL_FWVERS_LEN] = {};
196         struct nfp_net *nn = netdev_priv(netdev);
197
198         snprintf(vnic_version, sizeof(vnic_version), "%d.%d.%d.%d",
199                  nn->fw_ver.resv, nn->fw_ver.class,
200                  nn->fw_ver.major, nn->fw_ver.minor);
201         strlcpy(drvinfo->bus_info, pci_name(nn->pdev),
202                 sizeof(drvinfo->bus_info));
203
204         nfp_get_drvinfo(nn->app, nn->pdev, vnic_version, drvinfo);
205 }
206
207 static void
208 nfp_app_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
209 {
210         struct nfp_app *app = nfp_app_from_netdev(netdev);
211
212         strlcpy(drvinfo->bus_info, pci_name(app->pdev),
213                 sizeof(drvinfo->bus_info));
214         nfp_get_drvinfo(app, app->pdev, "*", drvinfo);
215 }
216
217 static void
218 nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
219                           struct ethtool_link_ksettings *c)
220 {
221         unsigned int modes;
222
223         ethtool_link_ksettings_add_link_mode(c, supported, FEC_NONE);
224         if (!nfp_eth_can_support_fec(eth_port)) {
225                 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_NONE);
226                 return;
227         }
228
229         modes = nfp_eth_supported_fec_modes(eth_port);
230         if (modes & NFP_FEC_BASER) {
231                 ethtool_link_ksettings_add_link_mode(c, supported, FEC_BASER);
232                 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_BASER);
233         }
234
235         if (modes & NFP_FEC_REED_SOLOMON) {
236                 ethtool_link_ksettings_add_link_mode(c, supported, FEC_RS);
237                 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_RS);
238         }
239 }
240
241 /**
242  * nfp_net_get_link_ksettings - Get Link Speed settings
243  * @netdev:     network interface device structure
244  * @cmd:        ethtool command
245  *
246  * Reports speed settings based on info in the BAR provided by the fw.
247  */
248 static int
249 nfp_net_get_link_ksettings(struct net_device *netdev,
250                            struct ethtool_link_ksettings *cmd)
251 {
252         static const u32 ls_to_ethtool[] = {
253                 [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0,
254                 [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN]     = SPEED_UNKNOWN,
255                 [NFP_NET_CFG_STS_LINK_RATE_1G]          = SPEED_1000,
256                 [NFP_NET_CFG_STS_LINK_RATE_10G]         = SPEED_10000,
257                 [NFP_NET_CFG_STS_LINK_RATE_25G]         = SPEED_25000,
258                 [NFP_NET_CFG_STS_LINK_RATE_40G]         = SPEED_40000,
259                 [NFP_NET_CFG_STS_LINK_RATE_50G]         = SPEED_50000,
260                 [NFP_NET_CFG_STS_LINK_RATE_100G]        = SPEED_100000,
261         };
262         struct nfp_eth_table_port *eth_port;
263         struct nfp_port *port;
264         struct nfp_net *nn;
265         u32 sts, ls;
266
267         /* Init to unknowns */
268         ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
269         cmd->base.port = PORT_OTHER;
270         cmd->base.speed = SPEED_UNKNOWN;
271         cmd->base.duplex = DUPLEX_UNKNOWN;
272
273         port = nfp_port_from_netdev(netdev);
274         eth_port = nfp_port_get_eth_port(port);
275         if (eth_port) {
276                 cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ?
277                         AUTONEG_ENABLE : AUTONEG_DISABLE;
278                 nfp_net_set_fec_link_mode(eth_port, cmd);
279         }
280
281         if (!netif_carrier_ok(netdev))
282                 return 0;
283
284         /* Use link speed from ETH table if available, otherwise try the BAR */
285         if (eth_port) {
286                 cmd->base.port = eth_port->port_type;
287                 cmd->base.speed = eth_port->speed;
288                 cmd->base.duplex = DUPLEX_FULL;
289                 return 0;
290         }
291
292         if (!nfp_netdev_is_nfp_net(netdev))
293                 return -EOPNOTSUPP;
294         nn = netdev_priv(netdev);
295
296         sts = nn_readl(nn, NFP_NET_CFG_STS);
297
298         ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts);
299         if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED)
300                 return -EOPNOTSUPP;
301
302         if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
303             ls >= ARRAY_SIZE(ls_to_ethtool))
304                 return 0;
305
306         cmd->base.speed = ls_to_ethtool[ls];
307         cmd->base.duplex = DUPLEX_FULL;
308
309         return 0;
310 }
311
312 static int
313 nfp_net_set_link_ksettings(struct net_device *netdev,
314                            const struct ethtool_link_ksettings *cmd)
315 {
316         struct nfp_eth_table_port *eth_port;
317         struct nfp_port *port;
318         struct nfp_nsp *nsp;
319         int err;
320
321         port = nfp_port_from_netdev(netdev);
322         eth_port = __nfp_port_get_eth_port(port);
323         if (!eth_port)
324                 return -EOPNOTSUPP;
325
326         if (netif_running(netdev)) {
327                 netdev_warn(netdev, "Changing settings not allowed on an active interface. It may cause the port to be disabled until driver reload.\n");
328                 return -EBUSY;
329         }
330
331         nsp = nfp_eth_config_start(port->app->cpp, eth_port->index);
332         if (IS_ERR(nsp))
333                 return PTR_ERR(nsp);
334
335         err = __nfp_eth_set_aneg(nsp, cmd->base.autoneg == AUTONEG_ENABLE ?
336                                  NFP_ANEG_AUTO : NFP_ANEG_DISABLED);
337         if (err)
338                 goto err_bad_set;
339         if (cmd->base.speed != SPEED_UNKNOWN) {
340                 u32 speed = cmd->base.speed / eth_port->lanes;
341
342                 err = __nfp_eth_set_speed(nsp, speed);
343                 if (err)
344                         goto err_bad_set;
345         }
346
347         err = nfp_eth_config_commit_end(nsp);
348         if (err > 0)
349                 return 0; /* no change */
350
351         nfp_net_refresh_port_table(port);
352
353         return err;
354
355 err_bad_set:
356         nfp_eth_config_cleanup_end(nsp);
357         return err;
358 }
359
360 static void nfp_net_get_ringparam(struct net_device *netdev,
361                                   struct ethtool_ringparam *ring)
362 {
363         struct nfp_net *nn = netdev_priv(netdev);
364
365         ring->rx_max_pending = NFP_NET_MAX_RX_DESCS;
366         ring->tx_max_pending = NFP_NET_MAX_TX_DESCS;
367         ring->rx_pending = nn->dp.rxd_cnt;
368         ring->tx_pending = nn->dp.txd_cnt;
369 }
370
371 static int nfp_net_set_ring_size(struct nfp_net *nn, u32 rxd_cnt, u32 txd_cnt)
372 {
373         struct nfp_net_dp *dp;
374
375         dp = nfp_net_clone_dp(nn);
376         if (!dp)
377                 return -ENOMEM;
378
379         dp->rxd_cnt = rxd_cnt;
380         dp->txd_cnt = txd_cnt;
381
382         return nfp_net_ring_reconfig(nn, dp, NULL);
383 }
384
385 static int nfp_net_set_ringparam(struct net_device *netdev,
386                                  struct ethtool_ringparam *ring)
387 {
388         struct nfp_net *nn = netdev_priv(netdev);
389         u32 rxd_cnt, txd_cnt;
390
391         /* We don't have separate queues/rings for small/large frames. */
392         if (ring->rx_mini_pending || ring->rx_jumbo_pending)
393                 return -EINVAL;
394
395         /* Round up to supported values */
396         rxd_cnt = roundup_pow_of_two(ring->rx_pending);
397         txd_cnt = roundup_pow_of_two(ring->tx_pending);
398
399         if (rxd_cnt < NFP_NET_MIN_RX_DESCS || rxd_cnt > NFP_NET_MAX_RX_DESCS ||
400             txd_cnt < NFP_NET_MIN_TX_DESCS || txd_cnt > NFP_NET_MAX_TX_DESCS)
401                 return -EINVAL;
402
403         if (nn->dp.rxd_cnt == rxd_cnt && nn->dp.txd_cnt == txd_cnt)
404                 return 0;
405
406         nn_dbg(nn, "Change ring size: RxQ %u->%u, TxQ %u->%u\n",
407                nn->dp.rxd_cnt, rxd_cnt, nn->dp.txd_cnt, txd_cnt);
408
409         return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt);
410 }
411
412 __printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...)
413 {
414         va_list args;
415
416         va_start(args, fmt);
417         vsnprintf(data, ETH_GSTRING_LEN, fmt, args);
418         va_end(args);
419
420         return data + ETH_GSTRING_LEN;
421 }
422
423 static unsigned int nfp_vnic_get_sw_stats_count(struct net_device *netdev)
424 {
425         struct nfp_net *nn = netdev_priv(netdev);
426
427         return NN_RVEC_GATHER_STATS + nn->max_r_vecs * NN_RVEC_PER_Q_STATS +
428                 NN_CTRL_PATH_STATS;
429 }
430
431 static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data)
432 {
433         struct nfp_net *nn = netdev_priv(netdev);
434         int i;
435
436         for (i = 0; i < nn->max_r_vecs; i++) {
437                 data = nfp_pr_et(data, "rvec_%u_rx_pkts", i);
438                 data = nfp_pr_et(data, "rvec_%u_tx_pkts", i);
439                 data = nfp_pr_et(data, "rvec_%u_tx_busy", i);
440         }
441
442         data = nfp_pr_et(data, "hw_rx_csum_ok");
443         data = nfp_pr_et(data, "hw_rx_csum_inner_ok");
444         data = nfp_pr_et(data, "hw_rx_csum_complete");
445         data = nfp_pr_et(data, "hw_rx_csum_err");
446         data = nfp_pr_et(data, "rx_replace_buf_alloc_fail");
447         data = nfp_pr_et(data, "rx_tls_decrypted_packets");
448         data = nfp_pr_et(data, "hw_tx_csum");
449         data = nfp_pr_et(data, "hw_tx_inner_csum");
450         data = nfp_pr_et(data, "tx_gather");
451         data = nfp_pr_et(data, "tx_lso");
452         data = nfp_pr_et(data, "tx_tls_encrypted_packets");
453         data = nfp_pr_et(data, "tx_tls_ooo");
454         data = nfp_pr_et(data, "tx_tls_drop_no_sync_data");
455
456         data = nfp_pr_et(data, "hw_tls_no_space");
457
458         return data;
459 }
460
461 static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
462 {
463         u64 gathered_stats[NN_RVEC_GATHER_STATS] = {};
464         struct nfp_net *nn = netdev_priv(netdev);
465         u64 tmp[NN_RVEC_GATHER_STATS];
466         unsigned int i, j;
467
468         for (i = 0; i < nn->max_r_vecs; i++) {
469                 unsigned int start;
470
471                 do {
472                         start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
473                         data[0] = nn->r_vecs[i].rx_pkts;
474                         tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
475                         tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
476                         tmp[2] = nn->r_vecs[i].hw_csum_rx_complete;
477                         tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
478                         tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
479                         tmp[5] = nn->r_vecs[i].hw_tls_rx;
480                 } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
481
482                 do {
483                         start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
484                         data[1] = nn->r_vecs[i].tx_pkts;
485                         data[2] = nn->r_vecs[i].tx_busy;
486                         tmp[6] = nn->r_vecs[i].hw_csum_tx;
487                         tmp[7] = nn->r_vecs[i].hw_csum_tx_inner;
488                         tmp[8] = nn->r_vecs[i].tx_gather;
489                         tmp[9] = nn->r_vecs[i].tx_lso;
490                         tmp[10] = nn->r_vecs[i].hw_tls_tx;
491                         tmp[11] = nn->r_vecs[i].tls_tx_fallback;
492                         tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
493                 } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
494
495                 data += NN_RVEC_PER_Q_STATS;
496
497                 for (j = 0; j < NN_RVEC_GATHER_STATS; j++)
498                         gathered_stats[j] += tmp[j];
499         }
500
501         for (j = 0; j < NN_RVEC_GATHER_STATS; j++)
502                 *data++ = gathered_stats[j];
503
504         *data++ = atomic_read(&nn->ktls_no_space);
505
506         return data;
507 }
508
509 static unsigned int nfp_vnic_get_hw_stats_count(unsigned int num_vecs)
510 {
511         return NN_ET_GLOBAL_STATS_LEN + num_vecs * 4;
512 }
513
514 static u8 *
515 nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int num_vecs, bool repr)
516 {
517         int swap_off, i;
518
519         BUILD_BUG_ON(NN_ET_GLOBAL_STATS_LEN < NN_ET_SWITCH_STATS_LEN * 2);
520         /* If repr is true first add SWITCH_STATS_LEN and then subtract it
521          * effectively swapping the RX and TX statistics (giving us the RX
522          * and TX from perspective of the switch).
523          */
524         swap_off = repr * NN_ET_SWITCH_STATS_LEN;
525
526         for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
527                 data = nfp_pr_et(data, nfp_net_et_stats[i + swap_off].name);
528
529         for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++)
530                 data = nfp_pr_et(data, nfp_net_et_stats[i - swap_off].name);
531
532         for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++)
533                 data = nfp_pr_et(data, nfp_net_et_stats[i].name);
534
535         for (i = 0; i < num_vecs; i++) {
536                 data = nfp_pr_et(data, "rxq_%u_pkts", i);
537                 data = nfp_pr_et(data, "rxq_%u_bytes", i);
538                 data = nfp_pr_et(data, "txq_%u_pkts", i);
539                 data = nfp_pr_et(data, "txq_%u_bytes", i);
540         }
541
542         return data;
543 }
544
545 static u64 *
546 nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem, unsigned int num_vecs)
547 {
548         unsigned int i;
549
550         for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
551                 *data++ = readq(mem + nfp_net_et_stats[i].off);
552
553         for (i = 0; i < num_vecs; i++) {
554                 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i));
555                 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8);
556                 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i));
557                 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8);
558         }
559
560         return data;
561 }
562
563 static unsigned int nfp_mac_get_stats_count(struct net_device *netdev)
564 {
565         struct nfp_port *port;
566
567         port = nfp_port_from_netdev(netdev);
568         if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
569                 return 0;
570
571         return ARRAY_SIZE(nfp_mac_et_stats);
572 }
573
574 static u8 *nfp_mac_get_stats_strings(struct net_device *netdev, u8 *data)
575 {
576         struct nfp_port *port;
577         unsigned int i;
578
579         port = nfp_port_from_netdev(netdev);
580         if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
581                 return data;
582
583         for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
584                 data = nfp_pr_et(data, "mac.%s", nfp_mac_et_stats[i].name);
585
586         return data;
587 }
588
589 static u64 *nfp_mac_get_stats(struct net_device *netdev, u64 *data)
590 {
591         struct nfp_port *port;
592         unsigned int i;
593
594         port = nfp_port_from_netdev(netdev);
595         if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
596                 return data;
597
598         for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
599                 *data++ = readq(port->eth_stats + nfp_mac_et_stats[i].off);
600
601         return data;
602 }
603
604 static void nfp_net_get_strings(struct net_device *netdev,
605                                 u32 stringset, u8 *data)
606 {
607         struct nfp_net *nn = netdev_priv(netdev);
608
609         switch (stringset) {
610         case ETH_SS_STATS:
611                 data = nfp_vnic_get_sw_stats_strings(netdev, data);
612                 data = nfp_vnic_get_hw_stats_strings(data, nn->max_r_vecs,
613                                                      false);
614                 data = nfp_mac_get_stats_strings(netdev, data);
615                 data = nfp_app_port_get_stats_strings(nn->port, data);
616                 break;
617         }
618 }
619
620 static void
621 nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
622                   u64 *data)
623 {
624         struct nfp_net *nn = netdev_priv(netdev);
625
626         data = nfp_vnic_get_sw_stats(netdev, data);
627         data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar, nn->max_r_vecs);
628         data = nfp_mac_get_stats(netdev, data);
629         data = nfp_app_port_get_stats(nn->port, data);
630 }
631
632 static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
633 {
634         struct nfp_net *nn = netdev_priv(netdev);
635
636         switch (sset) {
637         case ETH_SS_STATS:
638                 return nfp_vnic_get_sw_stats_count(netdev) +
639                        nfp_vnic_get_hw_stats_count(nn->max_r_vecs) +
640                        nfp_mac_get_stats_count(netdev) +
641                        nfp_app_port_get_stats_count(nn->port);
642         default:
643                 return -EOPNOTSUPP;
644         }
645 }
646
647 static void nfp_port_get_strings(struct net_device *netdev,
648                                  u32 stringset, u8 *data)
649 {
650         struct nfp_port *port = nfp_port_from_netdev(netdev);
651
652         switch (stringset) {
653         case ETH_SS_STATS:
654                 if (nfp_port_is_vnic(port))
655                         data = nfp_vnic_get_hw_stats_strings(data, 0, true);
656                 else
657                         data = nfp_mac_get_stats_strings(netdev, data);
658                 data = nfp_app_port_get_stats_strings(port, data);
659                 break;
660         }
661 }
662
663 static void
664 nfp_port_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
665                    u64 *data)
666 {
667         struct nfp_port *port = nfp_port_from_netdev(netdev);
668
669         if (nfp_port_is_vnic(port))
670                 data = nfp_vnic_get_hw_stats(data, port->vnic, 0);
671         else
672                 data = nfp_mac_get_stats(netdev, data);
673         data = nfp_app_port_get_stats(port, data);
674 }
675
676 static int nfp_port_get_sset_count(struct net_device *netdev, int sset)
677 {
678         struct nfp_port *port = nfp_port_from_netdev(netdev);
679         unsigned int count;
680
681         switch (sset) {
682         case ETH_SS_STATS:
683                 if (nfp_port_is_vnic(port))
684                         count = nfp_vnic_get_hw_stats_count(0);
685                 else
686                         count = nfp_mac_get_stats_count(netdev);
687                 count += nfp_app_port_get_stats_count(port);
688                 return count;
689         default:
690                 return -EOPNOTSUPP;
691         }
692 }
693
694 static int nfp_port_fec_ethtool_to_nsp(u32 fec)
695 {
696         switch (fec) {
697         case ETHTOOL_FEC_AUTO:
698                 return NFP_FEC_AUTO_BIT;
699         case ETHTOOL_FEC_OFF:
700                 return NFP_FEC_DISABLED_BIT;
701         case ETHTOOL_FEC_RS:
702                 return NFP_FEC_REED_SOLOMON_BIT;
703         case ETHTOOL_FEC_BASER:
704                 return NFP_FEC_BASER_BIT;
705         default:
706                 /* NSP only supports a single mode at a time */
707                 return -EOPNOTSUPP;
708         }
709 }
710
711 static u32 nfp_port_fec_nsp_to_ethtool(u32 fec)
712 {
713         u32 result = 0;
714
715         if (fec & NFP_FEC_AUTO)
716                 result |= ETHTOOL_FEC_AUTO;
717         if (fec & NFP_FEC_BASER)
718                 result |= ETHTOOL_FEC_BASER;
719         if (fec & NFP_FEC_REED_SOLOMON)
720                 result |= ETHTOOL_FEC_RS;
721         if (fec & NFP_FEC_DISABLED)
722                 result |= ETHTOOL_FEC_OFF;
723
724         return result ?: ETHTOOL_FEC_NONE;
725 }
726
727 static int
728 nfp_port_get_fecparam(struct net_device *netdev,
729                       struct ethtool_fecparam *param)
730 {
731         struct nfp_eth_table_port *eth_port;
732         struct nfp_port *port;
733
734         param->active_fec = ETHTOOL_FEC_NONE_BIT;
735         param->fec = ETHTOOL_FEC_NONE_BIT;
736
737         port = nfp_port_from_netdev(netdev);
738         eth_port = nfp_port_get_eth_port(port);
739         if (!eth_port)
740                 return -EOPNOTSUPP;
741
742         if (!nfp_eth_can_support_fec(eth_port))
743                 return 0;
744
745         param->fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec_modes_supported);
746         param->active_fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec);
747
748         return 0;
749 }
750
751 static int
752 nfp_port_set_fecparam(struct net_device *netdev,
753                       struct ethtool_fecparam *param)
754 {
755         struct nfp_eth_table_port *eth_port;
756         struct nfp_port *port;
757         int err, fec;
758
759         port = nfp_port_from_netdev(netdev);
760         eth_port = nfp_port_get_eth_port(port);
761         if (!eth_port)
762                 return -EOPNOTSUPP;
763
764         if (!nfp_eth_can_support_fec(eth_port))
765                 return -EOPNOTSUPP;
766
767         fec = nfp_port_fec_ethtool_to_nsp(param->fec);
768         if (fec < 0)
769                 return fec;
770
771         err = nfp_eth_set_fec(port->app->cpp, eth_port->index, fec);
772         if (!err)
773                 /* Only refresh if we did something */
774                 nfp_net_refresh_port_table(port);
775
776         return err < 0 ? err : 0;
777 }
778
779 /* RX network flow classification (RSS, filters, etc)
780  */
781 static u32 ethtool_flow_to_nfp_flag(u32 flow_type)
782 {
783         static const u32 xlate_ethtool_to_nfp[IPV6_FLOW + 1] = {
784                 [TCP_V4_FLOW]   = NFP_NET_CFG_RSS_IPV4_TCP,
785                 [TCP_V6_FLOW]   = NFP_NET_CFG_RSS_IPV6_TCP,
786                 [UDP_V4_FLOW]   = NFP_NET_CFG_RSS_IPV4_UDP,
787                 [UDP_V6_FLOW]   = NFP_NET_CFG_RSS_IPV6_UDP,
788                 [IPV4_FLOW]     = NFP_NET_CFG_RSS_IPV4,
789                 [IPV6_FLOW]     = NFP_NET_CFG_RSS_IPV6,
790         };
791
792         if (flow_type >= ARRAY_SIZE(xlate_ethtool_to_nfp))
793                 return 0;
794
795         return xlate_ethtool_to_nfp[flow_type];
796 }
797
798 static int nfp_net_get_rss_hash_opts(struct nfp_net *nn,
799                                      struct ethtool_rxnfc *cmd)
800 {
801         u32 nfp_rss_flag;
802
803         cmd->data = 0;
804
805         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
806                 return -EOPNOTSUPP;
807
808         nfp_rss_flag = ethtool_flow_to_nfp_flag(cmd->flow_type);
809         if (!nfp_rss_flag)
810                 return -EINVAL;
811
812         cmd->data |= RXH_IP_SRC | RXH_IP_DST;
813         if (nn->rss_cfg & nfp_rss_flag)
814                 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
815
816         return 0;
817 }
818
819 static int nfp_net_get_rxnfc(struct net_device *netdev,
820                              struct ethtool_rxnfc *cmd, u32 *rule_locs)
821 {
822         struct nfp_net *nn = netdev_priv(netdev);
823
824         switch (cmd->cmd) {
825         case ETHTOOL_GRXRINGS:
826                 cmd->data = nn->dp.num_rx_rings;
827                 return 0;
828         case ETHTOOL_GRXFH:
829                 return nfp_net_get_rss_hash_opts(nn, cmd);
830         default:
831                 return -EOPNOTSUPP;
832         }
833 }
834
835 static int nfp_net_set_rss_hash_opt(struct nfp_net *nn,
836                                     struct ethtool_rxnfc *nfc)
837 {
838         u32 new_rss_cfg = nn->rss_cfg;
839         u32 nfp_rss_flag;
840         int err;
841
842         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
843                 return -EOPNOTSUPP;
844
845         /* RSS only supports IP SA/DA and L4 src/dst ports  */
846         if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
847                           RXH_L4_B_0_1 | RXH_L4_B_2_3))
848                 return -EINVAL;
849
850         /* We need at least the IP SA/DA fields for hashing */
851         if (!(nfc->data & RXH_IP_SRC) ||
852             !(nfc->data & RXH_IP_DST))
853                 return -EINVAL;
854
855         nfp_rss_flag = ethtool_flow_to_nfp_flag(nfc->flow_type);
856         if (!nfp_rss_flag)
857                 return -EINVAL;
858
859         switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
860         case 0:
861                 new_rss_cfg &= ~nfp_rss_flag;
862                 break;
863         case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
864                 new_rss_cfg |= nfp_rss_flag;
865                 break;
866         default:
867                 return -EINVAL;
868         }
869
870         new_rss_cfg |= FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc);
871         new_rss_cfg |= NFP_NET_CFG_RSS_MASK;
872
873         if (new_rss_cfg == nn->rss_cfg)
874                 return 0;
875
876         writel(new_rss_cfg, nn->dp.ctrl_bar + NFP_NET_CFG_RSS_CTRL);
877         err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
878         if (err)
879                 return err;
880
881         nn->rss_cfg = new_rss_cfg;
882
883         nn_dbg(nn, "Changed RSS config to 0x%x\n", nn->rss_cfg);
884         return 0;
885 }
886
887 static int nfp_net_set_rxnfc(struct net_device *netdev,
888                              struct ethtool_rxnfc *cmd)
889 {
890         struct nfp_net *nn = netdev_priv(netdev);
891
892         switch (cmd->cmd) {
893         case ETHTOOL_SRXFH:
894                 return nfp_net_set_rss_hash_opt(nn, cmd);
895         default:
896                 return -EOPNOTSUPP;
897         }
898 }
899
900 static u32 nfp_net_get_rxfh_indir_size(struct net_device *netdev)
901 {
902         struct nfp_net *nn = netdev_priv(netdev);
903
904         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
905                 return 0;
906
907         return ARRAY_SIZE(nn->rss_itbl);
908 }
909
910 static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev)
911 {
912         struct nfp_net *nn = netdev_priv(netdev);
913
914         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
915                 return -EOPNOTSUPP;
916
917         return nfp_net_rss_key_sz(nn);
918 }
919
920 static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
921                             u8 *hfunc)
922 {
923         struct nfp_net *nn = netdev_priv(netdev);
924         int i;
925
926         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
927                 return -EOPNOTSUPP;
928
929         if (indir)
930                 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
931                         indir[i] = nn->rss_itbl[i];
932         if (key)
933                 memcpy(key, nn->rss_key, nfp_net_rss_key_sz(nn));
934         if (hfunc) {
935                 *hfunc = nn->rss_hfunc;
936                 if (*hfunc >= 1 << ETH_RSS_HASH_FUNCS_COUNT)
937                         *hfunc = ETH_RSS_HASH_UNKNOWN;
938         }
939
940         return 0;
941 }
942
943 static int nfp_net_set_rxfh(struct net_device *netdev,
944                             const u32 *indir, const u8 *key,
945                             const u8 hfunc)
946 {
947         struct nfp_net *nn = netdev_priv(netdev);
948         int i;
949
950         if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY) ||
951             !(hfunc == ETH_RSS_HASH_NO_CHANGE || hfunc == nn->rss_hfunc))
952                 return -EOPNOTSUPP;
953
954         if (!key && !indir)
955                 return 0;
956
957         if (key) {
958                 memcpy(nn->rss_key, key, nfp_net_rss_key_sz(nn));
959                 nfp_net_rss_write_key(nn);
960         }
961         if (indir) {
962                 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
963                         nn->rss_itbl[i] = indir[i];
964
965                 nfp_net_rss_write_itbl(nn);
966         }
967
968         return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
969 }
970
971 /* Dump BAR registers
972  */
973 static int nfp_net_get_regs_len(struct net_device *netdev)
974 {
975         return NFP_NET_CFG_BAR_SZ;
976 }
977
978 static void nfp_net_get_regs(struct net_device *netdev,
979                              struct ethtool_regs *regs, void *p)
980 {
981         struct nfp_net *nn = netdev_priv(netdev);
982         u32 *regs_buf = p;
983         int i;
984
985         regs->version = nn_readl(nn, NFP_NET_CFG_VERSION);
986
987         for (i = 0; i < NFP_NET_CFG_BAR_SZ / sizeof(u32); i++)
988                 regs_buf[i] = readl(nn->dp.ctrl_bar + (i * sizeof(u32)));
989 }
990
991 static int nfp_net_get_coalesce(struct net_device *netdev,
992                                 struct ethtool_coalesce *ec)
993 {
994         struct nfp_net *nn = netdev_priv(netdev);
995
996         if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
997                 return -EINVAL;
998
999         ec->rx_coalesce_usecs       = nn->rx_coalesce_usecs;
1000         ec->rx_max_coalesced_frames = nn->rx_coalesce_max_frames;
1001         ec->tx_coalesce_usecs       = nn->tx_coalesce_usecs;
1002         ec->tx_max_coalesced_frames = nn->tx_coalesce_max_frames;
1003
1004         return 0;
1005 }
1006
1007 /* Other debug dumps
1008  */
1009 static int
1010 nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer)
1011 {
1012         struct nfp_resource *res;
1013         int ret;
1014
1015         if (!app)
1016                 return -EOPNOTSUPP;
1017
1018         dump->version = 1;
1019         dump->flag = NFP_DUMP_NSP_DIAG;
1020
1021         res = nfp_resource_acquire(app->cpp, NFP_RESOURCE_NSP_DIAG);
1022         if (IS_ERR(res))
1023                 return PTR_ERR(res);
1024
1025         if (buffer) {
1026                 if (dump->len != nfp_resource_size(res)) {
1027                         ret = -EINVAL;
1028                         goto exit_release;
1029                 }
1030
1031                 ret = nfp_cpp_read(app->cpp, nfp_resource_cpp_id(res),
1032                                    nfp_resource_address(res),
1033                                    buffer, dump->len);
1034                 if (ret != dump->len)
1035                         ret = ret < 0 ? ret : -EIO;
1036                 else
1037                         ret = 0;
1038         } else {
1039                 dump->len = nfp_resource_size(res);
1040                 ret = 0;
1041         }
1042 exit_release:
1043         nfp_resource_release(res);
1044
1045         return ret;
1046 }
1047
1048 /* Set the dump flag/level. Calculate the dump length for flag > 0 only (new TLV
1049  * based dumps), since flag 0 (default) calculates the length in
1050  * nfp_app_get_dump_flag(), and we need to support triggering a level 0 dump
1051  * without setting the flag first, for backward compatibility.
1052  */
1053 static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1054 {
1055         struct nfp_app *app = nfp_app_from_netdev(netdev);
1056         s64 len;
1057
1058         if (!app)
1059                 return -EOPNOTSUPP;
1060
1061         if (val->flag == NFP_DUMP_NSP_DIAG) {
1062                 app->pf->dump_flag = val->flag;
1063                 return 0;
1064         }
1065
1066         if (!app->pf->dumpspec)
1067                 return -EOPNOTSUPP;
1068
1069         len = nfp_net_dump_calculate_size(app->pf, app->pf->dumpspec,
1070                                           val->flag);
1071         if (len < 0)
1072                 return len;
1073
1074         app->pf->dump_flag = val->flag;
1075         app->pf->dump_len = len;
1076
1077         return 0;
1078 }
1079
1080 static int
1081 nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1082 {
1083         struct nfp_app *app = nfp_app_from_netdev(netdev);
1084
1085         if (!app)
1086                 return -EOPNOTSUPP;
1087
1088         if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1089                 return nfp_dump_nsp_diag(app, dump, NULL);
1090
1091         dump->flag = app->pf->dump_flag;
1092         dump->len = app->pf->dump_len;
1093
1094         return 0;
1095 }
1096
1097 static int
1098 nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1099                       void *buffer)
1100 {
1101         struct nfp_app *app = nfp_app_from_netdev(netdev);
1102
1103         if (!app)
1104                 return -EOPNOTSUPP;
1105
1106         if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1107                 return nfp_dump_nsp_diag(app, dump, buffer);
1108
1109         dump->flag = app->pf->dump_flag;
1110         dump->len = app->pf->dump_len;
1111
1112         return nfp_net_dump_populate_buffer(app->pf, app->pf->dumpspec, dump,
1113                                             buffer);
1114 }
1115
1116 static int
1117 nfp_port_get_module_info(struct net_device *netdev,
1118                          struct ethtool_modinfo *modinfo)
1119 {
1120         struct nfp_eth_table_port *eth_port;
1121         struct nfp_port *port;
1122         unsigned int read_len;
1123         struct nfp_nsp *nsp;
1124         int err = 0;
1125         u8 data;
1126
1127         port = nfp_port_from_netdev(netdev);
1128         eth_port = nfp_port_get_eth_port(port);
1129         if (!eth_port)
1130                 return -EOPNOTSUPP;
1131
1132         nsp = nfp_nsp_open(port->app->cpp);
1133         if (IS_ERR(nsp)) {
1134                 err = PTR_ERR(nsp);
1135                 netdev_err(netdev, "Failed to access the NSP: %d\n", err);
1136                 return err;
1137         }
1138
1139         if (!nfp_nsp_has_read_module_eeprom(nsp)) {
1140                 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
1141                 err = -EOPNOTSUPP;
1142                 goto exit_close_nsp;
1143         }
1144
1145         switch (eth_port->interface) {
1146         case NFP_INTERFACE_SFP:
1147         case NFP_INTERFACE_SFP28:
1148                 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
1149                                                  SFP_SFF8472_COMPLIANCE, &data,
1150                                                  1, &read_len);
1151                 if (err < 0)
1152                         goto exit_close_nsp;
1153
1154                 if (!data) {
1155                         modinfo->type = ETH_MODULE_SFF_8079;
1156                         modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
1157                 } else {
1158                         modinfo->type = ETH_MODULE_SFF_8472;
1159                         modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
1160                 }
1161                 break;
1162         case NFP_INTERFACE_QSFP:
1163                 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
1164                                                  SFP_SFF_REV_COMPLIANCE, &data,
1165                                                  1, &read_len);
1166                 if (err < 0)
1167                         goto exit_close_nsp;
1168
1169                 if (data < 0x3) {
1170                         modinfo->type = ETH_MODULE_SFF_8436;
1171                         modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
1172                 } else {
1173                         modinfo->type = ETH_MODULE_SFF_8636;
1174                         modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
1175                 }
1176                 break;
1177         case NFP_INTERFACE_QSFP28:
1178                 modinfo->type = ETH_MODULE_SFF_8636;
1179                 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN;
1180                 break;
1181         default:
1182                 netdev_err(netdev, "Unsupported module 0x%x detected\n",
1183                            eth_port->interface);
1184                 err = -EINVAL;
1185         }
1186
1187 exit_close_nsp:
1188         nfp_nsp_close(nsp);
1189         return err;
1190 }
1191
1192 static int
1193 nfp_port_get_module_eeprom(struct net_device *netdev,
1194                            struct ethtool_eeprom *eeprom, u8 *data)
1195 {
1196         struct nfp_eth_table_port *eth_port;
1197         struct nfp_port *port;
1198         struct nfp_nsp *nsp;
1199         int err;
1200
1201         port = nfp_port_from_netdev(netdev);
1202         eth_port = __nfp_port_get_eth_port(port);
1203         if (!eth_port)
1204                 return -EOPNOTSUPP;
1205
1206         nsp = nfp_nsp_open(port->app->cpp);
1207         if (IS_ERR(nsp)) {
1208                 err = PTR_ERR(nsp);
1209                 netdev_err(netdev, "Failed to access the NSP: %d\n", err);
1210                 return err;
1211         }
1212
1213         if (!nfp_nsp_has_read_module_eeprom(nsp)) {
1214                 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
1215                 err = -EOPNOTSUPP;
1216                 goto exit_close_nsp;
1217         }
1218
1219         err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
1220                                          eeprom->offset, data, eeprom->len,
1221                                          &eeprom->len);
1222         if (err < 0) {
1223                 if (eeprom->len) {
1224                         netdev_warn(netdev,
1225                                     "Incomplete read from module EEPROM: %d\n",
1226                                      err);
1227                         err = 0;
1228                 } else {
1229                         netdev_err(netdev,
1230                                    "Reading from module EEPROM failed: %d\n",
1231                                    err);
1232                 }
1233         }
1234
1235 exit_close_nsp:
1236         nfp_nsp_close(nsp);
1237         return err;
1238 }
1239
1240 static int nfp_net_set_coalesce(struct net_device *netdev,
1241                                 struct ethtool_coalesce *ec)
1242 {
1243         struct nfp_net *nn = netdev_priv(netdev);
1244         unsigned int factor;
1245
1246         if (ec->rx_coalesce_usecs_irq ||
1247             ec->rx_max_coalesced_frames_irq ||
1248             ec->tx_coalesce_usecs_irq ||
1249             ec->tx_max_coalesced_frames_irq ||
1250             ec->stats_block_coalesce_usecs ||
1251             ec->use_adaptive_rx_coalesce ||
1252             ec->use_adaptive_tx_coalesce ||
1253             ec->pkt_rate_low ||
1254             ec->rx_coalesce_usecs_low ||
1255             ec->rx_max_coalesced_frames_low ||
1256             ec->tx_coalesce_usecs_low ||
1257             ec->tx_max_coalesced_frames_low ||
1258             ec->pkt_rate_high ||
1259             ec->rx_coalesce_usecs_high ||
1260             ec->rx_max_coalesced_frames_high ||
1261             ec->tx_coalesce_usecs_high ||
1262             ec->tx_max_coalesced_frames_high ||
1263             ec->rate_sample_interval)
1264                 return -EOPNOTSUPP;
1265
1266         /* Compute factor used to convert coalesce '_usecs' parameters to
1267          * ME timestamp ticks.  There are 16 ME clock cycles for each timestamp
1268          * count.
1269          */
1270         factor = nn->me_freq_mhz / 16;
1271
1272         /* Each pair of (usecs, max_frames) fields specifies that interrupts
1273          * should be coalesced until
1274          *      (usecs > 0 && time_since_first_completion >= usecs) ||
1275          *      (max_frames > 0 && completed_frames >= max_frames)
1276          *
1277          * It is illegal to set both usecs and max_frames to zero as this would
1278          * cause interrupts to never be generated.  To disable coalescing, set
1279          * usecs = 0 and max_frames = 1.
1280          *
1281          * Some implementations ignore the value of max_frames and use the
1282          * condition time_since_first_completion >= usecs
1283          */
1284
1285         if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
1286                 return -EINVAL;
1287
1288         /* ensure valid configuration */
1289         if (!ec->rx_coalesce_usecs && !ec->rx_max_coalesced_frames)
1290                 return -EINVAL;
1291
1292         if (!ec->tx_coalesce_usecs && !ec->tx_max_coalesced_frames)
1293                 return -EINVAL;
1294
1295         if (ec->rx_coalesce_usecs * factor >= ((1 << 16) - 1))
1296                 return -EINVAL;
1297
1298         if (ec->tx_coalesce_usecs * factor >= ((1 << 16) - 1))
1299                 return -EINVAL;
1300
1301         if (ec->rx_max_coalesced_frames >= ((1 << 16) - 1))
1302                 return -EINVAL;
1303
1304         if (ec->tx_max_coalesced_frames >= ((1 << 16) - 1))
1305                 return -EINVAL;
1306
1307         /* configuration is valid */
1308         nn->rx_coalesce_usecs      = ec->rx_coalesce_usecs;
1309         nn->rx_coalesce_max_frames = ec->rx_max_coalesced_frames;
1310         nn->tx_coalesce_usecs      = ec->tx_coalesce_usecs;
1311         nn->tx_coalesce_max_frames = ec->tx_max_coalesced_frames;
1312
1313         /* write configuration to device */
1314         nfp_net_coalesce_write_cfg(nn);
1315         return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD);
1316 }
1317
1318 static void nfp_net_get_channels(struct net_device *netdev,
1319                                  struct ethtool_channels *channel)
1320 {
1321         struct nfp_net *nn = netdev_priv(netdev);
1322         unsigned int num_tx_rings;
1323
1324         num_tx_rings = nn->dp.num_tx_rings;
1325         if (nn->dp.xdp_prog)
1326                 num_tx_rings -= nn->dp.num_rx_rings;
1327
1328         channel->max_rx = min(nn->max_rx_rings, nn->max_r_vecs);
1329         channel->max_tx = min(nn->max_tx_rings, nn->max_r_vecs);
1330         channel->max_combined = min(channel->max_rx, channel->max_tx);
1331         channel->max_other = NFP_NET_NON_Q_VECTORS;
1332         channel->combined_count = min(nn->dp.num_rx_rings, num_tx_rings);
1333         channel->rx_count = nn->dp.num_rx_rings - channel->combined_count;
1334         channel->tx_count = num_tx_rings - channel->combined_count;
1335         channel->other_count = NFP_NET_NON_Q_VECTORS;
1336 }
1337
1338 static int nfp_net_set_num_rings(struct nfp_net *nn, unsigned int total_rx,
1339                                  unsigned int total_tx)
1340 {
1341         struct nfp_net_dp *dp;
1342
1343         dp = nfp_net_clone_dp(nn);
1344         if (!dp)
1345                 return -ENOMEM;
1346
1347         dp->num_rx_rings = total_rx;
1348         dp->num_tx_rings = total_tx;
1349         /* nfp_net_check_config() will catch num_tx_rings > nn->max_tx_rings */
1350         if (dp->xdp_prog)
1351                 dp->num_tx_rings += total_rx;
1352
1353         return nfp_net_ring_reconfig(nn, dp, NULL);
1354 }
1355
1356 static int nfp_net_set_channels(struct net_device *netdev,
1357                                 struct ethtool_channels *channel)
1358 {
1359         struct nfp_net *nn = netdev_priv(netdev);
1360         unsigned int total_rx, total_tx;
1361
1362         /* Reject unsupported */
1363         if (!channel->combined_count ||
1364             channel->other_count != NFP_NET_NON_Q_VECTORS ||
1365             (channel->rx_count && channel->tx_count))
1366                 return -EINVAL;
1367
1368         total_rx = channel->combined_count + channel->rx_count;
1369         total_tx = channel->combined_count + channel->tx_count;
1370
1371         if (total_rx > min(nn->max_rx_rings, nn->max_r_vecs) ||
1372             total_tx > min(nn->max_tx_rings, nn->max_r_vecs))
1373                 return -EINVAL;
1374
1375         return nfp_net_set_num_rings(nn, total_rx, total_tx);
1376 }
1377
1378 static const struct ethtool_ops nfp_net_ethtool_ops = {
1379         .get_drvinfo            = nfp_net_get_drvinfo,
1380         .get_link               = ethtool_op_get_link,
1381         .get_ringparam          = nfp_net_get_ringparam,
1382         .set_ringparam          = nfp_net_set_ringparam,
1383         .get_strings            = nfp_net_get_strings,
1384         .get_ethtool_stats      = nfp_net_get_stats,
1385         .get_sset_count         = nfp_net_get_sset_count,
1386         .get_rxnfc              = nfp_net_get_rxnfc,
1387         .set_rxnfc              = nfp_net_set_rxnfc,
1388         .get_rxfh_indir_size    = nfp_net_get_rxfh_indir_size,
1389         .get_rxfh_key_size      = nfp_net_get_rxfh_key_size,
1390         .get_rxfh               = nfp_net_get_rxfh,
1391         .set_rxfh               = nfp_net_set_rxfh,
1392         .get_regs_len           = nfp_net_get_regs_len,
1393         .get_regs               = nfp_net_get_regs,
1394         .set_dump               = nfp_app_set_dump,
1395         .get_dump_flag          = nfp_app_get_dump_flag,
1396         .get_dump_data          = nfp_app_get_dump_data,
1397         .get_module_info        = nfp_port_get_module_info,
1398         .get_module_eeprom      = nfp_port_get_module_eeprom,
1399         .get_coalesce           = nfp_net_get_coalesce,
1400         .set_coalesce           = nfp_net_set_coalesce,
1401         .get_channels           = nfp_net_get_channels,
1402         .set_channels           = nfp_net_set_channels,
1403         .get_link_ksettings     = nfp_net_get_link_ksettings,
1404         .set_link_ksettings     = nfp_net_set_link_ksettings,
1405         .get_fecparam           = nfp_port_get_fecparam,
1406         .set_fecparam           = nfp_port_set_fecparam,
1407 };
1408
1409 const struct ethtool_ops nfp_port_ethtool_ops = {
1410         .get_drvinfo            = nfp_app_get_drvinfo,
1411         .get_link               = ethtool_op_get_link,
1412         .get_strings            = nfp_port_get_strings,
1413         .get_ethtool_stats      = nfp_port_get_stats,
1414         .get_sset_count         = nfp_port_get_sset_count,
1415         .set_dump               = nfp_app_set_dump,
1416         .get_dump_flag          = nfp_app_get_dump_flag,
1417         .get_dump_data          = nfp_app_get_dump_data,
1418         .get_module_info        = nfp_port_get_module_info,
1419         .get_module_eeprom      = nfp_port_get_module_eeprom,
1420         .get_link_ksettings     = nfp_net_get_link_ksettings,
1421         .set_link_ksettings     = nfp_net_set_link_ksettings,
1422         .get_fecparam           = nfp_port_get_fecparam,
1423         .set_fecparam           = nfp_port_set_fecparam,
1424 };
1425
1426 void nfp_net_set_ethtool_ops(struct net_device *netdev)
1427 {
1428         netdev->ethtool_ops = &nfp_net_ethtool_ops;
1429 }