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