[PATCH net-next 1/2] netdevsim: add link speed support

From: Hangbin Liu

Date: Sun Aug 30 2026 - 23:29:01 EST


From: Hangbin Liu <liuhangbin@xxxxxxxxxx>

Add ethtool get/set_link_ksettings callbacks to netdevsim so the simulated
link speed and duplex can be queried and configured from userspace.

Move NSIM_LINK_SPEED_MAX and NSIM_LINK_SPEED_UNIT from dev.c to netdevsim.h
so they are available to both the devlink rate path and the new ethtool
code. The set callback rejects speeds exceeding NSIM_LINK_SPEED_MAX.

The default link speed is set to SPEED_5000 with DUPLEX_FULL, matching the
existing NSIM_LINK_SPEED_MAX definition.

Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxxx>
---
drivers/net/netdevsim/dev.c | 6 ------
drivers/net/netdevsim/ethtool.c | 30 ++++++++++++++++++++++++++++++
drivers/net/netdevsim/netdevsim.h | 8 ++++++++
3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index feb88ccbbced..729ce80f6c83 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -1138,12 +1138,6 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
return 0;
}

-#define NSIM_LINK_SPEED_MAX 5000 /* Mbps */
-#define NSIM_LINK_SPEED_UNIT 125000 /* 1 Mbps given in bytes/sec to avoid
- * u64 overflow during conversion from
- * bytes to bits.
- */
-
static int nsim_rate_bytes_to_units(char *name, u64 *rate, struct netlink_ext_ack *extack)
{
u64 val;
diff --git a/drivers/net/netdevsim/ethtool.c b/drivers/net/netdevsim/ethtool.c
index 025ea79879f3..59768bd7b620 100644
--- a/drivers/net/netdevsim/ethtool.c
+++ b/drivers/net/netdevsim/ethtool.c
@@ -205,6 +205,30 @@ static int nsim_get_ts_info(struct net_device *dev,
return 0;
}

+static int nsim_get_link_ksettings(struct net_device *dev,
+ struct ethtool_link_ksettings *cmd)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+
+ cmd->base.speed = ns->ethtool.speed;
+ cmd->base.duplex = ns->ethtool.duplex;
+ cmd->base.port = PORT_OTHER;
+ cmd->base.autoneg = AUTONEG_DISABLE;
+ return 0;
+}
+
+static int nsim_set_link_ksettings(struct net_device *dev,
+ const struct ethtool_link_ksettings *cmd)
+{
+ struct netdevsim *ns = netdev_priv(dev);
+
+ if (cmd->base.speed > NSIM_LINK_SPEED_MAX)
+ return -EINVAL;
+
+ return ethtool_virtdev_set_link_ksettings(dev, cmd, &ns->ethtool.speed,
+ &ns->ethtool.duplex);
+}
+
static const struct ethtool_ops nsim_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_ALL_PARAMS,
.supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT |
@@ -223,6 +247,8 @@ static const struct ethtool_ops nsim_ethtool_ops = {
.set_fecparam = nsim_set_fecparam,
.get_fec_stats = nsim_get_fec_stats,
.get_ts_info = nsim_get_ts_info,
+ .get_link_ksettings = nsim_get_link_ksettings,
+ .set_link_ksettings = nsim_set_link_ksettings,
};

static void nsim_ethtool_ring_init(struct netdevsim *ns)
@@ -250,12 +276,16 @@ void nsim_ethtool_init(struct netdevsim *ns)
ns->ethtool.fec.active_fec = ETHTOOL_FEC_NONE;

ns->ethtool.channels = ns->nsim_bus_dev->num_queues;
+ ns->ethtool.duplex = DUPLEX_FULL;
+ ns->ethtool.speed = SPEED_5000;

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

debugfs_create_u32("get_err", 0600, ethtool, &ns->ethtool.get_err);
debugfs_create_u32("set_err", 0600, ethtool, &ns->ethtool.set_err);
+ debugfs_create_u32("speed", 0600, ethtool, &ns->ethtool.speed);
+ debugfs_create_u8("duplex", 0600, ethtool, &ns->ethtool.duplex);

dir = debugfs_create_dir("pause", ethtool);
debugfs_create_bool("report_stats_rx", 0600, dir,
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 55aec41237b9..ce0d0dea00fb 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -39,6 +39,11 @@

#define NSIM_HDS_THRESHOLD_MAX 1024

+#define NSIM_LINK_SPEED_MAX 5000 /* Mbps */
+#define NSIM_LINK_SPEED_UNIT 125000 /* 1 Mbps given in bytes/sec to avoid
+ * u64 overflow during conversion from
+ * bytes to bits.
+ */
struct nsim_sa {
struct xfrm_state *xs;
__be32 ipaddr[4];
@@ -95,6 +100,9 @@ struct nsim_ethtool {
struct ethtool_coalesce coalesce;
struct ethtool_ringparam ring;
struct ethtool_fecparam fec;
+
+ u32 speed;
+ u8 duplex;
};

struct nsim_rq {

--
2.55.0