Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
  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
 10static void
 11nsim_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.pauseparam.report_stats_rx)
 17		pause_stats->rx_pause_frames = 1;
 18	if (ns->ethtool.pauseparam.report_stats_tx)
 19		pause_stats->tx_pause_frames = 2;
 20}
 21
 22static void
 23nsim_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.pauseparam.rx;
 29	pause->tx_pause = ns->ethtool.pauseparam.tx;
 30}
 31
 32static int
 33nsim_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.pauseparam.rx = pause->rx_pause;
 41	ns->ethtool.pauseparam.tx = pause->tx_pause;
 42	return 0;
 43}
 44
 45static int nsim_get_coalesce(struct net_device *dev,
 46			     struct ethtool_coalesce *coal)
 47{
 48	struct netdevsim *ns = netdev_priv(dev);
 49
 50	memcpy(coal, &ns->ethtool.coalesce, sizeof(ns->ethtool.coalesce));
 51	return 0;
 52}
 53
 54static int nsim_set_coalesce(struct net_device *dev,
 55			     struct ethtool_coalesce *coal)
 56{
 57	struct netdevsim *ns = netdev_priv(dev);
 58
 59	memcpy(&ns->ethtool.coalesce, coal, sizeof(ns->ethtool.coalesce));
 60	return 0;
 61}
 62
 63static void nsim_get_ringparam(struct net_device *dev,
 64			       struct ethtool_ringparam *ring)
 65{
 66	struct netdevsim *ns = netdev_priv(dev);
 67
 68	memcpy(ring, &ns->ethtool.ring, sizeof(ns->ethtool.ring));
 69}
 70
 71static int nsim_set_ringparam(struct net_device *dev,
 72			      struct ethtool_ringparam *ring)
 73{
 74	struct netdevsim *ns = netdev_priv(dev);
 75
 76	memcpy(&ns->ethtool.ring, ring, sizeof(ns->ethtool.ring));
 77	return 0;
 78}
 79
 80static int
 81nsim_get_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
 82{
 83	struct netdevsim *ns = netdev_priv(dev);
 84
 85	if (ns->ethtool.get_err)
 86		return -ns->ethtool.get_err;
 87	memcpy(fecparam, &ns->ethtool.fec, sizeof(ns->ethtool.fec));
 88	return 0;
 89}
 90
 91static int
 92nsim_set_fecparam(struct net_device *dev, struct ethtool_fecparam *fecparam)
 93{
 94	struct netdevsim *ns = netdev_priv(dev);
 95	u32 fec;
 96
 97	if (ns->ethtool.set_err)
 98		return -ns->ethtool.set_err;
 99	memcpy(&ns->ethtool.fec, fecparam, sizeof(ns->ethtool.fec));
100	fec = fecparam->fec;
101	if (fec == ETHTOOL_FEC_AUTO)
102		fec |= ETHTOOL_FEC_OFF;
103	fec |= ETHTOOL_FEC_NONE;
104	ns->ethtool.fec.active_fec = 1 << (fls(fec) - 1);
105	return 0;
106}
107
108static const struct ethtool_ops nsim_ethtool_ops = {
109	.supported_coalesce_params	= ETHTOOL_COALESCE_ALL_PARAMS,
110	.get_pause_stats	        = nsim_get_pause_stats,
111	.get_pauseparam		        = nsim_get_pauseparam,
112	.set_pauseparam		        = nsim_set_pauseparam,
113	.set_coalesce			= nsim_set_coalesce,
114	.get_coalesce			= nsim_get_coalesce,
115	.get_ringparam			= nsim_get_ringparam,
116	.set_ringparam			= nsim_set_ringparam,
117	.get_fecparam			= nsim_get_fecparam,
118	.set_fecparam			= nsim_set_fecparam,
119};
120
121static void nsim_ethtool_ring_init(struct netdevsim *ns)
122{
123	ns->ethtool.ring.rx_max_pending = 4096;
124	ns->ethtool.ring.rx_jumbo_max_pending = 4096;
125	ns->ethtool.ring.rx_mini_max_pending = 4096;
126	ns->ethtool.ring.tx_max_pending = 4096;
127}
128
129void nsim_ethtool_init(struct netdevsim *ns)
130{
131	struct dentry *ethtool, *dir;
132
133	ns->netdev->ethtool_ops = &nsim_ethtool_ops;
134
135	nsim_ethtool_ring_init(ns);
136
137	ns->ethtool.fec.fec = ETHTOOL_FEC_NONE;
138	ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;
139
140	ethtool = debugfs_create_dir("ethtool", ns->nsim_dev_port->ddir);
141
142	debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
143	debugfs_create_u32("set_err", 0600, ethtool, &ns->ethtool.set_err);
144
145	dir = debugfs_create_dir("pause", ethtool);
146	debugfs_create_bool("report_stats_rx", 0600, dir,
147			    &ns->ethtool.pauseparam.report_stats_rx);
148	debugfs_create_bool("report_stats_tx", 0600, dir,
149			    &ns->ethtool.pauseparam.report_stats_tx);
150
151	dir = debugfs_create_dir("ring", ethtool);
152	debugfs_create_u32("rx_max_pending", 0600, dir,
153			   &ns->ethtool.ring.rx_max_pending);
154	debugfs_create_u32("rx_jumbo_max_pending", 0600, dir,
155			   &ns->ethtool.ring.rx_jumbo_max_pending);
156	debugfs_create_u32("rx_mini_max_pending", 0600, dir,
157			   &ns->ethtool.ring.rx_mini_max_pending);
158	debugfs_create_u32("tx_max_pending", 0600, dir,
159			   &ns->ethtool.ring.tx_max_pending);
160}