xref: /linux/drivers/net/phy/dp83tg720.c (revision 2ee738e90e80850582cbe10f34c6447965c1d87b)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83TG720 PHY
3  * Copyright (c) 2023 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
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  */
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 
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 
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  */
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  */
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 
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 
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 
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 
414 static int dp83tg720_get_sqi_max(struct phy_device *phydev)
415 {
416 	return DP83TG720_SQI_MAX;
417 }
418 
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 
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 
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 <kernel@pengutronix.de>");
533 MODULE_LICENSE("GPL");
534