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

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
...@@ -937,6 +937,17 @@ struct dsa_switch_ops { ...@@ -937,6 +937,17 @@ struct dsa_switch_ops {
int (*get_ts_info)(struct dsa_switch *ds, int port, int (*get_ts_info)(struct dsa_switch *ds, int port,
struct ethtool_ts_info *ts); 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 * DCB ops
*/ */
......
...@@ -1117,6 +1117,40 @@ static void dsa_slave_net_selftest(struct net_device *ndev, ...@@ -1117,6 +1117,40 @@ static void dsa_slave_net_selftest(struct net_device *ndev,
net_selftest(ndev, etest, buf); 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) static void dsa_slave_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)
{ {
struct dsa_port *dp = dsa_slave_to_port(dev); struct dsa_port *dp = dsa_slave_to_port(dev);
...@@ -2205,6 +2239,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = { ...@@ -2205,6 +2239,9 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
.set_rxnfc = dsa_slave_set_rxnfc, .set_rxnfc = dsa_slave_set_rxnfc,
.get_ts_info = dsa_slave_get_ts_info, .get_ts_info = dsa_slave_get_ts_info,
.self_test = dsa_slave_net_selftest, .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 = { static const struct dcbnl_rtnl_ops __maybe_unused dsa_slave_dcbnl_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment