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_dev.h"
25 #include "nfpcore/nfp_nsp.h"
26 #include "nfp_app.h"
27 #include "nfp_main.h"
28 #include "nfp_net_ctrl.h"
29 #include "nfp_net_dp.h"
30 #include "nfp_net.h"
31 #include "nfp_port.h"
32 #include "nfpcore/nfp_cpp.h"
33
34 struct nfp_et_stat {
35 char name[ETH_GSTRING_LEN];
36 int off;
37 };
38
39 static const struct nfp_et_stat nfp_net_et_stats[] = {
40 /* Stats from the device */
41 { "dev_rx_discards", NFP_NET_CFG_STATS_RX_DISCARDS },
42 { "dev_rx_errors", NFP_NET_CFG_STATS_RX_ERRORS },
43 { "dev_rx_bytes", NFP_NET_CFG_STATS_RX_OCTETS },
44 { "dev_rx_uc_bytes", NFP_NET_CFG_STATS_RX_UC_OCTETS },
45 { "dev_rx_mc_bytes", NFP_NET_CFG_STATS_RX_MC_OCTETS },
46 { "dev_rx_bc_bytes", NFP_NET_CFG_STATS_RX_BC_OCTETS },
47 { "dev_rx_pkts", NFP_NET_CFG_STATS_RX_FRAMES },
48 { "dev_rx_mc_pkts", NFP_NET_CFG_STATS_RX_MC_FRAMES },
49 { "dev_rx_bc_pkts", NFP_NET_CFG_STATS_RX_BC_FRAMES },
50
51 { "dev_tx_discards", NFP_NET_CFG_STATS_TX_DISCARDS },
52 { "dev_tx_errors", NFP_NET_CFG_STATS_TX_ERRORS },
53 { "dev_tx_bytes", NFP_NET_CFG_STATS_TX_OCTETS },
54 { "dev_tx_uc_bytes", NFP_NET_CFG_STATS_TX_UC_OCTETS },
55 { "dev_tx_mc_bytes", NFP_NET_CFG_STATS_TX_MC_OCTETS },
56 { "dev_tx_bc_bytes", NFP_NET_CFG_STATS_TX_BC_OCTETS },
57 { "dev_tx_pkts", NFP_NET_CFG_STATS_TX_FRAMES },
58 { "dev_tx_mc_pkts", NFP_NET_CFG_STATS_TX_MC_FRAMES },
59 { "dev_tx_bc_pkts", NFP_NET_CFG_STATS_TX_BC_FRAMES },
60
61 { "bpf_pass_pkts", NFP_NET_CFG_STATS_APP0_FRAMES },
62 { "bpf_pass_bytes", NFP_NET_CFG_STATS_APP0_BYTES },
63 /* see comments in outro functions in nfp_bpf_jit.c to find out
64 * how different BPF modes use app-specific counters
65 */
66 { "bpf_app1_pkts", NFP_NET_CFG_STATS_APP1_FRAMES },
67 { "bpf_app1_bytes", NFP_NET_CFG_STATS_APP1_BYTES },
68 { "bpf_app2_pkts", NFP_NET_CFG_STATS_APP2_FRAMES },
69 { "bpf_app2_bytes", NFP_NET_CFG_STATS_APP2_BYTES },
70 { "bpf_app3_pkts", NFP_NET_CFG_STATS_APP3_FRAMES },
71 { "bpf_app3_bytes", NFP_NET_CFG_STATS_APP3_BYTES },
72 };
73
74 static const struct nfp_et_stat nfp_mac_et_stats[] = {
75 { "rx_octets", NFP_MAC_STATS_RX_IN_OCTETS, },
76 { "rx_frame_too_long_errors",
77 NFP_MAC_STATS_RX_FRAME_TOO_LONG_ERRORS, },
78 { "rx_range_length_errors", NFP_MAC_STATS_RX_RANGE_LENGTH_ERRORS, },
79 { "rx_vlan_received_ok", NFP_MAC_STATS_RX_VLAN_RECEIVED_OK, },
80 { "rx_errors", NFP_MAC_STATS_RX_IN_ERRORS, },
81 { "rx_broadcast_pkts", NFP_MAC_STATS_RX_IN_BROADCAST_PKTS, },
82 { "rx_drop_events", NFP_MAC_STATS_RX_DROP_EVENTS, },
83 { "rx_alignment_errors", NFP_MAC_STATS_RX_ALIGNMENT_ERRORS, },
84 { "rx_pause_mac_ctrl_frames",
85 NFP_MAC_STATS_RX_PAUSE_MAC_CTRL_FRAMES, },
86 { "rx_frames_received_ok", NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK, },
87 { "rx_frame_check_sequence_errors",
88 NFP_MAC_STATS_RX_FRAME_CHECK_SEQUENCE_ERRORS, },
89 { "rx_unicast_pkts", NFP_MAC_STATS_RX_UNICAST_PKTS, },
90 { "rx_multicast_pkts", NFP_MAC_STATS_RX_MULTICAST_PKTS, },
91 { "rx_pkts", NFP_MAC_STATS_RX_PKTS, },
92 { "rx_undersize_pkts", NFP_MAC_STATS_RX_UNDERSIZE_PKTS, },
93 { "rx_pkts_64_octets", NFP_MAC_STATS_RX_PKTS_64_OCTETS, },
94 { "rx_pkts_65_to_127_octets",
95 NFP_MAC_STATS_RX_PKTS_65_TO_127_OCTETS, },
96 { "rx_pkts_128_to_255_octets",
97 NFP_MAC_STATS_RX_PKTS_128_TO_255_OCTETS, },
98 { "rx_pkts_256_to_511_octets",
99 NFP_MAC_STATS_RX_PKTS_256_TO_511_OCTETS, },
100 { "rx_pkts_512_to_1023_octets",
101 NFP_MAC_STATS_RX_PKTS_512_TO_1023_OCTETS, },
102 { "rx_pkts_1024_to_1518_octets",
103 NFP_MAC_STATS_RX_PKTS_1024_TO_1518_OCTETS, },
104 { "rx_pkts_1519_to_max_octets",
105 NFP_MAC_STATS_RX_PKTS_1519_TO_MAX_OCTETS, },
106 { "rx_jabbers", NFP_MAC_STATS_RX_JABBERS, },
107 { "rx_fragments", NFP_MAC_STATS_RX_FRAGMENTS, },
108 { "rx_oversize_pkts", NFP_MAC_STATS_RX_OVERSIZE_PKTS, },
109 { "rx_pause_frames_class0", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS0, },
110 { "rx_pause_frames_class1", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS1, },
111 { "rx_pause_frames_class2", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS2, },
112 { "rx_pause_frames_class3", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS3, },
113 { "rx_pause_frames_class4", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS4, },
114 { "rx_pause_frames_class5", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS5, },
115 { "rx_pause_frames_class6", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS6, },
116 { "rx_pause_frames_class7", NFP_MAC_STATS_RX_PAUSE_FRAMES_CLASS7, },
117 { "rx_mac_ctrl_frames_received",
118 NFP_MAC_STATS_RX_MAC_CTRL_FRAMES_RECEIVED, },
119 { "rx_mac_head_drop", NFP_MAC_STATS_RX_MAC_HEAD_DROP, },
120 { "tx_queue_drop", NFP_MAC_STATS_TX_QUEUE_DROP, },
121 { "tx_octets", NFP_MAC_STATS_TX_OUT_OCTETS, },
122 { "tx_vlan_transmitted_ok", NFP_MAC_STATS_TX_VLAN_TRANSMITTED_OK, },
123 { "tx_errors", NFP_MAC_STATS_TX_OUT_ERRORS, },
124 { "tx_broadcast_pkts", NFP_MAC_STATS_TX_BROADCAST_PKTS, },
125 { "tx_pause_mac_ctrl_frames",
126 NFP_MAC_STATS_TX_PAUSE_MAC_CTRL_FRAMES, },
127 { "tx_frames_transmitted_ok",
128 NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK, },
129 { "tx_unicast_pkts", NFP_MAC_STATS_TX_UNICAST_PKTS, },
130 { "tx_multicast_pkts", NFP_MAC_STATS_TX_MULTICAST_PKTS, },
131 { "tx_pkts_64_octets", NFP_MAC_STATS_TX_PKTS_64_OCTETS, },
132 { "tx_pkts_65_to_127_octets",
133 NFP_MAC_STATS_TX_PKTS_65_TO_127_OCTETS, },
134 { "tx_pkts_128_to_255_octets",
135 NFP_MAC_STATS_TX_PKTS_128_TO_255_OCTETS, },
136 { "tx_pkts_256_to_511_octets",
137 NFP_MAC_STATS_TX_PKTS_256_TO_511_OCTETS, },
138 { "tx_pkts_512_to_1023_octets",
139 NFP_MAC_STATS_TX_PKTS_512_TO_1023_OCTETS, },
140 { "tx_pkts_1024_to_1518_octets",
141 NFP_MAC_STATS_TX_PKTS_1024_TO_1518_OCTETS, },
142 { "tx_pkts_1519_to_max_octets",
143 NFP_MAC_STATS_TX_PKTS_1519_TO_MAX_OCTETS, },
144 { "tx_pause_frames_class0", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS0, },
145 { "tx_pause_frames_class1", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS1, },
146 { "tx_pause_frames_class2", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS2, },
147 { "tx_pause_frames_class3", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS3, },
148 { "tx_pause_frames_class4", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS4, },
149 { "tx_pause_frames_class5", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS5, },
150 { "tx_pause_frames_class6", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS6, },
151 { "tx_pause_frames_class7", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7, },
152 };
153
154 static const char nfp_tlv_stat_names[][ETH_GSTRING_LEN] = {
155 [1] = "dev_rx_discards",
156 [2] = "dev_rx_errors",
157 [3] = "dev_rx_bytes",
158 [4] = "dev_rx_uc_bytes",
159 [5] = "dev_rx_mc_bytes",
160 [6] = "dev_rx_bc_bytes",
161 [7] = "dev_rx_pkts",
162 [8] = "dev_rx_mc_pkts",
163 [9] = "dev_rx_bc_pkts",
164
165 [10] = "dev_tx_discards",
166 [11] = "dev_tx_errors",
167 [12] = "dev_tx_bytes",
168 [13] = "dev_tx_uc_bytes",
169 [14] = "dev_tx_mc_bytes",
170 [15] = "dev_tx_bc_bytes",
171 [16] = "dev_tx_pkts",
172 [17] = "dev_tx_mc_pkts",
173 [18] = "dev_tx_bc_pkts",
174 };
175
176 #define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats)
177 #define NN_ET_SWITCH_STATS_LEN 9
178 #define NN_RVEC_GATHER_STATS 13
179 #define NN_RVEC_PER_Q_STATS 3
180 #define NN_CTRL_PATH_STATS 4
181
182 #define SFP_SFF_REV_COMPLIANCE 1
183
nfp_net_get_nspinfo(struct nfp_app * app,char * version)184 static void nfp_net_get_nspinfo(struct nfp_app *app, char *version)
185 {
186 struct nfp_nsp *nsp;
187
188 if (!app)
189 return;
190
191 nsp = nfp_nsp_open(app->cpp);
192 if (IS_ERR(nsp))
193 return;
194
195 snprintf(version, ETHTOOL_FWVERS_LEN, "%hu.%hu",
196 nfp_nsp_get_abi_ver_major(nsp),
197 nfp_nsp_get_abi_ver_minor(nsp));
198
199 nfp_nsp_close(nsp);
200 }
201
202 static void
nfp_get_drvinfo(struct nfp_app * app,struct pci_dev * pdev,const char * vnic_version,struct ethtool_drvinfo * drvinfo)203 nfp_get_drvinfo(struct nfp_app *app, struct pci_dev *pdev,
204 const char *vnic_version, struct ethtool_drvinfo *drvinfo)
205 {
206 char nsp_version[ETHTOOL_FWVERS_LEN] = {};
207
208 strscpy(drvinfo->driver, dev_driver_string(&pdev->dev),
209 sizeof(drvinfo->driver));
210 nfp_net_get_nspinfo(app, nsp_version);
211 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
212 "%s %s %s %s", vnic_version, nsp_version,
213 nfp_app_mip_name(app), nfp_app_name(app));
214 }
215
216 static void
nfp_net_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)217 nfp_net_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
218 {
219 char vnic_version[ETHTOOL_FWVERS_LEN] = {};
220 struct nfp_net *nn = netdev_priv(netdev);
221
222 snprintf(vnic_version, sizeof(vnic_version), "%d.%d.%d.%d",
223 nn->fw_ver.extend, nn->fw_ver.class,
224 nn->fw_ver.major, nn->fw_ver.minor);
225 strscpy(drvinfo->bus_info, pci_name(nn->pdev),
226 sizeof(drvinfo->bus_info));
227
228 nfp_get_drvinfo(nn->app, nn->pdev, vnic_version, drvinfo);
229 }
230
231 static int
nfp_net_nway_reset(struct net_device * netdev)232 nfp_net_nway_reset(struct net_device *netdev)
233 {
234 struct nfp_eth_table_port *eth_port;
235 struct nfp_port *port;
236 int err;
237
238 port = nfp_port_from_netdev(netdev);
239 eth_port = nfp_port_get_eth_port(port);
240 if (!eth_port)
241 return -EOPNOTSUPP;
242
243 if (!netif_running(netdev))
244 return 0;
245
246 err = nfp_eth_set_configured(port->app->cpp, eth_port->index, false);
247 if (err) {
248 netdev_info(netdev, "Link down failed: %d\n", err);
249 return err;
250 }
251
252 err = nfp_eth_set_configured(port->app->cpp, eth_port->index, true);
253 if (err) {
254 netdev_info(netdev, "Link up failed: %d\n", err);
255 return err;
256 }
257
258 netdev_info(netdev, "Link reset succeeded\n");
259 return 0;
260 }
261
262 static void
nfp_app_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)263 nfp_app_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
264 {
265 struct nfp_app *app = nfp_app_from_netdev(netdev);
266
267 strscpy(drvinfo->bus_info, pci_name(app->pdev),
268 sizeof(drvinfo->bus_info));
269 nfp_get_drvinfo(app, app->pdev, "*", drvinfo);
270 }
271
272 static void
nfp_net_set_fec_link_mode(struct nfp_eth_table_port * eth_port,struct ethtool_link_ksettings * c)273 nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
274 struct ethtool_link_ksettings *c)
275 {
276 unsigned int modes;
277
278 ethtool_link_ksettings_add_link_mode(c, supported, FEC_NONE);
279 if (!nfp_eth_can_support_fec(eth_port)) {
280 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_NONE);
281 return;
282 }
283
284 modes = nfp_eth_supported_fec_modes(eth_port);
285 if (modes & NFP_FEC_BASER) {
286 ethtool_link_ksettings_add_link_mode(c, supported, FEC_BASER);
287 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_BASER);
288 }
289
290 if (modes & NFP_FEC_REED_SOLOMON) {
291 ethtool_link_ksettings_add_link_mode(c, supported, FEC_RS);
292 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_RS);
293 }
294 }
295
296 static const struct nfp_eth_media_link_mode {
297 u16 ethtool_link_mode;
298 u16 speed;
299 } nfp_eth_media_table[NFP_MEDIA_LINK_MODES_NUMBER] = {
300 [NFP_MEDIA_1000BASE_CX] = {
301 .ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
302 .speed = NFP_SPEED_1G,
303 },
304 [NFP_MEDIA_1000BASE_KX] = {
305 .ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
306 .speed = NFP_SPEED_1G,
307 },
308 [NFP_MEDIA_10GBASE_KX4] = {
309 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
310 .speed = NFP_SPEED_10G,
311 },
312 [NFP_MEDIA_10GBASE_KR] = {
313 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
314 .speed = NFP_SPEED_10G,
315 },
316 [NFP_MEDIA_10GBASE_LR] = {
317 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
318 .speed = NFP_SPEED_10G,
319 },
320 [NFP_MEDIA_10GBASE_CX4] = {
321 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
322 .speed = NFP_SPEED_10G,
323 },
324 [NFP_MEDIA_10GBASE_CR] = {
325 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
326 .speed = NFP_SPEED_10G,
327 },
328 [NFP_MEDIA_10GBASE_SR] = {
329 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
330 .speed = NFP_SPEED_10G,
331 },
332 [NFP_MEDIA_10GBASE_ER] = {
333 .ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
334 .speed = NFP_SPEED_10G,
335 },
336 [NFP_MEDIA_25GBASE_KR] = {
337 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
338 .speed = NFP_SPEED_25G,
339 },
340 [NFP_MEDIA_25GBASE_KR_S] = {
341 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
342 .speed = NFP_SPEED_25G,
343 },
344 [NFP_MEDIA_25GBASE_CR] = {
345 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
346 .speed = NFP_SPEED_25G,
347 },
348 [NFP_MEDIA_25GBASE_CR_S] = {
349 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
350 .speed = NFP_SPEED_25G,
351 },
352 [NFP_MEDIA_25GBASE_SR] = {
353 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
354 .speed = NFP_SPEED_25G,
355 },
356 [NFP_MEDIA_25GBASE_LR] = {
357 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
358 .speed = NFP_SPEED_25G,
359 },
360 [NFP_MEDIA_25GBASE_ER] = {
361 .ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
362 .speed = NFP_SPEED_25G,
363 },
364 [NFP_MEDIA_40GBASE_CR4] = {
365 .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
366 .speed = NFP_SPEED_40G,
367 },
368 [NFP_MEDIA_40GBASE_KR4] = {
369 .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
370 .speed = NFP_SPEED_40G,
371 },
372 [NFP_MEDIA_40GBASE_SR4] = {
373 .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
374 .speed = NFP_SPEED_40G,
375 },
376 [NFP_MEDIA_40GBASE_LR4] = {
377 .ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
378 .speed = NFP_SPEED_40G,
379 },
380 [NFP_MEDIA_50GBASE_KR] = {
381 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
382 .speed = NFP_SPEED_50G,
383 },
384 [NFP_MEDIA_50GBASE_SR] = {
385 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
386 .speed = NFP_SPEED_50G,
387 },
388 [NFP_MEDIA_50GBASE_CR] = {
389 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
390 .speed = NFP_SPEED_50G,
391 },
392 [NFP_MEDIA_50GBASE_LR] = {
393 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
394 .speed = NFP_SPEED_50G,
395 },
396 [NFP_MEDIA_50GBASE_ER] = {
397 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
398 .speed = NFP_SPEED_50G,
399 },
400 [NFP_MEDIA_50GBASE_FR] = {
401 .ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
402 .speed = NFP_SPEED_50G,
403 },
404 [NFP_MEDIA_100GBASE_KR4] = {
405 .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
406 .speed = NFP_SPEED_100G,
407 },
408 [NFP_MEDIA_100GBASE_SR4] = {
409 .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
410 .speed = NFP_SPEED_100G,
411 },
412 [NFP_MEDIA_100GBASE_CR4] = {
413 .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
414 .speed = NFP_SPEED_100G,
415 },
416 [NFP_MEDIA_100GBASE_KP4] = {
417 .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
418 .speed = NFP_SPEED_100G,
419 },
420 [NFP_MEDIA_100GBASE_CR10] = {
421 .ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
422 .speed = NFP_SPEED_100G,
423 },
424 };
425
426 static const unsigned int nfp_eth_speed_map[NFP_SUP_SPEED_NUMBER] = {
427 [NFP_SPEED_1G] = SPEED_1000,
428 [NFP_SPEED_10G] = SPEED_10000,
429 [NFP_SPEED_25G] = SPEED_25000,
430 [NFP_SPEED_40G] = SPEED_40000,
431 [NFP_SPEED_50G] = SPEED_50000,
432 [NFP_SPEED_100G] = SPEED_100000,
433 };
434
nfp_add_media_link_mode(struct nfp_port * port,struct nfp_eth_table_port * eth_port,struct ethtool_link_ksettings * cmd)435 static void nfp_add_media_link_mode(struct nfp_port *port,
436 struct nfp_eth_table_port *eth_port,
437 struct ethtool_link_ksettings *cmd)
438 {
439 bitmap_zero(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
440
441 for (u32 i = 0; i < NFP_MEDIA_LINK_MODES_NUMBER; i++) {
442 if (i < 64) {
443 if (eth_port->link_modes_supp[0] & BIT_ULL(i)) {
444 __set_bit(nfp_eth_media_table[i].ethtool_link_mode,
445 cmd->link_modes.supported);
446 __set_bit(nfp_eth_media_table[i].speed,
447 port->speed_bitmap);
448 }
449
450 if (eth_port->link_modes_ad[0] & BIT_ULL(i))
451 __set_bit(nfp_eth_media_table[i].ethtool_link_mode,
452 cmd->link_modes.advertising);
453 } else {
454 if (eth_port->link_modes_supp[1] & BIT_ULL(i - 64)) {
455 __set_bit(nfp_eth_media_table[i].ethtool_link_mode,
456 cmd->link_modes.supported);
457 __set_bit(nfp_eth_media_table[i].speed,
458 port->speed_bitmap);
459 }
460
461 if (eth_port->link_modes_ad[1] & BIT_ULL(i - 64))
462 __set_bit(nfp_eth_media_table[i].ethtool_link_mode,
463 cmd->link_modes.advertising);
464 }
465 }
466
467 /* We take all speeds as supported when it fails to read
468 * link modes due to old management firmware that doesn't
469 * support link modes reading or error occurring, so that
470 * speed change of this port is allowed.
471 */
472 if (bitmap_empty(port->speed_bitmap, NFP_SUP_SPEED_NUMBER))
473 bitmap_fill(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
474 }
475
476 /**
477 * nfp_net_get_link_ksettings - Get Link Speed settings
478 * @netdev: network interface device structure
479 * @cmd: ethtool command
480 *
481 * Reports speed settings based on info in the BAR provided by the fw.
482 */
483 static int
nfp_net_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * cmd)484 nfp_net_get_link_ksettings(struct net_device *netdev,
485 struct ethtool_link_ksettings *cmd)
486 {
487 struct nfp_eth_table_port *eth_port;
488 struct nfp_port *port;
489 struct nfp_net *nn;
490 unsigned int speed;
491 u16 sts;
492
493 /* Init to unknowns */
494 ethtool_link_ksettings_zero_link_mode(cmd, supported);
495 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
496 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
497 cmd->base.port = PORT_OTHER;
498 cmd->base.speed = SPEED_UNKNOWN;
499 cmd->base.duplex = DUPLEX_UNKNOWN;
500
501 port = nfp_port_from_netdev(netdev);
502 eth_port = nfp_port_get_eth_port(port);
503 if (eth_port) {
504 ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
505 ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
506 nfp_add_media_link_mode(port, eth_port, cmd);
507 if (eth_port->supp_aneg) {
508 ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
509 if (eth_port->aneg == NFP_ANEG_AUTO) {
510 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg);
511 cmd->base.autoneg = AUTONEG_ENABLE;
512 }
513 }
514 nfp_net_set_fec_link_mode(eth_port, cmd);
515 }
516
517 if (!netif_carrier_ok(netdev))
518 return 0;
519
520 /* Use link speed from ETH table if available, otherwise try the BAR */
521 if (eth_port) {
522 cmd->base.port = eth_port->port_type;
523 cmd->base.speed = eth_port->speed;
524 cmd->base.duplex = DUPLEX_FULL;
525 return 0;
526 }
527
528 if (!nfp_netdev_is_nfp_net(netdev))
529 return -EOPNOTSUPP;
530 nn = netdev_priv(netdev);
531
532 sts = nn_readw(nn, NFP_NET_CFG_STS);
533 speed = nfp_net_lr2speed(FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts));
534 if (!speed)
535 return -EOPNOTSUPP;
536
537 if (speed != SPEED_UNKNOWN) {
538 cmd->base.speed = speed;
539 cmd->base.duplex = DUPLEX_FULL;
540 }
541
542 return 0;
543 }
544
545 static int
nfp_net_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * cmd)546 nfp_net_set_link_ksettings(struct net_device *netdev,
547 const struct ethtool_link_ksettings *cmd)
548 {
549 bool req_aneg = (cmd->base.autoneg == AUTONEG_ENABLE);
550 struct nfp_eth_table_port *eth_port;
551 struct nfp_port *port;
552 struct nfp_nsp *nsp;
553 int err;
554
555 port = nfp_port_from_netdev(netdev);
556 eth_port = __nfp_port_get_eth_port(port);
557 if (!eth_port)
558 return -EOPNOTSUPP;
559
560 if (netif_running(netdev)) {
561 netdev_warn(netdev, "Changing settings not allowed on an active interface. It may cause the port to be disabled until driver reload.\n");
562 return -EBUSY;
563 }
564
565 nsp = nfp_eth_config_start(port->app->cpp, eth_port->index);
566 if (IS_ERR(nsp))
567 return PTR_ERR(nsp);
568
569 if (req_aneg && !eth_port->supp_aneg) {
570 netdev_warn(netdev, "Autoneg is not supported.\n");
571 err = -EOPNOTSUPP;
572 goto err_bad_set;
573 }
574
575 err = __nfp_eth_set_aneg(nsp, req_aneg ? NFP_ANEG_AUTO : NFP_ANEG_DISABLED);
576 if (err)
577 goto err_bad_set;
578
579 if (cmd->base.speed != SPEED_UNKNOWN) {
580 u32 speed = cmd->base.speed / eth_port->lanes;
581 bool is_supported = false;
582
583 for (u32 i = 0; i < NFP_SUP_SPEED_NUMBER; i++) {
584 if (cmd->base.speed == nfp_eth_speed_map[i] &&
585 test_bit(i, port->speed_bitmap)) {
586 is_supported = true;
587 break;
588 }
589 }
590
591 if (!is_supported) {
592 netdev_err(netdev, "Speed %u is not supported.\n",
593 cmd->base.speed);
594 err = -EINVAL;
595 goto err_bad_set;
596 }
597
598 if (req_aneg) {
599 netdev_err(netdev, "Speed changing is not allowed when working on autoneg mode.\n");
600 err = -EINVAL;
601 goto err_bad_set;
602 }
603
604 err = __nfp_eth_set_speed(nsp, speed);
605 if (err)
606 goto err_bad_set;
607 }
608
609 err = nfp_eth_config_commit_end(nsp);
610 if (err > 0)
611 return 0; /* no change */
612
613 nfp_net_refresh_port_table(port);
614
615 return err;
616
617 err_bad_set:
618 nfp_eth_config_cleanup_end(nsp);
619 return err;
620 }
621
nfp_net_get_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)622 static void nfp_net_get_ringparam(struct net_device *netdev,
623 struct ethtool_ringparam *ring,
624 struct kernel_ethtool_ringparam *kernel_ring,
625 struct netlink_ext_ack *extack)
626 {
627 struct nfp_net *nn = netdev_priv(netdev);
628 u32 qc_max = nn->dev_info->max_qc_size;
629
630 ring->rx_max_pending = qc_max;
631 ring->tx_max_pending = qc_max / nn->dp.ops->tx_min_desc_per_pkt;
632 ring->rx_pending = nn->dp.rxd_cnt;
633 ring->tx_pending = nn->dp.txd_cnt;
634 }
635
nfp_net_set_ring_size(struct nfp_net * nn,u32 rxd_cnt,u32 txd_cnt,struct netlink_ext_ack * extack)636 static int nfp_net_set_ring_size(struct nfp_net *nn, u32 rxd_cnt, u32 txd_cnt,
637 struct netlink_ext_ack *extack)
638 {
639 struct nfp_net_dp *dp;
640
641 dp = nfp_net_clone_dp(nn);
642 if (!dp)
643 return -ENOMEM;
644
645 dp->rxd_cnt = rxd_cnt;
646 dp->txd_cnt = txd_cnt;
647
648 return nfp_net_ring_reconfig(nn, dp, extack);
649 }
650
nfp_net_set_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring,struct kernel_ethtool_ringparam * kernel_ring,struct netlink_ext_ack * extack)651 static int nfp_net_set_ringparam(struct net_device *netdev,
652 struct ethtool_ringparam *ring,
653 struct kernel_ethtool_ringparam *kernel_ring,
654 struct netlink_ext_ack *extack)
655 {
656 u32 tx_dpp, qc_min, qc_max, rxd_cnt, txd_cnt;
657 struct nfp_net *nn = netdev_priv(netdev);
658
659 /* We don't have separate queues/rings for small/large frames. */
660 if (ring->rx_mini_pending || ring->rx_jumbo_pending)
661 return -EOPNOTSUPP;
662
663 qc_min = nn->dev_info->min_qc_size;
664 qc_max = nn->dev_info->max_qc_size;
665 tx_dpp = nn->dp.ops->tx_min_desc_per_pkt;
666 /* Round up to supported values */
667 rxd_cnt = roundup_pow_of_two(ring->rx_pending);
668 txd_cnt = roundup_pow_of_two(ring->tx_pending);
669
670 if (rxd_cnt < qc_min || rxd_cnt > qc_max) {
671 NL_SET_ERR_MSG_MOD(extack, "rx parameter out of bounds");
672 return -EINVAL;
673 }
674
675 if (txd_cnt < qc_min / tx_dpp || txd_cnt > qc_max / tx_dpp) {
676 NL_SET_ERR_MSG_MOD(extack, "tx parameter out of bounds");
677 return -EINVAL;
678 }
679
680 if (nn->dp.rxd_cnt == rxd_cnt && nn->dp.txd_cnt == txd_cnt)
681 return 0;
682
683 nn_dbg(nn, "Change ring size: RxQ %u->%u, TxQ %u->%u\n",
684 nn->dp.rxd_cnt, rxd_cnt, nn->dp.txd_cnt, txd_cnt);
685
686 return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt, extack);
687 }
688
nfp_test_link(struct net_device * netdev)689 static int nfp_test_link(struct net_device *netdev)
690 {
691 if (!netif_carrier_ok(netdev) || !(netdev->flags & IFF_UP))
692 return 1;
693
694 return 0;
695 }
696
nfp_test_nsp(struct net_device * netdev)697 static int nfp_test_nsp(struct net_device *netdev)
698 {
699 struct nfp_app *app = nfp_app_from_netdev(netdev);
700 struct nfp_nsp_identify *nspi;
701 struct nfp_nsp *nsp;
702 int err;
703
704 nsp = nfp_nsp_open(app->cpp);
705 if (IS_ERR(nsp)) {
706 err = PTR_ERR(nsp);
707 netdev_info(netdev, "NSP Test: failed to access the NSP: %d\n", err);
708 goto exit;
709 }
710
711 if (nfp_nsp_get_abi_ver_minor(nsp) < 15) {
712 err = -EOPNOTSUPP;
713 goto exit_close_nsp;
714 }
715
716 nspi = kzalloc_obj(*nspi);
717 if (!nspi) {
718 err = -ENOMEM;
719 goto exit_close_nsp;
720 }
721
722 err = nfp_nsp_read_identify(nsp, nspi, sizeof(*nspi));
723 if (err < 0)
724 netdev_info(netdev, "NSP Test: reading bsp version failed %d\n", err);
725
726 kfree(nspi);
727 exit_close_nsp:
728 nfp_nsp_close(nsp);
729 exit:
730 return err;
731 }
732
nfp_test_fw(struct net_device * netdev)733 static int nfp_test_fw(struct net_device *netdev)
734 {
735 struct nfp_net *nn = netdev_priv(netdev);
736 int err;
737
738 err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_GEN);
739 if (err)
740 netdev_info(netdev, "FW Test: update failed %d\n", err);
741
742 return err;
743 }
744
nfp_test_reg(struct net_device * netdev)745 static int nfp_test_reg(struct net_device *netdev)
746 {
747 struct nfp_app *app = nfp_app_from_netdev(netdev);
748 struct nfp_cpp *cpp = app->cpp;
749 u32 model = nfp_cpp_model(cpp);
750 u32 value;
751 int err;
752
753 err = nfp_cpp_model_autodetect(cpp, &value);
754 if (err < 0) {
755 netdev_info(netdev, "REG Test: NFP model detection failed %d\n", err);
756 return err;
757 }
758
759 return (value == model) ? 0 : 1;
760 }
761
link_test_supported(struct net_device * netdev)762 static bool link_test_supported(struct net_device *netdev)
763 {
764 return true;
765 }
766
nsp_test_supported(struct net_device * netdev)767 static bool nsp_test_supported(struct net_device *netdev)
768 {
769 if (nfp_app_from_netdev(netdev))
770 return true;
771
772 return false;
773 }
774
fw_test_supported(struct net_device * netdev)775 static bool fw_test_supported(struct net_device *netdev)
776 {
777 if (nfp_netdev_is_nfp_net(netdev))
778 return true;
779
780 return false;
781 }
782
reg_test_supported(struct net_device * netdev)783 static bool reg_test_supported(struct net_device *netdev)
784 {
785 if (nfp_app_from_netdev(netdev))
786 return true;
787
788 return false;
789 }
790
791 static struct nfp_self_test_item {
792 char name[ETH_GSTRING_LEN];
793 bool (*is_supported)(struct net_device *dev);
794 int (*func)(struct net_device *dev);
795 } nfp_self_test[] = {
796 {"Link Test", link_test_supported, nfp_test_link},
797 {"NSP Test", nsp_test_supported, nfp_test_nsp},
798 {"Firmware Test", fw_test_supported, nfp_test_fw},
799 {"Register Test", reg_test_supported, nfp_test_reg}
800 };
801
802 #define NFP_TEST_TOTAL_NUM ARRAY_SIZE(nfp_self_test)
803
nfp_get_self_test_strings(struct net_device * netdev,u8 * data)804 static void nfp_get_self_test_strings(struct net_device *netdev, u8 *data)
805 {
806 int i;
807
808 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++)
809 if (nfp_self_test[i].is_supported(netdev))
810 ethtool_puts(&data, nfp_self_test[i].name);
811 }
812
nfp_get_self_test_count(struct net_device * netdev)813 static int nfp_get_self_test_count(struct net_device *netdev)
814 {
815 int i, count = 0;
816
817 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++)
818 if (nfp_self_test[i].is_supported(netdev))
819 count++;
820
821 return count;
822 }
823
nfp_net_self_test(struct net_device * netdev,struct ethtool_test * eth_test,u64 * data)824 static void nfp_net_self_test(struct net_device *netdev, struct ethtool_test *eth_test,
825 u64 *data)
826 {
827 int i, ret, count = 0;
828
829 netdev_info(netdev, "Start self test\n");
830
831 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++) {
832 if (nfp_self_test[i].is_supported(netdev)) {
833 ret = nfp_self_test[i].func(netdev);
834 if (ret)
835 eth_test->flags |= ETH_TEST_FL_FAILED;
836 data[count++] = ret;
837 }
838 }
839
840 netdev_info(netdev, "Test end\n");
841 }
842
nfp_vnic_get_sw_stats_count(struct net_device * netdev)843 static unsigned int nfp_vnic_get_sw_stats_count(struct net_device *netdev)
844 {
845 struct nfp_net *nn = netdev_priv(netdev);
846
847 return NN_RVEC_GATHER_STATS + nn->max_r_vecs * NN_RVEC_PER_Q_STATS +
848 NN_CTRL_PATH_STATS;
849 }
850
nfp_vnic_get_sw_stats_strings(struct net_device * netdev,u8 * data)851 static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data)
852 {
853 struct nfp_net *nn = netdev_priv(netdev);
854 int i;
855
856 for (i = 0; i < nn->max_r_vecs; i++) {
857 ethtool_sprintf(&data, "rvec_%u_rx_pkts", i);
858 ethtool_sprintf(&data, "rvec_%u_tx_pkts", i);
859 ethtool_sprintf(&data, "rvec_%u_tx_busy", i);
860 }
861
862 ethtool_puts(&data, "hw_rx_csum_ok");
863 ethtool_puts(&data, "hw_rx_csum_inner_ok");
864 ethtool_puts(&data, "hw_rx_csum_complete");
865 ethtool_puts(&data, "hw_rx_csum_err");
866 ethtool_puts(&data, "rx_replace_buf_alloc_fail");
867 ethtool_puts(&data, "rx_tls_decrypted_packets");
868 ethtool_puts(&data, "hw_tx_csum");
869 ethtool_puts(&data, "hw_tx_inner_csum");
870 ethtool_puts(&data, "tx_gather");
871 ethtool_puts(&data, "tx_lso");
872 ethtool_puts(&data, "tx_tls_encrypted_packets");
873 ethtool_puts(&data, "tx_tls_ooo");
874 ethtool_puts(&data, "tx_tls_drop_no_sync_data");
875
876 ethtool_puts(&data, "hw_tls_no_space");
877 ethtool_puts(&data, "rx_tls_resync_req_ok");
878 ethtool_puts(&data, "rx_tls_resync_req_ign");
879 ethtool_puts(&data, "rx_tls_resync_sent");
880
881 return data;
882 }
883
nfp_vnic_get_sw_stats(struct net_device * netdev,u64 * data)884 static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data)
885 {
886 u64 gathered_stats[NN_RVEC_GATHER_STATS] = {};
887 struct nfp_net *nn = netdev_priv(netdev);
888 u64 tmp[NN_RVEC_GATHER_STATS];
889 unsigned int i, j;
890
891 for (i = 0; i < nn->max_r_vecs; i++) {
892 unsigned int start;
893
894 do {
895 start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync);
896 data[0] = nn->r_vecs[i].rx_pkts;
897 tmp[0] = nn->r_vecs[i].hw_csum_rx_ok;
898 tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok;
899 tmp[2] = nn->r_vecs[i].hw_csum_rx_complete;
900 tmp[3] = nn->r_vecs[i].hw_csum_rx_error;
901 tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail;
902 tmp[5] = nn->r_vecs[i].hw_tls_rx;
903 } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start));
904
905 do {
906 start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync);
907 data[1] = nn->r_vecs[i].tx_pkts;
908 data[2] = nn->r_vecs[i].tx_busy;
909 tmp[6] = nn->r_vecs[i].hw_csum_tx;
910 tmp[7] = nn->r_vecs[i].hw_csum_tx_inner;
911 tmp[8] = nn->r_vecs[i].tx_gather;
912 tmp[9] = nn->r_vecs[i].tx_lso;
913 tmp[10] = nn->r_vecs[i].hw_tls_tx;
914 tmp[11] = nn->r_vecs[i].tls_tx_fallback;
915 tmp[12] = nn->r_vecs[i].tls_tx_no_fallback;
916 } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start));
917
918 data += NN_RVEC_PER_Q_STATS;
919
920 for (j = 0; j < NN_RVEC_GATHER_STATS; j++)
921 gathered_stats[j] += tmp[j];
922 }
923
924 for (j = 0; j < NN_RVEC_GATHER_STATS; j++)
925 *data++ = gathered_stats[j];
926
927 *data++ = atomic_read(&nn->ktls_no_space);
928 *data++ = atomic_read(&nn->ktls_rx_resync_req);
929 *data++ = atomic_read(&nn->ktls_rx_resync_ign);
930 *data++ = atomic_read(&nn->ktls_rx_resync_sent);
931
932 return data;
933 }
934
nfp_vnic_get_hw_stats_count(unsigned int num_vecs)935 static unsigned int nfp_vnic_get_hw_stats_count(unsigned int num_vecs)
936 {
937 return NN_ET_GLOBAL_STATS_LEN + num_vecs * 4;
938 }
939
940 static u8 *
nfp_vnic_get_hw_stats_strings(u8 * data,unsigned int num_vecs,bool repr)941 nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int num_vecs, bool repr)
942 {
943 int swap_off, i;
944
945 BUILD_BUG_ON(NN_ET_GLOBAL_STATS_LEN < NN_ET_SWITCH_STATS_LEN * 2);
946 /* If repr is true first add SWITCH_STATS_LEN and then subtract it
947 * effectively swapping the RX and TX statistics (giving us the RX
948 * and TX from perspective of the switch).
949 */
950 swap_off = repr * NN_ET_SWITCH_STATS_LEN;
951
952 for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++)
953 ethtool_puts(&data, nfp_net_et_stats[i + swap_off].name);
954
955 for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++)
956 ethtool_puts(&data, nfp_net_et_stats[i - swap_off].name);
957
958 for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++)
959 ethtool_puts(&data, nfp_net_et_stats[i].name);
960
961 for (i = 0; i < num_vecs; i++) {
962 ethtool_sprintf(&data, "rxq_%u_pkts", i);
963 ethtool_sprintf(&data, "rxq_%u_bytes", i);
964 ethtool_sprintf(&data, "txq_%u_pkts", i);
965 ethtool_sprintf(&data, "txq_%u_bytes", i);
966 }
967
968 return data;
969 }
970
971 static u64 *
nfp_vnic_get_hw_stats(u64 * data,u8 __iomem * mem,unsigned int num_vecs)972 nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem, unsigned int num_vecs)
973 {
974 unsigned int i;
975
976 for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++)
977 *data++ = readq(mem + nfp_net_et_stats[i].off);
978
979 for (i = 0; i < num_vecs; i++) {
980 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i));
981 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8);
982 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i));
983 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8);
984 }
985
986 return data;
987 }
988
nfp_vnic_get_tlv_stats_count(struct nfp_net * nn)989 static unsigned int nfp_vnic_get_tlv_stats_count(struct nfp_net *nn)
990 {
991 return nn->tlv_caps.vnic_stats_cnt + nn->max_r_vecs * 4;
992 }
993
nfp_vnic_get_tlv_stats_strings(struct nfp_net * nn,u8 * data)994 static u8 *nfp_vnic_get_tlv_stats_strings(struct nfp_net *nn, u8 *data)
995 {
996 unsigned int i, id;
997 u8 __iomem *mem;
998 u64 id_word = 0;
999
1000 mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off;
1001 for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++) {
1002 if (!(i % 4))
1003 id_word = readq(mem + i * 2);
1004
1005 id = (u16)id_word;
1006 id_word >>= 16;
1007
1008 if (id < ARRAY_SIZE(nfp_tlv_stat_names) &&
1009 nfp_tlv_stat_names[id][0]) {
1010 memcpy(data, nfp_tlv_stat_names[id], ETH_GSTRING_LEN);
1011 data += ETH_GSTRING_LEN;
1012 } else {
1013 ethtool_sprintf(&data, "dev_unknown_stat%u", id);
1014 }
1015 }
1016
1017 for (i = 0; i < nn->max_r_vecs; i++) {
1018 ethtool_sprintf(&data, "rxq_%u_pkts", i);
1019 ethtool_sprintf(&data, "rxq_%u_bytes", i);
1020 ethtool_sprintf(&data, "txq_%u_pkts", i);
1021 ethtool_sprintf(&data, "txq_%u_bytes", i);
1022 }
1023
1024 return data;
1025 }
1026
nfp_vnic_get_tlv_stats(struct nfp_net * nn,u64 * data)1027 static u64 *nfp_vnic_get_tlv_stats(struct nfp_net *nn, u64 *data)
1028 {
1029 u8 __iomem *mem;
1030 unsigned int i;
1031
1032 mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off;
1033 mem += roundup(2 * nn->tlv_caps.vnic_stats_cnt, 8);
1034 for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++)
1035 *data++ = readq(mem + i * 8);
1036
1037 mem = nn->dp.ctrl_bar;
1038 for (i = 0; i < nn->max_r_vecs; i++) {
1039 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i));
1040 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8);
1041 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i));
1042 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8);
1043 }
1044
1045 return data;
1046 }
1047
nfp_mac_get_stats_count(struct net_device * netdev)1048 static unsigned int nfp_mac_get_stats_count(struct net_device *netdev)
1049 {
1050 struct nfp_port *port;
1051
1052 port = nfp_port_from_netdev(netdev);
1053 if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
1054 return 0;
1055
1056 return ARRAY_SIZE(nfp_mac_et_stats);
1057 }
1058
nfp_mac_get_stats_strings(struct net_device * netdev,u8 * data)1059 static u8 *nfp_mac_get_stats_strings(struct net_device *netdev, u8 *data)
1060 {
1061 struct nfp_port *port;
1062 unsigned int i;
1063
1064 port = nfp_port_from_netdev(netdev);
1065 if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
1066 return data;
1067
1068 for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
1069 ethtool_sprintf(&data, "mac.%s", nfp_mac_et_stats[i].name);
1070
1071 return data;
1072 }
1073
nfp_mac_get_stats(struct net_device * netdev,u64 * data)1074 static u64 *nfp_mac_get_stats(struct net_device *netdev, u64 *data)
1075 {
1076 struct nfp_port *port;
1077 unsigned int i;
1078
1079 port = nfp_port_from_netdev(netdev);
1080 if (!__nfp_port_get_eth_port(port) || !port->eth_stats)
1081 return data;
1082
1083 for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++)
1084 *data++ = readq(port->eth_stats + nfp_mac_et_stats[i].off);
1085
1086 return data;
1087 }
1088
nfp_net_get_strings(struct net_device * netdev,u32 stringset,u8 * data)1089 static void nfp_net_get_strings(struct net_device *netdev,
1090 u32 stringset, u8 *data)
1091 {
1092 struct nfp_net *nn = netdev_priv(netdev);
1093
1094 switch (stringset) {
1095 case ETH_SS_STATS:
1096 data = nfp_vnic_get_sw_stats_strings(netdev, data);
1097 if (!nn->tlv_caps.vnic_stats_off)
1098 data = nfp_vnic_get_hw_stats_strings(data,
1099 nn->max_r_vecs,
1100 false);
1101 else
1102 data = nfp_vnic_get_tlv_stats_strings(nn, data);
1103 data = nfp_mac_get_stats_strings(netdev, data);
1104 data = nfp_app_port_get_stats_strings(nn->port, data);
1105 break;
1106 case ETH_SS_TEST:
1107 nfp_get_self_test_strings(netdev, data);
1108 break;
1109 }
1110 }
1111
1112 static void
nfp_net_get_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)1113 nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
1114 u64 *data)
1115 {
1116 struct nfp_net *nn = netdev_priv(netdev);
1117
1118 data = nfp_vnic_get_sw_stats(netdev, data);
1119 if (!nn->tlv_caps.vnic_stats_off)
1120 data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar,
1121 nn->max_r_vecs);
1122 else
1123 data = nfp_vnic_get_tlv_stats(nn, data);
1124 data = nfp_mac_get_stats(netdev, data);
1125 data = nfp_app_port_get_stats(nn->port, data);
1126 }
1127
nfp_net_get_sset_count(struct net_device * netdev,int sset)1128 static int nfp_net_get_sset_count(struct net_device *netdev, int sset)
1129 {
1130 struct nfp_net *nn = netdev_priv(netdev);
1131 unsigned int cnt;
1132
1133 switch (sset) {
1134 case ETH_SS_STATS:
1135 cnt = nfp_vnic_get_sw_stats_count(netdev);
1136 if (!nn->tlv_caps.vnic_stats_off)
1137 cnt += nfp_vnic_get_hw_stats_count(nn->max_r_vecs);
1138 else
1139 cnt += nfp_vnic_get_tlv_stats_count(nn);
1140 cnt += nfp_mac_get_stats_count(netdev);
1141 cnt += nfp_app_port_get_stats_count(nn->port);
1142 return cnt;
1143 case ETH_SS_TEST:
1144 return nfp_get_self_test_count(netdev);
1145 default:
1146 return -EOPNOTSUPP;
1147 }
1148 }
1149
nfp_port_get_strings(struct net_device * netdev,u32 stringset,u8 * data)1150 static void nfp_port_get_strings(struct net_device *netdev,
1151 u32 stringset, u8 *data)
1152 {
1153 struct nfp_port *port = nfp_port_from_netdev(netdev);
1154
1155 switch (stringset) {
1156 case ETH_SS_STATS:
1157 if (nfp_port_is_vnic(port))
1158 data = nfp_vnic_get_hw_stats_strings(data, 0, true);
1159 else
1160 data = nfp_mac_get_stats_strings(netdev, data);
1161 data = nfp_app_port_get_stats_strings(port, data);
1162 break;
1163 case ETH_SS_TEST:
1164 nfp_get_self_test_strings(netdev, data);
1165 break;
1166 }
1167 }
1168
1169 static void
nfp_port_get_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * data)1170 nfp_port_get_stats(struct net_device *netdev, struct ethtool_stats *stats,
1171 u64 *data)
1172 {
1173 struct nfp_port *port = nfp_port_from_netdev(netdev);
1174
1175 if (nfp_port_is_vnic(port))
1176 data = nfp_vnic_get_hw_stats(data, port->vnic, 0);
1177 else
1178 data = nfp_mac_get_stats(netdev, data);
1179 data = nfp_app_port_get_stats(port, data);
1180 }
1181
nfp_port_get_sset_count(struct net_device * netdev,int sset)1182 static int nfp_port_get_sset_count(struct net_device *netdev, int sset)
1183 {
1184 struct nfp_port *port = nfp_port_from_netdev(netdev);
1185 unsigned int count;
1186
1187 switch (sset) {
1188 case ETH_SS_STATS:
1189 if (nfp_port_is_vnic(port))
1190 count = nfp_vnic_get_hw_stats_count(0);
1191 else
1192 count = nfp_mac_get_stats_count(netdev);
1193 count += nfp_app_port_get_stats_count(port);
1194 return count;
1195 case ETH_SS_TEST:
1196 return nfp_get_self_test_count(netdev);
1197 default:
1198 return -EOPNOTSUPP;
1199 }
1200 }
1201
nfp_port_fec_ethtool_to_nsp(u32 fec)1202 static int nfp_port_fec_ethtool_to_nsp(u32 fec)
1203 {
1204 switch (fec) {
1205 case ETHTOOL_FEC_AUTO:
1206 return NFP_FEC_AUTO_BIT;
1207 case ETHTOOL_FEC_OFF:
1208 return NFP_FEC_DISABLED_BIT;
1209 case ETHTOOL_FEC_RS:
1210 return NFP_FEC_REED_SOLOMON_BIT;
1211 case ETHTOOL_FEC_BASER:
1212 return NFP_FEC_BASER_BIT;
1213 default:
1214 /* NSP only supports a single mode at a time */
1215 return -EOPNOTSUPP;
1216 }
1217 }
1218
nfp_port_fec_nsp_to_ethtool(u32 fec)1219 static u32 nfp_port_fec_nsp_to_ethtool(u32 fec)
1220 {
1221 u32 result = 0;
1222
1223 if (fec & NFP_FEC_AUTO)
1224 result |= ETHTOOL_FEC_AUTO;
1225 if (fec & NFP_FEC_BASER)
1226 result |= ETHTOOL_FEC_BASER;
1227 if (fec & NFP_FEC_REED_SOLOMON)
1228 result |= ETHTOOL_FEC_RS;
1229 if (fec & NFP_FEC_DISABLED)
1230 result |= ETHTOOL_FEC_OFF;
1231
1232 return result ?: ETHTOOL_FEC_NONE;
1233 }
1234
1235 static int
nfp_port_get_fecparam(struct net_device * netdev,struct ethtool_fecparam * param)1236 nfp_port_get_fecparam(struct net_device *netdev,
1237 struct ethtool_fecparam *param)
1238 {
1239 struct nfp_eth_table_port *eth_port;
1240 struct nfp_port *port;
1241
1242 param->active_fec = ETHTOOL_FEC_NONE;
1243 param->fec = ETHTOOL_FEC_NONE;
1244
1245 port = nfp_port_from_netdev(netdev);
1246 eth_port = nfp_port_get_eth_port(port);
1247 if (!eth_port)
1248 return -EOPNOTSUPP;
1249
1250 if (!nfp_eth_can_support_fec(eth_port))
1251 return 0;
1252
1253 param->fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec_modes_supported);
1254 param->active_fec = nfp_port_fec_nsp_to_ethtool(BIT(eth_port->act_fec));
1255
1256 return 0;
1257 }
1258
1259 static int
nfp_port_set_fecparam(struct net_device * netdev,struct ethtool_fecparam * param)1260 nfp_port_set_fecparam(struct net_device *netdev,
1261 struct ethtool_fecparam *param)
1262 {
1263 struct nfp_eth_table_port *eth_port;
1264 struct nfp_port *port;
1265 int err, fec;
1266
1267 port = nfp_port_from_netdev(netdev);
1268 eth_port = nfp_port_get_eth_port(port);
1269 if (!eth_port)
1270 return -EOPNOTSUPP;
1271
1272 if (!nfp_eth_can_support_fec(eth_port))
1273 return -EOPNOTSUPP;
1274
1275 fec = nfp_port_fec_ethtool_to_nsp(param->fec);
1276 if (fec < 0)
1277 return fec;
1278
1279 err = nfp_eth_set_fec(port->app->cpp, eth_port->index, fec);
1280 if (!err)
1281 /* Only refresh if we did something */
1282 nfp_net_refresh_port_table(port);
1283
1284 return err < 0 ? err : 0;
1285 }
1286
1287 /* RX network flow classification (RSS, filters, etc)
1288 */
ethtool_flow_to_nfp_flag(u32 flow_type)1289 static u32 ethtool_flow_to_nfp_flag(u32 flow_type)
1290 {
1291 static const u32 xlate_ethtool_to_nfp[IPV6_FLOW + 1] = {
1292 [TCP_V4_FLOW] = NFP_NET_CFG_RSS_IPV4_TCP,
1293 [TCP_V6_FLOW] = NFP_NET_CFG_RSS_IPV6_TCP,
1294 [UDP_V4_FLOW] = NFP_NET_CFG_RSS_IPV4_UDP,
1295 [UDP_V6_FLOW] = NFP_NET_CFG_RSS_IPV6_UDP,
1296 [IPV4_FLOW] = NFP_NET_CFG_RSS_IPV4,
1297 [IPV6_FLOW] = NFP_NET_CFG_RSS_IPV6,
1298 };
1299
1300 if (flow_type >= ARRAY_SIZE(xlate_ethtool_to_nfp))
1301 return 0;
1302
1303 return xlate_ethtool_to_nfp[flow_type];
1304 }
1305
nfp_net_get_rxfh_fields(struct net_device * netdev,struct ethtool_rxfh_fields * cmd)1306 static int nfp_net_get_rxfh_fields(struct net_device *netdev,
1307 struct ethtool_rxfh_fields *cmd)
1308 {
1309 struct nfp_net *nn = netdev_priv(netdev);
1310 u32 nfp_rss_flag;
1311
1312 cmd->data = 0;
1313
1314 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1315 return -EOPNOTSUPP;
1316
1317 nfp_rss_flag = ethtool_flow_to_nfp_flag(cmd->flow_type);
1318 if (!nfp_rss_flag)
1319 return -EINVAL;
1320
1321 cmd->data |= RXH_IP_SRC | RXH_IP_DST;
1322 if (nn->rss_cfg & nfp_rss_flag)
1323 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
1324
1325 return 0;
1326 }
1327
1328 #define NFP_FS_MAX_ENTRY 1024
1329
nfp_net_fs_to_ethtool(struct nfp_fs_entry * entry,struct ethtool_rxnfc * cmd)1330 static int nfp_net_fs_to_ethtool(struct nfp_fs_entry *entry, struct ethtool_rxnfc *cmd)
1331 {
1332 struct ethtool_rx_flow_spec *fs = &cmd->fs;
1333 unsigned int i;
1334
1335 switch (entry->flow_type & ~FLOW_RSS) {
1336 case TCP_V4_FLOW:
1337 case UDP_V4_FLOW:
1338 case SCTP_V4_FLOW:
1339 fs->h_u.tcp_ip4_spec.ip4src = entry->key.sip4;
1340 fs->h_u.tcp_ip4_spec.ip4dst = entry->key.dip4;
1341 fs->h_u.tcp_ip4_spec.psrc = entry->key.sport;
1342 fs->h_u.tcp_ip4_spec.pdst = entry->key.dport;
1343 fs->m_u.tcp_ip4_spec.ip4src = entry->msk.sip4;
1344 fs->m_u.tcp_ip4_spec.ip4dst = entry->msk.dip4;
1345 fs->m_u.tcp_ip4_spec.psrc = entry->msk.sport;
1346 fs->m_u.tcp_ip4_spec.pdst = entry->msk.dport;
1347 break;
1348 case TCP_V6_FLOW:
1349 case UDP_V6_FLOW:
1350 case SCTP_V6_FLOW:
1351 for (i = 0; i < 4; i++) {
1352 fs->h_u.tcp_ip6_spec.ip6src[i] = entry->key.sip6[i];
1353 fs->h_u.tcp_ip6_spec.ip6dst[i] = entry->key.dip6[i];
1354 fs->m_u.tcp_ip6_spec.ip6src[i] = entry->msk.sip6[i];
1355 fs->m_u.tcp_ip6_spec.ip6dst[i] = entry->msk.dip6[i];
1356 }
1357 fs->h_u.tcp_ip6_spec.psrc = entry->key.sport;
1358 fs->h_u.tcp_ip6_spec.pdst = entry->key.dport;
1359 fs->m_u.tcp_ip6_spec.psrc = entry->msk.sport;
1360 fs->m_u.tcp_ip6_spec.pdst = entry->msk.dport;
1361 break;
1362 case IPV4_USER_FLOW:
1363 fs->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
1364 fs->h_u.usr_ip4_spec.ip4src = entry->key.sip4;
1365 fs->h_u.usr_ip4_spec.ip4dst = entry->key.dip4;
1366 fs->h_u.usr_ip4_spec.proto = entry->key.l4_proto;
1367 fs->m_u.usr_ip4_spec.ip4src = entry->msk.sip4;
1368 fs->m_u.usr_ip4_spec.ip4dst = entry->msk.dip4;
1369 fs->m_u.usr_ip4_spec.proto = entry->msk.l4_proto;
1370 break;
1371 case IPV6_USER_FLOW:
1372 for (i = 0; i < 4; i++) {
1373 fs->h_u.usr_ip6_spec.ip6src[i] = entry->key.sip6[i];
1374 fs->h_u.usr_ip6_spec.ip6dst[i] = entry->key.dip6[i];
1375 fs->m_u.usr_ip6_spec.ip6src[i] = entry->msk.sip6[i];
1376 fs->m_u.usr_ip6_spec.ip6dst[i] = entry->msk.dip6[i];
1377 }
1378 fs->h_u.usr_ip6_spec.l4_proto = entry->key.l4_proto;
1379 fs->m_u.usr_ip6_spec.l4_proto = entry->msk.l4_proto;
1380 break;
1381 case ETHER_FLOW:
1382 fs->h_u.ether_spec.h_proto = entry->key.l3_proto;
1383 fs->m_u.ether_spec.h_proto = entry->msk.l3_proto;
1384 break;
1385 default:
1386 return -EINVAL;
1387 }
1388
1389 fs->flow_type = entry->flow_type;
1390 fs->ring_cookie = entry->action;
1391
1392 if (fs->flow_type & FLOW_RSS) {
1393 /* Only rss_context of 0 is supported. */
1394 cmd->rss_context = 0;
1395 /* RSS is used, mask the ring. */
1396 fs->ring_cookie |= ETHTOOL_RX_FLOW_SPEC_RING;
1397 }
1398
1399 return 0;
1400 }
1401
nfp_net_get_fs_rule(struct nfp_net * nn,struct ethtool_rxnfc * cmd)1402 static int nfp_net_get_fs_rule(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
1403 {
1404 struct nfp_fs_entry *entry;
1405
1406 if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1407 return -EOPNOTSUPP;
1408
1409 if (cmd->fs.location >= NFP_FS_MAX_ENTRY)
1410 return -EINVAL;
1411
1412 list_for_each_entry(entry, &nn->fs.list, node) {
1413 if (entry->loc == cmd->fs.location)
1414 return nfp_net_fs_to_ethtool(entry, cmd);
1415
1416 if (entry->loc > cmd->fs.location)
1417 /* no need to continue */
1418 return -ENOENT;
1419 }
1420
1421 return -ENOENT;
1422 }
1423
nfp_net_get_fs_loc(struct nfp_net * nn,u32 * rule_locs)1424 static int nfp_net_get_fs_loc(struct nfp_net *nn, u32 *rule_locs)
1425 {
1426 struct nfp_fs_entry *entry;
1427 u32 count = 0;
1428
1429 if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1430 return -EOPNOTSUPP;
1431
1432 list_for_each_entry(entry, &nn->fs.list, node)
1433 rule_locs[count++] = entry->loc;
1434
1435 return 0;
1436 }
1437
nfp_net_get_rx_ring_count(struct net_device * netdev)1438 static u32 nfp_net_get_rx_ring_count(struct net_device *netdev)
1439 {
1440 struct nfp_net *nn = netdev_priv(netdev);
1441
1442 return nn->dp.num_rx_rings;
1443 }
1444
nfp_net_get_rxnfc(struct net_device * netdev,struct ethtool_rxnfc * cmd,u32 * rule_locs)1445 static int nfp_net_get_rxnfc(struct net_device *netdev,
1446 struct ethtool_rxnfc *cmd, u32 *rule_locs)
1447 {
1448 struct nfp_net *nn = netdev_priv(netdev);
1449
1450 switch (cmd->cmd) {
1451 case ETHTOOL_GRXCLSRLCNT:
1452 cmd->rule_cnt = nn->fs.count;
1453 return 0;
1454 case ETHTOOL_GRXCLSRULE:
1455 return nfp_net_get_fs_rule(nn, cmd);
1456 case ETHTOOL_GRXCLSRLALL:
1457 cmd->data = NFP_FS_MAX_ENTRY;
1458 return nfp_net_get_fs_loc(nn, rule_locs);
1459 default:
1460 return -EOPNOTSUPP;
1461 }
1462 }
1463
nfp_net_set_rxfh_fields(struct net_device * netdev,const struct ethtool_rxfh_fields * nfc,struct netlink_ext_ack * extack)1464 static int nfp_net_set_rxfh_fields(struct net_device *netdev,
1465 const struct ethtool_rxfh_fields *nfc,
1466 struct netlink_ext_ack *extack)
1467 {
1468 struct nfp_net *nn = netdev_priv(netdev);
1469 u32 new_rss_cfg = nn->rss_cfg;
1470 u32 nfp_rss_flag;
1471 int err;
1472
1473 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1474 return -EOPNOTSUPP;
1475
1476 /* RSS only supports IP SA/DA and L4 src/dst ports */
1477 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1478 RXH_L4_B_0_1 | RXH_L4_B_2_3))
1479 return -EINVAL;
1480
1481 /* We need at least the IP SA/DA fields for hashing */
1482 if (!(nfc->data & RXH_IP_SRC) ||
1483 !(nfc->data & RXH_IP_DST))
1484 return -EINVAL;
1485
1486 nfp_rss_flag = ethtool_flow_to_nfp_flag(nfc->flow_type);
1487 if (!nfp_rss_flag)
1488 return -EINVAL;
1489
1490 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1491 case 0:
1492 new_rss_cfg &= ~nfp_rss_flag;
1493 break;
1494 case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1495 new_rss_cfg |= nfp_rss_flag;
1496 break;
1497 default:
1498 return -EINVAL;
1499 }
1500
1501 new_rss_cfg |= FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc);
1502 new_rss_cfg |= NFP_NET_CFG_RSS_MASK;
1503
1504 if (new_rss_cfg == nn->rss_cfg)
1505 return 0;
1506
1507 writel(new_rss_cfg, nn->dp.ctrl_bar + NFP_NET_CFG_RSS_CTRL);
1508 err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
1509 if (err)
1510 return err;
1511
1512 nn->rss_cfg = new_rss_cfg;
1513
1514 nn_dbg(nn, "Changed RSS config to 0x%x\n", nn->rss_cfg);
1515 return 0;
1516 }
1517
nfp_net_fs_from_ethtool(struct nfp_fs_entry * entry,struct ethtool_rx_flow_spec * fs)1518 static int nfp_net_fs_from_ethtool(struct nfp_fs_entry *entry, struct ethtool_rx_flow_spec *fs)
1519 {
1520 unsigned int i;
1521
1522 /* FLOW_EXT/FLOW_MAC_EXT is not supported. */
1523 switch (fs->flow_type & ~FLOW_RSS) {
1524 case TCP_V4_FLOW:
1525 case UDP_V4_FLOW:
1526 case SCTP_V4_FLOW:
1527 entry->msk.sip4 = fs->m_u.tcp_ip4_spec.ip4src;
1528 entry->msk.dip4 = fs->m_u.tcp_ip4_spec.ip4dst;
1529 entry->msk.sport = fs->m_u.tcp_ip4_spec.psrc;
1530 entry->msk.dport = fs->m_u.tcp_ip4_spec.pdst;
1531 entry->key.sip4 = fs->h_u.tcp_ip4_spec.ip4src & entry->msk.sip4;
1532 entry->key.dip4 = fs->h_u.tcp_ip4_spec.ip4dst & entry->msk.dip4;
1533 entry->key.sport = fs->h_u.tcp_ip4_spec.psrc & entry->msk.sport;
1534 entry->key.dport = fs->h_u.tcp_ip4_spec.pdst & entry->msk.dport;
1535 break;
1536 case TCP_V6_FLOW:
1537 case UDP_V6_FLOW:
1538 case SCTP_V6_FLOW:
1539 for (i = 0; i < 4; i++) {
1540 entry->msk.sip6[i] = fs->m_u.tcp_ip6_spec.ip6src[i];
1541 entry->msk.dip6[i] = fs->m_u.tcp_ip6_spec.ip6dst[i];
1542 entry->key.sip6[i] = fs->h_u.tcp_ip6_spec.ip6src[i] & entry->msk.sip6[i];
1543 entry->key.dip6[i] = fs->h_u.tcp_ip6_spec.ip6dst[i] & entry->msk.dip6[i];
1544 }
1545 entry->msk.sport = fs->m_u.tcp_ip6_spec.psrc;
1546 entry->msk.dport = fs->m_u.tcp_ip6_spec.pdst;
1547 entry->key.sport = fs->h_u.tcp_ip6_spec.psrc & entry->msk.sport;
1548 entry->key.dport = fs->h_u.tcp_ip6_spec.pdst & entry->msk.dport;
1549 break;
1550 case IPV4_USER_FLOW:
1551 entry->msk.sip4 = fs->m_u.usr_ip4_spec.ip4src;
1552 entry->msk.dip4 = fs->m_u.usr_ip4_spec.ip4dst;
1553 entry->msk.l4_proto = fs->m_u.usr_ip4_spec.proto;
1554 entry->key.sip4 = fs->h_u.usr_ip4_spec.ip4src & entry->msk.sip4;
1555 entry->key.dip4 = fs->h_u.usr_ip4_spec.ip4dst & entry->msk.dip4;
1556 entry->key.l4_proto = fs->h_u.usr_ip4_spec.proto & entry->msk.l4_proto;
1557 break;
1558 case IPV6_USER_FLOW:
1559 for (i = 0; i < 4; i++) {
1560 entry->msk.sip6[i] = fs->m_u.usr_ip6_spec.ip6src[i];
1561 entry->msk.dip6[i] = fs->m_u.usr_ip6_spec.ip6dst[i];
1562 entry->key.sip6[i] = fs->h_u.usr_ip6_spec.ip6src[i] & entry->msk.sip6[i];
1563 entry->key.dip6[i] = fs->h_u.usr_ip6_spec.ip6dst[i] & entry->msk.dip6[i];
1564 }
1565 entry->msk.l4_proto = fs->m_u.usr_ip6_spec.l4_proto;
1566 entry->key.l4_proto = fs->h_u.usr_ip6_spec.l4_proto & entry->msk.l4_proto;
1567 break;
1568 case ETHER_FLOW:
1569 entry->msk.l3_proto = fs->m_u.ether_spec.h_proto;
1570 entry->key.l3_proto = fs->h_u.ether_spec.h_proto & entry->msk.l3_proto;
1571 break;
1572 default:
1573 return -EINVAL;
1574 }
1575
1576 switch (fs->flow_type & ~FLOW_RSS) {
1577 case TCP_V4_FLOW:
1578 case TCP_V6_FLOW:
1579 entry->key.l4_proto = IPPROTO_TCP;
1580 entry->msk.l4_proto = 0xff;
1581 break;
1582 case UDP_V4_FLOW:
1583 case UDP_V6_FLOW:
1584 entry->key.l4_proto = IPPROTO_UDP;
1585 entry->msk.l4_proto = 0xff;
1586 break;
1587 case SCTP_V4_FLOW:
1588 case SCTP_V6_FLOW:
1589 entry->key.l4_proto = IPPROTO_SCTP;
1590 entry->msk.l4_proto = 0xff;
1591 break;
1592 }
1593
1594 entry->flow_type = fs->flow_type;
1595 entry->action = fs->ring_cookie;
1596 entry->loc = fs->location;
1597
1598 return 0;
1599 }
1600
nfp_net_fs_check_existing(struct nfp_net * nn,struct nfp_fs_entry * new)1601 static int nfp_net_fs_check_existing(struct nfp_net *nn, struct nfp_fs_entry *new)
1602 {
1603 struct nfp_fs_entry *entry;
1604
1605 list_for_each_entry(entry, &nn->fs.list, node) {
1606 if (new->loc != entry->loc &&
1607 !((new->flow_type ^ entry->flow_type) & ~FLOW_RSS) &&
1608 !memcmp(&new->key, &entry->key, sizeof(new->key)) &&
1609 !memcmp(&new->msk, &entry->msk, sizeof(new->msk)))
1610 return entry->loc;
1611 }
1612
1613 /* -1 means no duplicates */
1614 return -1;
1615 }
1616
nfp_net_fs_add(struct nfp_net * nn,struct ethtool_rxnfc * cmd)1617 static int nfp_net_fs_add(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
1618 {
1619 struct ethtool_rx_flow_spec *fs = &cmd->fs;
1620 struct nfp_fs_entry *new, *entry;
1621 bool unsupp_mask;
1622 int err, id;
1623
1624 if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1625 return -EOPNOTSUPP;
1626
1627 /* Only default RSS context(0) is supported. */
1628 if ((fs->flow_type & FLOW_RSS) && cmd->rss_context)
1629 return -EOPNOTSUPP;
1630
1631 if (fs->location >= NFP_FS_MAX_ENTRY)
1632 return -EINVAL;
1633
1634 if (fs->ring_cookie != RX_CLS_FLOW_DISC &&
1635 fs->ring_cookie >= nn->dp.num_rx_rings)
1636 return -EINVAL;
1637
1638 /* FLOW_EXT/FLOW_MAC_EXT is not supported. */
1639 switch (fs->flow_type & ~FLOW_RSS) {
1640 case TCP_V4_FLOW:
1641 case UDP_V4_FLOW:
1642 case SCTP_V4_FLOW:
1643 unsupp_mask = !!fs->m_u.tcp_ip4_spec.tos;
1644 break;
1645 case TCP_V6_FLOW:
1646 case UDP_V6_FLOW:
1647 case SCTP_V6_FLOW:
1648 unsupp_mask = !!fs->m_u.tcp_ip6_spec.tclass;
1649 break;
1650 case IPV4_USER_FLOW:
1651 unsupp_mask = !!fs->m_u.usr_ip4_spec.l4_4_bytes ||
1652 !!fs->m_u.usr_ip4_spec.tos ||
1653 !!fs->m_u.usr_ip4_spec.ip_ver;
1654 /* ip_ver must be ETH_RX_NFC_IP4. */
1655 unsupp_mask |= fs->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4;
1656 break;
1657 case IPV6_USER_FLOW:
1658 unsupp_mask = !!fs->m_u.usr_ip6_spec.l4_4_bytes ||
1659 !!fs->m_u.usr_ip6_spec.tclass;
1660 break;
1661 case ETHER_FLOW:
1662 if (fs->h_u.ether_spec.h_proto == htons(ETH_P_IP) ||
1663 fs->h_u.ether_spec.h_proto == htons(ETH_P_IPV6)) {
1664 nn_err(nn, "Please use ip4/ip6 flow type instead.\n");
1665 return -EOPNOTSUPP;
1666 }
1667 /* Only unmasked ethtype is supported. */
1668 unsupp_mask = !is_zero_ether_addr(fs->m_u.ether_spec.h_dest) ||
1669 !is_zero_ether_addr(fs->m_u.ether_spec.h_source) ||
1670 (fs->m_u.ether_spec.h_proto != htons(0xffff));
1671 break;
1672 default:
1673 return -EOPNOTSUPP;
1674 }
1675
1676 if (unsupp_mask)
1677 return -EOPNOTSUPP;
1678
1679 new = kzalloc_obj(*new);
1680 if (!new)
1681 return -ENOMEM;
1682
1683 nfp_net_fs_from_ethtool(new, fs);
1684
1685 id = nfp_net_fs_check_existing(nn, new);
1686 if (id >= 0) {
1687 nn_err(nn, "Identical rule is existing in %d.\n", id);
1688 err = -EINVAL;
1689 goto err;
1690 }
1691
1692 /* Insert to list in ascending order of location. */
1693 list_for_each_entry(entry, &nn->fs.list, node) {
1694 if (entry->loc == fs->location) {
1695 err = nfp_net_fs_del_hw(nn, entry);
1696 if (err)
1697 goto err;
1698
1699 nn->fs.count--;
1700 err = nfp_net_fs_add_hw(nn, new);
1701 if (err)
1702 goto err;
1703
1704 nn->fs.count++;
1705 list_replace(&entry->node, &new->node);
1706 kfree(entry);
1707
1708 return 0;
1709 }
1710
1711 if (entry->loc > fs->location)
1712 break;
1713 }
1714
1715 if (nn->fs.count == NFP_FS_MAX_ENTRY) {
1716 err = -ENOSPC;
1717 goto err;
1718 }
1719
1720 err = nfp_net_fs_add_hw(nn, new);
1721 if (err)
1722 goto err;
1723
1724 list_add_tail(&new->node, &entry->node);
1725 nn->fs.count++;
1726
1727 return 0;
1728
1729 err:
1730 kfree(new);
1731 return err;
1732 }
1733
nfp_net_fs_del(struct nfp_net * nn,struct ethtool_rxnfc * cmd)1734 static int nfp_net_fs_del(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
1735 {
1736 struct nfp_fs_entry *entry;
1737 int err;
1738
1739 if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1740 return -EOPNOTSUPP;
1741
1742 if (!nn->fs.count || cmd->fs.location >= NFP_FS_MAX_ENTRY)
1743 return -EINVAL;
1744
1745 list_for_each_entry(entry, &nn->fs.list, node) {
1746 if (entry->loc == cmd->fs.location) {
1747 err = nfp_net_fs_del_hw(nn, entry);
1748 if (err)
1749 return err;
1750
1751 list_del(&entry->node);
1752 kfree(entry);
1753 nn->fs.count--;
1754
1755 return 0;
1756 } else if (entry->loc > cmd->fs.location) {
1757 /* no need to continue */
1758 break;
1759 }
1760 }
1761
1762 return -ENOENT;
1763 }
1764
nfp_net_set_rxnfc(struct net_device * netdev,struct ethtool_rxnfc * cmd)1765 static int nfp_net_set_rxnfc(struct net_device *netdev,
1766 struct ethtool_rxnfc *cmd)
1767 {
1768 struct nfp_net *nn = netdev_priv(netdev);
1769
1770 switch (cmd->cmd) {
1771 case ETHTOOL_SRXCLSRLINS:
1772 return nfp_net_fs_add(nn, cmd);
1773 case ETHTOOL_SRXCLSRLDEL:
1774 return nfp_net_fs_del(nn, cmd);
1775 default:
1776 return -EOPNOTSUPP;
1777 }
1778 }
1779
nfp_net_get_rxfh_indir_size(struct net_device * netdev)1780 static u32 nfp_net_get_rxfh_indir_size(struct net_device *netdev)
1781 {
1782 struct nfp_net *nn = netdev_priv(netdev);
1783
1784 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1785 return 0;
1786
1787 return ARRAY_SIZE(nn->rss_itbl);
1788 }
1789
nfp_net_get_rxfh_key_size(struct net_device * netdev)1790 static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev)
1791 {
1792 struct nfp_net *nn = netdev_priv(netdev);
1793
1794 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1795 return 0;
1796
1797 return nfp_net_rss_key_sz(nn);
1798 }
1799
nfp_net_get_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh)1800 static int nfp_net_get_rxfh(struct net_device *netdev,
1801 struct ethtool_rxfh_param *rxfh)
1802 {
1803 struct nfp_net *nn = netdev_priv(netdev);
1804 int i;
1805
1806 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1807 return -EOPNOTSUPP;
1808
1809 if (rxfh->indir)
1810 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
1811 rxfh->indir[i] = nn->rss_itbl[i];
1812 if (rxfh->key)
1813 memcpy(rxfh->key, nn->rss_key, nfp_net_rss_key_sz(nn));
1814
1815 rxfh->hfunc = nn->rss_hfunc;
1816 if (rxfh->hfunc >= 1 << ETH_RSS_HASH_FUNCS_COUNT)
1817 rxfh->hfunc = ETH_RSS_HASH_UNKNOWN;
1818
1819 return 0;
1820 }
1821
nfp_net_set_rxfh(struct net_device * netdev,struct ethtool_rxfh_param * rxfh,struct netlink_ext_ack * extack)1822 static int nfp_net_set_rxfh(struct net_device *netdev,
1823 struct ethtool_rxfh_param *rxfh,
1824 struct netlink_ext_ack *extack)
1825 {
1826 struct nfp_net *nn = netdev_priv(netdev);
1827 int i;
1828
1829 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY) ||
1830 !(rxfh->hfunc == ETH_RSS_HASH_NO_CHANGE ||
1831 rxfh->hfunc == nn->rss_hfunc))
1832 return -EOPNOTSUPP;
1833
1834 if (!rxfh->key && !rxfh->indir)
1835 return 0;
1836
1837 if (rxfh->key) {
1838 memcpy(nn->rss_key, rxfh->key, nfp_net_rss_key_sz(nn));
1839 nfp_net_rss_write_key(nn);
1840 }
1841 if (rxfh->indir) {
1842 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
1843 nn->rss_itbl[i] = rxfh->indir[i];
1844
1845 nfp_net_rss_write_itbl(nn);
1846 }
1847
1848 return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
1849 }
1850
1851 /* Dump BAR registers
1852 */
nfp_net_get_regs_len(struct net_device * netdev)1853 static int nfp_net_get_regs_len(struct net_device *netdev)
1854 {
1855 return NFP_NET_CFG_BAR_SZ;
1856 }
1857
nfp_net_get_regs(struct net_device * netdev,struct ethtool_regs * regs,void * p)1858 static void nfp_net_get_regs(struct net_device *netdev,
1859 struct ethtool_regs *regs, void *p)
1860 {
1861 struct nfp_net *nn = netdev_priv(netdev);
1862 u32 *regs_buf = p;
1863 int i;
1864
1865 regs->version = nn_readl(nn, NFP_NET_CFG_VERSION);
1866
1867 for (i = 0; i < NFP_NET_CFG_BAR_SZ / sizeof(u32); i++)
1868 regs_buf[i] = readl(nn->dp.ctrl_bar + (i * sizeof(u32)));
1869 }
1870
nfp_net_get_coalesce(struct net_device * netdev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)1871 static int nfp_net_get_coalesce(struct net_device *netdev,
1872 struct ethtool_coalesce *ec,
1873 struct kernel_ethtool_coalesce *kernel_coal,
1874 struct netlink_ext_ack *extack)
1875 {
1876 struct nfp_net *nn = netdev_priv(netdev);
1877
1878 if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
1879 return -EOPNOTSUPP;
1880
1881 ec->use_adaptive_rx_coalesce = nn->rx_coalesce_adapt_on;
1882 ec->use_adaptive_tx_coalesce = nn->tx_coalesce_adapt_on;
1883
1884 ec->rx_coalesce_usecs = nn->rx_coalesce_usecs;
1885 ec->rx_max_coalesced_frames = nn->rx_coalesce_max_frames;
1886 ec->tx_coalesce_usecs = nn->tx_coalesce_usecs;
1887 ec->tx_max_coalesced_frames = nn->tx_coalesce_max_frames;
1888
1889 return 0;
1890 }
1891
1892 /* Other debug dumps
1893 */
1894 static int
nfp_dump_nsp_diag(struct nfp_app * app,struct ethtool_dump * dump,void * buffer)1895 nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer)
1896 {
1897 struct nfp_resource *res;
1898 int ret;
1899
1900 if (!app)
1901 return -EOPNOTSUPP;
1902
1903 dump->version = 1;
1904 dump->flag = NFP_DUMP_NSP_DIAG;
1905
1906 res = nfp_resource_acquire(app->cpp, NFP_RESOURCE_NSP_DIAG);
1907 if (IS_ERR(res))
1908 return PTR_ERR(res);
1909
1910 if (buffer) {
1911 if (dump->len != nfp_resource_size(res)) {
1912 ret = -EINVAL;
1913 goto exit_release;
1914 }
1915
1916 ret = nfp_cpp_read(app->cpp, nfp_resource_cpp_id(res),
1917 nfp_resource_address(res),
1918 buffer, dump->len);
1919 if (ret != dump->len)
1920 ret = ret < 0 ? ret : -EIO;
1921 else
1922 ret = 0;
1923 } else {
1924 dump->len = nfp_resource_size(res);
1925 ret = 0;
1926 }
1927 exit_release:
1928 nfp_resource_release(res);
1929
1930 return ret;
1931 }
1932
1933 /* Set the dump flag/level. Calculate the dump length for flag > 0 only (new TLV
1934 * based dumps), since flag 0 (default) calculates the length in
1935 * nfp_app_get_dump_flag(), and we need to support triggering a level 0 dump
1936 * without setting the flag first, for backward compatibility.
1937 */
nfp_app_set_dump(struct net_device * netdev,struct ethtool_dump * val)1938 static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1939 {
1940 struct nfp_app *app = nfp_app_from_netdev(netdev);
1941 s64 len;
1942
1943 if (!app)
1944 return -EOPNOTSUPP;
1945
1946 if (val->flag == NFP_DUMP_NSP_DIAG) {
1947 app->pf->dump_flag = val->flag;
1948 return 0;
1949 }
1950
1951 if (!app->pf->dumpspec)
1952 return -EOPNOTSUPP;
1953
1954 len = nfp_net_dump_calculate_size(app->pf, app->pf->dumpspec,
1955 val->flag);
1956 if (len < 0)
1957 return len;
1958
1959 app->pf->dump_flag = val->flag;
1960 app->pf->dump_len = len;
1961
1962 return 0;
1963 }
1964
1965 static int
nfp_app_get_dump_flag(struct net_device * netdev,struct ethtool_dump * dump)1966 nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1967 {
1968 struct nfp_app *app = nfp_app_from_netdev(netdev);
1969
1970 if (!app)
1971 return -EOPNOTSUPP;
1972
1973 if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1974 return nfp_dump_nsp_diag(app, dump, NULL);
1975
1976 dump->flag = app->pf->dump_flag;
1977 dump->len = app->pf->dump_len;
1978
1979 return 0;
1980 }
1981
1982 static int
nfp_app_get_dump_data(struct net_device * netdev,struct ethtool_dump * dump,void * buffer)1983 nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1984 void *buffer)
1985 {
1986 struct nfp_app *app = nfp_app_from_netdev(netdev);
1987
1988 if (!app)
1989 return -EOPNOTSUPP;
1990
1991 if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1992 return nfp_dump_nsp_diag(app, dump, buffer);
1993
1994 dump->flag = app->pf->dump_flag;
1995 dump->len = app->pf->dump_len;
1996
1997 return nfp_net_dump_populate_buffer(app->pf, app->pf->dumpspec, dump,
1998 buffer);
1999 }
2000
2001 static int
nfp_port_get_module_info(struct net_device * netdev,struct ethtool_modinfo * modinfo)2002 nfp_port_get_module_info(struct net_device *netdev,
2003 struct ethtool_modinfo *modinfo)
2004 {
2005 struct nfp_eth_table_port *eth_port;
2006 struct nfp_port *port;
2007 unsigned int read_len;
2008 struct nfp_nsp *nsp;
2009 int err = 0;
2010 u8 data;
2011
2012 port = nfp_port_from_netdev(netdev);
2013 if (!port)
2014 return -EOPNOTSUPP;
2015
2016 /* update port state to get latest interface */
2017 set_bit(NFP_PORT_CHANGED, &port->flags);
2018 eth_port = nfp_port_get_eth_port(port);
2019 if (!eth_port)
2020 return -EOPNOTSUPP;
2021
2022 nsp = nfp_nsp_open(port->app->cpp);
2023 if (IS_ERR(nsp)) {
2024 err = PTR_ERR(nsp);
2025 netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2026 return err;
2027 }
2028
2029 if (!nfp_nsp_has_read_module_eeprom(nsp)) {
2030 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
2031 err = -EOPNOTSUPP;
2032 goto exit_close_nsp;
2033 }
2034
2035 switch (eth_port->interface) {
2036 case NFP_INTERFACE_SFP:
2037 case NFP_INTERFACE_SFP28:
2038 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2039 SFP_SFF8472_COMPLIANCE, &data,
2040 1, &read_len);
2041 if (err < 0)
2042 goto exit_close_nsp;
2043
2044 if (!data) {
2045 modinfo->type = ETH_MODULE_SFF_8079;
2046 modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
2047 } else {
2048 modinfo->type = ETH_MODULE_SFF_8472;
2049 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
2050 }
2051 break;
2052 case NFP_INTERFACE_QSFP:
2053 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2054 SFP_SFF_REV_COMPLIANCE, &data,
2055 1, &read_len);
2056 if (err < 0)
2057 goto exit_close_nsp;
2058
2059 if (data < 0x3) {
2060 modinfo->type = ETH_MODULE_SFF_8436;
2061 modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
2062 } else {
2063 modinfo->type = ETH_MODULE_SFF_8636;
2064 modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
2065 }
2066 break;
2067 case NFP_INTERFACE_QSFP28:
2068 modinfo->type = ETH_MODULE_SFF_8636;
2069 modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
2070 break;
2071 default:
2072 netdev_err(netdev, "Unsupported module 0x%x detected\n",
2073 eth_port->interface);
2074 err = -EINVAL;
2075 }
2076
2077 exit_close_nsp:
2078 nfp_nsp_close(nsp);
2079 return err;
2080 }
2081
2082 static int
nfp_port_get_module_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * data)2083 nfp_port_get_module_eeprom(struct net_device *netdev,
2084 struct ethtool_eeprom *eeprom, u8 *data)
2085 {
2086 struct nfp_eth_table_port *eth_port;
2087 struct nfp_port *port;
2088 struct nfp_nsp *nsp;
2089 int err;
2090
2091 port = nfp_port_from_netdev(netdev);
2092 eth_port = __nfp_port_get_eth_port(port);
2093 if (!eth_port)
2094 return -EOPNOTSUPP;
2095
2096 nsp = nfp_nsp_open(port->app->cpp);
2097 if (IS_ERR(nsp)) {
2098 err = PTR_ERR(nsp);
2099 netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2100 return err;
2101 }
2102
2103 if (!nfp_nsp_has_read_module_eeprom(nsp)) {
2104 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
2105 err = -EOPNOTSUPP;
2106 goto exit_close_nsp;
2107 }
2108
2109 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2110 eeprom->offset, data, eeprom->len,
2111 &eeprom->len);
2112 if (err < 0) {
2113 if (eeprom->len) {
2114 netdev_warn(netdev,
2115 "Incomplete read from module EEPROM: %d\n",
2116 err);
2117 err = 0;
2118 } else {
2119 netdev_err(netdev,
2120 "Reading from module EEPROM failed: %d\n",
2121 err);
2122 }
2123 }
2124
2125 exit_close_nsp:
2126 nfp_nsp_close(nsp);
2127 return err;
2128 }
2129
nfp_net_set_coalesce(struct net_device * netdev,struct ethtool_coalesce * ec,struct kernel_ethtool_coalesce * kernel_coal,struct netlink_ext_ack * extack)2130 static int nfp_net_set_coalesce(struct net_device *netdev,
2131 struct ethtool_coalesce *ec,
2132 struct kernel_ethtool_coalesce *kernel_coal,
2133 struct netlink_ext_ack *extack)
2134 {
2135 struct nfp_net *nn = netdev_priv(netdev);
2136 unsigned int factor;
2137
2138 /* Compute factor used to convert coalesce '_usecs' parameters to
2139 * ME timestamp ticks. There are 16 ME clock cycles for each timestamp
2140 * count.
2141 */
2142 factor = nn->tlv_caps.me_freq_mhz / 16;
2143
2144 /* Each pair of (usecs, max_frames) fields specifies that interrupts
2145 * should be coalesced until
2146 * (usecs > 0 && time_since_first_completion >= usecs) ||
2147 * (max_frames > 0 && completed_frames >= max_frames)
2148 *
2149 * It is illegal to set both usecs and max_frames to zero as this would
2150 * cause interrupts to never be generated. To disable coalescing, set
2151 * usecs = 0 and max_frames = 1.
2152 *
2153 * Some implementations ignore the value of max_frames and use the
2154 * condition time_since_first_completion >= usecs
2155 */
2156
2157 if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
2158 return -EOPNOTSUPP;
2159
2160 /* ensure valid configuration */
2161 if (!ec->rx_coalesce_usecs && !ec->rx_max_coalesced_frames) {
2162 NL_SET_ERR_MSG_MOD(extack,
2163 "rx-usecs and rx-frames cannot both be zero");
2164 return -EINVAL;
2165 }
2166
2167 if (!ec->tx_coalesce_usecs && !ec->tx_max_coalesced_frames) {
2168 NL_SET_ERR_MSG_MOD(extack,
2169 "tx-usecs and tx-frames cannot both be zero");
2170 return -EINVAL;
2171 }
2172
2173 if (nfp_net_coalesce_para_check(ec->rx_coalesce_usecs * factor)) {
2174 NL_SET_ERR_MSG_MOD(extack, "rx-usecs too large");
2175 return -EINVAL;
2176 }
2177
2178 if (nfp_net_coalesce_para_check(ec->rx_max_coalesced_frames)) {
2179 NL_SET_ERR_MSG_MOD(extack, "rx-frames too large");
2180 return -EINVAL;
2181 }
2182
2183 if (nfp_net_coalesce_para_check(ec->tx_coalesce_usecs * factor)) {
2184 NL_SET_ERR_MSG_MOD(extack, "tx-usecs too large");
2185 return -EINVAL;
2186 }
2187
2188 if (nfp_net_coalesce_para_check(ec->tx_max_coalesced_frames)) {
2189 NL_SET_ERR_MSG_MOD(extack, "tx-frames too large");
2190 return -EINVAL;
2191 }
2192
2193 /* configuration is valid */
2194 nn->rx_coalesce_adapt_on = !!ec->use_adaptive_rx_coalesce;
2195 nn->tx_coalesce_adapt_on = !!ec->use_adaptive_tx_coalesce;
2196
2197 nn->rx_coalesce_usecs = ec->rx_coalesce_usecs;
2198 nn->rx_coalesce_max_frames = ec->rx_max_coalesced_frames;
2199 nn->tx_coalesce_usecs = ec->tx_coalesce_usecs;
2200 nn->tx_coalesce_max_frames = ec->tx_max_coalesced_frames;
2201
2202 /* write configuration to device */
2203 nfp_net_coalesce_write_cfg(nn);
2204 return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD);
2205 }
2206
nfp_net_get_channels(struct net_device * netdev,struct ethtool_channels * channel)2207 static void nfp_net_get_channels(struct net_device *netdev,
2208 struct ethtool_channels *channel)
2209 {
2210 struct nfp_net *nn = netdev_priv(netdev);
2211 unsigned int num_tx_rings;
2212
2213 num_tx_rings = nn->dp.num_tx_rings;
2214 if (nn->dp.xdp_prog)
2215 num_tx_rings -= nn->dp.num_rx_rings;
2216
2217 channel->max_rx = min(nn->max_rx_rings, nn->max_r_vecs);
2218 channel->max_tx = min(nn->max_tx_rings, nn->max_r_vecs);
2219 channel->max_combined = min(channel->max_rx, channel->max_tx);
2220 channel->max_other = NFP_NET_NON_Q_VECTORS;
2221 channel->combined_count = min(nn->dp.num_rx_rings, num_tx_rings);
2222 channel->rx_count = nn->dp.num_rx_rings - channel->combined_count;
2223 channel->tx_count = num_tx_rings - channel->combined_count;
2224 channel->other_count = NFP_NET_NON_Q_VECTORS;
2225 }
2226
nfp_net_set_num_rings(struct nfp_net * nn,unsigned int total_rx,unsigned int total_tx)2227 static int nfp_net_set_num_rings(struct nfp_net *nn, unsigned int total_rx,
2228 unsigned int total_tx)
2229 {
2230 struct nfp_net_dp *dp;
2231
2232 dp = nfp_net_clone_dp(nn);
2233 if (!dp)
2234 return -ENOMEM;
2235
2236 dp->num_rx_rings = total_rx;
2237 dp->num_tx_rings = total_tx;
2238 /* nfp_net_check_config() will catch num_tx_rings > nn->max_tx_rings */
2239 if (dp->xdp_prog)
2240 dp->num_tx_rings += total_rx;
2241
2242 return nfp_net_ring_reconfig(nn, dp, NULL);
2243 }
2244
nfp_net_set_channels(struct net_device * netdev,struct ethtool_channels * channel)2245 static int nfp_net_set_channels(struct net_device *netdev,
2246 struct ethtool_channels *channel)
2247 {
2248 struct nfp_net *nn = netdev_priv(netdev);
2249 unsigned int total_rx, total_tx;
2250
2251 /* Reject unsupported */
2252 if (channel->other_count != NFP_NET_NON_Q_VECTORS ||
2253 (channel->rx_count && channel->tx_count))
2254 return -EINVAL;
2255
2256 total_rx = channel->combined_count + channel->rx_count;
2257 total_tx = channel->combined_count + channel->tx_count;
2258
2259 if (total_rx > min(nn->max_rx_rings, nn->max_r_vecs) ||
2260 total_tx > min(nn->max_tx_rings, nn->max_r_vecs))
2261 return -EINVAL;
2262
2263 return nfp_net_set_num_rings(nn, total_rx, total_tx);
2264 }
2265
nfp_port_set_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)2266 static int nfp_port_set_pauseparam(struct net_device *netdev,
2267 struct ethtool_pauseparam *pause)
2268 {
2269 struct nfp_eth_table_port *eth_port;
2270 struct nfp_port *port;
2271 int err;
2272
2273 port = nfp_port_from_netdev(netdev);
2274 eth_port = nfp_port_get_eth_port(port);
2275 if (!eth_port)
2276 return -EOPNOTSUPP;
2277
2278 if (pause->autoneg != AUTONEG_DISABLE)
2279 return -EOPNOTSUPP;
2280
2281 err = nfp_eth_set_pauseparam(port->app->cpp, eth_port->index,
2282 pause->tx_pause, pause->rx_pause);
2283 if (!err)
2284 /* Only refresh if we did something */
2285 nfp_net_refresh_port_table(port);
2286
2287 return err < 0 ? err : 0;
2288 }
2289
nfp_port_get_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)2290 static void nfp_port_get_pauseparam(struct net_device *netdev,
2291 struct ethtool_pauseparam *pause)
2292 {
2293 struct nfp_eth_table_port *eth_port;
2294 struct nfp_port *port;
2295
2296 port = nfp_port_from_netdev(netdev);
2297 eth_port = nfp_port_get_eth_port(port);
2298 if (!eth_port)
2299 return;
2300
2301 /* Currently pause frame autoneg is fixed */
2302 pause->autoneg = AUTONEG_DISABLE;
2303 pause->rx_pause = eth_port->rx_pause;
2304 pause->tx_pause = eth_port->tx_pause;
2305 }
2306
nfp_net_set_phys_id(struct net_device * netdev,enum ethtool_phys_id_state state)2307 static int nfp_net_set_phys_id(struct net_device *netdev,
2308 enum ethtool_phys_id_state state)
2309 {
2310 struct nfp_eth_table_port *eth_port;
2311 struct nfp_port *port;
2312 int err;
2313
2314 port = nfp_port_from_netdev(netdev);
2315 eth_port = __nfp_port_get_eth_port(port);
2316 if (!eth_port)
2317 return -EOPNOTSUPP;
2318
2319 switch (state) {
2320 case ETHTOOL_ID_ACTIVE:
2321 /* Control LED to blink */
2322 err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 1);
2323 break;
2324
2325 case ETHTOOL_ID_INACTIVE:
2326 /* Control LED to normal mode */
2327 err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 0);
2328 break;
2329
2330 case ETHTOOL_ID_ON:
2331 case ETHTOOL_ID_OFF:
2332 default:
2333 return -EOPNOTSUPP;
2334 }
2335
2336 return err;
2337 }
2338
2339 #define NFP_EEPROM_LEN ETH_ALEN
2340
2341 static int
nfp_net_get_eeprom_len(struct net_device * netdev)2342 nfp_net_get_eeprom_len(struct net_device *netdev)
2343 {
2344 struct nfp_eth_table_port *eth_port;
2345 struct nfp_port *port;
2346
2347 port = nfp_port_from_netdev(netdev);
2348 eth_port = __nfp_port_get_eth_port(port);
2349 if (!eth_port)
2350 return 0;
2351
2352 return NFP_EEPROM_LEN;
2353 }
2354
2355 static int
nfp_net_get_nsp_hwindex(struct net_device * netdev,struct nfp_nsp ** nspptr,u32 * index)2356 nfp_net_get_nsp_hwindex(struct net_device *netdev,
2357 struct nfp_nsp **nspptr,
2358 u32 *index)
2359 {
2360 struct nfp_eth_table_port *eth_port;
2361 struct nfp_port *port;
2362 struct nfp_nsp *nsp;
2363 int err;
2364
2365 port = nfp_port_from_netdev(netdev);
2366 eth_port = __nfp_port_get_eth_port(port);
2367 if (!eth_port)
2368 return -EOPNOTSUPP;
2369
2370 nsp = nfp_nsp_open(port->app->cpp);
2371 if (IS_ERR(nsp)) {
2372 err = PTR_ERR(nsp);
2373 netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2374 return err;
2375 }
2376
2377 if (!nfp_nsp_has_hwinfo_lookup(nsp)) {
2378 netdev_err(netdev, "NSP doesn't support PF MAC generation\n");
2379 nfp_nsp_close(nsp);
2380 return -EOPNOTSUPP;
2381 }
2382
2383 *nspptr = nsp;
2384 *index = eth_port->eth_index;
2385
2386 return 0;
2387 }
2388
2389 static int
nfp_net_get_port_mac_by_hwinfo(struct net_device * netdev,u8 * mac_addr)2390 nfp_net_get_port_mac_by_hwinfo(struct net_device *netdev,
2391 u8 *mac_addr)
2392 {
2393 char hwinfo[32] = {};
2394 struct nfp_nsp *nsp;
2395 u32 index;
2396 int err;
2397
2398 err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
2399 if (err)
2400 return err;
2401
2402 snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac", index);
2403 err = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
2404 nfp_nsp_close(nsp);
2405 if (err) {
2406 netdev_err(netdev, "Reading persistent MAC address failed: %d\n",
2407 err);
2408 return -EOPNOTSUPP;
2409 }
2410
2411 if (sscanf(hwinfo, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2412 &mac_addr[0], &mac_addr[1], &mac_addr[2],
2413 &mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
2414 netdev_err(netdev, "Can't parse persistent MAC address (%s)\n",
2415 hwinfo);
2416 return -EOPNOTSUPP;
2417 }
2418
2419 return 0;
2420 }
2421
2422 static int
nfp_net_set_port_mac_by_hwinfo(struct net_device * netdev,u8 * mac_addr)2423 nfp_net_set_port_mac_by_hwinfo(struct net_device *netdev,
2424 u8 *mac_addr)
2425 {
2426 char hwinfo[32] = {};
2427 struct nfp_nsp *nsp;
2428 u32 index;
2429 int err;
2430
2431 err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
2432 if (err)
2433 return err;
2434
2435 snprintf(hwinfo, sizeof(hwinfo),
2436 "eth%u.mac=%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2437 index, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
2438 mac_addr[4], mac_addr[5]);
2439
2440 err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
2441 nfp_nsp_close(nsp);
2442 if (err) {
2443 netdev_err(netdev, "HWinfo set failed: %d, hwinfo: %s\n",
2444 err, hwinfo);
2445 return -EOPNOTSUPP;
2446 }
2447
2448 return 0;
2449 }
2450
2451 static int
nfp_net_get_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * bytes)2452 nfp_net_get_eeprom(struct net_device *netdev,
2453 struct ethtool_eeprom *eeprom, u8 *bytes)
2454 {
2455 struct nfp_app *app = nfp_app_from_netdev(netdev);
2456 u8 buf[NFP_EEPROM_LEN] = {};
2457
2458 if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
2459 return -EOPNOTSUPP;
2460
2461 if (eeprom->len == 0)
2462 return -EINVAL;
2463
2464 eeprom->magic = app->pdev->vendor | (app->pdev->device << 16);
2465 memcpy(bytes, buf + eeprom->offset, eeprom->len);
2466
2467 return 0;
2468 }
2469
2470 static int
nfp_net_set_eeprom(struct net_device * netdev,struct ethtool_eeprom * eeprom,u8 * bytes)2471 nfp_net_set_eeprom(struct net_device *netdev,
2472 struct ethtool_eeprom *eeprom, u8 *bytes)
2473 {
2474 struct nfp_app *app = nfp_app_from_netdev(netdev);
2475 u8 buf[NFP_EEPROM_LEN] = {};
2476
2477 if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
2478 return -EOPNOTSUPP;
2479
2480 if (eeprom->len == 0)
2481 return -EINVAL;
2482
2483 if (eeprom->magic != (app->pdev->vendor | app->pdev->device << 16))
2484 return -EINVAL;
2485
2486 memcpy(buf + eeprom->offset, bytes, eeprom->len);
2487 if (nfp_net_set_port_mac_by_hwinfo(netdev, buf))
2488 return -EOPNOTSUPP;
2489
2490 return 0;
2491 }
2492
2493 static const struct ethtool_ops nfp_net_ethtool_ops = {
2494 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
2495 ETHTOOL_COALESCE_MAX_FRAMES |
2496 ETHTOOL_COALESCE_USE_ADAPTIVE,
2497 .get_drvinfo = nfp_net_get_drvinfo,
2498 .nway_reset = nfp_net_nway_reset,
2499 .get_link = ethtool_op_get_link,
2500 .get_ringparam = nfp_net_get_ringparam,
2501 .set_ringparam = nfp_net_set_ringparam,
2502 .self_test = nfp_net_self_test,
2503 .get_strings = nfp_net_get_strings,
2504 .get_ethtool_stats = nfp_net_get_stats,
2505 .get_sset_count = nfp_net_get_sset_count,
2506 .get_rxnfc = nfp_net_get_rxnfc,
2507 .set_rxnfc = nfp_net_set_rxnfc,
2508 .get_rx_ring_count = nfp_net_get_rx_ring_count,
2509 .get_rxfh_indir_size = nfp_net_get_rxfh_indir_size,
2510 .get_rxfh_key_size = nfp_net_get_rxfh_key_size,
2511 .get_rxfh = nfp_net_get_rxfh,
2512 .set_rxfh = nfp_net_set_rxfh,
2513 .get_rxfh_fields = nfp_net_get_rxfh_fields,
2514 .set_rxfh_fields = nfp_net_set_rxfh_fields,
2515 .get_regs_len = nfp_net_get_regs_len,
2516 .get_regs = nfp_net_get_regs,
2517 .set_dump = nfp_app_set_dump,
2518 .get_dump_flag = nfp_app_get_dump_flag,
2519 .get_dump_data = nfp_app_get_dump_data,
2520 .get_eeprom_len = nfp_net_get_eeprom_len,
2521 .get_eeprom = nfp_net_get_eeprom,
2522 .set_eeprom = nfp_net_set_eeprom,
2523 .get_module_info = nfp_port_get_module_info,
2524 .get_module_eeprom = nfp_port_get_module_eeprom,
2525 .get_coalesce = nfp_net_get_coalesce,
2526 .set_coalesce = nfp_net_set_coalesce,
2527 .get_channels = nfp_net_get_channels,
2528 .set_channels = nfp_net_set_channels,
2529 .get_link_ksettings = nfp_net_get_link_ksettings,
2530 .set_link_ksettings = nfp_net_set_link_ksettings,
2531 .get_fecparam = nfp_port_get_fecparam,
2532 .set_fecparam = nfp_port_set_fecparam,
2533 .set_pauseparam = nfp_port_set_pauseparam,
2534 .get_pauseparam = nfp_port_get_pauseparam,
2535 .set_phys_id = nfp_net_set_phys_id,
2536 .get_ts_info = ethtool_op_get_ts_info,
2537 };
2538
2539 const struct ethtool_ops nfp_port_ethtool_ops = {
2540 .get_drvinfo = nfp_app_get_drvinfo,
2541 .nway_reset = nfp_net_nway_reset,
2542 .get_link = ethtool_op_get_link,
2543 .get_strings = nfp_port_get_strings,
2544 .get_ethtool_stats = nfp_port_get_stats,
2545 .self_test = nfp_net_self_test,
2546 .get_sset_count = nfp_port_get_sset_count,
2547 .set_dump = nfp_app_set_dump,
2548 .get_dump_flag = nfp_app_get_dump_flag,
2549 .get_dump_data = nfp_app_get_dump_data,
2550 .get_eeprom_len = nfp_net_get_eeprom_len,
2551 .get_eeprom = nfp_net_get_eeprom,
2552 .set_eeprom = nfp_net_set_eeprom,
2553 .get_module_info = nfp_port_get_module_info,
2554 .get_module_eeprom = nfp_port_get_module_eeprom,
2555 .get_link_ksettings = nfp_net_get_link_ksettings,
2556 .set_link_ksettings = nfp_net_set_link_ksettings,
2557 .get_fecparam = nfp_port_get_fecparam,
2558 .set_fecparam = nfp_port_set_fecparam,
2559 .set_pauseparam = nfp_port_set_pauseparam,
2560 .get_pauseparam = nfp_port_get_pauseparam,
2561 .set_phys_id = nfp_net_set_phys_id,
2562 };
2563
nfp_net_set_ethtool_ops(struct net_device * netdev)2564 void nfp_net_set_ethtool_ops(struct net_device *netdev)
2565 {
2566 netdev->ethtool_ops = &nfp_net_ethtool_ops;
2567 }
2568