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