1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83TG720 PHY
3 * Copyright (c) 2023 Pengutronix, Oleksij Rempel <[email protected]>
4 */
5 #include <linux/bitfield.h>
6 #include <linux/ethtool_netlink.h>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/phy.h>
10
11 #include "open_alliance_helpers.h"
12
13 #define DP83TG720S_PHY_ID 0x2000a284
14
15 /* MDIO_MMD_VEND2 registers */
16 #define DP83TG720S_MII_REG_10 0x10
17 #define DP83TG720S_STS_MII_INT BIT(7)
18 #define DP83TG720S_LINK_STATUS BIT(0)
19
20 /* TDR Configuration Register (0x1E) */
21 #define DP83TG720S_TDR_CFG 0x1e
22 /* 1b = TDR start, 0b = No TDR */
23 #define DP83TG720S_TDR_START BIT(15)
24 /* 1b = TDR auto on link down, 0b = Manual TDR start */
25 #define DP83TG720S_CFG_TDR_AUTO_RUN BIT(14)
26 /* 1b = TDR done, 0b = TDR in progress */
27 #define DP83TG720S_TDR_DONE BIT(1)
28 /* 1b = TDR fail, 0b = TDR success */
29 #define DP83TG720S_TDR_FAIL BIT(0)
30
31 #define DP83TG720S_PHY_RESET 0x1f
32 #define DP83TG720S_HW_RESET BIT(15)
33
34 #define DP83TG720S_LPS_CFG3 0x18c
35 /* Power modes are documented as bit fields but used as values */
36 /* Power Mode 0 is Normal mode */
37 #define DP83TG720S_LPS_CFG3_PWR_MODE_0 BIT(0)
38
39 /* Open Aliance 1000BaseT1 compatible HDD.TDR Fault Status Register */
40 #define DP83TG720S_TDR_FAULT_STATUS 0x30f
41
42 /* Register 0x0301: TDR Configuration 2 */
43 #define DP83TG720S_TDR_CFG2 0x301
44
45 /* Register 0x0303: TDR Configuration 3 */
46 #define DP83TG720S_TDR_CFG3 0x303
47
48 /* Register 0x0304: TDR Configuration 4 */
49 #define DP83TG720S_TDR_CFG4 0x304
50
51 /* Register 0x0405: Unknown Register */
52 #define DP83TG720S_UNKNOWN_0405 0x405
53
54 #define DP83TG720S_LINK_QUAL_3 0x547
55 #define DP83TG720S_LINK_LOSS_CNT_MASK GENMASK(15, 10)
56
57 /* Register 0x0576: TDR Master Link Down Control */
58 #define DP83TG720S_TDR_MASTER_LINK_DOWN 0x576
59
60 #define DP83TG720S_RGMII_DELAY_CTRL 0x602
61 /* In RGMII mode, Enable or disable the internal delay for RXD */
62 #define DP83TG720S_RGMII_RX_CLK_SEL BIT(1)
63 /* In RGMII mode, Enable or disable the internal delay for TXD */
64 #define DP83TG720S_RGMII_TX_CLK_SEL BIT(0)
65
66 /*
67 * DP83TG720S_PKT_STAT_x registers correspond to similarly named registers
68 * in the datasheet (PKT_STAT_1 through PKT_STAT_6). These registers store
69 * 32-bit or 16-bit counters for TX and RX statistics and must be read in
70 * sequence to ensure the counters are cleared correctly.
71 *
72 * - DP83TG720S_PKT_STAT_1: Contains TX packet count bits [15:0].
73 * - DP83TG720S_PKT_STAT_2: Contains TX packet count bits [31:16].
74 * - DP83TG720S_PKT_STAT_3: Contains TX error packet count.
75 * - DP83TG720S_PKT_STAT_4: Contains RX packet count bits [15:0].
76 * - DP83TG720S_PKT_STAT_5: Contains RX packet count bits [31:16].
77 * - DP83TG720S_PKT_STAT_6: Contains RX error packet count.
78 *
79 * Keeping the register names as defined in the datasheet helps maintain
80 * clarity and alignment with the documentation.
81 */
82 #define DP83TG720S_PKT_STAT_1 0x639
83 #define DP83TG720S_PKT_STAT_2 0x63a
84 #define DP83TG720S_PKT_STAT_3 0x63b
85 #define DP83TG720S_PKT_STAT_4 0x63c
86 #define DP83TG720S_PKT_STAT_5 0x63d
87 #define DP83TG720S_PKT_STAT_6 0x63e
88
89 /* Register 0x083F: Unknown Register */
90 #define DP83TG720S_UNKNOWN_083F 0x83f
91
92 #define DP83TG720S_SQI_REG_1 0x871
93 #define DP83TG720S_SQI_OUT_WORST GENMASK(7, 5)
94 #define DP83TG720S_SQI_OUT GENMASK(3, 1)
95
96 #define DP83TG720_SQI_MAX 7
97
98 struct dp83tg720_stats {
99 u64 link_loss_cnt;
100 u64 tx_pkt_cnt;
101 u64 tx_err_pkt_cnt;
102 u64 rx_pkt_cnt;
103 u64 rx_err_pkt_cnt;
104 };
105
106 struct dp83tg720_priv {
107 struct dp83tg720_stats stats;
108 };
109
110 /**
111 * dp83tg720_update_stats - Update the PHY statistics for the DP83TD510 PHY.
112 * @phydev: Pointer to the phy_device structure.
113 *
114 * The function reads the PHY statistics registers and updates the statistics
115 * structure.
116 *
117 * Returns: 0 on success or a negative error code on failure.
118 */
dp83tg720_update_stats(struct phy_device * phydev)119 static int dp83tg720_update_stats(struct phy_device *phydev)
120 {
121 struct dp83tg720_priv *priv = phydev->priv;
122 u32 count;
123 int ret;
124
125 /* Read the link loss count */
126 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LINK_QUAL_3);
127 if (ret < 0)
128 return ret;
129 /* link_loss_cnt */
130 count = FIELD_GET(DP83TG720S_LINK_LOSS_CNT_MASK, ret);
131 priv->stats.link_loss_cnt += count;
132
133 /* The DP83TG720S_PKT_STAT registers are divided into two groups:
134 * - Group 1 (TX stats): DP83TG720S_PKT_STAT_1 to DP83TG720S_PKT_STAT_3
135 * - Group 2 (RX stats): DP83TG720S_PKT_STAT_4 to DP83TG720S_PKT_STAT_6
136 *
137 * Registers in each group are cleared only after reading them in a
138 * plain sequence (e.g., 1, 2, 3 for Group 1 or 4, 5, 6 for Group 2).
139 * Any deviation from the sequence, such as reading 1, 2, 1, 2, 3, will
140 * prevent the group from being cleared. Additionally, the counters
141 * for a group are frozen as soon as the first register in that group
142 * is accessed.
143 */
144 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_1);
145 if (ret < 0)
146 return ret;
147 /* tx_pkt_cnt_15_0 */
148 count = ret;
149
150 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_2);
151 if (ret < 0)
152 return ret;
153 /* tx_pkt_cnt_31_16 */
154 count |= ret << 16;
155 priv->stats.tx_pkt_cnt += count;
156
157 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_3);
158 if (ret < 0)
159 return ret;
160 /* tx_err_pkt_cnt */
161 priv->stats.tx_err_pkt_cnt += ret;
162
163 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_4);
164 if (ret < 0)
165 return ret;
166 /* rx_pkt_cnt_15_0 */
167 count = ret;
168
169 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_5);
170 if (ret < 0)
171 return ret;
172 /* rx_pkt_cnt_31_16 */
173 count |= ret << 16;
174 priv->stats.rx_pkt_cnt += count;
175
176 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_PKT_STAT_6);
177 if (ret < 0)
178 return ret;
179 /* rx_err_pkt_cnt */
180 priv->stats.rx_err_pkt_cnt += ret;
181
182 return 0;
183 }
184
dp83tg720_get_link_stats(struct phy_device * phydev,struct ethtool_link_ext_stats * link_stats)185 static void dp83tg720_get_link_stats(struct phy_device *phydev,
186 struct ethtool_link_ext_stats *link_stats)
187 {
188 struct dp83tg720_priv *priv = phydev->priv;
189
190 link_stats->link_down_events = priv->stats.link_loss_cnt;
191 }
192
dp83tg720_get_phy_stats(struct phy_device * phydev,struct ethtool_eth_phy_stats * eth_stats,struct ethtool_phy_stats * stats)193 static void dp83tg720_get_phy_stats(struct phy_device *phydev,
194 struct ethtool_eth_phy_stats *eth_stats,
195 struct ethtool_phy_stats *stats)
196 {
197 struct dp83tg720_priv *priv = phydev->priv;
198
199 stats->tx_packets = priv->stats.tx_pkt_cnt;
200 stats->tx_errors = priv->stats.tx_err_pkt_cnt;
201 stats->rx_packets = priv->stats.rx_pkt_cnt;
202 stats->rx_errors = priv->stats.rx_err_pkt_cnt;
203 }
204
205 /**
206 * dp83tg720_cable_test_start - Start the cable test for the DP83TG720 PHY.
207 * @phydev: Pointer to the phy_device structure.
208 *
209 * This sequence is based on the documented procedure for the DP83TG720 PHY.
210 *
211 * Returns: 0 on success, a negative error code on failure.
212 */
dp83tg720_cable_test_start(struct phy_device * phydev)213 static int dp83tg720_cable_test_start(struct phy_device *phydev)
214 {
215 int ret;
216
217 /* Initialize the PHY to run the TDR test as described in the
218 * "DP83TG720S-Q1: Configuring for Open Alliance Specification
219 * Compliance (Rev. B)" application note.
220 * Most of the registers are not documented. Some of register names
221 * are guessed by comparing the register offsets with the DP83TD510E.
222 */
223
224 /* Force master link down */
225 ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2,
226 DP83TG720S_TDR_MASTER_LINK_DOWN, 0x0400);
227 if (ret)
228 return ret;
229
230 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG2,
231 0xa008);
232 if (ret)
233 return ret;
234
235 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG3,
236 0x0928);
237 if (ret)
238 return ret;
239
240 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG4,
241 0x0004);
242 if (ret)
243 return ret;
244
245 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_UNKNOWN_0405,
246 0x6400);
247 if (ret)
248 return ret;
249
250 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_UNKNOWN_083F,
251 0x3003);
252 if (ret)
253 return ret;
254
255 /* Start the TDR */
256 ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG,
257 DP83TG720S_TDR_START);
258 if (ret)
259 return ret;
260
261 return 0;
262 }
263
264 /**
265 * dp83tg720_cable_test_get_status - Get the status of the cable test for the
266 * DP83TG720 PHY.
267 * @phydev: Pointer to the phy_device structure.
268 * @finished: Pointer to a boolean that indicates whether the test is finished.
269 *
270 * The function sets the @finished flag to true if the test is complete.
271 *
272 * Returns: 0 on success or a negative error code on failure.
273 */
dp83tg720_cable_test_get_status(struct phy_device * phydev,bool * finished)274 static int dp83tg720_cable_test_get_status(struct phy_device *phydev,
275 bool *finished)
276 {
277 int ret, stat;
278
279 *finished = false;
280
281 /* Read the TDR status */
282 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_TDR_CFG);
283 if (ret < 0)
284 return ret;
285
286 /* Check if the TDR test is done */
287 if (!(ret & DP83TG720S_TDR_DONE))
288 return 0;
289
290 /* Check for TDR test failure */
291 if (!(ret & DP83TG720S_TDR_FAIL)) {
292 int location;
293
294 /* Read fault status */
295 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2,
296 DP83TG720S_TDR_FAULT_STATUS);
297 if (ret < 0)
298 return ret;
299
300 /* Get fault type */
301 stat = oa_1000bt1_get_ethtool_cable_result_code(ret);
302
303 /* Determine fault location */
304 location = oa_1000bt1_get_tdr_distance(ret);
305 if (location > 0)
306 ethnl_cable_test_fault_length(phydev,
307 ETHTOOL_A_CABLE_PAIR_A,
308 location);
309 } else {
310 /* Active link partner or other issues */
311 stat = ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
312 }
313
314 *finished = true;
315
316 ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, stat);
317
318 /* save the current stats before resetting the PHY */
319 ret = dp83tg720_update_stats(phydev);
320 if (ret)
321 return ret;
322
323 return phy_init_hw(phydev);
324 }
325
dp83tg720_config_aneg(struct phy_device * phydev)326 static int dp83tg720_config_aneg(struct phy_device *phydev)
327 {
328 int ret;
329
330 /* Autoneg is not supported and this PHY supports only one speed.
331 * We need to care only about master/slave configuration if it was
332 * changed by user.
333 */
334 ret = genphy_c45_pma_baset1_setup_master_slave(phydev);
335 if (ret)
336 return ret;
337
338 /* Re-read role configuration to make changes visible even if
339 * the link is in administrative down state.
340 */
341 return genphy_c45_pma_baset1_read_master_slave(phydev);
342 }
343
dp83tg720_read_status(struct phy_device * phydev)344 static int dp83tg720_read_status(struct phy_device *phydev)
345 {
346 u16 phy_sts;
347 int ret;
348
349 phydev->pause = 0;
350 phydev->asym_pause = 0;
351
352 /* Most of Clause 45 registers are not present, so we can't use
353 * genphy_c45_read_status() here.
354 */
355 phy_sts = phy_read(phydev, DP83TG720S_MII_REG_10);
356 phydev->link = !!(phy_sts & DP83TG720S_LINK_STATUS);
357 if (!phydev->link) {
358 /* save the current stats before resetting the PHY */
359 ret = dp83tg720_update_stats(phydev);
360 if (ret)
361 return ret;
362
363 /* According to the "DP83TC81x, DP83TG72x Software
364 * Implementation Guide", the PHY needs to be reset after a
365 * link loss or if no link is created after at least 100ms.
366 *
367 * Currently we are polling with the PHY_STATE_TIME (1000ms)
368 * interval, which is still enough for not automotive use cases.
369 */
370 ret = phy_init_hw(phydev);
371 if (ret)
372 return ret;
373
374 /* After HW reset we need to restore master/slave configuration.
375 * genphy_c45_pma_baset1_read_master_slave() call will be done
376 * by the dp83tg720_config_aneg() function.
377 */
378 ret = dp83tg720_config_aneg(phydev);
379 if (ret)
380 return ret;
381
382 phydev->speed = SPEED_UNKNOWN;
383 phydev->duplex = DUPLEX_UNKNOWN;
384 } else {
385 /* PMA/PMD control 1 register (Register 1.0) is present, but it
386 * doesn't contain the link speed information.
387 * So genphy_c45_read_pma() can't be used here.
388 */
389 ret = genphy_c45_pma_baset1_read_master_slave(phydev);
390 if (ret)
391 return ret;
392
393 phydev->duplex = DUPLEX_FULL;
394 phydev->speed = SPEED_1000;
395 }
396
397 return 0;
398 }
399
dp83tg720_get_sqi(struct phy_device * phydev)400 static int dp83tg720_get_sqi(struct phy_device *phydev)
401 {
402 int ret;
403
404 if (!phydev->link)
405 return 0;
406
407 ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_SQI_REG_1);
408 if (ret < 0)
409 return ret;
410
411 return FIELD_GET(DP83TG720S_SQI_OUT, ret);
412 }
413
dp83tg720_get_sqi_max(struct phy_device * phydev)414 static int dp83tg720_get_sqi_max(struct phy_device *phydev)
415 {
416 return DP83TG720_SQI_MAX;
417 }
418
dp83tg720_config_rgmii_delay(struct phy_device * phydev)419 static int dp83tg720_config_rgmii_delay(struct phy_device *phydev)
420 {
421 u16 rgmii_delay_mask;
422 u16 rgmii_delay = 0;
423
424 switch (phydev->interface) {
425 case PHY_INTERFACE_MODE_RGMII:
426 rgmii_delay = 0;
427 break;
428 case PHY_INTERFACE_MODE_RGMII_ID:
429 rgmii_delay = DP83TG720S_RGMII_RX_CLK_SEL |
430 DP83TG720S_RGMII_TX_CLK_SEL;
431 break;
432 case PHY_INTERFACE_MODE_RGMII_RXID:
433 rgmii_delay = DP83TG720S_RGMII_RX_CLK_SEL;
434 break;
435 case PHY_INTERFACE_MODE_RGMII_TXID:
436 rgmii_delay = DP83TG720S_RGMII_TX_CLK_SEL;
437 break;
438 default:
439 return 0;
440 }
441
442 rgmii_delay_mask = DP83TG720S_RGMII_RX_CLK_SEL |
443 DP83TG720S_RGMII_TX_CLK_SEL;
444
445 return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
446 DP83TG720S_RGMII_DELAY_CTRL, rgmii_delay_mask,
447 rgmii_delay);
448 }
449
dp83tg720_config_init(struct phy_device * phydev)450 static int dp83tg720_config_init(struct phy_device *phydev)
451 {
452 int ret;
453
454 /* Software Restart is not enough to recover from a link failure.
455 * Using Hardware Reset instead.
456 */
457 ret = phy_write(phydev, DP83TG720S_PHY_RESET, DP83TG720S_HW_RESET);
458 if (ret)
459 return ret;
460
461 /* Wait until MDC can be used again.
462 * The wait value of one 1ms is documented in "DP83TG720S-Q1 1000BASE-T1
463 * Automotive Ethernet PHY with SGMII and RGMII" datasheet.
464 */
465 usleep_range(1000, 2000);
466
467 if (phy_interface_is_rgmii(phydev)) {
468 ret = dp83tg720_config_rgmii_delay(phydev);
469 if (ret)
470 return ret;
471 }
472
473 /* In case the PHY is bootstrapped in managed mode, we need to
474 * wake it.
475 */
476 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3,
477 DP83TG720S_LPS_CFG3_PWR_MODE_0);
478 if (ret)
479 return ret;
480
481 /* Make role configuration visible for ethtool on init and after
482 * rest.
483 */
484 return genphy_c45_pma_baset1_read_master_slave(phydev);
485 }
486
dp83tg720_probe(struct phy_device * phydev)487 static int dp83tg720_probe(struct phy_device *phydev)
488 {
489 struct device *dev = &phydev->mdio.dev;
490 struct dp83tg720_priv *priv;
491
492 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
493 if (!priv)
494 return -ENOMEM;
495
496 phydev->priv = priv;
497
498 return 0;
499 }
500
501 static struct phy_driver dp83tg720_driver[] = {
502 {
503 PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID),
504 .name = "TI DP83TG720S",
505
506 .flags = PHY_POLL_CABLE_TEST,
507 .probe = dp83tg720_probe,
508 .config_aneg = dp83tg720_config_aneg,
509 .read_status = dp83tg720_read_status,
510 .get_features = genphy_c45_pma_read_ext_abilities,
511 .config_init = dp83tg720_config_init,
512 .get_sqi = dp83tg720_get_sqi,
513 .get_sqi_max = dp83tg720_get_sqi_max,
514 .cable_test_start = dp83tg720_cable_test_start,
515 .cable_test_get_status = dp83tg720_cable_test_get_status,
516 .get_link_stats = dp83tg720_get_link_stats,
517 .get_phy_stats = dp83tg720_get_phy_stats,
518 .update_stats = dp83tg720_update_stats,
519
520 .suspend = genphy_suspend,
521 .resume = genphy_resume,
522 } };
523 module_phy_driver(dp83tg720_driver);
524
525 static const struct mdio_device_id __maybe_unused dp83tg720_tbl[] = {
526 { PHY_ID_MATCH_MODEL(DP83TG720S_PHY_ID) },
527 { }
528 };
529 MODULE_DEVICE_TABLE(mdio, dp83tg720_tbl);
530
531 MODULE_DESCRIPTION("Texas Instruments DP83TG720S PHY driver");
532 MODULE_AUTHOR("Oleksij Rempel <[email protected]>");
533 MODULE_LICENSE("GPL");
534