Skip to content

Commit

Permalink
net: ethtool: Add helpers for cable test TDR data
Browse files Browse the repository at this point in the history
Add helpers for returning raw TDR helpers in netlink messages.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed May 27, 2020
1 parent 1a644de commit 6b4a0fc
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 1 deletion.
21 changes: 21 additions & 0 deletions include/linux/ethtool_netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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_ */
80 changes: 79 additions & 1 deletion net/ethtool/cabletest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -251,3 +254,78 @@ int ethnl_act_cable_test_tdr(struct sk_buff *skb, struct genl_info *info)
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);

0 comments on commit 6b4a0fc

Please sign in to comment.