cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mlxbf_gige_ethtool.c (4241B)


      1// SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
      2
      3/* Ethtool support for Mellanox Gigabit Ethernet driver
      4 *
      5 * Copyright (C) 2020-2021 NVIDIA CORPORATION & AFFILIATES
      6 */
      7
      8#include <linux/phy.h>
      9
     10#include "mlxbf_gige.h"
     11#include "mlxbf_gige_regs.h"
     12
     13/* Start of struct ethtool_ops functions */
     14static int mlxbf_gige_get_regs_len(struct net_device *netdev)
     15{
     16	return MLXBF_GIGE_MMIO_REG_SZ;
     17}
     18
     19static void mlxbf_gige_get_regs(struct net_device *netdev,
     20				struct ethtool_regs *regs, void *p)
     21{
     22	struct mlxbf_gige *priv = netdev_priv(netdev);
     23
     24	regs->version = MLXBF_GIGE_REGS_VERSION;
     25
     26	/* Read entire MMIO register space and store results
     27	 * into the provided buffer. By design, a read to an
     28	 * offset without an existing register will be
     29	 * acknowledged and return zero.
     30	 */
     31	memcpy_fromio(p, priv->base, MLXBF_GIGE_MMIO_REG_SZ);
     32}
     33
     34static void
     35mlxbf_gige_get_ringparam(struct net_device *netdev,
     36			 struct ethtool_ringparam *ering,
     37			 struct kernel_ethtool_ringparam *kernel_ering,
     38			 struct netlink_ext_ack *extack)
     39{
     40	struct mlxbf_gige *priv = netdev_priv(netdev);
     41
     42	ering->rx_max_pending = MLXBF_GIGE_MAX_RXQ_SZ;
     43	ering->tx_max_pending = MLXBF_GIGE_MAX_TXQ_SZ;
     44	ering->rx_pending = priv->rx_q_entries;
     45	ering->tx_pending = priv->tx_q_entries;
     46}
     47
     48static const struct {
     49	const char string[ETH_GSTRING_LEN];
     50} mlxbf_gige_ethtool_stats_keys[] = {
     51	{ "hw_access_errors" },
     52	{ "tx_invalid_checksums" },
     53	{ "tx_small_frames" },
     54	{ "tx_index_errors" },
     55	{ "sw_config_errors" },
     56	{ "sw_access_errors" },
     57	{ "rx_truncate_errors" },
     58	{ "rx_mac_errors" },
     59	{ "rx_din_dropped_pkts" },
     60	{ "tx_fifo_full" },
     61	{ "rx_filter_passed_pkts" },
     62	{ "rx_filter_discard_pkts" },
     63};
     64
     65static int mlxbf_gige_get_sset_count(struct net_device *netdev, int stringset)
     66{
     67	if (stringset != ETH_SS_STATS)
     68		return -EOPNOTSUPP;
     69	return ARRAY_SIZE(mlxbf_gige_ethtool_stats_keys);
     70}
     71
     72static void mlxbf_gige_get_strings(struct net_device *netdev, u32 stringset,
     73				   u8 *buf)
     74{
     75	if (stringset != ETH_SS_STATS)
     76		return;
     77	memcpy(buf, &mlxbf_gige_ethtool_stats_keys,
     78	       sizeof(mlxbf_gige_ethtool_stats_keys));
     79}
     80
     81static void mlxbf_gige_get_ethtool_stats(struct net_device *netdev,
     82					 struct ethtool_stats *estats,
     83					 u64 *data)
     84{
     85	struct mlxbf_gige *priv = netdev_priv(netdev);
     86
     87	/* Fill data array with interface statistics
     88	 *
     89	 * NOTE: the data writes must be in
     90	 *       sync with the strings shown in
     91	 *       the mlxbf_gige_ethtool_stats_keys[] array
     92	 *
     93	 * NOTE2: certain statistics below are zeroed upon
     94	 *        port disable, so the calculation below
     95	 *        must include the "cached" value of the stat
     96	 *        plus the value read directly from hardware.
     97	 *        Cached statistics are currently:
     98	 *          rx_din_dropped_pkts
     99	 *          rx_filter_passed_pkts
    100	 *          rx_filter_discard_pkts
    101	 */
    102	*data++ = priv->stats.hw_access_errors;
    103	*data++ = priv->stats.tx_invalid_checksums;
    104	*data++ = priv->stats.tx_small_frames;
    105	*data++ = priv->stats.tx_index_errors;
    106	*data++ = priv->stats.sw_config_errors;
    107	*data++ = priv->stats.sw_access_errors;
    108	*data++ = priv->stats.rx_truncate_errors;
    109	*data++ = priv->stats.rx_mac_errors;
    110	*data++ = (priv->stats.rx_din_dropped_pkts +
    111		   readq(priv->base + MLXBF_GIGE_RX_DIN_DROP_COUNTER));
    112	*data++ = priv->stats.tx_fifo_full;
    113	*data++ = (priv->stats.rx_filter_passed_pkts +
    114		   readq(priv->base + MLXBF_GIGE_RX_PASS_COUNTER_ALL));
    115	*data++ = (priv->stats.rx_filter_discard_pkts +
    116		   readq(priv->base + MLXBF_GIGE_RX_DISC_COUNTER_ALL));
    117}
    118
    119static void mlxbf_gige_get_pauseparam(struct net_device *netdev,
    120				      struct ethtool_pauseparam *pause)
    121{
    122	pause->autoneg = AUTONEG_DISABLE;
    123	pause->rx_pause = 1;
    124	pause->tx_pause = 1;
    125}
    126
    127const struct ethtool_ops mlxbf_gige_ethtool_ops = {
    128	.get_link		= ethtool_op_get_link,
    129	.get_ringparam		= mlxbf_gige_get_ringparam,
    130	.get_regs_len           = mlxbf_gige_get_regs_len,
    131	.get_regs               = mlxbf_gige_get_regs,
    132	.get_strings            = mlxbf_gige_get_strings,
    133	.get_sset_count         = mlxbf_gige_get_sset_count,
    134	.get_ethtool_stats      = mlxbf_gige_get_ethtool_stats,
    135	.nway_reset		= phy_ethtool_nway_reset,
    136	.get_pauseparam		= mlxbf_gige_get_pauseparam,
    137	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
    138};