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
)
222 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
223 phy_write(phy
, MII_BMCR
, BMCR_PDOWN
);
228 static int bcm5401_init(struct mii_phy
* phy
)
233 rev
= phy_read(phy
, MII_PHYSID2
) & 0x000f;
234 if (rev
== 0 || rev
== 3) {
235 /* Some revisions of 5401 appear to need this
236 * initialisation sequence to disable, according
237 * to OF, "tap power management"
239 * WARNING ! OF and Darwin don't agree on the
240 * register addresses. OF seem to interpret the
241 * register numbers below as decimal
243 * Note: This should (and does) match tg3_init_5401phy_dsp
244 * in the tg3.c driver. -DaveM
246 phy_write(phy
, 0x18, 0x0c20);
247 phy_write(phy
, 0x17, 0x0012);
248 phy_write(phy
, 0x15, 0x1804);
249 phy_write(phy
, 0x17, 0x0013);
250 phy_write(phy
, 0x15, 0x1204);
251 phy_write(phy
, 0x17, 0x8006);
252 phy_write(phy
, 0x15, 0x0132);
253 phy_write(phy
, 0x17, 0x8006);
254 phy_write(phy
, 0x15, 0x0232);
255 phy_write(phy
, 0x17, 0x201f);
256 phy_write(phy
, 0x15, 0x0a20);
259 /* Configure for gigabit full duplex */
260 data
= phy_read(phy
, MII_BCM5400_GB_CONTROL
);
261 data
|= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP
;
262 phy_write(phy
, MII_BCM5400_GB_CONTROL
, data
);
266 /* Reset and configure cascaded 10/100 PHY */
267 (void)reset_one_mii_phy(phy
, 0x1f);
269 data
= __phy_read(phy
, 0x1f, MII_BCM5201_MULTIPHY
);
270 data
|= MII_BCM5201_MULTIPHY_SERIALMODE
;
271 __phy_write(phy
, 0x1f, MII_BCM5201_MULTIPHY
, data
);
276 static int bcm5401_suspend(struct mii_phy
* phy
)
278 #if 0 /* Commented out in Darwin... someone has those dawn docs ? */
279 phy_write(phy
, MII_BMCR
, BMCR_PDOWN
);
284 static int bcm5411_init(struct mii_phy
* phy
)
288 /* Here's some more Apple black magic to setup
289 * some voltage stuffs.
291 phy_write(phy
, 0x1c, 0x8c23);
292 phy_write(phy
, 0x1c, 0x8ca3);
293 phy_write(phy
, 0x1c, 0x8c23);
295 /* Here, Apple seems to want to reset it, do
298 phy_write(phy
, MII_BMCR
, BMCR_RESET
);
299 phy_write(phy
, MII_BMCR
, 0x1340);
301 data
= phy_read(phy
, MII_BCM5400_GB_CONTROL
);
302 data
|= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP
;
303 phy_write(phy
, MII_BCM5400_GB_CONTROL
, data
);
307 /* Reset and configure cascaded 10/100 PHY */
308 (void)reset_one_mii_phy(phy
, 0x1f);
313 static int generic_suspend(struct mii_phy
* phy
)
315 phy_write(phy
, MII_BMCR
, BMCR_PDOWN
);
320 static int bcm5421_init(struct mii_phy
* phy
)
325 id
= (phy_read(phy
, MII_PHYSID1
) << 16 | phy_read(phy
, MII_PHYSID2
));
327 /* Revision 0 of 5421 needs some fixups */
328 if (id
== 0x002060e0) {
329 /* This is borrowed from MacOS
331 phy_write(phy
, 0x18, 0x1007);
332 data
= phy_read(phy
, 0x18);
333 phy_write(phy
, 0x18, data
| 0x0400);
334 phy_write(phy
, 0x18, 0x0007);
335 data
= phy_read(phy
, 0x18);
336 phy_write(phy
, 0x18, data
| 0x0800);
337 phy_write(phy
, 0x17, 0x000a);
338 data
= phy_read(phy
, 0x15);
339 phy_write(phy
, 0x15, data
| 0x0200);
342 /* Pick up some init code from OF for K2 version */
343 if ((id
& 0xfffffff0) == 0x002062e0) {
344 phy_write(phy
, 4, 0x01e1);
345 phy_write(phy
, 9, 0x0300);
348 /* Check if we can enable automatic low power */
349 #ifdef CONFIG_PPC_PMAC
350 if (phy
->platform_data
) {
351 struct device_node
*np
= of_get_parent(phy
->platform_data
);
352 int can_low_power
= 1;
353 if (np
== NULL
|| get_property(np
, "no-autolowpower", NULL
))
356 /* Enable automatic low-power */
357 phy_write(phy
, 0x1c, 0x9002);
358 phy_write(phy
, 0x1c, 0xa821);
359 phy_write(phy
, 0x1c, 0x941d);
362 #endif /* CONFIG_PPC_PMAC */
367 static int bcm5421_enable_fiber(struct mii_phy
* phy
)
369 /* enable fiber mode */
370 phy_write(phy
, MII_NCONFIG
, 0x9020);
371 /* LEDs active in both modes, autosense prio = fiber */
372 phy_write(phy
, MII_NCONFIG
, 0x945f);
374 /* switch off fibre autoneg */
375 phy_write(phy
, MII_NCONFIG
, 0xfc01);
376 phy_write(phy
, 0x0b, 0x0004);
381 static int bcm5461_enable_fiber(struct mii_phy
* phy
)
383 phy_write(phy
, MII_NCONFIG
, 0xfc0c);
384 phy_write(phy
, MII_BMCR
, 0x4140);
385 phy_write(phy
, MII_NCONFIG
, 0xfc0b);
386 phy_write(phy
, MII_BMCR
, 0x0140);
391 static int bcm54xx_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
396 phy
->speed
= SPEED_10
;
397 phy
->duplex
= DUPLEX_HALF
;
399 phy
->advertising
= advertise
;
401 /* Setup standard advertise */
402 adv
= phy_read(phy
, MII_ADVERTISE
);
403 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
404 if (advertise
& ADVERTISED_10baseT_Half
)
405 adv
|= ADVERTISE_10HALF
;
406 if (advertise
& ADVERTISED_10baseT_Full
)
407 adv
|= ADVERTISE_10FULL
;
408 if (advertise
& ADVERTISED_100baseT_Half
)
409 adv
|= ADVERTISE_100HALF
;
410 if (advertise
& ADVERTISED_100baseT_Full
)
411 adv
|= ADVERTISE_100FULL
;
412 if (advertise
& ADVERTISED_Pause
)
413 adv
|= ADVERTISE_PAUSE_CAP
;
414 if (advertise
& ADVERTISED_Asym_Pause
)
415 adv
|= ADVERTISE_PAUSE_ASYM
;
416 phy_write(phy
, MII_ADVERTISE
, adv
);
418 /* Setup 1000BT advertise */
419 adv
= phy_read(phy
, MII_1000BASETCONTROL
);
420 adv
&= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP
|MII_1000BASETCONTROL_HALFDUPLEXCAP
);
421 if (advertise
& SUPPORTED_1000baseT_Half
)
422 adv
|= MII_1000BASETCONTROL_HALFDUPLEXCAP
;
423 if (advertise
& SUPPORTED_1000baseT_Full
)
424 adv
|= MII_1000BASETCONTROL_FULLDUPLEXCAP
;
425 phy_write(phy
, MII_1000BASETCONTROL
, adv
);
427 /* Start/Restart aneg */
428 ctl
= phy_read(phy
, MII_BMCR
);
429 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
430 phy_write(phy
, MII_BMCR
, ctl
);
435 static int bcm54xx_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
444 ctl
= phy_read(phy
, MII_BMCR
);
445 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_SPD2
|BMCR_ANENABLE
);
447 /* First reset the PHY */
448 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
450 /* Select speed & duplex */
455 ctl
|= BMCR_SPEED100
;
460 if (fd
== DUPLEX_FULL
)
461 ctl
|= BMCR_FULLDPLX
;
463 // XXX Should we set the sungem to GII now on 1000BT ?
465 phy_write(phy
, MII_BMCR
, ctl
);
470 static int bcm54xx_read_link(struct mii_phy
*phy
)
476 val
= phy_read(phy
, MII_BCM5400_AUXSTATUS
);
477 link_mode
= ((val
& MII_BCM5400_AUXSTATUS_LINKMODE_MASK
) >>
478 MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT
);
479 phy
->duplex
= phy_BCM5400_link_table
[link_mode
][0] ?
480 DUPLEX_FULL
: DUPLEX_HALF
;
481 phy
->speed
= phy_BCM5400_link_table
[link_mode
][2] ?
483 (phy_BCM5400_link_table
[link_mode
][1] ?
484 SPEED_100
: SPEED_10
);
485 val
= phy_read(phy
, MII_LPA
);
486 phy
->pause
= (phy
->duplex
== DUPLEX_FULL
) &&
487 ((val
& LPA_PAUSE
) != 0);
489 /* On non-aneg, we assume what we put in BMCR is the speed,
490 * though magic-aneg shouldn't prevent this case from occurring
496 static int marvell88e1111_init(struct mii_phy
* phy
)
500 /* magic init sequence for rev 0 */
501 rev
= phy_read(phy
, MII_PHYSID2
) & 0x000f;
503 phy_write(phy
, 0x1d, 0x000a);
504 phy_write(phy
, 0x1e, 0x0821);
506 phy_write(phy
, 0x1d, 0x0006);
507 phy_write(phy
, 0x1e, 0x8600);
509 phy_write(phy
, 0x1d, 0x000b);
510 phy_write(phy
, 0x1e, 0x0100);
512 phy_write(phy
, 0x1d, 0x0004);
513 phy_write(phy
, 0x1e, 0x4850);
518 static int marvell_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
523 phy
->speed
= SPEED_10
;
524 phy
->duplex
= DUPLEX_HALF
;
526 phy
->advertising
= advertise
;
528 /* Setup standard advertise */
529 adv
= phy_read(phy
, MII_ADVERTISE
);
530 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
531 if (advertise
& ADVERTISED_10baseT_Half
)
532 adv
|= ADVERTISE_10HALF
;
533 if (advertise
& ADVERTISED_10baseT_Full
)
534 adv
|= ADVERTISE_10FULL
;
535 if (advertise
& ADVERTISED_100baseT_Half
)
536 adv
|= ADVERTISE_100HALF
;
537 if (advertise
& ADVERTISED_100baseT_Full
)
538 adv
|= ADVERTISE_100FULL
;
539 if (advertise
& ADVERTISED_Pause
)
540 adv
|= ADVERTISE_PAUSE_CAP
;
541 if (advertise
& ADVERTISED_Asym_Pause
)
542 adv
|= ADVERTISE_PAUSE_ASYM
;
543 phy_write(phy
, MII_ADVERTISE
, adv
);
545 /* Setup 1000BT advertise & enable crossover detect
546 * XXX How do we advertise 1000BT ? Darwin source is
547 * confusing here, they read from specific control and
548 * write to control... Someone has specs for those
551 adv
= phy_read(phy
, MII_M1011_PHY_SPEC_CONTROL
);
552 adv
|= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX
;
553 adv
&= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP
|
554 MII_1000BASETCONTROL_HALFDUPLEXCAP
);
555 if (advertise
& SUPPORTED_1000baseT_Half
)
556 adv
|= MII_1000BASETCONTROL_HALFDUPLEXCAP
;
557 if (advertise
& SUPPORTED_1000baseT_Full
)
558 adv
|= MII_1000BASETCONTROL_FULLDUPLEXCAP
;
559 phy_write(phy
, MII_1000BASETCONTROL
, adv
);
561 /* Start/Restart aneg */
562 ctl
= phy_read(phy
, MII_BMCR
);
563 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
564 phy_write(phy
, MII_BMCR
, ctl
);
569 static int marvell_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
578 ctl
= phy_read(phy
, MII_BMCR
);
579 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_SPD2
|BMCR_ANENABLE
);
582 /* Select speed & duplex */
587 ctl
|= BMCR_SPEED100
;
589 /* I'm not sure about the one below, again, Darwin source is
590 * quite confusing and I lack chip specs
595 if (fd
== DUPLEX_FULL
)
596 ctl
|= BMCR_FULLDPLX
;
598 /* Disable crossover. Again, the way Apple does it is strange,
599 * though I don't assume they are wrong ;)
601 ctl2
= phy_read(phy
, MII_M1011_PHY_SPEC_CONTROL
);
602 ctl2
&= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX
|
603 MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX
|
604 MII_1000BASETCONTROL_FULLDUPLEXCAP
|
605 MII_1000BASETCONTROL_HALFDUPLEXCAP
);
606 if (speed
== SPEED_1000
)
607 ctl2
|= (fd
== DUPLEX_FULL
) ?
608 MII_1000BASETCONTROL_FULLDUPLEXCAP
:
609 MII_1000BASETCONTROL_HALFDUPLEXCAP
;
610 phy_write(phy
, MII_1000BASETCONTROL
, ctl2
);
612 // XXX Should we set the sungem to GII now on 1000BT ?
614 phy_write(phy
, MII_BMCR
, ctl
);
619 static int marvell_read_link(struct mii_phy
*phy
)
624 status
= phy_read(phy
, MII_M1011_PHY_SPEC_STATUS
);
625 if ((status
& MII_M1011_PHY_SPEC_STATUS_RESOLVED
) == 0)
627 if (status
& MII_M1011_PHY_SPEC_STATUS_1000
)
628 phy
->speed
= SPEED_1000
;
629 else if (status
& MII_M1011_PHY_SPEC_STATUS_100
)
630 phy
->speed
= SPEED_100
;
632 phy
->speed
= SPEED_10
;
633 if (status
& MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX
)
634 phy
->duplex
= DUPLEX_FULL
;
636 phy
->duplex
= DUPLEX_HALF
;
637 pmask
= MII_M1011_PHY_SPEC_STATUS_TX_PAUSE
|
638 MII_M1011_PHY_SPEC_STATUS_RX_PAUSE
;
639 phy
->pause
= (status
& pmask
) == pmask
;
641 /* On non-aneg, we assume what we put in BMCR is the speed,
642 * though magic-aneg shouldn't prevent this case from occurring
648 static int genmii_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
653 phy
->speed
= SPEED_10
;
654 phy
->duplex
= DUPLEX_HALF
;
656 phy
->advertising
= advertise
;
658 /* Setup standard advertise */
659 adv
= phy_read(phy
, MII_ADVERTISE
);
660 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
661 if (advertise
& ADVERTISED_10baseT_Half
)
662 adv
|= ADVERTISE_10HALF
;
663 if (advertise
& ADVERTISED_10baseT_Full
)
664 adv
|= ADVERTISE_10FULL
;
665 if (advertise
& ADVERTISED_100baseT_Half
)
666 adv
|= ADVERTISE_100HALF
;
667 if (advertise
& ADVERTISED_100baseT_Full
)
668 adv
|= ADVERTISE_100FULL
;
669 if (advertise
& ADVERTISED_Pause
)
670 adv
|= ADVERTISE_PAUSE_CAP
;
671 if (advertise
& ADVERTISED_Asym_Pause
)
672 adv
|= ADVERTISE_PAUSE_ASYM
;
673 phy_write(phy
, MII_ADVERTISE
, adv
);
675 /* Start/Restart aneg */
676 ctl
= phy_read(phy
, MII_BMCR
);
677 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
678 phy_write(phy
, MII_BMCR
, ctl
);
683 static int genmii_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
692 ctl
= phy_read(phy
, MII_BMCR
);
693 ctl
&= ~(BMCR_FULLDPLX
|BMCR_SPEED100
|BMCR_ANENABLE
);
695 /* First reset the PHY */
696 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
698 /* Select speed & duplex */
703 ctl
|= BMCR_SPEED100
;
709 if (fd
== DUPLEX_FULL
)
710 ctl
|= BMCR_FULLDPLX
;
711 phy_write(phy
, MII_BMCR
, ctl
);
716 static int genmii_poll_link(struct mii_phy
*phy
)
720 (void)phy_read(phy
, MII_BMSR
);
721 status
= phy_read(phy
, MII_BMSR
);
722 if ((status
& BMSR_LSTATUS
) == 0)
724 if (phy
->autoneg
&& !(status
& BMSR_ANEGCOMPLETE
))
729 static int genmii_read_link(struct mii_phy
*phy
)
734 lpa
= phy_read(phy
, MII_LPA
);
736 if (lpa
& (LPA_10FULL
| LPA_100FULL
))
737 phy
->duplex
= DUPLEX_FULL
;
739 phy
->duplex
= DUPLEX_HALF
;
740 if (lpa
& (LPA_100FULL
| LPA_100HALF
))
741 phy
->speed
= SPEED_100
;
743 phy
->speed
= SPEED_10
;
744 phy
->pause
= (phy
->duplex
== DUPLEX_FULL
) &&
745 ((lpa
& LPA_PAUSE
) != 0);
747 /* On non-aneg, we assume what we put in BMCR is the speed,
748 * though magic-aneg shouldn't prevent this case from occurring
755 #define MII_BASIC_FEATURES \
756 (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
757 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
758 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \
761 /* On gigabit capable PHYs, we advertise Pause support but not asym pause
762 * support for now as I'm not sure it's supported and Darwin doesn't do
763 * it neither. --BenH.
765 #define MII_GBIT_FEATURES \
766 (MII_BASIC_FEATURES | \
767 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
769 /* Broadcom BCM 5201 */
770 static struct mii_phy_ops bcm5201_phy_ops
= {
771 .init
= bcm5201_init
,
772 .suspend
= bcm5201_suspend
,
773 .setup_aneg
= genmii_setup_aneg
,
774 .setup_forced
= genmii_setup_forced
,
775 .poll_link
= genmii_poll_link
,
776 .read_link
= genmii_read_link
,
779 static struct mii_phy_def bcm5201_phy_def
= {
780 .phy_id
= 0x00406210,
781 .phy_id_mask
= 0xfffffff0,
783 .features
= MII_BASIC_FEATURES
,
785 .ops
= &bcm5201_phy_ops
788 /* Broadcom BCM 5221 */
789 static struct mii_phy_ops bcm5221_phy_ops
= {
790 .suspend
= bcm5221_suspend
,
791 .init
= bcm5221_init
,
792 .setup_aneg
= genmii_setup_aneg
,
793 .setup_forced
= genmii_setup_forced
,
794 .poll_link
= genmii_poll_link
,
795 .read_link
= genmii_read_link
,
798 static struct mii_phy_def bcm5221_phy_def
= {
799 .phy_id
= 0x004061e0,
800 .phy_id_mask
= 0xfffffff0,
802 .features
= MII_BASIC_FEATURES
,
804 .ops
= &bcm5221_phy_ops
807 /* Broadcom BCM 5241 */
808 static struct mii_phy_ops bcm5241_phy_ops
= {
809 .suspend
= bcm5241_suspend
,
810 .init
= bcm5241_init
,
811 .setup_aneg
= genmii_setup_aneg
,
812 .setup_forced
= genmii_setup_forced
,
813 .poll_link
= genmii_poll_link
,
814 .read_link
= genmii_read_link
,
816 static struct mii_phy_def bcm5241_phy_def
= {
817 .phy_id
= 0x0143bc30,
818 .phy_id_mask
= 0xfffffff0,
820 .features
= MII_BASIC_FEATURES
,
822 .ops
= &bcm5241_phy_ops
825 /* Broadcom BCM 5400 */
826 static struct mii_phy_ops bcm5400_phy_ops
= {
827 .init
= bcm5400_init
,
828 .suspend
= bcm5400_suspend
,
829 .setup_aneg
= bcm54xx_setup_aneg
,
830 .setup_forced
= bcm54xx_setup_forced
,
831 .poll_link
= genmii_poll_link
,
832 .read_link
= bcm54xx_read_link
,
835 static struct mii_phy_def bcm5400_phy_def
= {
836 .phy_id
= 0x00206040,
837 .phy_id_mask
= 0xfffffff0,
839 .features
= MII_GBIT_FEATURES
,
841 .ops
= &bcm5400_phy_ops
844 /* Broadcom BCM 5401 */
845 static struct mii_phy_ops bcm5401_phy_ops
= {
846 .init
= bcm5401_init
,
847 .suspend
= bcm5401_suspend
,
848 .setup_aneg
= bcm54xx_setup_aneg
,
849 .setup_forced
= bcm54xx_setup_forced
,
850 .poll_link
= genmii_poll_link
,
851 .read_link
= bcm54xx_read_link
,
854 static struct mii_phy_def bcm5401_phy_def
= {
855 .phy_id
= 0x00206050,
856 .phy_id_mask
= 0xfffffff0,
858 .features
= MII_GBIT_FEATURES
,
860 .ops
= &bcm5401_phy_ops
863 /* Broadcom BCM 5411 */
864 static struct mii_phy_ops bcm5411_phy_ops
= {
865 .init
= bcm5411_init
,
866 .suspend
= generic_suspend
,
867 .setup_aneg
= bcm54xx_setup_aneg
,
868 .setup_forced
= bcm54xx_setup_forced
,
869 .poll_link
= genmii_poll_link
,
870 .read_link
= bcm54xx_read_link
,
873 static struct mii_phy_def bcm5411_phy_def
= {
874 .phy_id
= 0x00206070,
875 .phy_id_mask
= 0xfffffff0,
877 .features
= MII_GBIT_FEATURES
,
879 .ops
= &bcm5411_phy_ops
882 /* Broadcom BCM 5421 */
883 static struct mii_phy_ops bcm5421_phy_ops
= {
884 .init
= bcm5421_init
,
885 .suspend
= generic_suspend
,
886 .setup_aneg
= bcm54xx_setup_aneg
,
887 .setup_forced
= bcm54xx_setup_forced
,
888 .poll_link
= genmii_poll_link
,
889 .read_link
= bcm54xx_read_link
,
890 .enable_fiber
= bcm5421_enable_fiber
,
893 static struct mii_phy_def bcm5421_phy_def
= {
894 .phy_id
= 0x002060e0,
895 .phy_id_mask
= 0xfffffff0,
897 .features
= MII_GBIT_FEATURES
,
899 .ops
= &bcm5421_phy_ops
902 /* Broadcom BCM 5421 built-in K2 */
903 static struct mii_phy_ops bcm5421k2_phy_ops
= {
904 .init
= bcm5421_init
,
905 .suspend
= generic_suspend
,
906 .setup_aneg
= bcm54xx_setup_aneg
,
907 .setup_forced
= bcm54xx_setup_forced
,
908 .poll_link
= genmii_poll_link
,
909 .read_link
= bcm54xx_read_link
,
912 static struct mii_phy_def bcm5421k2_phy_def
= {
913 .phy_id
= 0x002062e0,
914 .phy_id_mask
= 0xfffffff0,
915 .name
= "BCM5421-K2",
916 .features
= MII_GBIT_FEATURES
,
918 .ops
= &bcm5421k2_phy_ops
921 static struct mii_phy_ops bcm5461_phy_ops
= {
922 .init
= bcm5421_init
,
923 .suspend
= generic_suspend
,
924 .setup_aneg
= bcm54xx_setup_aneg
,
925 .setup_forced
= bcm54xx_setup_forced
,
926 .poll_link
= genmii_poll_link
,
927 .read_link
= bcm54xx_read_link
,
928 .enable_fiber
= bcm5461_enable_fiber
,
931 static struct mii_phy_def bcm5461_phy_def
= {
932 .phy_id
= 0x002060c0,
933 .phy_id_mask
= 0xfffffff0,
935 .features
= MII_GBIT_FEATURES
,
937 .ops
= &bcm5461_phy_ops
940 /* Broadcom BCM 5462 built-in Vesta */
941 static struct mii_phy_ops bcm5462V_phy_ops
= {
942 .init
= bcm5421_init
,
943 .suspend
= generic_suspend
,
944 .setup_aneg
= bcm54xx_setup_aneg
,
945 .setup_forced
= bcm54xx_setup_forced
,
946 .poll_link
= genmii_poll_link
,
947 .read_link
= bcm54xx_read_link
,
950 static struct mii_phy_def bcm5462V_phy_def
= {
951 .phy_id
= 0x002060d0,
952 .phy_id_mask
= 0xfffffff0,
953 .name
= "BCM5462-Vesta",
954 .features
= MII_GBIT_FEATURES
,
956 .ops
= &bcm5462V_phy_ops
959 /* Marvell 88E1101 amd 88E1111 */
960 static struct mii_phy_ops marvell88e1101_phy_ops
= {
961 .suspend
= generic_suspend
,
962 .setup_aneg
= marvell_setup_aneg
,
963 .setup_forced
= marvell_setup_forced
,
964 .poll_link
= genmii_poll_link
,
965 .read_link
= marvell_read_link
968 static struct mii_phy_ops marvell88e1111_phy_ops
= {
969 .init
= marvell88e1111_init
,
970 .suspend
= generic_suspend
,
971 .setup_aneg
= marvell_setup_aneg
,
972 .setup_forced
= marvell_setup_forced
,
973 .poll_link
= genmii_poll_link
,
974 .read_link
= marvell_read_link
977 /* two revs in darwin for the 88e1101 ... I could use a datasheet
978 * to get the proper names...
980 static struct mii_phy_def marvell88e1101v1_phy_def
= {
981 .phy_id
= 0x01410c20,
982 .phy_id_mask
= 0xfffffff0,
983 .name
= "Marvell 88E1101v1",
984 .features
= MII_GBIT_FEATURES
,
986 .ops
= &marvell88e1101_phy_ops
988 static struct mii_phy_def marvell88e1101v2_phy_def
= {
989 .phy_id
= 0x01410c60,
990 .phy_id_mask
= 0xfffffff0,
991 .name
= "Marvell 88E1101v2",
992 .features
= MII_GBIT_FEATURES
,
994 .ops
= &marvell88e1101_phy_ops
996 static struct mii_phy_def marvell88e1111_phy_def
= {
997 .phy_id
= 0x01410cc0,
998 .phy_id_mask
= 0xfffffff0,
999 .name
= "Marvell 88E1111",
1000 .features
= MII_GBIT_FEATURES
,
1002 .ops
= &marvell88e1111_phy_ops
1005 /* Generic implementation for most 10/100 PHYs */
1006 static struct mii_phy_ops generic_phy_ops
= {
1007 .setup_aneg
= genmii_setup_aneg
,
1008 .setup_forced
= genmii_setup_forced
,
1009 .poll_link
= genmii_poll_link
,
1010 .read_link
= genmii_read_link
1013 static struct mii_phy_def genmii_phy_def
= {
1014 .phy_id
= 0x00000000,
1015 .phy_id_mask
= 0x00000000,
1016 .name
= "Generic MII",
1017 .features
= MII_BASIC_FEATURES
,
1019 .ops
= &generic_phy_ops
1022 static struct mii_phy_def
* mii_phy_table
[] = {
1033 &marvell88e1101v1_phy_def
,
1034 &marvell88e1101v2_phy_def
,
1035 &marvell88e1111_phy_def
,
1040 int mii_phy_probe(struct mii_phy
*phy
, int mii_id
)
1044 struct mii_phy_def
* def
;
1047 /* We do not reset the mii_phy structure as the driver
1048 * may re-probe the PHY regulary
1050 phy
->mii_id
= mii_id
;
1052 /* Take PHY out of isloate mode and reset it. */
1053 rc
= reset_one_mii_phy(phy
, mii_id
);
1057 /* Read ID and find matching entry */
1058 id
= (phy_read(phy
, MII_PHYSID1
) << 16 | phy_read(phy
, MII_PHYSID2
));
1059 printk(KERN_DEBUG
"PHY ID: %x, addr: %x\n", id
, mii_id
);
1060 for (i
=0; (def
= mii_phy_table
[i
]) != NULL
; i
++)
1061 if ((id
& def
->phy_id_mask
) == def
->phy_id
)
1063 /* Should never be NULL (we have a generic entry), but... */
1074 phy
->advertising
= 0;
1078 EXPORT_SYMBOL(mii_phy_probe
);
1079 MODULE_LICENSE("GPL");