2 * PHY drivers for the sungem ethernet driver.
4 * This file could be shared with other drivers.
6 * (c) 2002, Benjamin Herrenscmidt (benh@kernel.crashing.org)
10 * - Add support for PHYs that provide an IRQ line
11 * - Eventually moved the entire polling state machine in
12 * there (out of the eth driver), so that it can easily be
13 * skipped on PHYs that implement it in hardware.
14 * - On LXT971 & BCM5201, Apple uses some chip specific regs
15 * to read the link status. Figure out why and if it makes
16 * sense to do the same (magic aneg ?)
17 * - Apple has some additional power management code for some
18 * Broadcom PHYs that they "hide" from the OpenSource version
19 * of darwin, still need to reverse engineer that
22 #include <linux/config.h>
24 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/types.h>
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31 #include <linux/mii.h>
32 #include <linux/ethtool.h>
33 #include <linux/delay.h>
35 #include "sungem_phy.h"
37 /* Link modes of the BCM5400 PHY */
38 static int phy_BCM5400_link_table[8][3] = {
39 { 0, 0, 0 }, /* No link */
40 { 0, 0, 0 }, /* 10BT Half Duplex */
41 { 1, 0, 0 }, /* 10BT Full Duplex */
42 { 0, 1, 0 }, /* 100BT Half Duplex */
43 { 0, 1, 0 }, /* 100BT Half Duplex */
44 { 1, 1, 0 }, /* 100BT Full Duplex*/
45 { 1, 0, 1 }, /* 1000BT */
46 { 1, 0, 1 }, /* 1000BT */
49 static inline int __phy_read(struct mii_phy* phy, int id, int reg)
51 return phy->mdio_read(phy->dev, id, reg);
54 static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val)
56 phy->mdio_write(phy->dev, id, reg, val);
59 static inline int phy_read(struct mii_phy* phy, int reg)
61 return phy->mdio_read(phy->dev, phy->mii_id, reg);
64 static inline void phy_write(struct mii_phy* phy, int reg, int val)
66 phy->mdio_write(phy->dev, phy->mii_id, reg, val);
69 static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
74 val = __phy_read(phy, phy_id, MII_BMCR);
77 __phy_write(phy, phy_id, MII_BMCR, val);
82 val = __phy_read(phy, phy_id, MII_BMCR);
83 if ((val & BMCR_RESET) == 0)
87 if ((val & BMCR_ISOLATE) && limit > 0)
88 __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
93 static int bcm5201_init(struct mii_phy* phy)
97 data = phy_read(phy, MII_BCM5201_MULTIPHY);
98 data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
99 phy_write(phy, MII_BCM5201_MULTIPHY, data);
104 static int bcm5201_suspend(struct mii_phy* phy, int wol_options)
107 phy_write(phy, MII_BCM5201_INTERRUPT, 0);
109 /* Here's a strange hack used by both MacOS 9 and X */
110 phy_write(phy, MII_LPA, phy_read(phy, MII_LPA));
113 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
114 u16 val = phy_read(phy, MII_BCM5201_AUXMODE2)
115 phy_write(phy, MII_BCM5201_AUXMODE2,
116 val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
118 phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
124 static int bcm5400_init(struct mii_phy* phy)
128 /* Configure for gigabit full duplex */
129 data = phy_read(phy, MII_BCM5400_AUXCONTROL);
130 data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
131 phy_write(phy, MII_BCM5400_AUXCONTROL, data);
133 data = phy_read(phy, MII_BCM5400_GB_CONTROL);
134 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
135 phy_write(phy, MII_BCM5400_GB_CONTROL, data);
139 /* Reset and configure cascaded 10/100 PHY */
140 (void)reset_one_mii_phy(phy, 0x1f);
142 data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
143 data |= MII_BCM5201_MULTIPHY_SERIALMODE;
144 __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
146 data = phy_read(phy, MII_BCM5400_AUXCONTROL);
147 data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
148 phy_write(phy, MII_BCM5400_AUXCONTROL, data);
153 static int bcm5400_suspend(struct mii_phy* phy, int wol_options)
155 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
156 phy_write(phy, MII_BMCR, BMCR_PDOWN);
161 static int bcm5401_init(struct mii_phy* phy)
166 rev = phy_read(phy, MII_PHYSID2) & 0x000f;
167 if (rev == 0 || rev == 3) {
168 /* Some revisions of 5401 appear to need this
169 * initialisation sequence to disable, according
170 * to OF, "tap power management"
172 * WARNING ! OF and Darwin don't agree on the
173 * register addresses. OF seem to interpret the
174 * register numbers below as decimal
176 * Note: This should (and does) match tg3_init_5401phy_dsp
177 * in the tg3.c driver. -DaveM
179 phy_write(phy, 0x18, 0x0c20);
180 phy_write(phy, 0x17, 0x0012);
181 phy_write(phy, 0x15, 0x1804);
182 phy_write(phy, 0x17, 0x0013);
183 phy_write(phy, 0x15, 0x1204);
184 phy_write(phy, 0x17, 0x8006);
185 phy_write(phy, 0x15, 0x0132);
186 phy_write(phy, 0x17, 0x8006);
187 phy_write(phy, 0x15, 0x0232);
188 phy_write(phy, 0x17, 0x201f);
189 phy_write(phy, 0x15, 0x0a20);
192 /* Configure for gigabit full duplex */
193 data = phy_read(phy, MII_BCM5400_GB_CONTROL);
194 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
195 phy_write(phy, MII_BCM5400_GB_CONTROL, data);
199 /* Reset and configure cascaded 10/100 PHY */
200 (void)reset_one_mii_phy(phy, 0x1f);
202 data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
203 data |= MII_BCM5201_MULTIPHY_SERIALMODE;
204 __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
209 static int bcm5401_suspend(struct mii_phy* phy, int wol_options)
211 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
212 phy_write(phy, MII_BMCR, BMCR_PDOWN);
217 static int bcm5411_init(struct mii_phy* phy)
221 /* Here's some more Apple black magic to setup
222 * some voltage stuffs.
224 phy_write(phy, 0x1c, 0x8c23);
225 phy_write(phy, 0x1c, 0x8ca3);
226 phy_write(phy, 0x1c, 0x8c23);
228 /* Here, Apple seems to want to reset it, do
231 phy_write(phy, MII_BMCR, BMCR_RESET);
232 phy_write(phy, MII_BMCR, 0x1340);
234 data = phy_read(phy, MII_BCM5400_GB_CONTROL);
235 data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
236 phy_write(phy, MII_BCM5400_GB_CONTROL, data);
240 /* Reset and configure cascaded 10/100 PHY */
241 (void)reset_one_mii_phy(phy, 0x1f);
246 static int bcm5411_suspend(struct mii_phy* phy, int wol_options)
248 phy_write(phy, MII_BMCR, BMCR_PDOWN);
253 static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise)
258 phy->speed = SPEED_10;
259 phy->duplex = DUPLEX_HALF;
261 phy->advertising = advertise;
263 /* Setup standard advertise */
264 adv = phy_read(phy, MII_ADVERTISE);
265 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
266 if (advertise & ADVERTISED_10baseT_Half)
267 adv |= ADVERTISE_10HALF;
268 if (advertise & ADVERTISED_10baseT_Full)
269 adv |= ADVERTISE_10FULL;
270 if (advertise & ADVERTISED_100baseT_Half)
271 adv |= ADVERTISE_100HALF;
272 if (advertise & ADVERTISED_100baseT_Full)
273 adv |= ADVERTISE_100FULL;
274 phy_write(phy, MII_ADVERTISE, adv);
276 /* Setup 1000BT advertise */
277 adv = phy_read(phy, MII_1000BASETCONTROL);
278 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP);
279 if (advertise & SUPPORTED_1000baseT_Half)
280 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
281 if (advertise & SUPPORTED_1000baseT_Full)
282 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
283 phy_write(phy, MII_1000BASETCONTROL, adv);
285 /* Start/Restart aneg */
286 ctl = phy_read(phy, MII_BMCR);
287 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
288 phy_write(phy, MII_BMCR, ctl);
293 static int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd)
302 ctl = phy_read(phy, MII_BMCR);
303 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
305 /* First reset the PHY */
306 phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
308 /* Select speed & duplex */
313 ctl |= BMCR_SPEED100;
318 if (fd == DUPLEX_FULL)
319 ctl |= BMCR_FULLDPLX;
321 // XXX Should we set the sungem to GII now on 1000BT ?
323 phy_write(phy, MII_BMCR, ctl);
328 static int bcm54xx_read_link(struct mii_phy *phy)
334 val = phy_read(phy, MII_BCM5400_AUXSTATUS);
335 link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
336 MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
337 phy->duplex = phy_BCM5400_link_table[link_mode][0] ? DUPLEX_FULL : DUPLEX_HALF;
338 phy->speed = phy_BCM5400_link_table[link_mode][2] ?
340 (phy_BCM5400_link_table[link_mode][1] ? SPEED_100 : SPEED_10);
341 val = phy_read(phy, MII_LPA);
342 phy->pause = ((val & LPA_PAUSE) != 0);
344 /* On non-aneg, we assume what we put in BMCR is the speed,
345 * though magic-aneg shouldn't prevent this case from occurring
351 static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
356 phy->speed = SPEED_10;
357 phy->duplex = DUPLEX_HALF;
359 phy->advertising = advertise;
361 /* Setup standard advertise */
362 adv = phy_read(phy, MII_ADVERTISE);
363 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
364 if (advertise & ADVERTISED_10baseT_Half)
365 adv |= ADVERTISE_10HALF;
366 if (advertise & ADVERTISED_10baseT_Full)
367 adv |= ADVERTISE_10FULL;
368 if (advertise & ADVERTISED_100baseT_Half)
369 adv |= ADVERTISE_100HALF;
370 if (advertise & ADVERTISED_100baseT_Full)
371 adv |= ADVERTISE_100FULL;
372 phy_write(phy, MII_ADVERTISE, adv);
374 /* Setup 1000BT advertise & enable crossover detect
375 * XXX How do we advertise 1000BT ? Darwin source is
376 * confusing here, they read from specific control and
377 * write to control... Someone has specs for those
380 adv = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
381 adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX;
382 adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
383 MII_1000BASETCONTROL_HALFDUPLEXCAP);
384 if (advertise & SUPPORTED_1000baseT_Half)
385 adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
386 if (advertise & SUPPORTED_1000baseT_Full)
387 adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
388 phy_write(phy, MII_1000BASETCONTROL, adv);
390 /* Start/Restart aneg */
391 ctl = phy_read(phy, MII_BMCR);
392 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
393 phy_write(phy, MII_BMCR, ctl);
398 static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd)
407 ctl = phy_read(phy, MII_BMCR);
408 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
411 /* Select speed & duplex */
416 ctl |= BMCR_SPEED100;
418 /* I'm not sure about the one below, again, Darwin source is
419 * quite confusing and I lack chip specs
424 if (fd == DUPLEX_FULL)
425 ctl |= BMCR_FULLDPLX;
427 /* Disable crossover. Again, the way Apple does it is strange,
428 * though I don't assume they are wrong ;)
430 ctl2 = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
431 ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX |
432 MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX |
433 MII_1000BASETCONTROL_FULLDUPLEXCAP |
434 MII_1000BASETCONTROL_HALFDUPLEXCAP);
435 if (speed == SPEED_1000)
436 ctl2 |= (fd == DUPLEX_FULL) ?
437 MII_1000BASETCONTROL_FULLDUPLEXCAP :
438 MII_1000BASETCONTROL_HALFDUPLEXCAP;
439 phy_write(phy, MII_1000BASETCONTROL, ctl2);
441 // XXX Should we set the sungem to GII now on 1000BT ?
443 phy_write(phy, MII_BMCR, ctl);
448 static int marvell_read_link(struct mii_phy *phy)
453 status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS);
454 if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
456 if (status & MII_M1011_PHY_SPEC_STATUS_1000)
457 phy->speed = SPEED_1000;
458 else if (status & MII_M1011_PHY_SPEC_STATUS_100)
459 phy->speed = SPEED_100;
461 phy->speed = SPEED_10;
462 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
463 phy->duplex = DUPLEX_FULL;
465 phy->duplex = DUPLEX_HALF;
466 phy->pause = 0; /* XXX Check against spec ! */
468 /* On non-aneg, we assume what we put in BMCR is the speed,
469 * though magic-aneg shouldn't prevent this case from occurring
475 static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
480 phy->speed = SPEED_10;
481 phy->duplex = DUPLEX_HALF;
483 phy->advertising = advertise;
485 /* Setup standard advertise */
486 adv = phy_read(phy, MII_ADVERTISE);
487 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
488 if (advertise & ADVERTISED_10baseT_Half)
489 adv |= ADVERTISE_10HALF;
490 if (advertise & ADVERTISED_10baseT_Full)
491 adv |= ADVERTISE_10FULL;
492 if (advertise & ADVERTISED_100baseT_Half)
493 adv |= ADVERTISE_100HALF;
494 if (advertise & ADVERTISED_100baseT_Full)
495 adv |= ADVERTISE_100FULL;
496 phy_write(phy, MII_ADVERTISE, adv);
498 /* Start/Restart aneg */
499 ctl = phy_read(phy, MII_BMCR);
500 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
501 phy_write(phy, MII_BMCR, ctl);
506 static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
515 ctl = phy_read(phy, MII_BMCR);
516 ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
518 /* First reset the PHY */
519 phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
521 /* Select speed & duplex */
526 ctl |= BMCR_SPEED100;
532 if (fd == DUPLEX_FULL)
533 ctl |= BMCR_FULLDPLX;
534 phy_write(phy, MII_BMCR, ctl);
539 static int genmii_poll_link(struct mii_phy *phy)
543 (void)phy_read(phy, MII_BMSR);
544 status = phy_read(phy, MII_BMSR);
545 if ((status & BMSR_LSTATUS) == 0)
547 if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
552 static int genmii_read_link(struct mii_phy *phy)
557 lpa = phy_read(phy, MII_LPA);
559 if (lpa & (LPA_10FULL | LPA_100FULL))
560 phy->duplex = DUPLEX_FULL;
562 phy->duplex = DUPLEX_HALF;
563 if (lpa & (LPA_100FULL | LPA_100HALF))
564 phy->speed = SPEED_100;
566 phy->speed = SPEED_10;
569 /* On non-aneg, we assume what we put in BMCR is the speed,
570 * though magic-aneg shouldn't prevent this case from occurring
577 #define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
578 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
579 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
580 #define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
581 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
583 /* Broadcom BCM 5201 */
584 static struct mii_phy_ops bcm5201_phy_ops = {
586 suspend: bcm5201_suspend,
587 setup_aneg: genmii_setup_aneg,
588 setup_forced: genmii_setup_forced,
589 poll_link: genmii_poll_link,
590 read_link: genmii_read_link,
593 static struct mii_phy_def bcm5201_phy_def = {
595 phy_id_mask: 0xfffffff0,
597 features: MII_BASIC_FEATURES,
599 ops: &bcm5201_phy_ops
602 /* Broadcom BCM 5221 */
603 static struct mii_phy_ops bcm5221_phy_ops = {
604 suspend: bcm5201_suspend,
605 setup_aneg: genmii_setup_aneg,
606 setup_forced: genmii_setup_forced,
607 poll_link: genmii_poll_link,
608 read_link: genmii_read_link,
611 static struct mii_phy_def bcm5221_phy_def = {
613 phy_id_mask: 0xfffffff0,
615 features: MII_BASIC_FEATURES,
617 ops: &bcm5221_phy_ops
620 /* Broadcom BCM 5400 */
621 static struct mii_phy_ops bcm5400_phy_ops = {
623 suspend: bcm5400_suspend,
624 setup_aneg: bcm54xx_setup_aneg,
625 setup_forced: bcm54xx_setup_forced,
626 poll_link: genmii_poll_link,
627 read_link: bcm54xx_read_link,
630 static struct mii_phy_def bcm5400_phy_def = {
632 phy_id_mask: 0xfffffff0,
634 features: MII_GBIT_FEATURES,
636 ops: &bcm5400_phy_ops
639 /* Broadcom BCM 5401 */
640 static struct mii_phy_ops bcm5401_phy_ops = {
642 suspend: bcm5401_suspend,
643 setup_aneg: bcm54xx_setup_aneg,
644 setup_forced: bcm54xx_setup_forced,
645 poll_link: genmii_poll_link,
646 read_link: bcm54xx_read_link,
649 static struct mii_phy_def bcm5401_phy_def = {
651 phy_id_mask: 0xfffffff0,
653 features: MII_GBIT_FEATURES,
655 ops: &bcm5401_phy_ops
658 /* Broadcom BCM 5411 */
659 static struct mii_phy_ops bcm5411_phy_ops = {
661 suspend: bcm5411_suspend,
662 setup_aneg: bcm54xx_setup_aneg,
663 setup_forced: bcm54xx_setup_forced,
664 poll_link: genmii_poll_link,
665 read_link: bcm54xx_read_link,
668 static struct mii_phy_def bcm5411_phy_def = {
670 phy_id_mask: 0xfffffff0,
672 features: MII_GBIT_FEATURES,
674 ops: &bcm5411_phy_ops
677 /* Broadcom BCM 5421 */
678 static struct mii_phy_ops bcm5421_phy_ops = {
679 suspend: bcm5411_suspend,
680 setup_aneg: bcm54xx_setup_aneg,
681 setup_forced: bcm54xx_setup_forced,
682 poll_link: genmii_poll_link,
683 read_link: bcm54xx_read_link,
686 static struct mii_phy_def bcm5421_phy_def = {
688 phy_id_mask: 0xfffffff0,
690 features: MII_GBIT_FEATURES,
692 ops: &bcm5421_phy_ops
695 /* Marvell 88E1101 (Apple seem to deal with 2 different revs,
696 * I masked out the 8 last bits to get both, but some specs
697 * would be useful here) --BenH.
699 static struct mii_phy_ops marvell_phy_ops = {
700 setup_aneg: marvell_setup_aneg,
701 setup_forced: marvell_setup_forced,
702 poll_link: genmii_poll_link,
703 read_link: marvell_read_link
706 static struct mii_phy_def marvell_phy_def = {
708 phy_id_mask: 0xffffff00,
709 name: "Marvell 88E1101",
710 features: MII_GBIT_FEATURES,
712 ops: &marvell_phy_ops
715 /* Generic implementation for most 10/100 PHYs */
716 static struct mii_phy_ops generic_phy_ops = {
717 setup_aneg: genmii_setup_aneg,
718 setup_forced: genmii_setup_forced,
719 poll_link: genmii_poll_link,
720 read_link: genmii_read_link
723 static struct mii_phy_def genmii_phy_def = {
725 phy_id_mask: 0x00000000,
727 features: MII_BASIC_FEATURES,
729 ops: &generic_phy_ops
732 static struct mii_phy_def* mii_phy_table[] = {
744 int mii_phy_probe(struct mii_phy *phy, int mii_id)
748 struct mii_phy_def* def;
752 phy->advertising = 0;
753 phy->mii_id = mii_id;
758 /* Take PHY out of isloate mode and reset it. */
759 rc = reset_one_mii_phy(phy, mii_id);
763 /* Read ID and find matching entry */
764 id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
766 for (i=0; (def = mii_phy_table[i]) != NULL; i++)
767 if ((id & def->phy_id_mask) == def->phy_id)
769 /* Should never be NULL (we have a generic entry), but... */
775 /* Setup default advertising */
776 phy->advertising = def->features;
781 EXPORT_SYMBOL(mii_phy_probe);
782 MODULE_LICENSE("GPL");