1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs.
4 * Copyright (C) 2017 Texas Instruments Inc.
7 #include <linux/ethtool.h>
8 #include <linux/etherdevice.h>
9 #include <linux/kernel.h>
10 #include <linux/mii.h>
11 #include <linux/module.h>
13 #include <linux/phy.h>
14 #include <linux/netdevice.h>
16 #define DP83822_PHY_ID 0x2000a240
17 #define DP83825S_PHY_ID 0x2000a140
18 #define DP83825I_PHY_ID 0x2000a150
19 #define DP83825CM_PHY_ID 0x2000a160
20 #define DP83825CS_PHY_ID 0x2000a170
21 #define DP83826C_PHY_ID 0x2000a130
22 #define DP83826NC_PHY_ID 0x2000a110
24 #define DP83822_DEVADDR 0x1f
26 #define MII_DP83822_CTRL_2 0x0a
27 #define MII_DP83822_PHYSTS 0x10
28 #define MII_DP83822_PHYSCR 0x11
29 #define MII_DP83822_MISR1 0x12
30 #define MII_DP83822_MISR2 0x13
31 #define MII_DP83822_FCSCR 0x14
32 #define MII_DP83822_RCSR 0x17
33 #define MII_DP83822_RESET_CTRL 0x1f
34 #define MII_DP83822_GENCFG 0x465
35 #define MII_DP83822_SOR1 0x467
38 #define DP83822_SIG_DET_LOW BIT(0)
40 /* Control Register 2 bits */
41 #define DP83822_FX_ENABLE BIT(14)
43 #define DP83822_HW_RESET BIT(15)
44 #define DP83822_SW_RESET BIT(14)
47 #define DP83822_PHYSTS_DUPLEX BIT(2)
48 #define DP83822_PHYSTS_10 BIT(1)
49 #define DP83822_PHYSTS_LINK BIT(0)
51 /* PHYSCR Register Fields */
52 #define DP83822_PHYSCR_INT_OE BIT(0) /* Interrupt Output Enable */
53 #define DP83822_PHYSCR_INTEN BIT(1) /* Interrupt Enable */
56 #define DP83822_RX_ERR_HF_INT_EN BIT(0)
57 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1)
58 #define DP83822_ANEG_COMPLETE_INT_EN BIT(2)
59 #define DP83822_DUP_MODE_CHANGE_INT_EN BIT(3)
60 #define DP83822_SPEED_CHANGED_INT_EN BIT(4)
61 #define DP83822_LINK_STAT_INT_EN BIT(5)
62 #define DP83822_ENERGY_DET_INT_EN BIT(6)
63 #define DP83822_LINK_QUAL_INT_EN BIT(7)
66 #define DP83822_JABBER_DET_INT_EN BIT(0)
67 #define DP83822_WOL_PKT_INT_EN BIT(1)
68 #define DP83822_SLEEP_MODE_INT_EN BIT(2)
69 #define DP83822_MDI_XOVER_INT_EN BIT(3)
70 #define DP83822_LB_FIFO_INT_EN BIT(4)
71 #define DP83822_PAGE_RX_INT_EN BIT(5)
72 #define DP83822_ANEG_ERR_INT_EN BIT(6)
73 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7)
76 #define DP83822_WOL_INT_EN BIT(4)
77 #define DP83822_WOL_INT_STAT BIT(12)
79 #define MII_DP83822_RXSOP1 0x04a5
80 #define MII_DP83822_RXSOP2 0x04a6
81 #define MII_DP83822_RXSOP3 0x04a7
84 #define MII_DP83822_WOL_CFG 0x04a0
85 #define MII_DP83822_WOL_STAT 0x04a1
86 #define MII_DP83822_WOL_DA1 0x04a2
87 #define MII_DP83822_WOL_DA2 0x04a3
88 #define MII_DP83822_WOL_DA3 0x04a4
91 #define DP83822_WOL_MAGIC_EN BIT(0)
92 #define DP83822_WOL_SECURE_ON BIT(5)
93 #define DP83822_WOL_EN BIT(7)
94 #define DP83822_WOL_INDICATION_SEL BIT(8)
95 #define DP83822_WOL_CLR_INDICATION BIT(11)
98 #define DP83822_RGMII_MODE_EN BIT(9)
99 #define DP83822_RX_CLK_SHIFT BIT(12)
100 #define DP83822_TX_CLK_SHIFT BIT(11)
103 #define DP83822_STRAP_MODE1 0
104 #define DP83822_STRAP_MODE2 BIT(0)
105 #define DP83822_STRAP_MODE3 BIT(1)
106 #define DP83822_STRAP_MODE4 GENMASK(1, 0)
108 #define DP83822_COL_STRAP_MASK GENMASK(11, 10)
109 #define DP83822_COL_SHIFT 10
110 #define DP83822_RX_ER_STR_MASK GENMASK(9, 8)
111 #define DP83822_RX_ER_SHIFT 8
113 #define MII_DP83822_FIBER_ADVERTISE (ADVERTISED_TP | ADVERTISED_MII | \
115 ADVERTISED_Pause | ADVERTISED_Asym_Pause)
117 struct dp83822_private {
118 bool fx_signal_det_low;
123 static int dp83822_ack_interrupt(struct phy_device *phydev)
127 err = phy_read(phydev, MII_DP83822_MISR1);
131 err = phy_read(phydev, MII_DP83822_MISR2);
138 static int dp83822_set_wol(struct phy_device *phydev,
139 struct ethtool_wolinfo *wol)
141 struct net_device *ndev = phydev->attached_dev;
145 if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
146 mac = (const u8 *)ndev->dev_addr;
148 if (!is_valid_ether_addr(mac))
151 /* MAC addresses start with byte 5, but stored in mac[0].
152 * 822 PHYs store bytes 4|5, 2|3, 0|1
154 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
155 (mac[1] << 8) | mac[0]);
156 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
157 (mac[3] << 8) | mac[2]);
158 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
159 (mac[5] << 8) | mac[4]);
161 value = phy_read_mmd(phydev, DP83822_DEVADDR,
162 MII_DP83822_WOL_CFG);
163 if (wol->wolopts & WAKE_MAGIC)
164 value |= DP83822_WOL_MAGIC_EN;
166 value &= ~DP83822_WOL_MAGIC_EN;
168 if (wol->wolopts & WAKE_MAGICSECURE) {
169 phy_write_mmd(phydev, DP83822_DEVADDR,
171 (wol->sopass[1] << 8) | wol->sopass[0]);
172 phy_write_mmd(phydev, DP83822_DEVADDR,
174 (wol->sopass[3] << 8) | wol->sopass[2]);
175 phy_write_mmd(phydev, DP83822_DEVADDR,
177 (wol->sopass[5] << 8) | wol->sopass[4]);
178 value |= DP83822_WOL_SECURE_ON;
180 value &= ~DP83822_WOL_SECURE_ON;
183 /* Clear any pending WoL interrupt */
184 phy_read(phydev, MII_DP83822_MISR2);
186 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
187 DP83822_WOL_CLR_INDICATION;
189 return phy_write_mmd(phydev, DP83822_DEVADDR,
190 MII_DP83822_WOL_CFG, value);
192 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
193 MII_DP83822_WOL_CFG, DP83822_WOL_EN);
197 static void dp83822_get_wol(struct phy_device *phydev,
198 struct ethtool_wolinfo *wol)
203 wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
206 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
208 if (value & DP83822_WOL_MAGIC_EN)
209 wol->wolopts |= WAKE_MAGIC;
211 if (value & DP83822_WOL_SECURE_ON) {
212 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
214 wol->sopass[0] = (sopass_val & 0xff);
215 wol->sopass[1] = (sopass_val >> 8);
217 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
219 wol->sopass[2] = (sopass_val & 0xff);
220 wol->sopass[3] = (sopass_val >> 8);
222 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
224 wol->sopass[4] = (sopass_val & 0xff);
225 wol->sopass[5] = (sopass_val >> 8);
227 wol->wolopts |= WAKE_MAGICSECURE;
230 /* WoL is not enabled so set wolopts to 0 */
231 if (!(value & DP83822_WOL_EN))
235 static int dp83822_config_intr(struct phy_device *phydev)
237 struct dp83822_private *dp83822 = phydev->priv;
242 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
243 misr_status = phy_read(phydev, MII_DP83822_MISR1);
247 misr_status |= (DP83822_LINK_STAT_INT_EN |
248 DP83822_ENERGY_DET_INT_EN |
249 DP83822_LINK_QUAL_INT_EN);
251 /* Private data pointer is NULL on DP83825/26 */
252 if (!dp83822 || !dp83822->fx_enabled)
253 misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
254 DP83822_DUP_MODE_CHANGE_INT_EN |
255 DP83822_SPEED_CHANGED_INT_EN;
258 err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
262 misr_status = phy_read(phydev, MII_DP83822_MISR2);
266 misr_status |= (DP83822_JABBER_DET_INT_EN |
267 DP83822_SLEEP_MODE_INT_EN |
268 DP83822_LB_FIFO_INT_EN |
269 DP83822_PAGE_RX_INT_EN |
270 DP83822_EEE_ERROR_CHANGE_INT_EN);
272 /* Private data pointer is NULL on DP83825/26 */
273 if (!dp83822 || !dp83822->fx_enabled)
274 misr_status |= DP83822_ANEG_ERR_INT_EN |
275 DP83822_WOL_PKT_INT_EN;
277 err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
281 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
282 if (physcr_status < 0)
283 return physcr_status;
285 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
288 err = phy_write(phydev, MII_DP83822_MISR1, 0);
292 err = phy_write(phydev, MII_DP83822_MISR2, 0);
296 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
297 if (physcr_status < 0)
298 return physcr_status;
300 physcr_status &= ~DP83822_PHYSCR_INTEN;
303 return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
306 static int dp8382x_disable_wol(struct phy_device *phydev)
308 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
309 DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
310 DP83822_WOL_SECURE_ON);
313 static int dp83822_read_status(struct phy_device *phydev)
315 struct dp83822_private *dp83822 = phydev->priv;
316 int status = phy_read(phydev, MII_DP83822_PHYSTS);
320 if (dp83822->fx_enabled) {
321 if (status & DP83822_PHYSTS_LINK) {
322 phydev->speed = SPEED_UNKNOWN;
323 phydev->duplex = DUPLEX_UNKNOWN;
325 ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2);
329 if (!(ctrl2 & DP83822_FX_ENABLE)) {
330 ret = phy_write(phydev, MII_DP83822_CTRL_2,
331 DP83822_FX_ENABLE | ctrl2);
338 ret = genphy_read_status(phydev);
345 if (status & DP83822_PHYSTS_DUPLEX)
346 phydev->duplex = DUPLEX_FULL;
348 phydev->duplex = DUPLEX_HALF;
350 if (status & DP83822_PHYSTS_10)
351 phydev->speed = SPEED_10;
353 phydev->speed = SPEED_100;
358 static int dp83822_config_init(struct phy_device *phydev)
360 struct dp83822_private *dp83822 = phydev->priv;
361 struct device *dev = &phydev->mdio.dev;
368 if (phy_interface_is_rgmii(phydev)) {
369 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
372 /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */
373 if (rx_int_delay > 0)
374 rgmii_delay |= DP83822_RX_CLK_SHIFT;
376 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
379 /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */
380 if (tx_int_delay <= 0)
381 rgmii_delay |= DP83822_TX_CLK_SHIFT;
383 err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
384 DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay);
388 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
389 MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
394 err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
395 MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
401 if (dp83822->fx_enabled) {
402 err = phy_modify(phydev, MII_DP83822_CTRL_2,
403 DP83822_FX_ENABLE, 1);
407 /* Only allow advertising what this PHY supports */
408 linkmode_and(phydev->advertising, phydev->advertising,
411 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
413 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
414 phydev->advertising);
415 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
417 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
419 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
420 phydev->advertising);
421 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
422 phydev->advertising);
424 /* Auto neg is not supported in fiber mode */
425 bmcr = phy_read(phydev, MII_BMCR);
429 if (bmcr & BMCR_ANENABLE) {
430 err = phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
434 phydev->autoneg = AUTONEG_DISABLE;
435 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
437 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
438 phydev->advertising);
440 /* Setup fiber advertisement */
441 err = phy_modify_changed(phydev, MII_ADVERTISE,
442 MII_DP83822_FIBER_ADVERTISE,
443 MII_DP83822_FIBER_ADVERTISE);
448 if (dp83822->fx_signal_det_low) {
449 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
451 DP83822_SIG_DET_LOW);
456 return dp8382x_disable_wol(phydev);
459 static int dp8382x_config_init(struct phy_device *phydev)
461 return dp8382x_disable_wol(phydev);
464 static int dp83822_phy_reset(struct phy_device *phydev)
468 err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET);
472 return phydev->drv->config_init(phydev);
475 #ifdef CONFIG_OF_MDIO
476 static int dp83822_of_init(struct phy_device *phydev)
478 struct dp83822_private *dp83822 = phydev->priv;
479 struct device *dev = &phydev->mdio.dev;
481 /* Signal detection for the PHY is only enabled if the FX_EN and the
482 * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
483 * is strapped otherwise signal detection is disabled for the PHY.
485 if (dp83822->fx_enabled && dp83822->fx_sd_enable)
486 dp83822->fx_signal_det_low = device_property_present(dev,
488 if (!dp83822->fx_enabled)
489 dp83822->fx_enabled = device_property_present(dev,
495 static int dp83822_of_init(struct phy_device *phydev)
499 #endif /* CONFIG_OF_MDIO */
501 static int dp83822_read_straps(struct phy_device *phydev)
503 struct dp83822_private *dp83822 = phydev->priv;
504 int fx_enabled, fx_sd_enable;
507 val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1);
511 fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT;
512 if (fx_enabled == DP83822_STRAP_MODE2 ||
513 fx_enabled == DP83822_STRAP_MODE3)
514 dp83822->fx_enabled = 1;
516 if (dp83822->fx_enabled) {
517 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT;
518 if (fx_sd_enable == DP83822_STRAP_MODE3 ||
519 fx_sd_enable == DP83822_STRAP_MODE4)
520 dp83822->fx_sd_enable = 1;
526 static int dp83822_probe(struct phy_device *phydev)
528 struct dp83822_private *dp83822;
531 dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
536 phydev->priv = dp83822;
538 ret = dp83822_read_straps(phydev);
542 dp83822_of_init(phydev);
544 if (dp83822->fx_enabled)
545 phydev->port = PORT_FIBRE;
550 static int dp83822_suspend(struct phy_device *phydev)
554 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
556 if (!(value & DP83822_WOL_EN))
557 genphy_suspend(phydev);
562 static int dp83822_resume(struct phy_device *phydev)
566 genphy_resume(phydev);
568 value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
570 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
571 DP83822_WOL_CLR_INDICATION);
576 #define DP83822_PHY_DRIVER(_id, _name) \
578 PHY_ID_MATCH_MODEL(_id), \
580 /* PHY_BASIC_FEATURES */ \
581 .probe = dp83822_probe, \
582 .soft_reset = dp83822_phy_reset, \
583 .config_init = dp83822_config_init, \
584 .read_status = dp83822_read_status, \
585 .get_wol = dp83822_get_wol, \
586 .set_wol = dp83822_set_wol, \
587 .ack_interrupt = dp83822_ack_interrupt, \
588 .config_intr = dp83822_config_intr, \
589 .suspend = dp83822_suspend, \
590 .resume = dp83822_resume, \
593 #define DP8382X_PHY_DRIVER(_id, _name) \
595 PHY_ID_MATCH_MODEL(_id), \
597 /* PHY_BASIC_FEATURES */ \
598 .soft_reset = dp83822_phy_reset, \
599 .config_init = dp8382x_config_init, \
600 .get_wol = dp83822_get_wol, \
601 .set_wol = dp83822_set_wol, \
602 .ack_interrupt = dp83822_ack_interrupt, \
603 .config_intr = dp83822_config_intr, \
604 .suspend = dp83822_suspend, \
605 .resume = dp83822_resume, \
608 static struct phy_driver dp83822_driver[] = {
609 DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
610 DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
611 DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
612 DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
613 DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
614 DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
615 DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
617 module_phy_driver(dp83822_driver);
619 static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
620 { DP83822_PHY_ID, 0xfffffff0 },
621 { DP83825I_PHY_ID, 0xfffffff0 },
622 { DP83826C_PHY_ID, 0xfffffff0 },
623 { DP83826NC_PHY_ID, 0xfffffff0 },
624 { DP83825S_PHY_ID, 0xfffffff0 },
625 { DP83825CM_PHY_ID, 0xfffffff0 },
626 { DP83825CS_PHY_ID, 0xfffffff0 },
629 MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
631 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
632 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
633 MODULE_LICENSE("GPL v2");