mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-03-03 18:28:01 +01:00
net: phy: dp83td510: add MSE interface support for 10BASE-T1L
Implement get_mse_capability() and get_mse_snapshot() for the DP83TD510E to expose its Mean Square Error (MSE) register via the new PHY MSE UAPI. The DP83TD510E does not document any peak MSE values; it only exposes a single average MSE register used internally to derive SQI. This implementation therefore advertises only PHY_MSE_CAP_AVG, along with LINK and channel-A selectors. Scaling is fixed to 0xFFFF, and the refresh interval/number of symbols are estimated from 10BASE-T1L symbol rate (7.5 MBd) and typical diagnostic intervals (~1 ms). For 10BASE-T1L deployments, SQI is a reliable indicator of link modulation quality once the link is established, but it does not indicate whether autonegotiation pulses will be correctly received in marginal conditions. MSE provides a direct measurement of slicer error rate that can be used to evaluate if autonegotiation is likely to succeed under a given cable length and condition. In practice, testing such scenarios often requires forcing a fixed-link setup to isolate MSE behaviour from the autonegotiation process. Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20251027122801.982364-5-o.rempel@pengutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
335a9660e1
commit
fd93ed77ef
@@ -61,6 +61,7 @@
|
||||
#define DP83TD510E_MASTER_SLAVE_RESOL_FAIL BIT(15)
|
||||
|
||||
#define DP83TD510E_MSE_DETECT 0xa85
|
||||
#define DP83TD510E_MSE_MAX U16_MAX
|
||||
|
||||
#define DP83TD510_SQI_MAX 7
|
||||
|
||||
@@ -249,6 +250,64 @@ struct dp83td510_priv {
|
||||
#define DP83TD510E_ALCD_COMPLETE BIT(15)
|
||||
#define DP83TD510E_ALCD_CABLE_LENGTH GENMASK(10, 0)
|
||||
|
||||
static int dp83td510_get_mse_capability(struct phy_device *phydev,
|
||||
struct phy_mse_capability *cap)
|
||||
{
|
||||
/* DP83TD510E documents only a single (average) MSE register
|
||||
* (used to derive SQI); no peak or worst-peak counters are
|
||||
* described. Advertise only PHY_MSE_CAP_AVG.
|
||||
*/
|
||||
cap->supported_caps = PHY_MSE_CAP_AVG;
|
||||
/* 10BASE-T1L is a single-pair medium, so there are no B/C/D channels.
|
||||
* We still advertise PHY_MSE_CAP_CHANNEL_A to indicate that the PHY
|
||||
* can attribute the measurement to a specific pair (the only one),
|
||||
* rather than exposing it only as a link-aggregate.
|
||||
*
|
||||
* Rationale:
|
||||
* - Keeps the ethtool MSE_GET selection logic consistent: per-channel
|
||||
* (A/B/C/D) is preferred over WORST/LINK, so userspace receives a
|
||||
* CHANNEL_A nest instead of LINK.
|
||||
* - Signals to tools that "per-pair" data is available (even if there's
|
||||
* just one pair), avoiding the impression that only aggregate values
|
||||
* are supported.
|
||||
* - Remains compatible with multi-pair PHYs and uniform UI handling.
|
||||
*
|
||||
* Note: WORST and other channels are not advertised on 10BASE-T1L.
|
||||
*/
|
||||
cap->supported_caps |= PHY_MSE_CHANNEL_A | PHY_MSE_CAP_LINK;
|
||||
cap->max_average_mse = DP83TD510E_MSE_MAX;
|
||||
|
||||
/* The datasheet does not specify the refresh rate or symbol count,
|
||||
* but based on similar PHYs and standards, we can assume a common
|
||||
* value. For 10BASE-T1L, the symbol rate is 7.5 MBd. A common
|
||||
* diagnostic interval is around 1ms.
|
||||
* 7.5e6 symbols/sec * 0.001 sec = 7500 symbols.
|
||||
*/
|
||||
cap->refresh_rate_ps = 1000000000; /* 1 ms */
|
||||
cap->num_symbols = 7500;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dp83td510_get_mse_snapshot(struct phy_device *phydev,
|
||||
enum phy_mse_channel channel,
|
||||
struct phy_mse_snapshot *snapshot)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (channel != PHY_MSE_CHANNEL_LINK &&
|
||||
channel != PHY_MSE_CHANNEL_A)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_MSE_DETECT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
snapshot->average_mse = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dp83td510_led_brightness_set(struct phy_device *phydev, u8 index,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
@@ -893,6 +952,9 @@ static struct phy_driver dp83td510_driver[] = {
|
||||
.get_phy_stats = dp83td510_get_phy_stats,
|
||||
.update_stats = dp83td510_update_stats,
|
||||
|
||||
.get_mse_capability = dp83td510_get_mse_capability,
|
||||
.get_mse_snapshot = dp83td510_get_mse_snapshot,
|
||||
|
||||
.led_brightness_set = dp83td510_led_brightness_set,
|
||||
.led_hw_is_supported = dp83td510_led_hw_is_supported,
|
||||
.led_hw_control_set = dp83td510_led_hw_control_set,
|
||||
|
||||
Reference in New Issue
Block a user