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