File Index
Files and directories
Sign in
FILE

nfp_net_ethtool.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c C
   1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
   2/* Copyright (C) 2015-2018 Netronome Systems, Inc. */
   3
   4/*
   5 * nfp_net_ethtool.c
   6 * Netronome network device driver: ethtool support
   7 * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
   8 *          Jason McMullan <jason.mcmullan@netronome.com>
   9 *          Rolf Neugebauer <rolf.neugebauer@netronome.com>
  10 *          Brad Petrus <brad.petrus@netronome.com>
  11 */
  12
  13#include <linux/bitfield.h>
  14#include <linux/kernel.h>
  15#include <linux/netdevice.h>
  16#include <linux/etherdevice.h>
  17#include <linux/interrupt.h>
  18#include <linux/pci.h>
  19#include <linux/ethtool.h>
  20#include <linux/firmware.h>
  21#include <linux/sfp.h>
  22
  23#include "nfpcore/nfp.h"
  24#include "nfpcore/nfp_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
  34struct nfp_et_stat {
  35	char name[ETH_GSTRING_LEN];
  36	int off;
  37};
  38
  39static 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
  74static 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
 154static 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
 184static 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
 202static void
 203nfp_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
 216static void
 217nfp_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
 231static int
 232nfp_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
 262static void
 263nfp_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
 272static void
 273nfp_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
 296static 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
 426static 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
 435static 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 */
 483static int
 484nfp_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
 545static int
 546nfp_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
 617err_bad_set:
 618	nfp_eth_config_cleanup_end(nsp);
 619	return err;
 620}
 621
 622static 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
 636static 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
 651static 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
 689static 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
 697static 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(sizeof(*nspi), GFP_KERNEL);
 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);
 727exit_close_nsp:
 728	nfp_nsp_close(nsp);
 729exit:
 730	return err;
 731}
 732
 733static 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
 745static 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
 762static bool link_test_supported(struct net_device *netdev)
 763{
 764	return true;
 765}
 766
 767static 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
 775static 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
 783static 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
 791static 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
 804static 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
 813static 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
 824static 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
 843static 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
 851static 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
 884static 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
 935static 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
 940static u8 *
 941nfp_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
 971static u64 *
 972nfp_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
 989static 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
 994static 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
