1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020 Facebook
4 #include <linux/debugfs.h>
5 #include <linux/ethtool.h>
6 #include <linux/random.h>
11 nsim_get_pause_stats(struct net_device
*dev
,
12 struct ethtool_pause_stats
*pause_stats
)
14 struct netdevsim
*ns
= netdev_priv(dev
);
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;
23 nsim_get_pauseparam(struct net_device
*dev
, struct ethtool_pauseparam
*pause
)
25 struct netdevsim
*ns
= netdev_priv(dev
);
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
;
33 nsim_set_pauseparam(struct net_device
*dev
, struct ethtool_pauseparam
*pause
)
35 struct netdevsim
*ns
= netdev_priv(dev
);
40 ns
->ethtool
.pauseparam
.rx
= pause
->rx_pause
;
41 ns
->ethtool
.pauseparam
.tx
= pause
->tx_pause
;
45 static int nsim_get_coalesce(struct net_device
*dev
,
46 struct ethtool_coalesce
*coal
)
48 struct netdevsim
*ns
= netdev_priv(dev
);
50 memcpy(coal
, &ns
->ethtool
.coalesce
, sizeof(ns
->ethtool
.coalesce
));
54 static int nsim_set_coalesce(struct net_device
*dev
,
55 struct ethtool_coalesce
*coal
)
57 struct netdevsim
*ns
= netdev_priv(dev
);
59 memcpy(&ns
->ethtool
.coalesce
, coal
, sizeof(ns
->ethtool
.coalesce
));
63 static void nsim_get_ringparam(struct net_device
*dev
,
64 struct ethtool_ringparam
*ring
)
66 struct netdevsim
*ns
= netdev_priv(dev
);
68 memcpy(ring
, &ns
->ethtool
.ring
, sizeof(ns
->ethtool
.ring
));
71 static int nsim_set_ringparam(struct net_device
*dev
,
72 struct ethtool_ringparam
*ring
)
74 struct netdevsim
*ns
= netdev_priv(dev
);
76 memcpy(&ns
->ethtool
.ring
, ring
, sizeof(ns
->ethtool
.ring
));
80 static const struct ethtool_ops nsim_ethtool_ops
= {
81 .supported_coalesce_params
= ETHTOOL_COALESCE_ALL_PARAMS
,
82 .get_pause_stats
= nsim_get_pause_stats
,
83 .get_pauseparam
= nsim_get_pauseparam
,
84 .set_pauseparam
= nsim_set_pauseparam
,
85 .set_coalesce
= nsim_set_coalesce
,
86 .get_coalesce
= nsim_get_coalesce
,
87 .get_ringparam
= nsim_get_ringparam
,
88 .set_ringparam
= nsim_set_ringparam
,
91 static void nsim_ethtool_ring_init(struct netdevsim
*ns
)
93 ns
->ethtool
.ring
.rx_max_pending
= 4096;
94 ns
->ethtool
.ring
.rx_jumbo_max_pending
= 4096;
95 ns
->ethtool
.ring
.rx_mini_max_pending
= 4096;
96 ns
->ethtool
.ring
.tx_max_pending
= 4096;
99 void nsim_ethtool_init(struct netdevsim
*ns
)
101 struct dentry
*ethtool
, *dir
;
103 ns
->netdev
->ethtool_ops
= &nsim_ethtool_ops
;
105 nsim_ethtool_ring_init(ns
);
107 ethtool
= debugfs_create_dir("ethtool", ns
->nsim_dev_port
->ddir
);
109 dir
= debugfs_create_dir("pause", ethtool
);
110 debugfs_create_bool("report_stats_rx", 0600, dir
,
111 &ns
->ethtool
.pauseparam
.report_stats_rx
);
112 debugfs_create_bool("report_stats_tx", 0600, dir
,
113 &ns
->ethtool
.pauseparam
.report_stats_tx
);
115 dir
= debugfs_create_dir("ring", ethtool
);
116 debugfs_create_u32("rx_max_pending", 0600, dir
,
117 &ns
->ethtool
.ring
.rx_max_pending
);
118 debugfs_create_u32("rx_jumbo_max_pending", 0600, dir
,
119 &ns
->ethtool
.ring
.rx_jumbo_max_pending
);
120 debugfs_create_u32("rx_mini_max_pending", 0600, dir
,
121 &ns
->ethtool
.ring
.rx_mini_max_pending
);
122 debugfs_create_u32("tx_max_pending", 0600, dir
,
123 &ns
->ethtool
.ring
.tx_max_pending
);