[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220608123236.792405-4-o.rempel@pengutronix.de>
Date: Wed, 8 Jun 2022 14:32:36 +0200
From: Oleksij Rempel <o.rempel@...gutronix.de>
To: Andrew Lunn <andrew@...n.ch>,
Heiner Kallweit <hkallweit1@...il.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>
Cc: Oleksij Rempel <o.rempel@...gutronix.de>, kernel@...gutronix.de,
linux-kernel@...r.kernel.org, netdev@...r.kernel.org
Subject: [PATCH net-next v3 3/3] net: phy: dp83td510: disable cable test support for 1Vpp PHYs
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@...gutronix.de>
---
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 de32ab1a262d..1eaf2ceaca8c 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;
+};
+
/* Register values are converted to SNR(dB) as suggested by
* "Application Report - DP83TD510E Cable Diagnostics Toolkit":
* SNR(dB) = -10 * log10 (VAL/2^17) - 1.76 dB.
@@ -308,12 +318,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);
}
@@ -369,6 +396,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.
@@ -393,6 +442,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
Powered by blists - more mailing lists