1027static 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
1048static 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
1059static 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
1074static 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
1089static 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
1112static void
1113nfp_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
1128static 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
1150static 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
1169static void
1170nfp_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
1182static 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
1202static 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
1219static 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
1235static int
1236nfp_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
1259static int
1260nfp_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 */
1289static 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
1306static 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
1330static 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
1402static 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
1424static 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
1438static int nfp_net_get_rxnfc(struct net_device *netdev,
1439			     struct ethtool_rxnfc *cmd, u32 *rule_locs)
1440{
1441	struct nfp_net *nn = netdev_priv(netdev);
1442
1443	switch (cmd->cmd) {
1444	case ETHTOOL_GRXRINGS:
1445		cmd->data = nn->dp.num_rx_rings;
1446		return 0;
1447	case ETHTOOL_GRXCLSRLCNT:
1448		cmd->rule_cnt = nn->fs.count;
1449		return 0;
1450	case ETHTOOL_GRXCLSRULE:
1451		return nfp_net_get_fs_rule(nn, cmd);
1452	case ETHTOOL_GRXCLSRLALL:
1453		cmd->data = NFP_FS_MAX_ENTRY;
1454		return nfp_net_get_fs_loc(nn, rule_locs);
1455	default:
1456		return -EOPNOTSUPP;
1457	}
1458}
1459
1460static int nfp_net_set_rxfh_fields(struct net_device *netdev,
1461				   const struct ethtool_rxfh_fields *nfc,
1462				   struct netlink_ext_ack *extack)
1463{
1464	struct nfp_net *nn = netdev_priv(netdev);
1465	u32 new_rss_cfg = nn->rss_cfg;
1466	u32 nfp_rss_flag;
1467	int err;
1468
1469	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1470		return -EOPNOTSUPP;
1471
1472	/* RSS only supports IP SA/DA and L4 src/dst ports  */
1473	if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
1474			  RXH_L4_B_0_1 | RXH_L4_B_2_3))
1475		return -EINVAL;
1476
1477	/* We need at least the IP SA/DA fields for hashing */
1478	if (!(nfc->data & RXH_IP_SRC) ||
1479	    !(nfc->data & RXH_IP_DST))
1480		return -EINVAL;
1481
1482	nfp_rss_flag = ethtool_flow_to_nfp_flag(nfc->flow_type);
1483	if (!nfp_rss_flag)
1484		return -EINVAL;
1485
1486	switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
1487	case 0:
1488		new_rss_cfg &= ~nfp_rss_flag;
1489		break;
1490	case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
1491		new_rss_cfg |= nfp_rss_flag;
1492		break;
1493	default:
1494		return -EINVAL;
1495	}
1496
1497	new_rss_cfg |= FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc);
1498	new_rss_cfg |= NFP_NET_CFG_RSS_MASK;
1499
1500	if (new_rss_cfg == nn->rss_cfg)
1501		return 0;
1502
1503	writel(new_rss_cfg, nn->dp.ctrl_bar + NFP_NET_CFG_RSS_CTRL);
1504	err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
1505	if (err)
1506		return err;
1507
1508	nn->rss_cfg = new_rss_cfg;
1509
1510	nn_dbg(nn, "Changed RSS config to 0x%x\n", nn->rss_cfg);
1511	return 0;
1512}
1513
1514static int nfp_net_fs_from_ethtool(struct nfp_fs_entry *entry, struct ethtool_rx_flow_spec *fs)
1515{
1516	unsigned int i;
1517
1518	/* FLOW_EXT/FLOW_MAC_EXT is not supported. */
1519	switch (fs->flow_type & ~FLOW_RSS) {
1520	case TCP_V4_FLOW:
1521	case UDP_V4_FLOW:
1522	case SCTP_V4_FLOW:
1523		entry->msk.sip4  = fs->m_u.tcp_ip4_spec.ip4src;
1524		entry->msk.dip4  = fs->m_u.tcp_ip4_spec.ip4dst;
1525		entry->msk.sport = fs->m_u.tcp_ip4_spec.psrc;
1526		entry->msk.dport = fs->m_u.tcp_ip4_spec.pdst;
1527		entry->key.sip4  = fs->h_u.tcp_ip4_spec.ip4src & entry->msk.sip4;
1528		entry->key.dip4  = fs->h_u.tcp_ip4_spec.ip4dst & entry->msk.dip4;
1529		entry->key.sport = fs->h_u.tcp_ip4_spec.psrc & entry->msk.sport;
1530		entry->key.dport = fs->h_u.tcp_ip4_spec.pdst & entry->msk.dport;
1531		break;
1532	case TCP_V6_FLOW:
1533	case UDP_V6_FLOW:
1534	case SCTP_V6_FLOW:
1535		for (i = 0; i < 4; i++) {
1536			entry->msk.sip6[i] = fs->m_u.tcp_ip6_spec.ip6src[i];
1537			entry->msk.dip6[i] = fs->m_u.tcp_ip6_spec.ip6dst[i];
1538			entry->key.sip6[i] = fs->h_u.tcp_ip6_spec.ip6src[i] & entry->msk.sip6[i];
1539			entry->key.dip6[i] = fs->h_u.tcp_ip6_spec.ip6dst[i] & entry->msk.dip6[i];
1540		}
1541		entry->msk.sport = fs->m_u.tcp_ip6_spec.psrc;
1542		entry->msk.dport = fs->m_u.tcp_ip6_spec.pdst;
1543		entry->key.sport = fs->h_u.tcp_ip6_spec.psrc & entry->msk.sport;
1544		entry->key.dport = fs->h_u.tcp_ip6_spec.pdst & entry->msk.dport;
1545		break;
1546	case IPV4_USER_FLOW:
1547		entry->msk.sip4     = fs->m_u.usr_ip4_spec.ip4src;
1548		entry->msk.dip4     = fs->m_u.usr_ip4_spec.ip4dst;
1549		entry->msk.l4_proto = fs->m_u.usr_ip4_spec.proto;
1550		entry->key.sip4     = fs->h_u.usr_ip4_spec.ip4src & entry->msk.sip4;
1551		entry->key.dip4     = fs->h_u.usr_ip4_spec.ip4dst & entry->msk.dip4;
1552		entry->key.l4_proto = fs->h_u.usr_ip4_spec.proto & entry->msk.l4_proto;
1553		break;
1554	case IPV6_USER_FLOW:
1555		for (i = 0; i < 4; i++) {
1556			entry->msk.sip6[i] = fs->m_u.usr_ip6_spec.ip6src[i];
1557			entry->msk.dip6[i] = fs->m_u.usr_ip6_spec.ip6dst[i];
1558			entry->key.sip6[i] = fs->h_u.usr_ip6_spec.ip6src[i] & entry->msk.sip6[i];
1559			entry->key.dip6[i] = fs->h_u.usr_ip6_spec.ip6dst[i] & entry->msk.dip6[i];
1560		}
1561		entry->msk.l4_proto = fs->m_u.usr_ip6_spec.l4_proto;
1562		entry->key.l4_proto = fs->h_u.usr_ip6_spec.l4_proto & entry->msk.l4_proto;
1563		break;
1564	case ETHER_FLOW:
1565		entry->msk.l3_proto = fs->m_u.ether_spec.h_proto;
1566		entry->key.l3_proto = fs->h_u.ether_spec.h_proto & entry->msk.l3_proto;
1567		break;
1568	default:
1569		return -EINVAL;
1570	}
1571
1572	switch (fs->flow_type & ~FLOW_RSS) {
1573	case TCP_V4_FLOW:
1574	case TCP_V6_FLOW:
1575		entry->key.l4_proto = IPPROTO_TCP;
1576		entry->msk.l4_proto = 0xff;
1577		break;
1578	case UDP_V4_FLOW:
1579	case UDP_V6_FLOW:
1580		entry->key.l4_proto = IPPROTO_UDP;
1581		entry->msk.l4_proto = 0xff;
1582		break;
1583	case SCTP_V4_FLOW:
1584	case SCTP_V6_FLOW:
1585		entry->key.l4_proto = IPPROTO_SCTP;
1586		entry->msk.l4_proto = 0xff;
1587		break;
1588	}
1589
1590	entry->flow_type = fs->flow_type;
1591	entry->action    = fs->ring_cookie;
1592	entry->loc       = fs->location;
1593
1594	return 0;
1595}
1596
1597static int nfp_net_fs_check_existing(struct nfp_net *nn, struct nfp_fs_entry *new)
1598{
1599	struct nfp_fs_entry *entry;
1600
1601	list_for_each_entry(entry, &nn->fs.list, node) {
1602		if (new->loc != entry->loc &&
1603		    !((new->flow_type ^ entry->flow_type) & ~FLOW_RSS) &&
1604		    !memcmp(&new->key, &entry->key, sizeof(new->key)) &&
1605		    !memcmp(&new->msk, &entry->msk, sizeof(new->msk)))
1606			return entry->loc;
1607	}
1608
1609	/* -1 means no duplicates */
1610	return -1;
1611}
1612
1613static int nfp_net_fs_add(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
1614{
1615	struct ethtool_rx_flow_spec *fs = &cmd->fs;
1616	struct nfp_fs_entry *new, *entry;
1617	bool unsupp_mask;
1618	int err, id;
1619
1620	if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1621		return -EOPNOTSUPP;
1622
1623	/* Only default RSS context(0) is supported. */
1624	if ((fs->flow_type & FLOW_RSS) && cmd->rss_context)
1625		return -EOPNOTSUPP;
1626
1627	if (fs->location >= NFP_FS_MAX_ENTRY)
1628		return -EINVAL;
1629
1630	if (fs->ring_cookie != RX_CLS_FLOW_DISC &&
1631	    fs->ring_cookie >= nn->dp.num_rx_rings)
1632		return -EINVAL;
1633
1634	/* FLOW_EXT/FLOW_MAC_EXT is not supported. */
1635	switch (fs->flow_type & ~FLOW_RSS) {
1636	case TCP_V4_FLOW:
1637	case UDP_V4_FLOW:
1638	case SCTP_V4_FLOW:
1639		unsupp_mask = !!fs->m_u.tcp_ip4_spec.tos;
1640		break;
1641	case TCP_V6_FLOW:
1642	case UDP_V6_FLOW:
1643	case SCTP_V6_FLOW:
1644		unsupp_mask = !!fs->m_u.tcp_ip6_spec.tclass;
1645		break;
1646	case IPV4_USER_FLOW:
1647		unsupp_mask = !!fs->m_u.usr_ip4_spec.l4_4_bytes ||
1648			      !!fs->m_u.usr_ip4_spec.tos ||
1649			      !!fs->m_u.usr_ip4_spec.ip_ver;
1650		/* ip_ver must be ETH_RX_NFC_IP4. */
1651		unsupp_mask |= fs->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4;
1652		break;
1653	case IPV6_USER_FLOW:
1654		unsupp_mask = !!fs->m_u.usr_ip6_spec.l4_4_bytes ||
1655			      !!fs->m_u.usr_ip6_spec.tclass;
1656		break;
1657	case ETHER_FLOW:
1658		if (fs->h_u.ether_spec.h_proto == htons(ETH_P_IP) ||
1659		    fs->h_u.ether_spec.h_proto == htons(ETH_P_IPV6)) {
1660			nn_err(nn, "Please use ip4/ip6 flow type instead.\n");
1661			return -EOPNOTSUPP;
1662		}
1663		/* Only unmasked ethtype is supported. */
1664		unsupp_mask = !is_zero_ether_addr(fs->m_u.ether_spec.h_dest) ||
1665			      !is_zero_ether_addr(fs->m_u.ether_spec.h_source) ||
1666			      (fs->m_u.ether_spec.h_proto != htons(0xffff));
1667		break;
1668	default:
1669		return -EOPNOTSUPP;
1670	}
1671
1672	if (unsupp_mask)
1673		return -EOPNOTSUPP;
1674
1675	new = kzalloc(sizeof(*new), GFP_KERNEL);
1676	if (!new)
1677		return -ENOMEM;
1678
1679	nfp_net_fs_from_ethtool(new, fs);
1680
1681	id = nfp_net_fs_check_existing(nn, new);
1682	if (id >= 0) {
1683		nn_err(nn, "Identical rule is existing in %d.\n", id);
1684		err = -EINVAL;
1685		goto err;
1686	}
1687
1688	/* Insert to list in ascending order of location. */
1689	list_for_each_entry(entry, &nn->fs.list, node) {
1690		if (entry->loc == fs->location) {
1691			err = nfp_net_fs_del_hw(nn, entry);
1692			if (err)
1693				goto err;
1694
1695			nn->fs.count--;
1696			err = nfp_net_fs_add_hw(nn, new);
1697			if (err)
1698				goto err;
1699
1700			nn->fs.count++;
1701			list_replace(&entry->node, &new->node);
1702			kfree(entry);
1703
1704			return 0;
1705		}
1706
1707		if (entry->loc > fs->location)
1708			break;
1709	}
1710
1711	if (nn->fs.count == NFP_FS_MAX_ENTRY) {
1712		err = -ENOSPC;
1713		goto err;
1714	}
1715
1716	err = nfp_net_fs_add_hw(nn, new);
1717	if (err)
1718		goto err;
1719
1720	list_add_tail(&new->node, &entry->node);
1721	nn->fs.count++;
1722
1723	return 0;
1724
1725err:
1726	kfree(new);
1727	return err;
1728}
1729
1730static int nfp_net_fs_del(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
1731{
1732	struct nfp_fs_entry *entry;
1733	int err;
1734
1735	if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
1736		return -EOPNOTSUPP;
1737
1738	if (!nn->fs.count || cmd->fs.location >= NFP_FS_MAX_ENTRY)
1739		return -EINVAL;
1740
1741	list_for_each_entry(entry, &nn->fs.list, node) {
1742		if (entry->loc == cmd->fs.location) {
1743			err = nfp_net_fs_del_hw(nn, entry);
1744			if (err)
1745				return err;
1746
1747			list_del(&entry->node);
1748			kfree(entry);
1749			nn->fs.count--;
1750
1751			return 0;
1752		} else if (entry->loc > cmd->fs.location) {
1753			/* no need to continue */
1754			break;
1755		}
1756	}
1757
1758	return -ENOENT;
1759}
1760
1761static int nfp_net_set_rxnfc(struct net_device *netdev,
1762			     struct ethtool_rxnfc *cmd)
1763{
1764	struct nfp_net *nn = netdev_priv(netdev);
1765
1766	switch (cmd->cmd) {
1767	case ETHTOOL_SRXCLSRLINS:
1768		return nfp_net_fs_add(nn, cmd);
1769	case ETHTOOL_SRXCLSRLDEL:
1770		return nfp_net_fs_del(nn, cmd);
1771	default:
1772		return -EOPNOTSUPP;
1773	}
1774}
1775
1776static u32 nfp_net_get_rxfh_indir_size(struct net_device *netdev)
1777{
1778	struct nfp_net *nn = netdev_priv(netdev);
1779
1780	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1781		return 0;
1782
1783	return ARRAY_SIZE(nn->rss_itbl);
1784}
1785
1786static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev)
1787{
1788	struct nfp_net *nn = netdev_priv(netdev);
1789
1790	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1791		return 0;
1792
1793	return nfp_net_rss_key_sz(nn);
1794}
1795
1796static int nfp_net_get_rxfh(struct net_device *netdev,
1797			    struct ethtool_rxfh_param *rxfh)
1798{
1799	struct nfp_net *nn = netdev_priv(netdev);
1800	int i;
1801
1802	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY))
1803		return -EOPNOTSUPP;
1804
1805	if (rxfh->indir)
1806		for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
1807			rxfh->indir[i] = nn->rss_itbl[i];
1808	if (rxfh->key)
1809		memcpy(rxfh->key, nn->rss_key, nfp_net_rss_key_sz(nn));
1810
1811	rxfh->hfunc = nn->rss_hfunc;
1812	if (rxfh->hfunc >= 1 << ETH_RSS_HASH_FUNCS_COUNT)
1813		rxfh->hfunc = ETH_RSS_HASH_UNKNOWN;
1814
1815	return 0;
1816}
1817
1818static int nfp_net_set_rxfh(struct net_device *netdev,
1819			    struct ethtool_rxfh_param *rxfh,
1820			    struct netlink_ext_ack *extack)
1821{
1822	struct nfp_net *nn = netdev_priv(netdev);
1823	int i;
1824
1825	if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY) ||
1826	    !(rxfh->hfunc == ETH_RSS_HASH_NO_CHANGE ||
1827	      rxfh->hfunc == nn->rss_hfunc))
1828		return -EOPNOTSUPP;
1829
1830	if (!rxfh->key && !rxfh->indir)
1831		return 0;
1832
1833	if (rxfh->key) {
1834		memcpy(nn->rss_key, rxfh->key, nfp_net_rss_key_sz(nn));
1835		nfp_net_rss_write_key(nn);
1836	}
1837	if (rxfh->indir) {
1838		for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++)
1839			nn->rss_itbl[i] = rxfh->indir[i];
1840
1841		nfp_net_rss_write_itbl(nn);
1842	}
1843
1844	return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS);
1845}
1846
1847/* Dump BAR registers
1848 */
1849static int nfp_net_get_regs_len(struct net_device *netdev)
1850{
1851	return NFP_NET_CFG_BAR_SZ;
1852}
1853
1854static void nfp_net_get_regs(struct net_device *netdev,
1855			     struct ethtool_regs *regs, void *p)
1856{
1857	struct nfp_net *nn = netdev_priv(netdev);
1858	u32 *regs_buf = p;
1859	int i;
1860
1861	regs->version = nn_readl(nn, NFP_NET_CFG_VERSION);
1862
1863	for (i = 0; i < NFP_NET_CFG_BAR_SZ / sizeof(u32); i++)
1864		regs_buf[i] = readl(nn->dp.ctrl_bar + (i * sizeof(u32)));
1865}
1866
1867static int nfp_net_get_coalesce(struct net_device *netdev,
1868				struct ethtool_coalesce *ec,
1869				struct kernel_ethtool_coalesce *kernel_coal,
1870				struct netlink_ext_ack *extack)
1871{
1872	struct nfp_net *nn = netdev_priv(netdev);
1873
1874	if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
1875		return -EOPNOTSUPP;
1876
1877	ec->use_adaptive_rx_coalesce = nn->rx_coalesce_adapt_on;
1878	ec->use_adaptive_tx_coalesce = nn->tx_coalesce_adapt_on;
1879
1880	ec->rx_coalesce_usecs       = nn->rx_coalesce_usecs;
1881	ec->rx_max_coalesced_frames = nn->rx_coalesce_max_frames;
1882	ec->tx_coalesce_usecs       = nn->tx_coalesce_usecs;
1883	ec->tx_max_coalesced_frames = nn->tx_coalesce_max_frames;
1884
1885	return 0;
1886}
1887
1888/* Other debug dumps
1889 */
1890static int
1891nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer)
1892{
1893	struct nfp_resource *res;
1894	int ret;
1895
1896	if (!app)
1897		return -EOPNOTSUPP;
1898
1899	dump->version = 1;
1900	dump->flag = NFP_DUMP_NSP_DIAG;
1901
1902	res = nfp_resource_acquire(app->cpp, NFP_RESOURCE_NSP_DIAG);
1903	if (IS_ERR(res))
1904		return PTR_ERR(res);
1905
1906	if (buffer) {
1907		if (dump->len != nfp_resource_size(res)) {
1908			ret = -EINVAL;
1909			goto exit_release;
1910		}
1911
1912		ret = nfp_cpp_read(app->cpp, nfp_resource_cpp_id(res),
1913				   nfp_resource_address(res),
1914				   buffer, dump->len);
1915		if (ret != dump->len)
1916			ret = ret < 0 ? ret : -EIO;
1917		else
1918			ret = 0;
1919	} else {
1920		dump->len = nfp_resource_size(res);
1921		ret = 0;
1922	}
1923exit_release:
1924	nfp_resource_release(res);
1925
1926	return ret;
1927}
1928
1929/* Set the dump flag/level. Calculate the dump length for flag > 0 only (new TLV
1930 * based dumps), since flag 0 (default) calculates the length in
1931 * nfp_app_get_dump_flag(), and we need to support triggering a level 0 dump
1932 * without setting the flag first, for backward compatibility.
1933 */
1934static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val)
1935{
1936	struct nfp_app *app = nfp_app_from_netdev(netdev);
1937	s64 len;
1938
1939	if (!app)
1940		return -EOPNOTSUPP;
1941
1942	if (val->flag == NFP_DUMP_NSP_DIAG) {
1943		app->pf->dump_flag = val->flag;
1944		return 0;
1945	}
1946
1947	if (!app->pf->dumpspec)
1948		return -EOPNOTSUPP;
1949
1950	len = nfp_net_dump_calculate_size(app->pf, app->pf->dumpspec,
1951					  val->flag);
1952	if (len < 0)
1953		return len;
1954
1955	app->pf->dump_flag = val->flag;
1956	app->pf->dump_len = len;
1957
1958	return 0;
1959}
1960
1961static int
1962nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
1963{
1964	struct nfp_app *app = nfp_app_from_netdev(netdev);
1965
1966	if (!app)
1967		return -EOPNOTSUPP;
1968
1969	if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1970		return nfp_dump_nsp_diag(app, dump, NULL);
1971
1972	dump->flag = app->pf->dump_flag;
1973	dump->len = app->pf->dump_len;
1974
1975	return 0;
1976}
1977
1978static int
1979nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
1980		      void *buffer)
1981{
1982	struct nfp_app *app = nfp_app_from_netdev(netdev);
1983
1984	if (!app)
1985		return -EOPNOTSUPP;
1986
1987	if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG)
1988		return nfp_dump_nsp_diag(app, dump, buffer);
1989
1990	dump->flag = app->pf->dump_flag;
1991	dump->len = app->pf->dump_len;
1992
1993	return nfp_net_dump_populate_buffer(app->pf, app->pf->dumpspec, dump,
1994					    buffer);
1995}
1996
1997static int
1998nfp_port_get_module_info(struct net_device *netdev,
1999			 struct ethtool_modinfo *modinfo)
2000{
2001	struct nfp_eth_table_port *eth_port;
2002	struct nfp_port *port;
2003	unsigned int read_len;
2004	struct nfp_nsp *nsp;
2005	int err = 0;
2006	u8 data;
2007
2008	port = nfp_port_from_netdev(netdev);
2009	if (!port)
2010		return -EOPNOTSUPP;
2011
2012	/* update port state to get latest interface */
2013	set_bit(NFP_PORT_CHANGED, &port->flags);
2014	eth_port = nfp_port_get_eth_port(port);
2015	if (!eth_port)
2016		return -EOPNOTSUPP;
2017
2018	nsp = nfp_nsp_open(port->app->cpp);
2019	if (IS_ERR(nsp)) {
2020		err = PTR_ERR(nsp);
2021		netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2022		return err;
2023	}
2024
2025	if (!nfp_nsp_has_read_module_eeprom(nsp)) {
2026		netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
2027		err = -EOPNOTSUPP;
2028		goto exit_close_nsp;
2029	}
2030
2031	switch (eth_port->interface) {
2032	case NFP_INTERFACE_SFP:
2033	case NFP_INTERFACE_SFP28:
2034		err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2035						 SFP_SFF8472_COMPLIANCE, &data,
2036						 1, &read_len);
2037		if (err < 0)
2038			goto exit_close_nsp;
2039
2040		if (!data) {
2041			modinfo->type = ETH_MODULE_SFF_8079;
2042			modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
2043		} else {
2044			modinfo->type = ETH_MODULE_SFF_8472;
2045			modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
2046		}
2047		break;
2048	case NFP_INTERFACE_QSFP:
2049		err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2050						 SFP_SFF_REV_COMPLIANCE, &data,
2051						 1, &read_len);
2052		if (err < 0)
2053			goto exit_close_nsp;
2054
2055		if (data < 0x3) {
2056			modinfo->type = ETH_MODULE_SFF_8436;
2057			modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN;
2058		} else {
2059			modinfo->type = ETH_MODULE_SFF_8636;
2060			modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
2061		}
2062		break;
2063	case NFP_INTERFACE_QSFP28:
2064		modinfo->type = ETH_MODULE_SFF_8636;
2065		modinfo->eeprom_len = ETH_MODULE_SFF_8636_MAX_LEN;
2066		break;
2067	default:
2068		netdev_err(netdev, "Unsupported module 0x%x detected\n",
2069			   eth_port->interface);
2070		err = -EINVAL;
2071	}
2072
2073exit_close_nsp:
2074	nfp_nsp_close(nsp);
2075	return err;
2076}
2077
2078static int
2079nfp_port_get_module_eeprom(struct net_device *netdev,
2080			   struct ethtool_eeprom *eeprom, u8 *data)
2081{
2082	struct nfp_eth_table_port *eth_port;
2083	struct nfp_port *port;
2084	struct nfp_nsp *nsp;
2085	int err;
2086
2087	port = nfp_port_from_netdev(netdev);
2088	eth_port = __nfp_port_get_eth_port(port);
2089	if (!eth_port)
2090		return -EOPNOTSUPP;
2091
2092	nsp = nfp_nsp_open(port->app->cpp);
2093	if (IS_ERR(nsp)) {
2094		err = PTR_ERR(nsp);
2095		netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2096		return err;
2097	}
2098
2099	if (!nfp_nsp_has_read_module_eeprom(nsp)) {
2100		netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n");
2101		err = -EOPNOTSUPP;
2102		goto exit_close_nsp;
2103	}
2104
2105	err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index,
2106					 eeprom->offset, data, eeprom->len,
2107					 &eeprom->len);
2108	if (err < 0) {
2109		if (eeprom->len) {
2110			netdev_warn(netdev,
2111				    "Incomplete read from module EEPROM: %d\n",
2112				     err);
2113			err = 0;
2114		} else {
2115			netdev_err(netdev,
2116				   "Reading from module EEPROM failed: %d\n",
2117				   err);
2118		}
2119	}
2120
2121exit_close_nsp:
2122	nfp_nsp_close(nsp);
2123	return err;
2124}
2125
2126static int nfp_net_set_coalesce(struct net_device *netdev,
2127				struct ethtool_coalesce *ec,
2128				struct kernel_ethtool_coalesce *kernel_coal,
2129				struct netlink_ext_ack *extack)
2130{
2131	struct nfp_net *nn = netdev_priv(netdev);
2132	unsigned int factor;
2133
2134	/* Compute factor used to convert coalesce '_usecs' parameters to
2135	 * ME timestamp ticks.  There are 16 ME clock cycles for each timestamp
2136	 * count.
2137	 */
2138	factor = nn->tlv_caps.me_freq_mhz / 16;
2139
2140	/* Each pair of (usecs, max_frames) fields specifies that interrupts
2141	 * should be coalesced until
2142	 *      (usecs > 0 && time_since_first_completion >= usecs) ||
2143	 *      (max_frames > 0 && completed_frames >= max_frames)
2144	 *
2145	 * It is illegal to set both usecs and max_frames to zero as this would
2146	 * cause interrupts to never be generated.  To disable coalescing, set
2147	 * usecs = 0 and max_frames = 1.
2148	 *
2149	 * Some implementations ignore the value of max_frames and use the
2150	 * condition time_since_first_completion >= usecs
2151	 */
2152
2153	if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD))
2154		return -EOPNOTSUPP;
2155
2156	/* ensure valid configuration */
2157	if (!ec->rx_coalesce_usecs && !ec->rx_max_coalesced_frames) {
2158		NL_SET_ERR_MSG_MOD(extack,
2159				   "rx-usecs and rx-frames cannot both be zero");
2160		return -EINVAL;
2161	}
2162
2163	if (!ec->tx_coalesce_usecs && !ec->tx_max_coalesced_frames) {
2164		NL_SET_ERR_MSG_MOD(extack,
2165				   "tx-usecs and tx-frames cannot both be zero");
2166		return -EINVAL;
2167	}
2168
2169	if (nfp_net_coalesce_para_check(ec->rx_coalesce_usecs * factor)) {
2170		NL_SET_ERR_MSG_MOD(extack, "rx-usecs too large");
2171		return -EINVAL;
2172	}
2173
2174	if (nfp_net_coalesce_para_check(ec->rx_max_coalesced_frames)) {
2175		NL_SET_ERR_MSG_MOD(extack, "rx-frames too large");
2176		return -EINVAL;
2177	}
2178
2179	if (nfp_net_coalesce_para_check(ec->tx_coalesce_usecs * factor)) {
2180		NL_SET_ERR_MSG_MOD(extack, "tx-usecs too large");
2181		return -EINVAL;
2182	}
2183
2184	if (nfp_net_coalesce_para_check(ec->tx_max_coalesced_frames)) {
2185		NL_SET_ERR_MSG_MOD(extack, "tx-frames too large");
2186		return -EINVAL;
2187	}
2188
2189	/* configuration is valid */
2190	nn->rx_coalesce_adapt_on = !!ec->use_adaptive_rx_coalesce;
2191	nn->tx_coalesce_adapt_on = !!ec->use_adaptive_tx_coalesce;
2192
2193	nn->rx_coalesce_usecs      = ec->rx_coalesce_usecs;
2194	nn->rx_coalesce_max_frames = ec->rx_max_coalesced_frames;
2195	nn->tx_coalesce_usecs      = ec->tx_coalesce_usecs;
2196	nn->tx_coalesce_max_frames = ec->tx_max_coalesced_frames;
2197
2198	/* write configuration to device */
2199	nfp_net_coalesce_write_cfg(nn);
2200	return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD);
2201}
2202
2203static void nfp_net_get_channels(struct net_device *netdev,
2204				 struct ethtool_channels *channel)
2205{
2206	struct nfp_net *nn = netdev_priv(netdev);
2207	unsigned int num_tx_rings;
2208
2209	num_tx_rings = nn->dp.num_tx_rings;
2210	if (nn->dp.xdp_prog)
2211		num_tx_rings -= nn->dp.num_rx_rings;
2212
2213	channel->max_rx = min(nn->max_rx_rings, nn->max_r_vecs);
2214	channel->max_tx = min(nn->max_tx_rings, nn->max_r_vecs);
2215	channel->max_combined = min(channel->max_rx, channel->max_tx);
2216	channel->max_other = NFP_NET_NON_Q_VECTORS;
2217	channel->combined_count = min(nn->dp.num_rx_rings, num_tx_rings);
2218	channel->rx_count = nn->dp.num_rx_rings - channel->combined_count;
2219	channel->tx_count = num_tx_rings - channel->combined_count;
2220	channel->other_count = NFP_NET_NON_Q_VECTORS;
2221}
2222
2223static int nfp_net_set_num_rings(struct nfp_net *nn, unsigned int total_rx,
2224				 unsigned int total_tx)
2225{
2226	struct nfp_net_dp *dp;
2227
2228	dp = nfp_net_clone_dp(nn);
2229	if (!dp)
2230		return -ENOMEM;
2231
2232	dp->num_rx_rings = total_rx;
2233	dp->num_tx_rings = total_tx;
2234	/* nfp_net_check_config() will catch num_tx_rings > nn->max_tx_rings */
2235	if (dp->xdp_prog)
2236		dp->num_tx_rings += total_rx;
2237
2238	return nfp_net_ring_reconfig(nn, dp, NULL);
2239}
2240
2241static int nfp_net_set_channels(struct net_device *netdev,
2242				struct ethtool_channels *channel)
2243{
2244	struct nfp_net *nn = netdev_priv(netdev);
2245	unsigned int total_rx, total_tx;
2246
2247	/* Reject unsupported */
2248	if (channel->other_count != NFP_NET_NON_Q_VECTORS ||
2249	    (channel->rx_count && channel->tx_count))
2250		return -EINVAL;
2251
2252	total_rx = channel->combined_count + channel->rx_count;
2253	total_tx = channel->combined_count + channel->tx_count;
2254
2255	if (total_rx > min(nn->max_rx_rings, nn->max_r_vecs) ||
2256	    total_tx > min(nn->max_tx_rings, nn->max_r_vecs))
2257		return -EINVAL;
2258
2259	return nfp_net_set_num_rings(nn, total_rx, total_tx);
2260}
2261
2262static int nfp_port_set_pauseparam(struct net_device *netdev,
2263				   struct ethtool_pauseparam *pause)
2264{
2265	struct nfp_eth_table_port *eth_port;
2266	struct nfp_port *port;
2267	int err;
2268
2269	port = nfp_port_from_netdev(netdev);
2270	eth_port = nfp_port_get_eth_port(port);
2271	if (!eth_port)
2272		return -EOPNOTSUPP;
2273
2274	if (pause->autoneg != AUTONEG_DISABLE)
2275		return -EOPNOTSUPP;
2276
2277	err = nfp_eth_set_pauseparam(port->app->cpp, eth_port->index,
2278				     pause->tx_pause, pause->rx_pause);
2279	if (!err)
2280		/* Only refresh if we did something */
2281		nfp_net_refresh_port_table(port);
2282
2283	return err < 0 ? err : 0;
2284}
2285
2286static void nfp_port_get_pauseparam(struct net_device *netdev,
2287				    struct ethtool_pauseparam *pause)
2288{
2289	struct nfp_eth_table_port *eth_port;
2290	struct nfp_port *port;
2291
2292	port = nfp_port_from_netdev(netdev);
2293	eth_port = nfp_port_get_eth_port(port);
2294	if (!eth_port)
2295		return;
2296
2297	/* Currently pause frame autoneg is fixed */
2298	pause->autoneg = AUTONEG_DISABLE;
2299	pause->rx_pause = eth_port->rx_pause;
2300	pause->tx_pause = eth_port->tx_pause;
2301}
2302
2303static int nfp_net_set_phys_id(struct net_device *netdev,
2304			       enum ethtool_phys_id_state state)
2305{
2306	struct nfp_eth_table_port *eth_port;
2307	struct nfp_port *port;
2308	int err;
2309
2310	port = nfp_port_from_netdev(netdev);
2311	eth_port = __nfp_port_get_eth_port(port);
2312	if (!eth_port)
2313		return -EOPNOTSUPP;
2314
2315	switch (state) {
2316	case ETHTOOL_ID_ACTIVE:
2317		/* Control LED to blink */
2318		err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 1);
2319		break;
2320
2321	case ETHTOOL_ID_INACTIVE:
2322		/* Control LED to normal mode */
2323		err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 0);
2324		break;
2325
2326	case ETHTOOL_ID_ON:
2327	case ETHTOOL_ID_OFF:
2328	default:
2329		return -EOPNOTSUPP;
2330	}
2331
2332	return err;
2333}
2334
2335#define NFP_EEPROM_LEN ETH_ALEN
2336
2337static int
2338nfp_net_get_eeprom_len(struct net_device *netdev)
2339{
2340	struct nfp_eth_table_port *eth_port;
2341	struct nfp_port *port;
2342
2343	port = nfp_port_from_netdev(netdev);
2344	eth_port = __nfp_port_get_eth_port(port);
2345	if (!eth_port)
2346		return 0;
2347
2348	return NFP_EEPROM_LEN;
2349}
2350
2351static int
2352nfp_net_get_nsp_hwindex(struct net_device *netdev,
2353			struct nfp_nsp **nspptr,
2354			u32 *index)
2355{
2356	struct nfp_eth_table_port *eth_port;
2357	struct nfp_port *port;
2358	struct nfp_nsp *nsp;
2359	int err;
2360
2361	port = nfp_port_from_netdev(netdev);
2362	eth_port = __nfp_port_get_eth_port(port);
2363	if (!eth_port)
2364		return -EOPNOTSUPP;
2365
2366	nsp = nfp_nsp_open(port->app->cpp);
2367	if (IS_ERR(nsp)) {
2368		err = PTR_ERR(nsp);
2369		netdev_err(netdev, "Failed to access the NSP: %d\n", err);
2370		return err;
2371	}
2372
2373	if (!nfp_nsp_has_hwinfo_lookup(nsp)) {
2374		netdev_err(netdev, "NSP doesn't support PF MAC generation\n");
2375		nfp_nsp_close(nsp);
2376		return -EOPNOTSUPP;
2377	}
2378
2379	*nspptr = nsp;
2380	*index = eth_port->eth_index;
2381
2382	return 0;
2383}
2384
2385static int
2386nfp_net_get_port_mac_by_hwinfo(struct net_device *netdev,
2387			       u8 *mac_addr)
2388{
2389	char hwinfo[32] = {};
2390	struct nfp_nsp *nsp;
2391	u32 index;
2392	int err;
2393
2394	err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
2395	if (err)
2396		return err;
2397
2398	snprintf(hwinfo, sizeof(hwinfo), "eth%u.mac", index);
2399	err = nfp_nsp_hwinfo_lookup(nsp, hwinfo, sizeof(hwinfo));
2400	nfp_nsp_close(nsp);
2401	if (err) {
2402		netdev_err(netdev, "Reading persistent MAC address failed: %d\n",
2403			   err);
2404		return -EOPNOTSUPP;
2405	}
2406
2407	if (sscanf(hwinfo, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2408		   &mac_addr[0], &mac_addr[1], &mac_addr[2],
2409		   &mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6) {
2410		netdev_err(netdev, "Can't parse persistent MAC address (%s)\n",
2411			   hwinfo);
2412		return -EOPNOTSUPP;
2413	}
2414
2415	return 0;
2416}
2417
2418static int
2419nfp_net_set_port_mac_by_hwinfo(struct net_device *netdev,
2420			       u8 *mac_addr)
2421{
2422	char hwinfo[32] = {};
2423	struct nfp_nsp *nsp;
2424	u32 index;
2425	int err;
2426
2427	err = nfp_net_get_nsp_hwindex(netdev, &nsp, &index);
2428	if (err)
2429		return err;
2430
2431	snprintf(hwinfo, sizeof(hwinfo),
2432		 "eth%u.mac=%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
2433		 index, mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
2434		 mac_addr[4], mac_addr[5]);
2435
2436	err = nfp_nsp_hwinfo_set(nsp, hwinfo, sizeof(hwinfo));
2437	nfp_nsp_close(nsp);
2438	if (err) {
2439		netdev_err(netdev, "HWinfo set failed: %d, hwinfo: %s\n",
2440			   err, hwinfo);
2441		return -EOPNOTSUPP;
2442	}
2443
2444	return 0;
2445}
2446
2447static int
2448nfp_net_get_eeprom(struct net_device *netdev,
2449		   struct ethtool_eeprom *eeprom, u8 *bytes)
2450{
2451	struct nfp_app *app = nfp_app_from_netdev(netdev);
2452	u8 buf[NFP_EEPROM_LEN] = {};
2453
2454	if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
2455		return -EOPNOTSUPP;
2456
2457	if (eeprom->len == 0)
2458		return -EINVAL;
2459
2460	eeprom->magic = app->pdev->vendor | (app->pdev->device << 16);
2461	memcpy(bytes, buf + eeprom->offset, eeprom->len);
2462
2463	return 0;
2464}
2465
2466static int
2467nfp_net_set_eeprom(struct net_device *netdev,
2468		   struct ethtool_eeprom *eeprom, u8 *bytes)
2469{
2470	struct nfp_app *app = nfp_app_from_netdev(netdev);
2471	u8 buf[NFP_EEPROM_LEN] = {};
2472
2473	if (nfp_net_get_port_mac_by_hwinfo(netdev, buf))
2474		return -EOPNOTSUPP;
2475
2476	if (eeprom->len == 0)
2477		return -EINVAL;
2478
2479	if (eeprom->magic != (app->pdev->vendor | app->pdev->device << 16))
2480		return -EINVAL;
2481
2482	memcpy(buf + eeprom->offset, bytes, eeprom->len);
2483	if (nfp_net_set_port_mac_by_hwinfo(netdev, buf))
2484		return -EOPNOTSUPP;
2485
2486	return 0;
2487}
2488
2489static const struct ethtool_ops nfp_net_ethtool_ops = {
2490	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
2491				     ETHTOOL_COALESCE_MAX_FRAMES |
2492				     ETHTOOL_COALESCE_USE_ADAPTIVE,
2493	.get_drvinfo		= nfp_net_get_drvinfo,
2494	.nway_reset             = nfp_net_nway_reset,
2495	.get_link		= ethtool_op_get_link,
2496	.get_ringparam		= nfp_net_get_ringparam,
2497	.set_ringparam		= nfp_net_set_ringparam,
2498	.self_test		= nfp_net_self_test,
2499	.get_strings		= nfp_net_get_strings,
2500	.get_ethtool_stats	= nfp_net_get_stats,
2501	.get_sset_count		= nfp_net_get_sset_count,
2502	.get_rxnfc		= nfp_net_get_rxnfc,
2503	.set_rxnfc		= nfp_net_set_rxnfc,
2504	.get_rxfh_indir_size	= nfp_net_get_rxfh_indir_size,
2505	.get_rxfh_key_size	= nfp_net_get_rxfh_key_size,
2506	.get_rxfh		= nfp_net_get_rxfh,
2507	.set_rxfh		= nfp_net_set_rxfh,
2508	.get_rxfh_fields	= nfp_net_get_rxfh_fields,
2509	.set_rxfh_fields	= nfp_net_set_rxfh_fields,
2510	.get_regs_len		= nfp_net_get_regs_len,
2511	.get_regs		= nfp_net_get_regs,
2512	.set_dump		= nfp_app_set_dump,
2513	.get_dump_flag		= nfp_app_get_dump_flag,
2514	.get_dump_data		= nfp_app_get_dump_data,
2515	.get_eeprom_len         = nfp_net_get_eeprom_len,
2516	.get_eeprom             = nfp_net_get_eeprom,
2517	.set_eeprom             = nfp_net_set_eeprom,
2518	.get_module_info	= nfp_port_get_module_info,
2519	.get_module_eeprom	= nfp_port_get_module_eeprom,
2520	.get_coalesce           = nfp_net_get_coalesce,
2521	.set_coalesce           = nfp_net_set_coalesce,
2522	.get_channels		= nfp_net_get_channels,
2523	.set_channels		= nfp_net_set_channels,
2524	.get_link_ksettings	= nfp_net_get_link_ksettings,
2525	.set_link_ksettings	= nfp_net_set_link_ksettings,
2526	.get_fecparam		= nfp_port_get_fecparam,
2527	.set_fecparam		= nfp_port_set_fecparam,
2528	.set_pauseparam		= nfp_port_set_pauseparam,
2529	.get_pauseparam		= nfp_port_get_pauseparam,
2530	.set_phys_id		= nfp_net_set_phys_id,
2531	.get_ts_info		= ethtool_op_get_ts_info,
2532};
2533
2534const struct ethtool_ops nfp_port_ethtool_ops = {
2535	.get_drvinfo		= nfp_app_get_drvinfo,
2536	.nway_reset             = nfp_net_nway_reset,
2537	.get_link		= ethtool_op_get_link,
2538	.get_strings		= nfp_port_get_strings,
2539	.get_ethtool_stats	= nfp_port_get_stats,
2540	.self_test		= nfp_net_self_test,
2541	.get_sset_count		= nfp_port_get_sset_count,
2542	.set_dump		= nfp_app_set_dump,
2543	.get_dump_flag		= nfp_app_get_dump_flag,
2544	.get_dump_data		= nfp_app_get_dump_data,
2545	.get_eeprom_len         = nfp_net_get_eeprom_len,
2546	.get_eeprom             = nfp_net_get_eeprom,
2547	.set_eeprom             = nfp_net_set_eeprom,
2548	.get_module_info	= nfp_port_get_module_info,
2549	.get_module_eeprom	= nfp_port_get_module_eeprom,
2550	.get_link_ksettings	= nfp_net_get_link_ksettings,
2551	.set_link_ksettings	= nfp_net_set_link_ksettings,
2552	.get_fecparam		= nfp_port_get_fecparam,
2553	.set_fecparam		= nfp_port_set_fecparam,
2554	.set_pauseparam		= nfp_port_set_pauseparam,
2555	.get_pauseparam		= nfp_port_get_pauseparam,
2556	.set_phys_id		= nfp_net_set_phys_id,
2557};
2558
2559void nfp_net_set_ethtool_ops(struct net_device *netdev)
2560{
2561	netdev->ethtool_ops = &nfp_net_ethtool_ops;
2562}
~/ Read-only file preview.