1
0

Merge branch 'net-phy-add-open-alliance-tc14-10base-t1s-phy-cable-diagnostic-support'

Parthiban Veerasooran says:

====================
net: phy: Add Open Alliance TC14 10Base-T1S PHY cable diagnostic support

This patch series adds Open Alliance TC14 (OATC14) 10BASE-T1S cable
diagnostic feature support to the Linux kernel PHY subsystem and enable
this feature for Microchip LAN867x Rev.D0 PHYs. These patches provide
standardized cable test functionality for 10BASE-T1S Ethernet PHYs,
allowing users to perform cable diagnostics via ethtool.

Patch Summary:
1. add OATC14 10BASE-T1S PHY cable diagnostic support
	- Implements support for the OATC14 cable diagnostic feature in
	  Clause 45 PHYs.
	- Adds functions to start a cable test and retrieve its status,
	  mapping hardware results to ethtool codes.
	- Exports these functions for use by PHY drivers.
	- Open Alliance TC14 10BASE-T1S Advanced Diagnostic PHY Features.
	  https://opensig.org/wp-content/uploads/2025/06/OPEN_Alliance_10BASE-T1S_Advanced_PHY_features_for-automotive_Ethernet_V2.1b.pdf

2. add cable diagnostic support for LAN867x Rev.D0
	- Integrates the generic OATC14 cable test functions into the
	  Microchip LAN867x Rev.D0 PHY driver.
	- Enables ethtool cable diagnostics for this PHY, improving
	  troubleshooting and maintenance.
====================

Link: https://patch.msgid.link/20251105051213.50443-1-parthiban.veerasooran@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2025-11-07 18:52:36 -08:00
4 changed files with 163 additions and 0 deletions

View File

@@ -43,4 +43,40 @@
/* Version Identifiers */
#define OATC14_IDM 0x0a00
/*
* Open Alliance TC14 (10BASE-T1S) - Advanced Diagnostic Features Registers
*
* Refer to the OPEN Alliance documentation:
* https://opensig.org/automotive-ethernet-specifications/
*
* Specification:
* "10BASE-T1S Advanced Diagnostic PHY Features"
* https://opensig.org/wp-content/uploads/2025/06/OPEN_Alliance_10BASE-T1S_Advanced_PHY_features_for-automotive_Ethernet_V2.1b.pdf
*/
/* Advanced Diagnostic Features Capability Register*/
#define MDIO_OATC14_ADFCAP 0xcc00
#define OATC14_ADFCAP_HDD_CAPABILITY GENMASK(10, 8)
/* Harness Defect Detection Register */
#define MDIO_OATC14_HDD 0xcc01
#define OATC14_HDD_CONTROL BIT(15)
#define OATC14_HDD_READY BIT(14)
#define OATC14_HDD_START_CONTROL BIT(13)
#define OATC14_HDD_VALID BIT(2)
#define OATC14_HDD_SHORT_OPEN_STATUS GENMASK(1, 0)
/* Bus Short/Open Status:
* 0 0 - no fault; everything is ok. (Default)
* 0 1 - detected as an open or missing termination(s)
* 1 0 - detected as a short or extra termination(s)
* 1 1 - fault but fault type not detectable. More details can be available by
* vender specific register if supported.
*/
enum oatc14_hdd_status {
OATC14_HDD_STATUS_CABLE_OK = 0,
OATC14_HDD_STATUS_OPEN,
OATC14_HDD_STATUS_SHORT,
OATC14_HDD_STATUS_NOT_DETECTABLE,
};
#endif /* __MDIO_OPEN_ALLIANCE__ */

View File

@@ -573,6 +573,8 @@ static struct phy_driver microchip_t1s_driver[] = {
.get_plca_cfg = genphy_c45_plca_get_cfg,
.set_plca_cfg = lan86xx_plca_set_cfg,
.get_plca_status = genphy_c45_plca_get_status,
.cable_test_start = genphy_c45_oatc14_cable_test_start,
.cable_test_get_status = genphy_c45_oatc14_cable_test_get_status,
},
{
PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB),

View File

