Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
David Thompson | 536 | 100.00% | 1 | 100.00% |
Total | 536 | 1 |
// SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause /* Ethtool support for Mellanox Gigabit Ethernet driver * * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES */ #include <linux/phy.h> #include "mlxbf_gige.h" #include "mlxbf_gige_regs.h" /* Start of struct ethtool_ops functions */ static int mlxbf_gige_get_regs_len(struct net_device *netdev) { return MLXBF_GIGE_MMIO_REG_SZ; } static void mlxbf_gige_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct mlxbf_gige *priv = netdev_priv(netdev); regs->version = MLXBF_GIGE_REGS_VERSION; /* Read entire MMIO register space and store results * into the provided buffer. Each 64-bit word is converted * to big-endian to make the output more readable. * * NOTE: by design, a read to an offset without an existing * register will be acknowledged and return zero. */ memcpy_fromio(p, priv->base, MLXBF_GIGE_MMIO_REG_SZ); } static void mlxbf_gige_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ering) { struct mlxbf_gige *priv = netdev_priv(netdev); ering->rx_max_pending = MLXBF_GIGE_MAX_RXQ_SZ; ering->tx_max_pending = MLXBF_GIGE_MAX_TXQ_SZ; ering->rx_pending = priv->rx_q_entries; ering->tx_pending = priv->tx_q_entries; } static const struct { const char string[ETH_GSTRING_LEN]; } mlxbf_gige_ethtool_stats_keys[] = { { "hw_access_errors" }, { "tx_invalid_checksums" }, { "tx_small_frames" }, { "tx_index_errors" }, { "sw_config_errors" }, { "sw_access_errors" }, { "rx_truncate_errors" }, { "rx_mac_errors" }, { "rx_din_dropped_pkts" }, { "tx_fifo_full" }, { "rx_filter_passed_pkts" }, { "rx_filter_discard_pkts" }, }; static int mlxbf_gige_get_sset_count(struct net_device *netdev, int stringset) { if (stringset != ETH_SS_STATS) return -EOPNOTSUPP; return ARRAY_SIZE(mlxbf_gige_ethtool_stats_keys); } static void mlxbf_gige_get_strings(struct net_device *netdev, u32 stringset, u8 *buf) { if (stringset != ETH_SS_STATS) return; memcpy(buf, &mlxbf_gige_ethtool_stats_keys, sizeof(mlxbf_gige_ethtool_stats_keys)); } static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *estats, u64 *data) { struct mlxbf_gige *priv = netdev_priv(netdev); /* Fill data array with interface statistics * * NOTE: the data writes must be in * sync with the strings shown in * the mlxbf_gige_ethtool_stats_keys[] array * * NOTE2: certain statistics below are zeroed upon * port disable, so the calculation below * must include the "cached" value of the stat * plus the value read directly from hardware. * Cached statistics are currently: * rx_din_dropped_pkts * rx_filter_passed_pkts * rx_filter_discard_pkts */ *data++ = priv->stats.hw_access_errors; *data++ = priv->stats.tx_invalid_checksums; *data++ = priv->stats.tx_small_frames; *data++ = priv->stats.tx_index_errors; *data++ = priv->stats.sw_config_errors; *data++ = priv->stats.sw_access_errors; *data++ = priv->stats.rx_truncate_errors; *data++ = priv->stats.rx_mac_errors; *data++ = (priv->stats.rx_din_dropped_pkts + readq(priv->base + MLXBF_GIGE_RX_DIN_DROP_COUNTER)); *data++ = priv->stats.tx_fifo_full; *data++ = (priv->stats.rx_filter_passed_pkts + readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL)); *data++ = (priv->stats.rx_filter_discard_pkts + readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL)); } static void mlxbf_gige_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { pause->autoneg = AUTONEG_DISABLE; pause->rx_pause = 1; pause->tx_pause = 1; } const struct ethtool_ops mlxbf_gige_ethtool_ops = { .get_link = ethtool_op_get_link, .get_ringparam = mlxbf_gige_get_ringparam, .get_regs_len = mlxbf_gige_get_regs_len, .get_regs = mlxbf_gige_get_regs, .get_strings = mlxbf_gige_get_strings, .get_sset_count = mlxbf_gige_get_sset_count, .get_ethtool_stats = mlxbf_gige_get_ethtool_stats, .nway_reset = phy_ethtool_nway_reset, .get_pauseparam = mlxbf_gige_get_pauseparam, .get_link_ksettings = phy_ethtool_get_link_ksettings, };
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1