2 * drivers/net/ibm_emac/ibm_emac_phy.c
4 * Driver for PowerPC 4xx on-chip ethernet controller, PHY support.
5 * Borrowed from sungem_phy.c, though I only kept the generic MII
8 * This file should be shared with other drivers or eventually
9 * merged as the "low level" part of miilib
11 * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
12 * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
15 #include <linux/module.h>
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/netdevice.h>
19 #include <linux/mii.h>
20 #include <linux/ethtool.h>
21 #include <linux/delay.h>
25 #include "ibm_emac_core.h"
26 #include "ibm_emac_phy.h"
28 static inline int phy_read(struct mii_phy *phy, int reg)
30 return phy->mdio_read(phy->dev, phy->address, reg);
33 static inline void phy_write(struct mii_phy *phy, int reg, int val)
35 phy->mdio_write(phy->dev, phy->address, reg, val);
39 * polls MII_BMCR until BMCR_RESET bit clears or operation times out.
42 * >= 0 => success, value in BMCR returned to caller
43 * -EBUSY => failure, RESET bit never cleared
44 * otherwise => failure, lower level PHY read failed
46 static int mii_spin_reset_complete(struct mii_phy *phy)
52 val = phy_read(phy, MII_BMCR);
53 if (val >= 0 && !(val & BMCR_RESET))
54 return val; /* success */
61 printk(KERN_ERR "emac%d: PHY reset timeout (%d)\n",
62 ((struct ocp_enet_private *)phy->dev->priv)->def->index,
67 int mii_reset_phy(struct mii_phy *phy)
71 val = phy_read(phy, MII_BMCR);
74 phy_write(phy, MII_BMCR, val);
78 val = mii_spin_reset_complete(phy);
79 if (val >= 0 && (val & BMCR_ISOLATE))
80 phy_write(phy, MII_BMCR, val & ~BMCR_ISOLATE);
85 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
89 phy->autoneg = AUTONEG_ENABLE;
90 phy->speed = SPEED_10;
91 phy->duplex = DUPLEX_HALF;
92 phy->pause = phy->asym_pause = 0;
93 phy->advertising = advertise;
95 /* Setup standard advertise */
96 adv = phy_read(phy, MII_ADVERTISE);
99 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
100 ADVERTISE_PAUSE_ASYM);
101 if (advertise & ADVERTISED_10baseT_Half)
102 adv |= ADVERTISE_10HALF;
103 if (advertise & ADVERTISED_10baseT_Full)
104 adv |= ADVERTISE_10FULL;
105 if (advertise & ADVERTISED_100baseT_Half)
106 adv |= ADVERTISE_100HALF;
107 if (advertise & ADVERTISED_100baseT_Full)
108 adv |= ADVERTISE_100FULL;
109 if (advertise & ADVERTISED_Pause)
110 adv |= ADVERTISE_PAUSE_CAP;
111 if (advertise & ADVERTISED_Asym_Pause)
112 adv |= ADVERTISE_PAUSE_ASYM;
113 phy_write(phy, MII_ADVERTISE, adv);
116 (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
117 adv = phy_read(phy, MII_CTRL1000);
120 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
121 if (advertise & ADVERTISED_1000baseT_Full)
122 adv |= ADVERTISE_1000FULL;
123 if (advertise & ADVERTISED_1000baseT_Half)
124 adv |= ADVERTISE_1000HALF;
125 phy_write(phy, MII_CTRL1000, adv);
128 /* Start/Restart aneg */
129 /* on some PHYs (e.g. National DP83843) a write to MII_ADVERTISE
130 * causes BMCR_RESET to be set on the next read of MII_BMCR, which
131 * if not checked for causes the PHY to be reset below */
132 ctl = mii_spin_reset_complete(phy);
136 ctl |= BMCR_ANENABLE | BMCR_ANRESTART;
137 phy_write(phy, MII_BMCR, ctl);
142 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
146 phy->autoneg = AUTONEG_DISABLE;
149 phy->pause = phy->asym_pause = 0;
151 /* First reset the PHY */
154 ctl = phy_read(phy, MII_BMCR);
157 ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE | BMCR_SPEED1000);
159 /* Select speed & duplex */
164 ctl |= BMCR_SPEED100;
167 ctl |= BMCR_SPEED1000;
172 if (fd == DUPLEX_FULL)
173 ctl |= BMCR_FULLDPLX;
174 phy_write(phy, MII_BMCR, ctl);
179 static int genmii_poll_link(struct mii_phy *phy)
183 /* Clear latched value with dummy read */
184 phy_read(phy, MII_BMSR);
185 status = phy_read(phy, MII_BMSR);
186 if (status < 0 || (status & BMSR_LSTATUS) == 0)
188 if (phy->autoneg == AUTONEG_ENABLE && !(status & BMSR_ANEGCOMPLETE))
193 static int genmii_read_link(struct mii_phy *phy)
195 if (phy->autoneg == AUTONEG_ENABLE) {
197 int lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
202 (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half)) {
203 int adv = phy_read(phy, MII_CTRL1000);
204 glpa = phy_read(phy, MII_STAT1000);
206 if (glpa < 0 || adv < 0)
212 phy->speed = SPEED_10;
213 phy->duplex = DUPLEX_HALF;
214 phy->pause = phy->asym_pause = 0;
216 if (glpa & (LPA_1000FULL | LPA_1000HALF)) {
217 phy->speed = SPEED_1000;
218 if (glpa & LPA_1000FULL)
219 phy->duplex = DUPLEX_FULL;
220 } else if (lpa & (LPA_100FULL | LPA_100HALF)) {
221 phy->speed = SPEED_100;
222 if (lpa & LPA_100FULL)
223 phy->duplex = DUPLEX_FULL;
224 } else if (lpa & LPA_10FULL)
225 phy->duplex = DUPLEX_FULL;
227 if (phy->duplex == DUPLEX_FULL) {
228 phy->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
229 phy->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
232 int bmcr = phy_read(phy, MII_BMCR);
236 if (bmcr & BMCR_FULLDPLX)
237 phy->duplex = DUPLEX_FULL;
239 phy->duplex = DUPLEX_HALF;
240 if (bmcr & BMCR_SPEED1000)
241 phy->speed = SPEED_1000;
242 else if (bmcr & BMCR_SPEED100)
243 phy->speed = SPEED_100;
245 phy->speed = SPEED_10;
247 phy->pause = phy->asym_pause = 0;
252 /* Generic implementation for most 10/100/1000 PHYs */
253 static struct mii_phy_ops generic_phy_ops = {
254 .setup_aneg = genmii_setup_aneg,
255 .setup_forced = genmii_setup_forced,
256 .poll_link = genmii_poll_link,
257 .read_link = genmii_read_link
260 static struct mii_phy_def genmii_phy_def = {
261 .phy_id = 0x00000000,
262 .phy_id_mask = 0x00000000,
263 .name = "Generic MII",
264 .ops = &generic_phy_ops
268 #define MII_CIS8201_10BTCSR 0x16
269 #define TENBTCSR_ECHO_DISABLE 0x2000
270 #define MII_CIS8201_EPCR 0x17
271 #define EPCR_MODE_MASK 0x3000
272 #define EPCR_GMII_MODE 0x0000
273 #define EPCR_RGMII_MODE 0x1000
274 #define EPCR_TBI_MODE 0x2000
275 #define EPCR_RTBI_MODE 0x3000
276 #define MII_CIS8201_ACSR 0x1c
277 #define ACSR_PIN_PRIO_SELECT 0x0004
279 static int cis8201_init(struct mii_phy *phy)
283 epcr = phy_read(phy, MII_CIS8201_EPCR);
287 epcr &= ~EPCR_MODE_MASK;
291 epcr |= EPCR_TBI_MODE;
294 epcr |= EPCR_RTBI_MODE;
297 epcr |= EPCR_GMII_MODE;
301 epcr |= EPCR_RGMII_MODE;
304 phy_write(phy, MII_CIS8201_EPCR, epcr);
306 /* MII regs override strap pins */
307 phy_write(phy, MII_CIS8201_ACSR,
308 phy_read(phy, MII_CIS8201_ACSR) | ACSR_PIN_PRIO_SELECT);
310 /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
311 phy_write(phy, MII_CIS8201_10BTCSR,
312 phy_read(phy, MII_CIS8201_10BTCSR) | TENBTCSR_ECHO_DISABLE);
317 static struct mii_phy_ops cis8201_phy_ops = {
318 .init = cis8201_init,
319 .setup_aneg = genmii_setup_aneg,
320 .setup_forced = genmii_setup_forced,
321 .poll_link = genmii_poll_link,
322 .read_link = genmii_read_link
325 static struct mii_phy_def cis8201_phy_def = {
326 .phy_id = 0x000fc410,
327 .phy_id_mask = 0x000ffff0,
328 .name = "CIS8201 Gigabit Ethernet",
329 .ops = &cis8201_phy_ops
332 static struct mii_phy_def *mii_phy_table[] = {
338 int mii_phy_probe(struct mii_phy *phy, int address)
340 struct mii_phy_def *def;
344 phy->autoneg = AUTONEG_DISABLE;
345 phy->advertising = 0;
346 phy->address = address;
347 phy->speed = SPEED_10;
348 phy->duplex = DUPLEX_HALF;
349 phy->pause = phy->asym_pause = 0;
351 /* Take PHY out of isolate mode and reset it. */
352 if (mii_reset_phy(phy))
355 /* Read ID and find matching entry */
356 id = (phy_read(phy, MII_PHYSID1) << 16) | phy_read(phy, MII_PHYSID2);
359 for (i = 0; (def = mii_phy_table[i]) != NULL; i++)
360 if ((id & def->phy_id_mask) == def->phy_id)
362 /* Should never be NULL (we have a generic entry), but... */
368 /* Determine PHY features if needed */
369 phy->features = def->features;
370 if (!phy->features) {
371 u16 bmsr = phy_read(phy, MII_BMSR);
372 if (bmsr & BMSR_ANEGCAPABLE)
373 phy->features |= SUPPORTED_Autoneg;
374 if (bmsr & BMSR_10HALF)
375 phy->features |= SUPPORTED_10baseT_Half;
376 if (bmsr & BMSR_10FULL)
377 phy->features |= SUPPORTED_10baseT_Full;
378 if (bmsr & BMSR_100HALF)
379 phy->features |= SUPPORTED_100baseT_Half;
380 if (bmsr & BMSR_100FULL)
381 phy->features |= SUPPORTED_100baseT_Full;
382 if (bmsr & BMSR_ESTATEN) {
383 u16 esr = phy_read(phy, MII_ESTATUS);
384 if (esr & ESTATUS_1000_TFULL)
385 phy->features |= SUPPORTED_1000baseT_Full;
386 if (esr & ESTATUS_1000_THALF)
387 phy->features |= SUPPORTED_1000baseT_Half;
389 phy->features |= SUPPORTED_MII;
392 /* Setup default advertising */
393 phy->advertising = phy->features;
398 MODULE_LICENSE("GPL");