1 /* $NetBSD: if_ie.c,v 1.37 2001/09/05 13:55:27 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1993, 1994, 1995 Charles M. Hannum. 5 * Copyright (c) 1992, 1993, University of Vermont and State 6 * Agricultural College. 7 * Copyright (c) 1992, 1993, Garrett A. Wollman. 8 * 9 * Portions: 10 * Copyright (c) 1994, 1995, Rafal K. Boni 11 * Copyright (c) 1990, 1991, William F. Jolitz 12 * Copyright (c) 1990, The Regents of the University of California 13 * 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by Charles M. Hannum, by the 27 * University of Vermont and State Agricultural College and Garrett A. 28 * Wollman, by William F. Jolitz, and by the University of California, 29 * Berkeley, Lawrence Berkeley Laboratory, and its contributors. 30 * 4. Neither the names of the Universities nor the names of the authors 31 * may be used to endorse or promote products derived from this software 32 * without specific prior written permission. 33 * 34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE 38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44 * SUCH DAMAGE. 45 */ 46 47 /* 48 * Intel 82586 Ethernet chip 49 * Register, bit, and structure definitions. 50 * 51 * Original StarLAN driver written by Garrett Wollman with reference to the 52 * Clarkson Packet Driver code for this chip written by Russ Nelson and others. 53 * 54 * BPF support code taken from hpdev/if_le.c, supplied with tcpdump. 55 * 56 * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni. 57 * 58 * Majorly cleaned up and 3C507 code merged by Charles Hannum. 59 * 60 * Converted to SUN ie driver by Charles D. Cranor, 61 * October 1994, January 1995. 62 * This sun version based on i386 version 1.30. 63 * [ see sys/dev/isa/if_ie.c ] 64 */ 65 66 /* 67 * The i82586 is a very painful chip, found in sun3's, sun-4/100's 68 * sun-4/200's, and VME based suns. The byte order is all wrong for a 69 * SUN, making life difficult. Programming this chip is mostly the same, 70 * but certain details differ from system to system. This driver is 71 * written so that different "ie" interfaces can be controled by the same 72 * driver. 73 */ 74 75 /* 76 Mode of operation: 77 78 We run the 82586 in a standard Ethernet mode. We keep NFRAMES 79 received frame descriptors around for the receiver to use, and 80 NRXBUF associated receive buffer descriptors, both in a circular 81 list. Whenever a frame is received, we rotate both lists as 82 necessary. (The 586 treats both lists as a simple queue.) We also 83 keep a transmit command around so that packets can be sent off 84 quickly. 85 86 We configure the adapter in AL-LOC = 1 mode, which means that the 87 Ethernet/802.3 MAC header is placed at the beginning of the receive 88 buffer rather than being split off into various fields in the RFD. 89 This also means that we must include this header in the transmit 90 buffer as well. 91 92 By convention, all transmit commands, and only transmit commands, 93 shall have the I (IE_CMD_INTR) bit set in the command. This way, 94 when an interrupt arrives at ieintr(), it is immediately possible 95 to tell what precisely caused it. ANY OTHER command-sending 96 routines should run at splnet(), and should post an acknowledgement 97 to every interrupt they generate. 98 */ 99 100 #include "opt_inet.h" 101 #include "opt_ns.h" 102 #include "bpfilter.h" 103 104 #include <sys/param.h> 105 #include <sys/systm.h> 106 #include <sys/mbuf.h> 107 #include <sys/buf.h> 108 #include <sys/protosw.h> 109 #include <sys/socket.h> 110 #include <sys/ioctl.h> 111 #include <sys/errno.h> 112 #include <sys/syslog.h> 113 #include <sys/device.h> 114 115 #include <net/if.h> 116 #include <net/if_types.h> 117 #include <net/if_dl.h> 118 #include <net/if_ether.h> 119 120 #if NBPFILTER > 0 121 #include <net/bpf.h> 122 #include <net/bpfdesc.h> 123 #endif 124 125 #ifdef INET 126 #include <netinet/in.h> 127 #include <netinet/in_systm.h> 128 #include <netinet/in_var.h> 129 #include <netinet/ip.h> 130 #include <netinet/if_inarp.h> 131 #endif 132 133 #ifdef NS 134 #include <netns/ns.h> 135 #include <netns/ns_if.h> 136 #endif 137 138 #include <uvm/uvm_extern.h> 139 140 #include <machine/autoconf.h> 141 #include <machine/cpu.h> 142 #include <machine/pmap.h> 143 144 /* 145 * ugly byte-order hack for SUNs 146 */ 147 148 #define XSWAP(y) ( (((y)&0xff00) >> 8) | (((y)&0xff) << 8) ) 149 #define SWAP(x) ((u_short)(XSWAP((u_short)(x)))) 150 151 #include "i82586.h" 152 #include "if_iereg.h" 153 #include "if_ievar.h" 154 155 /* #define IEDEBUG XXX */ 156 157 /* 158 * IED: ie debug flags 159 */ 160 161 #define IED_RINT 0x01 162 #define IED_TINT 0x02 163 #define IED_RNR 0x04 164 #define IED_CNA 0x08 165 #define IED_READFRAME 0x10 166 #define IED_ENQ 0x20 167 #define IED_XMIT 0x40 168 #define IED_ALL 0x7f 169 170 #ifdef IEDEBUG 171 #define inline /* not */ 172 void print_rbd __P((volatile struct ie_recv_buf_desc *)); 173 int in_ierint = 0; 174 int in_ietint = 0; 175 int ie_debug_flags = 0; 176 #endif 177 178 /* XXX - Skip TDR for now - it always complains... */ 179 int ie_run_tdr = 0; 180 181 static void iewatchdog __P((struct ifnet *)); 182 static int ieinit __P((struct ie_softc *)); 183 static int ieioctl __P((struct ifnet *, u_long, caddr_t)); 184 static void iestart __P((struct ifnet *)); 185 static void iereset __P((struct ie_softc *)); 186 static int ie_setupram __P((struct ie_softc *sc)); 187 188 static int cmd_and_wait __P((struct ie_softc *, int, void *, int)); 189 190 static void ie_drop_packet_buffer __P((struct ie_softc *)); 191 static void ie_readframe __P((struct ie_softc *, int)); 192 static inline void ie_setup_config __P((struct ie_config_cmd *, int, int)); 193 194 static void ierint __P((struct ie_softc *)); 195 static void iestop __P((struct ie_softc *)); 196 static void ietint __P((struct ie_softc *)); 197 static void iexmit __P((struct ie_softc *)); 198 199 static int mc_setup __P((struct ie_softc *, void *)); 200 static void mc_reset __P((struct ie_softc *)); 201 static void run_tdr __P((struct ie_softc *, struct ie_tdr_cmd *)); 202 static void iememinit __P((struct ie_softc *)); 203 204 static inline char * Align __P((char *)); 205 static inline u_int Swap32 __P((u_int x)); 206 static inline u_int vtop24 __P((struct ie_softc *, void *)); 207 static inline u_short vtop16sw __P((struct ie_softc *, void *)); 208 209 static inline void ie_ack __P((struct ie_softc *, u_int)); 210 static inline u_short ether_cmp __P((u_char *, u_char *)); 211 static inline int check_eh __P((struct ie_softc *, 212 struct ether_header *eh, int *)); 213 static inline int ie_buflen __P((struct ie_softc *, int)); 214 static inline int ie_packet_len __P((struct ie_softc *)); 215 static inline struct mbuf * ieget __P((struct ie_softc *sc, int *to_bpf)); 216 217 218 /* 219 * Here are a few useful functions. We could have done these as macros, 220 * but since we have the inline facility, it makes sense to use that 221 * instead. 222 */ 223 224 /* KVA to 24 bit device address */ 225 static inline u_int 226 vtop24(sc, ptr) 227 struct ie_softc *sc; 228 void *ptr; 229 { 230 u_int pa; 231 232 pa = ((caddr_t)ptr) - sc->sc_iobase; 233 #ifdef IEDEBUG 234 if (pa & ~0xffFFff) 235 panic("ie:vtop24"); 236 #endif 237 return (pa); 238 } 239 240 /* KVA to 16 bit offset, swapped */ 241 static inline u_short 242 vtop16sw(sc, ptr) 243 struct ie_softc *sc; 244 void *ptr; 245 { 246 u_int pa; 247 248 pa = ((caddr_t)ptr) - sc->sc_maddr; 249 #ifdef IEDEBUG 250 if (pa & ~0xFFff) 251 panic("ie:vtop16"); 252 #endif 253 254 return (SWAP(pa)); 255 } 256 257 static inline u_int 258 Swap32(x) 259 u_int x; 260 { 261 u_int y; 262 263 y = x & 0xFF; 264 y <<= 8; x >>= 8; 265 y |= x & 0xFF; 266 y <<= 8; x >>= 8; 267 y |= x & 0xFF; 268 y <<= 8; x >>= 8; 269 y |= x & 0xFF; 270 271 return (y); 272 } 273 274 static inline char * 275 Align(ptr) 276 caddr_t ptr; 277 { 278 u_long l = (u_long)ptr; 279 280 l = (l + 3) & ~3L; 281 return ((char *)l); 282 } 283 284 285 static inline void 286 ie_ack(sc, mask) 287 struct ie_softc *sc; 288 u_int mask; 289 { 290 volatile struct ie_sys_ctl_block *scb = sc->scb; 291 292 cmd_and_wait(sc, scb->ie_status & mask, 0, 0); 293 } 294 295 296 /* 297 * Taken almost exactly from Bill's if_is.c, 298 * then modified beyond recognition... 299 */ 300 void 301 ie_attach(sc) 302 struct ie_softc *sc; 303 { 304 struct ifnet *ifp = &sc->sc_if; 305 306 /* MD code has done its part before calling this. */ 307 printf(": macaddr %s\n", ether_sprintf(sc->sc_addr)); 308 309 /* 310 * Compute number of transmit and receive buffers. 311 * Tx buffers take 1536 bytes, and fixed in number. 312 * Rx buffers are 512 bytes each, variable number. 313 * Need at least 1 frame for each 3 rx buffers. 314 * The ratio 3bufs:2frames is a compromise. 315 */ 316 sc->ntxbuf = NTXBUF; /* XXX - Fix me... */ 317 switch (sc->sc_msize) { 318 case 16384: 319 sc->nframes = 8 * 4; 320 sc->nrxbuf = 8 * 6; 321 break; 322 case 32768: 323 sc->nframes = 16 * 4; 324 sc->nrxbuf = 16 * 6; 325 break; 326 case 65536: 327 sc->nframes = 32 * 4; 328 sc->nrxbuf = 32 * 6; 329 break; 330 default: 331 sc->nframes = 0; 332 } 333 if (sc->nframes > MXFRAMES) 334 sc->nframes = MXFRAMES; 335 if (sc->nrxbuf > MXRXBUF) 336 sc->nrxbuf = MXRXBUF; 337 338 #ifdef IEDEBUG 339 printf("%s: %dK memory, %d tx frames, %d rx frames, %d rx bufs\n", 340 sc->sc_dev.dv_xname, (sc->sc_msize >> 10), 341 sc->ntxbuf, sc->nframes, sc->nrxbuf); 342 #endif 343 344 if ((sc->nframes <= 0) || (sc->nrxbuf <= 0)) 345 panic("ie_attach: weird memory size"); 346 347 /* 348 * Setup RAM for transmit/receive 349 */ 350 if (ie_setupram(sc) == 0) { 351 printf(": RAM CONFIG FAILED!\n"); 352 /* XXX should reclaim resources? */ 353 return; 354 } 355 356 /* 357 * Initialize and attach S/W interface 358 */ 359 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 360 ifp->if_softc = sc; 361 ifp->if_start = iestart; 362 ifp->if_ioctl = ieioctl; 363 ifp->if_watchdog = iewatchdog; 364 ifp->if_flags = 365 IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 366 367 /* Attach the interface. */ 368 if_attach(ifp); 369 ether_ifattach(ifp, sc->sc_addr); 370 } 371 372 /* 373 * Setup IE's ram space. 374 */ 375 static int 376 ie_setupram(sc) 377 struct ie_softc *sc; 378 { 379 volatile struct ie_sys_conf_ptr *scp; 380 volatile struct ie_int_sys_conf_ptr *iscp; 381 volatile struct ie_sys_ctl_block *scb; 382 int off; 383 384 /* 385 * Allocate from end of buffer space for 386 * ISCP, SCB, and other small stuff. 387 */ 388 off = sc->buf_area_sz; 389 off &= ~3; 390 391 /* SCP (address already chosen). */ 392 scp = sc->scp; 393 (sc->sc_memset)((char *) scp, 0, sizeof(*scp)); 394 395 /* ISCP */ 396 off -= sizeof(*iscp); 397 iscp = (volatile void *) (sc->buf_area + off); 398 (sc->sc_memset)((char *) iscp, 0, sizeof(*iscp)); 399 sc->iscp = iscp; 400 401 /* SCB */ 402 off -= sizeof(*scb); 403 scb = (volatile void *) (sc->buf_area + off); 404 (sc->sc_memset)((char *) scb, 0, sizeof(*scb)); 405 sc->scb = scb; 406 407 /* Remainder is for buffers, etc. */ 408 sc->buf_area_sz = off; 409 410 /* 411 * Now fill in the structures we just allocated. 412 */ 413 414 /* SCP: main thing is 24-bit ptr to ISCP */ 415 scp->ie_bus_use = 0; /* 16-bit */ 416 scp->ie_iscp_ptr = Swap32(vtop24(sc, (void*)iscp)); 417 418 /* ISCP */ 419 iscp->ie_busy = 1; /* ie_busy == char */ 420 iscp->ie_scb_offset = vtop16sw(sc, (void*)scb); 421 iscp->ie_base = Swap32(vtop24(sc, sc->sc_maddr)); 422 423 /* SCB */ 424 scb->ie_command_list = SWAP(0xffff); 425 scb->ie_recv_list = SWAP(0xffff); 426 427 /* Other stuff is done in ieinit() */ 428 (sc->reset_586) (sc); 429 (sc->chan_attn) (sc); 430 431 delay(100); /* wait a while... */ 432 433 if (iscp->ie_busy) { 434 return 0; 435 } 436 /* 437 * Acknowledge any interrupts we may have caused... 438 */ 439 ie_ack(sc, IE_ST_WHENCE); 440 441 return 1; 442 } 443 444 /* 445 * Device timeout/watchdog routine. Entered if the device neglects to 446 * generate an interrupt after a transmit has been started on it. 447 */ 448 static void 449 iewatchdog(ifp) 450 struct ifnet *ifp; 451 { 452 struct ie_softc *sc = ifp->if_softc; 453 454 log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); 455 ++ifp->if_oerrors; 456 iereset(sc); 457 } 458 459 /* 460 * What to do upon receipt of an interrupt. 461 */ 462 int 463 ie_intr(arg) 464 void *arg; 465 { 466 struct ie_softc *sc = arg; 467 u_short status; 468 int loopcnt; 469 470 /* 471 * check for parity error 472 */ 473 if (sc->hard_type == IE_VME) { 474 volatile struct ievme *iev = (volatile struct ievme *)sc->sc_reg; 475 if (iev->status & IEVME_PERR) { 476 printf("%s: parity error (ctrl 0x%x @ 0x%02x%04x)\n", 477 sc->sc_dev.dv_xname, iev->pectrl, 478 iev->pectrl & IEVME_HADDR, iev->peaddr); 479 iev->pectrl = iev->pectrl | IEVME_PARACK; 480 } 481 } 482 483 status = sc->scb->ie_status; 484 if ((status & IE_ST_WHENCE) == 0) 485 return 0; 486 487 loopcnt = sc->nframes; 488 loop: 489 /* Ack interrupts FIRST in case we receive more during the ISR. */ 490 ie_ack(sc, IE_ST_WHENCE & status); 491 492 if (status & (IE_ST_RECV | IE_ST_RNR)) { 493 #ifdef IEDEBUG 494 in_ierint++; 495 if (sc->sc_debug & IED_RINT) 496 printf("%s: rint\n", sc->sc_dev.dv_xname); 497 #endif 498 ierint(sc); 499 #ifdef IEDEBUG 500 in_ierint--; 501 #endif 502 } 503 504 if (status & IE_ST_DONE) { 505 #ifdef IEDEBUG 506 in_ietint++; 507 if (sc->sc_debug & IED_TINT) 508 printf("%s: tint\n", sc->sc_dev.dv_xname); 509 #endif 510 ietint(sc); 511 #ifdef IEDEBUG 512 in_ietint--; 513 #endif 514 } 515 516 /* 517 * Receiver not ready (RNR) just means it has 518 * run out of resources (buffers or frames). 519 * One can easily cause this with (i.e.) spray. 520 * This is not a serious error, so be silent. 521 */ 522 if (status & IE_ST_RNR) { 523 #ifdef IEDEBUG 524 printf("%s: receiver not ready\n", sc->sc_dev.dv_xname); 525 #endif 526 sc->sc_if.if_ierrors++; 527 iereset(sc); 528 } 529 530 #ifdef IEDEBUG 531 if ((status & IE_ST_ALLDONE) && (sc->sc_debug & IED_CNA)) 532 printf("%s: cna\n", sc->sc_dev.dv_xname); 533 #endif 534 535 status = sc->scb->ie_status; 536 if (status & IE_ST_WHENCE) { 537 /* It still wants service... */ 538 if (--loopcnt > 0) 539 goto loop; 540 /* ... but we've been here long enough. */ 541 log(LOG_ERR, "%s: interrupt stuck?\n", 542 sc->sc_dev.dv_xname); 543 iereset(sc); 544 } 545 return 1; 546 } 547 548 /* 549 * Process a received-frame interrupt. 550 */ 551 void 552 ierint(sc) 553 struct ie_softc *sc; 554 { 555 volatile struct ie_sys_ctl_block *scb = sc->scb; 556 int i, status; 557 static int timesthru = 1024; 558 559 i = sc->rfhead; 560 for (;;) { 561 status = sc->rframes[i]->ie_fd_status; 562 563 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) { 564 if (!--timesthru) { 565 sc->sc_if.if_ierrors += 566 SWAP(scb->ie_err_crc) + 567 SWAP(scb->ie_err_align) + 568 SWAP(scb->ie_err_resource) + 569 SWAP(scb->ie_err_overrun); 570 scb->ie_err_crc = 0; 571 scb->ie_err_align = 0; 572 scb->ie_err_resource = 0; 573 scb->ie_err_overrun = 0; 574 timesthru = 1024; 575 } 576 ie_readframe(sc, i); 577 } else { 578 if ((status & IE_FD_RNR) != 0 && 579 (scb->ie_status & IE_RU_READY) == 0) { 580 sc->rframes[0]->ie_fd_buf_desc = 581 vtop16sw(sc, (void*) sc->rbuffs[0]); 582 scb->ie_recv_list = 583 vtop16sw(sc, (void*) sc->rframes[0]); 584 cmd_and_wait(sc, IE_RU_START, 0, 0); 585 } 586 break; 587 } 588 i = (i + 1) % sc->nframes; 589 } 590 } 591 592 /* 593 * Process a command-complete interrupt. These are only generated by the 594 * transmission of frames. This routine is deceptively simple, since most 595 * of the real work is done by iestart(). 596 */ 597 void 598 ietint(sc) 599 struct ie_softc *sc; 600 { 601 struct ifnet *ifp; 602 int status; 603 604 ifp = &sc->sc_if; 605 606 ifp->if_timer = 0; 607 ifp->if_flags &= ~IFF_OACTIVE; 608 609 status = sc->xmit_cmds[sc->xctail]->ie_xmit_status; 610 611 if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY)) 612 printf("ietint: command still busy!\n"); 613 614 if (status & IE_STAT_OK) { 615 ifp->if_opackets++; 616 ifp->if_collisions += 617 SWAP(status & IE_XS_MAXCOLL); 618 } else { 619 ifp->if_oerrors++; 620 /* 621 * XXX 622 * Check SQE and DEFERRED? 623 * What if more than one bit is set? 624 */ 625 if (status & IE_STAT_ABORT) 626 printf("%s: send aborted\n", sc->sc_dev.dv_xname); 627 if (status & IE_XS_LATECOLL) 628 printf("%s: late collision\n", sc->sc_dev.dv_xname); 629 if (status & IE_XS_NOCARRIER) 630 printf("%s: no carrier\n", sc->sc_dev.dv_xname); 631 if (status & IE_XS_LOSTCTS) 632 printf("%s: lost CTS\n", sc->sc_dev.dv_xname); 633 if (status & IE_XS_UNDERRUN) 634 printf("%s: DMA underrun\n", sc->sc_dev.dv_xname); 635 if (status & IE_XS_EXCMAX) { 636 /* Do not print this one (too noisy). */ 637 ifp->if_collisions += 16; 638 } 639 } 640 641 /* 642 * If multicast addresses were added or deleted while we 643 * were transmitting, mc_reset() set the want_mcsetup flag 644 * indicating that we should do it. 645 */ 646 if (sc->want_mcsetup) { 647 mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]); 648 sc->want_mcsetup = 0; 649 } 650 651 /* Done with the buffer. */ 652 sc->xmit_busy--; 653 sc->xctail = (sc->xctail + 1) % NTXBUF; 654 655 /* Start the next packet, if any, transmitting. */ 656 if (sc->xmit_busy > 0) 657 iexmit(sc); 658 659 iestart(ifp); 660 } 661 662 /* 663 * Compare two Ether/802 addresses for equality, inlined and 664 * unrolled for speed. I'd love to have an inline assembler 665 * version of this... XXX: Who wanted that? mycroft? 666 * I wrote one, but the following is just as efficient. 667 * This expands to 10 short m68k instructions! -gwr 668 * Note: use this like bcmp() 669 */ 670 static inline u_short 671 ether_cmp(one, two) 672 u_char *one, *two; 673 { 674 u_short *a = (u_short *) one; 675 u_short *b = (u_short *) two; 676 u_short diff; 677 678 diff = *a++ - *b++; 679 diff |= *a++ - *b++; 680 diff |= *a++ - *b++; 681 682 return (diff); 683 } 684 #define ether_equal !ether_cmp 685 686 /* 687 * Check for a valid address. to_bpf is filled in with one of the following: 688 * 0 -> BPF doesn't get this packet 689 * 1 -> BPF does get this packet 690 * 2 -> BPF does get this packet, but we don't 691 * Return value is true if the packet is for us, and false otherwise. 692 * 693 * This routine is a mess, but it's also critical that it be as fast 694 * as possible. It could be made cleaner if we can assume that the 695 * only client which will fiddle with IFF_PROMISC is BPF. This is 696 * probably a good assumption, but we do not make it here. (Yet.) 697 */ 698 static inline int 699 check_eh(sc, eh, to_bpf) 700 struct ie_softc *sc; 701 struct ether_header *eh; 702 int *to_bpf; 703 { 704 struct ifnet *ifp; 705 706 ifp = &sc->sc_if; 707 708 #if NBPFILTER > 0 709 *to_bpf = (ifp->if_bpf != 0); 710 #else 711 *to_bpf = 0; 712 #endif 713 714 /* 715 * This is all handled at a higher level now. 716 */ 717 return 1; 718 } 719 720 /* 721 * We want to isolate the bits that have meaning... This assumes that 722 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds 723 * the size of the buffer, then we are screwed anyway. 724 */ 725 static inline int 726 ie_buflen(sc, head) 727 struct ie_softc *sc; 728 int head; 729 { 730 int len; 731 732 len = SWAP(sc->rbuffs[head]->ie_rbd_actual); 733 len &= (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)); 734 return (len); 735 } 736 737 static inline int 738 ie_packet_len(sc) 739 struct ie_softc *sc; 740 { 741 int i; 742 int head = sc->rbhead; 743 int acc = 0; 744 745 do { 746 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) { 747 #ifdef IEDEBUG 748 print_rbd(sc->rbuffs[sc->rbhead]); 749 #endif 750 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n", 751 sc->sc_dev.dv_xname, sc->rbhead); 752 iereset(sc); 753 return -1; 754 } 755 756 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST; 757 758 acc += ie_buflen(sc, head); 759 head = (head + 1) % sc->nrxbuf; 760 } while (!i); 761 762 return acc; 763 } 764 765 /* 766 * Setup all necessary artifacts for an XMIT command, and then pass the XMIT 767 * command to the chip to be executed. On the way, if we have a BPF listener 768 * also give him a copy. 769 */ 770 static void 771 iexmit(sc) 772 struct ie_softc *sc; 773 { 774 struct ifnet *ifp; 775 776 ifp = &sc->sc_if; 777 778 #ifdef IEDEBUG 779 if (sc->sc_debug & IED_XMIT) 780 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname, 781 sc->xctail); 782 #endif 783 784 #if NBPFILTER > 0 785 /* 786 * If BPF is listening on this interface, let it see the packet before 787 * we push it on the wire. 788 */ 789 if (ifp->if_bpf) 790 bpf_tap(ifp->if_bpf, 791 sc->xmit_cbuffs[sc->xctail], 792 SWAP(sc->xmit_buffs[sc->xctail]->ie_xmit_flags)); 793 #endif 794 795 sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST; 796 sc->xmit_buffs[sc->xctail]->ie_xmit_next = SWAP(0xffff); 797 sc->xmit_buffs[sc->xctail]->ie_xmit_buf = 798 Swap32(vtop24(sc, sc->xmit_cbuffs[sc->xctail])); 799 800 sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = SWAP(0xffff); 801 sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd = 802 IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST; 803 804 sc->xmit_cmds[sc->xctail]->ie_xmit_status = SWAP(0); 805 sc->xmit_cmds[sc->xctail]->ie_xmit_desc = 806 vtop16sw(sc, (void*) sc->xmit_buffs[sc->xctail]); 807 808 sc->scb->ie_command_list = 809 vtop16sw(sc, (void*) sc->xmit_cmds[sc->xctail]); 810 cmd_and_wait(sc, IE_CU_START, 0, 0); 811 812 ifp->if_timer = 5; 813 } 814 815 /* 816 * Read data off the interface, and turn it into an mbuf chain. 817 * 818 * This code is DRAMATICALLY different from the previous version; this 819 * version tries to allocate the entire mbuf chain up front, given the 820 * length of the data available. This enables us to allocate mbuf 821 * clusters in many situations where before we would have had a long 822 * chain of partially-full mbufs. This should help to speed up the 823 * operation considerably. (Provided that it works, of course.) 824 */ 825 static inline struct mbuf * 826 ieget(sc, to_bpf) 827 struct ie_softc *sc; 828 int *to_bpf; 829 { 830 struct mbuf *top, **mp, *m; 831 int len, totlen, resid; 832 int thisrboff, thismboff; 833 int head; 834 struct ether_header eh; 835 836 totlen = ie_packet_len(sc); 837 if (totlen <= 0) 838 return 0; 839 840 head = sc->rbhead; 841 842 /* 843 * Snarf the Ethernet header. 844 */ 845 (sc->sc_memcpy)((caddr_t)&eh, (caddr_t)sc->cbuffs[head], 846 sizeof(struct ether_header)); 847 848 /* 849 * As quickly as possible, check if this packet is for us. 850 * If not, don't waste a single cycle copying the rest of the 851 * packet in. 852 * This is only a consideration when FILTER is defined; i.e., when 853 * we are either running BPF or doing multicasting. 854 */ 855 if (!check_eh(sc, &eh, to_bpf)) { 856 /* just this case, it's not an error */ 857 sc->sc_if.if_ierrors--; 858 return 0; 859 } 860 861 resid = totlen; 862 863 MGETHDR(m, M_DONTWAIT, MT_DATA); 864 if (m == 0) 865 return 0; 866 867 m->m_pkthdr.rcvif = &sc->sc_if; 868 m->m_pkthdr.len = totlen; 869 len = MHLEN; 870 top = 0; 871 mp = ⊤ 872 873 /* 874 * This loop goes through and allocates mbufs for all the data we will 875 * be copying in. It does not actually do the copying yet. 876 */ 877 while (totlen > 0) { 878 if (top) { 879 MGET(m, M_DONTWAIT, MT_DATA); 880 if (m == 0) { 881 m_freem(top); 882 return 0; 883 } 884 len = MLEN; 885 } 886 if (totlen >= MINCLSIZE) { 887 MCLGET(m, M_DONTWAIT); 888 if (m->m_flags & M_EXT) 889 len = MCLBYTES; 890 } 891 892 if (mp == &top) { 893 caddr_t newdata = (caddr_t) 894 ALIGN(m->m_data + sizeof(struct ether_header)) - 895 sizeof(struct ether_header); 896 len -= newdata - m->m_data; 897 m->m_data = newdata; 898 } 899 900 m->m_len = len = min(totlen, len); 901 902 totlen -= len; 903 *mp = m; 904 mp = &m->m_next; 905 } 906 907 m = top; 908 thismboff = 0; 909 910 /* 911 * Copy the Ethernet header into the mbuf chain. 912 */ 913 memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header)); 914 thismboff = sizeof(struct ether_header); 915 thisrboff = sizeof(struct ether_header); 916 resid -= sizeof(struct ether_header); 917 918 /* 919 * Now we take the mbuf chain (hopefully only one mbuf most of the 920 * time) and stuff the data into it. There are no possible failures 921 * at or after this point. 922 */ 923 while (resid > 0) { 924 int thisrblen = ie_buflen(sc, head) - thisrboff; 925 int thismblen = m->m_len - thismboff; 926 927 len = min(thisrblen, thismblen); 928 (sc->sc_memcpy)(mtod(m, caddr_t) + thismboff, 929 (caddr_t)(sc->cbuffs[head] + thisrboff), 930 (u_int)len); 931 resid -= len; 932 933 if (len == thismblen) { 934 m = m->m_next; 935 thismboff = 0; 936 } else 937 thismboff += len; 938 939 if (len == thisrblen) { 940 head = (head + 1) % sc->nrxbuf; 941 thisrboff = 0; 942 } else 943 thisrboff += len; 944 } 945 946 /* 947 * Unless something changed strangely while we were doing the copy, 948 * we have now copied everything in from the shared memory. 949 * This means that we are done. 950 */ 951 return top; 952 } 953 954 /* 955 * Read frame NUM from unit UNIT (pre-cached as IE). 956 * 957 * This routine reads the RFD at NUM, and copies in the buffers from 958 * the list of RBD, then rotates the RBD and RFD lists so that the receiver 959 * doesn't start complaining. Trailers are DROPPED---there's no point 960 * in wasting time on confusing code to deal with them. Hopefully, 961 * this machine will never ARP for trailers anyway. 962 */ 963 static void 964 ie_readframe(sc, num) 965 struct ie_softc *sc; 966 int num; /* frame number to read */ 967 { 968 int status; 969 struct mbuf *m = 0; 970 #if NBPFILTER > 0 971 int bpf_gets_it = 0; 972 #endif 973 974 status = sc->rframes[num]->ie_fd_status; 975 976 /* Advance the RFD list, since we're done with this descriptor. */ 977 sc->rframes[num]->ie_fd_status = SWAP(0); 978 sc->rframes[num]->ie_fd_last |= IE_FD_LAST; 979 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST; 980 sc->rftail = (sc->rftail + 1) % sc->nframes; 981 sc->rfhead = (sc->rfhead + 1) % sc->nframes; 982 983 if (status & IE_FD_OK) { 984 #if NBPFILTER > 0 985 m = ieget(sc, &bpf_gets_it); 986 #else 987 m = ieget(sc, 0); 988 #endif 989 ie_drop_packet_buffer(sc); 990 } 991 if (m == 0) { 992 sc->sc_if.if_ierrors++; 993 return; 994 } 995 996 #ifdef IEDEBUG 997 if (sc->sc_debug & IED_READFRAME) { 998 struct ether_header *eh = mtod(m, struct ether_header *); 999 1000 printf("%s: frame from ether %s type 0x%x\n", 1001 sc->sc_dev.dv_xname, 1002 ether_sprintf(eh->ether_shost), (u_int)eh->ether_type); 1003 } 1004 #endif 1005 1006 #if NBPFILTER > 0 1007 /* 1008 * Check for a BPF filter; if so, hand it up. 1009 * Note that we have to stick an extra mbuf up front, because 1010 * bpf_mtap expects to have the ether header at the front. 1011 * It doesn't matter that this results in an ill-formatted mbuf chain, 1012 * since BPF just looks at the data. (It doesn't try to free the mbuf, 1013 * tho' it will make a copy for tcpdump.) 1014 */ 1015 if (bpf_gets_it) { 1016 /* Pass it up. */ 1017 bpf_mtap(sc->sc_if.if_bpf, m); 1018 1019 /* 1020 * A signal passed up from the filtering code indicating that 1021 * the packet is intended for BPF but not for the protocol 1022 * machinery. We can save a few cycles by not handing it off 1023 * to them. 1024 */ 1025 if (bpf_gets_it == 2) { 1026 m_freem(m); 1027 return; 1028 } 1029 } 1030 #endif /* NBPFILTER > 0 */ 1031 1032 /* 1033 * In here there used to be code to check destination addresses upon 1034 * receipt of a packet. We have deleted that code, and replaced it 1035 * with code to check the address much earlier in the cycle, before 1036 * copying the data in; this saves us valuable cycles when operating 1037 * as a multicast router or when using BPF. 1038 */ 1039 1040 /* 1041 * Finally pass this packet up to higher layers. 1042 */ 1043 (*sc->sc_if.if_input)(&sc->sc_if, m); 1044 sc->sc_if.if_ipackets++; 1045 } 1046 1047 static void 1048 ie_drop_packet_buffer(sc) 1049 struct ie_softc *sc; 1050 { 1051 int i; 1052 1053 do { 1054 /* 1055 * This means we are somehow out of sync. So, we reset the 1056 * adapter. 1057 */ 1058 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) { 1059 #ifdef IEDEBUG 1060 print_rbd(sc->rbuffs[sc->rbhead]); 1061 #endif 1062 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n", 1063 sc->sc_dev.dv_xname, sc->rbhead); 1064 iereset(sc); 1065 return; 1066 } 1067 1068 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST; 1069 1070 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST; 1071 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0); 1072 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf; 1073 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; 1074 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf; 1075 } while (!i); 1076 } 1077 1078 /* 1079 * Start transmission on an interface. 1080 */ 1081 static void 1082 iestart(ifp) 1083 struct ifnet *ifp; 1084 { 1085 struct ie_softc *sc = ifp->if_softc; 1086 struct mbuf *m0, *m; 1087 u_char *buffer; 1088 u_short len; 1089 1090 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1091 return; 1092 1093 for (;;) { 1094 if (sc->xmit_busy == sc->ntxbuf) { 1095 ifp->if_flags |= IFF_OACTIVE; 1096 break; 1097 } 1098 1099 IF_DEQUEUE(&ifp->if_snd, m0); 1100 if (m0 == 0) 1101 break; 1102 1103 /* We need to use m->m_pkthdr.len, so require the header */ 1104 if ((m0->m_flags & M_PKTHDR) == 0) 1105 panic("iestart: no header mbuf"); 1106 1107 #if NBPFILTER > 0 1108 /* Tap off here if there is a BPF listener. */ 1109 if (ifp->if_bpf) 1110 bpf_mtap(ifp->if_bpf, m0); 1111 #endif 1112 1113 #ifdef IEDEBUG 1114 if (sc->sc_debug & IED_ENQ) 1115 printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname, 1116 sc->xchead); 1117 #endif 1118 1119 buffer = sc->xmit_cbuffs[sc->xchead]; 1120 for (m = m0; m != 0; m = m->m_next) { 1121 (sc->sc_memcpy)(buffer, mtod(m, caddr_t), m->m_len); 1122 buffer += m->m_len; 1123 } 1124 len = max(m0->m_pkthdr.len, ETHER_MIN_LEN); 1125 1126 m_freem(m0); 1127 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len); 1128 1129 /* Start the first packet transmitting. */ 1130 if (sc->xmit_busy == 0) 1131 iexmit(sc); 1132 1133 sc->xchead = (sc->xchead + 1) % sc->ntxbuf; 1134 sc->xmit_busy++; 1135 } 1136 } 1137 1138 static void 1139 iereset(sc) 1140 struct ie_softc *sc; 1141 { 1142 int s = splnet(); 1143 1144 /* No message here. The caller does that. */ 1145 iestop(sc); 1146 1147 /* 1148 * Stop i82586 dead in its tracks. 1149 */ 1150 if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0)) 1151 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname); 1152 1153 if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0)) 1154 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname); 1155 1156 ieinit(sc); 1157 1158 splx(s); 1159 } 1160 1161 /* 1162 * Send a command to the controller and wait for it to either 1163 * complete or be accepted, depending on the command. If the 1164 * command pointer is null, then pretend that the command is 1165 * not an action command. If the command pointer is not null, 1166 * and the command is an action command, wait for 1167 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK 1168 * to become true. 1169 */ 1170 static int 1171 cmd_and_wait(sc, cmd, pcmd, mask) 1172 struct ie_softc *sc; 1173 int cmd; 1174 void *pcmd; /* XXX - Was volatile */ 1175 int mask; 1176 { 1177 volatile struct ie_cmd_common *cc = pcmd; 1178 volatile struct ie_sys_ctl_block *scb = sc->scb; 1179 int tmo; 1180 1181 scb->ie_command = (u_short)cmd; 1182 (sc->chan_attn)(sc); 1183 1184 /* Wait for the command to be accepted by the CU. */ 1185 tmo = 10; 1186 while (scb->ie_command && --tmo) 1187 delay(10); 1188 if (scb->ie_command) { 1189 #ifdef IEDEBUG 1190 printf("%s: cmd_and_wait, CU stuck (1)\n", 1191 sc->sc_dev.dv_xname); 1192 #endif 1193 return -1; /* timed out */ 1194 } 1195 1196 /* 1197 * If asked, also wait for it to finish. 1198 */ 1199 if (IE_ACTION_COMMAND(cmd) && pcmd) { 1200 1201 /* 1202 * According to the packet driver, the minimum timeout should 1203 * be .369 seconds, which we round up to .4. 1204 */ 1205 tmo = 36900; 1206 1207 /* 1208 * Now spin-lock waiting for status. This is not a very nice 1209 * thing to do, but I haven't figured out how, or indeed if, we 1210 * can put the process waiting for action to sleep. (We may 1211 * be getting called through some other timeout running in the 1212 * kernel.) 1213 */ 1214 while (((cc->ie_cmd_status & mask) == 0) && --tmo) 1215 delay(10); 1216 1217 if ((cc->ie_cmd_status & mask) == 0) { 1218 #ifdef IEDEBUG 1219 printf("%s: cmd_and_wait, CU stuck (2)\n", 1220 sc->sc_dev.dv_xname); 1221 #endif 1222 return -1; /* timed out */ 1223 } 1224 } 1225 return 0; 1226 } 1227 1228 /* 1229 * Run the time-domain reflectometer. 1230 */ 1231 static void 1232 run_tdr(sc, cmd) 1233 struct ie_softc *sc; 1234 struct ie_tdr_cmd *cmd; 1235 { 1236 int result; 1237 1238 cmd->com.ie_cmd_status = SWAP(0); 1239 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST; 1240 cmd->com.ie_cmd_link = SWAP(0xffff); 1241 1242 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1243 cmd->ie_tdr_time = SWAP(0); 1244 1245 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1246 !(cmd->com.ie_cmd_status & IE_STAT_OK)) 1247 result = 0x10000; /* impossible value */ 1248 else 1249 result = cmd->ie_tdr_time; 1250 1251 ie_ack(sc, IE_ST_WHENCE); 1252 1253 if (result & IE_TDR_SUCCESS) 1254 return; 1255 1256 if (result & 0x10000) { 1257 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname); 1258 } else if (result & IE_TDR_XCVR) { 1259 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname); 1260 } else if (result & IE_TDR_OPEN) { 1261 printf("%s: TDR detected an open %d clocks away\n", 1262 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME)); 1263 } else if (result & IE_TDR_SHORT) { 1264 printf("%s: TDR detected a short %d clocks away\n", 1265 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME)); 1266 } else { 1267 printf("%s: TDR returned unknown status 0x%x\n", 1268 sc->sc_dev.dv_xname, result); 1269 } 1270 } 1271 1272 /* 1273 * iememinit: set up the buffers 1274 * 1275 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz. 1276 * this is to be used for the buffers. the chip indexs its control data 1277 * structures with 16 bit offsets, and it indexes actual buffers with 1278 * 24 bit addresses. so we should allocate control buffers first so that 1279 * we don't overflow the 16 bit offset field. The number of transmit 1280 * buffers is fixed at compile time. 1281 * 1282 * note: this function was written to be easy to understand, rather than 1283 * highly efficient (it isn't in the critical path). 1284 * 1285 * The memory layout is: tbufs, rbufs, (gap), control blocks 1286 * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes] 1287 * XXX - This needs review... 1288 */ 1289 static void 1290 iememinit(sc) 1291 struct ie_softc *sc; 1292 { 1293 char *ptr; 1294 int i; 1295 u_short nxt; 1296 1297 /* First, zero all the memory. */ 1298 ptr = sc->buf_area; 1299 (sc->sc_memset)(ptr, 0, sc->buf_area_sz); 1300 1301 /* Allocate tx/rx buffers. */ 1302 for (i = 0; i < NTXBUF; i++) { 1303 sc->xmit_cbuffs[i] = ptr; 1304 ptr += IE_TBUF_SIZE; 1305 } 1306 for (i = 0; i < sc->nrxbuf; i++) { 1307 sc->cbuffs[i] = ptr; 1308 ptr += IE_RBUF_SIZE; 1309 } 1310 1311 /* Small pad (Don't trust the chip...) */ 1312 ptr += 16; 1313 1314 /* Allocate and fill in xmit buffer descriptors. */ 1315 for (i = 0; i < NTXBUF; i++) { 1316 sc->xmit_buffs[i] = (volatile void *) ptr; 1317 ptr = Align(ptr + sizeof(*sc->xmit_buffs[i])); 1318 sc->xmit_buffs[i]->ie_xmit_buf = 1319 Swap32(vtop24(sc, sc->xmit_cbuffs[i])); 1320 sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff); 1321 } 1322 1323 /* Allocate and fill in recv buffer descriptors. */ 1324 for (i = 0; i < sc->nrxbuf; i++) { 1325 sc->rbuffs[i] = (volatile void *) ptr; 1326 ptr = Align(ptr + sizeof(*sc->rbuffs[i])); 1327 sc->rbuffs[i]->ie_rbd_buffer = 1328 Swap32(vtop24(sc, sc->cbuffs[i])); 1329 sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE); 1330 } 1331 1332 /* link together recv bufs and set EOL on last */ 1333 i = sc->nrxbuf - 1; 1334 sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST; 1335 nxt = vtop16sw(sc, (void*) sc->rbuffs[0]); 1336 do { 1337 sc->rbuffs[i]->ie_rbd_next = nxt; 1338 nxt = vtop16sw(sc, (void*) sc->rbuffs[i]); 1339 } while (--i >= 0); 1340 1341 /* Allocate transmit commands. */ 1342 for (i = 0; i < NTXBUF; i++) { 1343 sc->xmit_cmds[i] = (volatile void *) ptr; 1344 ptr = Align(ptr + sizeof(*sc->xmit_cmds[i])); 1345 sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff); 1346 } 1347 1348 /* Allocate receive frames. */ 1349 for (i = 0; i < sc->nframes; i++) { 1350 sc->rframes[i] = (volatile void *) ptr; 1351 ptr = Align(ptr + sizeof(*sc->rframes[i])); 1352 } 1353 1354 /* Link together recv frames and set EOL on last */ 1355 i = sc->nframes - 1; 1356 sc->rframes[i]->ie_fd_last |= IE_FD_LAST; 1357 nxt = vtop16sw(sc, (void*) sc->rframes[0]); 1358 do { 1359 sc->rframes[i]->ie_fd_next = nxt; 1360 nxt = vtop16sw(sc, (void*) sc->rframes[i]); 1361 } while (--i >= 0); 1362 1363 1364 /* Pointers to last packet sent and next available transmit buffer. */ 1365 sc->xchead = sc->xctail = 0; 1366 1367 /* Clear transmit-busy flag. */ 1368 sc->xmit_busy = 0; 1369 1370 /* 1371 * Set the head and tail pointers on receive to keep track of 1372 * the order in which RFDs and RBDs are used. link the 1373 * recv frames and buffer into the scb. 1374 */ 1375 sc->rfhead = 0; 1376 sc->rftail = sc->nframes - 1; 1377 sc->rbhead = 0; 1378 sc->rbtail = sc->nrxbuf - 1; 1379 1380 sc->scb->ie_recv_list = 1381 vtop16sw(sc, (void*) sc->rframes[0]); 1382 sc->rframes[0]->ie_fd_buf_desc = 1383 vtop16sw(sc, (void*) sc->rbuffs[0]); 1384 1385 i = (ptr - sc->buf_area); 1386 #ifdef IEDEBUG 1387 printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz); 1388 #endif 1389 if (i > sc->buf_area_sz) 1390 panic("ie: iememinit, out of space"); 1391 } 1392 1393 /* 1394 * Run the multicast setup command. 1395 * Called at splnet(). 1396 */ 1397 static int 1398 mc_setup(sc, ptr) 1399 struct ie_softc *sc; 1400 void *ptr; 1401 { 1402 struct ie_mcast_cmd *cmd = ptr; /* XXX - Was volatile */ 1403 1404 cmd->com.ie_cmd_status = SWAP(0); 1405 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST; 1406 cmd->com.ie_cmd_link = SWAP(0xffff); 1407 1408 (sc->sc_memcpy)((caddr_t)cmd->ie_mcast_addrs, 1409 (caddr_t)sc->mcast_addrs, 1410 sc->mcast_count * sizeof *sc->mcast_addrs); 1411 1412 cmd->ie_mcast_bytes = 1413 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */ 1414 1415 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1416 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1417 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1418 printf("%s: multicast address setup command failed\n", 1419 sc->sc_dev.dv_xname); 1420 return 0; 1421 } 1422 return 1; 1423 } 1424 1425 static inline void 1426 ie_setup_config(cmd, promiscuous, manchester) 1427 struct ie_config_cmd *cmd; /* XXX - was volatile */ 1428 int promiscuous, manchester; 1429 { 1430 1431 /* 1432 * these are all char's so no need to byte-swap 1433 */ 1434 cmd->ie_config_count = 0x0c; 1435 cmd->ie_fifo = 8; 1436 cmd->ie_save_bad = 0x40; 1437 cmd->ie_addr_len = 0x2e; 1438 cmd->ie_priority = 0; 1439 cmd->ie_ifs = 0x60; 1440 cmd->ie_slot_low = 0; 1441 cmd->ie_slot_high = 0xf2; 1442 cmd->ie_promisc = promiscuous | manchester << 2; 1443 cmd->ie_crs_cdt = 0; 1444 cmd->ie_min_len = 64; 1445 cmd->ie_junk = 0xff; 1446 } 1447 1448 /* 1449 * This routine inits the ie. 1450 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, 1451 * starting the receiver unit, and clearing interrupts. 1452 * 1453 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER. 1454 */ 1455 static int 1456 ieinit(sc) 1457 struct ie_softc *sc; 1458 { 1459 volatile struct ie_sys_ctl_block *scb = sc->scb; 1460 void *ptr; 1461 struct ifnet *ifp; 1462 1463 ifp = &sc->sc_if; 1464 ptr = sc->buf_area; /* XXX - Use scb instead? */ 1465 1466 /* 1467 * Send the configure command first. 1468 */ 1469 { 1470 struct ie_config_cmd *cmd = ptr; /* XXX - Was volatile */ 1471 1472 scb->ie_command_list = vtop16sw(sc, cmd); 1473 cmd->com.ie_cmd_status = SWAP(0); 1474 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST; 1475 cmd->com.ie_cmd_link = SWAP(0xffff); 1476 1477 ie_setup_config(cmd, (sc->promisc != 0), 0); 1478 1479 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1480 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1481 printf("%s: configure command failed\n", 1482 sc->sc_dev.dv_xname); 1483 return 0; 1484 } 1485 } 1486 1487 /* 1488 * Now send the Individual Address Setup command. 1489 */ 1490 { 1491 struct ie_iasetup_cmd *cmd = ptr; /* XXX - Was volatile */ 1492 1493 scb->ie_command_list = vtop16sw(sc, cmd); 1494 cmd->com.ie_cmd_status = SWAP(0); 1495 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; 1496 cmd->com.ie_cmd_link = SWAP(0xffff); 1497 1498 (sc->sc_memcpy)((caddr_t)&cmd->ie_address, 1499 LLADDR(ifp->if_sadl), sizeof(cmd->ie_address)); 1500 1501 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1502 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1503 printf("%s: individual address setup command failed\n", 1504 sc->sc_dev.dv_xname); 1505 return 0; 1506 } 1507 } 1508 1509 /* 1510 * Now run the time-domain reflectometer. 1511 */ 1512 if (ie_run_tdr) 1513 run_tdr(sc, ptr); 1514 1515 /* 1516 * Acknowledge any interrupts we have generated thus far. 1517 */ 1518 ie_ack(sc, IE_ST_WHENCE); 1519 1520 /* 1521 * Set up the transmit and recv buffers. 1522 */ 1523 iememinit(sc); 1524 1525 /* tell higher levels that we are here */ 1526 ifp->if_flags |= IFF_RUNNING; 1527 ifp->if_flags &= ~IFF_OACTIVE; 1528 1529 sc->scb->ie_recv_list = 1530 vtop16sw(sc, (void*) sc->rframes[0]); 1531 cmd_and_wait(sc, IE_RU_START, 0, 0); 1532 1533 ie_ack(sc, IE_ST_WHENCE); 1534 1535 if (sc->run_586) 1536 (sc->run_586)(sc); 1537 1538 return 0; 1539 } 1540 1541 static void 1542 iestop(sc) 1543 struct ie_softc *sc; 1544 { 1545 1546 cmd_and_wait(sc, IE_RU_DISABLE, 0, 0); 1547 } 1548 1549 static int 1550 ieioctl(ifp, cmd, data) 1551 struct ifnet *ifp; 1552 u_long cmd; 1553 caddr_t data; 1554 { 1555 struct ie_softc *sc = ifp->if_softc; 1556 struct ifaddr *ifa = (struct ifaddr *)data; 1557 struct ifreq *ifr = (struct ifreq *)data; 1558 int s, error = 0; 1559 1560 s = splnet(); 1561 1562 switch (cmd) { 1563 1564 case SIOCSIFADDR: 1565 ifp->if_flags |= IFF_UP; 1566 1567 switch (ifa->ifa_addr->sa_family) { 1568 #ifdef INET 1569 case AF_INET: 1570 ieinit(sc); 1571 arp_ifinit(ifp, ifa); 1572 break; 1573 #endif 1574 #ifdef NS 1575 /* XXX - This code is probably wrong. */ 1576 case AF_NS: 1577 { 1578 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1579 1580 if (ns_nullhost(*ina)) 1581 ina->x_host = 1582 *(union ns_host *)LLADDR(ifp->if_sadl); 1583 else 1584 memcpy(LLADDR(ifp->if_sadl), 1585 ina->x_host.c_host, ETHER_ADDR_LEN); 1586 /* Set new address. */ 1587 ieinit(sc); 1588 break; 1589 } 1590 #endif /* NS */ 1591 default: 1592 ieinit(sc); 1593 break; 1594 } 1595 break; 1596 1597 case SIOCSIFFLAGS: 1598 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); 1599 1600 if ((ifp->if_flags & IFF_UP) == 0 && 1601 (ifp->if_flags & IFF_RUNNING) != 0) { 1602 /* 1603 * If interface is marked down and it is running, then 1604 * stop it. 1605 */ 1606 iestop(sc); 1607 ifp->if_flags &= ~IFF_RUNNING; 1608 } else if ((ifp->if_flags & IFF_UP) != 0 && 1609 (ifp->if_flags & IFF_RUNNING) == 0) { 1610 /* 1611 * If interface is marked up and it is stopped, then 1612 * start it. 1613 */ 1614 ieinit(sc); 1615 } else { 1616 /* 1617 * Reset the interface to pick up changes in any other 1618 * flags that affect hardware registers. 1619 */ 1620 iestop(sc); 1621 ieinit(sc); 1622 } 1623 #ifdef IEDEBUG 1624 if (ifp->if_flags & IFF_DEBUG) 1625 sc->sc_debug = IED_ALL; 1626 else 1627 sc->sc_debug = ie_debug_flags; 1628 #endif 1629 break; 1630 1631 case SIOCADDMULTI: 1632 case SIOCDELMULTI: 1633 error = (cmd == SIOCADDMULTI) ? 1634 ether_addmulti(ifr, &sc->sc_ethercom) : 1635 ether_delmulti(ifr, &sc->sc_ethercom); 1636 1637 if (error == ENETRESET) { 1638 /* 1639 * Multicast list has changed; set the hardware filter 1640 * accordingly. 1641 */ 1642 mc_reset(sc); 1643 error = 0; 1644 } 1645 break; 1646 1647 default: 1648 error = EINVAL; 1649 } 1650 splx(s); 1651 return error; 1652 } 1653 1654 static void 1655 mc_reset(sc) 1656 struct ie_softc *sc; 1657 { 1658 struct ether_multi *enm; 1659 struct ether_multistep step; 1660 struct ifnet *ifp; 1661 1662 ifp = &sc->sc_if; 1663 1664 /* 1665 * Step through the list of addresses. 1666 */ 1667 sc->mcast_count = 0; 1668 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1669 while (enm) { 1670 if (sc->mcast_count >= MAXMCAST || 1671 ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) { 1672 ifp->if_flags |= IFF_ALLMULTI; 1673 ieioctl(ifp, SIOCSIFFLAGS, (void *)0); 1674 goto setflag; 1675 } 1676 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 1677 ETHER_ADDR_LEN); 1678 sc->mcast_count++; 1679 ETHER_NEXT_MULTI(step, enm); 1680 } 1681 setflag: 1682 sc->want_mcsetup = 1; 1683 } 1684 1685 #ifdef IEDEBUG 1686 void 1687 print_rbd(rbd) 1688 volatile struct ie_recv_buf_desc *rbd; 1689 { 1690 1691 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n" 1692 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual, 1693 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length, 1694 rbd->mbz); 1695 } 1696 #endif 1697