0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/phy.h>
0009
0010 #include "mlxbf_gige.h"
0011 #include "mlxbf_gige_regs.h"
0012
0013
0014 static int mlxbf_gige_get_regs_len(struct net_device *netdev)
0015 {
0016 return MLXBF_GIGE_MMIO_REG_SZ;
0017 }
0018
0019 static void mlxbf_gige_get_regs(struct net_device *netdev,
0020 struct ethtool_regs *regs, void *p)
0021 {
0022 struct mlxbf_gige *priv = netdev_priv(netdev);
0023
0024 regs->version = MLXBF_GIGE_REGS_VERSION;
0025
0026
0027
0028
0029
0030
0031 memcpy_fromio(p, priv->base, MLXBF_GIGE_MMIO_REG_SZ);
0032 }
0033
0034 static void
0035 mlxbf_gige_get_ringparam(struct net_device *netdev,
0036 struct ethtool_ringparam *ering,
0037 struct kernel_ethtool_ringparam *kernel_ering,
0038 struct netlink_ext_ack *extack)
0039 {
0040 struct mlxbf_gige *priv = netdev_priv(netdev);
0041
0042 ering->rx_max_pending = MLXBF_GIGE_MAX_RXQ_SZ;
0043 ering->tx_max_pending = MLXBF_GIGE_MAX_TXQ_SZ;
0044 ering->rx_pending = priv->rx_q_entries;
0045 ering->tx_pending = priv->tx_q_entries;
0046 }
0047
0048 static const struct {
0049 const char string[ETH_GSTRING_LEN];
0050 } mlxbf_gige_ethtool_stats_keys[] = {
0051 { "hw_access_errors" },
0052 { "tx_invalid_checksums" },
0053 { "tx_small_frames" },
0054 { "tx_index_errors" },
0055 { "sw_config_errors" },
0056 { "sw_access_errors" },
0057 { "rx_truncate_errors" },
0058 { "rx_mac_errors" },
0059 { "rx_din_dropped_pkts" },
0060 { "tx_fifo_full" },
0061 { "rx_filter_passed_pkts" },
0062 { "rx_filter_discard_pkts" },
0063 };
0064
0065 static int mlxbf_gige_get_sset_count(struct net_device *netdev, int stringset)
0066 {
0067 if (stringset != ETH_SS_STATS)
0068 return -EOPNOTSUPP;
0069 return ARRAY_SIZE(mlxbf_gige_ethtool_stats_keys);
0070 }
0071
0072 static void mlxbf_gige_get_strings(struct net_device *netdev, u32 stringset,
0073 u8 *buf)
0074 {
0075 if (stringset != ETH_SS_STATS)
0076 return;
0077 memcpy(buf, &mlxbf_gige_ethtool_stats_keys,
0078 sizeof(mlxbf_gige_ethtool_stats_keys));
0079 }
0080
0081 static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
0082 struct ethtool_stats *estats,
0083 u64 *data)
0084 {
0085 struct mlxbf_gige *priv = netdev_priv(netdev);
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 *data++ = priv->stats.hw_access_errors;
0103 *data++ = priv->stats.tx_invalid_checksums;
0104 *data++ = priv->stats.tx_small_frames;
0105 *data++ = priv->stats.tx_index_errors;
0106 *data++ = priv->stats.sw_config_errors;
0107 *data++ = priv->stats.sw_access_errors;
0108 *data++ = priv->stats.rx_truncate_errors;
0109 *data++ = priv->stats.rx_mac_errors;
0110 *data++ = (priv->stats.rx_din_dropped_pkts +
0111 readq(priv->base + MLXBF_GIGE_RX_DIN_DROP_COUNTER));
0112 *data++ = priv->stats.tx_fifo_full;
0113 *data++ = (priv->stats.rx_filter_passed_pkts +
0114 readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL));
0115 *data++ = (priv->stats.rx_filter_discard_pkts +
0116 readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL));
0117 }
0118
0119 static void mlxbf_gige_get_pauseparam(struct net_device *netdev,
0120 struct ethtool_pauseparam *pause)
0121 {
0122 pause->autoneg = AUTONEG_DISABLE;
0123 pause->rx_pause = 1;
0124 pause->tx_pause = 1;
0125 }
0126
0127 const struct ethtool_ops mlxbf_gige_ethtool_ops = {
0128 .get_link = ethtool_op_get_link,
0129 .get_ringparam = mlxbf_gige_get_ringparam,
0130 .get_regs_len = mlxbf_gige_get_regs_len,
0131 .get_regs = mlxbf_gige_get_regs,
0132 .get_strings = mlxbf_gige_get_strings,
0133 .get_sset_count = mlxbf_gige_get_sset_count,
0134 .get_ethtool_stats = mlxbf_gige_get_ethtool_stats,
0135 .nway_reset = phy_ethtool_nway_reset,
0136 .get_pauseparam = mlxbf_gige_get_pauseparam,
0137 .get_link_ksettings = phy_ethtool_get_link_ksettings,
0138 };