4 * SPDX-License-Identifier: GPL-2.0+
6 * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc.
13 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
15 /* RTL8211x PHY Status Register */
16 #define MIIM_RTL8211x_PHY_STATUS 0x11
17 #define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000
18 #define MIIM_RTL8211x_PHYSTAT_GBIT 0x8000
19 #define MIIM_RTL8211x_PHYSTAT_100 0x4000
20 #define MIIM_RTL8211x_PHYSTAT_DUPLEX 0x2000
21 #define MIIM_RTL8211x_PHYSTAT_SPDDONE 0x0800
22 #define MIIM_RTL8211x_PHYSTAT_LINK 0x0400
24 /* RTL8211x PHY Interrupt Enable Register */
25 #define MIIM_RTL8211x_PHY_INER 0x12
26 #define MIIM_RTL8211x_PHY_INTR_ENA 0x9f01
27 #define MIIM_RTL8211x_PHY_INTR_DIS 0x0000
29 /* RTL8211x PHY Interrupt Status Register */
30 #define MIIM_RTL8211x_PHY_INSR 0x13
32 /* RealTek RTL8211x */
33 static int rtl8211x_config(struct phy_device *phydev)
35 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
37 /* mask interrupt at init; if the interrupt is
38 * needed indeed, it should be explicitly enabled
40 phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER,
41 MIIM_RTL8211x_PHY_INTR_DIS);
43 /* read interrupt status just to clear it */
44 phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
46 genphy_config_aneg(phydev);
51 static int rtl8211x_parse_status(struct phy_device *phydev)
56 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
58 if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
61 /* in case of timeout ->link is cleared */
63 puts("Waiting for PHY realtime link");
64 while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
65 /* Timeout reached ? */
66 if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
72 if ((i++ % 1000) == 0)
74 udelay(1000); /* 1 ms */
75 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
76 MIIM_RTL8211x_PHY_STATUS);
79 udelay(500000); /* another 500 ms (results in faster booting) */
81 if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK)
87 if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX)
88 phydev->duplex = DUPLEX_FULL;
90 phydev->duplex = DUPLEX_HALF;
92 speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
95 case MIIM_RTL8211x_PHYSTAT_GBIT:
96 phydev->speed = SPEED_1000;
98 case MIIM_RTL8211x_PHYSTAT_100:
99 phydev->speed = SPEED_100;
102 phydev->speed = SPEED_10;
108 static int rtl8211x_startup(struct phy_device *phydev)
110 /* Read the Status (2x to make sure link is right) */
111 genphy_update_link(phydev);
112 rtl8211x_parse_status(phydev);
117 /* Support for RTL8211B PHY */
118 static struct phy_driver RTL8211B_driver = {
119 .name = "RealTek RTL8211B",
122 .features = PHY_GBIT_FEATURES,
123 .config = &rtl8211x_config,
124 .startup = &rtl8211x_startup,
125 .shutdown = &genphy_shutdown,
128 /* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
129 static struct phy_driver RTL8211E_driver = {
130 .name = "RealTek RTL8211E",
133 .features = PHY_GBIT_FEATURES,
134 .config = &rtl8211x_config,
135 .startup = &rtl8211x_startup,
136 .shutdown = &genphy_shutdown,
139 /* Support for RTL8211DN PHY */
140 static struct phy_driver RTL8211DN_driver = {
141 .name = "RealTek RTL8211DN",
144 .features = PHY_GBIT_FEATURES,
145 .config = &rtl8211x_config,
146 .startup = &rtl8211x_startup,
147 .shutdown = &genphy_shutdown,
150 int phy_realtek_init(void)
152 phy_register(&RTL8211B_driver);
153 phy_register(&RTL8211E_driver);
154 phy_register(&RTL8211DN_driver);