10Sstevel@tonic-gate/*-
20Sstevel@tonic-gate * Copyright (c) 1997, 1998, 1999
30Sstevel@tonic-gate *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
40Sstevel@tonic-gate * Copyright (c) 2006 Bernd Walter.  All rights reserved.
51914Scasper *
61914Scasper * Redistribution and use in source and binary forms, with or without
70Sstevel@tonic-gate * modification, are permitted provided that the following conditions
80Sstevel@tonic-gate * are met:
90Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
100Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer.
110Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
120Sstevel@tonic-gate *    notice, this list of conditions and the following disclaimer in the
130Sstevel@tonic-gate *    documentation and/or other materials provided with the distribution.
140Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
150Sstevel@tonic-gate *    must display the following acknowledgement:
160Sstevel@tonic-gate *	This product includes software developed by Bill Paul.
170Sstevel@tonic-gate * 4. Neither the name of the author nor the names of any co-contributors
180Sstevel@tonic-gate *    may be used to endorse or promote products derived from this software
190Sstevel@tonic-gate *    without specific prior written permission.
200Sstevel@tonic-gate *
21132Srobinson * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
220Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
236812Sraf * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240Sstevel@tonic-gate * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
250Sstevel@tonic-gate * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
260Sstevel@tonic-gate * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
270Sstevel@tonic-gate * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
280Sstevel@tonic-gate * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
290Sstevel@tonic-gate * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
306812Sraf * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
316812Sraf * THE POSSIBILITY OF SUCH DAMAGE.
321219Sraf */
330Sstevel@tonic-gate
340Sstevel@tonic-gate#include <sys/cdefs.h>
350Sstevel@tonic-gate__FBSDID("$FreeBSD$");
360Sstevel@tonic-gate
370Sstevel@tonic-gate/*
380Sstevel@tonic-gate * driver for RealTek 8305 pseudo PHYs
390Sstevel@tonic-gate */
400Sstevel@tonic-gate
410Sstevel@tonic-gate#include <sys/param.h>
420Sstevel@tonic-gate#include <sys/systm.h>
430Sstevel@tonic-gate#include <sys/kernel.h>
440Sstevel@tonic-gate#include <sys/module.h>
450Sstevel@tonic-gate#include <sys/socket.h>
460Sstevel@tonic-gate#include <sys/bus.h>
470Sstevel@tonic-gate
480Sstevel@tonic-gate#include <net/if.h>
490Sstevel@tonic-gate#include <net/if_arp.h>
500Sstevel@tonic-gate#include <net/if_media.h>
510Sstevel@tonic-gate
520Sstevel@tonic-gate#include <dev/mii/mii.h>
53132Srobinson#include <dev/mii/miivar.h>
54132Srobinson#include "miidevs.h"
55132Srobinson
56132Srobinson#include <machine/bus.h>
57132Srobinson#include <pci/if_rlreg.h>
580Sstevel@tonic-gate
590Sstevel@tonic-gate#include "miibus_if.h"
600Sstevel@tonic-gate
610Sstevel@tonic-gate//#define RL_DEBUG
620Sstevel@tonic-gate#define RL_VLAN
630Sstevel@tonic-gate
640Sstevel@tonic-gatestatic int rlswitch_probe(device_t);
650Sstevel@tonic-gatestatic int rlswitch_attach(device_t);
660Sstevel@tonic-gate
670Sstevel@tonic-gatestatic device_method_t rlswitch_methods[] = {
680Sstevel@tonic-gate	/* device interface */
690Sstevel@tonic-gate	DEVMETHOD(device_probe,		rlswitch_probe),
700Sstevel@tonic-gate	DEVMETHOD(device_attach,	rlswitch_attach),
710Sstevel@tonic-gate	DEVMETHOD(device_detach,	mii_phy_detach),
720Sstevel@tonic-gate	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
730Sstevel@tonic-gate	DEVMETHOD_END
740Sstevel@tonic-gate};
750Sstevel@tonic-gate
760Sstevel@tonic-gatestatic devclass_t rlswitch_devclass;
770Sstevel@tonic-gate
780Sstevel@tonic-gatestatic driver_t rlswitch_driver = {
790Sstevel@tonic-gate	"rlswitch",
800Sstevel@tonic-gate	rlswitch_methods,
810Sstevel@tonic-gate	sizeof(struct mii_softc)
821219Sraf};
830Sstevel@tonic-gate
840Sstevel@tonic-gateDRIVER_MODULE(rlswitch, miibus, rlswitch_driver, rlswitch_devclass, 0, 0);
851914Scasper
86132Srobinsonstatic int	rlswitch_service(struct mii_softc *, struct mii_data *, int);
870Sstevel@tonic-gatestatic void	rlswitch_status(struct mii_softc *);
880Sstevel@tonic-gate
890Sstevel@tonic-gate#ifdef RL_DEBUG
900Sstevel@tonic-gatestatic void	rlswitch_phydump(device_t dev);
910Sstevel@tonic-gate#endif
920Sstevel@tonic-gate
930Sstevel@tonic-gatestatic const struct mii_phydesc rlswitches[] = {
940Sstevel@tonic-gate	MII_PHY_DESC(REALTEK, RTL8305SC),
950Sstevel@tonic-gate	MII_PHY_END
960Sstevel@tonic-gate};
970Sstevel@tonic-gate
980Sstevel@tonic-gatestatic const struct mii_phy_funcs rlswitch_funcs = {
990Sstevel@tonic-gate	rlswitch_service,
1000Sstevel@tonic-gate	rlswitch_status,
1010Sstevel@tonic-gate	mii_phy_reset
1020Sstevel@tonic-gate};
1030Sstevel@tonic-gate
1040Sstevel@tonic-gatestatic int
1050Sstevel@tonic-gaterlswitch_probe(device_t dev)
1060Sstevel@tonic-gate{
1070Sstevel@tonic-gate	int rv;
1080Sstevel@tonic-gate
1090Sstevel@tonic-gate	rv = mii_phy_dev_probe(dev, rlswitches, BUS_PROBE_DEFAULT);
1100Sstevel@tonic-gate	if (rv <= 0)
1110Sstevel@tonic-gate		return (rv);
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate	return (ENXIO);
1140Sstevel@tonic-gate}
1150Sstevel@tonic-gate
1160Sstevel@tonic-gatestatic int
1170Sstevel@tonic-gaterlswitch_attach(device_t dev)
1180Sstevel@tonic-gate{
1190Sstevel@tonic-gate	struct mii_softc	*sc;
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate	sc = device_get_softc(dev);
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate	/*
1240Sstevel@tonic-gate	 * We handle all pseudo PHYs in a single instance.
125132Srobinson	 */
1260Sstevel@tonic-gate	mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
1270Sstevel@tonic-gate	    &rlswitch_funcs, 0);
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate	sc->mii_capabilities = BMSR_100TXFDX & sc->mii_capmask;
130132Srobinson	device_printf(dev, " ");
1310Sstevel@tonic-gate	mii_phy_add_media(sc);
1320Sstevel@tonic-gate	printf("\n");
1330Sstevel@tonic-gate#ifdef RL_DEBUG
1340Sstevel@tonic-gate	rlswitch_phydump(dev);
135132Srobinson#endif
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate#ifdef RL_VLAN
1380Sstevel@tonic-gate	int val;
1390Sstevel@tonic-gate
140132Srobinson	/* Global Control 0 */
1410Sstevel@tonic-gate	val = 0;
1420Sstevel@tonic-gate	val |= 0 << 10;		/* enable 802.1q VLAN Tag support */
1430Sstevel@tonic-gate	val |= 0 << 9;		/* enable VLAN ingress filtering */
1440Sstevel@tonic-gate	val |= 1 << 8;		/* disable VLAN tag admit control */
145132Srobinson	val |= 1 << 6;		/* internal use */
1460Sstevel@tonic-gate	val |= 1 << 5;		/* internal use */
1470Sstevel@tonic-gate	val |= 1 << 4;		/* internal use */
1480Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
1490Sstevel@tonic-gate	val |= 1 << 1;		/* reserved */
1500Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 0, 16, val);
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate	/* Global Control 2 */
1530Sstevel@tonic-gate	val = 0;
1540Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
1550Sstevel@tonic-gate	val |= 0 << 14;		/* enable 1552 Bytes support */
1560Sstevel@tonic-gate	val |= 1 << 13;		/* enable broadcast input drop */
1570Sstevel@tonic-gate	val |= 1 << 12;		/* forward reserved control frames */
1580Sstevel@tonic-gate	val |= 1 << 11;		/* disable forwarding unicast frames to other VLAN's */
1590Sstevel@tonic-gate	val |= 1 << 10;		/* disable forwarding ARP broadcasts to other VLAN's */
160132Srobinson	val |= 1 << 9;		/* enable 48 pass 1 */
161132Srobinson	val |= 0 << 8;		/* enable VLAN */
1620Sstevel@tonic-gate	val |= 1 << 7;		/* reserved */
1630Sstevel@tonic-gate	val |= 1 << 6;		/* enable defer */
1640Sstevel@tonic-gate	val |= 1 << 5;		/* 43ms LED blink time */
1650Sstevel@tonic-gate	val |= 3 << 3;		/* 16:1 queue weight */
1660Sstevel@tonic-gate	val |= 1 << 2;		/* disable broadcast storm control */
1670Sstevel@tonic-gate	val |= 1 << 1;		/* enable power-on LED blinking */
1680Sstevel@tonic-gate	val |= 1 << 0;		/* reserved */
1690Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 0, 18, val);
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate	/* Port 0 Control Register 0 */
1720Sstevel@tonic-gate	val = 0;
1730Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
1740Sstevel@tonic-gate	val |= 1 << 11;		/* drop received packets with wrong VLAN tag */
1750Sstevel@tonic-gate	val |= 1 << 10;		/* disable 802.1p priority classification */
1760Sstevel@tonic-gate	val |= 1 << 9;		/* disable diffserv priority classification */
1770Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
1780Sstevel@tonic-gate	val |= 3 << 4;		/* internal use */
1790Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
1800Sstevel@tonic-gate	val |= 1 << 2;		/* internal use */
181132Srobinson	val |= 1 << 0;		/* remove VLAN tags on output */
1820Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 0, 22, val);
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate	/* Port 1 Control Register 0 */
1850Sstevel@tonic-gate	val = 0;
1860Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
1870Sstevel@tonic-gate	val |= 1 << 11;		/* drop received packets with wrong VLAN tag */
1880Sstevel@tonic-gate	val |= 1 << 10;		/* disable 802.1p priority classification */
189132Srobinson	val |= 1 << 9;		/* disable diffserv priority classification */
1900Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
1910Sstevel@tonic-gate	val |= 3 << 4;		/* internal use */
1920Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
1930Sstevel@tonic-gate	val |= 1 << 2;		/* internal use */
1940Sstevel@tonic-gate	val |= 1 << 0;		/* remove VLAN tags on output */
1950Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 1, 22, val);
1960Sstevel@tonic-gate
197132Srobinson	/* Port 2 Control Register 0 */
1980Sstevel@tonic-gate	val = 0;
1990Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
2000Sstevel@tonic-gate	val |= 1 << 11;		/* drop received packets with wrong VLAN tag */
201132Srobinson	val |= 1 << 10;		/* disable 802.1p priority classification */
2020Sstevel@tonic-gate	val |= 1 << 9;		/* disable diffserv priority classification */
2030Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
2040Sstevel@tonic-gate	val |= 3 << 4;		/* internal use */
2050Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
2060Sstevel@tonic-gate	val |= 1 << 2;		/* internal use */
2070Sstevel@tonic-gate	val |= 1 << 0;		/* remove VLAN tags on output */
2080Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 2, 22, val);
2090Sstevel@tonic-gate
2100Sstevel@tonic-gate	/* Port 3 Control Register 0 */
2110Sstevel@tonic-gate	val = 0;
2120Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
2130Sstevel@tonic-gate	val |= 1 << 11;		/* drop received packets with wrong VLAN tag */
2140Sstevel@tonic-gate	val |= 1 << 10;		/* disable 802.1p priority classification */
2150Sstevel@tonic-gate	val |= 1 << 9;		/* disable diffserv priority classification */
2160Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
2170Sstevel@tonic-gate	val |= 3 << 4;		/* internal use */
2180Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
2190Sstevel@tonic-gate	val |= 1 << 2;		/* internal use */
2200Sstevel@tonic-gate	val |= 1 << 0;		/* remove VLAN tags on output */
2210Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 3, 22, val);
2220Sstevel@tonic-gate
2230Sstevel@tonic-gate	/* Port 4 (system port) Control Register 0 */
2240Sstevel@tonic-gate	val = 0;
2250Sstevel@tonic-gate	val |= 1 << 15;		/* reserved */
2260Sstevel@tonic-gate	val |= 0 << 11;		/* don't drop received packets with wrong VLAN tag */
227132Srobinson	val |= 1 << 10;		/* disable 802.1p priority classification */
228132Srobinson	val |= 1 << 9;		/* disable diffserv priority classification */
229132Srobinson	val |= 1 << 6;		/* internal use */
230132Srobinson	val |= 3 << 4;		/* internal use */
2310Sstevel@tonic-gate	val |= 1 << 3;		/* internal use */
2320Sstevel@tonic-gate	val |= 1 << 2;		/* internal use */
2330Sstevel@tonic-gate	val |= 2 << 0;		/* add VLAN tags for untagged packets on output */
2340Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 4, 22, val);
2350Sstevel@tonic-gate
2360Sstevel@tonic-gate	/* Port 0 Control Register 1 and VLAN A */
2370Sstevel@tonic-gate	val = 0;
2380Sstevel@tonic-gate	val |= 0x0 << 12;	/* Port 0 VLAN Index */
2390Sstevel@tonic-gate	val |= 1 << 11;		/* internal use */
2400Sstevel@tonic-gate	val |= 1 << 10;		/* internal use */
2410Sstevel@tonic-gate	val |= 1 << 9;		/* internal use */
2420Sstevel@tonic-gate	val |= 1 << 7;		/* internal use */
2430Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
2440Sstevel@tonic-gate	val |= 0x11 << 0;	/* VLAN A membership */
2450Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 0, 24, val);
246132Srobinson
2470Sstevel@tonic-gate	/* Port 0 Control Register 2 and VLAN A */
248132Srobinson	val = 0;
2490Sstevel@tonic-gate	val |= 1 << 15;		/* internal use */
2500Sstevel@tonic-gate	val |= 1 << 14;		/* internal use */
251132Srobinson	val |= 1 << 13;		/* internal use */
2520Sstevel@tonic-gate	val |= 1 << 12;		/* internal use */
253132Srobinson	val |= 0x100 << 0;	/* VLAN A ID */
254132Srobinson	MIIBUS_WRITEREG(sc->mii_dev, 0, 25, val);
2550Sstevel@tonic-gate
256132Srobinson	/* Port 1 Control Register 1 and VLAN B */
2570Sstevel@tonic-gate	val = 0;
2580Sstevel@tonic-gate	val |= 0x1 << 12;	/* Port 1 VLAN Index */
2590Sstevel@tonic-gate	val |= 1 << 11;		/* internal use */
2600Sstevel@tonic-gate	val |= 1 << 10;		/* internal use */
2610Sstevel@tonic-gate	val |= 1 << 9;		/* internal use */
2620Sstevel@tonic-gate	val |= 1 << 7;		/* internal use */
2630Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
2640Sstevel@tonic-gate	val |= 0x12 << 0;	/* VLAN B membership */
2650Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 1, 24, val);
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate	/* Port 1 Control Register 2 and VLAN B */
2680Sstevel@tonic-gate	val = 0;
2690Sstevel@tonic-gate	val |= 1 << 15;		/* internal use */
2700Sstevel@tonic-gate	val |= 1 << 14;		/* internal use */
2710Sstevel@tonic-gate	val |= 1 << 13;		/* internal use */
2720Sstevel@tonic-gate	val |= 1 << 12;		/* internal use */
2730Sstevel@tonic-gate	val |= 0x101 << 0;	/* VLAN B ID */
2740Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 1, 25, val);
275132Srobinson
2760Sstevel@tonic-gate	/* Port 2 Control Register 1 and VLAN C */
2770Sstevel@tonic-gate	val = 0;
2780Sstevel@tonic-gate	val |= 0x2 << 12;	/* Port 2 VLAN Index */
279132Srobinson	val |= 1 << 11;		/* internal use */
2800Sstevel@tonic-gate	val |= 1 << 10;		/* internal use */
2810Sstevel@tonic-gate	val |= 1 << 9;		/* internal use */
282132Srobinson	val |= 1 << 7;		/* internal use */
2830Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
2840Sstevel@tonic-gate	val |= 0x14 << 0;	/* VLAN C membership */
2850Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 2, 24, val);
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate	/* Port 2 Control Register 2 and VLAN C */
2880Sstevel@tonic-gate	val = 0;
2890Sstevel@tonic-gate	val |= 1 << 15;		/* internal use */
2900Sstevel@tonic-gate	val |= 1 << 14;		/* internal use */
2910Sstevel@tonic-gate	val |= 1 << 13;		/* internal use */
2920Sstevel@tonic-gate	val |= 1 << 12;		/* internal use */
2930Sstevel@tonic-gate	val |= 0x102 << 0;	/* VLAN C ID */
2940Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 2, 25, val);
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate	/* Port 3 Control Register 1 and VLAN D */
297132Srobinson	val = 0;
2980Sstevel@tonic-gate	val |= 0x3 << 12;	/* Port 3 VLAN Index */
2990Sstevel@tonic-gate	val |= 1 << 11;		/* internal use */
300132Srobinson	val |= 1 << 10;		/* internal use */
301132Srobinson	val |= 1 << 9;		/* internal use */
302132Srobinson	val |= 1 << 7;		/* internal use */
3030Sstevel@tonic-gate	val |= 1 << 6;		/* internal use */
3040Sstevel@tonic-gate	val |= 0x18 << 0;	/* VLAN D membership */
3050Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 3, 24, val);
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate	/* Port 3 Control Register 2 and VLAN D */
3080Sstevel@tonic-gate	val = 0;
3090Sstevel@tonic-gate	val |= 1 << 15;		/* internal use */
3100Sstevel@tonic-gate	val |= 1 << 14;		/* internal use */
3110Sstevel@tonic-gate	val |= 1 << 13;		/* internal use */
3120Sstevel@tonic-gate	val |= 1 << 12;		/* internal use */
3130Sstevel@tonic-gate	val |= 0x103 << 0;	/* VLAN D ID */
3140Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 3, 25, val);
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate	/* Port 4 Control Register 1 and VLAN E */
3170Sstevel@tonic-gate	val = 0;
3180Sstevel@tonic-gate	val |= 0x0 << 12;	/* Port 4 VLAN Index */
3190Sstevel@tonic-gate	val |= 1 << 11;		/* internal use */
3200Sstevel@tonic-gate	val |= 1 << 10;		/* internal use */
3210Sstevel@tonic-gate	val |= 1 << 9;		/* internal use */
3220Sstevel@tonic-gate	val |= 1 << 7;		/* internal use */
323132Srobinson	val |= 1 << 6;		/* internal use */
3240Sstevel@tonic-gate	val |= 0 << 0;		/* VLAN E membership */
325132Srobinson	MIIBUS_WRITEREG(sc->mii_dev, 4, 24, val);
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate	/* Port 4 Control Register 2 and VLAN E */
3280Sstevel@tonic-gate	val = 0;
3290Sstevel@tonic-gate	val |= 1 << 15;		/* internal use */
3300Sstevel@tonic-gate	val |= 1 << 14;		/* internal use */
3310Sstevel@tonic-gate	val |= 1 << 13;		/* internal use */
3320Sstevel@tonic-gate	val |= 1 << 12;		/* internal use */
3330Sstevel@tonic-gate	val |= 0x104 << 0;	/* VLAN E ID */
3340Sstevel@tonic-gate	MIIBUS_WRITEREG(sc->mii_dev, 4, 25, val);
335132Srobinson#endif
3360Sstevel@tonic-gate
337132Srobinson#ifdef RL_DEBUG
3380Sstevel@tonic-gate	rlswitch_phydump(dev);
3390Sstevel@tonic-gate#endif
3400Sstevel@tonic-gate	MIIBUS_MEDIAINIT(sc->mii_dev);
3410Sstevel@tonic-gate	return (0);
342132Srobinson}
3430Sstevel@tonic-gate
344132Srobinsonstatic int
345132Srobinsonrlswitch_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
346132Srobinson{
347132Srobinson
348132Srobinson	switch (cmd) {
3490Sstevel@tonic-gate	case MII_POLLSTAT:
350132Srobinson		break;
351132Srobinson
352132Srobinson	case MII_MEDIACHG:
353132Srobinson		break;
354132Srobinson
355132Srobinson	case MII_TICK:
356132Srobinson		/*
357132Srobinson		 * Is the interface even up?
358132Srobinson		 */
3590Sstevel@tonic-gate		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
360132Srobinson			return (0);
3610Sstevel@tonic-gate		break;
3620Sstevel@tonic-gate	}
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate	/* Update the media status. */
3650Sstevel@tonic-gate	PHY_STATUS(sc);
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate	/* Callback if something changed. */
3680Sstevel@tonic-gate	// mii_phy_update(sc, cmd);
3690Sstevel@tonic-gate	return (0);
3700Sstevel@tonic-gate}
3710Sstevel@tonic-gate
3720Sstevel@tonic-gatestatic void
3730Sstevel@tonic-gaterlswitch_status(struct mii_softc *phy)
3740Sstevel@tonic-gate{
3750Sstevel@tonic-gate	struct mii_data *mii = phy->mii_pdata;
3760Sstevel@tonic-gate
3770Sstevel@tonic-gate	mii->mii_media_status = IFM_AVALID;
3780Sstevel@tonic-gate	mii->mii_media_active = IFM_ETHER;
3790Sstevel@tonic-gate	mii->mii_media_status |= IFM_ACTIVE;
3800Sstevel@tonic-gate	mii->mii_media_active |=
3810Sstevel@tonic-gate	    IFM_100_TX | IFM_FDX | mii_phy_flowstatus(phy);
3820Sstevel@tonic-gate}
383132Srobinson
3840Sstevel@tonic-gate#ifdef RL_DEBUG
3850Sstevel@tonic-gatestatic void
386132Srobinsonrlswitch_phydump(device_t dev) {
387132Srobinson	int phy, reg, val;
388132Srobinson	struct mii_softc *sc;
3890Sstevel@tonic-gate
3900Sstevel@tonic-gate	sc = device_get_softc(dev);
3910Sstevel@tonic-gate	device_printf(dev, "rlswitchphydump\n");
3920Sstevel@tonic-gate	for (phy = 0; phy <= 5; phy++) {
3930Sstevel@tonic-gate		printf("PHY%i:", phy);
3940Sstevel@tonic-gate		for (reg = 0; reg <= 31; reg++) {
3950Sstevel@tonic-gate			val = MIIBUS_READREG(sc->mii_dev, phy, reg);
3960Sstevel@tonic-gate			printf(" 0x%x", val);
3970Sstevel@tonic-gate		}
398132Srobinson		printf("\n");
399132Srobinson	}
400132Srobinson}
4010Sstevel@tonic-gate#endif
402132Srobinson