1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83TD510 PHY
3 * Copyright (c) 2022 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
6 #include <linux/bitfield.h>
7 #include <linux/ethtool_netlink.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/phy.h>
12 #define DP83TD510E_PHY_ID 0x20000181
14 /* MDIO_MMD_VEND2 registers */
15 #define DP83TD510E_PHY_STS 0x10
16 /* Bit 7 - mii_interrupt, active high. Clears on read.
17 * Note: Clearing does not necessarily deactivate IRQ pin if interrupts pending.
18 * This differs from the DP83TD510E datasheet (2020) which states this bit
21 #define DP83TD510E_STS_MII_INT BIT(7)
22 #define DP83TD510E_LINK_STATUS BIT(0)
24 #define DP83TD510E_GEN_CFG 0x11
25 #define DP83TD510E_GENCFG_INT_POLARITY BIT(3)
26 #define DP83TD510E_GENCFG_INT_EN BIT(1)
27 #define DP83TD510E_GENCFG_INT_OE BIT(0)
29 #define DP83TD510E_INTERRUPT_REG_1 0x12
30 #define DP83TD510E_INT1_LINK BIT(13)
31 #define DP83TD510E_INT1_LINK_EN BIT(5)
33 #define DP83TD510E_CTRL 0x1f
34 #define DP83TD510E_CTRL_HW_RESET BIT(15)
35 #define DP83TD510E_CTRL_SW_RESET BIT(14)
37 #define DP83TD510E_AN_STAT_1 0x60c
38 #define DP83TD510E_MASTER_SLAVE_RESOL_FAIL BIT(15)
40 #define DP83TD510E_MSE_DETECT 0xa85
42 #define DP83TD510_SQI_MAX 7
44 /* Register values are converted to SNR(dB) as suggested by
45 * "Application Report - DP83TD510E Cable Diagnostics Toolkit":
46 * SNR(dB) = -10 * log10 (VAL/2^17) - 1.76 dB.
47 * SQI ranges are implemented according to "OPEN ALLIANCE - Advanced diagnostic
48 * features for 100BASE-T1 automotive Ethernet PHYs"
50 static const u16 dp83td510_mse_sqi_map
[] = {
52 0x044c, /* 18dB =< SNR < 19dB */
53 0x0369, /* 19dB =< SNR < 20dB */
54 0x02b6, /* 20dB =< SNR < 21dB */
55 0x0227, /* 21dB =< SNR < 22dB */
56 0x01b6, /* 22dB =< SNR < 23dB */
57 0x015b, /* 23dB =< SNR < 24dB */
58 0x0000 /* 24dB =< SNR */
61 struct dp83td510_priv
{
62 bool alcd_test_active
;
65 /* Time Domain Reflectometry (TDR) Functionality of DP83TD510 PHY
67 * I assume that this PHY is using a variation of Spread Spectrum Time Domain
68 * Reflectometry (SSTDR) rather than the commonly used TDR found in many PHYs.
69 * Here are the following observations which likely confirm this:
70 * - The DP83TD510 PHY transmits a modulated signal of configurable length
71 * (default 16000 µs) instead of a single pulse pattern, which is typical
72 * for traditional TDR.
73 * - The pulse observed on the wire, triggered by the HW RESET register, is not
74 * part of the cable testing process.
76 * I assume that SSTDR seems to be a logical choice for the 10BaseT1L
77 * environment due to improved noise resistance, making it suitable for
78 * environments with significant electrical noise, such as long 10BaseT1L cable
81 * Configuration Variables:
82 * The SSTDR variation used in this PHY involves more configuration variables
83 * that can dramatically affect the functionality and precision of cable
84 * testing. Since most of these configuration options are either not well
85 * documented or documented with minimal details, the following sections
86 * describe my understanding and observations of these variables and their
87 * impact on TDR functionality.
90 * ,<--cfg_pre_silence_time
91 * | ,<-SSTDR Modulated Transmission
92 * | | ,<--cfg_post_silence_time
93 * | | | ,<--Force Link Mode
94 * |<--'-->|<-------'------->|<--'-->|<--------'------->|
96 * - cfg_pre_silence_time: Optional silence time before TDR transmission starts.
97 * - SSTDR Modulated Transmission: Transmission duration configured by
98 * cfg_tdr_tx_duration and amplitude configured by cfg_tdr_tx_type.
99 * - cfg_post_silence_time: Silence time after TDR transmission.
100 * - Force Link Mode: If nothing is configured after cfg_post_silence_time,
101 * the PHY continues in force link mode without autonegotiation.
104 #define DP83TD510E_TDR_CFG 0x1e
105 #define DP83TD510E_TDR_START BIT(15)
106 #define DP83TD510E_TDR_DONE BIT(1)
107 #define DP83TD510E_TDR_FAIL BIT(0)
109 #define DP83TD510E_TDR_CFG1 0x300
110 /* cfg_tdr_tx_type: Transmit voltage level for TDR.
112 * Note: Using different voltage levels may not work
113 * in all configuration variations. For example, setting
114 * 2.4V may give different cable length measurements.
115 * Other settings may be needed to make it work properly.
117 #define DP83TD510E_TDR_TX_TYPE BIT(12)
118 #define DP83TD510E_TDR_TX_TYPE_1V 0
119 #define DP83TD510E_TDR_TX_TYPE_2_4V 1
120 /* cfg_post_silence_time: Time after the TDR sequence. Since we force master mode
121 * for the TDR will proceed with forced link state after this time. For Linux
122 * it is better to set max value to avoid false link state detection.
124 #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME GENMASK(3, 2)
125 #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_0MS 0
126 #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_10MS 1
127 #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_100MS 2
128 #define DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_1000MS 3
129 /* cfg_pre_silence_time: Time before the TDR sequence. It should be enough to
130 * settle down all pulses and reflections. Since for 10BASE-T1L we have
131 * maximum 2000m cable length, we can set it to 1ms.
133 #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME GENMASK(1, 0)
134 #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_0MS 0
135 #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_10MS 1
136 #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_100MS 2
137 #define DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_1000MS 3
139 #define DP83TD510E_TDR_CFG2 0x301
140 #define DP83TD510E_TDR_END_TAP_INDEX_1 GENMASK(14, 8)
141 #define DP83TD510E_TDR_END_TAP_INDEX_1_DEF 36
142 #define DP83TD510E_TDR_START_TAP_INDEX_1 GENMASK(6, 0)
143 #define DP83TD510E_TDR_START_TAP_INDEX_1_DEF 4
145 #define DP83TD510E_TDR_CFG3 0x302
146 /* cfg_tdr_tx_duration: Duration of the TDR transmission in microseconds.
147 * This value sets the duration of the modulated signal used for TDR
149 * - Default: 16000 µs
150 * - Observation: A minimum duration of 6000 µs is recommended to ensure
151 * accurate detection of cable faults. Durations shorter than 6000 µs may
152 * result in incomplete data, especially for shorter cables (e.g., 20 meters),
153 * leading to false "OK" results. Longer durations (e.g., 6000 µs or more)
154 * provide better accuracy, particularly for detecting open circuits.
156 #define DP83TD510E_TDR_TX_DURATION_US GENMASK(15, 0)
157 #define DP83TD510E_TDR_TX_DURATION_US_DEF 16000
159 #define DP83TD510E_TDR_FAULT_CFG1 0x303
160 #define DP83TD510E_TDR_FLT_LOC_OFFSET_1 GENMASK(14, 8)
161 #define DP83TD510E_TDR_FLT_LOC_OFFSET_1_DEF 4
162 #define DP83TD510E_TDR_FLT_INIT_1 GENMASK(7, 0)
163 #define DP83TD510E_TDR_FLT_INIT_1_DEF 62
165 #define DP83TD510E_TDR_FAULT_STAT 0x30c
166 #define DP83TD510E_TDR_PEAK_DETECT BIT(11)
167 #define DP83TD510E_TDR_PEAK_SIGN BIT(10)
168 #define DP83TD510E_TDR_PEAK_LOCATION GENMASK(9, 0)
170 /* Not documented registers and values but recommended according to
171 * "DP83TD510E Cable Diagnostics Toolkit revC"
173 #define DP83TD510E_UNKN_030E 0x30e
174 #define DP83TD510E_030E_VAL 0x2520
176 #define DP83TD510E_ALCD_STAT 0xa9f
177 #define DP83TD510E_ALCD_COMPLETE BIT(15)
178 #define DP83TD510E_ALCD_CABLE_LENGTH GENMASK(10, 0)
180 static int dp83td510_config_intr(struct phy_device
*phydev
)
184 if (phydev
->interrupts
== PHY_INTERRUPT_ENABLED
) {
185 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
,
186 DP83TD510E_INTERRUPT_REG_1
,
187 DP83TD510E_INT1_LINK_EN
);
191 ret
= phy_set_bits_mmd(phydev
, MDIO_MMD_VEND2
,
193 DP83TD510E_GENCFG_INT_POLARITY
|
194 DP83TD510E_GENCFG_INT_EN
|
195 DP83TD510E_GENCFG_INT_OE
);
197 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
,
198 DP83TD510E_INTERRUPT_REG_1
, 0x0);
202 ret
= phy_clear_bits_mmd(phydev
, MDIO_MMD_VEND2
,
204 DP83TD510E_GENCFG_INT_EN
);
212 static irqreturn_t
dp83td510_handle_interrupt(struct phy_device
*phydev
)
216 /* Read the current enabled interrupts */
217 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_INTERRUPT_REG_1
);
221 } else if (!(ret
& DP83TD510E_INT1_LINK_EN
) ||
222 !(ret
& DP83TD510E_INT1_LINK
)) {
226 phy_trigger_machine(phydev
);
231 static int dp83td510_read_status(struct phy_device
*phydev
)
236 phydev
->speed
= SPEED_UNKNOWN
;
237 phydev
->duplex
= DUPLEX_UNKNOWN
;
239 phydev
->asym_pause
= 0;
240 linkmode_zero(phydev
->lp_advertising
);
242 phy_sts
= phy_read(phydev
, DP83TD510E_PHY_STS
);
244 phydev
->link
= !!(phy_sts
& DP83TD510E_LINK_STATUS
);
246 /* This PHY supports only one link mode: 10BaseT1L_Full */
247 phydev
->duplex
= DUPLEX_FULL
;
248 phydev
->speed
= SPEED_10
;
250 if (phydev
->autoneg
== AUTONEG_ENABLE
) {
251 ret
= genphy_c45_read_lpa(phydev
);
255 phy_resolve_aneg_linkmode(phydev
);
259 if (phydev
->autoneg
== AUTONEG_ENABLE
) {
260 ret
= genphy_c45_baset1_read_status(phydev
);
264 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
,
265 DP83TD510E_AN_STAT_1
);
269 if (ret
& DP83TD510E_MASTER_SLAVE_RESOL_FAIL
)
270 phydev
->master_slave_state
= MASTER_SLAVE_STATE_ERR
;
272 return genphy_c45_pma_baset1_read_master_slave(phydev
);
278 static int dp83td510_config_aneg(struct phy_device
*phydev
)
280 bool changed
= false;
283 ret
= genphy_c45_pma_baset1_setup_master_slave(phydev
);
287 if (phydev
->autoneg
== AUTONEG_DISABLE
)
288 return genphy_c45_an_disable_aneg(phydev
);
290 ret
= genphy_c45_an_config_aneg(phydev
);
296 return genphy_c45_check_and_restart_aneg(phydev
, changed
);
299 static int dp83td510_get_sqi(struct phy_device
*phydev
)
307 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_MSE_DETECT
);
311 mse_val
= 0xFFFF & ret
;
312 for (sqi
= 0; sqi
< ARRAY_SIZE(dp83td510_mse_sqi_map
); sqi
++) {
313 if (mse_val
>= dp83td510_mse_sqi_map
[sqi
])
320 static int dp83td510_get_sqi_max(struct phy_device
*phydev
)
322 return DP83TD510_SQI_MAX
;
326 * dp83td510_cable_test_start - Start the cable test for the DP83TD510 PHY.
327 * @phydev: Pointer to the phy_device structure.
329 * This sequence is implemented according to the "Application Note DP83TD510E
330 * Cable Diagnostics Toolkit revC".
332 * Returns: 0 on success, a negative error code on failure.
334 static int dp83td510_cable_test_start(struct phy_device
*phydev
)
336 struct dp83td510_priv
*priv
= phydev
->priv
;
339 /* If link partner is active, we won't be able to use TDR, since
340 * we can't force link partner to be silent. The autonegotiation
341 * pulses will be too frequent and the TDR sequence will be
342 * too long. So, TDR will always fail. Since the link is established
343 * we already know that the cable is working, so we can get some
344 * extra information line the cable length using ALCD.
347 priv
->alcd_test_active
= true;
351 priv
->alcd_test_active
= false;
353 ret
= phy_set_bits_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_CTRL
,
354 DP83TD510E_CTRL_HW_RESET
);
358 ret
= genphy_c45_an_disable_aneg(phydev
);
362 /* Force master mode */
363 ret
= phy_set_bits_mmd(phydev
, MDIO_MMD_PMAPMD
, MDIO_PMA_PMD_BT1_CTRL
,
364 MDIO_PMA_PMD_BT1_CTRL_CFG_MST
);
368 /* There is no official recommendation for this register, but it is
369 * better to use 1V for TDR since other values seems to be optimized
370 * for this amplitude. Except of amplitude, it is better to configure
371 * pre TDR silence time to 10ms to avoid false reflections (value 0
372 * seems to be too short, otherwise we need to implement own silence
373 * time). Also, post TDR silence time should be set to 1000ms to avoid
374 * false link state detection, it fits to the polling time of the
375 * PHY framework. The idea is to wait until
376 * dp83td510_cable_test_get_status() will be called and reconfigure
377 * the PHY to the default state within the post silence time window.
379 ret
= phy_modify_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_CFG1
,
380 DP83TD510E_TDR_TX_TYPE
|
381 DP83TD510E_TDR_CFG1_POST_SILENCE_TIME
|
382 DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME
,
383 DP83TD510E_TDR_TX_TYPE_1V
|
384 DP83TD510E_TDR_CFG1_PRE_SILENCE_TIME_10MS
|
385 DP83TD510E_TDR_CFG1_POST_SILENCE_TIME_1000MS
);
389 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_CFG2
,
390 FIELD_PREP(DP83TD510E_TDR_END_TAP_INDEX_1
,
391 DP83TD510E_TDR_END_TAP_INDEX_1_DEF
) |
392 FIELD_PREP(DP83TD510E_TDR_START_TAP_INDEX_1
,
393 DP83TD510E_TDR_START_TAP_INDEX_1_DEF
));
397 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_FAULT_CFG1
,
398 FIELD_PREP(DP83TD510E_TDR_FLT_LOC_OFFSET_1
,
399 DP83TD510E_TDR_FLT_LOC_OFFSET_1_DEF
) |
400 FIELD_PREP(DP83TD510E_TDR_FLT_INIT_1
,
401 DP83TD510E_TDR_FLT_INIT_1_DEF
));
405 /* Undocumented register, from the "Application Note DP83TD510E Cable
406 * Diagnostics Toolkit revC".
408 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_UNKN_030E
,
409 DP83TD510E_030E_VAL
);
413 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_CFG3
,
414 DP83TD510E_TDR_TX_DURATION_US_DEF
);
418 ret
= phy_set_bits_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_CTRL
,
419 DP83TD510E_CTRL_SW_RESET
);
423 return phy_set_bits_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_CFG
,
424 DP83TD510E_TDR_START
);
428 * dp83td510_cable_test_get_tdr_status - Get the status of the TDR test for the
430 * @phydev: Pointer to the phy_device structure.
431 * @finished: Pointer to a boolean that indicates whether the test is finished.
433 * The function sets the @finished flag to true if the test is complete.
435 * Returns: 0 on success or a negative error code on failure.
437 static int dp83td510_cable_test_get_tdr_status(struct phy_device
*phydev
,
442 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_TDR_CFG
);
446 if (!(ret
& DP83TD510E_TDR_DONE
))
449 if (!(ret
& DP83TD510E_TDR_FAIL
)) {
452 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
,
453 DP83TD510E_TDR_FAULT_STAT
);
457 if (ret
& DP83TD510E_TDR_PEAK_DETECT
) {
458 if (ret
& DP83TD510E_TDR_PEAK_SIGN
)
459 stat
= ETHTOOL_A_CABLE_RESULT_CODE_OPEN
;
461 stat
= ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT
;
463 location
= FIELD_GET(DP83TD510E_TDR_PEAK_LOCATION
,
465 ethnl_cable_test_fault_length(phydev
,
466 ETHTOOL_A_CABLE_PAIR_A
,
469 stat
= ETHTOOL_A_CABLE_RESULT_CODE_OK
;
472 /* Most probably we have active link partner */
473 stat
= ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC
;
478 ethnl_cable_test_result(phydev
, ETHTOOL_A_CABLE_PAIR_A
, stat
);
480 return phy_init_hw(phydev
);
484 * dp83td510_cable_test_get_alcd_status - Get the status of the ALCD test for the
486 * @phydev: Pointer to the phy_device structure.
487 * @finished: Pointer to a boolean that indicates whether the test is finished.
489 * The function sets the @finished flag to true if the test is complete.
490 * The function reads the cable length and reports it to the user.
492 * Returns: 0 on success or a negative error code on failure.
494 static int dp83td510_cable_test_get_alcd_status(struct phy_device
*phydev
,
497 unsigned int location
;
500 phy_sts
= phy_read(phydev
, DP83TD510E_PHY_STS
);
502 if (!(phy_sts
& DP83TD510E_LINK_STATUS
)) {
503 /* If the link is down, we can't do any thing usable now */
504 ethnl_cable_test_result_with_src(phydev
, ETHTOOL_A_CABLE_PAIR_A
,
505 ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC
,
506 ETHTOOL_A_CABLE_INF_SRC_ALCD
);
511 ret
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
, DP83TD510E_ALCD_STAT
);
515 if (!(ret
& DP83TD510E_ALCD_COMPLETE
))
518 location
= FIELD_GET(DP83TD510E_ALCD_CABLE_LENGTH
, ret
) * 100;
520 ethnl_cable_test_fault_length_with_src(phydev
, ETHTOOL_A_CABLE_PAIR_A
,
522 ETHTOOL_A_CABLE_INF_SRC_ALCD
);
524 ethnl_cable_test_result_with_src(phydev
, ETHTOOL_A_CABLE_PAIR_A
,
525 ETHTOOL_A_CABLE_RESULT_CODE_OK
,
526 ETHTOOL_A_CABLE_INF_SRC_ALCD
);
533 * dp83td510_cable_test_get_status - Get the status of the cable test for the
535 * @phydev: Pointer to the phy_device structure.
536 * @finished: Pointer to a boolean that indicates whether the test is finished.
538 * The function sets the @finished flag to true if the test is complete.
540 * Returns: 0 on success or a negative error code on failure.
542 static int dp83td510_cable_test_get_status(struct phy_device
*phydev
,
545 struct dp83td510_priv
*priv
= phydev
->priv
;
548 if (priv
->alcd_test_active
)
549 return dp83td510_cable_test_get_alcd_status(phydev
, finished
);
551 return dp83td510_cable_test_get_tdr_status(phydev
, finished
);
554 static int dp83td510_get_features(struct phy_device
*phydev
)
556 /* This PHY can't respond on MDIO bus if no RMII clock is enabled.
557 * In case RMII mode is used (most meaningful mode for this PHY) and
558 * the PHY do not have own XTAL, and CLK providing MAC is not probed,
559 * we won't be able to read all needed ability registers.
560 * So provide it manually.
563 linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT
, phydev
->supported
);
564 linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT
, phydev
->supported
);
565 linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT
, phydev
->supported
);
566 linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT1L_Full_BIT
,
572 static int dp83td510_probe(struct phy_device
*phydev
)
574 struct device
*dev
= &phydev
->mdio
.dev
;
575 struct dp83td510_priv
*priv
;
577 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
586 static struct phy_driver dp83td510_driver
[] = {
588 PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID
),
589 .name
= "TI DP83TD510E",
591 .flags
= PHY_POLL_CABLE_TEST
,
592 .probe
= dp83td510_probe
,
593 .config_aneg
= dp83td510_config_aneg
,
594 .read_status
= dp83td510_read_status
,
595 .get_features
= dp83td510_get_features
,
596 .config_intr
= dp83td510_config_intr
,
597 .handle_interrupt
= dp83td510_handle_interrupt
,
598 .get_sqi
= dp83td510_get_sqi
,
599 .get_sqi_max
= dp83td510_get_sqi_max
,
600 .cable_test_start
= dp83td510_cable_test_start
,
601 .cable_test_get_status
= dp83td510_cable_test_get_status
,
603 .suspend
= genphy_suspend
,
604 .resume
= genphy_resume
,
606 module_phy_driver(dp83td510_driver
);
608 static struct mdio_device_id __maybe_unused dp83td510_tbl
[] = {
609 { PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID
) },
612 MODULE_DEVICE_TABLE(mdio
, dp83td510_tbl
);
614 MODULE_DESCRIPTION("Texas Instruments DP83TD510E PHY driver");
615 MODULE_AUTHOR("Oleksij Rempel <kernel@pengutronix.de>");
616 MODULE_LICENSE("GPL v2");