.. | .. |
---|
1 | | -/* |
---|
2 | | - * Copyright (C) 2015-2017 Netronome Systems, Inc. |
---|
3 | | - * |
---|
4 | | - * This software is dual licensed under the GNU General License Version 2, |
---|
5 | | - * June 1991 as shown in the file COPYING in the top-level directory of this |
---|
6 | | - * source tree or the BSD 2-Clause License provided below. You have the |
---|
7 | | - * option to license this software under the complete terms of either license. |
---|
8 | | - * |
---|
9 | | - * The BSD 2-Clause License: |
---|
10 | | - * |
---|
11 | | - * Redistribution and use in source and binary forms, with or |
---|
12 | | - * without modification, are permitted provided that the following |
---|
13 | | - * conditions are met: |
---|
14 | | - * |
---|
15 | | - * 1. Redistributions of source code must retain the above |
---|
16 | | - * copyright notice, this list of conditions and the following |
---|
17 | | - * disclaimer. |
---|
18 | | - * |
---|
19 | | - * 2. Redistributions in binary form must reproduce the above |
---|
20 | | - * copyright notice, this list of conditions and the following |
---|
21 | | - * disclaimer in the documentation and/or other materials |
---|
22 | | - * provided with the distribution. |
---|
23 | | - * |
---|
24 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
25 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
---|
26 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
27 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
---|
28 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
---|
29 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
---|
30 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
31 | | - * SOFTWARE. |
---|
32 | | - */ |
---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) |
---|
| 2 | +/* Copyright (C) 2015-2018 Netronome Systems, Inc. */ |
---|
33 | 3 | |
---|
34 | 4 | /* |
---|
35 | 5 | * nfp_net_ethtool.c |
---|
.. | .. |
---|
48 | 18 | #include <linux/pci.h> |
---|
49 | 19 | #include <linux/ethtool.h> |
---|
50 | 20 | #include <linux/firmware.h> |
---|
| 21 | +#include <linux/sfp.h> |
---|
51 | 22 | |
---|
52 | 23 | #include "nfpcore/nfp.h" |
---|
53 | 24 | #include "nfpcore/nfp_nsp.h" |
---|
.. | .. |
---|
177 | 148 | { "tx_pause_frames_class7", NFP_MAC_STATS_TX_PAUSE_FRAMES_CLASS7, }, |
---|
178 | 149 | }; |
---|
179 | 150 | |
---|
| 151 | +static const char nfp_tlv_stat_names[][ETH_GSTRING_LEN] = { |
---|
| 152 | + [1] = "dev_rx_discards", |
---|
| 153 | + [2] = "dev_rx_errors", |
---|
| 154 | + [3] = "dev_rx_bytes", |
---|
| 155 | + [4] = "dev_rx_uc_bytes", |
---|
| 156 | + [5] = "dev_rx_mc_bytes", |
---|
| 157 | + [6] = "dev_rx_bc_bytes", |
---|
| 158 | + [7] = "dev_rx_pkts", |
---|
| 159 | + [8] = "dev_rx_mc_pkts", |
---|
| 160 | + [9] = "dev_rx_bc_pkts", |
---|
| 161 | + |
---|
| 162 | + [10] = "dev_tx_discards", |
---|
| 163 | + [11] = "dev_tx_errors", |
---|
| 164 | + [12] = "dev_tx_bytes", |
---|
| 165 | + [13] = "dev_tx_uc_bytes", |
---|
| 166 | + [14] = "dev_tx_mc_bytes", |
---|
| 167 | + [15] = "dev_tx_bc_bytes", |
---|
| 168 | + [16] = "dev_tx_pkts", |
---|
| 169 | + [17] = "dev_tx_mc_pkts", |
---|
| 170 | + [18] = "dev_tx_bc_pkts", |
---|
| 171 | +}; |
---|
| 172 | + |
---|
180 | 173 | #define NN_ET_GLOBAL_STATS_LEN ARRAY_SIZE(nfp_net_et_stats) |
---|
181 | 174 | #define NN_ET_SWITCH_STATS_LEN 9 |
---|
182 | | -#define NN_RVEC_GATHER_STATS 9 |
---|
| 175 | +#define NN_RVEC_GATHER_STATS 13 |
---|
183 | 176 | #define NN_RVEC_PER_Q_STATS 3 |
---|
| 177 | +#define NN_CTRL_PATH_STATS 4 |
---|
| 178 | + |
---|
| 179 | +#define SFP_SFF_REV_COMPLIANCE 1 |
---|
184 | 180 | |
---|
185 | 181 | static void nfp_net_get_nspinfo(struct nfp_app *app, char *version) |
---|
186 | 182 | { |
---|
.. | .. |
---|
207 | 203 | char nsp_version[ETHTOOL_FWVERS_LEN] = {}; |
---|
208 | 204 | |
---|
209 | 205 | strlcpy(drvinfo->driver, pdev->driver->name, sizeof(drvinfo->driver)); |
---|
210 | | - strlcpy(drvinfo->version, nfp_driver_version, sizeof(drvinfo->version)); |
---|
211 | | - |
---|
212 | 206 | nfp_net_get_nspinfo(app, nsp_version); |
---|
213 | 207 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), |
---|
214 | 208 | "%s %s %s %s", vnic_version, nsp_version, |
---|
.. | .. |
---|
292 | 286 | |
---|
293 | 287 | /* Init to unknowns */ |
---|
294 | 288 | ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); |
---|
295 | | - ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); |
---|
296 | | - ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); |
---|
297 | 289 | cmd->base.port = PORT_OTHER; |
---|
298 | 290 | cmd->base.speed = SPEED_UNKNOWN; |
---|
299 | 291 | cmd->base.duplex = DUPLEX_UNKNOWN; |
---|
.. | .. |
---|
301 | 293 | port = nfp_port_from_netdev(netdev); |
---|
302 | 294 | eth_port = nfp_port_get_eth_port(port); |
---|
303 | 295 | if (eth_port) { |
---|
| 296 | + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); |
---|
| 297 | + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); |
---|
304 | 298 | cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ? |
---|
305 | 299 | AUTONEG_ENABLE : AUTONEG_DISABLE; |
---|
306 | 300 | nfp_net_set_fec_link_mode(eth_port, cmd); |
---|
.. | .. |
---|
452 | 446 | { |
---|
453 | 447 | struct nfp_net *nn = netdev_priv(netdev); |
---|
454 | 448 | |
---|
455 | | - return NN_RVEC_GATHER_STATS + nn->max_r_vecs * NN_RVEC_PER_Q_STATS; |
---|
| 449 | + return NN_RVEC_GATHER_STATS + nn->max_r_vecs * NN_RVEC_PER_Q_STATS + |
---|
| 450 | + NN_CTRL_PATH_STATS; |
---|
456 | 451 | } |
---|
457 | 452 | |
---|
458 | 453 | static u8 *nfp_vnic_get_sw_stats_strings(struct net_device *netdev, u8 *data) |
---|
.. | .. |
---|
471 | 466 | data = nfp_pr_et(data, "hw_rx_csum_complete"); |
---|
472 | 467 | data = nfp_pr_et(data, "hw_rx_csum_err"); |
---|
473 | 468 | data = nfp_pr_et(data, "rx_replace_buf_alloc_fail"); |
---|
| 469 | + data = nfp_pr_et(data, "rx_tls_decrypted_packets"); |
---|
474 | 470 | data = nfp_pr_et(data, "hw_tx_csum"); |
---|
475 | 471 | data = nfp_pr_et(data, "hw_tx_inner_csum"); |
---|
476 | 472 | data = nfp_pr_et(data, "tx_gather"); |
---|
477 | 473 | data = nfp_pr_et(data, "tx_lso"); |
---|
| 474 | + data = nfp_pr_et(data, "tx_tls_encrypted_packets"); |
---|
| 475 | + data = nfp_pr_et(data, "tx_tls_ooo"); |
---|
| 476 | + data = nfp_pr_et(data, "tx_tls_drop_no_sync_data"); |
---|
| 477 | + |
---|
| 478 | + data = nfp_pr_et(data, "hw_tls_no_space"); |
---|
| 479 | + data = nfp_pr_et(data, "rx_tls_resync_req_ok"); |
---|
| 480 | + data = nfp_pr_et(data, "rx_tls_resync_req_ign"); |
---|
| 481 | + data = nfp_pr_et(data, "rx_tls_resync_sent"); |
---|
478 | 482 | |
---|
479 | 483 | return data; |
---|
480 | 484 | } |
---|
.. | .. |
---|
490 | 494 | unsigned int start; |
---|
491 | 495 | |
---|
492 | 496 | do { |
---|
493 | | - start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); |
---|
| 497 | + start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].rx_sync); |
---|
494 | 498 | data[0] = nn->r_vecs[i].rx_pkts; |
---|
495 | 499 | tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; |
---|
496 | 500 | tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; |
---|
497 | 501 | tmp[2] = nn->r_vecs[i].hw_csum_rx_complete; |
---|
498 | 502 | tmp[3] = nn->r_vecs[i].hw_csum_rx_error; |
---|
499 | 503 | tmp[4] = nn->r_vecs[i].rx_replace_buf_alloc_fail; |
---|
500 | | - } while (u64_stats_fetch_retry(&nn->r_vecs[i].rx_sync, start)); |
---|
| 504 | + tmp[5] = nn->r_vecs[i].hw_tls_rx; |
---|
| 505 | + } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].rx_sync, start)); |
---|
501 | 506 | |
---|
502 | 507 | do { |
---|
503 | | - start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); |
---|
| 508 | + start = u64_stats_fetch_begin_irq(&nn->r_vecs[i].tx_sync); |
---|
504 | 509 | data[1] = nn->r_vecs[i].tx_pkts; |
---|
505 | 510 | data[2] = nn->r_vecs[i].tx_busy; |
---|
506 | | - tmp[5] = nn->r_vecs[i].hw_csum_tx; |
---|
507 | | - tmp[6] = nn->r_vecs[i].hw_csum_tx_inner; |
---|
508 | | - tmp[7] = nn->r_vecs[i].tx_gather; |
---|
509 | | - tmp[8] = nn->r_vecs[i].tx_lso; |
---|
510 | | - } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); |
---|
| 511 | + tmp[6] = nn->r_vecs[i].hw_csum_tx; |
---|
| 512 | + tmp[7] = nn->r_vecs[i].hw_csum_tx_inner; |
---|
| 513 | + tmp[8] = nn->r_vecs[i].tx_gather; |
---|
| 514 | + tmp[9] = nn->r_vecs[i].tx_lso; |
---|
| 515 | + tmp[10] = nn->r_vecs[i].hw_tls_tx; |
---|
| 516 | + tmp[11] = nn->r_vecs[i].tls_tx_fallback; |
---|
| 517 | + tmp[12] = nn->r_vecs[i].tls_tx_no_fallback; |
---|
| 518 | + } while (u64_stats_fetch_retry_irq(&nn->r_vecs[i].tx_sync, start)); |
---|
511 | 519 | |
---|
512 | 520 | data += NN_RVEC_PER_Q_STATS; |
---|
513 | 521 | |
---|
.. | .. |
---|
517 | 525 | |
---|
518 | 526 | for (j = 0; j < NN_RVEC_GATHER_STATS; j++) |
---|
519 | 527 | *data++ = gathered_stats[j]; |
---|
| 528 | + |
---|
| 529 | + *data++ = atomic_read(&nn->ktls_no_space); |
---|
| 530 | + *data++ = atomic_read(&nn->ktls_rx_resync_req); |
---|
| 531 | + *data++ = atomic_read(&nn->ktls_rx_resync_ign); |
---|
| 532 | + *data++ = atomic_read(&nn->ktls_rx_resync_sent); |
---|
520 | 533 | |
---|
521 | 534 | return data; |
---|
522 | 535 | } |
---|
.. | .. |
---|
575 | 588 | return data; |
---|
576 | 589 | } |
---|
577 | 590 | |
---|
| 591 | +static unsigned int nfp_vnic_get_tlv_stats_count(struct nfp_net *nn) |
---|
| 592 | +{ |
---|
| 593 | + return nn->tlv_caps.vnic_stats_cnt + nn->max_r_vecs * 4; |
---|
| 594 | +} |
---|
| 595 | + |
---|
| 596 | +static u8 *nfp_vnic_get_tlv_stats_strings(struct nfp_net *nn, u8 *data) |
---|
| 597 | +{ |
---|
| 598 | + unsigned int i, id; |
---|
| 599 | + u8 __iomem *mem; |
---|
| 600 | + u64 id_word = 0; |
---|
| 601 | + |
---|
| 602 | + mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off; |
---|
| 603 | + for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++) { |
---|
| 604 | + if (!(i % 4)) |
---|
| 605 | + id_word = readq(mem + i * 2); |
---|
| 606 | + |
---|
| 607 | + id = (u16)id_word; |
---|
| 608 | + id_word >>= 16; |
---|
| 609 | + |
---|
| 610 | + if (id < ARRAY_SIZE(nfp_tlv_stat_names) && |
---|
| 611 | + nfp_tlv_stat_names[id][0]) { |
---|
| 612 | + memcpy(data, nfp_tlv_stat_names[id], ETH_GSTRING_LEN); |
---|
| 613 | + data += ETH_GSTRING_LEN; |
---|
| 614 | + } else { |
---|
| 615 | + data = nfp_pr_et(data, "dev_unknown_stat%u", id); |
---|
| 616 | + } |
---|
| 617 | + } |
---|
| 618 | + |
---|
| 619 | + for (i = 0; i < nn->max_r_vecs; i++) { |
---|
| 620 | + data = nfp_pr_et(data, "rxq_%u_pkts", i); |
---|
| 621 | + data = nfp_pr_et(data, "rxq_%u_bytes", i); |
---|
| 622 | + data = nfp_pr_et(data, "txq_%u_pkts", i); |
---|
| 623 | + data = nfp_pr_et(data, "txq_%u_bytes", i); |
---|
| 624 | + } |
---|
| 625 | + |
---|
| 626 | + return data; |
---|
| 627 | +} |
---|
| 628 | + |
---|
| 629 | +static u64 *nfp_vnic_get_tlv_stats(struct nfp_net *nn, u64 *data) |
---|
| 630 | +{ |
---|
| 631 | + u8 __iomem *mem; |
---|
| 632 | + unsigned int i; |
---|
| 633 | + |
---|
| 634 | + mem = nn->dp.ctrl_bar + nn->tlv_caps.vnic_stats_off; |
---|
| 635 | + mem += roundup(2 * nn->tlv_caps.vnic_stats_cnt, 8); |
---|
| 636 | + for (i = 0; i < nn->tlv_caps.vnic_stats_cnt; i++) |
---|
| 637 | + *data++ = readq(mem + i * 8); |
---|
| 638 | + |
---|
| 639 | + mem = nn->dp.ctrl_bar; |
---|
| 640 | + for (i = 0; i < nn->max_r_vecs; i++) { |
---|
| 641 | + *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i)); |
---|
| 642 | + *data++ = readq(mem + NFP_NET_CFG_RXR_STATS(i) + 8); |
---|
| 643 | + *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i)); |
---|
| 644 | + *data++ = readq(mem + NFP_NET_CFG_TXR_STATS(i) + 8); |
---|
| 645 | + } |
---|
| 646 | + |
---|
| 647 | + return data; |
---|
| 648 | +} |
---|
| 649 | + |
---|
578 | 650 | static unsigned int nfp_mac_get_stats_count(struct net_device *netdev) |
---|
579 | 651 | { |
---|
580 | 652 | struct nfp_port *port; |
---|
.. | .. |
---|
624 | 696 | switch (stringset) { |
---|
625 | 697 | case ETH_SS_STATS: |
---|
626 | 698 | data = nfp_vnic_get_sw_stats_strings(netdev, data); |
---|
627 | | - data = nfp_vnic_get_hw_stats_strings(data, nn->max_r_vecs, |
---|
628 | | - false); |
---|
| 699 | + if (!nn->tlv_caps.vnic_stats_off) |
---|
| 700 | + data = nfp_vnic_get_hw_stats_strings(data, |
---|
| 701 | + nn->max_r_vecs, |
---|
| 702 | + false); |
---|
| 703 | + else |
---|
| 704 | + data = nfp_vnic_get_tlv_stats_strings(nn, data); |
---|
629 | 705 | data = nfp_mac_get_stats_strings(netdev, data); |
---|
630 | 706 | data = nfp_app_port_get_stats_strings(nn->port, data); |
---|
631 | 707 | break; |
---|
.. | .. |
---|
639 | 715 | struct nfp_net *nn = netdev_priv(netdev); |
---|
640 | 716 | |
---|
641 | 717 | data = nfp_vnic_get_sw_stats(netdev, data); |
---|
642 | | - data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar, nn->max_r_vecs); |
---|
| 718 | + if (!nn->tlv_caps.vnic_stats_off) |
---|
| 719 | + data = nfp_vnic_get_hw_stats(data, nn->dp.ctrl_bar, |
---|
| 720 | + nn->max_r_vecs); |
---|
| 721 | + else |
---|
| 722 | + data = nfp_vnic_get_tlv_stats(nn, data); |
---|
643 | 723 | data = nfp_mac_get_stats(netdev, data); |
---|
644 | 724 | data = nfp_app_port_get_stats(nn->port, data); |
---|
645 | 725 | } |
---|
.. | .. |
---|
647 | 727 | static int nfp_net_get_sset_count(struct net_device *netdev, int sset) |
---|
648 | 728 | { |
---|
649 | 729 | struct nfp_net *nn = netdev_priv(netdev); |
---|
| 730 | + unsigned int cnt; |
---|
650 | 731 | |
---|
651 | 732 | switch (sset) { |
---|
652 | 733 | case ETH_SS_STATS: |
---|
653 | | - return nfp_vnic_get_sw_stats_count(netdev) + |
---|
654 | | - nfp_vnic_get_hw_stats_count(nn->max_r_vecs) + |
---|
655 | | - nfp_mac_get_stats_count(netdev) + |
---|
656 | | - nfp_app_port_get_stats_count(nn->port); |
---|
| 734 | + cnt = nfp_vnic_get_sw_stats_count(netdev); |
---|
| 735 | + if (!nn->tlv_caps.vnic_stats_off) |
---|
| 736 | + cnt += nfp_vnic_get_hw_stats_count(nn->max_r_vecs); |
---|
| 737 | + else |
---|
| 738 | + cnt += nfp_vnic_get_tlv_stats_count(nn); |
---|
| 739 | + cnt += nfp_mac_get_stats_count(netdev); |
---|
| 740 | + cnt += nfp_app_port_get_stats_count(nn->port); |
---|
| 741 | + return cnt; |
---|
657 | 742 | default: |
---|
658 | 743 | return -EOPNOTSUPP; |
---|
659 | 744 | } |
---|
.. | .. |
---|
1128 | 1213 | buffer); |
---|
1129 | 1214 | } |
---|
1130 | 1215 | |
---|
| 1216 | +static int |
---|
| 1217 | +nfp_port_get_module_info(struct net_device *netdev, |
---|
| 1218 | + struct ethtool_modinfo *modinfo) |
---|
| 1219 | +{ |
---|
| 1220 | + struct nfp_eth_table_port *eth_port; |
---|
| 1221 | + struct nfp_port *port; |
---|
| 1222 | + unsigned int read_len; |
---|
| 1223 | + struct nfp_nsp *nsp; |
---|
| 1224 | + int err = 0; |
---|
| 1225 | + u8 data; |
---|
| 1226 | + |
---|
| 1227 | + port = nfp_port_from_netdev(netdev); |
---|
| 1228 | + if (!port) |
---|
| 1229 | + return -EOPNOTSUPP; |
---|
| 1230 | + |
---|
| 1231 | + /* update port state to get latest interface */ |
---|
| 1232 | + set_bit(NFP_PORT_CHANGED, &port->flags); |
---|
| 1233 | + eth_port = nfp_port_get_eth_port(port); |
---|
| 1234 | + if (!eth_port) |
---|
| 1235 | + return -EOPNOTSUPP; |
---|
| 1236 | + |
---|
| 1237 | + nsp = nfp_nsp_open(port->app->cpp); |
---|
| 1238 | + if (IS_ERR(nsp)) { |
---|
| 1239 | + err = PTR_ERR(nsp); |
---|
| 1240 | + netdev_err(netdev, "Failed to access the NSP: %d\n", err); |
---|
| 1241 | + return err; |
---|
| 1242 | + } |
---|
| 1243 | + |
---|
| 1244 | + if (!nfp_nsp_has_read_module_eeprom(nsp)) { |
---|
| 1245 | + netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n"); |
---|
| 1246 | + err = -EOPNOTSUPP; |
---|
| 1247 | + goto exit_close_nsp; |
---|
| 1248 | + } |
---|
| 1249 | + |
---|
| 1250 | + switch (eth_port->interface) { |
---|
| 1251 | + case NFP_INTERFACE_SFP: |
---|
| 1252 | + case NFP_INTERFACE_SFP28: |
---|
| 1253 | + err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, |
---|
| 1254 | + SFP_SFF8472_COMPLIANCE, &data, |
---|
| 1255 | + 1, &read_len); |
---|
| 1256 | + if (err < 0) |
---|
| 1257 | + goto exit_close_nsp; |
---|
| 1258 | + |
---|
| 1259 | + if (!data) { |
---|
| 1260 | + modinfo->type = ETH_MODULE_SFF_8079; |
---|
| 1261 | + modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; |
---|
| 1262 | + } else { |
---|
| 1263 | + modinfo->type = ETH_MODULE_SFF_8472; |
---|
| 1264 | + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; |
---|
| 1265 | + } |
---|
| 1266 | + break; |
---|
| 1267 | + case NFP_INTERFACE_QSFP: |
---|
| 1268 | + err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, |
---|
| 1269 | + SFP_SFF_REV_COMPLIANCE, &data, |
---|
| 1270 | + 1, &read_len); |
---|
| 1271 | + if (err < 0) |
---|
| 1272 | + goto exit_close_nsp; |
---|
| 1273 | + |
---|
| 1274 | + if (data < 0x3) { |
---|
| 1275 | + modinfo->type = ETH_MODULE_SFF_8436; |
---|
| 1276 | + modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN; |
---|
| 1277 | + } else { |
---|
| 1278 | + modinfo->type = ETH_MODULE_SFF_8636; |
---|
| 1279 | + modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; |
---|
| 1280 | + } |
---|
| 1281 | + break; |
---|
| 1282 | + case NFP_INTERFACE_QSFP28: |
---|
| 1283 | + modinfo->type = ETH_MODULE_SFF_8636; |
---|
| 1284 | + modinfo->eeprom_len = ETH_MODULE_SFF_8636_LEN; |
---|
| 1285 | + break; |
---|
| 1286 | + default: |
---|
| 1287 | + netdev_err(netdev, "Unsupported module 0x%x detected\n", |
---|
| 1288 | + eth_port->interface); |
---|
| 1289 | + err = -EINVAL; |
---|
| 1290 | + } |
---|
| 1291 | + |
---|
| 1292 | +exit_close_nsp: |
---|
| 1293 | + nfp_nsp_close(nsp); |
---|
| 1294 | + return err; |
---|
| 1295 | +} |
---|
| 1296 | + |
---|
| 1297 | +static int |
---|
| 1298 | +nfp_port_get_module_eeprom(struct net_device *netdev, |
---|
| 1299 | + struct ethtool_eeprom *eeprom, u8 *data) |
---|
| 1300 | +{ |
---|
| 1301 | + struct nfp_eth_table_port *eth_port; |
---|
| 1302 | + struct nfp_port *port; |
---|
| 1303 | + struct nfp_nsp *nsp; |
---|
| 1304 | + int err; |
---|
| 1305 | + |
---|
| 1306 | + port = nfp_port_from_netdev(netdev); |
---|
| 1307 | + eth_port = __nfp_port_get_eth_port(port); |
---|
| 1308 | + if (!eth_port) |
---|
| 1309 | + return -EOPNOTSUPP; |
---|
| 1310 | + |
---|
| 1311 | + nsp = nfp_nsp_open(port->app->cpp); |
---|
| 1312 | + if (IS_ERR(nsp)) { |
---|
| 1313 | + err = PTR_ERR(nsp); |
---|
| 1314 | + netdev_err(netdev, "Failed to access the NSP: %d\n", err); |
---|
| 1315 | + return err; |
---|
| 1316 | + } |
---|
| 1317 | + |
---|
| 1318 | + if (!nfp_nsp_has_read_module_eeprom(nsp)) { |
---|
| 1319 | + netdev_info(netdev, "reading module EEPROM not supported. Please update flash\n"); |
---|
| 1320 | + err = -EOPNOTSUPP; |
---|
| 1321 | + goto exit_close_nsp; |
---|
| 1322 | + } |
---|
| 1323 | + |
---|
| 1324 | + err = nfp_nsp_read_module_eeprom(nsp, eth_port->eth_index, |
---|
| 1325 | + eeprom->offset, data, eeprom->len, |
---|
| 1326 | + &eeprom->len); |
---|
| 1327 | + if (err < 0) { |
---|
| 1328 | + if (eeprom->len) { |
---|
| 1329 | + netdev_warn(netdev, |
---|
| 1330 | + "Incomplete read from module EEPROM: %d\n", |
---|
| 1331 | + err); |
---|
| 1332 | + err = 0; |
---|
| 1333 | + } else { |
---|
| 1334 | + netdev_err(netdev, |
---|
| 1335 | + "Reading from module EEPROM failed: %d\n", |
---|
| 1336 | + err); |
---|
| 1337 | + } |
---|
| 1338 | + } |
---|
| 1339 | + |
---|
| 1340 | +exit_close_nsp: |
---|
| 1341 | + nfp_nsp_close(nsp); |
---|
| 1342 | + return err; |
---|
| 1343 | +} |
---|
| 1344 | + |
---|
1131 | 1345 | static int nfp_net_set_coalesce(struct net_device *netdev, |
---|
1132 | 1346 | struct ethtool_coalesce *ec) |
---|
1133 | 1347 | { |
---|
1134 | 1348 | struct nfp_net *nn = netdev_priv(netdev); |
---|
1135 | 1349 | unsigned int factor; |
---|
1136 | 1350 | |
---|
1137 | | - if (ec->rx_coalesce_usecs_irq || |
---|
1138 | | - ec->rx_max_coalesced_frames_irq || |
---|
1139 | | - ec->tx_coalesce_usecs_irq || |
---|
1140 | | - ec->tx_max_coalesced_frames_irq || |
---|
1141 | | - ec->stats_block_coalesce_usecs || |
---|
1142 | | - ec->use_adaptive_rx_coalesce || |
---|
1143 | | - ec->use_adaptive_tx_coalesce || |
---|
1144 | | - ec->pkt_rate_low || |
---|
1145 | | - ec->rx_coalesce_usecs_low || |
---|
1146 | | - ec->rx_max_coalesced_frames_low || |
---|
1147 | | - ec->tx_coalesce_usecs_low || |
---|
1148 | | - ec->tx_max_coalesced_frames_low || |
---|
1149 | | - ec->pkt_rate_high || |
---|
1150 | | - ec->rx_coalesce_usecs_high || |
---|
1151 | | - ec->rx_max_coalesced_frames_high || |
---|
1152 | | - ec->tx_coalesce_usecs_high || |
---|
1153 | | - ec->tx_max_coalesced_frames_high || |
---|
1154 | | - ec->rate_sample_interval) |
---|
1155 | | - return -EOPNOTSUPP; |
---|
1156 | | - |
---|
1157 | 1351 | /* Compute factor used to convert coalesce '_usecs' parameters to |
---|
1158 | 1352 | * ME timestamp ticks. There are 16 ME clock cycles for each timestamp |
---|
1159 | 1353 | * count. |
---|
1160 | 1354 | */ |
---|
1161 | | - factor = nn->me_freq_mhz / 16; |
---|
| 1355 | + factor = nn->tlv_caps.me_freq_mhz / 16; |
---|
1162 | 1356 | |
---|
1163 | 1357 | /* Each pair of (usecs, max_frames) fields specifies that interrupts |
---|
1164 | 1358 | * should be coalesced until |
---|
.. | .. |
---|
1251 | 1445 | unsigned int total_rx, total_tx; |
---|
1252 | 1446 | |
---|
1253 | 1447 | /* Reject unsupported */ |
---|
1254 | | - if (!channel->combined_count || |
---|
1255 | | - channel->other_count != NFP_NET_NON_Q_VECTORS || |
---|
| 1448 | + if (channel->other_count != NFP_NET_NON_Q_VECTORS || |
---|
1256 | 1449 | (channel->rx_count && channel->tx_count)) |
---|
1257 | 1450 | return -EINVAL; |
---|
1258 | 1451 | |
---|
.. | .. |
---|
1266 | 1459 | return nfp_net_set_num_rings(nn, total_rx, total_tx); |
---|
1267 | 1460 | } |
---|
1268 | 1461 | |
---|
1269 | | -static int |
---|
1270 | | -nfp_net_flash_device(struct net_device *netdev, struct ethtool_flash *flash) |
---|
1271 | | -{ |
---|
1272 | | - const struct firmware *fw; |
---|
1273 | | - struct nfp_app *app; |
---|
1274 | | - struct nfp_nsp *nsp; |
---|
1275 | | - struct device *dev; |
---|
1276 | | - int err; |
---|
1277 | | - |
---|
1278 | | - if (flash->region != ETHTOOL_FLASH_ALL_REGIONS) |
---|
1279 | | - return -EOPNOTSUPP; |
---|
1280 | | - |
---|
1281 | | - app = nfp_app_from_netdev(netdev); |
---|
1282 | | - if (!app) |
---|
1283 | | - return -EOPNOTSUPP; |
---|
1284 | | - |
---|
1285 | | - dev = &app->pdev->dev; |
---|
1286 | | - |
---|
1287 | | - nsp = nfp_nsp_open(app->cpp); |
---|
1288 | | - if (IS_ERR(nsp)) { |
---|
1289 | | - err = PTR_ERR(nsp); |
---|
1290 | | - dev_err(dev, "Failed to access the NSP: %d\n", err); |
---|
1291 | | - return err; |
---|
1292 | | - } |
---|
1293 | | - |
---|
1294 | | - err = request_firmware_direct(&fw, flash->data, dev); |
---|
1295 | | - if (err) |
---|
1296 | | - goto exit_close_nsp; |
---|
1297 | | - |
---|
1298 | | - dev_info(dev, "Please be patient while writing flash image: %s\n", |
---|
1299 | | - flash->data); |
---|
1300 | | - dev_hold(netdev); |
---|
1301 | | - rtnl_unlock(); |
---|
1302 | | - |
---|
1303 | | - err = nfp_nsp_write_flash(nsp, fw); |
---|
1304 | | - if (err < 0) { |
---|
1305 | | - dev_err(dev, "Flash write failed: %d\n", err); |
---|
1306 | | - goto exit_rtnl_lock; |
---|
1307 | | - } |
---|
1308 | | - dev_info(dev, "Finished writing flash image\n"); |
---|
1309 | | - |
---|
1310 | | -exit_rtnl_lock: |
---|
1311 | | - rtnl_lock(); |
---|
1312 | | - dev_put(netdev); |
---|
1313 | | - release_firmware(fw); |
---|
1314 | | - |
---|
1315 | | -exit_close_nsp: |
---|
1316 | | - nfp_nsp_close(nsp); |
---|
1317 | | - return err; |
---|
1318 | | -} |
---|
1319 | | - |
---|
1320 | 1462 | static const struct ethtool_ops nfp_net_ethtool_ops = { |
---|
| 1463 | + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | |
---|
| 1464 | + ETHTOOL_COALESCE_MAX_FRAMES, |
---|
1321 | 1465 | .get_drvinfo = nfp_net_get_drvinfo, |
---|
1322 | 1466 | .get_link = ethtool_op_get_link, |
---|
1323 | 1467 | .get_ringparam = nfp_net_get_ringparam, |
---|
.. | .. |
---|
1327 | 1471 | .get_sset_count = nfp_net_get_sset_count, |
---|
1328 | 1472 | .get_rxnfc = nfp_net_get_rxnfc, |
---|
1329 | 1473 | .set_rxnfc = nfp_net_set_rxnfc, |
---|
1330 | | - .flash_device = nfp_net_flash_device, |
---|
1331 | 1474 | .get_rxfh_indir_size = nfp_net_get_rxfh_indir_size, |
---|
1332 | 1475 | .get_rxfh_key_size = nfp_net_get_rxfh_key_size, |
---|
1333 | 1476 | .get_rxfh = nfp_net_get_rxfh, |
---|
.. | .. |
---|
1337 | 1480 | .set_dump = nfp_app_set_dump, |
---|
1338 | 1481 | .get_dump_flag = nfp_app_get_dump_flag, |
---|
1339 | 1482 | .get_dump_data = nfp_app_get_dump_data, |
---|
| 1483 | + .get_module_info = nfp_port_get_module_info, |
---|
| 1484 | + .get_module_eeprom = nfp_port_get_module_eeprom, |
---|
1340 | 1485 | .get_coalesce = nfp_net_get_coalesce, |
---|
1341 | 1486 | .set_coalesce = nfp_net_set_coalesce, |
---|
1342 | 1487 | .get_channels = nfp_net_get_channels, |
---|
.. | .. |
---|
1353 | 1498 | .get_strings = nfp_port_get_strings, |
---|
1354 | 1499 | .get_ethtool_stats = nfp_port_get_stats, |
---|
1355 | 1500 | .get_sset_count = nfp_port_get_sset_count, |
---|
1356 | | - .flash_device = nfp_net_flash_device, |
---|
1357 | 1501 | .set_dump = nfp_app_set_dump, |
---|
1358 | 1502 | .get_dump_flag = nfp_app_get_dump_flag, |
---|
1359 | 1503 | .get_dump_data = nfp_app_get_dump_data, |
---|
| 1504 | + .get_module_info = nfp_port_get_module_info, |
---|
| 1505 | + .get_module_eeprom = nfp_port_get_module_eeprom, |
---|
1360 | 1506 | .get_link_ksettings = nfp_net_get_link_ksettings, |
---|
1361 | 1507 | .set_link_ksettings = nfp_net_set_link_ksettings, |
---|
1362 | 1508 | .get_fecparam = nfp_port_get_fecparam, |
---|