1/*-
2 * SPDX-License-Identifier: BSD-4-Clause
3 *
4 * Copyright (c) 2003
5 *	Bill Paul <wpaul@windriver.com>.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
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.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <sys/cdefs.h>
36/*
37 * Driver for the RealTek 8169S/8110S/8211B/8211C internal 10/100/1000 PHY.
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>
43#include <sys/module.h>
44#include <sys/socket.h>
45#include <sys/taskqueue.h>
46#include <sys/bus.h>
47
48#include <net/if.h>
49#include <net/if_var.h>
50#include <net/if_arp.h>
51#include <net/if_media.h>
52
53#include <dev/mii/mii.h>
54#include <dev/mii/miivar.h>
55#include "miidevs.h"
56
57#include <dev/mii/rgephyreg.h>
58
59#include "miibus_if.h"
60
61#include <machine/bus.h>
62#include <dev/rl/if_rlreg.h>
63
64static int rgephy_probe(device_t);
65static int rgephy_attach(device_t);
66
67static device_method_t rgephy_methods[] = {
68	/* device interface */
69	DEVMETHOD(device_probe,		rgephy_probe),
70	DEVMETHOD(device_attach,	rgephy_attach),
71	DEVMETHOD(device_detach,	mii_phy_detach),
72	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
73	DEVMETHOD_END
74};
75
76static driver_t rgephy_driver = {
77	"rgephy",
78	rgephy_methods,
79	sizeof(struct mii_softc)
80};
81
82DRIVER_MODULE(rgephy, miibus, rgephy_driver, 0, 0);
83
84static int	rgephy_service(struct mii_softc *, struct mii_data *, int);
85static void	rgephy_status(struct mii_softc *);
86static int	rgephy_mii_phy_auto(struct mii_softc *, int);
87static void	rgephy_reset(struct mii_softc *);
88static int	rgephy_linkup(struct mii_softc *);
89static void	rgephy_loop(struct mii_softc *);
90static void	rgephy_load_dspcode(struct mii_softc *);
91static void	rgephy_disable_eee(struct mii_softc *);
92
93static const struct mii_phydesc rgephys[] = {
94	MII_PHY_DESC(REALTEK, RTL8169S),
95	MII_PHY_DESC(REALTEK, RTL8251),
96	MII_PHY_DESC(REALTEK, RTL8211FVD),
97	MII_PHY_END
98};
99
100static const struct mii_phy_funcs rgephy_funcs = {
101	rgephy_service,
102	rgephy_status,
103	rgephy_reset
104};
105
106static int
107rgephy_probe(device_t dev)
108{
109
110	return (mii_phy_dev_probe(dev, rgephys, BUS_PROBE_DEFAULT));
111}
112
113static int
114rgephy_attach(device_t dev)
115{
116	struct mii_softc *sc;
117	u_int flags;
118
119	sc = device_get_softc(dev);
120	flags = 0;
121	if (mii_dev_mac_match(dev, "re"))
122		flags |= MIIF_PHYPRIV0;
123	else if (mii_dev_mac_match(dev, "ure"))
124		flags |= MIIF_PHYPRIV1;
125	mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
126
127	/* RTL8169S do not report auto-sense; add manually. */
128	sc->mii_capabilities = (PHY_READ(sc, MII_BMSR) | BMSR_ANEG) &
129	    sc->mii_capmask;
130	if (sc->mii_capabilities & BMSR_EXTSTAT)
131		sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
132	device_printf(dev, " ");
133	mii_phy_add_media(sc);
134	printf("\n");
135	/*
136	 * Allow IFM_FLAG0 to be set indicating that auto-negotiation with
137	 * manual configuration, which is used to work around issues with
138	 * certain setups by default, should not be triggered as it may in
139	 * turn cause harm in some edge cases.
140	 */
141	sc->mii_pdata->mii_media.ifm_mask |= IFM_FLAG0;
142
143	PHY_RESET(sc);
144
145	MIIBUS_MEDIAINIT(sc->mii_dev);
146	return (0);
147}
148
149static int
150rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
151{
152	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
153	int speed, gig, anar;
154
155	switch (cmd) {
156	case MII_POLLSTAT:
157		break;
158
159	case MII_MEDIACHG:
160		PHY_RESET(sc);	/* XXX hardware bug work-around */
161
162		anar = PHY_READ(sc, RGEPHY_MII_ANAR);
163		anar &= ~(RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP |
164		    RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX |
165		    RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10);
166
167		switch (IFM_SUBTYPE(ife->ifm_media)) {
168		case IFM_AUTO:
169#ifdef foo
170			/*
171			 * If we're already in auto mode, just return.
172			 */
173			if (PHY_READ(sc, RGEPHY_MII_BMCR) & RGEPHY_BMCR_AUTOEN)
174				return (0);
175#endif
176			(void)rgephy_mii_phy_auto(sc, ife->ifm_media);
177			break;
178		case IFM_1000_T:
179			speed = RGEPHY_S1000;
180			goto setit;
181		case IFM_100_TX:
182			speed = RGEPHY_S100;
183			anar |= RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_TX;
184			goto setit;
185		case IFM_10_T:
186			speed = RGEPHY_S10;
187			anar |= RGEPHY_ANAR_10_FD | RGEPHY_ANAR_10;
188setit:
189			if ((ife->ifm_media & IFM_FLOW) != 0 &&
190			    (mii->mii_media.ifm_media & IFM_FLAG0) != 0)
191				return (EINVAL);
192
193			if ((ife->ifm_media & IFM_FDX) != 0) {
194				speed |= RGEPHY_BMCR_FDX;
195				gig = RGEPHY_1000CTL_AFD;
196				anar &= ~(RGEPHY_ANAR_TX | RGEPHY_ANAR_10);
197				if ((ife->ifm_media & IFM_FLOW) != 0 ||
198				    (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
199					anar |=
200					    RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP;
201			} else {
202				gig = RGEPHY_1000CTL_AHD;
203				anar &=
204				    ~(RGEPHY_ANAR_TX_FD | RGEPHY_ANAR_10_FD);
205			}
206			if (IFM_SUBTYPE(ife->ifm_media) == IFM_1000_T) {
207				gig |= RGEPHY_1000CTL_MSE;
208				if ((ife->ifm_media & IFM_ETH_MASTER) != 0)
209				    gig |= RGEPHY_1000CTL_MSC;
210			} else {
211				gig = 0;
212				anar &= ~RGEPHY_ANAR_ASP;
213			}
214			if ((mii->mii_media.ifm_media & IFM_FLAG0) == 0)
215				speed |=
216				    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG;
217			rgephy_loop(sc);
218			PHY_WRITE(sc, RGEPHY_MII_1000CTL, gig);
219			PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
220			PHY_WRITE(sc, RGEPHY_MII_BMCR, speed);
221			break;
222		case IFM_NONE:
223			PHY_WRITE(sc, MII_BMCR, BMCR_ISO | BMCR_PDOWN);
224			break;
225		default:
226			return (EINVAL);
227		}
228		break;
229
230	case MII_TICK:
231		/*
232		 * Only used for autonegotiation.
233		 */
234		if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) {
235			sc->mii_ticks = 0;
236			break;
237		}
238
239		/*
240		 * Check to see if we have link.  If we do, we don't
241		 * need to restart the autonegotiation process.
242		 */
243		if (rgephy_linkup(sc) != 0) {
244			sc->mii_ticks = 0;
245			break;
246		}
247
248		/* Announce link loss right after it happens. */
249		if (sc->mii_ticks++ == 0)
250			break;
251
252		/* Only retry autonegotiation every mii_anegticks seconds. */
253		if (sc->mii_ticks <= sc->mii_anegticks)
254			return (0);
255
256		sc->mii_ticks = 0;
257		rgephy_mii_phy_auto(sc, ife->ifm_media);
258		break;
259	}
260
261	/* Update the media status. */
262	PHY_STATUS(sc);
263
264	/*
265	 * Callback if something changed. Note that we need to poke
266	 * the DSP on the RealTek PHYs if the media changes.
267	 *
268	 */
269	if (sc->mii_media_active != mii->mii_media_active ||
270	    sc->mii_media_status != mii->mii_media_status ||
271	    cmd == MII_MEDIACHG) {
272		rgephy_load_dspcode(sc);
273	}
274	mii_phy_update(sc, cmd);
275	return (0);
276}
277
278static int
279rgephy_linkup(struct mii_softc *sc)
280{
281	int linkup;
282	uint16_t reg;
283
284	linkup = 0;
285	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
286	    sc->mii_mpd_rev >= RGEPHY_8211B) {
287		if (sc->mii_mpd_rev >= RGEPHY_8211F) {
288			reg = PHY_READ(sc, RGEPHY_F_MII_SSR);
289			if (reg & RGEPHY_F_SSR_LINK)
290				linkup++;
291		} else {
292			reg = PHY_READ(sc, RGEPHY_MII_SSR);
293			if (reg & RGEPHY_SSR_LINK)
294				linkup++;
295		}
296	} else {
297		if (sc->mii_flags & MIIF_PHYPRIV1)
298			reg = PHY_READ(sc, URE_GMEDIASTAT);
299		else
300			reg = PHY_READ(sc, RL_GMEDIASTAT);
301		if (reg & RL_GMEDIASTAT_LINK)
302			linkup++;
303	}
304
305	return (linkup);
306}
307
308static void
309rgephy_status(struct mii_softc *sc)
310{
311	struct mii_data *mii = sc->mii_pdata;
312	int bmsr, bmcr;
313	uint16_t ssr;
314
315	mii->mii_media_status = IFM_AVALID;
316	mii->mii_media_active = IFM_ETHER;
317
318	if (rgephy_linkup(sc) != 0)
319		mii->mii_media_status |= IFM_ACTIVE;
320
321	bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
322	bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
323	if (bmcr & RGEPHY_BMCR_ISO) {
324		mii->mii_media_active |= IFM_NONE;
325		mii->mii_media_status = 0;
326		return;
327	}
328
329	if (bmcr & RGEPHY_BMCR_LOOP)
330		mii->mii_media_active |= IFM_LOOP;
331
332	if (bmcr & RGEPHY_BMCR_AUTOEN) {
333		if ((bmsr & RGEPHY_BMSR_ACOMP) == 0) {
334			/* Erg, still trying, I guess... */
335			mii->mii_media_active |= IFM_NONE;
336			return;
337		}
338	}
339
340	if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
341	    sc->mii_mpd_rev >= RGEPHY_8211B) {
342		if (sc->mii_mpd_rev >= RGEPHY_8211F) {
343			ssr = PHY_READ(sc, RGEPHY_F_MII_SSR);
344			switch (ssr & RGEPHY_F_SSR_SPD_MASK) {
345			case RGEPHY_F_SSR_S1000:
346				mii->mii_media_active |= IFM_1000_T;
347				break;
348			case RGEPHY_F_SSR_S100:
349				mii->mii_media_active |= IFM_100_TX;
350				break;
351			case RGEPHY_F_SSR_S10:
352				mii->mii_media_active |= IFM_10_T;
353				break;
354			default:
355				mii->mii_media_active |= IFM_NONE;
356				break;
357			}
358			if (ssr & RGEPHY_F_SSR_FDX)
359				mii->mii_media_active |= IFM_FDX;
360			else
361				mii->mii_media_active |= IFM_HDX;
362
363		} else {
364			ssr = PHY_READ(sc, RGEPHY_MII_SSR);
365			switch (ssr & RGEPHY_SSR_SPD_MASK) {
366			case RGEPHY_SSR_S1000:
367				mii->mii_media_active |= IFM_1000_T;
368				break;
369			case RGEPHY_SSR_S100:
370				mii->mii_media_active |= IFM_100_TX;
371				break;
372			case RGEPHY_SSR_S10:
373				mii->mii_media_active |= IFM_10_T;
374				break;
375			default:
376				mii->mii_media_active |= IFM_NONE;
377				break;
378			}
379			if (ssr & RGEPHY_SSR_FDX)
380				mii->mii_media_active |= IFM_FDX;
381			else
382				mii->mii_media_active |= IFM_HDX;
383		}
384	} else {
385		if (sc->mii_flags & MIIF_PHYPRIV1)
386			bmsr = PHY_READ(sc, URE_GMEDIASTAT);
387		else
388			bmsr = PHY_READ(sc, RL_GMEDIASTAT);
389		if (bmsr & RL_GMEDIASTAT_1000MBPS)
390			mii->mii_media_active |= IFM_1000_T;
391		else if (bmsr & RL_GMEDIASTAT_100MBPS)
392			mii->mii_media_active |= IFM_100_TX;
393		else if (bmsr & RL_GMEDIASTAT_10MBPS)
394			mii->mii_media_active |= IFM_10_T;
395		else
396			mii->mii_media_active |= IFM_NONE;
397		if (bmsr & RL_GMEDIASTAT_FDX)
398			mii->mii_media_active |= IFM_FDX;
399		else
400			mii->mii_media_active |= IFM_HDX;
401	}
402
403	if ((mii->mii_media_active & IFM_FDX) != 0)
404		mii->mii_media_active |= mii_phy_flowstatus(sc);
405
406	if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) &&
407	    (PHY_READ(sc, RGEPHY_MII_1000STS) & RGEPHY_1000STS_MSR) != 0)
408		mii->mii_media_active |= IFM_ETH_MASTER;
409}
410
411static int
412rgephy_mii_phy_auto(struct mii_softc *sc, int media)
413{
414	int anar;
415
416	rgephy_loop(sc);
417	PHY_RESET(sc);
418
419	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
420	if ((media & IFM_FLOW) != 0 || (sc->mii_flags & MIIF_FORCEPAUSE) != 0)
421		anar |= RGEPHY_ANAR_PC | RGEPHY_ANAR_ASP;
422	PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
423	DELAY(1000);
424	PHY_WRITE(sc, RGEPHY_MII_1000CTL,
425	    RGEPHY_1000CTL_AHD | RGEPHY_1000CTL_AFD);
426	DELAY(1000);
427	PHY_WRITE(sc, RGEPHY_MII_BMCR,
428	    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
429	DELAY(100);
430
431	return (EJUSTRETURN);
432}
433
434static void
435rgephy_loop(struct mii_softc *sc)
436{
437	int i;
438
439	if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 &&
440	    sc->mii_mpd_rev < RGEPHY_8211B) {
441		PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
442		DELAY(1000);
443	}
444
445	for (i = 0; i < 15000; i++) {
446		if (!(PHY_READ(sc, RGEPHY_MII_BMSR) & RGEPHY_BMSR_LINK)) {
447#if 0
448			device_printf(sc->mii_dev, "looped %d\n", i);
449#endif
450			break;
451		}
452		DELAY(10);
453	}
454}
455
456#define PHY_SETBIT(x, y, z) \
457	PHY_WRITE(x, y, (PHY_READ(x, y) | (z)))
458#define PHY_CLRBIT(x, y, z) \
459	PHY_WRITE(x, y, (PHY_READ(x, y) & ~(z)))
460
461/*
462 * Initialize RealTek PHY per the datasheet. The DSP in the PHYs of
463 * existing revisions of the 8169S/8110S chips need to be tuned in
464 * order to reliably negotiate a 1000Mbps link. This is only needed
465 * for rev 0 and rev 1 of the PHY. Later versions work without
466 * any fixups.
467 */
468static void
469rgephy_load_dspcode(struct mii_softc *sc)
470{
471	int val;
472
473	if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 ||
474	    sc->mii_mpd_rev >= RGEPHY_8211B)
475		return;
476
477	PHY_WRITE(sc, 31, 0x0001);
478	PHY_WRITE(sc, 21, 0x1000);
479	PHY_WRITE(sc, 24, 0x65C7);
480	PHY_CLRBIT(sc, 4, 0x0800);
481	val = PHY_READ(sc, 4) & 0xFFF;
482	PHY_WRITE(sc, 4, val);
483	PHY_WRITE(sc, 3, 0x00A1);
484	PHY_WRITE(sc, 2, 0x0008);
485	PHY_WRITE(sc, 1, 0x1020);
486	PHY_WRITE(sc, 0, 0x1000);
487	PHY_SETBIT(sc, 4, 0x0800);
488	PHY_CLRBIT(sc, 4, 0x0800);
489	val = (PHY_READ(sc, 4) & 0xFFF) | 0x7000;
490	PHY_WRITE(sc, 4, val);
491	PHY_WRITE(sc, 3, 0xFF41);
492	PHY_WRITE(sc, 2, 0xDE60);
493	PHY_WRITE(sc, 1, 0x0140);
494	PHY_WRITE(sc, 0, 0x0077);
495	val = (PHY_READ(sc, 4) & 0xFFF) | 0xA000;
496	PHY_WRITE(sc, 4, val);
497	PHY_WRITE(sc, 3, 0xDF01);
498	PHY_WRITE(sc, 2, 0xDF20);
499	PHY_WRITE(sc, 1, 0xFF95);
500	PHY_WRITE(sc, 0, 0xFA00);
501	val = (PHY_READ(sc, 4) & 0xFFF) | 0xB000;
502	PHY_WRITE(sc, 4, val);
503	PHY_WRITE(sc, 3, 0xFF41);
504	PHY_WRITE(sc, 2, 0xDE20);
505	PHY_WRITE(sc, 1, 0x0140);
506	PHY_WRITE(sc, 0, 0x00BB);
507	val = (PHY_READ(sc, 4) & 0xFFF) | 0xF000;
508	PHY_WRITE(sc, 4, val);
509	PHY_WRITE(sc, 3, 0xDF01);
510	PHY_WRITE(sc, 2, 0xDF20);
511	PHY_WRITE(sc, 1, 0xFF95);
512	PHY_WRITE(sc, 0, 0xBF00);
513	PHY_SETBIT(sc, 4, 0x0800);
514	PHY_CLRBIT(sc, 4, 0x0800);
515	PHY_WRITE(sc, 31, 0x0000);
516
517	DELAY(40);
518}
519
520static void
521rgephy_reset(struct mii_softc *sc)
522{
523	uint16_t pcr, ssr;
524
525	switch (sc->mii_mpd_rev) {
526	case RGEPHY_8211F:
527	case RGEPHY_8211FVD:
528		pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1);
529		pcr &= ~(RGEPHY_F_PCR1_MDI_MM | RGEPHY_F_PCR1_ALDPS_EN);
530		PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
531		rgephy_disable_eee(sc);
532		break;
533	case RGEPHY_8211C:
534		if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
535			/* RTL8211C(L) */
536			ssr = PHY_READ(sc, RGEPHY_MII_SSR);
537			if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
538				ssr &= ~RGEPHY_SSR_ALDPS;
539				PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
540			}
541		}
542		/* FALLTHROUGH */
543	default:
544		if (sc->mii_mpd_rev >= RGEPHY_8211B) {
545			pcr = PHY_READ(sc, RGEPHY_MII_PCR);
546			if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
547				pcr &= ~RGEPHY_PCR_MDI_MASK;
548				pcr |= RGEPHY_PCR_MDIX_AUTO;
549				PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
550			}
551		}
552		break;
553	}
554
555	mii_phy_reset(sc);
556	DELAY(1000);
557	rgephy_load_dspcode(sc);
558}
559
560static void
561rgephy_disable_eee(struct mii_softc *sc)
562{
563	uint16_t anar;
564
565	PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000);
566	PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS |
567	    (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
568	PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR);
569	PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI |
570	    (MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
571	PHY_WRITE(sc, MII_MMDAADR, 0x0000);
572	PHY_WRITE(sc, MII_MMDACR, 0x0000);
573	/*
574	 * XXX
575	 * Restart auto-negotiation to take changes effect.
576	 * This may result in link establishment.
577	 */
578	anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
579	PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
580	PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD |
581	    RGEPHY_1000CTL_AFD);
582	PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET |
583	    RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
584}
585