forked from mirrors/linux
		
	net: ethtool: Add helpers for reporting test results
The PHY drivers can use these helpers for reporting the results. The results get translated into netlink attributes which are added to the pre-allocated skbuf. v3: Poison phydev->skb Return -EMSGSIZE when ethnl_bcastmsg_put() fails Return valid error code when nla_nest_start() fails Use u8 for results Actually put u32 length into message v4: s/ENOTSUPP/EOPNOTSUPP/g Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Michal Kubecek <mkubecek@suse.cz> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
		
							parent
							
								
									1dd3f212af
								
							
						
					
					
						commit
						1e2dc14509
					
				
					 3 changed files with 70 additions and 2 deletions
				
			
		| 
						 | 
					@ -20,10 +20,12 @@ struct phy_device;
 | 
				
			||||||
int ethnl_cable_test_alloc(struct phy_device *phydev);
 | 
					int ethnl_cable_test_alloc(struct phy_device *phydev);
 | 
				
			||||||
void ethnl_cable_test_free(struct phy_device *phydev);
 | 
					void ethnl_cable_test_free(struct phy_device *phydev);
 | 
				
			||||||
void ethnl_cable_test_finished(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);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static inline int ethnl_cable_test_alloc(struct phy_device *phydev)
 | 
					static inline int ethnl_cable_test_alloc(struct phy_device *phydev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return -ENOTSUPP;
 | 
						return -EOPNOTSUPP;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void ethnl_cable_test_free(struct phy_device *phydev)
 | 
					static inline void ethnl_cable_test_free(struct phy_device *phydev)
 | 
				
			||||||
| 
						 | 
					@ -33,5 +35,16 @@ static inline void ethnl_cable_test_free(struct phy_device *phydev)
 | 
				
			||||||
static inline void ethnl_cable_test_finished(struct phy_device *phydev)
 | 
					static inline void ethnl_cable_test_finished(struct phy_device *phydev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					static inline int ethnl_cable_test_result(struct phy_device *phydev, u8 pair,
 | 
				
			||||||
 | 
										  u8 result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline int ethnl_cable_test_fault_length(struct phy_device *phydev,
 | 
				
			||||||
 | 
											u8 pair, u32 cm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -EOPNOTSUPP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
#endif /* IS_ENABLED(ETHTOOL_NETLINK) */
 | 
					#endif /* IS_ENABLED(ETHTOOL_NETLINK) */
 | 
				
			||||||
#endif /* _LINUX_ETHTOOL_NETLINK_H_ */
 | 
					#endif /* _LINUX_ETHTOOL_NETLINK_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1265,6 +1265,10 @@ int phy_start_cable_test(struct phy_device *phydev,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int phy_cable_test_result(struct phy_device *phydev, u8 pair, u16 result);
 | 
				
			||||||
 | 
					int phy_cable_test_fault_length(struct phy_device *phydev, u8 pair,
 | 
				
			||||||
 | 
									u16 cm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void phy_device_reset(struct phy_device *phydev, int value)
 | 
					static inline void phy_device_reset(struct phy_device *phydev, int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	mdio_device_reset(&phydev->mdio, value);
 | 
						mdio_device_reset(&phydev->mdio, value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,13 +81,16 @@ int ethnl_cable_test_alloc(struct phy_device *phydev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	phydev->nest = nla_nest_start(phydev->skb,
 | 
						phydev->nest = nla_nest_start(phydev->skb,
 | 
				
			||||||
				      ETHTOOL_A_CABLE_TEST_NTF_NEST);
 | 
									      ETHTOOL_A_CABLE_TEST_NTF_NEST);
 | 
				
			||||||
	if (!phydev->nest)
 | 
						if (!phydev->nest) {
 | 
				
			||||||
 | 
							err = -EMSGSIZE;
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	nlmsg_free(phydev->skb);
 | 
						nlmsg_free(phydev->skb);
 | 
				
			||||||
 | 
						phydev->skb = NULL;
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(ethnl_cable_test_alloc);
 | 
					EXPORT_SYMBOL_GPL(ethnl_cable_test_alloc);
 | 
				
			||||||
| 
						 | 
					@ -95,6 +98,7 @@ EXPORT_SYMBOL_GPL(ethnl_cable_test_alloc);
 | 
				
			||||||
void ethnl_cable_test_free(struct phy_device *phydev)
 | 
					void ethnl_cable_test_free(struct phy_device *phydev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	nlmsg_free(phydev->skb);
 | 
						nlmsg_free(phydev->skb);
 | 
				
			||||||
 | 
						phydev->skb = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(ethnl_cable_test_free);
 | 
					EXPORT_SYMBOL_GPL(ethnl_cable_test_free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,3 +111,50 @@ void ethnl_cable_test_finished(struct phy_device *phydev)
 | 
				
			||||||
	ethnl_multicast(phydev->skb, phydev->attached_dev);
 | 
						ethnl_multicast(phydev->skb, phydev->attached_dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(ethnl_cable_test_finished);
 | 
					EXPORT_SYMBOL_GPL(ethnl_cable_test_finished);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, u8 result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nlattr *nest;
 | 
				
			||||||
 | 
						int ret = -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nest = nla_nest_start(phydev->skb, ETHTOOL_A_CABLE_NEST_RESULT);
 | 
				
			||||||
 | 
						if (!nest)
 | 
				
			||||||
 | 
							return -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_RESULT_PAIR, pair))
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						if (nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_RESULT_CODE, result))
 | 
				
			||||||
 | 
							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_result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int ethnl_cable_test_fault_length(struct phy_device *phydev, u8 pair, u32 cm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nlattr *nest;
 | 
				
			||||||
 | 
						int ret = -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nest = nla_nest_start(phydev->skb,
 | 
				
			||||||
 | 
								      ETHTOOL_A_CABLE_NEST_FAULT_LENGTH);
 | 
				
			||||||
 | 
						if (!nest)
 | 
				
			||||||
 | 
							return -EMSGSIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR, pair))
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_FAULT_LENGTH_CM, cm))
 | 
				
			||||||
 | 
							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_fault_length);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue