if_le.c revision 1.13 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