1 /* $NetBSD: i82586.c,v 1.42 2001/11/26 23:30:59 fredette Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Paul Kranenburg and Charles M. Hannum. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /*- 40 * Copyright (c) 1997 Paul Kranenburg. 41 * Copyright (c) 1992, 1993, University of Vermont and State 42 * Agricultural College. 43 * Copyright (c) 1992, 1993, Garrett A. Wollman. 44 * 45 * Portions: 46 * Copyright (c) 1994, 1995, Rafal K. Boni 47 * Copyright (c) 1990, 1991, William F. Jolitz 48 * Copyright (c) 1990, The Regents of the University of California 49 * 50 * All rights reserved. 51 * 52 * Redistribution and use in source and binary forms, with or without 53 * modification, are permitted provided that the following conditions 54 * are met: 55 * 1. Redistributions of source code must retain the above copyright 56 * notice, this list of conditions and the following disclaimer. 57 * 2. Redistributions in binary form must reproduce the above copyright 58 * notice, this list of conditions and the following disclaimer in the 59 * documentation and/or other materials provided with the distribution. 60 * 3. All advertising materials mentioning features or use of this software 61 * must display the following acknowledgement: 62 * This product includes software developed by the University of Vermont 63 * and State Agricultural College and Garrett A. Wollman, by William F. 64 * Jolitz, and by the University of California, Berkeley, Lawrence 65 * Berkeley Laboratory, and its contributors. 66 * 4. Neither the names of the Universities nor the names of the authors 67 * may be used to endorse or promote products derived from this software 68 * without specific prior written permission. 69 * 70 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 71 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 72 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 73 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE 74 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 75 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 76 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 77 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 78 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 79 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 80 * SUCH DAMAGE. 81 */ 82 83 /* 84 * Intel 82586 Ethernet chip 85 * Register, bit, and structure definitions. 86 * 87 * Original StarLAN driver written by Garrett Wollman with reference to the 88 * Clarkson Packet Driver code for this chip written by Russ Nelson and others. 89 * 90 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump. 91 * 92 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni. 93 * 94 * Majorly cleaned up and 3C507 code merged by Charles Hannum. 95 * 96 * Converted to SUN ie driver by Charles D. Cranor, 97 * October 1994, January 1995. 98 * This sun version based on i386 version 1.30. 99 */ 100 101 /* 102 * The i82586 is a very painful chip, found in sun3's, sun-4/100's 103 * sun-4/200's, and VME based suns. The byte order is all wrong for a 104 * SUN, making life difficult. Programming this chip is mostly the same, 105 * but certain details differ from system to system. This driver is 106 * written so that different "ie" interfaces can be controled by the same 107 * driver. 108 */ 109 110 /* 111 Mode of operation: 112 113 We run the 82586 in a standard Ethernet mode. We keep NFRAMES 114 received frame descriptors around for the receiver to use, and 115 NRXBUF associated receive buffer descriptors, both in a circular 116 list. Whenever a frame is received, we rotate both lists as 117 necessary. (The 586 treats both lists as a simple queue.) We also 118 keep a transmit command around so that packets can be sent off 119 quickly. 120 121 We configure the adapter in AL-LOC = 1 mode, which means that the 122 Ethernet/802.3 MAC header is placed at the beginning of the receive 123 buffer rather than being split off into various fields in the RFD. 124 This also means that we must include this header in the transmit 125 buffer as well. 126 127 By convention, all transmit commands, and only transmit commands, 128 shall have the I (IE_CMD_INTR) bit set in the command. This way, 129 when an interrupt arrives at i82586_intr(), it is immediately possible 130 to tell what precisely caused it. ANY OTHER command-sending 131 routines should run at splnet(), and should post an acknowledgement 132 to every interrupt they generate. 133 134 To save the expense of shipping a command to 82586 every time we 135 want to send a frame, we use a linked list of commands consisting 136 of alternate XMIT and NOP commands. The links of these elements 137 are manipulated (in iexmit()) such that the NOP command loops back 138 to itself whenever the following XMIT command is not yet ready to 139 go. Whenever an XMIT is ready, the preceding NOP link is pointed 140 at it, while its own link field points to the following NOP command. 141 Thus, a single transmit command sets off an interlocked traversal 142 of the xmit command chain, with the host processor in control of 143 the synchronization. 144 */ 145 146 #include <sys/cdefs.h> 147 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.42 2001/11/26 23:30:59 fredette Exp $"); 148 149 #include "bpfilter.h" 150 151 #include <sys/cdefs.h> 152 __KERNEL_RCSID(0, "$NetBSD: i82586.c,v 1.42 2001/11/26 23:30:59 fredette Exp $"); 153 154 #include <sys/param.h> 155 #include <sys/systm.h> 156 #include <sys/mbuf.h> 157 #include <sys/socket.h> 158 #include <sys/ioctl.h> 159 #include <sys/errno.h> 160 #include <sys/syslog.h> 161 #include <sys/device.h> 162 163 #include <net/if.h> 164 #include <net/if_dl.h> 165 #include <net/if_types.h> 166 #include <net/if_media.h> 167 #include <net/if_ether.h> 168 169 #if NBPFILTER > 0 170 #include <net/bpf.h> 171 #include <net/bpfdesc.h> 172 #endif 173 174 #include <machine/bus.h> 175 176 #include <dev/ic/i82586reg.h> 177 #include <dev/ic/i82586var.h> 178 179 void i82586_reset __P((struct ie_softc *, int)); 180 void i82586_watchdog __P((struct ifnet *)); 181 int i82586_init __P((struct ifnet *)); 182 int i82586_ioctl __P((struct ifnet *, u_long, caddr_t)); 183 void i82586_start __P((struct ifnet *)); 184 void i82586_stop __P((struct ifnet *, int)); 185 186 187 int i82586_rint __P((struct ie_softc *, int)); 188 int i82586_tint __P((struct ie_softc *, int)); 189 190 int i82586_mediachange __P((struct ifnet *)); 191 void i82586_mediastatus __P((struct ifnet *, 192 struct ifmediareq *)); 193 194 static int ie_readframe __P((struct ie_softc *, int)); 195 static struct mbuf *ieget __P((struct ie_softc *, int, int)); 196 static int i82586_get_rbd_list __P((struct ie_softc *, 197 u_int16_t *, u_int16_t *, int *)); 198 static void i82586_release_rbd_list __P((struct ie_softc *, 199 u_int16_t, u_int16_t)); 200 static int i82586_drop_frames __P((struct ie_softc *)); 201 static int i82586_chk_rx_ring __P((struct ie_softc *)); 202 203 static __inline__ void ie_ack __P((struct ie_softc *, u_int)); 204 static __inline__ void iexmit __P((struct ie_softc *)); 205 static void i82586_start_transceiver 206 __P((struct ie_softc *)); 207 208 static void i82586_count_errors __P((struct ie_softc *)); 209 static void i82586_rx_errors __P((struct ie_softc *, int, int)); 210 static void i82586_setup_bufs __P((struct ie_softc *)); 211 static void setup_simple_command __P((struct ie_softc *, int, int)); 212 static int ie_cfg_setup __P((struct ie_softc *, int, int, int)); 213 static int ie_ia_setup __P((struct ie_softc *, int)); 214 static void ie_run_tdr __P((struct ie_softc *, int)); 215 static int ie_mc_setup __P((struct ie_softc *, int)); 216 static void ie_mc_reset __P((struct ie_softc *)); 217 static int i82586_start_cmd __P((struct ie_softc *, 218 int, int, int, int)); 219 static int i82586_cmd_wait __P((struct ie_softc *)); 220 221 #if I82586_DEBUG 222 void print_rbd __P((struct ie_softc *, int)); 223 #endif 224 225 226 /* 227 * Front-ends call this function to attach to the MI driver. 228 * 229 * The front-end has responsibility for managing the ICP and ISCP 230 * structures. Both of these are opaque to us. Also, the front-end 231 * chooses a location for the SCB which is expected to be addressable 232 * (through `sc->scb') as an offset against the shared-memory bus handle. 233 * 234 * The following MD interface function must be setup by the front-end 235 * before calling here: 236 * 237 * hwreset - board dependent reset 238 * hwinit - board dependent initialization 239 * chan_attn - channel attention 240 * intrhook - board dependent interrupt processing 241 * memcopyin - shared memory copy: board to KVA 242 * memcopyout - shared memory copy: KVA to board 243 * ie_bus_read16 - read a sixteen-bit i82586 pointer 244 * ie_bus_write16 - write a sixteen-bit i82586 pointer 245 * ie_bus_write24 - write a twenty-four-bit i82586 pointer 246 * 247 */ 248 void 249 i82586_attach(sc, name, etheraddr, media, nmedia, defmedia) 250 struct ie_softc *sc; 251 char *name; 252 u_int8_t *etheraddr; 253 int *media, nmedia, defmedia; 254 { 255 int i; 256 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 257 258 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 259 ifp->if_softc = sc; 260 ifp->if_start = i82586_start; 261 ifp->if_ioctl = i82586_ioctl; 262 ifp->if_init = i82586_init; 263 ifp->if_stop = i82586_stop; 264 ifp->if_watchdog = i82586_watchdog; 265 ifp->if_flags = 266 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 267 IFQ_SET_READY(&ifp->if_snd); 268 269 /* Initialize media goo. */ 270 ifmedia_init(&sc->sc_media, 0, i82586_mediachange, i82586_mediastatus); 271 if (media != NULL) { 272 for (i = 0; i < nmedia; i++) 273 ifmedia_add(&sc->sc_media, media[i], 0, NULL); 274 ifmedia_set(&sc->sc_media, defmedia); 275 } else { 276 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 277 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); 278 } 279 280 /* Attach the interface. */ 281 if_attach(ifp); 282 ether_ifattach(ifp, etheraddr); 283 284 printf(" address %s, type %s\n", ether_sprintf(etheraddr), name); 285 } 286 287 288 /* 289 * Device timeout/watchdog routine. 290 * Entered if the device neglects to generate an interrupt after a 291 * transmit has been started on it. 292 */ 293 void 294 i82586_watchdog(ifp) 295 struct ifnet *ifp; 296 { 297 struct ie_softc *sc = ifp->if_softc; 298 299 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 300 ++ifp->if_oerrors; 301 302 i82586_reset(sc, 1); 303 } 304 305 static int 306 i82586_cmd_wait(sc) 307 struct ie_softc *sc; 308 { 309 /* spin on i82586 command acknowledge; wait at most 0.9 (!) seconds */ 310 int i, off; 311 u_int16_t cmd; 312 313 for (i = 0; i < 900000; i++) { 314 /* Read the command word */ 315 off = IE_SCB_CMD(sc->scb); 316 317 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 318 if ((cmd = sc->ie_bus_read16(sc, off)) == 0) 319 return (0); 320 delay(1); 321 } 322 323 off = IE_SCB_STATUS(sc->scb); 324 printf("i82586_cmd_wait: timo(%ssync): scb status: 0x%x, cmd: 0x%x\n", 325 sc->async_cmd_inprogress?"a":"", 326 sc->ie_bus_read16(sc, off), cmd); 327 328 return (1); /* Timeout */ 329 } 330 331 /* 332 * Send a command to the controller and wait for it to either complete 333 * or be accepted, depending on the command. If the command pointer 334 * is null, then pretend that the command is not an action command. 335 * If the command pointer is not null, and the command is an action 336 * command, wait for one of the MASK bits to turn on in the command's 337 * status field. 338 * If ASYNC is set, we just call the chip's attention and return. 339 * We may have to wait for the command's acceptance later though. 340 */ 341 static int 342 i82586_start_cmd(sc, cmd, iecmdbuf, mask, async) 343 struct ie_softc *sc; 344 int cmd; 345 int iecmdbuf; 346 int mask; 347 int async; 348 { 349 int i; 350 int off; 351 352 if (sc->async_cmd_inprogress != 0) { 353 /* 354 * If previous command was issued asynchronously, wait 355 * for it now. 356 */ 357 if (i82586_cmd_wait(sc) != 0) 358 return (1); 359 sc->async_cmd_inprogress = 0; 360 } 361 362 off = IE_SCB_CMD(sc->scb); 363 sc->ie_bus_write16(sc, off, cmd); 364 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE); 365 (sc->chan_attn)(sc, CARD_RESET); 366 367 if (async != 0) { 368 sc->async_cmd_inprogress = 1; 369 return (0); 370 } 371 372 if (IE_ACTION_COMMAND(cmd) && iecmdbuf) { 373 int status; 374 /* 375 * Now spin-lock waiting for status. This is not a very nice 376 * thing to do, and can kill performance pretty well... 377 * According to the packet driver, the minimum timeout 378 * should be .369 seconds. 379 */ 380 for (i = 0; i < 369000; i++) { 381 /* Read the command status */ 382 off = IE_CMD_COMMON_STATUS(iecmdbuf); 383 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 384 status = sc->ie_bus_read16(sc, off); 385 if (status & mask) 386 return (0); 387 delay(1); 388 } 389 390 } else { 391 /* 392 * Otherwise, just wait for the command to be accepted. 393 */ 394 return (i82586_cmd_wait(sc)); 395 } 396 397 /* Timeout */ 398 return (1); 399 } 400 401 /* 402 * Interrupt Acknowledge. 403 */ 404 static __inline__ void 405 ie_ack(sc, mask) 406 struct ie_softc *sc; 407 u_int mask; /* in native byte-order */ 408 { 409 u_int status; 410 411 IE_BUS_BARRIER(sc, 0, 0, BUS_SPACE_BARRIER_READ); 412 status = sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb)); 413 i82586_start_cmd(sc, status & mask, 0, 0, 0); 414 if (sc->intrhook) 415 sc->intrhook(sc, INTR_ACK); 416 } 417 418 /* 419 * Transfer accumulated chip error counters to IF. 420 */ 421 static __inline void 422 i82586_count_errors(sc) 423 struct ie_softc *sc; 424 { 425 int scb = sc->scb; 426 427 sc->sc_ethercom.ec_if.if_ierrors += 428 sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) + 429 sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) + 430 sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) + 431 sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb)); 432 433 /* Clear error counters */ 434 sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0); 435 sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0); 436 sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0); 437 sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0); 438 } 439 440 static void 441 i82586_rx_errors(sc, fn, status) 442 struct ie_softc *sc; 443 int fn; 444 int status; 445 { 446 char bits[128]; 447 448 log(LOG_ERR, "%s: rx error (frame# %d): %s\n", sc->sc_dev.dv_xname, fn, 449 bitmask_snprintf(status, IE_FD_STATUSBITS, bits, sizeof(bits))); 450 } 451 452 /* 453 * i82586 interrupt entry point. 454 */ 455 int 456 i82586_intr(v) 457 void *v; 458 { 459 struct ie_softc *sc = v; 460 u_int status; 461 int off; 462 463 /* 464 * Implementation dependent interrupt handling. 465 */ 466 if (sc->intrhook) 467 (sc->intrhook)(sc, INTR_ENTER); 468 469 off = IE_SCB_STATUS(sc->scb); 470 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 471 status = sc->ie_bus_read16(sc, off) & IE_ST_WHENCE; 472 473 if ((status & IE_ST_WHENCE) == 0) { 474 if (sc->intrhook) 475 (sc->intrhook)(sc, INTR_EXIT); 476 477 return (0); 478 } 479 480 loop: 481 /* Ack interrupts FIRST in case we receive more during the ISR. */ 482 #if 0 483 ie_ack(sc, status & IE_ST_WHENCE); 484 #endif 485 i82586_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, 1); 486 487 if (status & (IE_ST_FR | IE_ST_RNR)) 488 if (i82586_rint(sc, status) != 0) 489 goto reset; 490 491 if (status & IE_ST_CX) 492 if (i82586_tint(sc, status) != 0) 493 goto reset; 494 495 #if I82586_DEBUG 496 if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA)) 497 printf("%s: cna; status=0x%x\n", sc->sc_dev.dv_xname, status); 498 #endif 499 if (sc->intrhook) 500 (sc->intrhook)(sc, INTR_LOOP); 501 502 /* 503 * Interrupt ACK was posted asynchronously; wait for 504 * completion here before reading SCB status again. 505 * 506 * If ACK fails, try to reset the chip, in hopes that 507 * it helps. 508 */ 509 if (i82586_cmd_wait(sc) != 0) 510 goto reset; 511 512 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 513 status = sc->ie_bus_read16(sc, off); 514 if ((status & IE_ST_WHENCE) != 0) 515 goto loop; 516 517 out: 518 if (sc->intrhook) 519 (sc->intrhook)(sc, INTR_EXIT); 520 return (1); 521 522 reset: 523 i82586_cmd_wait(sc); 524 i82586_reset(sc, 1); 525 goto out; 526 527 } 528 529 /* 530 * Process a received-frame interrupt. 531 */ 532 int 533 i82586_rint(sc, scbstatus) 534 struct ie_softc *sc; 535 int scbstatus; 536 { 537 static int timesthru = 1024; 538 int i, status, off; 539 540 #if I82586_DEBUG 541 if (sc->sc_debug & IED_RINT) 542 printf("%s: rint: status 0x%x\n", 543 sc->sc_dev.dv_xname, scbstatus); 544 #endif 545 546 for (;;) { 547 int drop = 0; 548 549 i = sc->rfhead; 550 off = IE_RFRAME_STATUS(sc->rframes, i); 551 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 552 status = sc->ie_bus_read16(sc, off); 553 554 #if I82586_DEBUG 555 if (sc->sc_debug & IED_RINT) 556 printf("%s: rint: frame(%d) status 0x%x\n", 557 sc->sc_dev.dv_xname, i, status); 558 #endif 559 if ((status & IE_FD_COMPLETE) == 0) { 560 if ((status & IE_FD_OK) != 0) { 561 printf("%s: rint: weird: ", 562 sc->sc_dev.dv_xname); 563 i82586_rx_errors(sc, i, status); 564 break; 565 } 566 if (--timesthru == 0) { 567 /* Account the accumulated errors */ 568 i82586_count_errors(sc); 569 timesthru = 1024; 570 } 571 break; 572 } else if ((status & IE_FD_OK) == 0) { 573 /* 574 * If the chip is configured to automatically 575 * discard bad frames, the only reason we can 576 * get here is an "out-of-resource" condition. 577 */ 578 i82586_rx_errors(sc, i, status); 579 drop = 1; 580 } 581 582 #if I82586_DEBUG 583 if ((status & IE_FD_BUSY) != 0) 584 printf("%s: rint: frame(%d) busy; status=0x%x\n", 585 sc->sc_dev.dv_xname, i, status); 586 #endif 587 588 589 /* 590 * Advance the RFD list, since we're done with 591 * this descriptor. 592 */ 593 594 /* Clear frame status */ 595 sc->ie_bus_write16(sc, off, 0); 596 597 /* Put fence at this frame (the head) */ 598 off = IE_RFRAME_LAST(sc->rframes, i); 599 sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP); 600 601 /* and clear RBD field */ 602 off = IE_RFRAME_BUFDESC(sc->rframes, i); 603 sc->ie_bus_write16(sc, off, 0xffff); 604 605 /* Remove fence from current tail */ 606 off = IE_RFRAME_LAST(sc->rframes, sc->rftail); 607 sc->ie_bus_write16(sc, off, 0); 608 609 if (++sc->rftail == sc->nframes) 610 sc->rftail = 0; 611 if (++sc->rfhead == sc->nframes) 612 sc->rfhead = 0; 613 614 /* Pull the frame off the board */ 615 if (drop) { 616 i82586_drop_frames(sc); 617 if ((status & IE_FD_RNR) != 0) 618 sc->rnr_expect = 1; 619 sc->sc_ethercom.ec_if.if_ierrors++; 620 } else if (ie_readframe(sc, i) != 0) 621 return (1); 622 } 623 624 if ((scbstatus & IE_ST_RNR) != 0) { 625 626 /* 627 * Receiver went "Not Ready". We try to figure out 628 * whether this was an expected event based on past 629 * frame status values. 630 */ 631 632 if ((scbstatus & IE_RUS_SUSPEND) != 0) { 633 /* 634 * We use the "suspend on last frame" flag. 635 * Send a RU RESUME command in response, since 636 * we should have dealt with all completed frames 637 * by now. 638 */ 639 printf("RINT: SUSPENDED; scbstatus=0x%x\n", 640 scbstatus); 641 if (i82586_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0) 642 return (0); 643 printf("%s: RU RESUME command timed out\n", 644 sc->sc_dev.dv_xname); 645 return (1); /* Ask for a reset */ 646 } 647 648 if (sc->rnr_expect != 0) { 649 /* 650 * The RNR condition was announced in the previously 651 * completed frame. Assume the receive ring is Ok, 652 * so restart the receiver without further delay. 653 */ 654 i82586_start_transceiver(sc); 655 sc->rnr_expect = 0; 656 return (0); 657 658 } else if ((scbstatus & IE_RUS_NOSPACE) != 0) { 659 /* 660 * We saw no previous IF_FD_RNR flag. 661 * We check our ring invariants and, if ok, 662 * just restart the receiver at the current 663 * point in the ring. 664 */ 665 if (i82586_chk_rx_ring(sc) != 0) 666 return (1); 667 668 i82586_start_transceiver(sc); 669 sc->sc_ethercom.ec_if.if_ierrors++; 670 return (0); 671 } else 672 printf("%s: receiver not ready; scbstatus=0x%x\n", 673 sc->sc_dev.dv_xname, scbstatus); 674 675 sc->sc_ethercom.ec_if.if_ierrors++; 676 return (1); /* Ask for a reset */ 677 } 678 679 return (0); 680 } 681 682 /* 683 * Process a command-complete interrupt. These are only generated by the 684 * transmission of frames. This routine is deceptively simple, since most 685 * of the real work is done by i82586_start(). 686 */ 687 int 688 i82586_tint(sc, scbstatus) 689 struct ie_softc *sc; 690 int scbstatus; 691 { 692 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 693 int status; 694 695 ifp->if_timer = 0; 696 ifp->if_flags &= ~IFF_OACTIVE; 697 698 #if I82586_DEBUG 699 if (sc->xmit_busy <= 0) { 700 printf("i82586_tint: WEIRD: xmit_busy=%d, xctail=%d, xchead=%d\n", 701 sc->xmit_busy, sc->xctail, sc->xchead); 702 return (0); 703 } 704 #endif 705 706 status = sc->ie_bus_read16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, 707 sc->xctail)); 708 709 #if I82586_DEBUG 710 if (sc->sc_debug & IED_TINT) 711 printf("%s: tint: SCB status 0x%x; xmit status 0x%x\n", 712 sc->sc_dev.dv_xname, scbstatus, status); 713 #endif 714 715 if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) { 716 printf("i82586_tint: command still busy; status=0x%x; tail=%d\n", 717 status, sc->xctail); 718 printf("iestatus = 0x%x\n", scbstatus); 719 } 720 721 if (status & IE_STAT_OK) { 722 ifp->if_opackets++; 723 ifp->if_collisions += (status & IE_XS_MAXCOLL); 724 } else { 725 ifp->if_oerrors++; 726 /* 727 * Check SQE and DEFERRED? 728 * What if more than one bit is set? 729 */ 730 if (status & IE_STAT_ABORT) 731 printf("%s: send aborted\n", sc->sc_dev.dv_xname); 732 else if (status & IE_XS_NOCARRIER) 733 printf("%s: no carrier\n", sc->sc_dev.dv_xname); 734 else if (status & IE_XS_LOSTCTS) 735 printf("%s: lost CTS\n", sc->sc_dev.dv_xname); 736 else if (status & IE_XS_UNDERRUN) 737 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname); 738 else if (status & IE_XS_EXCMAX) { 739 printf("%s: too many collisions\n", 740 sc->sc_dev.dv_xname); 741 sc->sc_ethercom.ec_if.if_collisions += 16; 742 } 743 } 744 745 /* 746 * If multicast addresses were added or deleted while transmitting, 747 * ie_mc_reset() set the want_mcsetup flag indicating that we 748 * should do it. 749 */ 750 if (sc->want_mcsetup) { 751 ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail)); 752 sc->want_mcsetup = 0; 753 } 754 755 /* Done with the buffer. */ 756 sc->xmit_busy--; 757 sc->xctail = (sc->xctail + 1) % NTXBUF; 758 759 /* Start the next packet, if any, transmitting. */ 760 if (sc->xmit_busy > 0) 761 iexmit(sc); 762 763 i82586_start(ifp); 764 return (0); 765 } 766 767 /* 768 * Get a range of receive buffer descriptors that represent one packet. 769 */ 770 static int 771 i82586_get_rbd_list(sc, start, end, pktlen) 772 struct ie_softc *sc; 773 u_int16_t *start; 774 u_int16_t *end; 775 int *pktlen; 776 { 777 int off, rbbase = sc->rbds; 778 int rbindex, count = 0; 779 int plen = 0; 780 int rbdstatus; 781 782 *start = rbindex = sc->rbhead; 783 784 do { 785 off = IE_RBD_STATUS(rbbase, rbindex); 786 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 787 rbdstatus = sc->ie_bus_read16(sc, off); 788 if ((rbdstatus & IE_RBD_USED) == 0) { 789 /* 790 * This means we are somehow out of sync. So, we 791 * reset the adapter. 792 */ 793 #if I82586_DEBUG 794 print_rbd(sc, rbindex); 795 #endif 796 log(LOG_ERR, 797 "%s: receive descriptors out of sync at %d\n", 798 sc->sc_dev.dv_xname, rbindex); 799 return (0); 800 } 801 plen += (rbdstatus & IE_RBD_CNTMASK); 802 803 if (++rbindex == sc->nrxbuf) 804 rbindex = 0; 805 806 ++count; 807 } while ((rbdstatus & IE_RBD_LAST) == 0); 808 *end = rbindex; 809 *pktlen = plen; 810 return (count); 811 } 812 813 814 /* 815 * Release a range of receive buffer descriptors after we've copied the packet. 816 */ 817 static void 818 i82586_release_rbd_list(sc, start, end) 819 struct ie_softc *sc; 820 u_int16_t start; 821 u_int16_t end; 822 { 823 int off, rbbase = sc->rbds; 824 int rbindex = start; 825 826 do { 827 /* Clear buffer status */ 828 off = IE_RBD_STATUS(rbbase, rbindex); 829 sc->ie_bus_write16(sc, off, 0); 830 if (++rbindex == sc->nrxbuf) 831 rbindex = 0; 832 } while (rbindex != end); 833 834 /* Mark EOL at new tail */ 835 rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1; 836 off = IE_RBD_BUFLEN(rbbase, rbindex); 837 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL); 838 839 /* Remove EOL from current tail */ 840 off = IE_RBD_BUFLEN(rbbase, sc->rbtail); 841 sc->ie_bus_write16(sc, off, IE_RBUF_SIZE); 842 843 /* New head & tail pointer */ 844 /* hmm, why have both? head is always (tail + 1) % NRXBUF */ 845 sc->rbhead = end; 846 sc->rbtail = rbindex; 847 } 848 849 /* 850 * Drop the packet at the head of the RX buffer ring. 851 * Called if the frame descriptor reports an error on this packet. 852 * Returns 1 if the buffer descriptor ring appears to be corrupt; 853 * and 0 otherwise. 854 */ 855 static int 856 i82586_drop_frames(sc) 857 struct ie_softc *sc; 858 { 859 u_int16_t bstart, bend; 860 int pktlen; 861 862 if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) 863 return (1); 864 i82586_release_rbd_list(sc, bstart, bend); 865 return (0); 866 } 867 868 /* 869 * Check the RX frame & buffer descriptor lists for our invariants, 870 * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer. 871 * 872 * Called when the receive unit has stopped unexpectedly. 873 * Returns 1 if an inconsistency is detected; 0 otherwise. 874 * 875 * The Receive Unit is expected to be NOT RUNNING. 876 */ 877 static int 878 i82586_chk_rx_ring(sc) 879 struct ie_softc *sc; 880 { 881 int n, off, val; 882 883 for (n = 0; n < sc->nrxbuf; n++) { 884 off = IE_RBD_BUFLEN(sc->rbds, n); 885 val = sc->ie_bus_read16(sc, off); 886 if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) { 887 /* `rbtail' and EOL flag out of sync */ 888 log(LOG_ERR, 889 "%s: rx buffer descriptors out of sync at %d\n", 890 sc->sc_dev.dv_xname, n); 891 return (1); 892 } 893 894 /* Take the opportunity to clear the status fields here ? */ 895 } 896 897 for (n = 0; n < sc->nframes; n++) { 898 off = IE_RFRAME_LAST(sc->rframes, n); 899 val = sc->ie_bus_read16(sc, off); 900 if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) { 901 /* `rftail' and EOL flag out of sync */ 902 log(LOG_ERR, 903 "%s: rx frame list out of sync at %d\n", 904 sc->sc_dev.dv_xname, n); 905 return (1); 906 } 907 } 908 909 return (0); 910 } 911 912 /* 913 * Read data off the interface, and turn it into an mbuf chain. 914 * 915 * This code is DRAMATICALLY different from the previous version; this 916 * version tries to allocate the entire mbuf chain up front, given the 917 * length of the data available. This enables us to allocate mbuf 918 * clusters in many situations where before we would have had a long 919 * chain of partially-full mbufs. This should help to speed up the 920 * operation considerably. (Provided that it works, of course.) 921 */ 922 static __inline struct mbuf * 923 ieget(sc, head, totlen) 924 struct ie_softc *sc; 925 int head; 926 int totlen; 927 { 928 struct mbuf *m, *m0, *newm; 929 int len, resid; 930 int thisrboff, thismboff; 931 struct ether_header eh; 932 933 /* 934 * Snarf the Ethernet header. 935 */ 936 (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head), 937 sizeof(struct ether_header)); 938 939 resid = totlen; 940 941 MGETHDR(m0, M_DONTWAIT, MT_DATA); 942 if (m0 == 0) 943 return (0); 944 m0->m_pkthdr.rcvif = &sc->sc_ethercom.ec_if; 945 m0->m_pkthdr.len = totlen; 946 len = MHLEN; 947 m = m0; 948 949 /* 950 * This loop goes through and allocates mbufs for all the data we will 951 * be copying in. It does not actually do the copying yet. 952 */ 953 while (totlen > 0) { 954 if (totlen >= MINCLSIZE) { 955 MCLGET(m, M_DONTWAIT); 956 if ((m->m_flags & M_EXT) == 0) 957 goto bad; 958 len = MCLBYTES; 959 } 960 961 if (m == m0) { 962 caddr_t newdata = (caddr_t) 963 ALIGN(m->m_data + sizeof(struct ether_header)) - 964 sizeof(struct ether_header); 965 len -= newdata - m->m_data; 966 m->m_data = newdata; 967 } 968 969 m->m_len = len = min(totlen, len); 970 971 totlen -= len; 972 if (totlen > 0) { 973 MGET(newm, M_DONTWAIT, MT_DATA); 974 if (newm == 0) 975 goto bad; 976 len = MLEN; 977 m = m->m_next = newm; 978 } 979 } 980 981 m = m0; 982 thismboff = 0; 983 984 /* 985 * Copy the Ethernet header into the mbuf chain. 986 */ 987 memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header)); 988 thismboff = sizeof(struct ether_header); 989 thisrboff = sizeof(struct ether_header); 990 resid -= sizeof(struct ether_header); 991 992 /* 993 * Now we take the mbuf chain (hopefully only one mbuf most of the 994 * time) and stuff the data into it. There are no possible failures 995 * at or after this point. 996 */ 997 while (resid > 0) { 998 int thisrblen = IE_RBUF_SIZE - thisrboff, 999 thismblen = m->m_len - thismboff; 1000 len = min(thisrblen, thismblen); 1001 1002 (sc->memcopyin)(sc, mtod(m, caddr_t) + thismboff, 1003 IE_RBUF_ADDR(sc,head) + thisrboff, 1004 (u_int)len); 1005 resid -= len; 1006 1007 if (len == thismblen) { 1008 m = m->m_next; 1009 thismboff = 0; 1010 } else 1011 thismboff += len; 1012 1013 if (len == thisrblen) { 1014 if (++head == sc->nrxbuf) 1015 head = 0; 1016 thisrboff = 0; 1017 } else 1018 thisrboff += len; 1019 } 1020 1021 /* 1022 * Unless something changed strangely while we were doing the copy, 1023 * we have now copied everything in from the shared memory. 1024 * This means that we are done. 1025 */ 1026 return (m0); 1027 1028 bad: 1029 m_freem(m0); 1030 return (0); 1031 } 1032 1033 /* 1034 * Read frame NUM from unit UNIT (pre-cached as IE). 1035 * 1036 * This routine reads the RFD at NUM, and copies in the buffers from the list 1037 * of RBD, then rotates the RBD list so that the receiver doesn't start 1038 * complaining. Trailers are DROPPED---there's no point in wasting time 1039 * on confusing code to deal with them. Hopefully, this machine will 1040 * never ARP for trailers anyway. 1041 */ 1042 static int 1043 ie_readframe(sc, num) 1044 struct ie_softc *sc; 1045 int num; /* frame number to read */ 1046 { 1047 struct mbuf *m; 1048 u_int16_t bstart, bend; 1049 int pktlen; 1050 1051 if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) { 1052 sc->sc_ethercom.ec_if.if_ierrors++; 1053 return (1); 1054 } 1055 1056 m = ieget(sc, bstart, pktlen); 1057 i82586_release_rbd_list(sc, bstart, bend); 1058 1059 if (m == 0) { 1060 sc->sc_ethercom.ec_if.if_ierrors++; 1061 return (0); 1062 } 1063 1064 #if I82586_DEBUG 1065 if (sc->sc_debug & IED_READFRAME) { 1066 struct ether_header *eh = mtod(m, struct ether_header *); 1067 1068 printf("%s: frame from ether %s type 0x%x len %d\n", 1069 sc->sc_dev.dv_xname, 1070 ether_sprintf(eh->ether_shost), 1071 (u_int)ntohs(eh->ether_type), 1072 pktlen); 1073 } 1074 #endif 1075 1076 #if NBPFILTER > 0 1077 /* Check for a BPF filter; if so, hand it up. */ 1078 if (sc->sc_ethercom.ec_if.if_bpf != 0) 1079 /* Pass it up. */ 1080 bpf_mtap(sc->sc_ethercom.ec_if.if_bpf, m); 1081 #endif /* NBPFILTER > 0 */ 1082 1083 /* 1084 * Finally pass this packet up to higher layers. 1085 */ 1086 (*sc->sc_ethercom.ec_if.if_input)(&sc->sc_ethercom.ec_if, m); 1087 sc->sc_ethercom.ec_if.if_ipackets++; 1088 return (0); 1089 } 1090 1091 1092 /* 1093 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT 1094 * command to the chip to be executed. 1095 */ 1096 static __inline__ void 1097 iexmit(sc) 1098 struct ie_softc *sc; 1099 { 1100 int off; 1101 int cur, prev; 1102 1103 cur = sc->xctail; 1104 1105 #if I82586_DEBUG 1106 if (sc->sc_debug & IED_XMIT) 1107 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, cur); 1108 #endif 1109 1110 /* 1111 * Setup the transmit command. 1112 */ 1113 sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur), 1114 IE_XBD_ADDR(sc->xbds, cur)); 1115 1116 sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0); 1117 1118 if (sc->do_xmitnopchain) { 1119 /* 1120 * Gate this XMIT command to the following NOP 1121 */ 1122 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur), 1123 IE_CMD_NOP_ADDR(sc->nop_cmds, cur)); 1124 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur), 1125 IE_CMD_XMIT | IE_CMD_INTR); 1126 1127 /* 1128 * Loopback at following NOP 1129 */ 1130 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0); 1131 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur), 1132 IE_CMD_NOP_ADDR(sc->nop_cmds, cur)); 1133 1134 /* 1135 * Gate preceding NOP to this XMIT command 1136 */ 1137 prev = (cur + NTXBUF - 1) % NTXBUF; 1138 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0); 1139 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev), 1140 IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur)); 1141 1142 off = IE_SCB_STATUS(sc->scb); 1143 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 1144 if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) { 1145 printf("iexmit: CU not active\n"); 1146 i82586_start_transceiver(sc); 1147 } 1148 } else { 1149 sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur), 1150 0xffff); 1151 1152 sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur), 1153 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST); 1154 1155 off = IE_SCB_CMDLST(sc->scb); 1156 sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur)); 1157 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 1158 1159 if (i82586_start_cmd(sc, IE_CUC_START, 0, 0, 1)) 1160 printf("%s: iexmit: start xmit command timed out\n", 1161 sc->sc_dev.dv_xname); 1162 } 1163 1164 sc->sc_ethercom.ec_if.if_timer = 5; 1165 } 1166 1167 1168 /* 1169 * Start transmission on an interface. 1170 */ 1171 void 1172 i82586_start(ifp) 1173 struct ifnet *ifp; 1174 { 1175 struct ie_softc *sc = ifp->if_softc; 1176 struct mbuf *m0, *m; 1177 int buffer, head, xbase; 1178 u_short len; 1179 int s; 1180 1181 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1182 return; 1183 1184 for (;;) { 1185 if (sc->xmit_busy == NTXBUF) { 1186 ifp->if_flags |= IFF_OACTIVE; 1187 break; 1188 } 1189 1190 head = sc->xchead; 1191 xbase = sc->xbds; 1192 1193 IFQ_DEQUEUE(&ifp->if_snd, m0); 1194 if (m0 == 0) 1195 break; 1196 1197 /* We need to use m->m_pkthdr.len, so require the header */ 1198 if ((m0->m_flags & M_PKTHDR) == 0) 1199 panic("i82586_start: no header mbuf"); 1200 1201 #if NBPFILTER > 0 1202 /* Tap off here if there is a BPF listener. */ 1203 if (ifp->if_bpf) 1204 bpf_mtap(ifp->if_bpf, m0); 1205 #endif 1206 1207 #if I82586_DEBUG 1208 if (sc->sc_debug & IED_ENQ) 1209 printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname, 1210 sc->xchead); 1211 #endif 1212 1213 if (m0->m_pkthdr.len > IE_TBUF_SIZE) 1214 printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname); 1215 1216 buffer = IE_XBUF_ADDR(sc, head); 1217 for (m = m0; m != 0; m = m->m_next) { 1218 (sc->memcopyout)(sc, mtod(m,caddr_t), buffer, m->m_len); 1219 buffer += m->m_len; 1220 } 1221 1222 len = max(m0->m_pkthdr.len, ETHER_MIN_LEN); 1223 m_freem(m0); 1224 1225 /* 1226 * Setup the transmit buffer descriptor here, while we 1227 * know the packet's length. 1228 */ 1229 sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head), 1230 len | IE_TBD_EOL); 1231 sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff); 1232 sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head), 1233 IE_XBUF_ADDR(sc, head)); 1234 1235 if (++head == NTXBUF) 1236 head = 0; 1237 sc->xchead = head; 1238 1239 s = splnet(); 1240 /* Start the first packet transmitting. */ 1241 if (sc->xmit_busy == 0) 1242 iexmit(sc); 1243 1244 sc->xmit_busy++; 1245 splx(s); 1246 } 1247 } 1248 1249 /* 1250 * Probe IE's ram setup [ Move all this into MD front-end!? ] 1251 * Use only if SCP and ISCP represent offsets into shared ram space. 1252 */ 1253 int 1254 i82586_proberam(sc) 1255 struct ie_softc *sc; 1256 { 1257 int result, off; 1258 1259 /* Put in 16-bit mode */ 1260 off = IE_SCP_BUS_USE(sc->scp); 1261 sc->ie_bus_write16(sc, off, IE_SYSBUS_16BIT); 1262 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE); 1263 1264 /* Set the ISCP `busy' bit */ 1265 off = IE_ISCP_BUSY(sc->iscp); 1266 sc->ie_bus_write16(sc, off, 1); 1267 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE); 1268 1269 if (sc->hwreset) 1270 (sc->hwreset)(sc, CHIP_PROBE); 1271 1272 (sc->chan_attn) (sc, CHIP_PROBE); 1273 1274 delay(100); /* wait a while... */ 1275 1276 /* Read back the ISCP `busy' bit; it should be clear by now */ 1277 off = IE_ISCP_BUSY(sc->iscp); 1278 IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ); 1279 result = sc->ie_bus_read16(sc, off) == 0; 1280 1281 /* Acknowledge any interrupts we may have caused. */ 1282 ie_ack(sc, IE_ST_WHENCE); 1283 1284 return (result); 1285 } 1286 1287 void 1288 i82586_reset(sc, hard) 1289 struct ie_softc *sc; 1290 int hard; 1291 { 1292 int s = splnet(); 1293 1294 if (hard) 1295 printf("%s: reset\n", sc->sc_dev.dv_xname); 1296 1297 /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */ 1298 sc->sc_ethercom.ec_if.if_timer = 0; 1299 sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 1300 1301 /* 1302 * Stop i82586 dead in its tracks. 1303 */ 1304 if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0)) 1305 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname); 1306 1307 /* 1308 * This can really slow down the i82586_reset() on some cards, but it's 1309 * necessary to unwedge other ones (eg, the Sun VME ones) from certain 1310 * lockups. 1311 */ 1312 if (hard && sc->hwreset) 1313 (sc->hwreset)(sc, CARD_RESET); 1314 1315 delay(100); 1316 ie_ack(sc, IE_ST_WHENCE); 1317 1318 if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) { 1319 int retries=0; /* XXX - find out why init sometimes fails */ 1320 while (retries++ < 2) 1321 if (i82586_init(&sc->sc_ethercom.ec_if) == 0) 1322 break; 1323 } 1324 1325 splx(s); 1326 } 1327 1328 1329 static void 1330 setup_simple_command(sc, cmd, cmdbuf) 1331 struct ie_softc *sc; 1332 int cmd; 1333 int cmdbuf; 1334 { 1335 /* Setup a simple command */ 1336 sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0); 1337 sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST); 1338 sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff); 1339 1340 /* Assign the command buffer to the SCB command list */ 1341 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf); 1342 } 1343 1344 /* 1345 * Run the time-domain reflectometer. 1346 */ 1347 static void 1348 ie_run_tdr(sc, cmd) 1349 struct ie_softc *sc; 1350 int cmd; 1351 { 1352 int result; 1353 1354 setup_simple_command(sc, IE_CMD_TDR, cmd); 1355 sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0); 1356 1357 if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) || 1358 (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0) 1359 result = 0x10000; /* XXX */ 1360 else 1361 result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd)); 1362 1363 /* Squash any pending interrupts */ 1364 ie_ack(sc, IE_ST_WHENCE); 1365 1366 if (result & IE_TDR_SUCCESS) 1367 return; 1368 1369 if (result & 0x10000) 1370 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname); 1371 else if (result & IE_TDR_XCVR) 1372 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname); 1373 else if (result & IE_TDR_OPEN) 1374 printf("%s: TDR detected incorrect termination %d clocks away\n", 1375 sc->sc_dev.dv_xname, result & IE_TDR_TIME); 1376 else if (result & IE_TDR_SHORT) 1377 printf("%s: TDR detected a short circuit %d clocks away\n", 1378 sc->sc_dev.dv_xname, result & IE_TDR_TIME); 1379 else 1380 printf("%s: TDR returned unknown status 0x%x\n", 1381 sc->sc_dev.dv_xname, result); 1382 } 1383 1384 1385 /* 1386 * i82586_setup_bufs: set up the buffers 1387 * 1388 * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz. 1389 * this is to be used for the buffers. The chip indexs its control data 1390 * structures with 16 bit offsets, and it indexes actual buffers with 1391 * 24 bit addresses. So we should allocate control buffers first so that 1392 * we don't overflow the 16 bit offset field. The number of transmit 1393 * buffers is fixed at compile time. 1394 * 1395 */ 1396 static void 1397 i82586_setup_bufs(sc) 1398 struct ie_softc *sc; 1399 { 1400 int ptr = sc->buf_area; /* memory pool */ 1401 int n, r; 1402 1403 /* 1404 * step 0: zero memory and figure out how many recv buffers and 1405 * frames we can have. 1406 */ 1407 ptr = (ptr + 3) & ~3; /* set alignment and stick with it */ 1408 1409 1410 /* 1411 * step 1: lay out data structures in the shared-memory area 1412 */ 1413 1414 /* The no-op commands; used if "nop-chaining" is in effect */ 1415 sc->nop_cmds = ptr; 1416 ptr += NTXBUF * IE_CMD_NOP_SZ; 1417 1418 /* The transmit commands */ 1419 sc->xmit_cmds = ptr; 1420 ptr += NTXBUF * IE_CMD_XMIT_SZ; 1421 1422 /* The transmit buffers descriptors */ 1423 sc->xbds = ptr; 1424 ptr += NTXBUF * IE_XBD_SZ; 1425 1426 /* The transmit buffers */ 1427 sc->xbufs = ptr; 1428 ptr += NTXBUF * IE_TBUF_SIZE; 1429 1430 ptr = (ptr + 3) & ~3; /* re-align.. just in case */ 1431 1432 /* Compute free space for RECV stuff */ 1433 n = sc->buf_area_sz - (ptr - sc->buf_area); 1434 1435 /* Compute size of one RECV frame */ 1436 r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F); 1437 1438 sc->nframes = n / r; 1439 1440 if (sc->nframes <= 0) 1441 panic("ie: bogus buffer calc\n"); 1442 1443 sc->nrxbuf = sc->nframes * B_PER_F; 1444 1445 /* The receice frame descriptors */ 1446 sc->rframes = ptr; 1447 ptr += sc->nframes * IE_RFRAME_SZ; 1448 1449 /* The receive buffer descriptors */ 1450 sc->rbds = ptr; 1451 ptr += sc->nrxbuf * IE_RBD_SZ; 1452 1453 /* The receive buffers */ 1454 sc->rbufs = ptr; 1455 ptr += sc->nrxbuf * IE_RBUF_SIZE; 1456 1457 #if I82586_DEBUG 1458 printf("%s: %d frames %d bufs\n", sc->sc_dev.dv_xname, sc->nframes, 1459 sc->nrxbuf); 1460 #endif 1461 1462 /* 1463 * step 2: link together the recv frames and set EOL on last one 1464 */ 1465 for (n = 0; n < sc->nframes; n++) { 1466 int m = (n == sc->nframes - 1) ? 0 : n + 1; 1467 1468 /* Clear status */ 1469 sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0); 1470 1471 /* RBD link = NULL */ 1472 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n), 1473 0xffff); 1474 1475 /* Make a circular list */ 1476 sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n), 1477 IE_RFRAME_ADDR(sc->rframes,m)); 1478 1479 /* Mark last as EOL */ 1480 sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n), 1481 ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0)); 1482 } 1483 1484 /* 1485 * step 3: link the RBDs and set EOL on last one 1486 */ 1487 for (n = 0; n < sc->nrxbuf; n++) { 1488 int m = (n == sc->nrxbuf - 1) ? 0 : n + 1; 1489 1490 /* Clear status */ 1491 sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0); 1492 1493 /* Make a circular list */ 1494 sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n), 1495 IE_RBD_ADDR(sc->rbds,m)); 1496 1497 /* Link to data buffers */ 1498 sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n), 1499 IE_RBUF_ADDR(sc, n)); 1500 sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n), 1501 IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0)); 1502 } 1503 1504 /* 1505 * step 4: all xmit no-op commands loopback onto themselves 1506 */ 1507 for (n = 0; n < NTXBUF; n++) { 1508 sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0); 1509 1510 sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n), 1511 IE_CMD_NOP); 1512 1513 sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n), 1514 IE_CMD_NOP_ADDR(sc->nop_cmds, n)); 1515 } 1516 1517 1518 /* 1519 * step 6: set the head and tail pointers on receive to keep track of 1520 * the order in which RFDs and RBDs are used. 1521 */ 1522 1523 /* Pointers to last packet sent and next available transmit buffer. */ 1524 sc->xchead = sc->xctail = 0; 1525 1526 /* Clear transmit-busy flag and set number of free transmit buffers. */ 1527 sc->xmit_busy = 0; 1528 1529 /* 1530 * Pointers to first and last receive frame. 1531 * The RFD pointed to by rftail is the only one that has EOL set. 1532 */ 1533 sc->rfhead = 0; 1534 sc->rftail = sc->nframes - 1; 1535 1536 /* 1537 * Pointers to first and last receive descriptor buffer. 1538 * The RBD pointed to by rbtail is the only one that has EOL set. 1539 */ 1540 sc->rbhead = 0; 1541 sc->rbtail = sc->nrxbuf - 1; 1542 1543 /* link in recv frames * and buffer into the scb. */ 1544 #if I82586_DEBUG 1545 printf("%s: reserved %d bytes\n", 1546 sc->sc_dev.dv_xname, ptr - sc->buf_area); 1547 #endif 1548 } 1549 1550 static int 1551 ie_cfg_setup(sc, cmd, promiscuous, manchester) 1552 struct ie_softc *sc; 1553 int cmd; 1554 int promiscuous, manchester; 1555 { 1556 int cmdresult, status; 1557 u_int8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */ 1558 1559 *IE_CMD_CFG_CNT(buf) = 0x0c; 1560 *IE_CMD_CFG_FIFO(buf) = 8; 1561 *IE_CMD_CFG_SAVEBAD(buf) = 0x40; 1562 *IE_CMD_CFG_ADDRLEN(buf) = 0x2e; 1563 *IE_CMD_CFG_PRIORITY(buf) = 0; 1564 *IE_CMD_CFG_IFS(buf) = 0x60; 1565 *IE_CMD_CFG_SLOT_LOW(buf) = 0; 1566 *IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2; 1567 *IE_CMD_CFG_PROMISC(buf) = !!promiscuous | manchester << 2; 1568 *IE_CMD_CFG_CRSCDT(buf) = 0; 1569 *IE_CMD_CFG_MINLEN(buf) = 64; 1570 *IE_CMD_CFG_JUNK(buf) = 0xff; 1571 sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ); 1572 setup_simple_command(sc, IE_CMD_CONFIG, cmd); 1573 IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE); 1574 1575 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0); 1576 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)); 1577 if (cmdresult != 0) { 1578 printf("%s: configure command timed out; status %x\n", 1579 sc->sc_dev.dv_xname, status); 1580 return (0); 1581 } 1582 if ((status & IE_STAT_OK) == 0) { 1583 printf("%s: configure command failed; status %x\n", 1584 sc->sc_dev.dv_xname, status); 1585 return (0); 1586 } 1587 1588 /* Squash any pending interrupts */ 1589 ie_ack(sc, IE_ST_WHENCE); 1590 return (1); 1591 } 1592 1593 static int 1594 ie_ia_setup(sc, cmdbuf) 1595 struct ie_softc *sc; 1596 int cmdbuf; 1597 { 1598 int cmdresult, status; 1599 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1600 1601 setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf); 1602 1603 (sc->memcopyout)(sc, LLADDR(ifp->if_sadl), 1604 IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN); 1605 1606 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0); 1607 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf)); 1608 if (cmdresult != 0) { 1609 printf("%s: individual address command timed out; status %x\n", 1610 sc->sc_dev.dv_xname, status); 1611 return (0); 1612 } 1613 if ((status & IE_STAT_OK) == 0) { 1614 printf("%s: individual address command failed; status %x\n", 1615 sc->sc_dev.dv_xname, status); 1616 return (0); 1617 } 1618 1619 /* Squash any pending interrupts */ 1620 ie_ack(sc, IE_ST_WHENCE); 1621 return (1); 1622 } 1623 1624 /* 1625 * Run the multicast setup command. 1626 * Called at splnet(). 1627 */ 1628 static int 1629 ie_mc_setup(sc, cmdbuf) 1630 struct ie_softc *sc; 1631 int cmdbuf; 1632 { 1633 int cmdresult, status; 1634 1635 if (sc->mcast_count == 0) 1636 return (1); 1637 1638 setup_simple_command(sc, IE_CMD_MCAST, cmdbuf); 1639 1640 (sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs, 1641 IE_CMD_MCAST_MADDR(cmdbuf), 1642 sc->mcast_count * ETHER_ADDR_LEN); 1643 1644 sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf), 1645 sc->mcast_count * ETHER_ADDR_LEN); 1646 1647 /* Start the command */ 1648 cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0); 1649 status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf)); 1650 if (cmdresult != 0) { 1651 printf("%s: multicast setup command timed out; status %x\n", 1652 sc->sc_dev.dv_xname, status); 1653 return (0); 1654 } 1655 if ((status & IE_STAT_OK) == 0) { 1656 printf("%s: multicast setup command failed; status %x\n", 1657 sc->sc_dev.dv_xname, status); 1658 return (0); 1659 } 1660 1661 /* Squash any pending interrupts */ 1662 ie_ack(sc, IE_ST_WHENCE); 1663 return (1); 1664 } 1665 1666 /* 1667 * This routine takes the environment generated by check_ie_present() and adds 1668 * to it all the other structures we need to operate the adapter. This 1669 * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting 1670 * the receiver unit, and clearing interrupts. 1671 * 1672 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER. 1673 */ 1674 int 1675 i82586_init(ifp) 1676 struct ifnet *ifp; 1677 { 1678 struct ie_softc *sc = ifp->if_softc; 1679 int cmd; 1680 1681 sc->async_cmd_inprogress = 0; 1682 1683 cmd = sc->buf_area; 1684 1685 /* 1686 * Send the configure command first. 1687 */ 1688 if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0) 1689 return EIO; 1690 1691 /* 1692 * Send the Individual Address Setup command. 1693 */ 1694 if (ie_ia_setup(sc, cmd) == 0) 1695 return EIO; 1696 1697 /* 1698 * Run the time-domain reflectometer. 1699 */ 1700 ie_run_tdr(sc, cmd); 1701 1702 /* 1703 * Set the multi-cast filter, if any 1704 */ 1705 if (ie_mc_setup(sc, cmd) == 0) 1706 return EIO; 1707 1708 /* 1709 * Acknowledge any interrupts we have generated thus far. 1710 */ 1711 ie_ack(sc, IE_ST_WHENCE); 1712 1713 /* 1714 * Set up the transmit and recv buffers. 1715 */ 1716 i82586_setup_bufs(sc); 1717 1718 if (sc->hwinit) 1719 (sc->hwinit)(sc); 1720 1721 ifp->if_flags |= IFF_RUNNING; 1722 ifp->if_flags &= ~IFF_OACTIVE; 1723 1724 if (NTXBUF < 2) 1725 sc->do_xmitnopchain = 0; 1726 1727 i82586_start_transceiver(sc); 1728 return (0); 1729 } 1730 1731 /* 1732 * Start the RU and possibly the CU unit 1733 */ 1734 static void 1735 i82586_start_transceiver(sc) 1736 struct ie_softc *sc; 1737 { 1738 1739 /* 1740 * Start RU at current position in frame & RBD lists. 1741 */ 1742 sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead), 1743 IE_RBD_ADDR(sc->rbds, sc->rbhead)); 1744 1745 sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb), 1746 IE_RFRAME_ADDR(sc->rframes,sc->rfhead)); 1747 1748 if (sc->do_xmitnopchain) { 1749 /* Stop transmit command chain */ 1750 if (i82586_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0)) 1751 printf("%s: CU/RU stop command timed out\n", 1752 sc->sc_dev.dv_xname); 1753 1754 /* Start the receiver & transmitter chain */ 1755 /* sc->scb->ie_command_list = 1756 IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/ 1757 sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), 1758 IE_CMD_NOP_ADDR( 1759 sc->nop_cmds, 1760 (sc->xctail + NTXBUF - 1) % NTXBUF)); 1761 1762 if (i82586_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0)) 1763 printf("%s: CU/RU command timed out\n", 1764 sc->sc_dev.dv_xname); 1765 } else { 1766 if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0)) 1767 printf("%s: RU command timed out\n", 1768 sc->sc_dev.dv_xname); 1769 } 1770 } 1771 1772 void 1773 i82586_stop(ifp, disable) 1774 struct ifnet *ifp; 1775 int disable; 1776 { 1777 struct ie_softc *sc = ifp->if_softc; 1778 1779 if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0)) 1780 printf("%s: iestop: disable commands timed out\n", 1781 sc->sc_dev.dv_xname); 1782 } 1783 1784 int 1785 i82586_ioctl(ifp, cmd, data) 1786 struct ifnet *ifp; 1787 u_long cmd; 1788 caddr_t data; 1789 { 1790 struct ie_softc *sc = ifp->if_softc; 1791 struct ifreq *ifr = (struct ifreq *)data; 1792 int s, error = 0; 1793 1794 s = splnet(); 1795 switch(cmd) { 1796 case SIOCGIFMEDIA: 1797 case SIOCSIFMEDIA: 1798 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 1799 break; 1800 default: 1801 error = ether_ioctl(ifp, cmd, data); 1802 if (error == ENETRESET) { 1803 /* 1804 * Multicast list has changed; set the hardware filter 1805 * accordingly. 1806 */ 1807 ie_mc_reset(sc); 1808 error = 0; 1809 } 1810 break; 1811 } 1812 #if I82586_DEBUG 1813 if (cmd == SIOCSIFFLAGS) 1814 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0; 1815 #endif 1816 splx(s); 1817 return (error); 1818 } 1819 1820 static void 1821 ie_mc_reset(sc) 1822 struct ie_softc *sc; 1823 { 1824 struct ether_multi *enm; 1825 struct ether_multistep step; 1826 int size; 1827 1828 /* 1829 * Step through the list of addresses. 1830 */ 1831 again: 1832 size = 0; 1833 sc->mcast_count = 0; 1834 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1835 while (enm) { 1836 size += 6; 1837 if (sc->mcast_count >= IE_MAXMCAST || 1838 memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) { 1839 sc->sc_ethercom.ec_if.if_flags |= IFF_ALLMULTI; 1840 i82586_ioctl(&sc->sc_ethercom.ec_if, 1841 SIOCSIFFLAGS, (void *)0); 1842 return; 1843 } 1844 ETHER_NEXT_MULTI(step, enm); 1845 } 1846 1847 if (size > sc->mcast_addrs_size) { 1848 /* Need to allocate more space */ 1849 if (sc->mcast_addrs_size) 1850 free(sc->mcast_addrs, M_IPMADDR); 1851 sc->mcast_addrs = (char *) 1852 malloc(size, M_IPMADDR, M_WAITOK); 1853 sc->mcast_addrs_size = size; 1854 } 1855 1856 /* 1857 * We've got the space; now copy the addresses 1858 */ 1859 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1860 while (enm) { 1861 if (sc->mcast_count >= IE_MAXMCAST) 1862 goto again; /* Just in case */ 1863 1864 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6); 1865 sc->mcast_count++; 1866 ETHER_NEXT_MULTI(step, enm); 1867 } 1868 sc->want_mcsetup = 1; 1869 } 1870 1871 /* 1872 * Media change callback. 1873 */ 1874 int 1875 i82586_mediachange(ifp) 1876 struct ifnet *ifp; 1877 { 1878 struct ie_softc *sc = ifp->if_softc; 1879 1880 if (sc->sc_mediachange) 1881 return ((*sc->sc_mediachange)(sc)); 1882 return (0); 1883 } 1884 1885 /* 1886 * Media status callback. 1887 */ 1888 void 1889 i82586_mediastatus(ifp, ifmr) 1890 struct ifnet *ifp; 1891 struct ifmediareq *ifmr; 1892 { 1893 struct ie_softc *sc = ifp->if_softc; 1894 1895 if (sc->sc_mediastatus) 1896 (*sc->sc_mediastatus)(sc, ifmr); 1897 } 1898 1899 #if I82586_DEBUG 1900 void 1901 print_rbd(sc, n) 1902 struct ie_softc *sc; 1903 int n; 1904 { 1905 1906 printf("RBD at %08x:\n status %04x, next %04x, buffer %lx\n" 1907 "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n), 1908 sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)), 1909 sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)), 1910 (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */ 1911 sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n))); 1912 } 1913 #endif 1914