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