if_de.c revision 1.9 1 /* $NetBSD: if_de.c,v 1.9 2001/04/26 19:36:07 ragge Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
5 * Copyright (c) 2000 Ludd, University of Lule}, Sweden.
6 * All rights reserved.
7 *
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * @(#)if_de.c 7.12 (Berkeley) 12/16/90
38 */
39
40 /*
41 * DEC DEUNA interface
42 *
43 * Lou Salkind
44 * New York University
45 *
46 * Rewritten by Ragge 30 April 2000 to match new world.
47 *
48 * TODO:
49 * timeout routine (get statistics)
50 */
51
52 #include "opt_inet.h"
53 #include "bpfilter.h"
54
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/mbuf.h>
58 #include <sys/buf.h>
59 #include <sys/protosw.h>
60 #include <sys/socket.h>
61 #include <sys/ioctl.h>
62 #include <sys/errno.h>
63 #include <sys/syslog.h>
64 #include <sys/device.h>
65
66 #include <net/if.h>
67 #include <net/if_ether.h>
68 #include <net/if_dl.h>
69
70 #ifdef INET
71 #include <netinet/in.h>
72 #include <netinet/if_inarp.h>
73 #endif
74
75 #if NBPFILTER > 0
76 #include <net/bpf.h>
77 #include <net/bpfdesc.h>
78 #endif
79
80 #include <machine/bus.h>
81
82 #include <dev/qbus/ubavar.h>
83 #include <dev/qbus/if_dereg.h>
84
85 #include "ioconf.h"
86
87 /*
88 * Be careful with transmit/receive buffers, each entry steals 4 map
89 * registers, and there is only 496 on one unibus...
90 */
91 #define NRCV 10 /* number of receive buffers (must be > 1) */
92 #define NXMT 10 /* number of transmit buffers */
93
94 /*
95 * Structure containing the elements that must be in DMA-safe memory.
96 */
97 struct de_cdata {
98 /* the following structures are always mapped in */
99 struct de_pcbb dc_pcbb; /* port control block */
100 struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */
101 struct de_ring dc_rrent[NRCV]; /* receive ring entrys */
102 struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */
103 /* end mapped area */
104 };
105
106 /*
107 * Ethernet software status per interface.
108 *
109 * Each interface is referenced by a network interface structure,
110 * ds_if, which the routing code uses to locate the interface.
111 * This structure contains the output queue for the interface, its address, ...
112 * We also have, for each interface, a UBA interface structure, which
113 * contains information about the UNIBUS resources held by the interface:
114 * map registers, buffered data paths, etc. Information is cached in this
115 * structure for use by the if_uba.c routines in running the interface
116 * efficiently.
117 */
118 struct de_softc {
119 struct device sc_dev; /* Configuration common part */
120 struct evcnt sc_intrcnt; /* Interrupt counting */
121 struct ethercom sc_ec; /* Ethernet common part */
122 #define sc_if sc_ec.ec_if /* network-visible interface */
123 bus_space_tag_t sc_iot;
124 bus_addr_t sc_ioh;
125 bus_dma_tag_t sc_dmat;
126 struct ubinfo sc_ui;
127 struct de_cdata *sc_dedata; /* Control structure */
128 struct de_cdata *sc_pdedata; /* Bus-mapped control structure */
129 bus_dmamap_t sc_rcvmap[NRCV]; /* unibus receive maps */
130 struct mbuf *sc_rxmbuf[NRCV];
131 bus_dmamap_t sc_xmtmap[NXMT];
132 struct mbuf *sc_txmbuf[NXMT];
133 char sc_xbuf[NXMT][ETHER_MAX_LEN];
134 int sc_xindex; /* UNA index into transmit chain */
135 int sc_rindex; /* UNA index into receive chain */
136 int sc_xfree; /* index for next transmit buffer */
137 int sc_nxmit; /* # of transmits in progress */
138 void *sc_sh; /* shutdownhook cookie */
139 };
140
141 static int dematch(struct device *, struct cfdata *, void *);
142 static void deattach(struct device *, struct device *, void *);
143 static void dewait(struct de_softc *, char *);
144 static void deinit(struct de_softc *);
145 static int deioctl(struct ifnet *, u_long, caddr_t);
146 static void dereset(struct device *);
147 static void destart(struct ifnet *);
148 static void derecv(struct de_softc *);
149 static void deintr(void *);
150 static int de_add_rxbuf(struct de_softc *, int);
151 static void deshutdown(void *);
152
153 struct cfattach de_ca = {
154 sizeof(struct de_softc), dematch, deattach
155 };
156
157 #define DE_WCSR(csr, val) \
158 bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val)
159 #define DE_WLOW(val) \
160 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val)
161 #define DE_WHIGH(val) \
162 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val)
163 #define DE_RCSR(csr) \
164 bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr)
165
166 #define LOWORD(x) ((int)(x) & 0xffff)
167 #define HIWORD(x) (((int)(x) >> 16) & 0x3)
168 /*
169 * Interface exists: make available by filling in network interface
170 * record. System will initialize the interface when it is ready
171 * to accept packets. We get the ethernet address here.
172 */
173 void
174 deattach(struct device *parent, struct device *self, void *aux)
175 {
176 struct uba_attach_args *ua = aux;
177 struct de_softc *sc = (struct de_softc *)self;
178 struct ifnet *ifp = &sc->sc_if;
179 u_int8_t myaddr[ETHER_ADDR_LEN];
180 int csr1, error, i;
181 char *c;
182
183 sc->sc_iot = ua->ua_iot;
184 sc->sc_ioh = ua->ua_ioh;
185 sc->sc_dmat = ua->ua_dmat;
186
187 /*
188 * What kind of a board is this?
189 * The error bits 4-6 in pcsr1 are a device id as long as
190 * the high byte is zero.
191 */
192 csr1 = DE_RCSR(DE_PCSR1);
193 if (csr1 & 0xff60)
194 c = "broken";
195 else if (csr1 & 0x10)
196 c = "delua";
197 else
198 c = "deuna";
199
200 /*
201 * Reset the board and temporarily map
202 * the pcbb buffer onto the Unibus.
203 */
204 DE_WCSR(DE_PCSR0, 0); /* reset INTE */
205 DELAY(100);
206 DE_WCSR(DE_PCSR0, PCSR0_RSET);
207 dewait(sc, "reset");
208
209 sc->sc_ui.ui_size = sizeof(struct de_cdata);
210 if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) {
211 printf(": unable to ubmemalloc(), error = %d\n", error);
212 return;
213 }
214 sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr;
215 sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;
216
217 /*
218 * Create receive buffer DMA maps.
219 */
220 for (i = 0; i < NRCV; i++) {
221 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
222 MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
223 &sc->sc_rcvmap[i]))) {
224 printf(": unable to create rx DMA map %d, error = %d\n",
225 i, error);
226 goto fail_5;
227 }
228 }
229
230 /*
231 * Pre-allocate the receive buffers.
232 */
233 for (i = 0; i < NRCV; i++) {
234 if ((error = de_add_rxbuf(sc, i)) != 0) {
235 printf(": unable to allocate or map rx buffer %d\n,"
236 " error = %d\n", i, error);
237 goto fail_6;
238 }
239 }
240
241 /*
242 * Pre-allocate the transmit buffers.
243 */
244 for (i = 0; i < NXMT; i++) {
245 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
246 MCLBYTES, 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW,
247 &sc->sc_xmtmap[i]))) {
248 printf(": unable to create tx DMA map %d, error = %d\n",
249 i, error);
250 goto fail_7;
251 }
252 }
253
254 /*
255 * Tell the DEUNA about our PCB
256 */
257 DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata));
258 DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata));
259 DE_WLOW(CMD_GETPCBB);
260 dewait(sc, "pcbb");
261
262 sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD;
263 DE_WLOW(CMD_GETCMD);
264 dewait(sc, "read addr ");
265
266 bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr));
267 printf("\n%s: %s, hardware address %s\n", sc->sc_dev.dv_xname, c,
268 ether_sprintf(myaddr));
269
270 uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc,
271 &sc->sc_intrcnt);
272 uba_reset_establish(dereset, &sc->sc_dev);
273 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
274 sc->sc_dev.dv_xname, "intr");
275
276 strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
277 ifp->if_softc = sc;
278 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI;
279 ifp->if_ioctl = deioctl;
280 ifp->if_start = destart;
281 IFQ_SET_READY(&ifp->if_snd);
282
283 if_attach(ifp);
284 ether_ifattach(ifp, myaddr);
285
286 sc->sc_sh = shutdownhook_establish(deshutdown, sc);
287 return;
288
289 /*
290 * Free any resources we've allocated during the failed attach
291 * attempt. Do this in reverse order and fall through.
292 */
293 fail_7:
294 for (i = 0; i < NXMT; i++)
295 if (sc->sc_xmtmap[i] != NULL)
296 bus_dmamap_destroy(sc->sc_dmat, sc->sc_xmtmap[i]);
297 fail_6:
298 for (i = 0; i < NRCV; i++) {
299 if (sc->sc_rxmbuf[i] != NULL) {
300 bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
301 m_freem(sc->sc_rxmbuf[i]);
302 }
303 }
304 fail_5:
305 for (i = 0; i < NRCV; i++) {
306 if (sc->sc_rcvmap[i] != NULL)
307 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rcvmap[i]);
308 }
309 }
310
311 /*
312 * Reset of interface after UNIBUS reset.
313 */
314 void
315 dereset(struct device *dev)
316 {
317 struct de_softc *sc = (void *)dev;
318
319 sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
320 sc->sc_pdedata = NULL; /* All mappings lost */
321 DE_WCSR(DE_PCSR0, PCSR0_RSET);
322 dewait(sc, "reset");
323 deinit(sc);
324 }
325
326 /*
327 * Initialization of interface; clear recorded pending
328 * operations, and reinitialize UNIBUS usage.
329 */
330 void
331 deinit(struct de_softc *sc)
332 {
333 struct de_cdata *dc, *pdc;
334 int s, i;
335
336 if (sc->sc_if.if_flags & IFF_RUNNING)
337 return;
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 for (i = 0; i < NXMT; i++)
374 dc->dc_xrent[i].r_flags = 0;
375
376 for (i = 0; i < NRCV; i++)
377 dc->dc_rrent[i].r_flags = RFLG_OWN;
378
379 /* start up the board (rah rah) */
380 s = splnet();
381 sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0;
382 sc->sc_if.if_flags |= IFF_RUNNING;
383 DE_WLOW(PCSR0_INTE); /* avoid interlock */
384 destart(&sc->sc_if); /* queue output packets */
385 DE_WLOW(CMD_START|PCSR0_INTE);
386 splx(s);
387 }
388
389 /*
390 * Setup output on interface.
391 * Get another datagram to send off of the interface queue,
392 * and map it to the interface before starting the output.
393 * Must be called from ipl >= our interrupt level.
394 */
395 void
396 destart(struct ifnet *ifp)
397 {
398 struct de_softc *sc = ifp->if_softc;
399 struct de_cdata *dc;
400 struct de_ring *rp, *rp2;
401 struct mbuf *m;
402 int nxmit, buffer, freeb, freeb2;
403
404 /*
405 * the following test is necessary, since
406 * the code is not reentrant and we have
407 * multiple transmission buffers.
408 */
409 if (sc->sc_if.if_flags & IFF_OACTIVE)
410 return;
411 dc = sc->sc_dedata;
412 for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) {
413 IFQ_DEQUEUE(&ifp->if_snd, m);
414 if (m == 0)
415 break;
416 freeb = sc->sc_xfree;
417 rp = &dc->dc_xrent[freeb];
418 if (rp->r_flags & XFLG_OWN)
419 panic("deuna xmit in progress");
420
421 /*
422 * One or two mbufs: DMA out of those mbufs.
423 * Three or more: copy to the preallocated buffer space.
424 * XXX - should use bus_dmamap_load_mbuf().
425 */
426 rp->r_tdrerr = 0;
427 if (m->m_next == NULL) {
428 bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
429 mtod(m, void *), m->m_len, 0, 0);
430 buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
431 rp->r_slen = m->m_pkthdr.len;
432 rp->r_segbl = LOWORD(buffer);
433 rp->r_segbh = HIWORD(buffer);
434 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
435 } else if (m->m_next->m_next == NULL) {
436 if (nxmit+1 == NXMT) {
437 IF_PREPEND(&ifp->if_snd, m);
438 goto out;
439 }
440 freeb2 = (freeb+1 == NXMT ? 0 : freeb+1);
441 rp2 = &dc->dc_xrent[freeb2];
442 bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
443 mtod(m, void *), m->m_len, 0, 0);
444 buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
445 rp->r_slen = m->m_len;
446 rp->r_segbl = LOWORD(buffer);
447 rp->r_segbh = HIWORD(buffer);
448 bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb2],
449 mtod(m->m_next, void *), m->m_next->m_len, 0, 0);
450 buffer = sc->sc_xmtmap[freeb2]->dm_segs[0].ds_addr;
451 rp2->r_slen = m->m_next->m_len;
452 rp2->r_segbl = LOWORD(buffer);
453 rp2->r_segbh = HIWORD(buffer);
454 rp2->r_flags = XFLG_ENP|XFLG_OWN;
455 rp->r_flags = XFLG_STP|XFLG_OWN;
456 nxmit++;
457 sc->sc_xfree = freeb2;
458
459 } else {
460 m_copydata(m, 0, m->m_pkthdr.len,
461 &sc->sc_xbuf[freeb][0]);
462
463 bus_dmamap_load(sc->sc_dmat, sc->sc_xmtmap[freeb],
464 &sc->sc_xbuf[freeb][0], m->m_pkthdr.len, 0, 0);
465 buffer = sc->sc_xmtmap[freeb]->dm_segs[0].ds_addr;
466 rp->r_segbl = LOWORD(buffer);
467 rp->r_segbh = HIWORD(buffer);
468 rp->r_slen = m->m_pkthdr.len;
469 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN;
470 }
471
472 sc->sc_txmbuf[sc->sc_xfree] = m;
473
474 #if NBPFILTER > 0
475 if (ifp->if_bpf)
476 bpf_mtap(ifp->if_bpf, m);
477 #endif
478
479 sc->sc_xfree++;
480 if (sc->sc_xfree == NXMT)
481 sc->sc_xfree = 0;
482 }
483 out: if (sc->sc_nxmit != nxmit) {
484 sc->sc_nxmit = nxmit;
485 if (ifp->if_flags & IFF_RUNNING)
486 DE_WLOW(PCSR0_INTE|CMD_PDMD);
487 }
488 }
489
490 /*
491 * Command done interrupt.
492 */
493 void
494 deintr(void *arg)
495 {
496 struct de_cdata *dc;
497 struct de_softc *sc = arg;
498 struct de_ring *rp;
499 short csr0;
500
501 /* save flags right away - clear out interrupt bits */
502 csr0 = DE_RCSR(DE_PCSR0);
503 DE_WHIGH(csr0 >> 8);
504
505
506 sc->sc_if.if_flags |= IFF_OACTIVE; /* prevent entering destart */
507 /*
508 * if receive, put receive buffer on mbuf
509 * and hang the request again
510 */
511 derecv(sc);
512
513 /*
514 * Poll transmit ring and check status.
515 * Be careful about loopback requests.
516 * Then free buffer space and check for
517 * more transmit requests.
518 */
519 dc = sc->sc_dedata;
520 for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) {
521 rp = &dc->dc_xrent[sc->sc_xindex];
522 if (rp->r_flags & XFLG_OWN)
523 break;
524 bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[sc->sc_xindex]);
525 if (sc->sc_txmbuf[sc->sc_xindex]) {
526 m_freem(sc->sc_txmbuf[sc->sc_xindex]);
527 sc->sc_txmbuf[sc->sc_xindex] = NULL;
528 }
529 sc->sc_if.if_opackets++;
530 /* check for unusual conditions */
531 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) {
532 if (rp->r_flags & XFLG_ERRS) {
533 /* output error */
534 sc->sc_if.if_oerrors++;
535 } else if (rp->r_flags & XFLG_ONE) {
536 /* one collision */
537 sc->sc_if.if_collisions++;
538 } else if (rp->r_flags & XFLG_MORE) {
539 /* more than one collision */
540 sc->sc_if.if_collisions += 2; /* guess */
541 }
542 }
543 /* check if next transmit buffer also finished */
544 sc->sc_xindex++;
545 if (sc->sc_xindex == NXMT)
546 sc->sc_xindex = 0;
547 }
548 sc->sc_if.if_flags &= ~IFF_OACTIVE;
549 destart(&sc->sc_if);
550
551 if (csr0 & PCSR0_RCBI) {
552 DE_WLOW(PCSR0_INTE|CMD_PDMD);
553 }
554 }
555
556 /*
557 * Ethernet interface receiver interface.
558 * If input error just drop packet.
559 * Otherwise purge input buffered data path and examine
560 * packet to determine type. If can't determine length
561 * from type, then have to drop packet. Othewise decapsulate
562 * packet based on type and pass to type specific higher-level
563 * input routine.
564 */
565 void
566 derecv(struct de_softc *sc)
567 {
568 struct ifnet *ifp = &sc->sc_if;
569 struct de_ring *rp;
570 struct de_cdata *dc;
571 struct mbuf *m;
572 int len;
573
574 dc = sc->sc_dedata;
575 rp = &dc->dc_rrent[sc->sc_rindex];
576 while ((rp->r_flags & RFLG_OWN) == 0) {
577 sc->sc_if.if_ipackets++;
578 len = (rp->r_lenerr&RERR_MLEN) - ETHER_CRC_LEN;
579 /* check for errors */
580 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) ||
581 (rp->r_lenerr & (RERR_BUFL|RERR_UBTO))) {
582 sc->sc_if.if_ierrors++;
583 goto next;
584 }
585 m = sc->sc_rxmbuf[sc->sc_rindex];
586 #if NBPFILTER > 0
587 if (ifp->if_bpf)
588 bpf_mtap(ifp->if_bpf, m);
589 #endif
590
591 if (de_add_rxbuf(sc, sc->sc_rindex) == 0) {
592 m->m_pkthdr.rcvif = ifp;
593 m->m_pkthdr.len = m->m_len = len;
594 (*ifp->if_input)(ifp, m);
595 } else
596 sc->sc_if.if_ierrors++;
597
598 /* hang the receive buffer again */
599 next: rp->r_lenerr = 0;
600 rp->r_flags = RFLG_OWN;
601
602 /* check next receive buffer */
603 sc->sc_rindex++;
604 if (sc->sc_rindex == NRCV)
605 sc->sc_rindex = 0;
606 rp = &dc->dc_rrent[sc->sc_rindex];
607 }
608 }
609
610 /*
611 * Add a receive buffer to the indicated descriptor.
612 */
613 int
614 de_add_rxbuf(sc, i)
615 struct de_softc *sc;
616 int i;
617 {
618 struct mbuf *m;
619 struct de_ring *rp;
620 vaddr_t addr;
621 int error;
622
623 MGETHDR(m, M_DONTWAIT, MT_DATA);
624 if (m == NULL)
625 return (ENOBUFS);
626
627 MCLGET(m, M_DONTWAIT);
628 if ((m->m_flags & M_EXT) == 0) {
629 m_freem(m);
630 return (ENOBUFS);
631 }
632
633 if (sc->sc_rxmbuf[i] != NULL)
634 bus_dmamap_unload(sc->sc_dmat, sc->sc_rcvmap[i]);
635
636 error = bus_dmamap_load(sc->sc_dmat, sc->sc_rcvmap[i],
637 m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT);
638 if (error)
639 panic("%s: can't load rx DMA map %d, error = %d\n",
640 sc->sc_dev.dv_xname, i, error);
641 sc->sc_rxmbuf[i] = m;
642
643 bus_dmamap_sync(sc->sc_dmat, sc->sc_rcvmap[i], 0,
644 sc->sc_rcvmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD);
645
646 /*
647 * We know that the mbuf cluster is page aligned. Also, be sure
648 * that the IP header will be longword aligned.
649 */
650 m->m_data += 2;
651 addr = sc->sc_rcvmap[i]->dm_segs[0].ds_addr + 2;
652 rp = &sc->sc_dedata->dc_rrent[i];
653 rp->r_lenerr = 0;
654 rp->r_segbl = LOWORD(addr);
655 rp->r_segbh = HIWORD(addr);
656 rp->r_slen = m->m_ext.ext_size - 2;
657 rp->r_flags = RFLG_OWN;
658
659 return (0);
660 }
661
662
663 /*
664 * Process an ioctl request.
665 */
666 int
667 deioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
668 {
669 struct ifaddr *ifa = (struct ifaddr *)data;
670 struct ifreq *ifr = (struct ifreq *)data;
671 struct de_softc *sc = ifp->if_softc;
672 int s = splnet(), error = 0;
673
674 switch (cmd) {
675
676 case SIOCSIFADDR:
677 ifp->if_flags |= IFF_UP;
678 switch (ifa->ifa_addr->sa_family) {
679 #ifdef INET
680 case AF_INET:
681 deinit(sc);
682 arp_ifinit(ifp, ifa);
683 break;
684 #endif
685 }
686 break;
687
688 case SIOCSIFFLAGS:
689 if ((ifp->if_flags & IFF_UP) == 0 &&
690 (ifp->if_flags & IFF_RUNNING) != 0) {
691 /*
692 * If interface is marked down and it is running,
693 * stop it.
694 */
695 DE_WLOW(0);
696 DELAY(5000);
697 DE_WLOW(PCSR0_RSET);
698 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
699 } else if ((ifp->if_flags & IFF_UP) != 0 &&
700 (ifp->if_flags & IFF_RUNNING) == 0) {
701 /*
702 * If interface it marked up and it is stopped, then
703 * start it.
704 */
705 deinit(sc);
706 } else if ((ifp->if_flags & IFF_UP) != 0) {
707 /*
708 * Send a new setup packet to match any new changes.
709 * (Like IFF_PROMISC etc)
710 */
711 sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE;
712 sc->sc_dedata->dc_pcbb.pcbb2 =
713 MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL;
714 if (ifp->if_flags & IFF_PROMISC)
715 sc->sc_dedata->dc_pcbb.pcbb2 |= MOD_PROM;
716 DE_WLOW(CMD_GETCMD|PCSR0_INTE);
717 dewait(sc, "chgmode");
718 }
719 break;
720
721 case SIOCADDMULTI:
722 case SIOCDELMULTI:
723 /*
724 * Update our multicast list.
725 */
726 error = (cmd == SIOCADDMULTI) ?
727 ether_addmulti(ifr, &sc->sc_ec):
728 ether_delmulti(ifr, &sc->sc_ec);
729
730 if (error == ENETRESET) {
731 /*
732 * Multicast list has changed; set the hardware filter
733 * accordingly.
734 */
735 error = 0;
736 }
737 break;
738
739 default:
740 error = EINVAL;
741 }
742 splx(s);
743 return (error);
744 }
745
746 /*
747 * Await completion of the named function
748 * and check for errors.
749 */
750 void
751 dewait(struct de_softc *sc, char *fn)
752 {
753 int csr0;
754
755 while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
756 ;
757 csr0 = DE_RCSR(DE_PCSR0);
758 DE_WHIGH(csr0 >> 8);
759 if (csr0 & PCSR0_PCEI) {
760 char bits[64];
761 printf("%s: %s failed, csr0=%s ", sc->sc_dev.dv_xname, fn,
762 bitmask_snprintf(csr0, PCSR0_BITS, bits, sizeof(bits)));
763 printf("csr1=%s\n", bitmask_snprintf(DE_RCSR(DE_PCSR1),
764 PCSR1_BITS, bits, sizeof(bits)));
765 }
766 }
767
768 int
769 dematch(struct device *parent, struct cfdata *cf, void *aux)
770 {
771 struct uba_attach_args *ua = aux;
772 struct de_softc ssc;
773 struct de_softc *sc = &ssc;
774 int i;
775
776 sc->sc_iot = ua->ua_iot;
777 sc->sc_ioh = ua->ua_ioh;
778 /*
779 * Make sure self-test is finished before we screw with the board.
780 * Self-test on a DELUA can take 15 seconds (argh).
781 */
782 for (i = 0;
783 (i < 160) &&
784 (DE_RCSR(DE_PCSR0) & PCSR0_FATI) == 0 &&
785 (DE_RCSR(DE_PCSR1) & PCSR1_STMASK) == STAT_RESET;
786 ++i)
787 DELAY(50000);
788 if (((DE_RCSR(DE_PCSR0) & PCSR0_FATI) != 0) ||
789 (((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_READY) &&
790 ((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_RUN)))
791 return(0);
792
793 DE_WCSR(DE_PCSR0, 0);
794 DELAY(5000);
795 DE_WCSR(DE_PCSR0, PCSR0_RSET);
796 while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0)
797 ;
798 /* make board interrupt by executing a GETPCBB command */
799 DE_WCSR(DE_PCSR0, PCSR0_INTE);
800 DE_WCSR(DE_PCSR2, 0);
801 DE_WCSR(DE_PCSR3, 0);
802 DE_WCSR(DE_PCSR0, PCSR0_INTE|CMD_GETPCBB);
803 DELAY(50000);
804
805 return 1;
806 }
807
808 void
809 deshutdown(void *arg)
810 {
811 struct de_softc *sc = arg;
812
813 DE_WCSR(DE_PCSR0, 0);
814 DELAY(1000);
815 DE_WCSR(DE_PCSR0, PCSR0_RSET);
816 dewait(sc, "shutdown");
817 }
818