Commit ff1f7c17 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

netdevsim: add pause frame stats



Add minimal ethtool interface for testing ethtool pause stats.

v2: add missing static on nsim_ethtool_ops

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8c00bd93
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
obj-$(CONFIG_NETDEVSIM) += netdevsim.o

netdevsim-objs := \
	netdev.o dev.o fib.o bus.o health.o udp_tunnels.o
	netdev.o dev.o ethtool.o fib.o bus.o health.o udp_tunnels.o

ifeq ($(CONFIG_BPF_SYSCALL),y)
netdevsim-objs += \
+64 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2020 Facebook

#include <linux/debugfs.h>
#include <linux/ethtool.h>
#include <linux/random.h>

#include "netdevsim.h"

static void
nsim_get_pause_stats(struct net_device *dev,
		     struct ethtool_pause_stats *pause_stats)
{
	struct netdevsim *ns = netdev_priv(dev);

	if (ns->ethtool.report_stats_rx)
		pause_stats->rx_pause_frames = 1;
	if (ns->ethtool.report_stats_tx)
		pause_stats->tx_pause_frames = 2;
}

static void
nsim_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
{
	struct netdevsim *ns = netdev_priv(dev);

	pause->autoneg = 0; /* We don't support ksettings, so can't pretend */
	pause->rx_pause = ns->ethtool.rx;
	pause->tx_pause = ns->ethtool.tx;
}

static int
nsim_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause)
{
	struct netdevsim *ns = netdev_priv(dev);

	if (pause->autoneg)
		return -EINVAL;

	ns->ethtool.rx = pause->rx_pause;
	ns->ethtool.tx = pause->tx_pause;
	return 0;
}

static const struct ethtool_ops nsim_ethtool_ops = {
	.get_pause_stats	= nsim_get_pause_stats,
	.get_pauseparam		= nsim_get_pauseparam,
	.set_pauseparam		= nsim_set_pauseparam,
};

void nsim_ethtool_init(struct netdevsim *ns)
{
	struct dentry *ethtool, *dir;

	ns->netdev->ethtool_ops = &nsim_ethtool_ops;

	ethtool = debugfs_create_dir("ethtool", ns->nsim_dev->ddir);

	dir = debugfs_create_dir("pause", ethtool);
	debugfs_create_bool("report_stats_rx", 0600, dir,
			    &ns->ethtool.report_stats_rx);
	debugfs_create_bool("report_stats_tx", 0600, dir,
			    &ns->ethtool.report_stats_tx);
}
+1 −0
Original line number Diff line number Diff line
@@ -301,6 +301,7 @@ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
	ns->nsim_bus_dev = nsim_dev->nsim_bus_dev;
	SET_NETDEV_DEV(dev, &ns->nsim_bus_dev->dev);
	dev->netdev_ops = &nsim_netdev_ops;
	nsim_ethtool_init(ns);

	err = nsim_udp_tunnels_info_create(nsim_dev, dev);
	if (err)
+11 −0
Original line number Diff line number Diff line
@@ -50,6 +50,13 @@ struct nsim_ipsec {
	u32 ok;
};

struct nsim_ethtool {
	bool rx;
	bool tx;
	bool report_stats_rx;
	bool report_stats_tx;
};

struct netdevsim {
	struct net_device *netdev;
	struct nsim_dev *nsim_dev;
@@ -80,12 +87,16 @@ struct netdevsim {
		u32 ports[2][NSIM_UDP_TUNNEL_N_PORTS];
		struct debugfs_u32_array dfs_ports[2];
	} udp_ports;

	struct nsim_ethtool ethtool;
};

struct netdevsim *
nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port);
void nsim_destroy(struct netdevsim *ns);

void nsim_ethtool_init(struct netdevsim *ns);

void nsim_udp_tunnels_debugfs_create(struct nsim_dev *nsim_dev);
int nsim_udp_tunnels_info_create(struct nsim_dev *nsim_dev,
				 struct net_device *dev);