2 * Principal Author: Parag Patel
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Additional Copyright (c) 2001 by Traakan Software under same licence.
29 * Secondary Author: Matthew Jacob
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
36 * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY.
40 * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and
42 * Nathan Binkert <nate@openbsd.org>
43 * Jung-uk Kim <jkim@niksun.com>
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/kernel.h>
49 #include <sys/module.h>
50 #include <sys/socket.h>
55 #include <net/if_media.h>
57 #include <dev/mii/mii.h>
58 #include <dev/mii/miivar.h>
61 #include <dev/mii/e1000phyreg.h>
63 #include "miibus_if.h"
65 static int e1000phy_probe(device_t
);
66 static int e1000phy_attach(device_t
);
68 static device_method_t e1000phy_methods
[] = {
69 /* device interface */
70 DEVMETHOD(device_probe
, e1000phy_probe
),
71 DEVMETHOD(device_attach
, e1000phy_attach
),
72 DEVMETHOD(device_detach
, mii_phy_detach
),
73 DEVMETHOD(device_shutdown
, bus_generic_shutdown
),
77 static devclass_t e1000phy_devclass
;
78 static driver_t e1000phy_driver
= {
81 sizeof(struct mii_softc
)
84 DRIVER_MODULE(e1000phy
, miibus
, e1000phy_driver
, e1000phy_devclass
, 0, 0);
86 static int e1000phy_service(struct mii_softc
*, struct mii_data
*, int);
87 static void e1000phy_status(struct mii_softc
*);
88 static void e1000phy_reset(struct mii_softc
*);
89 static int e1000phy_mii_phy_auto(struct mii_softc
*, int);
91 static const struct mii_phydesc e1000phys
[] = {
92 MII_PHY_DESC(MARVELL
, E1000
),
93 MII_PHY_DESC(MARVELL
, E1011
),
94 MII_PHY_DESC(MARVELL
, E1000_3
),
95 MII_PHY_DESC(MARVELL
, E1000_5
),
96 MII_PHY_DESC(MARVELL
, E1111
),
97 MII_PHY_DESC(xxMARVELL
, E1000
),
98 MII_PHY_DESC(xxMARVELL
, E1011
),
99 MII_PHY_DESC(xxMARVELL
, E1000_3
),
100 MII_PHY_DESC(xxMARVELL
, E1000S
),
101 MII_PHY_DESC(xxMARVELL
, E1000_5
),
102 MII_PHY_DESC(xxMARVELL
, E1101
),
103 MII_PHY_DESC(xxMARVELL
, E3082
),
104 MII_PHY_DESC(xxMARVELL
, E1112
),
105 MII_PHY_DESC(xxMARVELL
, E1149
),
106 MII_PHY_DESC(xxMARVELL
, E1111
),
107 MII_PHY_DESC(xxMARVELL
, E1116
),
108 MII_PHY_DESC(xxMARVELL
, E1116R
),
109 MII_PHY_DESC(xxMARVELL
, E1118
),
110 MII_PHY_DESC(xxMARVELL
, E1149R
),
111 MII_PHY_DESC(xxMARVELL
, E3016
),
112 MII_PHY_DESC(xxMARVELL
, PHYG65G
),
116 static const struct mii_phy_funcs e1000phy_funcs
= {
123 e1000phy_probe(device_t dev
)
126 return (mii_phy_dev_probe(dev
, e1000phys
, BUS_PROBE_DEFAULT
));
130 e1000phy_attach(device_t dev
)
132 struct mii_softc
*sc
;
135 sc
= device_get_softc(dev
);
137 mii_phy_dev_attach(dev
, MIIF_NOMANPAUSE
, &e1000phy_funcs
, 0);
139 ifp
= sc
->mii_pdata
->mii_ifp
;
140 if (strcmp(ifp
->if_dname
, "msk") == 0 &&
141 (sc
->mii_flags
& MIIF_MACPRIV0
) != 0)
142 sc
->mii_flags
|= MIIF_PHYPRIV0
;
144 switch (sc
->mii_mpd_model
) {
145 case MII_MODEL_xxMARVELL_E1011
:
146 case MII_MODEL_xxMARVELL_E1112
:
147 if (PHY_READ(sc
, E1000_ESSR
) & E1000_ESSR_FIBER_LINK
)
148 sc
->mii_flags
|= MIIF_HAVEFIBER
;
150 case MII_MODEL_xxMARVELL_E1149
:
151 case MII_MODEL_xxMARVELL_E1149R
:
153 * Some 88E1149 PHY's page select is initialized to
154 * point to other bank instead of copper/fiber bank
155 * which in turn resulted in wrong registers were
156 * accessed during PHY operation. It is believed that
157 * page 0 should be used for copper PHY so reinitialize
158 * E1000_EADR to select default copper PHY. If parent
159 * device know the type of PHY(either copper or fiber),
160 * that information should be used to select default
163 PHY_WRITE(sc
, E1000_EADR
, 0);
169 sc
->mii_capabilities
= PHY_READ(sc
, MII_BMSR
) & sc
->mii_capmask
;
170 if (sc
->mii_capabilities
& BMSR_EXTSTAT
)
171 sc
->mii_extcapabilities
= PHY_READ(sc
, MII_EXTSR
);
172 device_printf(dev
, " ");
173 mii_phy_add_media(sc
);
176 MIIBUS_MEDIAINIT(sc
->mii_dev
);
181 e1000phy_reset(struct mii_softc
*sc
)
185 reg
= PHY_READ(sc
, E1000_SCR
);
186 if ((sc
->mii_flags
& MIIF_HAVEFIBER
) != 0) {
187 reg
&= ~E1000_SCR_AUTO_X_MODE
;
188 PHY_WRITE(sc
, E1000_SCR
, reg
);
189 if (sc
->mii_mpd_model
== MII_MODEL_xxMARVELL_E1112
) {
190 /* Select 1000BASE-X only mode. */
191 page
= PHY_READ(sc
, E1000_EADR
);
192 PHY_WRITE(sc
, E1000_EADR
, 2);
193 reg
= PHY_READ(sc
, E1000_SCR
);
194 reg
&= ~E1000_SCR_MODE_MASK
;
195 reg
|= E1000_SCR_MODE_1000BX
;
196 PHY_WRITE(sc
, E1000_SCR
, reg
);
197 if ((sc
->mii_flags
& MIIF_PHYPRIV0
) != 0) {
198 /* Set SIGDET polarity low for SFP module. */
199 PHY_WRITE(sc
, E1000_EADR
, 1);
200 reg
= PHY_READ(sc
, E1000_SCR
);
201 reg
|= E1000_SCR_FIB_SIGDET_POLARITY
;
202 PHY_WRITE(sc
, E1000_SCR
, reg
);
204 PHY_WRITE(sc
, E1000_EADR
, page
);
207 switch (sc
->mii_mpd_model
) {
208 case MII_MODEL_xxMARVELL_E1111
:
209 case MII_MODEL_xxMARVELL_E1112
:
210 case MII_MODEL_xxMARVELL_E1116
:
211 case MII_MODEL_xxMARVELL_E1118
:
212 case MII_MODEL_xxMARVELL_E1149
:
213 case MII_MODEL_xxMARVELL_E1149R
:
214 case MII_MODEL_xxMARVELL_PHYG65G
:
215 /* Disable energy detect mode. */
216 reg
&= ~E1000_SCR_EN_DETECT_MASK
;
217 reg
|= E1000_SCR_AUTO_X_MODE
;
218 if (sc
->mii_mpd_model
== MII_MODEL_xxMARVELL_E1116
)
219 reg
&= ~E1000_SCR_POWER_DOWN
;
220 reg
|= E1000_SCR_ASSERT_CRS_ON_TX
;
222 case MII_MODEL_xxMARVELL_E3082
:
223 reg
|= (E1000_SCR_AUTO_X_MODE
>> 1);
224 reg
|= E1000_SCR_ASSERT_CRS_ON_TX
;
226 case MII_MODEL_xxMARVELL_E3016
:
227 reg
|= E1000_SCR_AUTO_MDIX
;
228 reg
&= ~(E1000_SCR_EN_DETECT
|
229 E1000_SCR_SCRAMBLER_DISABLE
);
230 reg
|= E1000_SCR_LPNP
;
231 /* XXX Enable class A driver for Yukon FE+ A0. */
232 PHY_WRITE(sc
, 0x1C, PHY_READ(sc
, 0x1C) | 0x0001);
235 reg
&= ~E1000_SCR_AUTO_X_MODE
;
236 reg
|= E1000_SCR_ASSERT_CRS_ON_TX
;
239 if (sc
->mii_mpd_model
!= MII_MODEL_xxMARVELL_E3016
) {
240 /* Auto correction for reversed cable polarity. */
241 reg
&= ~E1000_SCR_POLARITY_REVERSAL
;
243 PHY_WRITE(sc
, E1000_SCR
, reg
);
245 if (sc
->mii_mpd_model
== MII_MODEL_xxMARVELL_E1116
||
246 sc
->mii_mpd_model
== MII_MODEL_xxMARVELL_E1149
||
247 sc
->mii_mpd_model
== MII_MODEL_xxMARVELL_E1149R
) {
248 PHY_WRITE(sc
, E1000_EADR
, 2);
249 reg
= PHY_READ(sc
, E1000_SCR
);
250 reg
|= E1000_SCR_RGMII_POWER_UP
;
251 PHY_WRITE(sc
, E1000_SCR
, reg
);
252 PHY_WRITE(sc
, E1000_EADR
, 0);
256 switch (sc
->mii_mpd_model
) {
257 case MII_MODEL_xxMARVELL_E3082
:
258 case MII_MODEL_xxMARVELL_E1112
:
259 case MII_MODEL_xxMARVELL_E1118
:
261 case MII_MODEL_xxMARVELL_E1116
:
262 page
= PHY_READ(sc
, E1000_EADR
);
263 /* Select page 3, LED control register. */
264 PHY_WRITE(sc
, E1000_EADR
, 3);
265 PHY_WRITE(sc
, E1000_SCR
,
266 E1000_SCR_LED_LOS(1) | /* Link/Act */
267 E1000_SCR_LED_INIT(8) | /* 10Mbps */
268 E1000_SCR_LED_STAT1(7) | /* 100Mbps */
269 E1000_SCR_LED_STAT0(7)); /* 1000Mbps */
270 /* Set blink rate. */
271 PHY_WRITE(sc
, E1000_IER
, E1000_PULSE_DUR(E1000_PULSE_170MS
) |
272 E1000_BLINK_RATE(E1000_BLINK_84MS
));
273 PHY_WRITE(sc
, E1000_EADR
, page
);
275 case MII_MODEL_xxMARVELL_E3016
:
276 /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
277 PHY_WRITE(sc
, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
278 /* Integrated register calibration workaround. */
279 PHY_WRITE(sc
, 0x1D, 17);
280 PHY_WRITE(sc
, 0x1E, 0x3F60);
283 /* Force TX_CLK to 25MHz clock. */
284 reg
= PHY_READ(sc
, E1000_ESCR
);
285 reg
|= E1000_ESCR_TX_CLK_25
;
286 PHY_WRITE(sc
, E1000_ESCR
, reg
);
290 /* Reset the PHY so all changes take effect. */
291 reg
= PHY_READ(sc
, E1000_CR
);
292 reg
|= E1000_CR_RESET
;
293 PHY_WRITE(sc
, E1000_CR
, reg
);
297 e1000phy_service(struct mii_softc
*sc
, struct mii_data
*mii
, int cmd
)
299 struct ifmedia_entry
*ife
= mii
->mii_media
.ifm_cur
;
309 * If the interface is not up, don't do anything.
311 if ((mii
->mii_ifp
->if_flags
& IFF_UP
) == 0)
314 if (IFM_SUBTYPE(ife
->ifm_media
) == IFM_AUTO
) {
315 e1000phy_mii_phy_auto(sc
, ife
->ifm_media
);
320 switch (IFM_SUBTYPE(ife
->ifm_media
)) {
322 if ((sc
->mii_extcapabilities
&
323 (EXTSR_1000TFDX
| EXTSR_1000THDX
)) == 0)
325 speed
= E1000_CR_SPEED_1000
;
328 if ((sc
->mii_extcapabilities
&
329 (EXTSR_1000XFDX
| EXTSR_1000XHDX
)) == 0)
331 speed
= E1000_CR_SPEED_1000
;
334 speed
= E1000_CR_SPEED_100
;
337 speed
= E1000_CR_SPEED_10
;
340 reg
= PHY_READ(sc
, E1000_CR
);
341 PHY_WRITE(sc
, E1000_CR
,
342 reg
| E1000_CR_ISOLATE
| E1000_CR_POWER_DOWN
);
348 if ((ife
->ifm_media
& IFM_FDX
) != 0) {
349 speed
|= E1000_CR_FULL_DUPLEX
;
350 gig
= E1000_1GCR_1000T_FD
;
352 gig
= E1000_1GCR_1000T
;
354 reg
= PHY_READ(sc
, E1000_CR
);
355 reg
&= ~E1000_CR_AUTO_NEG_ENABLE
;
356 PHY_WRITE(sc
, E1000_CR
, reg
| E1000_CR_RESET
);
358 if (IFM_SUBTYPE(ife
->ifm_media
) == IFM_1000_T
) {
359 gig
|= E1000_1GCR_MS_ENABLE
;
360 if ((ife
->ifm_media
& IFM_ETH_MASTER
) != 0)
361 gig
|= E1000_1GCR_MS_VALUE
;
362 } else if ((sc
->mii_extcapabilities
&
363 (EXTSR_1000TFDX
| EXTSR_1000THDX
)) != 0)
365 PHY_WRITE(sc
, E1000_1GCR
, gig
);
366 PHY_WRITE(sc
, E1000_AR
, E1000_AR_SELECTOR_FIELD
);
367 PHY_WRITE(sc
, E1000_CR
, speed
| E1000_CR_RESET
);
372 * Is the interface even up?
374 if ((mii
->mii_ifp
->if_flags
& IFF_UP
) == 0)
378 * Only used for autonegotiation.
380 if (IFM_SUBTYPE(ife
->ifm_media
) != IFM_AUTO
) {
387 * Read the status register twice; BMSR_LINK is latch-low.
389 reg
= PHY_READ(sc
, MII_BMSR
) | PHY_READ(sc
, MII_BMSR
);
390 if (reg
& BMSR_LINK
) {
395 /* Announce link loss right after it happens. */
396 if (sc
->mii_ticks
++ == 0)
398 if (sc
->mii_ticks
<= sc
->mii_anegticks
)
403 e1000phy_mii_phy_auto(sc
, ife
->ifm_media
);
407 /* Update the media status. */
410 /* Callback if something changed. */
411 mii_phy_update(sc
, cmd
);
416 e1000phy_status(struct mii_softc
*sc
)
418 struct mii_data
*mii
= sc
->mii_pdata
;
421 mii
->mii_media_status
= IFM_AVALID
;
422 mii
->mii_media_active
= IFM_ETHER
;
424 bmsr
= PHY_READ(sc
, E1000_SR
) | PHY_READ(sc
, E1000_SR
);
425 bmcr
= PHY_READ(sc
, E1000_CR
);
426 ssr
= PHY_READ(sc
, E1000_SSR
);
428 if (bmsr
& E1000_SR_LINK_STATUS
)
429 mii
->mii_media_status
|= IFM_ACTIVE
;
431 if (bmcr
& E1000_CR_LOOPBACK
)
432 mii
->mii_media_active
|= IFM_LOOP
;
434 if ((bmcr
& E1000_CR_AUTO_NEG_ENABLE
) != 0 &&
435 (ssr
& E1000_SSR_SPD_DPLX_RESOLVED
) == 0) {
436 /* Erg, still trying, I guess... */
437 mii
->mii_media_active
|= IFM_NONE
;
441 if ((sc
->mii_flags
& MIIF_HAVEFIBER
) == 0) {
442 switch (ssr
& E1000_SSR_SPEED
) {
443 case E1000_SSR_1000MBS
:
444 mii
->mii_media_active
|= IFM_1000_T
;
446 case E1000_SSR_100MBS
:
447 mii
->mii_media_active
|= IFM_100_TX
;
449 case E1000_SSR_10MBS
:
450 mii
->mii_media_active
|= IFM_10_T
;
453 mii
->mii_media_active
|= IFM_NONE
;
458 * Some fiber PHY(88E1112) does not seem to set resolved
459 * speed so always assume we've got IFM_1000_SX.
461 mii
->mii_media_active
|= IFM_1000_SX
;
464 if (ssr
& E1000_SSR_DUPLEX
) {
465 mii
->mii_media_active
|= IFM_FDX
;
466 if ((sc
->mii_flags
& MIIF_HAVEFIBER
) == 0)
467 mii
->mii_media_active
|= mii_phy_flowstatus(sc
);
469 mii
->mii_media_active
|= IFM_HDX
;
471 if (IFM_SUBTYPE(mii
->mii_media_active
) == IFM_1000_T
) {
472 if (((PHY_READ(sc
, E1000_1GSR
) | PHY_READ(sc
, E1000_1GSR
)) &
473 E1000_1GSR_MS_CONFIG_RES
) != 0)
474 mii
->mii_media_active
|= IFM_ETH_MASTER
;
479 e1000phy_mii_phy_auto(struct mii_softc
*sc
, int media
)
483 if ((sc
->mii_flags
& MIIF_HAVEFIBER
) == 0) {
484 reg
= PHY_READ(sc
, E1000_AR
);
485 reg
&= ~(E1000_AR_PAUSE
| E1000_AR_ASM_DIR
);
486 reg
|= E1000_AR_10T
| E1000_AR_10T_FD
|
487 E1000_AR_100TX
| E1000_AR_100TX_FD
;
488 if ((media
& IFM_FLOW
) != 0 ||
489 (sc
->mii_flags
& MIIF_FORCEPAUSE
) != 0)
490 reg
|= E1000_AR_PAUSE
| E1000_AR_ASM_DIR
;
491 PHY_WRITE(sc
, E1000_AR
, reg
| E1000_AR_SELECTOR_FIELD
);
493 PHY_WRITE(sc
, E1000_AR
, E1000_FA_1000X_FD
| E1000_FA_1000X
);
494 if ((sc
->mii_extcapabilities
& (EXTSR_1000TFDX
| EXTSR_1000THDX
)) != 0)
495 PHY_WRITE(sc
, E1000_1GCR
,
496 E1000_1GCR_1000T_FD
| E1000_1GCR_1000T
);
497 PHY_WRITE(sc
, E1000_CR
,
498 E1000_CR_AUTO_NEG_ENABLE
| E1000_CR_RESTART_AUTO_NEG
);
500 return (EJUSTRETURN
);