xref: /netbsd-src/sys/arch/vax/if/if_le.c (revision dc306354b0b29af51801a7632f1e95265a68cd81)
1 /*	$NetBSD: if_le.c,v 1.13 1998/08/15 10:18:19 mycroft Exp $	*/
2 
3 /* #define LE_CHIP_IS_POKEY	/* does VS2000 need this ??? */
4 
5 /*-
6  * Copyright (c) 1998 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to The NetBSD Foundation
10  * by Charles M. Hannum.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*-
42  * Copyright (c) 1992, 1993
43  *	The Regents of the University of California.  All rights reserved.
44  *
45  * This code is derived from software contributed to Berkeley by
46  * Ralph Campbell and Rick Macklem.
47  *
48  * Redistribution and use in source and binary forms, with or without
49  * modification, are permitted provided that the following conditions
50  * are met:
51  * 1. Redistributions of source code must retain the above copyright
52  *    notice, this list of conditions and the following disclaimer.
53  * 2. Redistributions in binary form must reproduce the above copyright
54  *    notice, this list of conditions and the following disclaimer in the
55  *    documentation and/or other materials provided with the distribution.
56  * 3. All advertising materials mentioning features or use of this software
57  *    must display the following acknowledgement:
58  *	This product includes software developed by the University of
59  *	California, Berkeley and its contributors.
60  * 4. Neither the name of the University nor the names of its contributors
61  *    may be used to endorse or promote products derived from this software
62  *    without specific prior written permission.
63  *
64  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74  * SUCH DAMAGE.
75  *
76  *	@(#)if_le.c	8.2 (Berkeley) 11/16/93
77  */
78 
79 #include "opt_inet.h"
80 #include "bpfilter.h"
81 
82 #include <sys/param.h>
83 #include <sys/syslog.h>
84 #include <sys/socket.h>
85 #include <sys/device.h>
86 #include <sys/reboot.h>
87 
88 #include <net/if.h>
89 #include <net/if_ether.h>
90 #include <net/if_media.h>
91 
92 #if INET
93 #include <netinet/in.h>
94 #include <netinet/if_inarp.h>
95 #endif
96 
97 /*
98  * This would be nice, but it's not yet there...
99  *
100  * #include <machine/autoconf.h>
101  */
102 
103 #include <machine/pte.h>
104 #include <machine/cpu.h>
105 #include <machine/mtpr.h>
106 #include <machine/uvax.h>
107 #include <machine/ka410.h>
108 #include <machine/vsbus.h>
109 #include <machine/rpb.h>
110 
111 #include <dev/ic/lancereg.h>
112 #include <dev/ic/lancevar.h>
113 #include <dev/ic/am7990reg.h>
114 #define LE_NEED_BUF_CONTIG
115 #include <dev/ic/am7990var.h>
116 
117 #include <dev/tc/if_levar.h>
118 
119 #define xdebug(x)
120 
121 #ifdef LE_CHIP_IS_POKEY
122 /*
123  * access LANCE registers and double-check their contents
124  */
125 #define wbflush()	/* do nothing */
126 void lewritereg();
127 #define LERDWR(cntl, src, dst)	{ (dst) = (src); wbflush(); }
128 #define LEWREG(src, dst)	lewritereg(&(dst), (src))
129 #endif
130 
131 #define LE_IOSIZE 64*1024	/* 64K of real-mem are reserved and already */
132 extern void *le_iomem;		/* mapped into virt-mem by cpu_steal_pages */
133 extern u_long le_ioaddr;	/* le_iomem is virt, le_ioaddr is phys */
134 
135 #define LE_SOFTC(unit)	le_cd.cd_devs[unit]
136 #define LE_DELAY(x)	DELAY(x)
137 
138 int lematch __P((struct device *, struct cfdata *, void *));
139 void leattach __P((struct device *, struct device *, void *));
140 
141 int leintr __P((void *sc));
142 
143 struct cfattach le_ca = {
144 	sizeof(struct le_softc), lematch, leattach
145 };
146 
147 extern struct cfdriver le_cd;
148 
149 #if defined(_KERNEL) && !defined(_LKM)
150 #include "opt_ddb.h"
151 #endif
152 
153 #ifdef DDB
154 #define	integrate
155 #define hide
156 #else
157 #define	integrate	static __inline
158 #define hide		static
159 #endif
160 
161 hide void lewrcsr __P ((struct lance_softc *, u_int16_t, u_int16_t));
162 hide u_int16_t lerdcsr __P ((struct lance_softc *, u_int16_t));
163 
164 hide void
165 lewrcsr(sc, port, val)
166 	struct lance_softc *sc;
167 	u_int16_t port, val;
168 {
169 	struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
170 
171 #ifdef LE_CHIP_IS_POKEY
172 	LEWREG(port, ler1->ler1_rap);
173 	LERDWR(port, val, ler1->ler1_rdp);
174 #else
175 	ler1->ler1_rap = port;
176 	ler1->ler1_rdp = val;
177 #endif
178 }
179 
180 hide u_int16_t
181 lerdcsr(sc, port)
182 	struct lance_softc *sc;
183 	u_int16_t port;
184 {
185 	struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1;
186 	u_int16_t val;
187 
188 #ifdef LE_CHIP_IS_POKEY
189 	LEWREG(port, ler1->ler1_rap);
190 	LERDWR(0, ler1->ler1_rdp, val);
191 #else
192 	ler1->ler1_rap = port;
193 	val = ler1->ler1_rdp;
194 #endif
195 	return (val);
196 }
197 
198 integrate void
199 lehwinit(sc)
200 	struct lance_softc *sc;
201 {
202 }
203 
204 int
205 lematch(parent, cf, aux)
206 	struct device *parent;
207 	struct cfdata *cf;
208 	void *aux;
209 {
210 	struct confargs *ca = aux;
211 
212 	/*
213 	 * There could/should be more checks, but for now...
214 	 */
215 	if (strcmp(ca->ca_name, "le") &&
216 	    strcmp(ca->ca_name, "am7990") &&
217 	    strcmp(ca->ca_name, "AM7990"))
218 		return (0);
219 
220 	return (1);
221 }
222 
223 /*
224  *
225  */
226 void
227 leattach(parent, self, aux)
228 	struct device *parent, *self;
229 	void *aux;
230 {
231 	register struct le_softc *sc = (void *)self;
232 	struct confargs *ca = aux;
233 	u_char *cp;	/* pointer to MAC address */
234 	int i;
235 
236 	sc->sc_r1  = (void*)uvax_phys2virt(ca->ca_ioaddr);
237 
238 	sc->sc_am7990.lsc.sc_conf3 = 0;
239 	sc->sc_am7990.lsc.sc_mem = le_iomem;
240 	sc->sc_am7990.lsc.sc_addr = le_ioaddr;
241 	sc->sc_am7990.lsc.sc_memsize = LE_IOSIZE;
242 	sc->sc_am7990.lsc.sc_wrcsr = lewrcsr;
243 	sc->sc_am7990.lsc.sc_rdcsr = lerdcsr;
244 	sc->sc_am7990.lsc.sc_hwinit = lehwinit;
245 	sc->sc_am7990.lsc.sc_nocarrier = NULL;
246 
247 	xdebug(("leattach: mem=%x, addr=%x, size=%x (%d)\n",
248 	    sc->sc_am7990.lsc.sc_mem, sc->sc_am7990.lsc.sc_addr,
249 	    sc->sc_am7990.lsc.sc_memsize, sc->sc_am7990.lsc.sc_memsize));
250 
251 	sc->sc_am7990.lsc.sc_copytodesc = lance_copytobuf_contig;
252 	sc->sc_am7990.lsc.sc_copyfromdesc = lance_copyfrombuf_contig;
253 	sc->sc_am7990.lsc.sc_copytobuf = lance_copytobuf_contig;
254 	sc->sc_am7990.lsc.sc_copyfrombuf = lance_copyfrombuf_contig;
255 	sc->sc_am7990.lsc.sc_zerobuf = lance_zerobuf_contig;
256 
257 	/*
258 	 * Get the ethernet address out of rom
259 	 */
260 	for (i = 0; i < sizeof(sc->sc_am7990.lsc.sc_enaddr); i++) {
261 		int *eaddr = (void*)uvax_phys2virt(ca->ca_enaddr);
262 		sc->sc_am7990.lsc.sc_enaddr[i] = (u_char)eaddr[i];
263 	}
264 
265 	bcopy(self->dv_xname, sc->sc_am7990.lsc.sc_ethercom.ec_if.if_xname,
266 	    IFNAMSIZ);
267 	am7990_config(&sc->sc_am7990);
268 
269 #ifdef LEDEBUG
270 	sc->sc_am7990.lsc.sc_debug = LEDEBUG;
271 #endif
272 
273 	vsbus_intr_register(ca, am7990_intr, &sc->sc_am7990);
274 	vsbus_intr_enable(ca);
275 
276 	/*
277 	 * Register this device as boot device if we booted from it.
278 	 * This will fail if there are more than one le in a machine,
279 	 * fortunately there may be only one.
280 	 */
281 	if (B_TYPE(bootdev) == BDEV_LE)
282 		booted_from = self;
283 }
284 
285 #ifdef LE_CHIP_IS_POKEY
286 /*
287  * Write a lance register port, reading it back to ensure success. This seems
288  * to be necessary during initialization, since the chip appears to be a bit
289  * pokey sometimes.
290  */
291 void
292 lewritereg(regptr, val)
293 	register volatile u_short *regptr;
294 	register u_short val;
295 {
296 	register int i = 0;
297 
298 	while (*regptr != val) {
299 		*regptr = val;
300 		wbflush();
301 		if (++i > 10000) {
302 			printf("le: Reg did not settle (to x%x): x%x\n", val,
303 			    *regptr);
304 			return;
305 		}
306 		DELAY(100);
307 	}
308 }
309 #endif
310