@@ -7,6 +7,7 @@
#include <linux/mdio.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/ethtool_netlink.h>
#include "mdio-open-alliance.h"
#include "phylib-internal.h"
@@ -1573,3 +1574,124 @@ int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
return ret;
}
EXPORT_SYMBOL(genphy_c45_ethtool_set_eee);
/**
* oatc14_cable_test_get_result_code - Convert hardware cable test status to
* ethtool result code.
* @status: The hardware-reported cable test status
*
* This helper function maps the OATC14 HDD cable test status to the
* corresponding ethtool cable test result code. It provides a translation
* between the device-specific status values and the standardized ethtool
* result codes.
*
* Return:
* * ETHTOOL_A_CABLE_RESULT_CODE_OK - Cable is OK
* * ETHTOOL_A_CABLE_RESULT_CODE_OPEN - Open circuit detected
* * ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT - Short circuit detected
* * ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC - Status not detectable or invalid
*/
static int oatc14_cable_test_get_result_code(enum oatc14_hdd_status status)
{
switch (status) {
case OATC14_HDD_STATUS_CABLE_OK:
return ETHTOOL_A_CABLE_RESULT_CODE_OK;
case OATC14_HDD_STATUS_OPEN:
return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
case OATC14_HDD_STATUS_SHORT:
return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
case OATC14_HDD_STATUS_NOT_DETECTABLE:
default:
return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
}
}
/**
* genphy_c45_oatc14_cable_test_get_status - Get status of OATC14 10Base-T1S
* PHY cable test.
* @phydev: pointer to the PHY device structure
* @finished: pointer to a boolean set true if the test is complete
*
* Retrieves the current status of the OATC14 10Base-T1S PHY cable test.
* This function reads the OATC14 HDD register to determine whether the test
* results are valid and whether the test has finished.
*
* If the test is complete, the function reports the cable test result via
* the ethtool cable test interface using ethnl_cable_test_result(), and then
* clears the test control bit in the PHY register to reset the test state.
*
* Return: 0 on success, or a negative error code on failure (e.g. register
* read/write error).
*/
int genphy_c45_oatc14_cable_test_get_status(struct phy_device *phydev,
bool *finished)
{
int ret;
u8 sts;
*finished = false;
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_HDD);
if (ret < 0)
return ret;
if (!(ret & OATC14_HDD_VALID))
return 0;
*finished = true;
sts = FIELD_GET(OATC14_HDD_SHORT_OPEN_STATUS, ret);
ret = ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
oatc14_cable_test_get_result_code(sts));
if (ret)
return ret;
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
MDIO_OATC14_HDD, OATC14_HDD_CONTROL);
}
EXPORT_SYMBOL(genphy_c45_oatc14_cable_test_get_status);
/**
* genphy_c45_oatc14_cable_test_start - Start a cable test on an OATC14
* 10Base-T1S PHY.
* @phydev: Pointer to the PHY device structure
*
* This function initiates a cable diagnostic test on a Clause 45 OATC14
* 10Base-T1S capable PHY device. It first reads the PHYs advanced diagnostic
* capability register to check if High Definition Diagnostics (HDD) mode is
* supported. If the PHY does not report HDD capability, cable testing is not
* supported and the function returns -EOPNOTSUPP.
*
* For PHYs that support HDD, the function sets the appropriate control bits in
* the OATC14_HDD register to enable and start the cable diagnostic test.
*
* Return:
* * 0 on success
* * -EOPNOTSUPP if the PHY does not support HDD capability
* * A negative error code on I/O or register access failures
*/
int genphy_c45_oatc14_cable_test_start(struct phy_device *phydev)
{
int ret;
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_ADFCAP);
if (ret < 0)
return ret;
if (!(ret & OATC14_ADFCAP_HDD_CAPABILITY))
return -EOPNOTSUPP;
ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_HDD,
OATC14_HDD_CONTROL);
if (ret)
return ret;
ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_HDD);
if (ret < 0)
return ret;
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_HDD,
OATC14_HDD_START_CONTROL);
}
EXPORT_SYMBOL(genphy_c45_oatc14_cable_test_start);

View File

@@ -2251,6 +2251,9 @@ int genphy_c45_ethtool_get_eee(struct phy_device *phydev,
int genphy_c45_ethtool_set_eee(struct phy_device *phydev,
struct ethtool_keee *data);
int genphy_c45_an_config_eee_aneg(struct phy_device *phydev);
int genphy_c45_oatc14_cable_test_start(struct phy_device *phydev);
int genphy_c45_oatc14_cable_test_get_status(struct phy_device *phydev,
bool *finished);
/* The gen10g_* functions are the old Clause 45 stub */
int gen10g_config_aneg(struct phy_device *phydev);