xref: /freebsd/sys/dev/mii/e1000phy.c (revision 814bd1ed438f7dfc5bedcb1f3e772a46fe7026bb)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-NetBSD
3  *
4  * Principal Author: Parag Patel
5  * Copyright (c) 2001
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice unmodified, this list of conditions, and the following
13  *    disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * Additional Copyright (c) 2001 by Traakan Software under same licence.
31  * Secondary Author: Matthew Jacob
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 /*
38  * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY.
39  */
40 
41 /*
42  * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and
43  * 1000baseSX PHY.
44  * Nathan Binkert <nate@openbsd.org>
45  * Jung-uk Kim <jkim@niksun.com>
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/module.h>
52 #include <sys/socket.h>
53 #include <sys/bus.h>
54 
55 #include <net/if.h>
56 #include <net/if_var.h>
57 #include <net/if_media.h>
58 
59 #include <dev/mii/mii.h>
60 #include <dev/mii/miivar.h>
61 #include "miidevs.h"
62 
63 #include <dev/mii/e1000phyreg.h>
64 
65 #include "miibus_if.h"
66 
67 static int	e1000phy_probe(device_t);
68 static int	e1000phy_attach(device_t);
69 
70 static device_method_t e1000phy_methods[] = {
71 	/* device interface */
72 	DEVMETHOD(device_probe,		e1000phy_probe),
73 	DEVMETHOD(device_attach,	e1000phy_attach),
74 	DEVMETHOD(device_detach,	mii_phy_detach),
75 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
76 	DEVMETHOD_END
77 };
78 
79 static driver_t e1000phy_driver = {
80 	"e1000phy",
81 	e1000phy_methods,
82 	sizeof(struct mii_softc)
83 };
84 
85 DRIVER_MODULE(e1000phy, miibus, e1000phy_driver, 0, 0);
86 
87 static int	e1000phy_service(struct mii_softc *, struct mii_data *, int);
88 static void	e1000phy_status(struct mii_softc *);
89 static void	e1000phy_reset(struct mii_softc *);
90 static int	e1000phy_mii_phy_auto(struct mii_softc *, int);
91 
92 static const struct mii_phydesc e1000phys[] = {
93 	MII_PHY_DESC(MARVELL, E1000),
94 	MII_PHY_DESC(MARVELL, E1011),
95 	MII_PHY_DESC(MARVELL, E1000_3),
96 	MII_PHY_DESC(MARVELL, E1000_5),
97 	MII_PHY_DESC(MARVELL, E1111),
98 	MII_PHY_DESC(xxMARVELL, E1000),
99 	MII_PHY_DESC(xxMARVELL, E1011),
100 	MII_PHY_DESC(xxMARVELL, E1000_3),
101 	MII_PHY_DESC(xxMARVELL, E1000S),
102 	MII_PHY_DESC(xxMARVELL, E1000_5),
103 	MII_PHY_DESC(xxMARVELL, E1101),
104 	MII_PHY_DESC(xxMARVELL, E3082),
105 	MII_PHY_DESC(xxMARVELL, E1112),
106 	MII_PHY_DESC(xxMARVELL, E1149),
107 	MII_PHY_DESC(xxMARVELL, E1111),
108 	MII_PHY_DESC(xxMARVELL, E1116),
109 	MII_PHY_DESC(xxMARVELL, E1116R),
110 	MII_PHY_DESC(xxMARVELL, E1116R_29),
111 	MII_PHY_DESC(xxMARVELL, E1118),
112 	MII_PHY_DESC(xxMARVELL, E1145),
113 	MII_PHY_DESC(xxMARVELL, E1149R),
114 	MII_PHY_DESC(xxMARVELL, E3016),
115 	MII_PHY_DESC(xxMARVELL, PHYG65G),
116 	MII_PHY_END
117 };
118 
119 static const struct mii_phy_funcs e1000phy_funcs = {
120 	e1000phy_service,
121 	e1000phy_status,
122 	e1000phy_reset
123 };
124 
125 static int
126 e1000phy_probe(device_t	dev)
127 {
128 
129 	return (mii_phy_dev_probe(dev, e1000phys, BUS_PROBE_DEFAULT));
130 }
131 
132 static int
133 e1000phy_attach(device_t dev)
134 {
135 	struct mii_softc *sc;
136 
137 	sc = device_get_softc(dev);
138 
139 	mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &e1000phy_funcs, 0);
140 
141 	if (mii_dev_mac_match(dev, "msk") &&
142 	    (sc->mii_flags & MIIF_MACPRIV0) != 0)
143 		sc->mii_flags |= MIIF_PHYPRIV0;
144 
145 	switch (sc->mii_mpd_model) {
146 	case MII_MODEL_xxMARVELL_E1011:
147 	case MII_MODEL_xxMARVELL_E1112:
148 		if (PHY_READ(sc, E1000_ESSR) & E1000_ESSR_FIBER_LINK)
149 			sc->mii_flags |= MIIF_HAVEFIBER;
150 		break;
151 	case MII_MODEL_xxMARVELL_E1149:
152 	case MII_MODEL_xxMARVELL_E1149R:
153 		/*
154 		 * Some 88E1149 PHY's page select is initialized to
155 		 * point to other bank instead of copper/fiber bank
156 		 * which in turn resulted in wrong registers were
157 		 * accessed during PHY operation. It is believed that
158 		 * page 0 should be used for copper PHY so reinitialize
159 		 * E1000_EADR to select default copper PHY. If parent
160 		 * device know the type of PHY(either copper or fiber),
161 		 * that information should be used to select default
162 		 * type of PHY.
163 		 */
164 		PHY_WRITE(sc, E1000_EADR, 0);
165 		break;
166 	}
167 
168 	PHY_RESET(sc);
169 
170 	sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask;
171 	if (sc->mii_capabilities & BMSR_EXTSTAT) {
172 		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
173 		if ((sc->mii_extcapabilities &
174 		    (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
175 			sc->mii_flags |= MIIF_HAVE_GTCR;
176 	}
177 	device_printf(dev, " ");
178 	mii_phy_add_media(sc);
179 	printf("\n");
180 
181 	MIIBUS_MEDIAINIT(sc->mii_dev);
182 	return (0);
183 }
184 
185 static void
186 e1000phy_reset(struct mii_softc *sc)
187 {
188 	uint16_t reg, page;
189 
190 	reg = PHY_READ(sc, E1000_SCR);
191 	if ((sc->mii_flags & MIIF_HAVEFIBER) != 0) {
192 		reg &= ~E1000_SCR_AUTO_X_MODE;
193 		PHY_WRITE(sc, E1000_SCR, reg);
194 		if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1112) {
195 			/* Select 1000BASE-X only mode. */
196 			page = PHY_READ(sc, E1000_EADR);
197 			PHY_WRITE(sc, E1000_EADR, 2);
198 			reg = PHY_READ(sc, E1000_SCR);
199 			reg &= ~E1000_SCR_MODE_MASK;
200 			reg |= E1000_SCR_MODE_1000BX;
201 			PHY_WRITE(sc, E1000_SCR, reg);
202 			if ((sc->mii_flags & MIIF_PHYPRIV0) != 0) {
203 				/* Set SIGDET polarity low for SFP module. */
204 				PHY_WRITE(sc, E1000_EADR, 1);
205 				reg = PHY_READ(sc, E1000_SCR);
206 				reg |= E1000_SCR_FIB_SIGDET_POLARITY;
207 				PHY_WRITE(sc, E1000_SCR, reg);
208 			}
209 			PHY_WRITE(sc, E1000_EADR, page);
210 		}
211 	} else {
212 		switch (sc->mii_mpd_model) {
213 		case MII_MODEL_xxMARVELL_E1111:
214 		case MII_MODEL_xxMARVELL_E1112:
215 		case MII_MODEL_xxMARVELL_E1116:
216 		case MII_MODEL_xxMARVELL_E1116R_29:
217 		case MII_MODEL_xxMARVELL_E1118:
218 		case MII_MODEL_xxMARVELL_E1149:
219 		case MII_MODEL_xxMARVELL_E1149R:
220 		case MII_MODEL_xxMARVELL_PHYG65G:
221 			/* Disable energy detect mode. */
222 			reg &= ~E1000_SCR_EN_DETECT_MASK;
223 			reg |= E1000_SCR_AUTO_X_MODE;
224 			if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116 ||
225 			    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116R_29)
226 				reg &= ~E1000_SCR_POWER_DOWN;
227 			reg |= E1000_SCR_ASSERT_CRS_ON_TX;
228 			break;
229 		case MII_MODEL_xxMARVELL_E3082:
230 			reg |= (E1000_SCR_AUTO_X_MODE >> 1);
231 			reg |= E1000_SCR_ASSERT_CRS_ON_TX;
232 			break;
233 		case MII_MODEL_xxMARVELL_E3016:
234 			reg |= E1000_SCR_AUTO_MDIX;
235 			reg &= ~(E1000_SCR_EN_DETECT |
236 			    E1000_SCR_SCRAMBLER_DISABLE);
237 			reg |= E1000_SCR_LPNP;
238 			/* XXX Enable class A driver for Yukon FE+ A0. */
239 			PHY_WRITE(sc, 0x1C, PHY_READ(sc, 0x1C) | 0x0001);
240 			break;
241 		default:
242 			reg &= ~E1000_SCR_AUTO_X_MODE;
243 			reg |= E1000_SCR_ASSERT_CRS_ON_TX;
244 			break;
245 		}
246 		if (sc->mii_mpd_model != MII_MODEL_xxMARVELL_E3016) {
247 			/* Auto correction for reversed cable polarity. */
248 			reg &= ~E1000_SCR_POLARITY_REVERSAL;
249 		}
250 		PHY_WRITE(sc, E1000_SCR, reg);
251 
252 		if (sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116 ||
253 		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1116R_29 ||
254 		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1149 ||
255 		    sc->mii_mpd_model == MII_MODEL_xxMARVELL_E1149R) {
256 			PHY_WRITE(sc, E1000_EADR, 2);
257 			reg = PHY_READ(sc, E1000_SCR);
258 			reg |= E1000_SCR_RGMII_POWER_UP;
259 			PHY_WRITE(sc, E1000_SCR, reg);
260 			PHY_WRITE(sc, E1000_EADR, 0);
261 		}
262 	}
263 
264 	switch (sc->mii_mpd_model) {
265 	case MII_MODEL_xxMARVELL_E3082:
266 	case MII_MODEL_xxMARVELL_E1112:
267 	case MII_MODEL_xxMARVELL_E1118:
268 		break;
269 	case MII_MODEL_xxMARVELL_E1116:
270 	case MII_MODEL_xxMARVELL_E1116R_29:
271 		page = PHY_READ(sc, E1000_EADR);
272 		/* Select page 3, LED control register. */
273 		PHY_WRITE(sc, E1000_EADR, 3);
274 		PHY_WRITE(sc, E1000_SCR,
275 		    E1000_SCR_LED_LOS(1) |	/* Link/Act */
276 		    E1000_SCR_LED_INIT(8) |	/* 10Mbps */
277 		    E1000_SCR_LED_STAT1(7) |	/* 100Mbps */
278 		    E1000_SCR_LED_STAT0(7));	/* 1000Mbps */
279 		/* Set blink rate. */
280 		PHY_WRITE(sc, E1000_IER, E1000_PULSE_DUR(E1000_PULSE_170MS) |
281 		    E1000_BLINK_RATE(E1000_BLINK_84MS));
282 		PHY_WRITE(sc, E1000_EADR, page);
283 		break;
284 	case MII_MODEL_xxMARVELL_E3016:
285 		/* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */
286 		PHY_WRITE(sc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04);
287 		/* Integrated register calibration workaround. */
288 		PHY_WRITE(sc, 0x1D, 17);
289 		PHY_WRITE(sc, 0x1E, 0x3F60);
290 		break;
291 	default:
292 		/* Force TX_CLK to 25MHz clock. */
293 		reg = PHY_READ(sc, E1000_ESCR);
294 		reg |= E1000_ESCR_TX_CLK_25;
295 		PHY_WRITE(sc, E1000_ESCR, reg);
296 		break;
297 	}
298 
299 	/* Reset the PHY so all changes take effect. */
300 	reg = PHY_READ(sc, E1000_CR);
301 	reg |= E1000_CR_RESET;
302 	PHY_WRITE(sc, E1000_CR, reg);
303 }
304 
305 static int
306 e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
307 {
308 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
309 	uint16_t speed, gig;
310 	int reg;
311 
312 	switch (cmd) {
313 	case MII_POLLSTAT:
314 		break;
315 
316 	case MII_MEDIACHG:
317 		if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) {
318 			e1000phy_mii_phy_auto(sc, ife->ifm_media);
319 			break;
320 		}
321 
322 		speed = 0;
323 		switch (IFM_SUBTYPE(ife->ifm_media)) {
324 		case IFM_1000_T:
325 			if ((sc->mii_flags & MIIF_HAVE_GTCR) == 0)
326 				return (EINVAL);
327 			speed = E1000_CR_SPEED_1000;
328 			break;
329 		case IFM_1000_SX:
330 			if ((sc->mii_extcapabilities &
331 			    (EXTSR_1000XFDX | EXTSR_1000XHDX)) == 0)
332 				return (EINVAL);
333 			speed = E1000_CR_SPEED_1000;
334 			break;
335 		case IFM_100_TX:
336 			speed = E1000_CR_SPEED_100;
337 			break;
338 		case IFM_10_T:
339 			speed = E1000_CR_SPEED_10;
340 			break;
341 		case IFM_NONE:
342 			reg = PHY_READ(sc, E1000_CR);
343 			PHY_WRITE(sc, E1000_CR,
344 			    reg | E1000_CR_ISOLATE | E1000_CR_POWER_DOWN);
345 			goto done;
346 		default:
347 			return (EINVAL);
348 		}
349 
350 		if ((ife->ifm_media & IFM_FDX) != 0) {
351 			speed |= E1000_CR_FULL_DUPLEX;
352 			gig = E1000_1GCR_1000T_FD;
353 		} else
354 			gig = E1000_1GCR_1000T;
355 
356 		reg = PHY_READ(sc, E1000_CR);
357 		reg &= ~E1000_CR_AUTO_NEG_ENABLE;
358 		PHY_WRITE(sc, E1000_CR, reg | E1000_CR_RESET);
359 
360 		if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
361 			gig |= E1000_1GCR_MS_ENABLE;
362 			if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
363 				gig |= E1000_1GCR_MS_VALUE;
364 		} else if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0)
365 			gig = 0;
366 		PHY_WRITE(sc, E1000_1GCR, gig);
367 		PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD);
368 		PHY_WRITE(sc, E1000_CR, speed | E1000_CR_RESET);
369 done:
370 		break;
371 	case MII_TICK:
372 		/*
373 		 * Only used for autonegotiation.
374 		 */
375 		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
376 			sc->mii_ticks = 0;
377 			break;
378 		}
379 
380 		/*
381 		 * check for link.
382 		 * Read the status register twice; BMSR_LINK is latch-low.
383 		 */
384 		reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
385 		if (reg & BMSR_LINK) {
386 			sc->mii_ticks = 0;
387 			break;
388 		}
389 
390 		/* Announce link loss right after it happens. */
391 		if (sc->mii_ticks++ == 0)
392 			break;
393 		if (sc->mii_ticks <= sc->mii_anegticks)
394 			break;
395 
396 		sc->mii_ticks = 0;
397 		PHY_RESET(sc);
398 		e1000phy_mii_phy_auto(sc, ife->ifm_media);
399 		break;
400 	}
401 
402 	/* Update the media status. */
403 	PHY_STATUS(sc);
404 
405 	/* Callback if something changed. */
406 	mii_phy_update(sc, cmd);
407 	return (0);
408 }
409 
410 static void
411 e1000phy_status(struct mii_softc *sc)
412 {
413 	struct mii_data *mii = sc->mii_pdata;
414 	int bmcr, bmsr, ssr;
415 
416 	mii->mii_media_status = IFM_AVALID;
417 	mii->mii_media_active = IFM_ETHER;
418 
419 	bmsr = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR);
420 	bmcr = PHY_READ(sc, E1000_CR);
421 	ssr = PHY_READ(sc, E1000_SSR);
422 
423 	if (bmsr & E1000_SR_LINK_STATUS)
424 		mii->mii_media_status |= IFM_ACTIVE;
425 
426 	if (bmcr & E1000_CR_LOOPBACK)
427 		mii->mii_media_active |= IFM_LOOP;
428 
429 	if ((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0 &&
430 	    (ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0) {
431 		/* Erg, still trying, I guess... */
432 		mii->mii_media_active |= IFM_NONE;
433 		return;
434 	}
435 
436 	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
437 		switch (ssr & E1000_SSR_SPEED) {
438 		case E1000_SSR_1000MBS:
439 			mii->mii_media_active |= IFM_1000_T;
440 			break;
441 		case E1000_SSR_100MBS:
442 			mii->mii_media_active |= IFM_100_TX;
443 			break;
444 		case E1000_SSR_10MBS:
445 			mii->mii_media_active |= IFM_10_T;
446 			break;
447 		default:
448 			mii->mii_media_active |= IFM_NONE;
449 			return;
450 		}
451 	} else {
452 		/*
453 		 * Some fiber PHY(88E1112) does not seem to set resolved
454 		 * speed so always assume we've got IFM_1000_SX.
455 		 */
456 		mii->mii_media_active |= IFM_1000_SX;
457 	}
458 
459 	if (ssr & E1000_SSR_DUPLEX) {
460 		mii->mii_media_active |= IFM_FDX;
461 		if ((sc->mii_flags & MIIF_HAVEFIBER) == 0)
462 			mii->mii_media_active |= mii_phy_flowstatus(sc);
463 	} else
464 		mii->mii_media_active |= IFM_HDX;
465 
466 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
467 		if (((PHY_READ(sc, E1000_1GSR) | PHY_READ(sc, E1000_1GSR)) &
468 		    E1000_1GSR_MS_CONFIG_RES) != 0)
469 			mii->mii_media_active |= IFM_ETH_MASTER;
470 	}
471 }
472 
473 static int
474 e1000phy_mii_phy_auto(struct mii_softc *sc, int media)
475 {
476 	uint16_t reg;
477 
478 	if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
479 		reg = PHY_READ(sc, E1000_AR);
480 		reg &= ~(E1000_AR_PAUSE | E1000_AR_ASM_DIR);
481 		reg |= E1000_AR_10T | E1000_AR_10T_FD |
482 		    E1000_AR_100TX | E1000_AR_100TX_FD;
483 		if ((media & IFM_FLOW) != 0 ||
484 		    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
485 			reg |= E1000_AR_PAUSE | E1000_AR_ASM_DIR;
486 		PHY_WRITE(sc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD);
487 	} else
488 		PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X);
489 	if ((sc->mii_flags & MIIF_HAVE_GTCR) != 0) {
490 		reg = 0;
491 		if ((sc->mii_extcapabilities & EXTSR_1000TFDX) != 0)
492 			reg |= E1000_1GCR_1000T_FD;
493 		if ((sc->mii_extcapabilities & EXTSR_1000THDX) != 0)
494 			reg |= E1000_1GCR_1000T;
495 		PHY_WRITE(sc, E1000_1GCR, reg);
496 	}
497 	PHY_WRITE(sc, E1000_CR,
498 	    E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG);
499 
500 	return (EJUSTRETURN);
501 }
502