xref: /openbsd/sys/dev/mii/txphy.c (revision f01de91c)
1*f01de91cSjsg /*	$OpenBSD: txphy.c,v 1.14 2024/05/27 03:56:59 jsg Exp $	*/
25f832cefSjason 
35f832cefSjason /*
45f832cefSjason  * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
55f832cefSjason  * All rights reserved.
65f832cefSjason  *
75f832cefSjason  * Redistribution and use in source and binary forms, with or without
85f832cefSjason  * modification, are permitted provided that the following conditions
95f832cefSjason  * are met:
105f832cefSjason  * 1. Redistributions of source code must retain the above copyright
115f832cefSjason  *    notice, this list of conditions and the following disclaimer.
125f832cefSjason  * 2. Redistributions in binary form must reproduce the above copyright
135f832cefSjason  *    notice, this list of conditions and the following disclaimer in the
145f832cefSjason  *    documentation and/or other materials provided with the distribution.
155f832cefSjason  *
165f832cefSjason  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
175f832cefSjason  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
185f832cefSjason  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
195f832cefSjason  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
205f832cefSjason  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
215f832cefSjason  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
225f832cefSjason  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
235f832cefSjason  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
245f832cefSjason  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
255f832cefSjason  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
265f832cefSjason  * POSSIBILITY OF SUCH DAMAGE.
275f832cefSjason  */
285f832cefSjason 
295f832cefSjason /*
305f832cefSjason  * Driver for the Texas Instruments TNETE2101 phy.
315f832cefSjason  */
325f832cefSjason 
335f832cefSjason #include <sys/param.h>
345f832cefSjason #include <sys/systm.h>
355f832cefSjason #include <sys/kernel.h>
365f832cefSjason #include <sys/device.h>
375f832cefSjason #include <sys/socket.h>
385f832cefSjason #include <sys/errno.h>
395f832cefSjason 
405f832cefSjason #include <net/if.h>
41*f01de91cSjsg #include <net/if_var.h>
425f832cefSjason #include <net/if_media.h>
435f832cefSjason 
445f832cefSjason #include <dev/mii/mii.h>
455f832cefSjason #include <dev/mii/miivar.h>
465f832cefSjason #include <dev/mii/miidevs.h>
475f832cefSjason 
48c4071fd1Smillert int	txphymatch(struct device *, void *, void *);
49c4071fd1Smillert void	txphyattach(struct device *, struct device *, void *);
505f832cefSjason 
51471aeecfSnaddy const struct cfattach txphy_ca = {
52fa9fb3edSderaadt 	sizeof(struct mii_softc), txphymatch, txphyattach, mii_phy_detach
535f832cefSjason };
545f832cefSjason 
555f832cefSjason struct cfdriver txphy_cd = {
565f832cefSjason 	NULL, "txphy", DV_DULL
575f832cefSjason };
585f832cefSjason 
59c4071fd1Smillert int	txphy_service(struct mii_softc *, struct mii_data *, int);
605f832cefSjason 
6178a92591Sbrad const struct mii_phy_funcs txphy_funcs = {
6278a92591Sbrad 	txphy_service, ukphy_status, mii_phy_reset,
6378a92591Sbrad };
6478a92591Sbrad 
65c2246be4Sbrad static const struct mii_phydesc txphys[] = {
66c2246be4Sbrad 	{ MII_OUI_xxTI,	MII_MODEL_xxTI_TNETE2101,
67c2246be4Sbrad 	  MII_STR_xxTI_TNETE2101 },
68c2246be4Sbrad 
69c2246be4Sbrad 	{ 0,			0,
70c2246be4Sbrad 	  NULL },
71c2246be4Sbrad };
72c2246be4Sbrad 
735f832cefSjason int
txphymatch(struct device * parent,void * match,void * aux)74c43900ffSbrad txphymatch(struct device *parent, void *match, void *aux)
755f832cefSjason {
765f832cefSjason 	struct mii_attach_args *ma = aux;
775f832cefSjason 
78c2246be4Sbrad 	if (mii_phy_match(ma, txphys) != NULL)
795f832cefSjason 		return (10);
80c2246be4Sbrad 
815f832cefSjason 	return (0);
825f832cefSjason }
835f832cefSjason 
845f832cefSjason void
txphyattach(struct device * parent,struct device * self,void * aux)85c43900ffSbrad txphyattach(struct device *parent, struct device *self, void *aux)
865f832cefSjason {
875f832cefSjason 	struct mii_softc *sc = (struct mii_softc *)self;
885f832cefSjason 	struct mii_attach_args *ma = aux;
895f832cefSjason 	struct mii_data *mii = ma->mii_data;
90c2246be4Sbrad 	const struct mii_phydesc *mpd;
915f832cefSjason 
92c2246be4Sbrad 	mpd = mii_phy_match(ma, txphys);
93c2246be4Sbrad 	printf(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
945f832cefSjason 
955f832cefSjason 	sc->mii_inst = mii->mii_instance;
965f832cefSjason 	sc->mii_phy = ma->mii_phyno;
9778a92591Sbrad 	sc->mii_funcs = &txphy_funcs;
985f832cefSjason 	sc->mii_pdata = mii;
99d240c9bfSbrad 	sc->mii_flags = ma->mii_flags;
1005f832cefSjason 
10178a92591Sbrad 	PHY_RESET(sc);
1025f832cefSjason 
1035f832cefSjason 	sc->mii_capabilities =
1045f832cefSjason 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
1055f832cefSjason 	if (sc->mii_capabilities & BMSR_MEDIAMASK)
1065d6e3d42Snate 		mii_phy_add_media(sc);
1075f832cefSjason }
1085f832cefSjason 
1095f832cefSjason int
txphy_service(struct mii_softc * sc,struct mii_data * mii,int cmd)110c43900ffSbrad txphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
1115f832cefSjason {
1125f832cefSjason 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
1135f832cefSjason 
1145d6e3d42Snate 	if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0)
1155d6e3d42Snate 		return (ENXIO);
1165d6e3d42Snate 
1175f832cefSjason 	/*
118aabe28d3Skevlo 	 * Can't isolate the TNETE2101 phy, so it has to be the only one.
1195f832cefSjason 	 */
1205f832cefSjason 	if (IFM_INST(ife->ifm_media) != sc->mii_inst)
1215f832cefSjason 		panic("txphy_service: attempt to isolate phy");
1225f832cefSjason 
1235f832cefSjason 	switch (cmd) {
1245f832cefSjason 	case MII_POLLSTAT:
1255f832cefSjason 		break;
1265f832cefSjason 
1275f832cefSjason 	case MII_MEDIACHG:
1285f832cefSjason 		/*
1295f832cefSjason 		 * If the interface is not up, don't do anything.
1305f832cefSjason 		 */
1315f832cefSjason 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
1325f832cefSjason 			break;
1335f832cefSjason 
1345f832cefSjason 		mii_phy_setmedia(sc);
1355f832cefSjason 		break;
1365f832cefSjason 
1375f832cefSjason 	case MII_TICK:
1385d6e3d42Snate 		if (mii_phy_tick(sc) == EJUSTRETURN)
1395f832cefSjason 			return (0);
1405f832cefSjason 		break;
1415f832cefSjason 
1425f832cefSjason 	case MII_DOWN:
1435f832cefSjason 		mii_phy_down(sc);
1445f832cefSjason 		return (0);
1455f832cefSjason 	}
1465f832cefSjason 
1475f832cefSjason 	/* Update the media status. */
1485d6e3d42Snate 	mii_phy_status(sc);
1495f832cefSjason 
1505f832cefSjason 	/* Callback if something changed. */
1515d6e3d42Snate 	mii_phy_update(sc, cmd);
1525f832cefSjason 	return (0);
1535f832cefSjason }
154