xref: /freebsd/sys/dev/mii/qsphy.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
19526a692SSemen Ustimenko /*	OpenBSD: qsphy.c,v 1.6 2000/08/26 20:04:18 nate Exp */
29526a692SSemen Ustimenko /*	NetBSD: qsphy.c,v 1.19 2000/02/02 23:34:57 thorpej Exp 	*/
39526a692SSemen Ustimenko 
49526a692SSemen Ustimenko /*-
5*eebd9d53SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
6718cf2ccSPedro F. Giffuni  *
79526a692SSemen Ustimenko  * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
89526a692SSemen Ustimenko  * All rights reserved.
99526a692SSemen Ustimenko  *
109526a692SSemen Ustimenko  * This code is derived from software contributed to The NetBSD Foundation
119526a692SSemen Ustimenko  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
129526a692SSemen Ustimenko  * NASA Ames Research Center.
139526a692SSemen Ustimenko  *
149526a692SSemen Ustimenko  * Redistribution and use in source and binary forms, with or without
159526a692SSemen Ustimenko  * modification, are permitted provided that the following conditions
169526a692SSemen Ustimenko  * are met:
179526a692SSemen Ustimenko  * 1. Redistributions of source code must retain the above copyright
189526a692SSemen Ustimenko  *    notice, this list of conditions and the following disclaimer.
199526a692SSemen Ustimenko  * 2. Redistributions in binary form must reproduce the above copyright
209526a692SSemen Ustimenko  *    notice, this list of conditions and the following disclaimer in the
219526a692SSemen Ustimenko  *    documentation and/or other materials provided with the distribution.
229526a692SSemen Ustimenko  *
239526a692SSemen Ustimenko  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
249526a692SSemen Ustimenko  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
259526a692SSemen Ustimenko  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
269526a692SSemen Ustimenko  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
279526a692SSemen Ustimenko  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
289526a692SSemen Ustimenko  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
299526a692SSemen Ustimenko  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
309526a692SSemen Ustimenko  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
319526a692SSemen Ustimenko  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
329526a692SSemen Ustimenko  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
339526a692SSemen Ustimenko  * POSSIBILITY OF SUCH DAMAGE.
349526a692SSemen Ustimenko  */
359526a692SSemen Ustimenko 
36098ca2bdSWarner Losh /*-
379526a692SSemen Ustimenko  * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
389526a692SSemen Ustimenko  *
399526a692SSemen Ustimenko  * Redistribution and use in source and binary forms, with or without
409526a692SSemen Ustimenko  * modification, are permitted provided that the following conditions
419526a692SSemen Ustimenko  * are met:
429526a692SSemen Ustimenko  * 1. Redistributions of source code must retain the above copyright
439526a692SSemen Ustimenko  *    notice, this list of conditions and the following disclaimer.
449526a692SSemen Ustimenko  * 2. Redistributions in binary form must reproduce the above copyright
459526a692SSemen Ustimenko  *    notice, this list of conditions and the following disclaimer in the
469526a692SSemen Ustimenko  *    documentation and/or other materials provided with the distribution.
479526a692SSemen Ustimenko  *
489526a692SSemen Ustimenko  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
499526a692SSemen Ustimenko  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
509526a692SSemen Ustimenko  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
519526a692SSemen Ustimenko  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
529526a692SSemen Ustimenko  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
539526a692SSemen Ustimenko  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
549526a692SSemen Ustimenko  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
559526a692SSemen Ustimenko  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
569526a692SSemen Ustimenko  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
579526a692SSemen Ustimenko  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
589526a692SSemen Ustimenko  */
599526a692SSemen Ustimenko 
6050aa1061SMarius Strobl #include <sys/cdefs.h>
619526a692SSemen Ustimenko /*
629526a692SSemen Ustimenko  * driver for Quality Semiconductor's QS6612 ethernet 10/100 PHY
639526a692SSemen Ustimenko  * datasheet from www.qualitysemi.com
649526a692SSemen Ustimenko  */
659526a692SSemen Ustimenko 
669526a692SSemen Ustimenko #include <sys/param.h>
679526a692SSemen Ustimenko #include <sys/systm.h>
689526a692SSemen Ustimenko #include <sys/kernel.h>
699526a692SSemen Ustimenko #include <sys/socket.h>
709526a692SSemen Ustimenko #include <sys/errno.h>
719526a692SSemen Ustimenko #include <sys/module.h>
729526a692SSemen Ustimenko #include <sys/bus.h>
739526a692SSemen Ustimenko 
749526a692SSemen Ustimenko #include <net/if.h>
759526a692SSemen Ustimenko #include <net/if_media.h>
769526a692SSemen Ustimenko 
779526a692SSemen Ustimenko #include <dev/mii/mii.h>
789526a692SSemen Ustimenko #include <dev/mii/miivar.h>
792d3ce713SDavid E. O'Brien #include "miidevs.h"
809526a692SSemen Ustimenko 
819526a692SSemen Ustimenko #include <dev/mii/qsphyreg.h>
829526a692SSemen Ustimenko 
839526a692SSemen Ustimenko #include "miibus_if.h"
849526a692SSemen Ustimenko 
85e51a25f8SAlfred Perlstein static int qsphy_probe(device_t);
86e51a25f8SAlfred Perlstein static int qsphy_attach(device_t);
879526a692SSemen Ustimenko 
889526a692SSemen Ustimenko static device_method_t qsphy_methods[] = {
899526a692SSemen Ustimenko 	/* device interface */
909526a692SSemen Ustimenko 	DEVMETHOD(device_probe,		qsphy_probe),
919526a692SSemen Ustimenko 	DEVMETHOD(device_attach,	qsphy_attach),
92279fe8d1SPoul-Henning Kamp 	DEVMETHOD(device_detach,	mii_phy_detach),
939526a692SSemen Ustimenko 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
94604f5f1fSMarius Strobl 	DEVMETHOD_END
959526a692SSemen Ustimenko };
969526a692SSemen Ustimenko 
979526a692SSemen Ustimenko static driver_t qsphy_driver = {
989526a692SSemen Ustimenko 	"qsphy",
999526a692SSemen Ustimenko 	qsphy_methods,
1009526a692SSemen Ustimenko 	sizeof(struct mii_softc)
1019526a692SSemen Ustimenko };
1029526a692SSemen Ustimenko 
103f438c2ffSJohn Baldwin DRIVER_MODULE(qsphy, miibus, qsphy_driver, 0, 0);
1049526a692SSemen Ustimenko 
105e51a25f8SAlfred Perlstein static int	qsphy_service(struct mii_softc *, struct mii_data *, int);
106e51a25f8SAlfred Perlstein static void	qsphy_reset(struct mii_softc *);
107e51a25f8SAlfred Perlstein static void	qsphy_status(struct mii_softc *);
1089526a692SSemen Ustimenko 
109a35b9333SMarius Strobl static const struct mii_phydesc qsphys[] = {
1103fcb7a53SMarius Strobl 	MII_PHY_DESC(xxQUALSEMI, QS6612),
111a35b9333SMarius Strobl 	MII_PHY_END
112a35b9333SMarius Strobl };
113a35b9333SMarius Strobl 
1143fcb7a53SMarius Strobl static const struct mii_phy_funcs qsphy_funcs = {
1153fcb7a53SMarius Strobl 	qsphy_service,
1163fcb7a53SMarius Strobl 	qsphy_status,
1173fcb7a53SMarius Strobl 	qsphy_reset
1183fcb7a53SMarius Strobl };
1193fcb7a53SMarius Strobl 
1209c1c2e99SAlfred Perlstein static int
qsphy_probe(device_t dev)1217d830ac9SWarner Losh qsphy_probe(device_t dev)
1229526a692SSemen Ustimenko {
1239526a692SSemen Ustimenko 
124a35b9333SMarius Strobl 	return (mii_phy_dev_probe(dev, qsphys, BUS_PROBE_DEFAULT));
1259526a692SSemen Ustimenko }
1269526a692SSemen Ustimenko 
1279c1c2e99SAlfred Perlstein static int
qsphy_attach(device_t dev)1287d830ac9SWarner Losh qsphy_attach(device_t dev)
1299526a692SSemen Ustimenko {
1309526a692SSemen Ustimenko 
1313fcb7a53SMarius Strobl 	mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &qsphy_funcs, 1);
1329526a692SSemen Ustimenko 	return (0);
1339526a692SSemen Ustimenko }
1349526a692SSemen Ustimenko 
135d9730b8bSJonathan Lemon static int
qsphy_service(struct mii_softc * sc,struct mii_data * mii,int cmd)1367d830ac9SWarner Losh qsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
1379526a692SSemen Ustimenko {
1389526a692SSemen Ustimenko 
1394592db46SSemen Ustimenko 	switch (cmd) {
1404592db46SSemen Ustimenko 	case MII_POLLSTAT:
1414592db46SSemen Ustimenko 		break;
1424592db46SSemen Ustimenko 
1434592db46SSemen Ustimenko 	case MII_MEDIACHG:
144f8f3badfSMarius Strobl 		mii_phy_setmedia(sc);
1459526a692SSemen Ustimenko 		break;
1469526a692SSemen Ustimenko 
1479526a692SSemen Ustimenko 	case MII_TICK:
1489526a692SSemen Ustimenko 		/*
1494592db46SSemen Ustimenko 		 * This PHY's autonegotiation doesn't need to be kicked.
150d9730b8bSJonathan Lemon 		 */
1519526a692SSemen Ustimenko 		break;
1529526a692SSemen Ustimenko 	}
1539526a692SSemen Ustimenko 
1549526a692SSemen Ustimenko 	/* Update the media status. */
1553fcb7a53SMarius Strobl 	PHY_STATUS(sc);
1569526a692SSemen Ustimenko 
1579526a692SSemen Ustimenko 	/* Callback if something changed. */
158d9730b8bSJonathan Lemon 	mii_phy_update(sc, cmd);
1599526a692SSemen Ustimenko 	return (0);
1609526a692SSemen Ustimenko }
1619526a692SSemen Ustimenko 
162d9730b8bSJonathan Lemon static void
qsphy_status(struct mii_softc * sc)1637d830ac9SWarner Losh qsphy_status(struct mii_softc *sc)
1649526a692SSemen Ustimenko {
1659526a692SSemen Ustimenko 	struct mii_data *mii = sc->mii_pdata;
1669526a692SSemen Ustimenko 	int bmsr, bmcr, pctl;
1679526a692SSemen Ustimenko 
1689526a692SSemen Ustimenko 	mii->mii_media_status = IFM_AVALID;
1699526a692SSemen Ustimenko 	mii->mii_media_active = IFM_ETHER;
1709526a692SSemen Ustimenko 
1719526a692SSemen Ustimenko 	bmsr = PHY_READ(sc, MII_BMSR) |
1729526a692SSemen Ustimenko 	    PHY_READ(sc, MII_BMSR);
1739526a692SSemen Ustimenko 	if (bmsr & BMSR_LINK)
1749526a692SSemen Ustimenko 		mii->mii_media_status |= IFM_ACTIVE;
1759526a692SSemen Ustimenko 
1769526a692SSemen Ustimenko 	bmcr = PHY_READ(sc, MII_BMCR);
1779526a692SSemen Ustimenko 	if (bmcr & BMCR_ISO) {
1789526a692SSemen Ustimenko 		mii->mii_media_active |= IFM_NONE;
1799526a692SSemen Ustimenko 		mii->mii_media_status = 0;
1809526a692SSemen Ustimenko 		return;
1819526a692SSemen Ustimenko 	}
1829526a692SSemen Ustimenko 
1839526a692SSemen Ustimenko 	if (bmcr & BMCR_LOOP)
1849526a692SSemen Ustimenko 		mii->mii_media_active |= IFM_LOOP;
1859526a692SSemen Ustimenko 
1864592db46SSemen Ustimenko 	pctl = PHY_READ(sc, MII_QSPHY_PCTL);
1879526a692SSemen Ustimenko 	switch (pctl & PCTL_OPMASK) {
1889526a692SSemen Ustimenko 	case PCTL_10_T:
189d7a9ad56SMarius Strobl 		mii->mii_media_active |= IFM_10_T|IFM_HDX;
1909526a692SSemen Ustimenko 		break;
1919526a692SSemen Ustimenko 	case PCTL_10_T_FDX:
1929526a692SSemen Ustimenko 		mii->mii_media_active |= IFM_10_T|IFM_FDX;
1939526a692SSemen Ustimenko 		break;
1949526a692SSemen Ustimenko 	case PCTL_100_TX:
195d7a9ad56SMarius Strobl 		mii->mii_media_active |= IFM_100_TX|IFM_HDX;
1969526a692SSemen Ustimenko 		break;
1979526a692SSemen Ustimenko 	case PCTL_100_TX_FDX:
1989526a692SSemen Ustimenko 		mii->mii_media_active |= IFM_100_TX|IFM_FDX;
1999526a692SSemen Ustimenko 		break;
2009526a692SSemen Ustimenko 	case PCTL_100_T4:
201d7a9ad56SMarius Strobl 		mii->mii_media_active |= IFM_100_T4|IFM_HDX;
2029526a692SSemen Ustimenko 		break;
2034592db46SSemen Ustimenko 	case PCTL_AN:
2044592db46SSemen Ustimenko 		mii->mii_media_active |= IFM_NONE;
2054592db46SSemen Ustimenko 		break;
2069526a692SSemen Ustimenko 	default:
2079526a692SSemen Ustimenko 		/* Erg... this shouldn't happen. */
2089526a692SSemen Ustimenko 		mii->mii_media_active |= IFM_NONE;
2099526a692SSemen Ustimenko 		break;
2109526a692SSemen Ustimenko 	}
2113fcb7a53SMarius Strobl 	if ((mii->mii_media_active & IFM_FDX) != 0)
2123fcb7a53SMarius Strobl 		mii->mii_media_active |= mii_phy_flowstatus(sc);
2139526a692SSemen Ustimenko }
2149526a692SSemen Ustimenko 
215d9730b8bSJonathan Lemon static void
qsphy_reset(struct mii_softc * sc)2167d830ac9SWarner Losh qsphy_reset(struct mii_softc *sc)
2179526a692SSemen Ustimenko {
2189526a692SSemen Ustimenko 
2199526a692SSemen Ustimenko 	mii_phy_reset(sc);
2209526a692SSemen Ustimenko 	PHY_WRITE(sc, MII_QSPHY_IMASK, 0);
2219526a692SSemen Ustimenko }
222