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