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