Commit b8768dc4 authored by Richard Cochran's avatar Richard Cochran Committed by David S. Miller
Browse files

net: ethtool: Refactor identical get_ts_info implementations.



The vlan, macvlan and the bonding drivers call their "real" device driver
in order to report the time stamping capabilities.  Provide a core
ethtool helper function to avoid copy/paste in the stack.

Signed-off-by: default avatarRichard Cochran <richardcochran@gmail.com>
Signed-off-by: default avatarKory Maincent <kory.maincent@bootlin.com>
Reviewed-by: default avatarFlorian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: default avatarJay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 430dc325
Loading
Loading
Loading
Loading
+2 −27
Original line number Diff line number Diff line
@@ -5755,10 +5755,8 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
{
	struct bonding *bond = netdev_priv(bond_dev);
	struct ethtool_ts_info ts_info;
	const struct ethtool_ops *ops;
	struct net_device *real_dev;
	bool sw_tx_support = false;
	struct phy_device *phydev;
	struct list_head *iter;
	struct slave *slave;
	int ret = 0;
@@ -5769,29 +5767,12 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
	rcu_read_unlock();

	if (real_dev) {
		ops = real_dev->ethtool_ops;
		phydev = real_dev->phydev;

		if (phy_has_tsinfo(phydev)) {
			ret = phy_ts_info(phydev, info);
			goto out;
		} else if (ops->get_ts_info) {
			ret = ops->get_ts_info(real_dev, info);
			goto out;
		}
		ret = ethtool_get_ts_info_by_layer(real_dev, info);
	} else {
		/* Check if all slaves support software tx timestamping */
		rcu_read_lock();
		bond_for_each_slave_rcu(bond, slave, iter) {
			ret = -1;
			ops = slave->dev->ethtool_ops;
			phydev = slave->dev->phydev;

			if (phy_has_tsinfo(phydev))
				ret = phy_ts_info(phydev, &ts_info);
			else if (ops->get_ts_info)
				ret = ops->get_ts_info(slave->dev, &ts_info);

			ret = ethtool_get_ts_info_by_layer(slave->dev, &ts_info);
			if (!ret && (ts_info.so_timestamping & SOF_TIMESTAMPING_TX_SOFTWARE)) {
				sw_tx_support = true;
				continue;
@@ -5803,15 +5784,9 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
		rcu_read_unlock();
	}

	ret = 0;
	info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
				SOF_TIMESTAMPING_SOFTWARE;
	if (sw_tx_support)
		info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;

	info->phc_index = -1;

out:
	dev_put(real_dev);
	return ret;
}
+1 −13
Original line number Diff line number Diff line
@@ -1086,20 +1086,8 @@ static int macvlan_ethtool_get_ts_info(struct net_device *dev,
				       struct ethtool_ts_info *info)
{
	struct net_device *real_dev = macvlan_dev_real_dev(dev);
	const struct ethtool_ops *ops = real_dev->ethtool_ops;
	struct phy_device *phydev = real_dev->phydev;

	if (phy_has_tsinfo(phydev)) {
		return phy_ts_info(phydev, info);
	} else if (ops->get_ts_info) {
		return ops->get_ts_info(real_dev, info);
	} else {
		info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
			SOF_TIMESTAMPING_SOFTWARE;
		info->phc_index = -1;
	}

	return 0;
	return ethtool_get_ts_info_by_layer(real_dev, info);
}

static netdev_features_t macvlan_fix_features(struct net_device *dev,
+8 −0
Original line number Diff line number Diff line
@@ -1043,6 +1043,14 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add,
	return -EINVAL;
}

/**
 * ethtool_get_ts_info_by_layer - Obtains time stamping capabilities from the MAC or PHY layer.
 * @dev: pointer to net_device structure
 * @info: buffer to hold the result
 * Returns zero on success, non-zero otherwise.
 */
int ethtool_get_ts_info_by_layer(struct net_device *dev, struct ethtool_ts_info *info);

/**
 * ethtool_sprintf - Write formatted string to ethtool string data
 * @data: Pointer to a pointer to the start of string to update
+1 −14
Original line number Diff line number Diff line
@@ -702,20 +702,7 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev,
				    struct ethtool_ts_info *info)
{
	const struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
	const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops;
	struct phy_device *phydev = vlan->real_dev->phydev;

	if (phy_has_tsinfo(phydev)) {
		return phy_ts_info(phydev, info);
	} else if (ops->get_ts_info) {
		return ops->get_ts_info(vlan->real_dev, info);
	} else {
		info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
			SOF_TIMESTAMPING_SOFTWARE;
		info->phc_index = -1;
	}

	return 0;
	return ethtool_get_ts_info_by_layer(vlan->real_dev, info);
}

static void vlan_dev_get_stats64(struct net_device *dev,
+6 −0
Original line number Diff line number Diff line
@@ -661,6 +661,12 @@ int ethtool_get_phc_vclocks(struct net_device *dev, int **vclock_index)
}
EXPORT_SYMBOL(ethtool_get_phc_vclocks);

int ethtool_get_ts_info_by_layer(struct net_device *dev, struct ethtool_ts_info *info)
{
	return __ethtool_get_ts_info(dev, info);
}
EXPORT_SYMBOL(ethtool_get_ts_info_by_layer);

const struct ethtool_phy_ops *ethtool_phy_ops;

void ethtool_set_ethtool_phy_ops(const struct ethtool_phy_ops *ops)