xref: /openbsd-src/sys/dev/mii/mtdphy.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: mtdphy.c,v 1.5 2000/08/26 20:04:18 nate Exp $	*/
2 
3 /*
4  * Copyright (c) 1998, 1999 Jason L. Wright (jason@thought.net)
5  * 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 Jason L. Wright
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Driver for the Myson Technology MTD972 100BaseTX PCS/PMA.
36  */
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/device.h>
42 #include <sys/malloc.h>
43 #include <sys/socket.h>
44 #include <sys/errno.h>
45 
46 #include <net/if.h>
47 #include <net/if_media.h>
48 
49 #include <dev/mii/mii.h>
50 #include <dev/mii/miivar.h>
51 #include <dev/mii/miidevs.h>
52 #include <dev/mii/mtdphyreg.h>
53 
54 int	mtdphymatch __P((struct device *, void *, void *));
55 void	mtdphyattach __P((struct device *, struct device *, void *));
56 
57 struct cfattach mtdphy_ca = {
58 	sizeof(struct mii_softc), mtdphymatch, mtdphyattach, mii_phy_detach,
59 	    mii_phy_activate
60 };
61 
62 struct cfdriver mtdphy_cd = {
63 	NULL, "mtdphy", DV_DULL
64 };
65 
66 int	mtdphy_service __P((struct mii_softc *, struct mii_data *, int));
67 
68 int
69 mtdphymatch(parent, match, aux)
70 	struct device *parent;
71 	void *match;
72 	void *aux;
73 {
74 	struct mii_attach_args *ma = aux;
75 
76 	if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_MYSON &&
77 	    MII_MODEL(ma->mii_id2) == MII_MODEL_MYSON_MTD972)
78 		return (10);
79 
80 	return (0);
81 }
82 
83 void
84 mtdphyattach(parent, self, aux)
85 	struct device *parent, *self;
86 	void *aux;
87 {
88 	struct mii_softc *sc = (struct mii_softc *)self;
89 	struct mii_attach_args *ma = aux;
90 	struct mii_data *mii = ma->mii_data;
91 
92 	printf(": %s, rev. %d\n", MII_STR_MYSON_MTD972, MII_REV(ma->mii_id2));
93 
94 	sc->mii_inst = mii->mii_instance;
95 	sc->mii_phy = ma->mii_phyno;
96 	sc->mii_service = mtdphy_service;
97 	sc->mii_status = ukphy_status;
98 	sc->mii_pdata = mii;
99 	sc->mii_flags = mii->mii_flags;
100 
101 	mii_phy_reset(sc);
102 
103 	sc->mii_capabilities =
104 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
105 	if (sc->mii_capabilities & BMSR_MEDIAMASK)
106 		mii_phy_add_media(sc);
107 }
108 
109 int
110 mtdphy_service(sc, mii, cmd)
111 	struct mii_softc *sc;
112 	struct mii_data *mii;
113 	int cmd;
114 {
115 	struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
116 	int reg;
117 
118 	if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0)
119 		return (ENXIO);
120 
121 	switch (cmd) {
122 	case MII_POLLSTAT:
123 		/*
124 		 * If we're not polling our PHY instance, just return.
125 		 */
126 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
127 			return (0);
128 		break;
129 
130 	case MII_MEDIACHG:
131 		/*
132 		 * If the interface is not up, don't do anything.
133 		 */
134 		if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
135 			reg = PHY_READ(sc, MII_BMCR);
136 			PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
137 			return (0);
138 		}
139 
140 		if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
141 			break;
142 
143 		mii_phy_setmedia(sc);
144 		break;
145 
146 	case MII_TICK:
147 		/*
148 		 *If we're not currently selected, just return.
149 		 */
150 		if (IFM_INST(ife->ifm_media) != sc->mii_inst)
151 			return (0);
152 
153 		if (mii_phy_tick(sc) == EJUSTRETURN)
154 			return (0);
155 		break;
156 
157 	case MII_DOWN:
158 		mii_phy_down(sc);
159 		return (0);
160 	}
161 
162 	/* Update the media status. */
163 	mii_phy_status(sc);
164 
165 	/* Callback if something changed. */
166 	mii_phy_update(sc, cmd);
167 	return (0);
168 }
169