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