Commit 5f6c2d49 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller
Browse files

net: dsa: add plumbing for changing and getting MAC merge layer state



The DSA core is in charge of the ethtool_ops of the net devices
associated with switch ports, so in case a hardware driver supports the
MAC merge layer, DSA must pass the callbacks through to the driver.
Add support for precisely that.

Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dd1c4164
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -937,6 +937,17 @@ struct dsa_switch_ops {
	int	(*get_ts_info)(struct dsa_switch *ds, int port,
			       struct ethtool_ts_info *ts);

	/*
	 * ethtool MAC merge layer
	 */
	int	(*get_mm)(struct dsa_switch *ds, int port,
			  struct ethtool_mm_state *state);
	int	(*set_mm)(struct dsa_switch *ds, int port,
			  struct ethtool_mm_cfg *cfg,
			  struct netlink_ext_ack *extack);
	void	(*get_mm_stats)(struct dsa_switch *ds, int port,
				struct ethtool_mm_stats *stats);

	/*
	 * DCB ops
	 */
+37 −0
Original line number Diff line number Diff line
@@ -1117,6 +1117,40 @@ static void dsa_slave_net_selftest(struct net_device *ndev,
	net_selftest(ndev, etest, buf);
}

static int dsa_slave_get_mm(struct net_device *dev,
			    struct ethtool_mm_state *state)
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_switch *ds = dp->ds;

	if (!ds->ops->get_mm)
		return -EOPNOTSUPP;

	return ds->ops->get_mm(ds, dp->index, state);
}

static int dsa_slave_set_mm(struct net_device *dev, struct ethtool_mm_cfg *cfg,
			    struct netlink_ext_ack *extack)
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_switch *ds = dp->ds;

	if (!ds->ops->set_mm)
		return -EOPNOTSUPP;

	return ds->ops->set_mm(ds, dp->index, cfg, extack);
}

static void dsa_slave_get_mm_stats(struct net_device *dev,
				   struct ethtool_mm_stats *stats)
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_switch *ds = dp->ds;

	if (ds->ops->get_mm_stats)
		ds->ops->get_mm_stats(ds, dp->index, stats);
}

static void dsa_slave_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
@@ -2205,6 +2239,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
	.set_rxnfc		= dsa_slave_set_rxnfc,
	.get_ts_info		= dsa_slave_get_ts_info,
	.self_test		= dsa_slave_net_selftest,
	.get_mm			= dsa_slave_get_mm,
	.set_mm			= dsa_slave_set_mm,
	.get_mm_stats		= dsa_slave_get_mm_stats,
};

static const struct dcbnl_rtnl_ops __maybe_unused dsa_slave_dcbnl_ops = {