xref: /netbsd-src/sys/dev/qbus/if_de.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /*	$NetBSD: if_de.c,v 1.32 2017/05/22 17:22:29 ragge Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
5  * All rights reserved.
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)if_de.c	7.12 (Berkeley) 12/16/90
33  */
34 
35 /*
36  * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
37  * All rights reserved.
38  *
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  */
61 
62 /*
63  * DEC DEUNA interface
64  *
65  *	Lou Salkind
66  *	New York University
67  *
68  *	Rewritten by Ragge 30 April 2000 to match new world.
69  *
70  * TODO:
71  *	timeout routine (get statistics)
72  */
73 
74 #include <sys/cdefs.h>
75 __KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.32 2017/05/22 17:22:29 ragge Exp $");
76 
77 #include "opt_inet.h"
78 
79 #include <sys/param.h>
80 #include <sys/systm.h>
81 #include <sys/mbuf.h>
82 #include <sys/buf.h>
83 #include <sys/protosw.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #include <sys/errno.h>
87 #include <sys/syslog.h>
88 #include <sys/device.h>
89 
90 #include <net/if.h>
91 #include <net/if_ether.h>
92 #include <net/if_dl.h>
93 
94 #ifdef INET
95 #include <netinet/in.h>
96 #include <netinet/if_inarp.h>
97 #endif
98 
99 #include <net/bpf.h>
100 #include <net/bpfdesc.h>
101 
102 #include <sys/bus.h>
103 
104 #include <dev/qbus/ubavar.h>
105 #include <dev/qbus/if_dereg.h>
106 #include <dev/qbus/if_uba.h>
107 
108 #include "ioconf.h"
109 
110 /*
111  * Be careful with transmit/receive buffers, each entry steals 4 map
112  * registers, and there is only 496 on one unibus...
113  */
114 #define NRCV	7	/* number of receive buffers (must be > 1) */
115 #define NXMT	3	/* number of transmit buffers */
116 
117 /*
118  * Structure containing the elements that must be in DMA-safe memory.
119  */
120 struct	de_cdata {
121 	/* the following structures are always mapped in */
122 	struct	de_pcbb dc_pcbb;	/* port control block */
123 	struct	de_ring dc_xrent[NXMT]; /* transmit ring entrys */
124 	struct	de_ring dc_rrent[NRCV]; /* receive ring entrys */
125 	struct	de_udbbuf dc_udbbuf;	/* UNIBUS data buffer */
126 	/* end mapped area */
127 };
128 
129 /*
130  * Ethernet software status per interface.
131  *
132  * Each interface is referenced by a network interface structure,
133  * ds_if, which the routing code uses to locate the interface.
134  * This structure contains the output queue for the interface, its address, ...
135  * We also have, for each interface, a UBA interface structure, which
136  * contains information about the UNIBUS resources held by the interface:
137  * map registers, buffered data paths, etc.  Information is cached in this
138  * structure for use by the if_uba.c routines in running the interface
139  * efficiently.
140  */
141 struct	de_softc {
142 	device_t sc_dev;		/* Configuration common part */
143 	struct uba_softc *sc_uh;	/* our parent */
144 	struct evcnt sc_intrcnt;	/* Interrupt counting */
145 	struct ethercom sc_ec;		/* Ethernet common part */
146 #define sc_if	sc_ec.ec_if		/* network-visible interface */
147 	bus_space_tag_t sc_iot;
148 	bus_addr_t sc_ioh;
149 	bus_dma_tag_t sc_dmat;
150 	int sc_flags;
151 #define	DSF_MAPPED	1
152 	struct ubinfo sc_ui;
153 	struct de_cdata *sc_dedata;	/* Control structure */
154 	struct de_cdata *sc_pdedata;	/* Bus-mapped control structure */
155 	struct ifubinfo sc_ifuba;	/* UNIBUS resources */
156 	struct ifrw sc_ifr[NRCV];	/* UNIBUS receive buffer maps */
157 	struct ifxmt sc_ifw[NXMT];	/* UNIBUS receive buffer maps */
158 
159 	int sc_xindex;			/* UNA index into transmit chain */
160 	int sc_rindex;			/* UNA index into receive chain */
161 	int sc_xfree;			/* index for next transmit buffer */
162 	int sc_nxmit;			/* # of transmits in progress */
163 	void *sc_sh;			/* shutdownhook cookie */
164 };
165 
166 static	int dematch(device_t, cfdata_t, void *);
167 static	void deattach(device_t, device_t, void *);
168 static	void dewait(struct de_softc *, const char *);
169 static	int deinit(struct ifnet *);
170 static	int deioctl(struct ifnet *, u_long, void *);
171 static	void dereset(device_t);
172 static	void destop(struct ifnet *, int);
173 static	void destart(struct ifnet *);
174 static	void derecv(struct de_softc *);
175 static	void deintr(void *);
176 static	void deshutdown(void *);
177 
178 CFATTACH_DECL_NEW(de, sizeof(struct de_softc),
179     dematch, deattach, NULL, NULL);
180 
181 #define DE_WCSR(csr, val) \
182 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
183 #define DE_WLOW(val) \
184 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val)
185 #define DE_WHIGH(val) \
186 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val)
187 #define DE_RCSR(csr) \
188 	bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
189 
190 #define LOWORD(x)	((int)(x) & 0xffff)
191 #define HIWORD(x)	(((int)(x) >> 16) & 0x3)
192 /*
193  * Interface exists: make available by filling in network interface
194  * record.  System will initialize the interface when it is ready
195  * to accept packets.  We get the ethernet address here.
196  */
197 void
198 deattach(device_t parent, device_t self, void *aux)
199 {
200 	struct uba_attach_args *ua = aux;
201 	struct de_softc *sc = device_private(self);
202 	struct ifnet *ifp = &sc->sc_if;
203 	u_int8_t myaddr[ETHER_ADDR_LEN];
204 	int csr1, error;
205 	const char *c;
206 
207 	sc->sc_dev = self;
208 	sc->sc_uh = device_private(parent);
209 	sc->sc_iot = ua->ua_iot;
210 	sc->sc_ioh = ua->ua_ioh;
211 	sc->sc_dmat = ua->ua_dmat;
212 
213 	/*
214 	 * What kind of a board is this?
215 	 * The error bits 4-6 in pcsr1 are a device id as long as
216 	 * the high byte is zero.
217 	 */
218 	csr1 = DE_RCSR(DE_PCSR1);
219 	if (csr1 & 0xff60)
220 		c = "broken";
221 	else if (csr1 & 0x10)
222 		c = "delua";
223 	else
224 		c = "deuna";
225 
226 	/*
227 	 * Reset the board and temporarily map
228 	 * the pcbb buffer onto the Unibus.
229 	 */
230 	DE_WCSR(DE_PCSR0, 0);		/* reset INTE */
231 	DELAY(100);
232 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
233 	dewait(sc, "reset");
234 
235 	sc->sc_ui.ui_size = sizeof(struct de_cdata);
236 	if ((error = ubmemalloc(sc->sc_uh, &sc->sc_ui, 0)))
237 		return printf(": failed ubmemalloc(), error = %d\n", error);
238 	sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
239 
240 	/*
241 	 * Tell the DEUNA about our PCB
242 	 */
243 	DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr));
244 	DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr));
245 	DE_WLOW(CMD_GETPCBB);
246 	dewait(sc, "pcbb");
247 
248 	sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD;
249 	DE_WLOW(CMD_GETCMD);
250 	dewait(sc, "read addr ");
251 
252 	memcpy(myaddr, (void *)&sc->sc_dedata->dc_pcbb.pcbb2, sizeof (myaddr));
253 	printf(": %s, hardware address %s\n", c, ether_sprintf(myaddr));
254 
255 	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc,
256 	    &sc->sc_intrcnt);
257 	uba_reset_establish(dereset, sc->sc_dev);
258 	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
259 	    device_xname(sc->sc_dev), "intr");
260 
261 	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
262 	ifp->if_softc = sc;
263 	ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI;
264 	ifp->if_ioctl = deioctl;
265 	ifp->if_start = destart;
266 	ifp->if_init = deinit;
267 	ifp->if_stop = destop;
268 	IFQ_SET_READY(&ifp->if_snd);
269 
270 	if_attach(ifp);
271 	ether_ifattach(ifp, myaddr);
272 	ubmemfree(sc->sc_uh, &sc->sc_ui);
273 
274 	sc->sc_sh = shutdownhook_establish(deshutdown, sc);
275 }
276 
277 void
278 destop(struct ifnet *ifp, int a)
279 {
280 	struct de_softc *sc = ifp->if_softc;
281 
282 	DE_WLOW(0);
283 	DELAY(5000);
284 	DE_WLOW(PCSR0_RSET);
285 }
286 
287 
288 /*
289  * Reset of interface after UNIBUS reset.
290  */
291 void
292 dereset(device_t dev)
293 {
294 	struct de_softc *sc = (void *)dev;
295 
296 	sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
297 	sc->sc_flags &= ~DSF_MAPPED;
298 	sc->sc_pdedata = NULL;	/* All mappings lost */
299 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
300 	dewait(sc, "reset");
301 	deinit(&sc->sc_if);
302 }
303 
304 /*
305  * Initialization of interface; clear recorded pending
306  * operations, and reinitialize UNIBUS usage.
307  */
308 int
309 deinit(struct ifnet *ifp)
310 {
311 	struct de_softc *sc = ifp->if_softc;
312 	struct de_cdata *dc, *pdc;
313 	struct ifrw *ifrw;
314 	struct ifxmt *ifxp;
315 	struct de_ring *rp;
316 	int s, error;
317 
318 	if (ifp->if_flags & IFF_RUNNING)
319 		return 0;
320 	if ((sc->sc_flags & DSF_MAPPED) == 0) {
321 		if (if_ubaminit(&sc->sc_ifuba, sc->sc_uh, MCLBYTES,
322 				sc->sc_ifr, NRCV, sc->sc_ifw, NXMT)) {
323 			aprint_error_dev(sc->sc_dev, " can't initialize\n");
324 			ifp->if_flags &= ~IFF_UP;
325 			return 0;
326 		}
327 		sc->sc_ui.ui_size = sizeof(struct de_cdata);
328 		if ((error = ubmemalloc(sc->sc_uh, &sc->sc_ui, 0))) {
329 			aprint_error(": unable to ubmemalloc(), error = %d\n",
330 			    error);
331 			return 0;
332 		}
333 		sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr;
334 		sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
335 		sc->sc_flags |= DSF_MAPPED;
336 	}
337 
338 	/*
339 	 * Tell the DEUNA about our PCB
340 	 */
341 	DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata));
342 	DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata));
343 	DE_WLOW(0);		/* reset INTE */
344 	DELAY(500);
345 	DE_WLOW(CMD_GETPCBB);
346 	dewait(sc, "pcbb");
347 
348 	dc = sc->sc_dedata;
349 	pdc = sc->sc_pdedata;
350 	/* set the transmit and receive ring header addresses */
351 	dc->dc_pcbb.pcbb0 = FC_WTRING;
352 	dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf);
353 	dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf);
354 
355 	dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]);
356 	dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]);
357 	dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t);
358 	dc->dc_udbbuf.b_trlen = NXMT;
359 	dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]);
360 	dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]);
361 	dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t);
362 	dc->dc_udbbuf.b_rrlen = NRCV;
363 
364 	DE_WLOW(CMD_GETCMD);
365 	dewait(sc, "wtring");
366 
367 	sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE;
368 	sc->sc_dedata->dc_pcbb.pcbb2 = MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL;
369 	DE_WLOW(CMD_GETCMD);
370 	dewait(sc, "wtmode");
371 
372 	/* set up the receive and transmit ring entries */
373 	ifxp = &sc->sc_ifw[0];
374 	for (rp = &dc->dc_xrent[0]; rp < &dc->dc_xrent[NXMT]; rp++) {
375 		rp->r_segbl = LOWORD(ifxp->ifw_info);
376 		rp->r_segbh = HIWORD(ifxp->ifw_info);
377 		rp->r_flags = 0;
378 		ifxp++;
379 	}
380 	ifrw = &sc->sc_ifr[0];
381 	for (rp = &dc->dc_rrent[0]; rp < &dc->dc_rrent[NRCV]; rp++) {
382 		rp->r_slen = MCLBYTES - 2;
383 		rp->r_segbl = LOWORD(ifrw->ifrw_info);
384 		rp->r_segbh = HIWORD(ifrw->ifrw_info);
385 		rp->r_flags = RFLG_OWN;
386 		ifrw++;
387 	}
388 
389 	/* start up the board (rah rah) */
390 	s = splnet();
391 	sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0;
392 	sc->sc_if.if_flags |= IFF_RUNNING;
393 	DE_WLOW(PCSR0_INTE);			/* avoid interlock */
394 	destart(&sc->sc_if);		/* queue output packets */
395 	DE_WLOW(CMD_START|PCSR0_INTE);
396 	splx(s);
397 	return 0;
398 }
399 
400 /*
401  * Setup output on interface.
402  * Get another datagram to send off of the interface queue,
403  * and map it to the interface before starting the output.
404  * Must be called from ipl >= our interrupt level.
405  */
406 void
407 destart(struct ifnet *ifp)
408 {
409 	struct de_softc *sc = ifp->if_softc;
410 	struct de_cdata *dc;
411 	struct de_ring *rp;
412 	struct mbuf *m;
413 	int nxmit, len;
414 
415 	/*
416 	 * the following test is necessary, since
417 	 * the code is not reentrant and we have
418 	 * multiple transmission buffers.
419 	 */
420 	if (sc->sc_if.if_flags & IFF_OACTIVE)
421 		return;
422 	dc = sc->sc_dedata;
423 	for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) {
424 		IFQ_DEQUEUE(&ifp->if_snd, m);
425 		if (m == 0)
426 			break;
427 
428 		rp = &dc->dc_xrent[sc->sc_xfree];
429 		if (rp->r_flags & XFLG_OWN)
430 			panic("deuna xmit in progress");
431 		bpf_mtap(ifp, m);
432 
433 		len = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[sc->sc_xfree], m);
434 		rp->r_slen = len;
435 		rp->r_tdrerr = 0;
436 		rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
437 
438 		sc->sc_xfree++;
439 		if (sc->sc_xfree == NXMT)
440 			sc->sc_xfree = 0;
441 	}
442 	if (sc->sc_nxmit != nxmit) {
443 		sc->sc_nxmit = nxmit;
444 		if (ifp->if_flags & IFF_RUNNING)
445 			DE_WLOW(PCSR0_INTE|CMD_PDMD);
446 	}
447 }
448 
449 /*
450  * Command done interrupt.
451  */
452 void
453 deintr(void *arg)
454 {
455 	struct ifxmt *ifxp;
456 	struct de_cdata *dc;
457 	struct de_softc *sc = arg;
458 	struct de_ring *rp;
459 	short csr0;
460 
461 	/* save flags right away - clear out interrupt bits */
462 	csr0 = DE_RCSR(DE_PCSR0);
463 	DE_WHIGH(csr0 >> 8);
464 
465 
466 	sc->sc_if.if_flags |= IFF_OACTIVE;	/* prevent entering destart */
467 	/*
468 	 * if receive, put receive buffer on mbuf
469 	 * and hang the request again
470 	 */
471 	derecv(sc);
472 
473 	/*
474 	 * Poll transmit ring and check status.
475 	 * Be careful about loopback requests.
476 	 * Then free buffer space and check for
477 	 * more transmit requests.
478 	 */
479 	dc = sc->sc_dedata;
480 	for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) {
481 		rp = &dc->dc_xrent[sc->sc_xindex];
482 		if (rp->r_flags & XFLG_OWN)
483 			break;
484 
485 		sc->sc_if.if_opackets++;
486 		ifxp = &sc->sc_ifw[sc->sc_xindex];
487 		/* check for unusual conditions */
488 		if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) {
489 			if (rp->r_flags & XFLG_ERRS) {
490 				/* output error */
491 				sc->sc_if.if_oerrors++;
492 			} else if (rp->r_flags & XFLG_ONE) {
493 				/* one collision */
494 				sc->sc_if.if_collisions++;
495 			} else if (rp->r_flags & XFLG_MORE) {
496 				/* more than one collision */
497 				sc->sc_if.if_collisions += 2;	/* guess */
498 			}
499 		}
500 		if_ubaend(&sc->sc_ifuba, ifxp);
501 		/* check if next transmit buffer also finished */
502 		sc->sc_xindex++;
503 		if (sc->sc_xindex == NXMT)
504 			sc->sc_xindex = 0;
505 	}
506 	sc->sc_if.if_flags &= ~IFF_OACTIVE;
507 	destart(&sc->sc_if);
508 
509 	if (csr0 & PCSR0_RCBI) {
510 		DE_WLOW(PCSR0_INTE|CMD_PDMD);
511 	}
512 }
513 
514 /*
515  * Ethernet interface receiver interface.
516  * If input error just drop packet.
517  * Otherwise purge input buffered data path and examine
518  * packet to determine type.  If can't determine length
519  * from type, then have to drop packet.	 Othewise decapsulate
520  * packet based on type and pass to type specific higher-level
521  * input routine.
522  */
523 void
524 derecv(struct de_softc *sc)
525 {
526 	struct ifnet *ifp = &sc->sc_if;
527 	struct de_ring *rp;
528 	struct de_cdata *dc;
529 	struct mbuf *m;
530 	int len;
531 
532 	dc = sc->sc_dedata;
533 	rp = &dc->dc_rrent[sc->sc_rindex];
534 	while ((rp->r_flags & RFLG_OWN) == 0) {
535 		len = (rp->r_lenerr&RERR_MLEN) - ETHER_CRC_LEN;
536 		/* check for errors */
537 		if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) ||
538 		    (rp->r_lenerr & (RERR_BUFL|RERR_UBTO))) {
539 			sc->sc_if.if_ierrors++;
540 			goto next;
541 		}
542 		m = if_ubaget(&sc->sc_ifuba, &sc->sc_ifr[sc->sc_rindex],
543 		    ifp, len);
544 		if (m == 0) {
545 			sc->sc_if.if_ierrors++;
546 			goto next;
547 		}
548 
549 		if_percpuq_enqueue(ifp->if_percpuq, m);
550 
551 		/* hang the receive buffer again */
552 next:		rp->r_lenerr = 0;
553 		rp->r_flags = RFLG_OWN;
554 
555 		/* check next receive buffer */
556 		sc->sc_rindex++;
557 		if (sc->sc_rindex == NRCV)
558 			sc->sc_rindex = 0;
559 		rp = &dc->dc_rrent[sc->sc_rindex];
560 	}
561 }
562 
563 /*
564  * Process an ioctl request.
565  */
566 int
567 deioctl(struct ifnet *ifp, u_long cmd, void *data)
568 {
569 	int s, error = 0;
570 
571 	s = splnet();
572 
573 	error = ether_ioctl(ifp, cmd, data);
574 	if (error == ENETRESET)
575 		error = 0;
576 
577 	splx(s);
578 	return (error);
579 }
580 
581 /*
582  * Await completion of the named function
583  * and check for errors.
584  */
585 void
586 dewait(struct de_softc *sc, const char *fn)
587 {
588 	int csr0, csr1;
589 
590 	while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
591 		;
592 	csr0 = DE_RCSR(DE_PCSR0);
593 	DE_WHIGH(csr0 >> 8);
594 	if (csr0 & PCSR0_PCEI) {
595 		char bits0[64];
596 		char bits1[64];
597 		csr1 = DE_RCSR(DE_PCSR1);
598 		snprintb(bits0, sizeof(bits0), PCSR0_BITS, csr0);
599 		snprintb(bits1, sizeof(bits1), PCSR1_BITS, csr1);
600 		aprint_error_dev(sc->sc_dev, "%s failed, csr0=%s csr1=%s\n",
601 		    fn, bits0, bits1);
602 	}
603 }
604 
605 int
606 dematch(device_t parent, cfdata_t cf, void *aux)
607 {
608 	struct uba_attach_args *ua = aux;
609 	struct de_softc ssc;
610 	struct de_softc *sc = &ssc;
611 	int i;
612 
613 	sc->sc_iot = ua->ua_iot;
614 	sc->sc_ioh = ua->ua_ioh;
615 	/*
616 	 * Make sure self-test is finished before we screw with the board.
617 	 * Self-test on a DELUA can take 15 seconds (argh).
618 	 */
619 	for (i = 0;
620 	    (i < 160) &&
621 	    (DE_RCSR(DE_PCSR0) & PCSR0_FATI) == 0 &&
622 	    (DE_RCSR(DE_PCSR1) & PCSR1_STMASK) == STAT_RESET;
623 	    ++i)
624 		DELAY(50000);
625 	if (((DE_RCSR(DE_PCSR0) & PCSR0_FATI) != 0) ||
626 	    (((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_READY) &&
627 	    ((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_RUN)))
628 		return(0);
629 
630 	DE_WCSR(DE_PCSR0, 0);
631 	DELAY(5000);
632 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
633 	while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
634 		;
635 	/* make board interrupt by executing a GETPCBB command */
636 	DE_WCSR(DE_PCSR0, PCSR0_INTE);
637 	DE_WCSR(DE_PCSR2, 0);
638 	DE_WCSR(DE_PCSR3, 0);
639 	DE_WCSR(DE_PCSR0, PCSR0_INTE|CMD_GETPCBB);
640 	DELAY(50000);
641 
642 	return 1;
643 }
644 
645 void
646 deshutdown(void *arg)
647 {
648 	struct de_softc *sc = arg;
649 
650 	DE_WCSR(DE_PCSR0, 0);
651 	DELAY(1000);
652 	DE_WCSR(DE_PCSR0, PCSR0_RSET);
653 	dewait(sc, "shutdown");
654 }
655