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 static inline int phy_read(struct mii_phy
*phy
, int reg
)
33 return phy
->mdio_read(phy
->dev
, phy
->address
, reg
);
36 static inline void phy_write(struct mii_phy
*phy
, int reg
, int val
)
38 phy
->mdio_write(phy
->dev
, phy
->address
, reg
, val
);
41 static inline int gpcs_phy_read(struct mii_phy
*phy
, int reg
)
43 return phy
->mdio_read(phy
->dev
, phy
->gpcs_address
, reg
);
46 static inline void gpcs_phy_write(struct mii_phy
*phy
, int reg
, int val
)
48 phy
->mdio_write(phy
->dev
, phy
->gpcs_address
, reg
, val
);
51 int emac_mii_reset_phy(struct mii_phy
*phy
)
56 val
= phy_read(phy
, MII_BMCR
);
57 val
&= ~(BMCR_ISOLATE
| BMCR_ANENABLE
);
59 phy_write(phy
, MII_BMCR
, val
);
64 val
= phy_read(phy
, MII_BMCR
);
65 if (val
>= 0 && (val
& BMCR_RESET
) == 0)
69 if ((val
& BMCR_ISOLATE
) && limit
> 0)
70 phy_write(phy
, MII_BMCR
, val
& ~BMCR_ISOLATE
);
75 int emac_mii_reset_gpcs(struct mii_phy
*phy
)
80 val
= gpcs_phy_read(phy
, MII_BMCR
);
81 val
&= ~(BMCR_ISOLATE
| BMCR_ANENABLE
);
83 gpcs_phy_write(phy
, MII_BMCR
, val
);
88 val
= gpcs_phy_read(phy
, MII_BMCR
);
89 if (val
>= 0 && (val
& BMCR_RESET
) == 0)
93 if ((val
& BMCR_ISOLATE
) && limit
> 0)
94 gpcs_phy_write(phy
, MII_BMCR
, val
& ~BMCR_ISOLATE
);
96 if (limit
> 0 && phy
->mode
== PHY_MODE_SGMII
) {
97 /* Configure GPCS interface to recommended setting for SGMII */
98 gpcs_phy_write(phy
, 0x04, 0x8120); /* AsymPause, FDX */
99 gpcs_phy_write(phy
, 0x07, 0x2801); /* msg_pg, toggle */
100 gpcs_phy_write(phy
, 0x00, 0x0140); /* 1Gbps, FDX */
106 static int genmii_setup_aneg(struct mii_phy
*phy
, u32 advertise
)
110 phy
->autoneg
= AUTONEG_ENABLE
;
111 phy
->speed
= SPEED_10
;
112 phy
->duplex
= DUPLEX_HALF
;
113 phy
->pause
= phy
->asym_pause
= 0;
114 phy
->advertising
= advertise
;
116 ctl
= phy_read(phy
, MII_BMCR
);
119 ctl
&= ~(BMCR_FULLDPLX
| BMCR_SPEED100
| BMCR_SPEED1000
| BMCR_ANENABLE
);
121 /* First clear the PHY */
122 phy_write(phy
, MII_BMCR
, ctl
);
124 /* Setup standard advertise */
125 adv
= phy_read(phy
, MII_ADVERTISE
);
128 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
| ADVERTISE_PAUSE_CAP
|
129 ADVERTISE_PAUSE_ASYM
);
130 if (advertise
& ADVERTISED_10baseT_Half
)
131 adv
|= ADVERTISE_10HALF
;
132 if (advertise
& ADVERTISED_10baseT_Full
)
133 adv
|= ADVERTISE_10FULL
;
134 if (advertise
& ADVERTISED_100baseT_Half
)
135 adv
|= ADVERTISE_100HALF
;
136 if (advertise
& ADVERTISED_100baseT_Full
)
137 adv
|= ADVERTISE_100FULL
;
138 if (advertise
& ADVERTISED_Pause
)
139 adv
|= ADVERTISE_PAUSE_CAP
;
140 if (advertise
& ADVERTISED_Asym_Pause
)
141 adv
|= ADVERTISE_PAUSE_ASYM
;
142 phy_write(phy
, MII_ADVERTISE
, adv
);
145 (SUPPORTED_1000baseT_Full
| SUPPORTED_1000baseT_Half
)) {
146 adv
= phy_read(phy
, MII_CTRL1000
);
149 adv
&= ~(ADVERTISE_1000FULL
| ADVERTISE_1000HALF
);
150 if (advertise
& ADVERTISED_1000baseT_Full
)
151 adv
|= ADVERTISE_1000FULL
;
152 if (advertise
& ADVERTISED_1000baseT_Half
)
153 adv
|= ADVERTISE_1000HALF
;
154 phy_write(phy
, MII_CTRL1000
, adv
);
157 /* Start/Restart aneg */
158 ctl
= phy_read(phy
, MII_BMCR
);
159 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
160 phy_write(phy
, MII_BMCR
, ctl
);
165 static int genmii_setup_forced(struct mii_phy
*phy
, int speed
, int fd
)
169 phy
->autoneg
= AUTONEG_DISABLE
;
172 phy
->pause
= phy
->asym_pause
= 0;
174 ctl
= phy_read(phy
, MII_BMCR
);
177 ctl
&= ~(BMCR_FULLDPLX
| BMCR_SPEED100
| BMCR_SPEED1000
| BMCR_ANENABLE
);
179 /* First clear the PHY */
180 phy_write(phy
, MII_BMCR
, ctl
| BMCR_RESET
);
182 /* Select speed & duplex */
187 ctl
|= BMCR_SPEED100
;
190 ctl
|= BMCR_SPEED1000
;
195 if (fd
== DUPLEX_FULL
)
196 ctl
|= BMCR_FULLDPLX
;
197 phy_write(phy
, MII_BMCR
, ctl
);
202 static int genmii_poll_link(struct mii_phy
*phy
)
206 /* Clear latched value with dummy read */
207 phy_read(phy
, MII_BMSR
);
208 status
= phy_read(phy
, MII_BMSR
);
209 if (status
< 0 || (status
& BMSR_LSTATUS
) == 0)
211 if (phy
->autoneg
== AUTONEG_ENABLE
&& !(status
& BMSR_ANEGCOMPLETE
))
216 static int genmii_read_link(struct mii_phy
*phy
)
218 if (phy
->autoneg
== AUTONEG_ENABLE
) {
220 int lpa
= phy_read(phy
, MII_LPA
) & phy_read(phy
, MII_ADVERTISE
);
225 (SUPPORTED_1000baseT_Full
| SUPPORTED_1000baseT_Half
)) {
226 int adv
= phy_read(phy
, MII_CTRL1000
);
227 glpa
= phy_read(phy
, MII_STAT1000
);
229 if (glpa
< 0 || adv
< 0)
235 phy
->speed
= SPEED_10
;
236 phy
->duplex
= DUPLEX_HALF
;
237 phy
->pause
= phy
->asym_pause
= 0;
239 if (glpa
& (LPA_1000FULL
| LPA_1000HALF
)) {
240 phy
->speed
= SPEED_1000
;
241 if (glpa
& LPA_1000FULL
)
242 phy
->duplex
= DUPLEX_FULL
;
243 } else if (lpa
& (LPA_100FULL
| LPA_100HALF
)) {
244 phy
->speed
= SPEED_100
;
245 if (lpa
& LPA_100FULL
)
246 phy
->duplex
= DUPLEX_FULL
;
247 } else if (lpa
& LPA_10FULL
)
248 phy
->duplex
= DUPLEX_FULL
;
250 if (phy
->duplex
== DUPLEX_FULL
) {
251 phy
->pause
= lpa
& LPA_PAUSE_CAP
? 1 : 0;
252 phy
->asym_pause
= lpa
& LPA_PAUSE_ASYM
? 1 : 0;
255 int bmcr
= phy_read(phy
, MII_BMCR
);
259 if (bmcr
& BMCR_FULLDPLX
)
260 phy
->duplex
= DUPLEX_FULL
;
262 phy
->duplex
= DUPLEX_HALF
;
263 if (bmcr
& BMCR_SPEED1000
)
264 phy
->speed
= SPEED_1000
;
265 else if (bmcr
& BMCR_SPEED100
)
266 phy
->speed
= SPEED_100
;
268 phy
->speed
= SPEED_10
;
270 phy
->pause
= phy
->asym_pause
= 0;
275 /* Generic implementation for most 10/100/1000 PHYs */
276 static struct mii_phy_ops generic_phy_ops
= {
277 .setup_aneg
= genmii_setup_aneg
,
278 .setup_forced
= genmii_setup_forced
,
279 .poll_link
= genmii_poll_link
,
280 .read_link
= genmii_read_link
283 static struct mii_phy_def genmii_phy_def
= {
284 .phy_id
= 0x00000000,
285 .phy_id_mask
= 0x00000000,
286 .name
= "Generic MII",
287 .ops
= &generic_phy_ops
291 #define MII_CIS8201_10BTCSR 0x16
292 #define TENBTCSR_ECHO_DISABLE 0x2000
293 #define MII_CIS8201_EPCR 0x17
294 #define EPCR_MODE_MASK 0x3000
295 #define EPCR_GMII_MODE 0x0000
296 #define EPCR_RGMII_MODE 0x1000
297 #define EPCR_TBI_MODE 0x2000
298 #define EPCR_RTBI_MODE 0x3000
299 #define MII_CIS8201_ACSR 0x1c
300 #define ACSR_PIN_PRIO_SELECT 0x0004
302 static int cis8201_init(struct mii_phy
*phy
)
306 epcr
= phy_read(phy
, MII_CIS8201_EPCR
);
310 epcr
&= ~EPCR_MODE_MASK
;
314 epcr
|= EPCR_TBI_MODE
;
317 epcr
|= EPCR_RTBI_MODE
;
320 epcr
|= EPCR_GMII_MODE
;
324 epcr
|= EPCR_RGMII_MODE
;
327 phy_write(phy
, MII_CIS8201_EPCR
, epcr
);
329 /* MII regs override strap pins */
330 phy_write(phy
, MII_CIS8201_ACSR
,
331 phy_read(phy
, MII_CIS8201_ACSR
) | ACSR_PIN_PRIO_SELECT
);
333 /* Disable TX_EN -> CRS echo mode, otherwise 10/HDX doesn't work */
334 phy_write(phy
, MII_CIS8201_10BTCSR
,
335 phy_read(phy
, MII_CIS8201_10BTCSR
) | TENBTCSR_ECHO_DISABLE
);
340 static struct mii_phy_ops cis8201_phy_ops
= {
341 .init
= cis8201_init
,
342 .setup_aneg
= genmii_setup_aneg
,
343 .setup_forced
= genmii_setup_forced
,
344 .poll_link
= genmii_poll_link
,
345 .read_link
= genmii_read_link
348 static struct mii_phy_def cis8201_phy_def
= {
349 .phy_id
= 0x000fc410,
350 .phy_id_mask
= 0x000ffff0,
351 .name
= "CIS8201 Gigabit Ethernet",
352 .ops
= &cis8201_phy_ops
355 static struct mii_phy_def bcm5248_phy_def
= {
357 .phy_id
= 0x0143bc00,
358 .phy_id_mask
= 0x0ffffff0,
359 .name
= "BCM5248 10/100 SMII Ethernet",
360 .ops
= &generic_phy_ops
363 static int m88e1111_init(struct mii_phy
*phy
)
365 pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__
);
366 phy_write(phy
, 0x14, 0x0ce3);
367 phy_write(phy
, 0x18, 0x4101);
368 phy_write(phy
, 0x09, 0x0e00);
369 phy_write(phy
, 0x04, 0x01e1);
370 phy_write(phy
, 0x00, 0x9140);
371 phy_write(phy
, 0x00, 0x1140);
376 static int m88e1112_init(struct mii_phy
*phy
)
379 * Marvell 88E1112 PHY needs to have the SGMII MAC
380 * interace (page 2) properly configured to
381 * communicate with the 460EX/GT GPCS interface.
386 pr_debug("%s: Marvell 88E1112 Ethernet\n", __func__
);
388 /* Set access to Page 2 */
389 phy_write(phy
, 0x16, 0x0002);
391 phy_write(phy
, 0x00, 0x0040); /* 1Gbps */
392 reg_short
= (u16
)(phy_read(phy
, 0x1a));
393 reg_short
|= 0x8000; /* bypass Auto-Negotiation */
394 phy_write(phy
, 0x1a, reg_short
);
395 emac_mii_reset_phy(phy
); /* reset MAC interface */
397 /* Reset access to Page 0 */
398 phy_write(phy
, 0x16, 0x0000);
403 static int et1011c_init(struct mii_phy
*phy
)
407 reg_short
= (u16
)(phy_read(phy
, 0x16));
409 reg_short
|= 0x6; /* RGMII Trace Delay*/
410 phy_write(phy
, 0x16, reg_short
);
412 reg_short
= (u16
)(phy_read(phy
, 0x17));
413 reg_short
&= ~(0x40);
414 phy_write(phy
, 0x17, reg_short
);
416 phy_write(phy
, 0x1c, 0x74f0);
420 static struct mii_phy_ops et1011c_phy_ops
= {
421 .init
= et1011c_init
,
422 .setup_aneg
= genmii_setup_aneg
,
423 .setup_forced
= genmii_setup_forced
,
424 .poll_link
= genmii_poll_link
,
425 .read_link
= genmii_read_link
428 static struct mii_phy_def et1011c_phy_def
= {
429 .phy_id
= 0x0282f000,
430 .phy_id_mask
= 0x0fffff00,
431 .name
= "ET1011C Gigabit Ethernet",
432 .ops
= &et1011c_phy_ops
439 static struct mii_phy_ops m88e1111_phy_ops
= {
440 .init
= m88e1111_init
,
441 .setup_aneg
= genmii_setup_aneg
,
442 .setup_forced
= genmii_setup_forced
,
443 .poll_link
= genmii_poll_link
,
444 .read_link
= genmii_read_link
447 static struct mii_phy_def m88e1111_phy_def
= {
449 .phy_id
= 0x01410CC0,
450 .phy_id_mask
= 0x0ffffff0,
451 .name
= "Marvell 88E1111 Ethernet",
452 .ops
= &m88e1111_phy_ops
,
455 static struct mii_phy_ops m88e1112_phy_ops
= {
456 .init
= m88e1112_init
,
457 .setup_aneg
= genmii_setup_aneg
,
458 .setup_forced
= genmii_setup_forced
,
459 .poll_link
= genmii_poll_link
,
460 .read_link
= genmii_read_link
463 static struct mii_phy_def m88e1112_phy_def
= {
464 .phy_id
= 0x01410C90,
465 .phy_id_mask
= 0x0ffffff0,
466 .name
= "Marvell 88E1112 Ethernet",
467 .ops
= &m88e1112_phy_ops
,
470 static struct mii_phy_def
*mii_phy_table
[] = {
480 int emac_mii_phy_probe(struct mii_phy
*phy
, int address
)
482 struct mii_phy_def
*def
;
486 phy
->autoneg
= AUTONEG_DISABLE
;
487 phy
->advertising
= 0;
488 phy
->address
= address
;
489 phy
->speed
= SPEED_10
;
490 phy
->duplex
= DUPLEX_HALF
;
491 phy
->pause
= phy
->asym_pause
= 0;
493 /* Take PHY out of isolate mode and reset it. */
494 if (emac_mii_reset_phy(phy
))
497 /* Read ID and find matching entry */
498 id
= (phy_read(phy
, MII_PHYSID1
) << 16) | phy_read(phy
, MII_PHYSID2
);
499 for (i
= 0; (def
= mii_phy_table
[i
]) != NULL
; i
++)
500 if ((id
& def
->phy_id_mask
) == def
->phy_id
)
502 /* Should never be NULL (we have a generic entry), but... */
508 /* Determine PHY features if needed */
509 phy
->features
= def
->features
;
510 if (!phy
->features
) {
511 u16 bmsr
= phy_read(phy
, MII_BMSR
);
512 if (bmsr
& BMSR_ANEGCAPABLE
)
513 phy
->features
|= SUPPORTED_Autoneg
;
514 if (bmsr
& BMSR_10HALF
)
515 phy
->features
|= SUPPORTED_10baseT_Half
;
516 if (bmsr
& BMSR_10FULL
)
517 phy
->features
|= SUPPORTED_10baseT_Full
;
518 if (bmsr
& BMSR_100HALF
)
519 phy
->features
|= SUPPORTED_100baseT_Half
;
520 if (bmsr
& BMSR_100FULL
)
521 phy
->features
|= SUPPORTED_100baseT_Full
;
522 if (bmsr
& BMSR_ESTATEN
) {
523 u16 esr
= phy_read(phy
, MII_ESTATUS
);
524 if (esr
& ESTATUS_1000_TFULL
)
525 phy
->features
|= SUPPORTED_1000baseT_Full
;
526 if (esr
& ESTATUS_1000_THALF
)
527 phy
->features
|= SUPPORTED_1000baseT_Half
;
529 phy
->features
|= SUPPORTED_MII
;
532 /* Setup default advertising */
533 phy
->advertising
= phy
->features
;
538 MODULE_LICENSE("GPL");