Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7905288f authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller
Browse files

net: dsa: allow switches driver to implement get/set EEE



Allow switches driver to query and enable/disable EEE on a per-port
basis by implementing the ethtool_{get,set}_eee settings and delegating
these operations to the switch driver.

set_eee() will need to coordinate with the PHY driver to make sure that
EEE is enabled, the link-partner supports it and the auto-negotiation
result is satisfactory.

Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b6d045db
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -232,6 +232,15 @@ struct dsa_switch_driver {
			       struct phy_device *phy);
			       struct phy_device *phy);
	void	(*port_disable)(struct dsa_switch *ds, int port,
	void	(*port_disable)(struct dsa_switch *ds, int port,
				struct phy_device *phy);
				struct phy_device *phy);

	/*
	 * EEE setttings
	 */
	int	(*set_eee)(struct dsa_switch *ds, int port,
			   struct phy_device *phydev,
			   struct ethtool_eee *e);
	int	(*get_eee)(struct dsa_switch *ds, int port,
			   struct ethtool_eee *e);
};
};


void register_switch_driver(struct dsa_switch_driver *type);
void register_switch_driver(struct dsa_switch_driver *type);
+40 −0
Original line number Original line Diff line number Diff line
@@ -342,6 +342,44 @@ static int dsa_slave_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
	return ret;
	return ret;
}
}


static int dsa_slave_set_eee(struct net_device *dev, struct ethtool_eee *e)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret;

	if (!ds->drv->set_eee)
		return -EOPNOTSUPP;

	ret = ds->drv->set_eee(ds, p->port, p->phy, e);
	if (ret)
		return ret;

	if (p->phy)
		ret = phy_ethtool_set_eee(p->phy, e);

	return ret;
}

static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e)
{
	struct dsa_slave_priv *p = netdev_priv(dev);
	struct dsa_switch *ds = p->parent;
	int ret;

	if (!ds->drv->get_eee)
		return -EOPNOTSUPP;

	ret = ds->drv->get_eee(ds, p->port, e);
	if (ret)
		return ret;

	if (p->phy)
		ret = phy_ethtool_get_eee(p->phy, e);

	return ret;
}

static const struct ethtool_ops dsa_slave_ethtool_ops = {
static const struct ethtool_ops dsa_slave_ethtool_ops = {
	.get_settings		= dsa_slave_get_settings,
	.get_settings		= dsa_slave_get_settings,
	.set_settings		= dsa_slave_set_settings,
	.set_settings		= dsa_slave_set_settings,
@@ -353,6 +391,8 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
	.get_sset_count		= dsa_slave_get_sset_count,
	.get_sset_count		= dsa_slave_get_sset_count,
	.set_wol		= dsa_slave_set_wol,
	.set_wol		= dsa_slave_set_wol,
	.get_wol		= dsa_slave_get_wol,
	.get_wol		= dsa_slave_get_wol,
	.set_eee		= dsa_slave_set_eee,
	.get_eee		= dsa_slave_get_eee,
};
};


static const struct net_device_ops dsa_slave_netdev_ops = {
static const struct net_device_ops dsa_slave_netdev_ops = {