4 * SPDX-License-Identifier: GPL-2.0+
6 * Copyright 2010-2011 Freescale Semiconductor, Inc.
8 * (C) 2012 NetModule AG, David Andrey, added KSZ9031
15 static struct phy_driver KSZ804_driver = {
16 .name = "Micrel KSZ804",
19 .features = PHY_BASIC_FEATURES,
20 .config = &genphy_config,
21 .startup = &genphy_startup,
22 .shutdown = &genphy_shutdown,
25 #ifndef CONFIG_PHY_MICREL_KSZ9021
27 * I can't believe Micrel used the exact same part number
28 * for the KSZ9021. Shame Micrel, Shame!
30 static struct phy_driver KS8721_driver = {
31 .name = "Micrel KS8721BL",
34 .features = PHY_BASIC_FEATURES,
35 .config = &genphy_config,
36 .startup = &genphy_startup,
37 .shutdown = &genphy_shutdown,
43 * KSZ9021 - KSZ9031 common
46 #define MII_KSZ90xx_PHY_CTL 0x1f
47 #define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6)
48 #define MIIM_KSZ90xx_PHYCTL_100 (1 << 5)
49 #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4)
50 #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3)
52 static int ksz90xx_startup(struct phy_device *phydev)
55 genphy_update_link(phydev);
56 phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
58 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
59 phydev->duplex = DUPLEX_FULL;
61 phydev->duplex = DUPLEX_HALF;
63 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
64 phydev->speed = SPEED_1000;
65 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
66 phydev->speed = SPEED_100;
67 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
68 phydev->speed = SPEED_10;
72 #ifdef CONFIG_PHY_MICREL_KSZ9021
78 #define MII_KSZ9021_EXTENDED_CTRL 0x0b
79 #define MII_KSZ9021_EXTENDED_DATAW 0x0c
80 #define MII_KSZ9021_EXTENDED_DATAR 0x0d
82 #define CTRL1000_PREFER_MASTER (1 << 10)
83 #define CTRL1000_CONFIG_MASTER (1 << 11)
84 #define CTRL1000_MANUAL_CONFIG (1 << 12)
86 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
88 /* extended registers */
89 phy_write(phydev, MDIO_DEVAD_NONE,
90 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
91 return phy_write(phydev, MDIO_DEVAD_NONE,
92 MII_KSZ9021_EXTENDED_DATAW, val);
95 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
97 /* extended registers */
98 phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
99 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
103 static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr,
106 return ksz9021_phy_extended_read(phydev, regnum);
109 static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr,
110 int devaddr, int regnum, u16 val)
112 return ksz9021_phy_extended_write(phydev, regnum, val);
116 static int ksz9021_config(struct phy_device *phydev)
118 unsigned ctrl1000 = 0;
119 const unsigned master = CTRL1000_PREFER_MASTER |
120 CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
121 unsigned features = phydev->drv->features;
123 if (getenv("disable_giga"))
124 features &= ~(SUPPORTED_1000baseT_Half |
125 SUPPORTED_1000baseT_Full);
126 /* force master mode for 1000BaseT due to chip errata */
127 if (features & SUPPORTED_1000baseT_Half)
128 ctrl1000 |= ADVERTISE_1000HALF | master;
129 if (features & SUPPORTED_1000baseT_Full)
130 ctrl1000 |= ADVERTISE_1000FULL | master;
131 phydev->advertising = phydev->supported = features;
132 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
133 genphy_config_aneg(phydev);
134 genphy_restart_aneg(phydev);
138 static struct phy_driver ksz9021_driver = {
139 .name = "Micrel ksz9021",
142 .features = PHY_GBIT_FEATURES,
143 .config = &ksz9021_config,
144 .startup = &ksz90xx_startup,
145 .shutdown = &genphy_shutdown,
146 .writeext = &ksz9021_phy_extwrite,
147 .readext = &ksz9021_phy_extread,
155 #define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
156 #define MII_KSZ9031_MMD_REG_DATA 0x0e
158 /* Accessors to extended registers*/
159 int ksz9031_phy_extended_write(struct phy_device *phydev,
160 int devaddr, int regnum, u16 mode, u16 val)
162 /*select register addr for mmd*/
163 phy_write(phydev, MDIO_DEVAD_NONE,
164 MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
165 /*select register for mmd*/
166 phy_write(phydev, MDIO_DEVAD_NONE,
167 MII_KSZ9031_MMD_REG_DATA, regnum);
169 phy_write(phydev, MDIO_DEVAD_NONE,
170 MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
172 return phy_write(phydev, MDIO_DEVAD_NONE,
173 MII_KSZ9031_MMD_REG_DATA, val);
176 int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
177 int regnum, u16 mode)
179 phy_write(phydev, MDIO_DEVAD_NONE,
180 MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
181 phy_write(phydev, MDIO_DEVAD_NONE,
182 MII_KSZ9031_MMD_REG_DATA, regnum);
183 phy_write(phydev, MDIO_DEVAD_NONE,
184 MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
185 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
188 static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr,
191 return ksz9031_phy_extended_read(phydev, devaddr, regnum,
192 MII_KSZ9031_MOD_DATA_NO_POST_INC);
195 static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr,
196 int devaddr, int regnum, u16 val)
198 return ksz9031_phy_extended_write(phydev, devaddr, regnum,
199 MII_KSZ9031_MOD_DATA_POST_INC_RW, val);
203 static struct phy_driver ksz9031_driver = {
204 .name = "Micrel ksz9031",
207 .features = PHY_GBIT_FEATURES,
208 .config = &genphy_config,
209 .startup = &ksz90xx_startup,
210 .shutdown = &genphy_shutdown,
211 .writeext = &ksz9031_phy_extwrite,
212 .readext = &ksz9031_phy_extread,
215 int phy_micrel_init(void)
217 phy_register(&KSZ804_driver);
218 #ifdef CONFIG_PHY_MICREL_KSZ9021
219 phy_register(&ksz9021_driver);
221 phy_register(&KS8721_driver);
223 phy_register(&ksz9031_driver);