[PATCH net-next v1 3/3] net: phy: dp83td510: disable cable test support for 1Vpp PHYs
From: Oleksij Rempel
Date: Tue Jun 07 2022 - 06:17:39 EST
Using 1Vpp pulse provides most unreliable results. So, disable cable
testing if PHY is bootstrapped to use 1Vpp-only mode.
Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
---
drivers/net/phy/dp83td510.c | 52 ++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83td510.c b/drivers/net/phy/dp83td510.c
index d0229f3b0181..fb39eec40e10 100644
--- a/drivers/net/phy/dp83td510.c
+++ b/drivers/net/phy/dp83td510.c
@@ -31,6 +31,8 @@
#define DP83TD510E_TDR_FAIL BIT(0)
#define DP83TD510E_TDR_CFG1 0x300
+/* TX_TYPE: Transmit voltage level for TDR. 0 = 1V, 1 = 2.4V */
+#define DP83TD510E_TDR_TX_TYPE BIT(12)
#define DP83TD510E_TDR_CFG2 0x301
#define DP83TD510E_TDR_END_TAP_INDEX_1 GENMASK(14, 8)
@@ -71,6 +73,10 @@
#define DP83TD510E_UNKN_0310 0x310
#define DP83TD510E_0310_VAL 0x0036
+#define DP83TD510E_CHIP_SOR_1 0x467
+/* If LED_2 is set, blacklist 2.4V mode */
+#define DP83TD510E_SOR_LED_2 BIT(7)
+
#define DP83TD510E_AN_STAT_1 0x60c
#define DP83TD510E_MASTER_SLAVE_RESOL_FAIL BIT(15)
@@ -78,6 +84,10 @@
#define DP83TD510_SQI_MAX 7
+struct dp83td510_priv {
+ bool allow_v2_4_mode;
+};
+
struct dp83td510_mse_sqi_range {
u16 end;
u16 start;
@@ -315,12 +325,29 @@ static int dp83td510_tdr_init(struct phy_device *phydev)
static int dp83td510_cable_test_start(struct phy_device *phydev)
{
- int ret;
+ struct dp83td510_priv *priv = phydev->priv;
+ int ret, cfg = 0;
+
+ /* Generate 2.4Vpp pulse if HW is allowed to do so */
+ if (priv->allow_v2_4_mode) {
+ cfg |= DP83TD510E_TDR_TX_TYPE;
+ } else {
+ /* This PHY do not provide usable results with 1Vpp pulse.
+ * Potentially different dp83td510_tdr_init() values are
+ * needed.
+ */
+ return -EOPNOTSUPP;
+ }
ret = dp83td510_tdr_init(phydev);
if (ret)
return ret;
+ ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG1,
+ DP83TD510E_TDR_TX_TYPE, cfg);
+ if (ret)
+ return ret;
+
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG,
DP83TD510E_TDR_START);
}
@@ -376,6 +403,28 @@ static int dp83td510_cable_test_get_status(struct phy_device *phydev,
return phy_set_bits(phydev, MII_BMCR, BMCR_RESET);
}
+static int dp83td510_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct dp83td510_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ phydev->priv = priv;
+
+ ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_CHIP_SOR_1);
+ if (ret < 0)
+ return ret;
+
+ if (!(ret & DP83TD510E_SOR_LED_2))
+ priv->allow_v2_4_mode = true;
+
+ return 0;
+}
+
static int dp83td510_get_features(struct phy_device *phydev)
{
/* This PHY can't respond on MDIO bus if no RMII clock is enabled.
@@ -400,6 +449,7 @@ static struct phy_driver dp83td510_driver[] = {
.name = "TI DP83TD510E",
.flags = PHY_POLL_CABLE_TEST,
+ .probe = dp83td510_probe,
.config_aneg = dp83td510_config_aneg,
.read_status = dp83td510_read_status,
.get_features = dp83td510_get_features,
--
2.30.2