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: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
				
					committed by
					
						
						David S. Miller
					
				
			
			
				
	
			
			
			
						parent
						
							dd1c416450
						
					
				
				
					commit
					5f6c2d498a
				
			@@ -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
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user