From patchwork Thu Aug 22 12:07:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 13773268 X-Patchwork-Delegate: kuba@kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 567FA1C93DC for ; Thu, 22 Aug 2024 12:07:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328436; cv=none; b=WXIdgDYwmDFYOfs7TPs2J/xEUPl+HF9VyPmFc5MmzwSkciepZuSdIjLKohBpI1lYpJcmln6LD41Rkoz6JPXVl5COIyJwux3bVhMz0mB/HmW42nETMrXUaRHbT/zQ85kM3V6oKplKfdfWGKLh01jzPodPhrbgTmdgHf91wAyryIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328436; c=relaxed/simple; bh=0/kZ5kTdGoks6QrkmC3SqdsHYofk1DuEBDq2H7eYYFQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=eWhkTNOp5i4N6ZxrpDMn8V6FBBUSIS5cjkC2/e7m+70ZVMQYq8LJStYJFrvt7fn40AyasLFvBct3UokOyyOi3u6CB7sU4TErZBVU4k5xQig3nRu4mFqPwY1be8tn7hVyS2CoQgf2vNUdNly59KaSGeIIJnFdowwpZ7FdZ4Q5XKM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sh6an-0008Cc-MB; Thu, 22 Aug 2024 14:07:05 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sh6an-002F7S-6w; Thu, 22 Aug 2024 14:07:05 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1sh6an-005qQP-0S; Thu, 22 Aug 2024 14:07:05 +0200 From: Oleksij Rempel To: Andrew Lunn , Heiner Kallweit , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jonathan Corbet Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Russell King Subject: [PATCH net-next v3 1/3] ethtool: Extend cable testing interface with result source information Date: Thu, 22 Aug 2024 14:07:01 +0200 Message-Id: <20240822120703.1393130-2-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240822120703.1393130-1-o.rempel@pengutronix.de> References: <20240822120703.1393130-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Extend the ethtool netlink cable testing interface by adding support for specifying the source of cable testing results. This allows users to differentiate between results obtained through different diagnostic methods. For example, some TI 10BaseT1L PHYs provide two variants of cable diagnostics: Time Domain Reflectometry (TDR) and Active Link Cable Diagnostic (ALCD). By introducing `ETHTOOL_A_CABLE_RESULT_SRC` and `ETHTOOL_A_CABLE_FAULT_LENGTH_SRC` attributes, this update enables drivers to indicate whether the result was derived from TDR or ALCD, improving the clarity and utility of diagnostic information. Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn --- changes v3: - use u32 instead of u8 changes v2: - update Documentation/netlink/specs/ethtool.yaml - use u8 instead of u32 for _src - update comments --- Documentation/netlink/specs/ethtool.yaml | 6 ++++++ Documentation/networking/ethtool-netlink.rst | 5 +++++ include/uapi/linux/ethtool_netlink.h | 11 +++++++++++ 3 files changed, 22 insertions(+) diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml index 1bbeaba5c6442..057f8916024a6 100644 --- a/Documentation/netlink/specs/ethtool.yaml +++ b/Documentation/netlink/specs/ethtool.yaml @@ -659,6 +659,9 @@ attribute-sets: - name: code type: u8 + - + name: src + type: u32 - name: cable-fault-length attributes: @@ -668,6 +671,9 @@ attribute-sets: - name: cm type: u32 + - + name: src + type: u32 - name: cable-nest attributes: diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst index 3f6c6880e7c48..5ca0b3661379a 100644 --- a/Documentation/networking/ethtool-netlink.rst +++ b/Documentation/networking/ethtool-netlink.rst @@ -1307,12 +1307,17 @@ information. +-+-+-----------------------------------------+--------+---------------------+ | | | ``ETHTOOL_A_CABLE_RESULTS_CODE`` | u8 | result code | +-+-+-----------------------------------------+--------+---------------------+ + | | | ``ETHTOOL_A_CABLE_RESULT_SRC`` | u32 | information source | + +-+-+-----------------------------------------+--------+---------------------+ | | ``ETHTOOL_A_CABLE_NEST_FAULT_LENGTH`` | nested | cable length | +-+-+-----------------------------------------+--------+---------------------+ | | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR`` | u8 | pair number | +-+-+-----------------------------------------+--------+---------------------+ | | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_CM`` | u32 | length in cm | +-+-+-----------------------------------------+--------+---------------------+ + | | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_SRC`` | u32 | information source | + +-+-+-----------------------------------------+--------+---------------------+ + CABLE_TEST TDR ============== diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h index 9074fa309bd6d..810c8630bfbed 100644 --- a/include/uapi/linux/ethtool_netlink.h +++ b/include/uapi/linux/ethtool_netlink.h @@ -569,10 +569,20 @@ enum { ETHTOOL_A_CABLE_PAIR_D, }; +/* Information source for specific results. */ +enum { + ETHTOOL_A_CABLE_INF_SRC_UNSPEC, + /* Results provided by the Time Domain Reflectometry (TDR) */ + ETHTOOL_A_CABLE_INF_SRC_TDR, + /* Results provided by the Active Link Cable Diagnostic (ALCD) */ + ETHTOOL_A_CABLE_INF_SRC_ALCD, +}; + enum { ETHTOOL_A_CABLE_RESULT_UNSPEC, ETHTOOL_A_CABLE_RESULT_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ ETHTOOL_A_CABLE_RESULT_CODE, /* u8 ETHTOOL_A_CABLE_RESULT_CODE_ */ + ETHTOOL_A_CABLE_RESULT_SRC, /* u32 ETHTOOL_A_CABLE_INF_SRC_ */ __ETHTOOL_A_CABLE_RESULT_CNT, ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1) @@ -582,6 +592,7 @@ enum { ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC, ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ ETHTOOL_A_CABLE_FAULT_LENGTH_CM, /* u32 */ + ETHTOOL_A_CABLE_FAULT_LENGTH_SRC, /* u32 ETHTOOL_A_CABLE_INF_SRC_ */ __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT, ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1) From patchwork Thu Aug 22 12:07:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 13773269 X-Patchwork-Delegate: kuba@kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57CC31C9429 for ; Thu, 22 Aug 2024 12:07:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328437; cv=none; b=VbmrIJIiWRs9Qp8sISLGbnaTO2hzCP5X65XONxmH/xZDzJQybiJwsWl6glpzkRs9yUunQtHXheOWY077ni2v72fOiYDk8U9drlsrcrwcXoscrOg0cGlYNd6V1h9WPj6Sc7D7qksNLkkjObih3xHj1XhGiZkiL1/M4vbiJlWN9Cw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328437; c=relaxed/simple; bh=gjQfAwJDc8lDZjDaYJdxa7z1ksCqx4Gd6ED6xIvitPY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gs70OatKWTEaBHB9o3V687j8xCNj0SIrRrppdb/9TH71oVo1NTYzGP2B0TSp0pTlojDSaRSIl85kzgjolhnueLovp3vsaRkdMwnaWdP2f5OsJ6SeX9lOXPyzkeDFfOYlIk8h84K9E+xPuQiC1JZ9kFcCCot/OqDFLHCVbawv3XM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sh6an-0008Cf-Ms; Thu, 22 Aug 2024 14:07:05 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sh6an-002F7T-7m; Thu, 22 Aug 2024 14:07:05 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1sh6an-005qQZ-0X; Thu, 22 Aug 2024 14:07:05 +0200 From: Oleksij Rempel To: Andrew Lunn , Heiner Kallweit , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jonathan Corbet Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Russell King Subject: [PATCH net-next v3 2/3] ethtool: Add support for specifying information source in cable test results Date: Thu, 22 Aug 2024 14:07:02 +0200 Message-Id: <20240822120703.1393130-3-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240822120703.1393130-1-o.rempel@pengutronix.de> References: <20240822120703.1393130-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Enhance the ethtool cable test interface by introducing the ability to specify the source of the diagnostic information for cable test results. This is particularly useful for PHYs that offer multiple diagnostic methods, such as Time Domain Reflectometry (TDR) and Active Link Cable Diagnostic (ALCD). Key changes: - Added `ethnl_cable_test_result_with_src` and `ethnl_cable_test_fault_length_with_src` functions to allow specifying the information source when reporting cable test results. - Updated existing `ethnl_cable_test_result` and `ethnl_cable_test_fault_length` functions to use TDR as the default source, ensuring backward compatibility. - Modified the UAPI to support these new attributes, enabling drivers to provide more detailed diagnostic information. Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn --- changes v3: - use u32 instead for u8 for src changes v2: - use u8 instead of u32 for src - do not send src field if src is ETHTOOL_A_CABLE_INF_SRC_UNSPEC --- include/linux/ethtool_netlink.h | 29 +++++++++++++++++++++++------ net/ethtool/cabletest.c | 19 +++++++++++++++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h index fae0dfb9a9c82..aba91335273af 100644 --- a/include/linux/ethtool_netlink.h +++ b/include/linux/ethtool_netlink.h @@ -23,8 +23,10 @@ struct phy_device; int ethnl_cable_test_alloc(struct phy_device *phydev, u8 cmd); 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_result_with_src(struct phy_device *phydev, u8 pair, + u8 result, u32 src); +int ethnl_cable_test_fault_length_with_src(struct phy_device *phydev, u8 pair, + u32 cm, u32 src); 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, @@ -54,14 +56,14 @@ static inline void ethnl_cable_test_free(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) +static inline int ethnl_cable_test_result_with_src(struct phy_device *phydev, + u8 pair, u8 result, u32 src) { return -EOPNOTSUPP; } -static inline int ethnl_cable_test_fault_length(struct phy_device *phydev, - u8 pair, u32 cm) +static inline int ethnl_cable_test_fault_length_with_src(struct phy_device *phydev, + u8 pair, u32 cm, u32 src) { return -EOPNOTSUPP; } @@ -119,4 +121,19 @@ static inline bool ethtool_dev_mm_supported(struct net_device *dev) } #endif /* IS_ENABLED(CONFIG_ETHTOOL_NETLINK) */ + +static inline int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, + u8 result) +{ + return ethnl_cable_test_result_with_src(phydev, pair, result, + ETHTOOL_A_CABLE_INF_SRC_TDR); +} + +static inline int ethnl_cable_test_fault_length(struct phy_device *phydev, + u8 pair, u32 cm) +{ + return ethnl_cable_test_fault_length_with_src(phydev, pair, cm, + ETHTOOL_A_CABLE_INF_SRC_TDR); +} + #endif /* _LINUX_ETHTOOL_NETLINK_H_ */ diff --git a/net/ethtool/cabletest.c b/net/ethtool/cabletest.c index f6f136ec7ddfc..6f7e4ab4b68ca 100644 --- a/net/ethtool/cabletest.c +++ b/net/ethtool/cabletest.c @@ -160,7 +160,8 @@ void ethnl_cable_test_finished(struct phy_device *phydev) } EXPORT_SYMBOL_GPL(ethnl_cable_test_finished); -int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, u8 result) +int ethnl_cable_test_result_with_src(struct phy_device *phydev, u8 pair, + u8 result, u32 src) { struct nlattr *nest; int ret = -EMSGSIZE; @@ -173,6 +174,10 @@ int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, u8 result) goto err; if (nla_put_u8(phydev->skb, ETHTOOL_A_CABLE_RESULT_CODE, result)) goto err; + if (src != ETHTOOL_A_CABLE_INF_SRC_UNSPEC) { + if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_RESULT_SRC, src)) + goto err; + } nla_nest_end(phydev->skb, nest); return 0; @@ -181,9 +186,10 @@ int ethnl_cable_test_result(struct phy_device *phydev, u8 pair, u8 result) nla_nest_cancel(phydev->skb, nest); return ret; } -EXPORT_SYMBOL_GPL(ethnl_cable_test_result); +EXPORT_SYMBOL_GPL(ethnl_cable_test_result_with_src); -int ethnl_cable_test_fault_length(struct phy_device *phydev, u8 pair, u32 cm) +int ethnl_cable_test_fault_length_with_src(struct phy_device *phydev, u8 pair, + u32 cm, u32 src) { struct nlattr *nest; int ret = -EMSGSIZE; @@ -197,6 +203,11 @@ int ethnl_cable_test_fault_length(struct phy_device *phydev, u8 pair, u32 cm) goto err; if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_FAULT_LENGTH_CM, cm)) goto err; + if (src != ETHTOOL_A_CABLE_INF_SRC_UNSPEC) { + if (nla_put_u32(phydev->skb, ETHTOOL_A_CABLE_FAULT_LENGTH_SRC, + src)) + goto err; + } nla_nest_end(phydev->skb, nest); return 0; @@ -205,7 +216,7 @@ int ethnl_cable_test_fault_length(struct phy_device *phydev, u8 pair, u32 cm) nla_nest_cancel(phydev->skb, nest); return ret; } -EXPORT_SYMBOL_GPL(ethnl_cable_test_fault_length); +EXPORT_SYMBOL_GPL(ethnl_cable_test_fault_length_with_src); static const struct nla_policy cable_test_tdr_act_cfg_policy[] = { [ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST] = { .type = NLA_U32 }, From patchwork Thu Aug 22 12:07:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksij Rempel X-Patchwork-Id: 13773270 X-Patchwork-Delegate: kuba@kernel.org Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [185.203.201.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9CE9A1C93CA for ; Thu, 22 Aug 2024 12:07:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.203.201.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328437; cv=none; b=Ga1VgG7otcYvN7hNDTNPkYkrZ/5pUz/9qZAq4tkMYWz5YtYwtrLTZbETb2juPVKMOdiaChtSM5MRi6hFn0F2ptCxWI2XlTvuwikygfOrHZaq2jmb+3PcQf8OrHIe3PvLFah1Zu4s8gJbdG1p2sk2BOtdec/DYMDrKSuH8BhZ5xU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724328437; c=relaxed/simple; bh=joyb8XnVuKuiuUsf5VjS4NyrSMa664Pha87LRbQwJVE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Y9HiZX2xhMxVFGwBO7vVDNbfQZ4IpQPzZnUG2RaFZOnVLajjtWfXGTJpIIMp6xSiuis8HwtWctgp1mECmJfd4itUv2cN2wdQ9VOdrNoGFuPw1dIUKCbpirhwt5Nm2mmI+Gr8OPW8Ihg/eHCnWeMod2Df32RCGmPfAC5cxVpa2MU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de; spf=pass smtp.mailfrom=pengutronix.de; arc=none smtp.client-ip=185.203.201.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=pengutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pengutronix.de Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.whiteo.stw.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sh6an-0008Cg-Mh; Thu, 22 Aug 2024 14:07:05 +0200 Received: from [2a0a:edc0:0:1101:1d::ac] (helo=dude04.red.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sh6an-002F7U-8Y; Thu, 22 Aug 2024 14:07:05 +0200 Received: from ore by dude04.red.stw.pengutronix.de with local (Exim 4.96) (envelope-from ) id 1sh6an-005qQj-0b; Thu, 22 Aug 2024 14:07:05 +0200 From: Oleksij Rempel To: Andrew Lunn , Heiner Kallweit , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Jonathan Corbet Cc: Oleksij Rempel , kernel@pengutronix.de, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, Russell King Subject: [PATCH net-next v3 3/3] phy: dp83td510: Utilize ALCD for cable length measurement when link is active Date: Thu, 22 Aug 2024 14:07:03 +0200 Message-Id: <20240822120703.1393130-4-o.rempel@pengutronix.de> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240822120703.1393130-1-o.rempel@pengutronix.de> References: <20240822120703.1393130-1-o.rempel@pengutronix.de> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ore@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org In industrial environments where 10BaseT1L PHYs are replacing existing field bus systems like CAN, it's often essential to retain the existing cable infrastructure. After installation, collecting metrics such as cable length is crucial for assessing the quality of the infrastructure. Traditionally, TDR (Time Domain Reflectometry) is used for this purpose. However, TDR requires interrupting the link, and if the link partner remains active, the TDR measurement will fail. Unlike multi-pair systems, where TDR can be attempted during the MDI-X switching window, 10BaseT1L systems face greater challenges. The TDR sequence on 10BaseT1L is longer and coincides with uninterrupted autonegotiation pulses, making TDR impossible when the link partner is active. The DP83TD510 PHY provides an alternative through ALCD (Active Link Cable Diagnostics), which allows for cable length measurement without disrupting an active link. Since a live link indicates no short or open cable states, ALCD can be used effectively to gather cable length information. Enhance the dp83td510 driver by: - Leveraging ALCD to measure cable length when the link is active. - Bypassing TDR when a link is detected, as ALCD provides the required information without disruption. Signed-off-by: Oleksij Rempel Reviewed-by: Andrew Lunn --- changes v3: - use alcd_test_active flag to signal ALCD mode --- drivers/net/phy/dp83td510.c | 119 ++++++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/dp83td510.c b/drivers/net/phy/dp83td510.c index 551e37786c2da..92aa3a2b9744c 100644 --- a/drivers/net/phy/dp83td510.c +++ b/drivers/net/phy/dp83td510.c @@ -58,6 +58,10 @@ static const u16 dp83td510_mse_sqi_map[] = { 0x0000 /* 24dB =< SNR */ }; +struct dp83td510_priv { + bool alcd_test_active; +}; + /* Time Domain Reflectometry (TDR) Functionality of DP83TD510 PHY * * I assume that this PHY is using a variation of Spread Spectrum Time Domain @@ -169,6 +173,10 @@ static const u16 dp83td510_mse_sqi_map[] = { #define DP83TD510E_UNKN_030E 0x30e #define DP83TD510E_030E_VAL 0x2520 +#define DP83TD510E_ALCD_STAT 0xa9f +#define DP83TD510E_ALCD_COMPLETE BIT(15) +#define DP83TD510E_ALCD_CABLE_LENGTH GENMASK(10, 0) + static int dp83td510_config_intr(struct phy_device *phydev) { int ret; @@ -325,8 +333,23 @@ static int dp83td510_get_sqi_max(struct phy_device *phydev) */ static int dp83td510_cable_test_start(struct phy_device *phydev) { + struct dp83td510_priv *priv = phydev->priv; int ret; + /* If link partner is active, we won't be able to use TDR, since + * we can't force link partner to be silent. The autonegotiation + * pulses will be too frequent and the TDR sequence will be + * too long. So, TDR will always fail. Since the link is established + * we already know that the cable is working, so we can get some + * extra information line the cable length using ALCD. + */ + if (phydev->link) { + priv->alcd_test_active = true; + return 0; + } + + priv->alcd_test_active = false; + ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_CTRL, DP83TD510E_CTRL_HW_RESET); if (ret) @@ -402,8 +425,8 @@ static int dp83td510_cable_test_start(struct phy_device *phydev) } /** - * dp83td510_cable_test_get_status - Get the status of the cable test for the - * DP83TD510 PHY. + * dp83td510_cable_test_get_tdr_status - Get the status of the TDR test for the + * DP83TD510 PHY. * @phydev: Pointer to the phy_device structure. * @finished: Pointer to a boolean that indicates whether the test is finished. * @@ -411,13 +434,11 @@ static int dp83td510_cable_test_start(struct phy_device *phydev) * * Returns: 0 on success or a negative error code on failure. */ -static int dp83td510_cable_test_get_status(struct phy_device *phydev, - bool *finished) +static int dp83td510_cable_test_get_tdr_status(struct phy_device *phydev, + bool *finished) { int ret, stat; - *finished = false; - ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_TDR_CFG); if (ret < 0) return ret; @@ -459,6 +480,77 @@ static int dp83td510_cable_test_get_status(struct phy_device *phydev, return phy_init_hw(phydev); } +/** + * dp83td510_cable_test_get_alcd_status - Get the status of the ALCD test for the + * DP83TD510 PHY. + * @phydev: Pointer to the phy_device structure. + * @finished: Pointer to a boolean that indicates whether the test is finished. + * + * The function sets the @finished flag to true if the test is complete. + * The function reads the cable length and reports it to the user. + * + * Returns: 0 on success or a negative error code on failure. + */ +static int dp83td510_cable_test_get_alcd_status(struct phy_device *phydev, + bool *finished) +{ + unsigned int location; + int ret, phy_sts; + + phy_sts = phy_read(phydev, DP83TD510E_PHY_STS); + + if (!(phy_sts & DP83TD510E_LINK_STATUS)) { + /* If the link is down, we can't do any thing usable now */ + ethnl_cable_test_result_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A, + ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC, + ETHTOOL_A_CABLE_INF_SRC_ALCD); + *finished = true; + return 0; + } + + ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TD510E_ALCD_STAT); + if (ret < 0) + return ret; + + if (!(ret & DP83TD510E_ALCD_COMPLETE)) + return 0; + + location = FIELD_GET(DP83TD510E_ALCD_CABLE_LENGTH, ret) * 100; + + ethnl_cable_test_fault_length_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A, + location, + ETHTOOL_A_CABLE_INF_SRC_ALCD); + + ethnl_cable_test_result_with_src(phydev, ETHTOOL_A_CABLE_PAIR_A, + ETHTOOL_A_CABLE_RESULT_CODE_OK, + ETHTOOL_A_CABLE_INF_SRC_ALCD); + *finished = true; + + return 0; +} + +/** + * dp83td510_cable_test_get_status - Get the status of the cable test for the + * DP83TD510 PHY. + * @phydev: Pointer to the phy_device structure. + * @finished: Pointer to a boolean that indicates whether the test is finished. + * + * The function sets the @finished flag to true if the test is complete. + * + * Returns: 0 on success or a negative error code on failure. + */ +static int dp83td510_cable_test_get_status(struct phy_device *phydev, + bool *finished) +{ + struct dp83td510_priv *priv = phydev->priv; + *finished = false; + + if (priv->alcd_test_active) + return dp83td510_cable_test_get_alcd_status(phydev, finished); + + return dp83td510_cable_test_get_tdr_status(phydev, finished); +} + static int dp83td510_get_features(struct phy_device *phydev) { /* This PHY can't respond on MDIO bus if no RMII clock is enabled. @@ -477,12 +569,27 @@ static int dp83td510_get_features(struct phy_device *phydev) return 0; } +static int dp83td510_probe(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + struct dp83td510_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + return 0; +} + static struct phy_driver dp83td510_driver[] = { { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID), .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,