4 * SPDX-License-Identifier: GPL-2.0+
6 * Copyright 2010-2011 Freescale Semiconductor, Inc.
13 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
15 /* RTL8211B PHY Status Register */
16 #define MIIM_RTL8211B_PHY_STATUS 0x11
17 #define MIIM_RTL8211B_PHYSTAT_SPEED 0xc000
18 #define MIIM_RTL8211B_PHYSTAT_GBIT 0x8000
19 #define MIIM_RTL8211B_PHYSTAT_100 0x4000
20 #define MIIM_RTL8211B_PHYSTAT_DUPLEX 0x2000
21 #define MIIM_RTL8211B_PHYSTAT_SPDDONE 0x0800
22 #define MIIM_RTL8211B_PHYSTAT_LINK 0x0400
25 /* RealTek RTL8211B */
26 static int rtl8211b_config(struct phy_device
*phydev
)
28 phy_write(phydev
, MDIO_DEVAD_NONE
, MII_BMCR
, BMCR_RESET
);
30 genphy_config_aneg(phydev
);
35 static int rtl8211b_parse_status(struct phy_device
*phydev
)
40 mii_reg
= phy_read(phydev
, MDIO_DEVAD_NONE
, MIIM_RTL8211B_PHY_STATUS
);
42 if (!(mii_reg
& MIIM_RTL8211B_PHYSTAT_SPDDONE
)) {
45 /* in case of timeout ->link is cleared */
47 puts("Waiting for PHY realtime link");
48 while (!(mii_reg
& MIIM_RTL8211B_PHYSTAT_SPDDONE
)) {
49 /* Timeout reached ? */
50 if (i
> PHY_AUTONEGOTIATE_TIMEOUT
) {
56 if ((i
++ % 1000) == 0)
58 udelay(1000); /* 1 ms */
59 mii_reg
= phy_read(phydev
, MDIO_DEVAD_NONE
,
60 MIIM_RTL8211B_PHY_STATUS
);
63 udelay(500000); /* another 500 ms (results in faster booting) */
65 if (mii_reg
& MIIM_RTL8211B_PHYSTAT_LINK
)
71 if (mii_reg
& MIIM_RTL8211B_PHYSTAT_DUPLEX
)
72 phydev
->duplex
= DUPLEX_FULL
;
74 phydev
->duplex
= DUPLEX_HALF
;
76 speed
= (mii_reg
& MIIM_RTL8211B_PHYSTAT_SPEED
);
79 case MIIM_RTL8211B_PHYSTAT_GBIT
:
80 phydev
->speed
= SPEED_1000
;
82 case MIIM_RTL8211B_PHYSTAT_100
:
83 phydev
->speed
= SPEED_100
;
86 phydev
->speed
= SPEED_10
;
92 static int rtl8211b_startup(struct phy_device
*phydev
)
94 /* Read the Status (2x to make sure link is right) */
95 genphy_update_link(phydev
);
96 rtl8211b_parse_status(phydev
);
101 static struct phy_driver RTL8211B_driver
= {
102 .name
= "RealTek RTL8211B",
105 .features
= PHY_GBIT_FEATURES
,
106 .config
= &rtl8211b_config
,
107 .startup
= &rtl8211b_startup
,
108 .shutdown
= &genphy_shutdown
,
111 int phy_realtek_init(void)
113 phy_register(&RTL8211B_driver
);