2 * PHY drivers for the sungem ethernet driver.
4 * This file could be shared with other drivers.
6 * (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org)
9 * - Add support for PHYs that provide an IRQ line
10 * - Eventually moved the entire polling state machine in
11 * there (out of the eth driver), so that it can easily be
12 * skipped on PHYs that implement it in hardware.
13 * - On LXT971 & BCM5201, Apple uses some chip specific regs
14 * to read the link status. Figure out why and if it makes
15 * sense to do the same (magic aneg ?)
16 * - Apple has some additional power management code for some
17 * Broadcom PHYs that they "hide" from the OpenSource version
18 * of darwin, still need to reverse engineer that
22 #include <linux/module.h>
24 #include <linux/kernel.h>
25 #include <linux/types.h>
26 #include <linux/netdevice.h>
27 #include <linux/etherdevice.h>
28 #include <linux/mii.h>
29 #include <linux/ethtool.h>
30 #include <linux/delay.h>
32 #ifdef CONFIG_PPC_PMAC
36 #include "sungem_phy.h"
38 /* Link modes of the BCM5400 PHY */
39 static const int phy_BCM5400_link_table
[8][3] = {
40 { 0, 0, 0 }, /* No link */
41 { 0, 0, 0 }, /* 10BT Half Duplex */
42 { 1, 0, 0 }, /* 10BT Full Duplex */
43 { 0, 1, 0 }, /* 100BT Half Duplex */
44 { 0, 1, 0 }, /* 100BT Half Duplex */
45 { 1, 1, 0 }, /* 100BT Full Duplex*/
46 { 1, 0, 1 }, /* 1000BT */
47 { 1, 0, 1 }, /* 1000BT */
50 static inline int __phy_read(struct mii_phy
* phy
, int id
, int reg
)
52 return phy
->mdio_read(phy
->dev
, id
, reg
);
55 static inline void __phy_write(struct mii_phy
* phy
, int id
, int reg
, int val
)
57 phy
->mdio_write(phy
->dev
, id
, reg
, val
);
60 static inline int phy_read(struct mii_phy
* phy
, int reg
)
62 return phy
->mdio_read(phy
->dev
, phy
->mii_id
, reg
);
65 static inline void phy_write(struct mii_phy
* phy
, int reg
, int val
)
67 phy
->mdio_write(phy
->dev
, phy
->mii_id
, reg
, val
);
70 static int reset_one_mii_phy(struct mii_phy
* phy
, int phy_id
)
75 val
= __phy_read(phy
, phy_id
, MII_BMCR
);
76 val
&= ~(BMCR_ISOLATE
| BMCR_PDOWN
);
78 __phy_write(phy
, phy_id
, MII_BMCR
, val
);
83 val
= __phy_read(phy
, phy_id
, MII_BMCR
);
84 if ((val
& BMCR_RESET
) == 0)
88 if ((val
& BMCR_ISOLATE
) && limit
> 0)
89 __phy_write(phy
, phy_id
, MII_BMCR
, val
& ~BMCR_ISOLATE
);
94 static int bcm5201_init(struct mii_phy
* phy
)
98 data
= phy_read(phy
, MII_BCM5201_MULTIPHY
);
99 data
&= ~MII_BCM5201_MULTIPHY_SUPERISOLATE
;
100 phy_write(phy
, MII_BCM5201_MULTIPHY
, data
);
102 phy_write(phy
, MII_BCM5201_INTERRUPT
, 0);
107 static int bcm5201_suspend(struct mii_phy
* phy
)
109 phy_write(phy
, MII_BCM5201_INTERRUPT
, 0);
110 phy_write(phy
, MII_BCM5201_MULTIPHY
, MII_BCM5201_MULTIPHY_SUPERISOLATE
);
115 static int bcm5221_init(struct mii_phy
* phy
)
119 data
= phy_read(phy
, MII_BCM5221_TEST
);
120 phy_write(phy
, MII_BCM5221_TEST
,
121 data
| MII_BCM5221_TEST_ENABLE_SHADOWS
);
123 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_STAT2
);
124 phy_write(phy
, MII_BCM5221_SHDOW_AUX_STAT2
,
125 data
| MII_BCM5221_SHDOW_AUX_STAT2_APD
);
127 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_MODE4
);
128 phy_write(phy
, MII_BCM5221_SHDOW_AUX_MODE4
,
129 data
| MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR
);
131 data
= phy_read(phy
, MII_BCM5221_TEST
);
132 phy_write(phy
, MII_BCM5221_TEST
,
133 data
& ~MII_BCM5221_TEST_ENABLE_SHADOWS
);
138 static int bcm5221_suspend(struct mii_phy
* phy
)
142 data
= phy_read(phy
, MII_BCM5221_TEST
);
143 phy_write(phy
, MII_BCM5221_TEST
,
144 data
| MII_BCM5221_TEST_ENABLE_SHADOWS
);
146 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_MODE4
);
147 phy_write(phy
, MII_BCM5221_SHDOW_AUX_MODE4
,
148 data
| MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE
);
153 static int bcm5241_init(struct mii_phy
* phy
)
157 data
= phy_read(phy
, MII_BCM5221_TEST
);
158 phy_write(phy
, MII_BCM5221_TEST
,
159 data
| MII_BCM5221_TEST_ENABLE_SHADOWS
);
161 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_STAT2
);
162 phy_write(phy
, MII_BCM5221_SHDOW_AUX_STAT2
,
163 data
| MII_BCM5221_SHDOW_AUX_STAT2_APD
);
165 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_MODE4
);
166 phy_write(phy
, MII_BCM5221_SHDOW_AUX_MODE4
,
167 data
& ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR
);
169 data
= phy_read(phy
, MII_BCM5221_TEST
);
170 phy_write(phy
, MII_BCM5221_TEST
,
171 data
& ~MII_BCM5221_TEST_ENABLE_SHADOWS
);
176 static int bcm5241_suspend(struct mii_phy
* phy
)
180 data
= phy_read(phy
, MII_BCM5221_TEST
);
181 phy_write(phy
, MII_BCM5221_TEST
,
182 data
| MII_BCM5221_TEST_ENABLE_SHADOWS
);
184 data
= phy_read(phy
, MII_BCM5221_SHDOW_AUX_MODE4
);
185 phy_write(phy
, MII_BCM5221_SHDOW_AUX_MODE4
,
186 data
| MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR
);
191 static int bcm5400_init(struct mii_phy
* phy
)
195 /* Configure for gigabit full duplex */
196 data
= phy_read(phy
, MII_BCM5400_AUXCONTROL
);
197 data
|= MII_BCM5400_AUXCONTROL_PWR10BASET
;
198 phy_write(phy
, MII_BCM5400_AUXCONTROL
, data
);
200 data
= phy_read(phy
, MII_BCM5400_GB_CONTROL
);
201 data
|= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP
;
202 phy_write(phy
, MII_BCM5400_GB_CONTROL
, data
);
206 /* Reset and configure cascaded 10/100 PHY */
207 (void)reset_one_mii_phy(phy
, 0x1f);
209 data
= __phy_read(phy
, 0x1f, MII_BCM5201_MULTIPHY
);
210 data
|= MII_BCM5201_MULTIPHY_SERIALMODE
;
211 __phy_write(phy
, 0x1f, MII_BCM5201_MULTIPHY
, data
);
213 data
= phy_read(phy
, MII_BCM5400_AUXCONTROL
);
214 data
&= ~MII_BCM5400_AUXCONTROL_PWR10BASET
;
215 phy_write(phy
, MII_BCM5400_AUXCONTROL
, data
);
220 static int bcm5400_suspend(struct mii_phy
* phy
)
225 static int bcm5401_init(struct mii_phy
* phy
)
230 rev
= phy_read(phy
, MII_PHYSID2
) & 0x000f;
231 if (rev
== 0 || rev
== 3) {
232 /* Some revisions of 5401 appear to need this
233 * initialisation sequence to disable, according
234 * to OF, "tap power management"
236 * WARNING ! OF and Darwin don't agree on the
237 * register addresses. OF seem to interpret the
238 * register numbers below as decimal
240 * Note: This should (and does) match tg3_init_5401phy_dsp
241 * in the tg3.c driver. -DaveM
243 phy_write(phy
, 0x18, 0x0c20);
244 phy_write(phy
, 0x17, 0x0012);
245 phy_write(phy
, 0x15, 0x1804);
246 phy_write(phy
, 0x17, 0x0013);
247 phy_write(phy
, 0x15, 0x1204);
248 phy_write(phy
, 0x17, 0x8006);
249 phy_write(phy
, 0x15, 0x0132);
250 phy_write(phy
, 0x17, 0x8006);
251 phy_write(phy
, 0x15, 0x0232);
252 phy_write(phy
, 0x17, 0x201f);
253 phy_write(phy
, 0x15, 0x0a20);
256 /* Configure for gigabit full duplex */
257 data
= phy_read(phy
, MII_BCM5400_GB_CONTROL
);
258 data
|= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP
;
259 phy_write(phy
, MII_BCM5400_GB_CONTROL
, data
);
263 /* Reset and configure cascaded 10/100 PHY */
264 (void)reset_one_mii_phy(phy
, 0x1f);
266 data
= __phy_read(phy
, 0x1f, MII_BCM5201_MULTIPHY
);
267 data
|= MII_BCM5201_MULTIPHY_SERIALMODE
;
268 __phy_write(phy
, 0x1f, MII_BCM5201_MULTIPHY
, data
);
273 static int bcm5401_suspend(struct mii_phy
* phy
)
278 static int bcm5411_init(struct mii_phy
* phy
)
282 /* Here's some more Apple black magic to setup
283 * some voltage stuffs.
285 phy_write(phy
, 0x1c, 0x8c23);
286 phy_write(phy
, 0x1c, 0x8ca3);
287 phy_write(phy
, 0x1c, 0x8c23);
289 /* Here, Apple seems to want to reset it, do
292 phy_write(phy
, MII_BMCR
, BMCR_RESET
);
293 phy_write(phy
, MII_BMCR
, 0x1340);
295 data
= phy_read(phy
, MII_BCM5400_GB_CONTROL
);
296 data
|= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP
;
297 phy_write(phy
, MII_BCM5400_GB_CONTROL
, data
);
301 /* Reset and configure cascaded 10/100 PHY */
302 (void)reset_one_mii_phy(phy
, 0x1f);
307 static int genmii_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
312 phy
->speed
= SPEED_10
;
313 phy
->duplex
= DUPLEX_HALF
;
315 phy
->advertising
= advertise
;
317 /* Setup standard advertise */
318 adv
= phy_read(phy
, MII_ADVERTISE
);
319 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
320 if (advertise
& ADVERTISED_10baseT_Half
)
321 adv
|= ADVERTISE_10HALF
;
322 if (advertise
& ADVERTISED_10baseT_Full
)
323 adv
|= ADVERTISE_10FULL
;
324 if (advertise
& ADVERTISED_100baseT_Half
)
325 adv
|= ADVERTISE_100HALF
;
326 if (advertise
& ADVERTISED_100baseT_Full
)
327 adv
|= ADVERTISE_100FULL
;
328 phy_write(phy
, MII_ADVERTISE
, adv
);
330 /* Start/Restart aneg */
331 ctl
= phy_read(phy
, MII_BMCR
);
332 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
333 phy_write(phy
, MII_BMCR
, ctl
);
338 static int genmii_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
347 ctl
= phy_read(phy
, MII_BMCR
);
348 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_ANENABLE
);
350 /* First reset the PHY */
351 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
353 /* Select speed & duplex */
358 ctl
|= BMCR_SPEED100
;
364 if (fd
== DUPLEX_FULL
)
365 ctl
|= BMCR_FULLDPLX
;
366 phy_write(phy
, MII_BMCR
, ctl
);
371 static int genmii_poll_link(struct mii_phy
*phy
)
375 (void)phy_read(phy
, MII_BMSR
);
376 status
= phy_read(phy
, MII_BMSR
);
377 if ((status
& BMSR_LSTATUS
) == 0)
379 if (phy
->autoneg
&& !(status
& BMSR_ANEGCOMPLETE
))
384 static int genmii_read_link(struct mii_phy
*phy
)
389 lpa
= phy_read(phy
, MII_LPA
);
391 if (lpa
& (LPA_10FULL
| LPA_100FULL
))
392 phy
->duplex
= DUPLEX_FULL
;
394 phy
->duplex
= DUPLEX_HALF
;
395 if (lpa
& (LPA_100FULL
| LPA_100HALF
))
396 phy
->speed
= SPEED_100
;
398 phy
->speed
= SPEED_10
;
401 /* On non-aneg, we assume what we put in BMCR is the speed,
402 * though magic-aneg shouldn't prevent this case from occurring
408 static int generic_suspend(struct mii_phy
* phy
)
410 phy_write(phy
, MII_BMCR
, BMCR_PDOWN
);
415 static int bcm5421_init(struct mii_phy
* phy
)
420 id
= (phy_read(phy
, MII_PHYSID1
) << 16 | phy_read(phy
, MII_PHYSID2
));
422 /* Revision 0 of 5421 needs some fixups */
423 if (id
== 0x002060e0) {
424 /* This is borrowed from MacOS
426 phy_write(phy
, 0x18, 0x1007);
427 data
= phy_read(phy
, 0x18);
428 phy_write(phy
, 0x18, data
| 0x0400);
429 phy_write(phy
, 0x18, 0x0007);
430 data
= phy_read(phy
, 0x18);
431 phy_write(phy
, 0x18, data
| 0x0800);
432 phy_write(phy
, 0x17, 0x000a);
433 data
= phy_read(phy
, 0x15);
434 phy_write(phy
, 0x15, data
| 0x0200);
437 /* Pick up some init code from OF for K2 version */
438 if ((id
& 0xfffffff0) == 0x002062e0) {
439 phy_write(phy
, 4, 0x01e1);
440 phy_write(phy
, 9, 0x0300);
443 /* Check if we can enable automatic low power */
444 #ifdef CONFIG_PPC_PMAC
445 if (phy
->platform_data
) {
446 struct device_node
*np
= of_get_parent(phy
->platform_data
);
447 int can_low_power
= 1;
448 if (np
== NULL
|| of_get_property(np
, "no-autolowpower", NULL
))
451 /* Enable automatic low-power */
452 phy_write(phy
, 0x1c, 0x9002);
453 phy_write(phy
, 0x1c, 0xa821);
454 phy_write(phy
, 0x1c, 0x941d);
457 #endif /* CONFIG_PPC_PMAC */
462 static int bcm54xx_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
467 phy
->speed
= SPEED_10
;
468 phy
->duplex
= DUPLEX_HALF
;
470 phy
->advertising
= advertise
;
472 /* Setup standard advertise */
473 adv
= phy_read(phy
, MII_ADVERTISE
);
474 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
475 if (advertise
& ADVERTISED_10baseT_Half
)
476 adv
|= ADVERTISE_10HALF
;
477 if (advertise
& ADVERTISED_10baseT_Full
)
478 adv
|= ADVERTISE_10FULL
;
479 if (advertise
& ADVERTISED_100baseT_Half
)
480 adv
|= ADVERTISE_100HALF
;
481 if (advertise
& ADVERTISED_100baseT_Full
)
482 adv
|= ADVERTISE_100FULL
;
483 if (advertise
& ADVERTISED_Pause
)
484 adv
|= ADVERTISE_PAUSE_CAP
;
485 if (advertise
& ADVERTISED_Asym_Pause
)
486 adv
|= ADVERTISE_PAUSE_ASYM
;
487 phy_write(phy
, MII_ADVERTISE
, adv
);
489 /* Setup 1000BT advertise */
490 adv
= phy_read(phy
, MII_1000BASETCONTROL
);
491 adv
&= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP
|MII_1000BASETCONTROL_HALFDUPLEXCAP
);
492 if (advertise
& SUPPORTED_1000baseT_Half
)
493 adv
|= MII_1000BASETCONTROL_HALFDUPLEXCAP
;
494 if (advertise
& SUPPORTED_1000baseT_Full
)
495 adv
|= MII_1000BASETCONTROL_FULLDUPLEXCAP
;
496 phy_write(phy
, MII_1000BASETCONTROL
, 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 bcm54xx_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
515 ctl
= phy_read(phy
, MII_BMCR
);
516 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_SPD2
|BMCR_ANENABLE
);
518 /* First reset the PHY */
519 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
521 /* Select speed & duplex */
526 ctl
|= BMCR_SPEED100
;
531 if (fd
== DUPLEX_FULL
)
532 ctl
|= BMCR_FULLDPLX
;
535 phy_write(phy
, MII_BMCR
, ctl
);
540 static int bcm54xx_read_link(struct mii_phy
*phy
)
546 val
= phy_read(phy
, MII_BCM5400_AUXSTATUS
);
547 link_mode
= ((val
& MII_BCM5400_AUXSTATUS_LINKMODE_MASK
) >>
548 MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT
);
549 phy
->duplex
= phy_BCM5400_link_table
[link_mode
][0] ?
550 DUPLEX_FULL
: DUPLEX_HALF
;
551 phy
->speed
= phy_BCM5400_link_table
[link_mode
][2] ?
553 (phy_BCM5400_link_table
[link_mode
][1] ?
554 SPEED_100
: SPEED_10
);
555 val
= phy_read(phy
, MII_LPA
);
556 phy
->pause
= (phy
->duplex
== DUPLEX_FULL
) &&
557 ((val
& LPA_PAUSE
) != 0);
559 /* On non-aneg, we assume what we put in BMCR is the speed,
560 * though magic-aneg shouldn't prevent this case from occurring
566 static int marvell88e1111_init(struct mii_phy
* phy
)
570 /* magic init sequence for rev 0 */
571 rev
= phy_read(phy
, MII_PHYSID2
) & 0x000f;
573 phy_write(phy
, 0x1d, 0x000a);
574 phy_write(phy
, 0x1e, 0x0821);
576 phy_write(phy
, 0x1d, 0x0006);
577 phy_write(phy
, 0x1e, 0x8600);
579 phy_write(phy
, 0x1d, 0x000b);
580 phy_write(phy
, 0x1e, 0x0100);
582 phy_write(phy
, 0x1d, 0x0004);
583 phy_write(phy
, 0x1e, 0x4850);
588 #define BCM5421_MODE_MASK (1 << 5)
590 static int bcm5421_poll_link(struct mii_phy
* phy
)
595 /* find out in what mode we are */
596 phy_write(phy
, MII_NCONFIG
, 0x1000);
597 phy_reg
= phy_read(phy
, MII_NCONFIG
);
599 mode
= (phy_reg
& BCM5421_MODE_MASK
) >> 5;
601 if ( mode
== BCM54XX_COPPER
)
602 return genmii_poll_link(phy
);
604 /* try to find out wether we have a link */
605 phy_write(phy
, MII_NCONFIG
, 0x2000);
606 phy_reg
= phy_read(phy
, MII_NCONFIG
);
608 if (phy_reg
& 0x0020)
614 static int bcm5421_read_link(struct mii_phy
* phy
)
619 /* find out in what mode we are */
620 phy_write(phy
, MII_NCONFIG
, 0x1000);
621 phy_reg
= phy_read(phy
, MII_NCONFIG
);
623 mode
= (phy_reg
& BCM5421_MODE_MASK
) >> 5;
625 if ( mode
== BCM54XX_COPPER
)
626 return bcm54xx_read_link(phy
);
628 phy
->speed
= SPEED_1000
;
630 /* find out wether we are running half- or full duplex */
631 phy_write(phy
, MII_NCONFIG
, 0x2000);
632 phy_reg
= phy_read(phy
, MII_NCONFIG
);
634 if ( (phy_reg
& 0x0080) >> 7)
635 phy
->duplex
|= DUPLEX_HALF
;
637 phy
->duplex
|= DUPLEX_FULL
;
642 static int bcm5421_enable_fiber(struct mii_phy
* phy
, int autoneg
)
644 /* enable fiber mode */
645 phy_write(phy
, MII_NCONFIG
, 0x9020);
646 /* LEDs active in both modes, autosense prio = fiber */
647 phy_write(phy
, MII_NCONFIG
, 0x945f);
650 /* switch off fibre autoneg */
651 phy_write(phy
, MII_NCONFIG
, 0xfc01);
652 phy_write(phy
, 0x0b, 0x0004);
655 phy
->autoneg
= autoneg
;
660 #define BCM5461_FIBER_LINK (1 << 2)
661 #define BCM5461_MODE_MASK (3 << 1)
663 static int bcm5461_poll_link(struct mii_phy
* phy
)
668 /* find out in what mode we are */
669 phy_write(phy
, MII_NCONFIG
, 0x7c00);
670 phy_reg
= phy_read(phy
, MII_NCONFIG
);
672 mode
= (phy_reg
& BCM5461_MODE_MASK
) >> 1;
674 if ( mode
== BCM54XX_COPPER
)
675 return genmii_poll_link(phy
);
677 /* find out wether we have a link */
678 phy_write(phy
, MII_NCONFIG
, 0x7000);
679 phy_reg
= phy_read(phy
, MII_NCONFIG
);
681 if (phy_reg
& BCM5461_FIBER_LINK
)
687 #define BCM5461_FIBER_DUPLEX (1 << 3)
689 static int bcm5461_read_link(struct mii_phy
* phy
)
694 /* find out in what mode we are */
695 phy_write(phy
, MII_NCONFIG
, 0x7c00);
696 phy_reg
= phy_read(phy
, MII_NCONFIG
);
698 mode
= (phy_reg
& BCM5461_MODE_MASK
) >> 1;
700 if ( mode
== BCM54XX_COPPER
) {
701 return bcm54xx_read_link(phy
);
704 phy
->speed
= SPEED_1000
;
706 /* find out wether we are running half- or full duplex */
707 phy_write(phy
, MII_NCONFIG
, 0x7000);
708 phy_reg
= phy_read(phy
, MII_NCONFIG
);
710 if (phy_reg
& BCM5461_FIBER_DUPLEX
)
711 phy
->duplex
|= DUPLEX_FULL
;
713 phy
->duplex
|= DUPLEX_HALF
;
718 static int bcm5461_enable_fiber(struct mii_phy
* phy
, int autoneg
)
720 /* select fiber mode, enable 1000 base-X registers */
721 phy_write(phy
, MII_NCONFIG
, 0xfc0b);
724 /* enable fiber with no autonegotiation */
725 phy_write(phy
, MII_ADVERTISE
, 0x01e0);
726 phy_write(phy
, MII_BMCR
, 0x1140);
728 /* enable fiber with autonegotiation */
729 phy_write(phy
, MII_BMCR
, 0x0140);
732 phy
->autoneg
= autoneg
;
737 static int marvell_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
742 phy
->speed
= SPEED_10
;
743 phy
->duplex
= DUPLEX_HALF
;
745 phy
->advertising
= advertise
;
747 /* Setup standard advertise */
748 adv
= phy_read(phy
, MII_ADVERTISE
);
749 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
750 if (advertise
& ADVERTISED_10baseT_Half
)
751 adv
|= ADVERTISE_10HALF
;
752 if (advertise
& ADVERTISED_10baseT_Full
)
753 adv
|= ADVERTISE_10FULL
;
754 if (advertise
& ADVERTISED_100baseT_Half
)
755 adv
|= ADVERTISE_100HALF
;
756 if (advertise
& ADVERTISED_100baseT_Full
)
757 adv
|= ADVERTISE_100FULL
;
758 if (advertise
& ADVERTISED_Pause
)
759 adv
|= ADVERTISE_PAUSE_CAP
;
760 if (advertise
& ADVERTISED_Asym_Pause
)
761 adv
|= ADVERTISE_PAUSE_ASYM
;
762 phy_write(phy
, MII_ADVERTISE
, adv
);
764 adv
= phy_read(phy
, MII_M1011_PHY_SPEC_CONTROL
);
765 adv
|= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX
;
766 adv
&= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP
|
767 MII_1000BASETCONTROL_HALFDUPLEXCAP
);
768 if (advertise
& SUPPORTED_1000baseT_Half
)
769 adv
|= MII_1000BASETCONTROL_HALFDUPLEXCAP
;
770 if (advertise
& SUPPORTED_1000baseT_Full
)
771 adv
|= MII_1000BASETCONTROL_FULLDUPLEXCAP
;
772 phy_write(phy
, MII_1000BASETCONTROL
, adv
);
774 /* Start/Restart aneg */
775 ctl
= phy_read(phy
, MII_BMCR
);
776 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
777 phy_write(phy
, MII_BMCR
, ctl
);
782 static int marvell_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
791 ctl
= phy_read(phy
, MII_BMCR
);
792 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_SPD2
|BMCR_ANENABLE
);
795 /* Select speed & duplex */
800 ctl
|= BMCR_SPEED100
;
802 /* I'm not sure about the one below, again, Darwin source is
803 * quite confusing and I lack chip specs
808 if (fd
== DUPLEX_FULL
)
809 ctl
|= BMCR_FULLDPLX
;
811 /* Disable crossover. Again, the way Apple does it is strange,
812 * though I don't assume they are wrong ;)
814 ctl2
= phy_read(phy
, MII_M1011_PHY_SPEC_CONTROL
);
815 ctl2
&= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX
|
816 MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX
|
817 MII_1000BASETCONTROL_FULLDUPLEXCAP
|
818 MII_1000BASETCONTROL_HALFDUPLEXCAP
);
819 if (speed
== SPEED_1000
)
820 ctl2
|= (fd
== DUPLEX_FULL
) ?
821 MII_1000BASETCONTROL_FULLDUPLEXCAP
:
822 MII_1000BASETCONTROL_HALFDUPLEXCAP
;
823 phy_write(phy
, MII_1000BASETCONTROL
, ctl2
);
826 phy_write(phy
, MII_BMCR
, ctl
);
831 static int marvell_read_link(struct mii_phy
*phy
)
836 status
= phy_read(phy
, MII_M1011_PHY_SPEC_STATUS
);
837 if ((status
& MII_M1011_PHY_SPEC_STATUS_RESOLVED
) == 0)
839 if (status
& MII_M1011_PHY_SPEC_STATUS_1000
)
840 phy
->speed
= SPEED_1000
;
841 else if (status
& MII_M1011_PHY_SPEC_STATUS_100
)
842 phy
->speed
= SPEED_100
;
844 phy
->speed
= SPEED_10
;
845 if (status
& MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX
)
846 phy
->duplex
= DUPLEX_FULL
;
848 phy
->duplex
= DUPLEX_HALF
;
849 pmask
= MII_M1011_PHY_SPEC_STATUS_TX_PAUSE
|
850 MII_M1011_PHY_SPEC_STATUS_RX_PAUSE
;
851 phy
->pause
= (status
& pmask
) == pmask
;
853 /* On non-aneg, we assume what we put in BMCR is the speed,
854 * though magic-aneg shouldn't prevent this case from occurring
860 #define MII_BASIC_FEATURES \
861 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
862 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
863 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \
866 /* On gigabit capable PHYs, we advertise Pause support but not asym pause
867 * support for now as I'm not sure it's supported and Darwin doesn't do
868 * it neither. --BenH.
870 #define MII_GBIT_FEATURES \
871 (MII_BASIC_FEATURES | \
872 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
874 /* Broadcom BCM 5201 */
875 static struct mii_phy_ops bcm5201_phy_ops
= {
876 .init
= bcm5201_init
,
877 .suspend
= bcm5201_suspend
,
878 .setup_aneg
= genmii_setup_aneg
,
879 .setup_forced
= genmii_setup_forced
,
880 .poll_link
= genmii_poll_link
,
881 .read_link
= genmii_read_link
,
884 static struct mii_phy_def bcm5201_phy_def
= {
885 .phy_id
= 0x00406210,
886 .phy_id_mask
= 0xfffffff0,
888 .features
= MII_BASIC_FEATURES
,
890 .ops
= &bcm5201_phy_ops
893 /* Broadcom BCM 5221 */
894 static struct mii_phy_ops bcm5221_phy_ops
= {
895 .suspend
= bcm5221_suspend
,
896 .init
= bcm5221_init
,
897 .setup_aneg
= genmii_setup_aneg
,
898 .setup_forced
= genmii_setup_forced
,
899 .poll_link
= genmii_poll_link
,
900 .read_link
= genmii_read_link
,
903 static struct mii_phy_def bcm5221_phy_def
= {
904 .phy_id
= 0x004061e0,
905 .phy_id_mask
= 0xfffffff0,
907 .features
= MII_BASIC_FEATURES
,
909 .ops
= &bcm5221_phy_ops
912 /* Broadcom BCM 5241 */
913 static struct mii_phy_ops bcm5241_phy_ops
= {
914 .suspend
= bcm5241_suspend
,
915 .init
= bcm5241_init
,
916 .setup_aneg
= genmii_setup_aneg
,
917 .setup_forced
= genmii_setup_forced
,
918 .poll_link
= genmii_poll_link
,
919 .read_link
= genmii_read_link
,
921 static struct mii_phy_def bcm5241_phy_def
= {
922 .phy_id
= 0x0143bc30,
923 .phy_id_mask
= 0xfffffff0,
925 .features
= MII_BASIC_FEATURES
,
927 .ops
= &bcm5241_phy_ops
930 /* Broadcom BCM 5400 */
931 static struct mii_phy_ops bcm5400_phy_ops
= {
932 .init
= bcm5400_init
,
933 .suspend
= bcm5400_suspend
,
934 .setup_aneg
= bcm54xx_setup_aneg
,
935 .setup_forced
= bcm54xx_setup_forced
,
936 .poll_link
= genmii_poll_link
,
937 .read_link
= bcm54xx_read_link
,
940 static struct mii_phy_def bcm5400_phy_def
= {
941 .phy_id
= 0x00206040,
942 .phy_id_mask
= 0xfffffff0,
944 .features
= MII_GBIT_FEATURES
,
946 .ops
= &bcm5400_phy_ops
949 /* Broadcom BCM 5401 */
950 static struct mii_phy_ops bcm5401_phy_ops
= {
951 .init
= bcm5401_init
,
952 .suspend
= bcm5401_suspend
,
953 .setup_aneg
= bcm54xx_setup_aneg
,
954 .setup_forced
= bcm54xx_setup_forced
,
955 .poll_link
= genmii_poll_link
,
956 .read_link
= bcm54xx_read_link
,
959 static struct mii_phy_def bcm5401_phy_def
= {
960 .phy_id
= 0x00206050,
961 .phy_id_mask
= 0xfffffff0,
963 .features
= MII_GBIT_FEATURES
,
965 .ops
= &bcm5401_phy_ops
968 /* Broadcom BCM 5411 */
969 static struct mii_phy_ops bcm5411_phy_ops
= {
970 .init
= bcm5411_init
,
971 .suspend
= generic_suspend
,
972 .setup_aneg
= bcm54xx_setup_aneg
,
973 .setup_forced
= bcm54xx_setup_forced
,
974 .poll_link
= genmii_poll_link
,
975 .read_link
= bcm54xx_read_link
,
978 static struct mii_phy_def bcm5411_phy_def
= {
979 .phy_id
= 0x00206070,
980 .phy_id_mask
= 0xfffffff0,
982 .features
= MII_GBIT_FEATURES
,
984 .ops
= &bcm5411_phy_ops
987 /* Broadcom BCM 5421 */
988 static struct mii_phy_ops bcm5421_phy_ops
= {
989 .init
= bcm5421_init
,
990 .suspend
= generic_suspend
,
991 .setup_aneg
= bcm54xx_setup_aneg
,
992 .setup_forced
= bcm54xx_setup_forced
,
993 .poll_link
= bcm5421_poll_link
,
994 .read_link
= bcm5421_read_link
,
995 .enable_fiber
= bcm5421_enable_fiber
,
998 static struct mii_phy_def bcm5421_phy_def
= {
999 .phy_id
= 0x002060e0,
1000 .phy_id_mask
= 0xfffffff0,
1002 .features
= MII_GBIT_FEATURES
,
1004 .ops
= &bcm5421_phy_ops
1007 /* Broadcom BCM 5421 built-in K2 */
1008 static struct mii_phy_ops bcm5421k2_phy_ops
= {
1009 .init
= bcm5421_init
,
1010 .suspend
= generic_suspend
,
1011 .setup_aneg
= bcm54xx_setup_aneg
,
1012 .setup_forced
= bcm54xx_setup_forced
,
1013 .poll_link
= genmii_poll_link
,
1014 .read_link
= bcm54xx_read_link
,
1017 static struct mii_phy_def bcm5421k2_phy_def
= {
1018 .phy_id
= 0x002062e0,
1019 .phy_id_mask
= 0xfffffff0,
1020 .name
= "BCM5421-K2",
1021 .features
= MII_GBIT_FEATURES
,
1023 .ops
= &bcm5421k2_phy_ops
1026 static struct mii_phy_ops bcm5461_phy_ops
= {
1027 .init
= bcm5421_init
,
1028 .suspend
= generic_suspend
,
1029 .setup_aneg
= bcm54xx_setup_aneg
,
1030 .setup_forced
= bcm54xx_setup_forced
,
1031 .poll_link
= bcm5461_poll_link
,
1032 .read_link
= bcm5461_read_link
,
1033 .enable_fiber
= bcm5461_enable_fiber
,
1036 static struct mii_phy_def bcm5461_phy_def
= {
1037 .phy_id
= 0x002060c0,
1038 .phy_id_mask
= 0xfffffff0,
1040 .features
= MII_GBIT_FEATURES
,
1042 .ops
= &bcm5461_phy_ops
1045 /* Broadcom BCM 5462 built-in Vesta */
1046 static struct mii_phy_ops bcm5462V_phy_ops
= {
1047 .init
= bcm5421_init
,
1048 .suspend
= generic_suspend
,
1049 .setup_aneg
= bcm54xx_setup_aneg
,
1050 .setup_forced
= bcm54xx_setup_forced
,
1051 .poll_link
= genmii_poll_link
,
1052 .read_link
= bcm54xx_read_link
,
1055 static struct mii_phy_def bcm5462V_phy_def
= {
1056 .phy_id
= 0x002060d0,
1057 .phy_id_mask
= 0xfffffff0,
1058 .name
= "BCM5462-Vesta",
1059 .features
= MII_GBIT_FEATURES
,
1061 .ops
= &bcm5462V_phy_ops
1064 /* Marvell 88E1101 amd 88E1111 */
1065 static struct mii_phy_ops marvell88e1101_phy_ops
= {
1066 .suspend
= generic_suspend
,
1067 .setup_aneg
= marvell_setup_aneg
,
1068 .setup_forced
= marvell_setup_forced
,
1069 .poll_link
= genmii_poll_link
,
1070 .read_link
= marvell_read_link
1073 static struct mii_phy_ops marvell88e1111_phy_ops
= {
1074 .init
= marvell88e1111_init
,
1075 .suspend
= generic_suspend
,
1076 .setup_aneg
= marvell_setup_aneg
,
1077 .setup_forced
= marvell_setup_forced
,
1078 .poll_link
= genmii_poll_link
,
1079 .read_link
= marvell_read_link
1082 /* two revs in darwin for the 88e1101 ... I could use a datasheet
1083 * to get the proper names...
1085 static struct mii_phy_def marvell88e1101v1_phy_def
= {
1086 .phy_id
= 0x01410c20,
1087 .phy_id_mask
= 0xfffffff0,
1088 .name
= "Marvell 88E1101v1",
1089 .features
= MII_GBIT_FEATURES
,
1091 .ops
= &marvell88e1101_phy_ops
1093 static struct mii_phy_def marvell88e1101v2_phy_def
= {
1094 .phy_id
= 0x01410c60,
1095 .phy_id_mask
= 0xfffffff0,
1096 .name
= "Marvell 88E1101v2",
1097 .features
= MII_GBIT_FEATURES
,
1099 .ops
= &marvell88e1101_phy_ops
1101 static struct mii_phy_def marvell88e1111_phy_def
= {
1102 .phy_id
= 0x01410cc0,
1103 .phy_id_mask
= 0xfffffff0,
1104 .name
= "Marvell 88E1111",
1105 .features
= MII_GBIT_FEATURES
,
1107 .ops
= &marvell88e1111_phy_ops
1110 /* Generic implementation for most 10/100 PHYs */
1111 static struct mii_phy_ops generic_phy_ops
= {
1112 .setup_aneg
= genmii_setup_aneg
,
1113 .setup_forced
= genmii_setup_forced
,
1114 .poll_link
= genmii_poll_link
,
1115 .read_link
= genmii_read_link
1118 static struct mii_phy_def genmii_phy_def
= {
1119 .phy_id
= 0x00000000,
1120 .phy_id_mask
= 0x00000000,
1121 .name
= "Generic MII",
1122 .features
= MII_BASIC_FEATURES
,
1124 .ops
= &generic_phy_ops
1127 static struct mii_phy_def
* mii_phy_table
[] = {
1138 &marvell88e1101v1_phy_def
,
1139 &marvell88e1101v2_phy_def
,
1140 &marvell88e1111_phy_def
,
1145 int mii_phy_probe(struct mii_phy
*phy
, int mii_id
)
1149 struct mii_phy_def
* def
;
1152 /* We do not reset the mii_phy structure as the driver
1153 * may re-probe the PHY regulary
1155 phy
->mii_id
= mii_id
;
1157 /* Take PHY out of isloate mode and reset it. */
1158 rc
= reset_one_mii_phy(phy
, mii_id
);
1162 /* Read ID and find matching entry */
1163 id
= (phy_read(phy
, MII_PHYSID1
) << 16 | phy_read(phy
, MII_PHYSID2
));
1164 printk(KERN_DEBUG
"PHY ID: %x, addr: %x\n", id
, mii_id
);
1165 for (i
=0; (def
= mii_phy_table
[i
]) != NULL
; i
++)
1166 if ((id
& def
->phy_id_mask
) == def
->phy_id
)
1168 /* Should never be NULL (we have a generic entry), but... */
1179 phy
->advertising
= 0;
1183 EXPORT_SYMBOL(mii_phy_probe
);
1184 MODULE_LICENSE("GPL");