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