2 * drivers/net/ibm_newemac/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 * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
12 * <benh@kernel.crashing.org>
14 * Based on the arch/ppc version of the driver:
16 * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
17 * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/netdevice.h>
24 #include <linux/mii.h>
25 #include <linux/ethtool.h>
26 #include <linux/delay.h>
31 #define phy_read _phy_read
32 #define phy_write _phy_write
34 static inline int _phy_read(struct mii_phy
*phy
, int reg
)
36 return phy
->mdio_read(phy
->dev
, phy
->address
, reg
);
39 static inline void _phy_write(struct mii_phy
*phy
, int reg
, int val
)
41 phy
->mdio_write(phy
->dev
, phy
->address
, reg
, val
);
44 static inline int gpcs_phy_read(struct mii_phy
*phy
, int reg
)
46 return phy
->mdio_read(phy
->dev
, phy
->gpcs_address
, reg
);
49 static inline void gpcs_phy_write(struct mii_phy
*phy
, int reg
, int val
)
51 phy
->mdio_write(phy
->dev
, phy
->gpcs_address
, reg
, val
);
54 int emac_mii_reset_phy(struct mii_phy
*phy
)
59 val
= phy_read(phy
, MII_BMCR
);
60 val
&= ~(BMCR_ISOLATE
| BMCR_ANENABLE
);
62 phy_write(phy
, MII_BMCR
, val
);
67 val
= phy_read(phy
, MII_BMCR
);
68 if (val
>= 0 && (val
& BMCR_RESET
) == 0)
72 if ((val
& BMCR_ISOLATE
) && limit
> 0)
73 phy_write(phy
, MII_BMCR
, val
& ~BMCR_ISOLATE
);
78 int emac_mii_reset_gpcs(struct mii_phy
*phy
)
83 val
= gpcs_phy_read(phy
, MII_BMCR
);
84 val
&= ~(BMCR_ISOLATE
| BMCR_ANENABLE
);
86 gpcs_phy_write(phy
, MII_BMCR
, val
);
91 val
= gpcs_phy_read(phy
, MII_BMCR
);
92 if (val
>= 0 && (val
& BMCR_RESET
) == 0)
96 if ((val
& BMCR_ISOLATE
) && limit
> 0)
97 gpcs_phy_write(phy
, MII_BMCR
, val
& ~BMCR_ISOLATE
);
99 if (limit
> 0 && phy
->mode
== PHY_MODE_SGMII
) {
100 /* Configure GPCS interface to recommended setting for SGMII */
101 gpcs_phy_write(phy
, 0x04, 0x8120); /* AsymPause, FDX */
102 gpcs_phy_write(phy
, 0x07, 0x2801); /* msg_pg, toggle */
103 gpcs_phy_write(phy
, 0x00, 0x0140); /* 1Gbps, FDX */
109 static int genmii_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
113 phy
->autoneg
= AUTONEG_ENABLE
;
114 phy
->speed
= SPEED_10
;
115 phy
->duplex
= DUPLEX_HALF
;
116 phy
->pause
= phy
->asym_pause
= 0;
117 phy
->advertising
= advertise
;
119 ctl
= phy_read(phy
, MII_BMCR
);
122 ctl
&= ~(BMCR_FULLDPLX
| BMCR_SPEED100
| BMCR_SPEED1000
| BMCR_ANENABLE
);
124 /* First clear the PHY */
125 phy_write(phy
, MII_BMCR
, ctl
);
127 /* Setup standard advertise */
128 adv
= phy_read(phy
, MII_ADVERTISE
);
131 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
| ADVERTISE_PAUSE_CAP
|
132 ADVERTISE_PAUSE_ASYM
);
133 if (advertise
& ADVERTISED_10baseT_Half
)
134 adv
|= ADVERTISE_10HALF
;
135 if (advertise
& ADVERTISED_10baseT_Full
)
136 adv
|= ADVERTISE_10FULL
;
137 if (advertise
& ADVERTISED_100baseT_Half
)
138 adv
|= ADVERTISE_100HALF
;
139 if (advertise
& ADVERTISED_100baseT_Full
)
140 adv
|= ADVERTISE_100FULL
;
141 if (advertise
& ADVERTISED_Pause
)
142 adv
|= ADVERTISE_PAUSE_CAP
;
143 if (advertise
& ADVERTISED_Asym_Pause
)
144 adv
|= ADVERTISE_PAUSE_ASYM
;
145 phy_write(phy
, MII_ADVERTISE
, adv
);
148 (SUPPORTED_1000baseT_Full
| SUPPORTED_1000baseT_Half
)) {
149 adv
= phy_read(phy
, MII_CTRL1000
);
152 adv
&= ~(ADVERTISE_1000FULL
| ADVERTISE_1000HALF
);
153 if (advertise
& ADVERTISED_1000baseT_Full
)
154 adv
|= ADVERTISE_1000FULL
;
155 if (advertise
& ADVERTISED_1000baseT_Half
)
156 adv
|= ADVERTISE_1000HALF
;
157 phy_write(phy
, MII_CTRL1000
, adv
);
160 /* Start/Restart aneg */
161 ctl
= phy_read(phy
, MII_BMCR
);
162 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
163 phy_write(phy
, MII_BMCR
, ctl
);
168 static int genmii_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
172 phy
->autoneg
= AUTONEG_DISABLE
;
175 phy
->pause
= phy
->asym_pause
= 0;
177 ctl
= phy_read(phy
, MII_BMCR
);
180 ctl
&= ~(BMCR_FULLDPLX
| BMCR_SPEED100
| BMCR_SPEED1000
| BMCR_ANENABLE
);
182 /* First clear the PHY */
183 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
185 /* Select speed & duplex */
190 ctl
|= BMCR_SPEED100
;
193 ctl
|= BMCR_SPEED1000
;
198 if (fd
== DUPLEX_FULL
)
199 ctl
|= BMCR_FULLDPLX
;
200 phy_write(phy
, MII_BMCR
, ctl
);
205 static int genmii_poll_link(struct mii_phy
*phy
)
209 /* Clear latched value with dummy read */
210 phy_read(phy
, MII_BMSR
);
211 status
= phy_read(phy
, MII_BMSR
);
212 if (status
< 0 || (status
& BMSR_LSTATUS
) == 0)
214 if (phy
->autoneg
== AUTONEG_ENABLE
&& !(status
& BMSR_ANEGCOMPLETE
))
219 static int genmii_read_link(struct mii_phy
*phy
)
221 if (phy
->autoneg
== AUTONEG_ENABLE
) {
223 int lpa
= phy_read(phy
, MII_LPA
) & phy_read(phy
, MII_ADVERTISE
);
228 (SUPPORTED_1000baseT_Full
| SUPPORTED_1000baseT_Half
)) {
229 int adv
= phy_read(phy
, MII_CTRL1000
);
230 glpa
= phy_read(phy
, MII_STAT1000
);
232 if (glpa
< 0 || adv
< 0)
238 phy
->speed
= SPEED_10
;
239 phy
->duplex
= DUPLEX_HALF
;
240 phy
->pause
= phy
->asym_pause
= 0;
242 if (glpa
& (LPA_1000FULL
| LPA_1000HALF
)) {
243 phy
->speed
= SPEED_1000
;
244 if (glpa
& LPA_1000FULL
)
245 phy
->duplex
= DUPLEX_FULL
;
246 } else if (lpa
& (LPA_100FULL
| LPA_100HALF
)) {
247 phy
->speed
= SPEED_100
;
248 if (lpa
& LPA_100FULL
)
249 phy
->duplex
= DUPLEX_FULL
;
250 } else if (lpa
& LPA_10FULL
)
251 phy
->duplex
= DUPLEX_FULL
;
253 if (phy
->duplex
== DUPLEX_FULL
) {
254 phy
->pause
= lpa
& LPA_PAUSE_CAP
? 1 : 0;
255 phy
->asym_pause
= lpa
& LPA_PAUSE_ASYM
? 1 : 0;
258 int bmcr
= phy_read(phy
, MII_BMCR
);
262 if (bmcr
& BMCR_FULLDPLX
)
263 phy
->duplex
= DUPLEX_FULL
;
265 phy
->duplex
= DUPLEX_HALF
;
266 if (bmcr
& BMCR_SPEED1000
)
267 phy
->speed
= SPEED_1000
;
268 else if (bmcr
& BMCR_SPEED100
)
269 phy
->speed
= SPEED_100
;
271 phy
->speed
= SPEED_10
;
273 phy
->pause
= phy
->asym_pause
= 0;
278 /* Generic implementation for most 10/100/1000 PHYs */
279 static struct mii_phy_ops generic_phy_ops
= {
280 .setup_aneg
= genmii_setup_aneg
,
281 .setup_forced
= genmii_setup_forced
,
282 .poll_link
= genmii_poll_link
,
283 .read_link
= genmii_read_link
286 static struct mii_phy_def genmii_phy_def
= {
287 .phy_id
= 0x00000000,
288 .phy_id_mask
= 0x00000000,
289 .name
= "Generic MII",
290 .ops
= &generic_phy_ops
294 #define MII_CIS8201_10BTCSR 0x16
295 #define TENBTCSR_ECHO_DISABLE 0x2000
296 #define MII_CIS8201_EPCR 0x17
297 #define EPCR_MODE_MASK 0x3000
298 #define EPCR_GMII_MODE 0x0000
299 #define EPCR_RGMII_MODE 0x1000
300 #define EPCR_TBI_MODE 0x2000
301 #define EPCR_RTBI_MODE 0x3000
302 #define MII_CIS8201_ACSR 0x1c
303 #define ACSR_PIN_PRIO_SELECT 0x0004
305 static int cis8201_init(struct mii_phy
*phy
)
309 epcr
= phy_read(phy
, MII_CIS8201_EPCR
);
313 epcr
&= ~EPCR_MODE_MASK
;
317 epcr
|= EPCR_TBI_MODE
;
320 epcr
|= EPCR_RTBI_MODE
;
323 epcr
|= EPCR_GMII_MODE
;
327 epcr
|= EPCR_RGMII_MODE
;
330 phy_write(phy
, MII_CIS8201_EPCR
, epcr
);
332 /* MII regs override strap pins */
333 phy_write(phy
, MII_CIS8201_ACSR
,
334 phy_read(phy
, MII_CIS8201_ACSR
) | ACSR_PIN_PRIO_SELECT
);
336 /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
337 phy_write(phy
, MII_CIS8201_10BTCSR
,
338 phy_read(phy
, MII_CIS8201_10BTCSR
) | TENBTCSR_ECHO_DISABLE
);
343 static struct mii_phy_ops cis8201_phy_ops
= {
344 .init
= cis8201_init
,
345 .setup_aneg
= genmii_setup_aneg
,
346 .setup_forced
= genmii_setup_forced
,
347 .poll_link
= genmii_poll_link
,
348 .read_link
= genmii_read_link
351 static struct mii_phy_def cis8201_phy_def
= {
352 .phy_id
= 0x000fc410,
353 .phy_id_mask
= 0x000ffff0,
354 .name
= "CIS8201 Gigabit Ethernet",
355 .ops
= &cis8201_phy_ops
358 static struct mii_phy_def bcm5248_phy_def
= {
360 .phy_id
= 0x0143bc00,
361 .phy_id_mask
= 0x0ffffff0,
362 .name
= "BCM5248 10/100 SMII Ethernet",
363 .ops
= &generic_phy_ops
366 static int m88e1111_init(struct mii_phy
*phy
)
368 pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__
);
369 phy_write(phy
, 0x14, 0x0ce3);
370 phy_write(phy
, 0x18, 0x4101);
371 phy_write(phy
, 0x09, 0x0e00);
372 phy_write(phy
, 0x04, 0x01e1);
373 phy_write(phy
, 0x00, 0x9140);
374 phy_write(phy
, 0x00, 0x1140);
379 static int m88e1112_init(struct mii_phy
*phy
)
382 * Marvell 88E1112 PHY needs to have the SGMII MAC
383 * interace (page 2) properly configured to
384 * communicate with the 460EX/GT GPCS interface.
389 pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__
);
391 /* Set access to Page 2 */
392 phy_write(phy
, 0x16, 0x0002);
394 phy_write(phy
, 0x00, 0x0040); /* 1Gbps */
395 reg_short
= (u16
)(phy_read(phy
, 0x1a));
396 reg_short
|= 0x8000; /* bypass Auto-Negotiation */
397 phy_write(phy
, 0x1a, reg_short
);
398 emac_mii_reset_phy(phy
); /* reset MAC interface */
400 /* Reset access to Page 0 */
401 phy_write(phy
, 0x16, 0x0000);
406 static int et1011c_init(struct mii_phy
*phy
)
410 reg_short
= (u16
)(phy_read(phy
, 0x16));
412 reg_short
|= 0x6; /* RGMII Trace Delay*/
413 phy_write(phy
, 0x16, reg_short
);
415 reg_short
= (u16
)(phy_read(phy
, 0x17));
416 reg_short
&= ~(0x40);
417 phy_write(phy
, 0x17, reg_short
);
419 phy_write(phy
, 0x1c, 0x74f0);
423 static struct mii_phy_ops et1011c_phy_ops
= {
424 .init
= et1011c_init
,
425 .setup_aneg
= genmii_setup_aneg
,
426 .setup_forced
= genmii_setup_forced
,
427 .poll_link
= genmii_poll_link
,
428 .read_link
= genmii_read_link
431 static struct mii_phy_def et1011c_phy_def
= {
432 .phy_id
= 0x0282f000,
433 .phy_id_mask
= 0x0fffff00,
434 .name
= "ET1011C Gigabit Ethernet",
435 .ops
= &et1011c_phy_ops
442 static struct mii_phy_ops m88e1111_phy_ops
= {
443 .init
= m88e1111_init
,
444 .setup_aneg
= genmii_setup_aneg
,
445 .setup_forced
= genmii_setup_forced
,
446 .poll_link
= genmii_poll_link
,
447 .read_link
= genmii_read_link
450 static struct mii_phy_def m88e1111_phy_def
= {
452 .phy_id
= 0x01410CC0,
453 .phy_id_mask
= 0x0ffffff0,
454 .name
= "Marvell 88E1111 Ethernet",
455 .ops
= &m88e1111_phy_ops
,
458 static struct mii_phy_ops m88e1112_phy_ops
= {
459 .init
= m88e1112_init
,
460 .setup_aneg
= genmii_setup_aneg
,
461 .setup_forced
= genmii_setup_forced
,
462 .poll_link
= genmii_poll_link
,
463 .read_link
= genmii_read_link
466 static struct mii_phy_def m88e1112_phy_def
= {
467 .phy_id
= 0x01410C90,
468 .phy_id_mask
= 0x0ffffff0,
469 .name
= "Marvell 88E1112 Ethernet",
470 .ops
= &m88e1112_phy_ops
,
473 static struct mii_phy_def
*mii_phy_table
[] = {
483 int emac_mii_phy_probe(struct mii_phy
*phy
, int address
)
485 struct mii_phy_def
*def
;
489 phy
->autoneg
= AUTONEG_DISABLE
;
490 phy
->advertising
= 0;
491 phy
->address
= address
;
492 phy
->speed
= SPEED_10
;
493 phy
->duplex
= DUPLEX_HALF
;
494 phy
->pause
= phy
->asym_pause
= 0;
496 /* Take PHY out of isolate mode and reset it. */
497 if (emac_mii_reset_phy(phy
))
500 /* Read ID and find matching entry */
501 id
= (phy_read(phy
, MII_PHYSID1
) << 16) | phy_read(phy
, MII_PHYSID2
);
502 for (i
= 0; (def
= mii_phy_table
[i
]) != NULL
; i
++)
503 if ((id
& def
->phy_id_mask
) == def
->phy_id
)
505 /* Should never be NULL (we have a generic entry), but... */
511 /* Determine PHY features if needed */
512 phy
->features
= def
->features
;
513 if (!phy
->features
) {
514 u16 bmsr
= phy_read(phy
, MII_BMSR
);
515 if (bmsr
& BMSR_ANEGCAPABLE
)
516 phy
->features
|= SUPPORTED_Autoneg
;
517 if (bmsr
& BMSR_10HALF
)
518 phy
->features
|= SUPPORTED_10baseT_Half
;
519 if (bmsr
& BMSR_10FULL
)
520 phy
->features
|= SUPPORTED_10baseT_Full
;
521 if (bmsr
& BMSR_100HALF
)
522 phy
->features
|= SUPPORTED_100baseT_Half
;
523 if (bmsr
& BMSR_100FULL
)
524 phy
->features
|= SUPPORTED_100baseT_Full
;
525 if (bmsr
& BMSR_ESTATEN
) {
526 u16 esr
= phy_read(phy
, MII_ESTATUS
);
527 if (esr
& ESTATUS_1000_TFULL
)
528 phy
->features
|= SUPPORTED_1000baseT_Full
;
529 if (esr
& ESTATUS_1000_THALF
)
530 phy
->features
|= SUPPORTED_1000baseT_Half
;
532 phy
->features
|= SUPPORTED_MII
;
535 /* Setup default advertising */
536 phy
->advertising
= phy
->features
;
541 MODULE_LICENSE("GPL");