Commit 6b4a0fc1 authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller
Browse files

net: ethtool: Add helpers for cable test TDR data



Add helpers for returning raw TDR helpers in netlink messages.

Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a644de2
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -22,6 +22,10 @@ void ethnl_cable_test_free(struct phy_device *phydev);
void ethnl_cable_test_finished(struct phy_device *phydev);
int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, u8 result);
int ethnl_cable_test_fault_length(struct phy_device *phydev, u8 pair, u32 cm);
int ethnl_cable_test_amplitude(struct phy_device *phydev, u8 pair, s16 mV);
int ethnl_cable_test_pulse(struct phy_device *phydev, u16 mV);
int ethnl_cable_test_step(struct phy_device *phydev, u32 first, u32 last,
			  u32 step);
#else
static inline int ethnl_cable_test_alloc(struct phy_device *phydev, u8 cmd)
{
@@ -46,5 +50,22 @@ static inline int ethnl_cable_test_fault_length(struct phy_device *phydev,
{
	return -EOPNOTSUPP;
}

static inline int ethnl_cable_test_amplitude(struct phy_device *phydev,
					     u8 pair, s16 mV)
{
	return -EOPNOTSUPP;
}

static inline int ethnl_cable_test_pulse(struct phy_device *phydev, u16 mV)
{
	return -EOPNOTSUPP;
}

static inline int ethnl_cable_test_step(struct phy_device *phydev, u32 first,
					u32 last, u32 step)
{
	return -EOPNOTSUPP;
}
#endif /* IS_ENABLED(ETHTOOL_NETLINK) */
#endif /* _LINUX_ETHTOOL_NETLINK_H_ */
+79 −1
Original line number Diff line number Diff line
@@ -100,7 +100,10 @@ int ethnl_cable_test_alloc(struct phy_device *phydev, u8 cmd)
{
	int err = -ENOMEM;

	phydev->skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	/* One TDR sample occupies 20 bytes. For a 150 meter cable,
	 * with four pairs, around 12K is needed.
	 */
	phydev->skb = genlmsg_new(SZ_16K, GFP_KERNEL);
	if (!phydev->skb)
		goto out;

@@ -251,3 +254,78 @@ out_dev_put:
	dev_put(dev);
	return ret;
}
 
int ethnl_cable_test_amplitude(struct phy_device *phydev,
			       u8 pair, s16 mV)
{
	struct nlattr *nest;
	int ret = -EMSGSIZE;

	nest = nla_nest_start(phydev->skb,
			      ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE);
	if (!nest)
		return -EMSGSIZE;

	if (nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_AMPLITUDE_PAIR, pair))
		goto err;
	if (nla_put_u16(phydev->skb, ETHTOOL_A_CABLE_AMPLITUDE_mV, mV))
		goto err;

	nla_nest_end(phydev->skb, nest);
	return 0;

err:
	nla_nest_cancel(phydev->skb, nest);
	return ret;
}
EXPORT_SYMBOL_GPL(ethnl_cable_test_amplitude);

int ethnl_cable_test_pulse(struct phy_device *phydev, u16 mV)
{
	struct nlattr *nest;
	int ret = -EMSGSIZE;

	nest = nla_nest_start(phydev->skb, ETHTOOL_A_CABLE_TDR_NEST_PULSE);
	if (!nest)
		return -EMSGSIZE;

	if (nla_put_u16(phydev->skb, ETHTOOL_A_CABLE_PULSE_mV, mV))
		goto err;

	nla_nest_end(phydev->skb, nest);
	return 0;

err:
	nla_nest_cancel(phydev->skb, nest);
	return ret;
}
EXPORT_SYMBOL_GPL(ethnl_cable_test_pulse);

int ethnl_cable_test_step(struct phy_device *phydev, u32 first, u32 last,
			  u32 step)
{
	struct nlattr *nest;
	int ret = -EMSGSIZE;

	nest = nla_nest_start(phydev->skb, ETHTOOL_A_CABLE_TDR_NEST_STEP);
	if (!nest)
		return -EMSGSIZE;

	if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE,
			first))
		goto err;

	if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_STEP_LAST_DISTANCE, last))
		goto err;

	if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_STEP_STEP_DISTANCE, step))
		goto err;

	nla_nest_end(phydev->skb, nest);
	return 0;

err:
	nla_nest_cancel(phydev->skb, nest);
	return ret;
}
EXPORT_SYMBOL_GPL(ethnl_cable_test_step);