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 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 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 strlcpy(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 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 strlcpy(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 void 232 nfp_app_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) 233 { 234 struct nfp_app *app = nfp_app_from_netdev(netdev); 235 236 strlcpy(drvinfo->bus_info, pci_name(app->pdev), 237 sizeof(drvinfo->bus_info)); 238 nfp_get_drvinfo(app, app->pdev, "*", drvinfo); 239 } 240 241 static void 242 nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port, 243 struct ethtool_link_ksettings *c) 244 { 245 unsigned int modes; 246 247 ethtool_link_ksettings_add_link_mode(c, supported, FEC_NONE); 248 if (!nfp_eth_can_support_fec(eth_port)) { 249 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_NONE); 250 return; 251 } 252 253 modes = nfp_eth_supported_fec_modes(eth_port); 254 if (modes & NFP_FEC_BASER) { 255 ethtool_link_ksettings_add_link_mode(c, supported, FEC_BASER); 256 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_BASER); 257 } 258 259 if (modes & NFP_FEC_REED_SOLOMON) { 260 ethtool_link_ksettings_add_link_mode(c, supported, FEC_RS); 261 ethtool_link_ksettings_add_link_mode(c, advertising, FEC_RS); 262 } 263 } 264 265 /** 266 * nfp_net_get_link_ksettings - Get Link Speed settings 267 * @netdev: network interface device structure 268 * @cmd: ethtool command 269 * 270 * Reports speed settings based on info in the BAR provided by the fw. 271 */ 272 static int 273 nfp_net_get_link_ksettings(struct net_device *netdev, 274 struct ethtool_link_ksettings *cmd) 275 { 276 static const u32 ls_to_ethtool[] = { 277 [NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0, 278 [NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = SPEED_UNKNOWN, 279 [NFP_NET_CFG_STS_LINK_RATE_1G] = SPEED_1000, 280 [NFP_NET_CFG_STS_LINK_RATE_10G] = SPEED_10000, 281 [NFP_NET_CFG_STS_LINK_RATE_25G] = SPEED_25000, 282 [NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000, 283 [NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000, 284 [NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000, 285 }; 286 struct nfp_eth_table_port *eth_port; 287 struct nfp_port *port; 288 struct nfp_net *nn; 289 u32 sts, ls; 290 291 /* Init to unknowns */ 292 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 293 cmd->base.port = PORT_OTHER; 294 cmd->base.speed = SPEED_UNKNOWN; 295 cmd->base.duplex = DUPLEX_UNKNOWN; 296 297 port = nfp_port_from_netdev(netdev); 298 eth_port = nfp_port_get_eth_port(port); 299 if (eth_port) { 300 ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); 301 ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); 302 cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ? 303 AUTONEG_ENABLE : AUTONEG_DISABLE; 304 nfp_net_set_fec_link_mode(eth_port, cmd); 305 } 306 307 if (!netif_carrier_ok(netdev)) 308 return 0; 309 310 /* Use link speed from ETH table if available, otherwise try the BAR */ 311 if (eth_port) { 312 cmd->base.port = eth_port->port_type; 313 cmd->base.speed = eth_port->speed; 314 cmd->base.duplex = DUPLEX_FULL; 315 return 0; 316 } 317 318 if (!nfp_netdev_is_nfp_net(netdev)) 319 return -EOPNOTSUPP; 320 nn = netdev_priv(netdev); 321 322 sts = nn_readl(nn, NFP_NET_CFG_STS); 323 324 ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts); 325 if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED) 326 return -EOPNOTSUPP; 327 328 if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN || 329 ls >= ARRAY_SIZE(ls_to_ethtool)) 330 return 0; 331 332 cmd->base.speed = ls_to_ethtool[ls]; 333 cmd->base.duplex = DUPLEX_FULL; 334 335 return 0; 336 } 337 338 static int 339 nfp_net_set_link_ksettings(struct net_device *netdev, 340 const struct ethtool_link_ksettings *cmd) 341 { 342 struct nfp_eth_table_port *eth_port; 343 struct nfp_port *port; 344 struct nfp_nsp *nsp; 345 int err; 346 347 port = nfp_port_from_netdev(netdev); 348 eth_port = __nfp_port_get_eth_port(port); 349 if (!eth_port) 350 return -EOPNOTSUPP; 351 352 if (netif_running(netdev)) { 353 netdev_warn(netdev, "Changing settings not allowed on an active interface. It may cause the port to be disabled until driver reload.\n"); 354 return -EBUSY; 355 } 356 357 nsp = nfp_eth_config_start(port->app->cpp, eth_port->index); 358 if (IS_ERR(nsp)) 359 return PTR_ERR(nsp); 360 361 err = __nfp_eth_set_aneg(nsp, cmd->base.autoneg == AUTONEG_ENABLE ? 362 NFP_ANEG_AUTO : NFP_ANEG_DISABLED); 363 if (err) 364 goto err_bad_set; 365 if (cmd->base.speed != SPEED_UNKNOWN) { 366 u32 speed = cmd->base.speed / eth_port->lanes; 367 368 err = __nfp_eth_set_speed(nsp, speed); 369 if (err) 370 goto err_bad_set; 371 } 372 373 err = nfp_eth_config_commit_end(nsp); 374 if (err > 0) 375 return 0; /* no change */ 376 377 nfp_net_refresh_port_table(port); 378 379 return err; 380 381 err_bad_set: 382 nfp_eth_config_cleanup_end(nsp); 383 return err; 384 } 385 386 static void nfp_net_get_ringparam(struct net_device *netdev, 387 struct ethtool_ringparam *ring, 388 struct kernel_ethtool_ringparam *kernel_ring, 389 struct netlink_ext_ack *extack) 390 { 391 struct nfp_net *nn = netdev_priv(netdev); 392 u32 qc_max = nn->dev_info->max_qc_size; 393 394 ring->rx_max_pending = qc_max; 395 ring->tx_max_pending = qc_max / nn->dp.ops->tx_min_desc_per_pkt; 396 ring->rx_pending = nn->dp.rxd_cnt; 397 ring->tx_pending = nn->dp.txd_cnt; 398 } 399 400 static int nfp_net_set_ring_size(struct nfp_net *nn, u32 rxd_cnt, u32 txd_cnt) 401 { 402 struct nfp_net_dp *dp; 403 404 dp = nfp_net_clone_dp(nn); 405 if (!dp) 406 return -ENOMEM; 407 408 dp->rxd_cnt = rxd_cnt; 409 dp->txd_cnt = txd_cnt; 410 411 return nfp_net_ring_reconfig(nn, dp, NULL); 412 } 413 414 static int nfp_net_set_ringparam(struct net_device *netdev, 415 struct ethtool_ringparam *ring, 416 struct kernel_ethtool_ringparam *kernel_ring, 417 struct netlink_ext_ack *extack) 418 { 419 u32 tx_dpp, qc_min, qc_max, rxd_cnt, txd_cnt; 420 struct nfp_net *nn = netdev_priv(netdev); 421 422 /* We don't have separate queues/rings for small/large frames. */ 423 if (ring->rx_mini_pending || ring->rx_jumbo_pending) 424 return -EINVAL; 425 426 qc_min = nn->dev_info->min_qc_size; 427 qc_max = nn->dev_info->max_qc_size; 428 tx_dpp = nn->dp.ops->tx_min_desc_per_pkt; 429 /* Round up to supported values */ 430 rxd_cnt = roundup_pow_of_two(ring->rx_pending); 431 txd_cnt = roundup_pow_of_two(ring->tx_pending); 432 433 if (rxd_cnt < qc_min || rxd_cnt > qc_max || 434 txd_cnt < qc_min / tx_dpp || txd_cnt > qc_max / tx_dpp) 435 return -EINVAL; 436 437 if (nn->dp.rxd_cnt == rxd_cnt && nn->dp.txd_cnt == txd_cnt) 438 return 0; 439 440 nn_dbg(nn, "Change ring size: RxQ %u->%u, TxQ %u->%u\n", 441 nn->dp.rxd_cnt, rxd_cnt, nn->dp.txd_cnt, txd_cnt); 442 443 return nfp_net_set_ring_size(nn, rxd_cnt, txd_cnt); 444 } 445 446 static int nfp_test_link(struct net_device *netdev) 447 { 448 if (!netif_carrier_ok(netdev) || !(netdev->flags & IFF_UP)) 449 return 1; 450 451 return 0; 452 } 453 454 static int nfp_test_nsp(struct net_device *netdev) 455 { 456 struct nfp_app *app = nfp_app_from_netdev(netdev); 457 struct nfp_nsp_identify *nspi; 458 struct nfp_nsp *nsp; 459 int err; 460 461 nsp = nfp_nsp_open(app->cpp); 462 if (IS_ERR(nsp)) { 463 err = PTR_ERR(nsp); 464 netdev_info(netdev, "NSP Test: failed to access the NSP: %d\n", err); 465 goto exit; 466 } 467 468 if (nfp_nsp_get_abi_ver_minor(nsp) < 15) { 469 err = -EOPNOTSUPP; 470 goto exit_close_nsp; 471 } 472 473 nspi = kzalloc(sizeof(*nspi), GFP_KERNEL); 474 if (!nspi) { 475 err = -ENOMEM; 476 goto exit_close_nsp; 477 } 478 479 err = nfp_nsp_read_identify(nsp, nspi, sizeof(*nspi)); 480 if (err < 0) 481 netdev_info(netdev, "NSP Test: reading bsp version failed %d\n", err); 482 483 kfree(nspi); 484 exit_close_nsp: 485 nfp_nsp_close(nsp); 486 exit: 487 return err; 488 } 489 490 static int nfp_test_fw(struct net_device *netdev) 491 { 492 struct nfp_net *nn = netdev_priv(netdev); 493 int err; 494 495 err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_GEN); 496 if (err) 497 netdev_info(netdev, "FW Test: update failed %d\n", err); 498 499 return err; 500 } 501 502 static int nfp_test_reg(struct net_device *netdev) 503 { 504 struct nfp_app *app = nfp_app_from_netdev(netdev); 505 struct nfp_cpp *cpp = app->cpp; 506 u32 model = nfp_cpp_model(cpp); 507 u32 value; 508 int err; 509 510 err = nfp_cpp_model_autodetect(cpp, &value); 511 if (err < 0) { 512 netdev_info(netdev, "REG Test: NFP model detection failed %d\n", err); 513 return err; 514 } 515 516 return (value == model) ? 0 : 1; 517 } 518 519 static bool link_test_supported(struct net_device *netdev) 520 { 521 return true; 522 } 523 524 static bool nsp_test_supported(struct net_device *netdev) 525 { 526 if (nfp_app_from_netdev(netdev)) 527 return true; 528 529 return false; 530 } 531 532 static bool fw_test_supported(struct net_device *netdev) 533 { 534 if (nfp_netdev_is_nfp_net(netdev)) 535 return true; 536 537 return false; 538 } 539 540 static bool reg_test_supported(struct net_device *netdev) 541 { 542 if (nfp_app_from_netdev(netdev)) 543 return true; 544 545 return false; 546 } 547 548 static struct nfp_self_test_item { 549 char name[ETH_GSTRING_LEN]; 550 bool (*is_supported)(struct net_device *dev); 551 int (*func)(struct net_device *dev); 552 } nfp_self_test[] = { 553 {"Link Test", link_test_supported, nfp_test_link}, 554 {"NSP Test", nsp_test_supported, nfp_test_nsp}, 555 {"Firmware Test", fw_test_supported, nfp_test_fw}, 556 {"Register Test", reg_test_supported, nfp_test_reg} 557 }; 558 559 #define NFP_TEST_TOTAL_NUM ARRAY_SIZE(nfp_self_test) 560 561 static void nfp_get_self_test_strings(struct net_device *netdev, u8 *data) 562 { 563 int i; 564 565 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++) 566 if (nfp_self_test[i].is_supported(netdev)) 567 ethtool_sprintf(&data, nfp_self_test[i].name); 568 } 569 570 static int nfp_get_self_test_count(struct net_device *netdev) 571 { 572 int i, count = 0; 573 574 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++) 575 if (nfp_self_test[i].is_supported(netdev)) 576 count++; 577 578 return count; 579 } 580 581 static void nfp_net_self_test(struct net_device *netdev, struct ethtool_test *eth_test, 582 u64 *data) 583 { 584 int i, ret, count = 0; 585 586 netdev_info(netdev, "Start self test\n"); 587 588 for (i = 0; i < NFP_TEST_TOTAL_NUM; i++) { 589 if (nfp_self_test[i].is_supported(netdev)) { 590 ret = nfp_self_test[i].func(netdev); 591 if (ret) 592 eth_test->flags |= ETH_TEST_FL_FAILED; 593 data[count++] = ret; 594 } 595 } 596 597 netdev_info(netdev, "Test end\n"); 598 } 599 600 static unsigned int nfp_vnic_get_sw_stats_count(struct net_device *netdev) 601 { 602 struct nfp_net *nn = netdev_priv(netdev); 603 604 return NN_RVEC_GATHER_STATS + nn->max_r_vecs * NN_RVEC_PER_Q_STATS + 605 NN_CTRL_PATH_STATS; 606 } 607 608 static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data) 609 { 610 struct nfp_net *nn = netdev_priv(netdev); 611 int i; 612 613 for (i = 0; i < nn->max_r_vecs; i++) { 614 ethtool_sprintf(&data, "rvec_%u_rx_pkts", i); 615 ethtool_sprintf(&data, "rvec_%u_tx_pkts", i); 616 ethtool_sprintf(&data, "rvec_%u_tx_busy", i); 617 } 618 619 ethtool_sprintf(&data, "hw_rx_csum_ok"); 620 ethtool_sprintf(&data, "hw_rx_csum_inner_ok"); 621 ethtool_sprintf(&data, "hw_rx_csum_complete"); 622 ethtool_sprintf(&data, "hw_rx_csum_err"); 623 ethtool_sprintf(&data, "rx_replace_buf_alloc_fail"); 624 ethtool_sprintf(&data, "rx_tls_decrypted_packets"); 625 ethtool_sprintf(&data, "hw_tx_csum"); 626 ethtool_sprintf(&data, "hw_tx_inner_csum"); 627 ethtool_sprintf(&data, "tx_gather"); 628 ethtool_sprintf(&data, "tx_lso"); 629 ethtool_sprintf(&data, "tx_tls_encrypted_packets"); 630 ethtool_sprintf(&data, "tx_tls_ooo"); 631 ethtool_sprintf(&data, "tx_tls_drop_no_sync_data"); 632 633 ethtool_sprintf(&data, "hw_tls_no_space"); 634 ethtool_sprintf(&data, "rx_tls_resync_req_ok"); 635 ethtool_sprintf(&data, "rx_tls_resync_req_ign"); 636 ethtool_sprintf(&data, "rx_tls_resync_sent"); 637 638 return data; 639 } 640 641 static u64 *nfp_vnic_get_sw_stats(struct net_device *netdev, u64 *data) 642 { 643 u64 gathered_stats[NN_RVEC_GATHER_STATS] = {}; 644 struct nfp_net *nn = netdev_priv(netdev); 645 u64 tmp[NN_RVEC_GATHER_STATS]; 646 unsigned int i, j; 647 648 for (i = 0; i < nn->max_r_vecs; i++) { 649 unsigned int start; 650 651 do { 652 start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); 653 data[0] = nn->r_vecs[i].rx_pkts; 654 tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; 655 tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; 656 tmp[2] = nn->r_vecs[i].hw_csum_rx_complete; 657 tmp[3] = nn->r_vecs[i].hw_csum_rx_error; 658 tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail; 659 tmp[5] = nn->r_vecs[i].hw_tls_rx; 660 } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start)); 661 662 do { 663 start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); 664 data[1] = nn->r_vecs[i].tx_pkts; 665 data[2] = nn->r_vecs[i].tx_busy; 666 tmp[6] = nn->r_vecs[i].hw_csum_tx; 667 tmp[7] = nn->r_vecs[i].hw_csum_tx_inner; 668 tmp[8] = nn->r_vecs[i].tx_gather; 669 tmp[9] = nn->r_vecs[i].tx_lso; 670 tmp[10] = nn->r_vecs[i].hw_tls_tx; 671 tmp[11] = nn->r_vecs[i].tls_tx_fallback; 672 tmp[12] = nn->r_vecs[i].tls_tx_no_fallback; 673 } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); 674 675 data += NN_RVEC_PER_Q_STATS; 676 677 for (j = 0; j < NN_RVEC_GATHER_STATS; j++) 678 gathered_stats[j] += tmp[j]; 679 } 680 681 for (j = 0; j < NN_RVEC_GATHER_STATS; j++) 682 *data++ = gathered_stats[j]; 683 684 *data++ = atomic_read(&nn->ktls_no_space); 685 *data++ = atomic_read(&nn->ktls_rx_resync_req); 686 *data++ = atomic_read(&nn->ktls_rx_resync_ign); 687 *data++ = atomic_read(&nn->ktls_rx_resync_sent); 688 689 return data; 690 } 691 692 static unsigned int nfp_vnic_get_hw_stats_count(unsigned int num_vecs) 693 { 694 return NN_ET_GLOBAL_STATS_LEN + num_vecs * 4; 695 } 696 697 static u8 * 698 nfp_vnic_get_hw_stats_strings(u8 *data, unsigned int num_vecs, bool repr) 699 { 700 int swap_off, i; 701 702 BUILD_BUG_ON(NN_ET_GLOBAL_STATS_LEN < NN_ET_SWITCH_STATS_LEN * 2); 703 /* If repr is true first add SWITCH_STATS_LEN and then subtract it 704 * effectively swapping the RX and TX statistics (giving us the RX 705 * and TX from perspective of the switch). 706 */ 707 swap_off = repr * NN_ET_SWITCH_STATS_LEN; 708 709 for (i = 0; i < NN_ET_SWITCH_STATS_LEN; i++) 710 ethtool_sprintf(&data, nfp_net_et_stats[i + swap_off].name); 711 712 for (i = NN_ET_SWITCH_STATS_LEN; i < NN_ET_SWITCH_STATS_LEN * 2; i++) 713 ethtool_sprintf(&data, nfp_net_et_stats[i - swap_off].name); 714 715 for (i = NN_ET_SWITCH_STATS_LEN * 2; i < NN_ET_GLOBAL_STATS_LEN; i++) 716 ethtool_sprintf(&data, nfp_net_et_stats[i].name); 717 718 for (i = 0; i < num_vecs; i++) { 719 ethtool_sprintf(&data, "rxq_%u_pkts", i); 720 ethtool_sprintf(&data, "rxq_%u_bytes", i); 721 ethtool_sprintf(&data, "txq_%u_pkts", i); 722 ethtool_sprintf(&data, "txq_%u_bytes", i); 723 } 724 725 return data; 726 } 727 728 static u64 * 729 nfp_vnic_get_hw_stats(u64 *data, u8 __iomem *mem, unsigned int num_vecs) 730 { 731 unsigned int i; 732 733 for (i = 0; i < NN_ET_GLOBAL_STATS_LEN; i++) 734 *data++ = readq(mem + nfp_net_et_stats[i].off); 735 736 for (i = 0; i < num_vecs; i++) { 737 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i)); 738 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8); 739 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i)); 740 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8); 741 } 742 743 return data; 744 } 745 746 static unsigned int nfp_vnic_get_tlv_stats_count(struct nfp_net *nn) 747 { 748 return nn->tlv_caps.vnic_stats_cnt + nn->max_r_vecs * 4; 749 } 750 751 static u8 *nfp_vnic_get_tlv_stats_strings(struct nfp_net *nn, u8 *data) 752 { 753 unsigned int i, id; 754 u8 __iomem *mem; 755 u64 id_word = 0; 756 757 mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off; 758 for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++) { 759 if (!(i % 4)) 760 id_word = readq(mem + i * 2); 761 762 id = (u16)id_word; 763 id_word >>= 16; 764 765 if (id < ARRAY_SIZE(nfp_tlv_stat_names) && 766 nfp_tlv_stat_names[id][0]) { 767 memcpy(data, nfp_tlv_stat_names[id], ETH_GSTRING_LEN); 768 data += ETH_GSTRING_LEN; 769 } else { 770 ethtool_sprintf(&data, "dev_unknown_stat%u", id); 771 } 772 } 773 774 for (i = 0; i < nn->max_r_vecs; i++) { 775 ethtool_sprintf(&data, "rxq_%u_pkts", i); 776 ethtool_sprintf(&data, "rxq_%u_bytes", i); 777 ethtool_sprintf(&data, "txq_%u_pkts", i); 778 ethtool_sprintf(&data, "txq_%u_bytes", i); 779 } 780 781 return data; 782 } 783 784 static u64 *nfp_vnic_get_tlv_stats(struct nfp_net *nn, u64 *data) 785 { 786 u8 __iomem *mem; 787 unsigned int i; 788 789 mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off; 790 mem += roundup(2 * nn->tlv_caps.vnic_stats_cnt, 8); 791 for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++) 792 *data++ = readq(mem + i * 8); 793 794 mem = nn->dp.ctrl_bar; 795 for (i = 0; i < nn->max_r_vecs; i++) { 796 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i)); 797 *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8); 798 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i)); 799 *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8); 800 } 801 802 return data; 803 } 804 805 static unsigned int nfp_mac_get_stats_count(struct net_device *netdev) 806 { 807 struct nfp_port *port; 808 809 port = nfp_port_from_netdev(netdev); 810 if (!__nfp_port_get_eth_port(port) || !port->eth_stats) 811 return 0; 812 813 return ARRAY_SIZE(nfp_mac_et_stats); 814 } 815 816 static u8 *nfp_mac_get_stats_strings(struct net_device *netdev, u8 *data) 817 { 818 struct nfp_port *port; 819 unsigned int i; 820 821 port = nfp_port_from_netdev(netdev); 822 if (!__nfp_port_get_eth_port(port) || !port->eth_stats) 823 return data; 824 825 for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++) 826 ethtool_sprintf(&data, "mac.%s", nfp_mac_et_stats[i].name); 827 828 return data; 829 } 830 831 static u64 *nfp_mac_get_stats(struct net_device *netdev, u64 *data) 832 { 833 struct nfp_port *port; 834 unsigned int i; 835 836 port = nfp_port_from_netdev(netdev); 837 if (!__nfp_port_get_eth_port(port) || !port->eth_stats) 838 return data; 839 840 for (i = 0; i < ARRAY_SIZE(nfp_mac_et_stats); i++) 841 *data++ = readq(port->eth_stats + nfp_mac_et_stats[i].off); 842 843 return data; 844 } 845 846 static void nfp_net_get_strings(struct net_device *netdev, 847 u32 stringset, u8 *data) 848 { 849 struct nfp_net *nn = netdev_priv(netdev); 850 851 switch (stringset) { 852 case ETH_SS_STATS: 853 data = nfp_vnic_get_sw_stats_strings(netdev, data); 854 if (!nn->tlv_caps.vnic_stats_off) 855 data = nfp_vnic_get_hw_stats_strings(data, 856 nn->max_r_vecs, 857 false); 858 else 859 data = nfp_vnic_get_tlv_stats_strings(nn, data); 860 data = nfp_mac_get_stats_strings(netdev, data); 861 data = nfp_app_port_get_stats_strings(nn->port, data); 862 break; 863 case ETH_SS_TEST: 864 nfp_get_self_test_strings(netdev, data); 865 break; 866 } 867 } 868 869 static void 870 nfp_net_get_stats(struct net_device *netdev, struct ethtool_stats *stats, 871 u64 *data) 872 { 873 struct nfp_net *nn = netdev_priv(netdev); 874 875 data = nfp_vnic_get_sw_stats(netdev, data); 876 if (!nn->tlv_caps.vnic_stats_off) 877 data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar, 878 nn->max_r_vecs); 879 else 880 data = nfp_vnic_get_tlv_stats(nn, data); 881 data = nfp_mac_get_stats(netdev, data); 882 data = nfp_app_port_get_stats(nn->port, data); 883 } 884 885 static int nfp_net_get_sset_count(struct net_device *netdev, int sset) 886 { 887 struct nfp_net *nn = netdev_priv(netdev); 888 unsigned int cnt; 889 890 switch (sset) { 891 case ETH_SS_STATS: 892 cnt = nfp_vnic_get_sw_stats_count(netdev); 893 if (!nn->tlv_caps.vnic_stats_off) 894 cnt += nfp_vnic_get_hw_stats_count(nn->max_r_vecs); 895 else 896 cnt += nfp_vnic_get_tlv_stats_count(nn); 897 cnt += nfp_mac_get_stats_count(netdev); 898 cnt += nfp_app_port_get_stats_count(nn->port); 899 return cnt; 900 case ETH_SS_TEST: 901 return nfp_get_self_test_count(netdev); 902 default: 903 return -EOPNOTSUPP; 904 } 905 } 906 907 static void nfp_port_get_strings(struct net_device *netdev, 908 u32 stringset, u8 *data) 909 { 910 struct nfp_port *port = nfp_port_from_netdev(netdev); 911 912 switch (stringset) { 913 case ETH_SS_STATS: 914 if (nfp_port_is_vnic(port)) 915 data = nfp_vnic_get_hw_stats_strings(data, 0, true); 916 else 917 data = nfp_mac_get_stats_strings(netdev, data); 918 data = nfp_app_port_get_stats_strings(port, data); 919 break; 920 case ETH_SS_TEST: 921 nfp_get_self_test_strings(netdev, data); 922 break; 923 } 924 } 925 926 static void 927 nfp_port_get_stats(struct net_device *netdev, struct ethtool_stats *stats, 928 u64 *data) 929 { 930 struct nfp_port *port = nfp_port_from_netdev(netdev); 931 932 if (nfp_port_is_vnic(port)) 933 data = nfp_vnic_get_hw_stats(data, port->vnic, 0); 934 else 935 data = nfp_mac_get_stats(netdev, data); 936 data = nfp_app_port_get_stats(port, data); 937 } 938 939 static int nfp_port_get_sset_count(struct net_device *netdev, int sset) 940 { 941 struct nfp_port *port = nfp_port_from_netdev(netdev); 942 unsigned int count; 943 944 switch (sset) { 945 case ETH_SS_STATS: 946 if (nfp_port_is_vnic(port)) 947 count = nfp_vnic_get_hw_stats_count(0); 948 else 949 count = nfp_mac_get_stats_count(netdev); 950 count += nfp_app_port_get_stats_count(port); 951 return count; 952 case ETH_SS_TEST: 953 return nfp_get_self_test_count(netdev); 954 default: 955 return -EOPNOTSUPP; 956 } 957 } 958 959 static int nfp_port_fec_ethtool_to_nsp(u32 fec) 960 { 961 switch (fec) { 962 case ETHTOOL_FEC_AUTO: 963 return NFP_FEC_AUTO_BIT; 964 case ETHTOOL_FEC_OFF: 965 return NFP_FEC_DISABLED_BIT; 966 case ETHTOOL_FEC_RS: 967 return NFP_FEC_REED_SOLOMON_BIT; 968 case ETHTOOL_FEC_BASER: 969 return NFP_FEC_BASER_BIT; 970 default: 971 /* NSP only supports a single mode at a time */ 972 return -EOPNOTSUPP; 973 } 974 } 975 976 static u32 nfp_port_fec_nsp_to_ethtool(u32 fec) 977 { 978 u32 result = 0; 979 980 if (fec & NFP_FEC_AUTO) 981 result |= ETHTOOL_FEC_AUTO; 982 if (fec & NFP_FEC_BASER) 983 result |= ETHTOOL_FEC_BASER; 984 if (fec & NFP_FEC_REED_SOLOMON) 985 result |= ETHTOOL_FEC_RS; 986 if (fec & NFP_FEC_DISABLED) 987 result |= ETHTOOL_FEC_OFF; 988 989 return result ?: ETHTOOL_FEC_NONE; 990 } 991 992 static int 993 nfp_port_get_fecparam(struct net_device *netdev, 994 struct ethtool_fecparam *param) 995 { 996 struct nfp_eth_table_port *eth_port; 997 struct nfp_port *port; 998 999 param->active_fec = ETHTOOL_FEC_NONE; 1000 param->fec = ETHTOOL_FEC_NONE; 1001 1002 port = nfp_port_from_netdev(netdev); 1003 eth_port = nfp_port_get_eth_port(port); 1004 if (!eth_port) 1005 return -EOPNOTSUPP; 1006 1007 if (!nfp_eth_can_support_fec(eth_port)) 1008 return 0; 1009 1010 param->fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec_modes_supported); 1011 param->active_fec = nfp_port_fec_nsp_to_ethtool(eth_port->fec); 1012 1013 return 0; 1014 } 1015 1016 static int 1017 nfp_port_set_fecparam(struct net_device *netdev, 1018 struct ethtool_fecparam *param) 1019 { 1020 struct nfp_eth_table_port *eth_port; 1021 struct nfp_port *port; 1022 int err, fec; 1023 1024 port = nfp_port_from_netdev(netdev); 1025 eth_port = nfp_port_get_eth_port(port); 1026 if (!eth_port) 1027 return -EOPNOTSUPP; 1028 1029 if (!nfp_eth_can_support_fec(eth_port)) 1030 return -EOPNOTSUPP; 1031 1032 fec = nfp_port_fec_ethtool_to_nsp(param->fec); 1033 if (fec < 0) 1034 return fec; 1035 1036 err = nfp_eth_set_fec(port->app->cpp, eth_port->index, fec); 1037 if (!err) 1038 /* Only refresh if we did something */ 1039 nfp_net_refresh_port_table(port); 1040 1041 return err < 0 ? err : 0; 1042 } 1043 1044 /* RX network flow classification (RSS, filters, etc) 1045 */ 1046 static u32 ethtool_flow_to_nfp_flag(u32 flow_type) 1047 { 1048 static const u32 xlate_ethtool_to_nfp[IPV6_FLOW + 1] = { 1049 [TCP_V4_FLOW] = NFP_NET_CFG_RSS_IPV4_TCP, 1050 [TCP_V6_FLOW] = NFP_NET_CFG_RSS_IPV6_TCP, 1051 [UDP_V4_FLOW] = NFP_NET_CFG_RSS_IPV4_UDP, 1052 [UDP_V6_FLOW] = NFP_NET_CFG_RSS_IPV6_UDP, 1053 [IPV4_FLOW] = NFP_NET_CFG_RSS_IPV4, 1054 [IPV6_FLOW] = NFP_NET_CFG_RSS_IPV6, 1055 }; 1056 1057 if (flow_type >= ARRAY_SIZE(xlate_ethtool_to_nfp)) 1058 return 0; 1059 1060 return xlate_ethtool_to_nfp[flow_type]; 1061 } 1062 1063 static int nfp_net_get_rss_hash_opts(struct nfp_net *nn, 1064 struct ethtool_rxnfc *cmd) 1065 { 1066 u32 nfp_rss_flag; 1067 1068 cmd->data = 0; 1069 1070 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) 1071 return -EOPNOTSUPP; 1072 1073 nfp_rss_flag = ethtool_flow_to_nfp_flag(cmd->flow_type); 1074 if (!nfp_rss_flag) 1075 return -EINVAL; 1076 1077 cmd->data |= RXH_IP_SRC | RXH_IP_DST; 1078 if (nn->rss_cfg & nfp_rss_flag) 1079 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1080 1081 return 0; 1082 } 1083 1084 static int nfp_net_get_rxnfc(struct net_device *netdev, 1085 struct ethtool_rxnfc *cmd, u32 *rule_locs) 1086 { 1087 struct nfp_net *nn = netdev_priv(netdev); 1088 1089 switch (cmd->cmd) { 1090 case ETHTOOL_GRXRINGS: 1091 cmd->data = nn->dp.num_rx_rings; 1092 return 0; 1093 case ETHTOOL_GRXFH: 1094 return nfp_net_get_rss_hash_opts(nn, cmd); 1095 default: 1096 return -EOPNOTSUPP; 1097 } 1098 } 1099 1100 static int nfp_net_set_rss_hash_opt(struct nfp_net *nn, 1101 struct ethtool_rxnfc *nfc) 1102 { 1103 u32 new_rss_cfg = nn->rss_cfg; 1104 u32 nfp_rss_flag; 1105 int err; 1106 1107 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) 1108 return -EOPNOTSUPP; 1109 1110 /* RSS only supports IP SA/DA and L4 src/dst ports */ 1111 if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | 1112 RXH_L4_B_0_1 | RXH_L4_B_2_3)) 1113 return -EINVAL; 1114 1115 /* We need at least the IP SA/DA fields for hashing */ 1116 if (!(nfc->data & RXH_IP_SRC) || 1117 !(nfc->data & RXH_IP_DST)) 1118 return -EINVAL; 1119 1120 nfp_rss_flag = ethtool_flow_to_nfp_flag(nfc->flow_type); 1121 if (!nfp_rss_flag) 1122 return -EINVAL; 1123 1124 switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 1125 case 0: 1126 new_rss_cfg &= ~nfp_rss_flag; 1127 break; 1128 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 1129 new_rss_cfg |= nfp_rss_flag; 1130 break; 1131 default: 1132 return -EINVAL; 1133 } 1134 1135 new_rss_cfg |= FIELD_PREP(NFP_NET_CFG_RSS_HFUNC, nn->rss_hfunc); 1136 new_rss_cfg |= NFP_NET_CFG_RSS_MASK; 1137 1138 if (new_rss_cfg == nn->rss_cfg) 1139 return 0; 1140 1141 writel(new_rss_cfg, nn->dp.ctrl_bar + NFP_NET_CFG_RSS_CTRL); 1142 err = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS); 1143 if (err) 1144 return err; 1145 1146 nn->rss_cfg = new_rss_cfg; 1147 1148 nn_dbg(nn, "Changed RSS config to 0x%x\n", nn->rss_cfg); 1149 return 0; 1150 } 1151 1152 static int nfp_net_set_rxnfc(struct net_device *netdev, 1153 struct ethtool_rxnfc *cmd) 1154 { 1155 struct nfp_net *nn = netdev_priv(netdev); 1156 1157 switch (cmd->cmd) { 1158 case ETHTOOL_SRXFH: 1159 return nfp_net_set_rss_hash_opt(nn, cmd); 1160 default: 1161 return -EOPNOTSUPP; 1162 } 1163 } 1164 1165 static u32 nfp_net_get_rxfh_indir_size(struct net_device *netdev) 1166 { 1167 struct nfp_net *nn = netdev_priv(netdev); 1168 1169 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) 1170 return 0; 1171 1172 return ARRAY_SIZE(nn->rss_itbl); 1173 } 1174 1175 static u32 nfp_net_get_rxfh_key_size(struct net_device *netdev) 1176 { 1177 struct nfp_net *nn = netdev_priv(netdev); 1178 1179 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) 1180 return -EOPNOTSUPP; 1181 1182 return nfp_net_rss_key_sz(nn); 1183 } 1184 1185 static int nfp_net_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, 1186 u8 *hfunc) 1187 { 1188 struct nfp_net *nn = netdev_priv(netdev); 1189 int i; 1190 1191 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY)) 1192 return -EOPNOTSUPP; 1193 1194 if (indir) 1195 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++) 1196 indir[i] = nn->rss_itbl[i]; 1197 if (key) 1198 memcpy(key, nn->rss_key, nfp_net_rss_key_sz(nn)); 1199 if (hfunc) { 1200 *hfunc = nn->rss_hfunc; 1201 if (*hfunc >= 1 << ETH_RSS_HASH_FUNCS_COUNT) 1202 *hfunc = ETH_RSS_HASH_UNKNOWN; 1203 } 1204 1205 return 0; 1206 } 1207 1208 static int nfp_net_set_rxfh(struct net_device *netdev, 1209 const u32 *indir, const u8 *key, 1210 const u8 hfunc) 1211 { 1212 struct nfp_net *nn = netdev_priv(netdev); 1213 int i; 1214 1215 if (!(nn->cap & NFP_NET_CFG_CTRL_RSS_ANY) || 1216 !(hfunc == ETH_RSS_HASH_NO_CHANGE || hfunc == nn->rss_hfunc)) 1217 return -EOPNOTSUPP; 1218 1219 if (!key && !indir) 1220 return 0; 1221 1222 if (key) { 1223 memcpy(nn->rss_key, key, nfp_net_rss_key_sz(nn)); 1224 nfp_net_rss_write_key(nn); 1225 } 1226 if (indir) { 1227 for (i = 0; i < ARRAY_SIZE(nn->rss_itbl); i++) 1228 nn->rss_itbl[i] = indir[i]; 1229 1230 nfp_net_rss_write_itbl(nn); 1231 } 1232 1233 return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_RSS); 1234 } 1235 1236 /* Dump BAR registers 1237 */ 1238 static int nfp_net_get_regs_len(struct net_device *netdev) 1239 { 1240 return NFP_NET_CFG_BAR_SZ; 1241 } 1242 1243 static void nfp_net_get_regs(struct net_device *netdev, 1244 struct ethtool_regs *regs, void *p) 1245 { 1246 struct nfp_net *nn = netdev_priv(netdev); 1247 u32 *regs_buf = p; 1248 int i; 1249 1250 regs->version = nn_readl(nn, NFP_NET_CFG_VERSION); 1251 1252 for (i = 0; i < NFP_NET_CFG_BAR_SZ / sizeof(u32); i++) 1253 regs_buf[i] = readl(nn->dp.ctrl_bar + (i * sizeof(u32))); 1254 } 1255 1256 static int nfp_net_get_coalesce(struct net_device *netdev, 1257 struct ethtool_coalesce *ec, 1258 struct kernel_ethtool_coalesce *kernel_coal, 1259 struct netlink_ext_ack *extack) 1260 { 1261 struct nfp_net *nn = netdev_priv(netdev); 1262 1263 if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD)) 1264 return -EINVAL; 1265 1266 ec->use_adaptive_rx_coalesce = nn->rx_coalesce_adapt_on; 1267 ec->use_adaptive_tx_coalesce = nn->tx_coalesce_adapt_on; 1268 1269 ec->rx_coalesce_usecs = nn->rx_coalesce_usecs; 1270 ec->rx_max_coalesced_frames = nn->rx_coalesce_max_frames; 1271 ec->tx_coalesce_usecs = nn->tx_coalesce_usecs; 1272 ec->tx_max_coalesced_frames = nn->tx_coalesce_max_frames; 1273 1274 return 0; 1275 } 1276 1277 /* Other debug dumps 1278 */ 1279 static int 1280 nfp_dump_nsp_diag(struct nfp_app *app, struct ethtool_dump *dump, void *buffer) 1281 { 1282 struct nfp_resource *res; 1283 int ret; 1284 1285 if (!app) 1286 return -EOPNOTSUPP; 1287 1288 dump->version = 1; 1289 dump->flag = NFP_DUMP_NSP_DIAG; 1290 1291 res = nfp_resource_acquire(app->cpp, NFP_RESOURCE_NSP_DIAG); 1292 if (IS_ERR(res)) 1293 return PTR_ERR(res); 1294 1295 if (buffer) { 1296 if (dump->len != nfp_resource_size(res)) { 1297 ret = -EINVAL; 1298 goto exit_release; 1299 } 1300 1301 ret = nfp_cpp_read(app->cpp, nfp_resource_cpp_id(res), 1302 nfp_resource_address(res), 1303 buffer, dump->len); 1304 if (ret != dump->len) 1305 ret = ret < 0 ? ret : -EIO; 1306 else 1307 ret = 0; 1308 } else { 1309 dump->len = nfp_resource_size(res); 1310 ret = 0; 1311 } 1312 exit_release: 1313 nfp_resource_release(res); 1314 1315 return ret; 1316 } 1317 1318 /* Set the dump flag/level. Calculate the dump length for flag > 0 only (new TLV 1319 * based dumps), since flag 0 (default) calculates the length in 1320 * nfp_app_get_dump_flag(), and we need to support triggering a level 0 dump 1321 * without setting the flag first, for backward compatibility. 1322 */ 1323 static int nfp_app_set_dump(struct net_device *netdev, struct ethtool_dump *val) 1324 { 1325 struct nfp_app *app = nfp_app_from_netdev(netdev); 1326 s64 len; 1327 1328 if (!app) 1329 return -EOPNOTSUPP; 1330 1331 if (val->flag == NFP_DUMP_NSP_DIAG) { 1332 app->pf->dump_flag = val->flag; 1333 return 0; 1334 } 1335 1336 if (!app->pf->dumpspec) 1337 return -EOPNOTSUPP; 1338 1339 len = nfp_net_dump_calculate_size(app->pf, app->pf->dumpspec, 1340 val->flag); 1341 if (len < 0) 1342 return len; 1343 1344 app->pf->dump_flag = val->flag; 1345 app->pf->dump_len = len; 1346 1347 return 0; 1348 } 1349 1350 static int 1351 nfp_app_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump) 1352 { 1353 struct nfp_app *app = nfp_app_from_netdev(netdev); 1354 1355 if (!app) 1356 return -EOPNOTSUPP; 1357 1358 if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG) 1359 return nfp_dump_nsp_diag(app, dump, NULL); 1360 1361 dump->flag = app->pf->dump_flag; 1362 dump->len = app->pf->dump_len; 1363 1364 return 0; 1365 } 1366 1367 static int 1368 nfp_app_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump, 1369 void *buffer) 1370 { 1371 struct nfp_app *app = nfp_app_from_netdev(netdev); 1372 1373 if (!app) 1374 return -EOPNOTSUPP; 1375 1376 if (app->pf->dump_flag == NFP_DUMP_NSP_DIAG) 1377 return nfp_dump_nsp_diag(app, dump, buffer); 1378 1379 dump->flag = app->pf->dump_flag; 1380 dump->len = app->pf->dump_len; 1381 1382 return nfp_net_dump_populate_buffer(app->pf, app->pf->dumpspec, dump, 1383 buffer); 1384 } 1385 1386 static int 1387 nfp_port_get_module_info(struct net_device *netdev, 1388 struct ethtool_modinfo *modinfo) 1389 { 1390 struct nfp_eth_table_port *eth_port; 1391 struct nfp_port *port; 1392 unsigned int read_len; 1393 struct nfp_nsp *nsp; 1394 int err = 0; 1395 u8 data; 1396 1397 port = nfp_port_from_netdev(netdev); 1398 /* update port state to get latest interface */ 1399 set_bit(NFP_PORT_CHANGED, &port->flags); 1400 eth_port = nfp_port_get_eth_port(port); 1401 if (!eth_port) 1402 return -EOPNOTSUPP; 1403 1404 nsp = nfp_nsp_open(port->app->cpp); 1405 if (IS_ERR(nsp)) { 1406 err = PTR_ERR(nsp); 1407 netdev_err(netdev, "Failed to access the NSP: %d\n", err); 1408 return err; 1409 } 1410 1411 if (!nfp_nsp_has_read_module_eeprom(nsp)) { 1412 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n"); 1413 err = -EOPNOTSUPP; 1414 goto exit_close_nsp; 1415 } 1416 1417 switch (eth_port->interface) { 1418 case NFP_INTERFACE_SFP: 1419 case NFP_INTERFACE_SFP28: 1420 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, 1421 SFP_SFF8472_COMPLIANCE, &data, 1422 1, &read_len); 1423 if (err < 0) 1424 goto exit_close_nsp; 1425 1426 if (!data) { 1427 modinfo->type = ETH_MODULE_SFF_8079; 1428 modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; 1429 } else { 1430 modinfo->type = ETH_MODULE_SFF_8472; 1431 modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; 1432 } 1433 break; 1434 case NFP_INTERFACE_QSFP: 1435 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, 1436 SFP_SFF_REV_COMPLIANCE, &data, 1437 1, &read_len); 1438 if (err < 0) 1439 goto exit_close_nsp; 1440 1441 if (data < 0x3) { 1442 modinfo->type = ETH_MODULE_SFF_8436; 1443 modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; 1444 } else { 1445 modinfo->type = ETH_MODULE_SFF_8636; 1446 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; 1447 } 1448 break; 1449 case NFP_INTERFACE_QSFP28: 1450 modinfo->type = ETH_MODULE_SFF_8636; 1451 modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; 1452 break; 1453 default: 1454 netdev_err(netdev, "Unsupported module 0x%x detected\n", 1455 eth_port->interface); 1456 err = -EINVAL; 1457 } 1458 1459 exit_close_nsp: 1460 nfp_nsp_close(nsp); 1461 return err; 1462 } 1463 1464 static int 1465 nfp_port_get_module_eeprom(struct net_device *netdev, 1466 struct ethtool_eeprom *eeprom, u8 *data) 1467 { 1468 struct nfp_eth_table_port *eth_port; 1469 struct nfp_port *port; 1470 struct nfp_nsp *nsp; 1471 int err; 1472 1473 port = nfp_port_from_netdev(netdev); 1474 eth_port = __nfp_port_get_eth_port(port); 1475 if (!eth_port) 1476 return -EOPNOTSUPP; 1477 1478 nsp = nfp_nsp_open(port->app->cpp); 1479 if (IS_ERR(nsp)) { 1480 err = PTR_ERR(nsp); 1481 netdev_err(netdev, "Failed to access the NSP: %d\n", err); 1482 return err; 1483 } 1484 1485 if (!nfp_nsp_has_read_module_eeprom(nsp)) { 1486 netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n"); 1487 err = -EOPNOTSUPP; 1488 goto exit_close_nsp; 1489 } 1490 1491 err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, 1492 eeprom->offset, data, eeprom->len, 1493 &eeprom->len); 1494 if (err < 0) { 1495 if (eeprom->len) { 1496 netdev_warn(netdev, 1497 "Incomplete read from module EEPROM: %d\n", 1498 err); 1499 err = 0; 1500 } else { 1501 netdev_err(netdev, 1502 "Reading from module EEPROM failed: %d\n", 1503 err); 1504 } 1505 } 1506 1507 exit_close_nsp: 1508 nfp_nsp_close(nsp); 1509 return err; 1510 } 1511 1512 static int nfp_net_set_coalesce(struct net_device *netdev, 1513 struct ethtool_coalesce *ec, 1514 struct kernel_ethtool_coalesce *kernel_coal, 1515 struct netlink_ext_ack *extack) 1516 { 1517 struct nfp_net *nn = netdev_priv(netdev); 1518 unsigned int factor; 1519 1520 /* Compute factor used to convert coalesce '_usecs' parameters to 1521 * ME timestamp ticks. There are 16 ME clock cycles for each timestamp 1522 * count. 1523 */ 1524 factor = nn->tlv_caps.me_freq_mhz / 16; 1525 1526 /* Each pair of (usecs, max_frames) fields specifies that interrupts 1527 * should be coalesced until 1528 * (usecs > 0 && time_since_first_completion >= usecs) || 1529 * (max_frames > 0 && completed_frames >= max_frames) 1530 * 1531 * It is illegal to set both usecs and max_frames to zero as this would 1532 * cause interrupts to never be generated. To disable coalescing, set 1533 * usecs = 0 and max_frames = 1. 1534 * 1535 * Some implementations ignore the value of max_frames and use the 1536 * condition time_since_first_completion >= usecs 1537 */ 1538 1539 if (!(nn->cap & NFP_NET_CFG_CTRL_IRQMOD)) 1540 return -EINVAL; 1541 1542 /* ensure valid configuration */ 1543 if (!ec->rx_coalesce_usecs && !ec->rx_max_coalesced_frames) 1544 return -EINVAL; 1545 1546 if (!ec->tx_coalesce_usecs && !ec->tx_max_coalesced_frames) 1547 return -EINVAL; 1548 1549 if (nfp_net_coalesce_para_check(ec->rx_coalesce_usecs * factor, 1550 ec->rx_max_coalesced_frames)) 1551 return -EINVAL; 1552 1553 if (nfp_net_coalesce_para_check(ec->tx_coalesce_usecs * factor, 1554 ec->tx_max_coalesced_frames)) 1555 return -EINVAL; 1556 1557 /* configuration is valid */ 1558 nn->rx_coalesce_adapt_on = !!ec->use_adaptive_rx_coalesce; 1559 nn->tx_coalesce_adapt_on = !!ec->use_adaptive_tx_coalesce; 1560 1561 nn->rx_coalesce_usecs = ec->rx_coalesce_usecs; 1562 nn->rx_coalesce_max_frames = ec->rx_max_coalesced_frames; 1563 nn->tx_coalesce_usecs = ec->tx_coalesce_usecs; 1564 nn->tx_coalesce_max_frames = ec->tx_max_coalesced_frames; 1565 1566 /* write configuration to device */ 1567 nfp_net_coalesce_write_cfg(nn); 1568 return nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_IRQMOD); 1569 } 1570 1571 static void nfp_net_get_channels(struct net_device *netdev, 1572 struct ethtool_channels *channel) 1573 { 1574 struct nfp_net *nn = netdev_priv(netdev); 1575 unsigned int num_tx_rings; 1576 1577 num_tx_rings = nn->dp.num_tx_rings; 1578 if (nn->dp.xdp_prog) 1579 num_tx_rings -= nn->dp.num_rx_rings; 1580 1581 channel->max_rx = min(nn->max_rx_rings, nn->max_r_vecs); 1582 channel->max_tx = min(nn->max_tx_rings, nn->max_r_vecs); 1583 channel->max_combined = min(channel->max_rx, channel->max_tx); 1584 channel->max_other = NFP_NET_NON_Q_VECTORS; 1585 channel->combined_count = min(nn->dp.num_rx_rings, num_tx_rings); 1586 channel->rx_count = nn->dp.num_rx_rings - channel->combined_count; 1587 channel->tx_count = num_tx_rings - channel->combined_count; 1588 channel->other_count = NFP_NET_NON_Q_VECTORS; 1589 } 1590 1591 static int nfp_net_set_num_rings(struct nfp_net *nn, unsigned int total_rx, 1592 unsigned int total_tx) 1593 { 1594 struct nfp_net_dp *dp; 1595 1596 dp = nfp_net_clone_dp(nn); 1597 if (!dp) 1598 return -ENOMEM; 1599 1600 dp->num_rx_rings = total_rx; 1601 dp->num_tx_rings = total_tx; 1602 /* nfp_net_check_config() will catch num_tx_rings > nn->max_tx_rings */ 1603 if (dp->xdp_prog) 1604 dp->num_tx_rings += total_rx; 1605 1606 return nfp_net_ring_reconfig(nn, dp, NULL); 1607 } 1608 1609 static int nfp_net_set_channels(struct net_device *netdev, 1610 struct ethtool_channels *channel) 1611 { 1612 struct nfp_net *nn = netdev_priv(netdev); 1613 unsigned int total_rx, total_tx; 1614 1615 /* Reject unsupported */ 1616 if (channel->other_count != NFP_NET_NON_Q_VECTORS || 1617 (channel->rx_count && channel->tx_count)) 1618 return -EINVAL; 1619 1620 total_rx = channel->combined_count + channel->rx_count; 1621 total_tx = channel->combined_count + channel->tx_count; 1622 1623 if (total_rx > min(nn->max_rx_rings, nn->max_r_vecs) || 1624 total_tx > min(nn->max_tx_rings, nn->max_r_vecs)) 1625 return -EINVAL; 1626 1627 return nfp_net_set_num_rings(nn, total_rx, total_tx); 1628 } 1629 1630 static void nfp_port_get_pauseparam(struct net_device *netdev, 1631 struct ethtool_pauseparam *pause) 1632 { 1633 struct nfp_eth_table_port *eth_port; 1634 struct nfp_port *port; 1635 1636 port = nfp_port_from_netdev(netdev); 1637 eth_port = nfp_port_get_eth_port(port); 1638 if (!eth_port) 1639 return; 1640 1641 /* Currently pause frame support is fixed */ 1642 pause->autoneg = AUTONEG_DISABLE; 1643 pause->rx_pause = 1; 1644 pause->tx_pause = 1; 1645 } 1646 1647 static int nfp_net_set_phys_id(struct net_device *netdev, 1648 enum ethtool_phys_id_state state) 1649 { 1650 struct nfp_eth_table_port *eth_port; 1651 struct nfp_port *port; 1652 int err; 1653 1654 port = nfp_port_from_netdev(netdev); 1655 eth_port = __nfp_port_get_eth_port(port); 1656 if (!eth_port) 1657 return -EOPNOTSUPP; 1658 1659 switch (state) { 1660 case ETHTOOL_ID_ACTIVE: 1661 /* Control LED to blink */ 1662 err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 1); 1663 break; 1664 1665 case ETHTOOL_ID_INACTIVE: 1666 /* Control LED to normal mode */ 1667 err = nfp_eth_set_idmode(port->app->cpp, eth_port->index, 0); 1668 break; 1669 1670 case ETHTOOL_ID_ON: 1671 case ETHTOOL_ID_OFF: 1672 default: 1673 return -EOPNOTSUPP; 1674 } 1675 1676 return err; 1677 } 1678 1679 static const struct ethtool_ops nfp_net_ethtool_ops = { 1680 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1681 ETHTOOL_COALESCE_MAX_FRAMES | 1682 ETHTOOL_COALESCE_USE_ADAPTIVE, 1683 .get_drvinfo = nfp_net_get_drvinfo, 1684 .get_link = ethtool_op_get_link, 1685 .get_ringparam = nfp_net_get_ringparam, 1686 .set_ringparam = nfp_net_set_ringparam, 1687 .self_test = nfp_net_self_test, 1688 .get_strings = nfp_net_get_strings, 1689 .get_ethtool_stats = nfp_net_get_stats, 1690 .get_sset_count = nfp_net_get_sset_count, 1691 .get_rxnfc = nfp_net_get_rxnfc, 1692 .set_rxnfc = nfp_net_set_rxnfc, 1693 .get_rxfh_indir_size = nfp_net_get_rxfh_indir_size, 1694 .get_rxfh_key_size = nfp_net_get_rxfh_key_size, 1695 .get_rxfh = nfp_net_get_rxfh, 1696 .set_rxfh = nfp_net_set_rxfh, 1697 .get_regs_len = nfp_net_get_regs_len, 1698 .get_regs = nfp_net_get_regs, 1699 .set_dump = nfp_app_set_dump, 1700 .get_dump_flag = nfp_app_get_dump_flag, 1701 .get_dump_data = nfp_app_get_dump_data, 1702 .get_module_info = nfp_port_get_module_info, 1703 .get_module_eeprom = nfp_port_get_module_eeprom, 1704 .get_coalesce = nfp_net_get_coalesce, 1705 .set_coalesce = nfp_net_set_coalesce, 1706 .get_channels = nfp_net_get_channels, 1707 .set_channels = nfp_net_set_channels, 1708 .get_link_ksettings = nfp_net_get_link_ksettings, 1709 .set_link_ksettings = nfp_net_set_link_ksettings, 1710 .get_fecparam = nfp_port_get_fecparam, 1711 .set_fecparam = nfp_port_set_fecparam, 1712 .get_pauseparam = nfp_port_get_pauseparam, 1713 .set_phys_id = nfp_net_set_phys_id, 1714 }; 1715 1716 const struct ethtool_ops nfp_port_ethtool_ops = { 1717 .get_drvinfo = nfp_app_get_drvinfo, 1718 .get_link = ethtool_op_get_link, 1719 .get_strings = nfp_port_get_strings, 1720 .get_ethtool_stats = nfp_port_get_stats, 1721 .self_test = nfp_net_self_test, 1722 .get_sset_count = nfp_port_get_sset_count, 1723 .set_dump = nfp_app_set_dump, 1724 .get_dump_flag = nfp_app_get_dump_flag, 1725 .get_dump_data = nfp_app_get_dump_data, 1726 .get_module_info = nfp_port_get_module_info, 1727 .get_module_eeprom = nfp_port_get_module_eeprom, 1728 .get_link_ksettings = nfp_net_get_link_ksettings, 1729 .set_link_ksettings = nfp_net_set_link_ksettings, 1730 .get_fecparam = nfp_port_get_fecparam, 1731 .set_fecparam = nfp_port_set_fecparam, 1732 .get_pauseparam = nfp_port_get_pauseparam, 1733 .set_phys_id = nfp_net_set_phys_id, 1734 }; 1735 1736 void nfp_net_set_ethtool_ops(struct net_device *netdev) 1737 { 1738 netdev->ethtool_ops = &nfp_net_ethtool_ops; 1739 } 1740