1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2020 Facebook 3 4 #include <linux/debugfs.h> 5 #include <linux/ethtool.h> 6 #include <linux/random.h> 7 8 #include "netdevsim.h" 9 10 static void 11 nsim_get_pause_stats(struct net_device *dev, 12 struct ethtool_pause_stats *pause_stats) 13 { 14 struct netdevsim *ns = netdev_priv(dev); 15 16 if (ns->ethtool.report_stats_rx) 17 pause_stats->rx_pause_frames = 1; 18 if (ns->ethtool.report_stats_tx) 19 pause_stats->tx_pause_frames = 2; 20 } 21 22 static void 23 nsim_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) 24 { 25 struct netdevsim *ns = netdev_priv(dev); 26 27 pause->autoneg = 0; /* We don't support ksettings, so can't pretend */ 28 pause->rx_pause = ns->ethtool.rx; 29 pause->tx_pause = ns->ethtool.tx; 30 } 31 32 static int 33 nsim_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *pause) 34 { 35 struct netdevsim *ns = netdev_priv(dev); 36 37 if (pause->autoneg) 38 return -EINVAL; 39 40 ns->ethtool.rx = pause->rx_pause; 41 ns->ethtool.tx = pause->tx_pause; 42 return 0; 43 } 44 45 static const struct ethtool_ops nsim_ethtool_ops = { 46 .get_pause_stats = nsim_get_pause_stats, 47 .get_pauseparam = nsim_get_pauseparam, 48 .set_pauseparam = nsim_set_pauseparam, 49 }; 50 51 void nsim_ethtool_init(struct netdevsim *ns) 52 { 53 struct dentry *ethtool, *dir; 54 55 ns->netdev->ethtool_ops = &nsim_ethtool_ops; 56 57 ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir); 58 59 dir = debugfs_create_dir("pause", ethtool); 60 debugfs_create_bool("report_stats_rx", 0600, dir, 61 &ns->ethtool.report_stats_rx); 62 debugfs_create_bool("report_stats_tx", 0600, dir, 63 &ns->ethtool.report_stats_tx); 64 } 65