mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
net: phy: phy-c45: add OATC14 10BASE-T1S PHY cable diagnostic support
Add support for Open Alliance TC14 (OATC14) 10BASE-T1S PHYs cable diagnostic feature. This patch implements: - genphy_c45_oatc14_cable_test_start() to initiate a cable test - genphy_c45_oatc14_cable_test_get_status() to retrieve test results - Helper function to map PHY cable test status to ethtool result codes - Function declarations and exports for use by PHY drivers This enables ethtool to report ok, open, short, and undetectable cable conditions on OATC14 10Base-T1S PHYs. Open Alliance TC14 10BASE-T1S Advanced Diagnostic PHY Features Specification ref: https://opensig.org/wp-content/uploads/2025/06/OPEN_Alliance_10BASE-T1S_Advanced_PHY_features_for-automotive_Ethernet_V2.1b.pdf Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com> Link: https://patch.msgid.link/20251105051213.50443-2-parthiban.veerasooran@microchip.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
140039580e
commit
b87ee13e34
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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 PHY’s 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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user