1 /* $NetBSD: if_ie.c,v 1.38 2003/01/20 15:03:45 bouyer 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 if (m0->m_pkthdr.len < ETHER_MIN_LEN - ETHER_CRC_LEN) { 1125 sc->sc_memset(buffer, 0, 1126 ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len); 1127 len = ETHER_MIN_LEN - ETHER_CRC_LEN; 1128 } else 1129 len = m0->m_pkthdr.len; 1130 1131 m_freem(m0); 1132 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len); 1133 1134 /* Start the first packet transmitting. */ 1135 if (sc->xmit_busy == 0) 1136 iexmit(sc); 1137 1138 sc->xchead = (sc->xchead + 1) % sc->ntxbuf; 1139 sc->xmit_busy++; 1140 } 1141 } 1142 1143 static void 1144 iereset(sc) 1145 struct ie_softc *sc; 1146 { 1147 int s = splnet(); 1148 1149 /* No message here. The caller does that. */ 1150 iestop(sc); 1151 1152 /* 1153 * Stop i82586 dead in its tracks. 1154 */ 1155 if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0)) 1156 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname); 1157 1158 if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0)) 1159 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname); 1160 1161 ieinit(sc); 1162 1163 splx(s); 1164 } 1165 1166 /* 1167 * Send a command to the controller and wait for it to either 1168 * complete or be accepted, depending on the command. If the 1169 * command pointer is null, then pretend that the command is 1170 * not an action command. If the command pointer is not null, 1171 * and the command is an action command, wait for 1172 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK 1173 * to become true. 1174 */ 1175 static int 1176 cmd_and_wait(sc, cmd, pcmd, mask) 1177 struct ie_softc *sc; 1178 int cmd; 1179 void *pcmd; /* XXX - Was volatile */ 1180 int mask; 1181 { 1182 volatile struct ie_cmd_common *cc = pcmd; 1183 volatile struct ie_sys_ctl_block *scb = sc->scb; 1184 int tmo; 1185 1186 scb->ie_command = (u_short)cmd; 1187 (sc->chan_attn)(sc); 1188 1189 /* Wait for the command to be accepted by the CU. */ 1190 tmo = 10; 1191 while (scb->ie_command && --tmo) 1192 delay(10); 1193 if (scb->ie_command) { 1194 #ifdef IEDEBUG 1195 printf("%s: cmd_and_wait, CU stuck (1)\n", 1196 sc->sc_dev.dv_xname); 1197 #endif 1198 return -1; /* timed out */ 1199 } 1200 1201 /* 1202 * If asked, also wait for it to finish. 1203 */ 1204 if (IE_ACTION_COMMAND(cmd) && pcmd) { 1205 1206 /* 1207 * According to the packet driver, the minimum timeout should 1208 * be .369 seconds, which we round up to .4. 1209 */ 1210 tmo = 36900; 1211 1212 /* 1213 * Now spin-lock waiting for status. This is not a very nice 1214 * thing to do, but I haven't figured out how, or indeed if, we 1215 * can put the process waiting for action to sleep. (We may 1216 * be getting called through some other timeout running in the 1217 * kernel.) 1218 */ 1219 while (((cc->ie_cmd_status & mask) == 0) && --tmo) 1220 delay(10); 1221 1222 if ((cc->ie_cmd_status & mask) == 0) { 1223 #ifdef IEDEBUG 1224 printf("%s: cmd_and_wait, CU stuck (2)\n", 1225 sc->sc_dev.dv_xname); 1226 #endif 1227 return -1; /* timed out */ 1228 } 1229 } 1230 return 0; 1231 } 1232 1233 /* 1234 * Run the time-domain reflectometer. 1235 */ 1236 static void 1237 run_tdr(sc, cmd) 1238 struct ie_softc *sc; 1239 struct ie_tdr_cmd *cmd; 1240 { 1241 int result; 1242 1243 cmd->com.ie_cmd_status = SWAP(0); 1244 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST; 1245 cmd->com.ie_cmd_link = SWAP(0xffff); 1246 1247 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1248 cmd->ie_tdr_time = SWAP(0); 1249 1250 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1251 !(cmd->com.ie_cmd_status & IE_STAT_OK)) 1252 result = 0x10000; /* impossible value */ 1253 else 1254 result = cmd->ie_tdr_time; 1255 1256 ie_ack(sc, IE_ST_WHENCE); 1257 1258 if (result & IE_TDR_SUCCESS) 1259 return; 1260 1261 if (result & 0x10000) { 1262 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname); 1263 } else if (result & IE_TDR_XCVR) { 1264 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname); 1265 } else if (result & IE_TDR_OPEN) { 1266 printf("%s: TDR detected an open %d clocks away\n", 1267 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME)); 1268 } else if (result & IE_TDR_SHORT) { 1269 printf("%s: TDR detected a short %d clocks away\n", 1270 sc->sc_dev.dv_xname, SWAP(result & IE_TDR_TIME)); 1271 } else { 1272 printf("%s: TDR returned unknown status 0x%x\n", 1273 sc->sc_dev.dv_xname, result); 1274 } 1275 } 1276 1277 /* 1278 * iememinit: set up the buffers 1279 * 1280 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz. 1281 * this is to be used for the buffers. the chip indexs its control data 1282 * structures with 16 bit offsets, and it indexes actual buffers with 1283 * 24 bit addresses. so we should allocate control buffers first so that 1284 * we don't overflow the 16 bit offset field. The number of transmit 1285 * buffers is fixed at compile time. 1286 * 1287 * note: this function was written to be easy to understand, rather than 1288 * highly efficient (it isn't in the critical path). 1289 * 1290 * The memory layout is: tbufs, rbufs, (gap), control blocks 1291 * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes] 1292 * XXX - This needs review... 1293 */ 1294 static void 1295 iememinit(sc) 1296 struct ie_softc *sc; 1297 { 1298 char *ptr; 1299 int i; 1300 u_short nxt; 1301 1302 /* First, zero all the memory. */ 1303 ptr = sc->buf_area; 1304 (sc->sc_memset)(ptr, 0, sc->buf_area_sz); 1305 1306 /* Allocate tx/rx buffers. */ 1307 for (i = 0; i < NTXBUF; i++) { 1308 sc->xmit_cbuffs[i] = ptr; 1309 ptr += IE_TBUF_SIZE; 1310 } 1311 for (i = 0; i < sc->nrxbuf; i++) { 1312 sc->cbuffs[i] = ptr; 1313 ptr += IE_RBUF_SIZE; 1314 } 1315 1316 /* Small pad (Don't trust the chip...) */ 1317 ptr += 16; 1318 1319 /* Allocate and fill in xmit buffer descriptors. */ 1320 for (i = 0; i < NTXBUF; i++) { 1321 sc->xmit_buffs[i] = (volatile void *) ptr; 1322 ptr = Align(ptr + sizeof(*sc->xmit_buffs[i])); 1323 sc->xmit_buffs[i]->ie_xmit_buf = 1324 Swap32(vtop24(sc, sc->xmit_cbuffs[i])); 1325 sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff); 1326 } 1327 1328 /* Allocate and fill in recv buffer descriptors. */ 1329 for (i = 0; i < sc->nrxbuf; i++) { 1330 sc->rbuffs[i] = (volatile void *) ptr; 1331 ptr = Align(ptr + sizeof(*sc->rbuffs[i])); 1332 sc->rbuffs[i]->ie_rbd_buffer = 1333 Swap32(vtop24(sc, sc->cbuffs[i])); 1334 sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE); 1335 } 1336 1337 /* link together recv bufs and set EOL on last */ 1338 i = sc->nrxbuf - 1; 1339 sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST; 1340 nxt = vtop16sw(sc, (void*) sc->rbuffs[0]); 1341 do { 1342 sc->rbuffs[i]->ie_rbd_next = nxt; 1343 nxt = vtop16sw(sc, (void*) sc->rbuffs[i]); 1344 } while (--i >= 0); 1345 1346 /* Allocate transmit commands. */ 1347 for (i = 0; i < NTXBUF; i++) { 1348 sc->xmit_cmds[i] = (volatile void *) ptr; 1349 ptr = Align(ptr + sizeof(*sc->xmit_cmds[i])); 1350 sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff); 1351 } 1352 1353 /* Allocate receive frames. */ 1354 for (i = 0; i < sc->nframes; i++) { 1355 sc->rframes[i] = (volatile void *) ptr; 1356 ptr = Align(ptr + sizeof(*sc->rframes[i])); 1357 } 1358 1359 /* Link together recv frames and set EOL on last */ 1360 i = sc->nframes - 1; 1361 sc->rframes[i]->ie_fd_last |= IE_FD_LAST; 1362 nxt = vtop16sw(sc, (void*) sc->rframes[0]); 1363 do { 1364 sc->rframes[i]->ie_fd_next = nxt; 1365 nxt = vtop16sw(sc, (void*) sc->rframes[i]); 1366 } while (--i >= 0); 1367 1368 1369 /* Pointers to last packet sent and next available transmit buffer. */ 1370 sc->xchead = sc->xctail = 0; 1371 1372 /* Clear transmit-busy flag. */ 1373 sc->xmit_busy = 0; 1374 1375 /* 1376 * Set the head and tail pointers on receive to keep track of 1377 * the order in which RFDs and RBDs are used. link the 1378 * recv frames and buffer into the scb. 1379 */ 1380 sc->rfhead = 0; 1381 sc->rftail = sc->nframes - 1; 1382 sc->rbhead = 0; 1383 sc->rbtail = sc->nrxbuf - 1; 1384 1385 sc->scb->ie_recv_list = 1386 vtop16sw(sc, (void*) sc->rframes[0]); 1387 sc->rframes[0]->ie_fd_buf_desc = 1388 vtop16sw(sc, (void*) sc->rbuffs[0]); 1389 1390 i = (ptr - sc->buf_area); 1391 #ifdef IEDEBUG 1392 printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz); 1393 #endif 1394 if (i > sc->buf_area_sz) 1395 panic("ie: iememinit, out of space"); 1396 } 1397 1398 /* 1399 * Run the multicast setup command. 1400 * Called at splnet(). 1401 */ 1402 static int 1403 mc_setup(sc, ptr) 1404 struct ie_softc *sc; 1405 void *ptr; 1406 { 1407 struct ie_mcast_cmd *cmd = ptr; /* XXX - Was volatile */ 1408 1409 cmd->com.ie_cmd_status = SWAP(0); 1410 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST; 1411 cmd->com.ie_cmd_link = SWAP(0xffff); 1412 1413 (sc->sc_memcpy)((caddr_t)cmd->ie_mcast_addrs, 1414 (caddr_t)sc->mcast_addrs, 1415 sc->mcast_count * sizeof *sc->mcast_addrs); 1416 1417 cmd->ie_mcast_bytes = 1418 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */ 1419 1420 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1421 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1422 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1423 printf("%s: multicast address setup command failed\n", 1424 sc->sc_dev.dv_xname); 1425 return 0; 1426 } 1427 return 1; 1428 } 1429 1430 static inline void 1431 ie_setup_config(cmd, promiscuous, manchester) 1432 struct ie_config_cmd *cmd; /* XXX - was volatile */ 1433 int promiscuous, manchester; 1434 { 1435 1436 /* 1437 * these are all char's so no need to byte-swap 1438 */ 1439 cmd->ie_config_count = 0x0c; 1440 cmd->ie_fifo = 8; 1441 cmd->ie_save_bad = 0x40; 1442 cmd->ie_addr_len = 0x2e; 1443 cmd->ie_priority = 0; 1444 cmd->ie_ifs = 0x60; 1445 cmd->ie_slot_low = 0; 1446 cmd->ie_slot_high = 0xf2; 1447 cmd->ie_promisc = promiscuous | manchester << 2; 1448 cmd->ie_crs_cdt = 0; 1449 cmd->ie_min_len = 64; 1450 cmd->ie_junk = 0xff; 1451 } 1452 1453 /* 1454 * This routine inits the ie. 1455 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, 1456 * starting the receiver unit, and clearing interrupts. 1457 * 1458 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER. 1459 */ 1460 static int 1461 ieinit(sc) 1462 struct ie_softc *sc; 1463 { 1464 volatile struct ie_sys_ctl_block *scb = sc->scb; 1465 void *ptr; 1466 struct ifnet *ifp; 1467 1468 ifp = &sc->sc_if; 1469 ptr = sc->buf_area; /* XXX - Use scb instead? */ 1470 1471 /* 1472 * Send the configure command first. 1473 */ 1474 { 1475 struct ie_config_cmd *cmd = ptr; /* XXX - Was volatile */ 1476 1477 scb->ie_command_list = vtop16sw(sc, cmd); 1478 cmd->com.ie_cmd_status = SWAP(0); 1479 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST; 1480 cmd->com.ie_cmd_link = SWAP(0xffff); 1481 1482 ie_setup_config(cmd, (sc->promisc != 0), 0); 1483 1484 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1485 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1486 printf("%s: configure command failed\n", 1487 sc->sc_dev.dv_xname); 1488 return 0; 1489 } 1490 } 1491 1492 /* 1493 * Now send the Individual Address Setup command. 1494 */ 1495 { 1496 struct ie_iasetup_cmd *cmd = ptr; /* XXX - Was volatile */ 1497 1498 scb->ie_command_list = vtop16sw(sc, cmd); 1499 cmd->com.ie_cmd_status = SWAP(0); 1500 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; 1501 cmd->com.ie_cmd_link = SWAP(0xffff); 1502 1503 (sc->sc_memcpy)((caddr_t)&cmd->ie_address, 1504 LLADDR(ifp->if_sadl), sizeof(cmd->ie_address)); 1505 1506 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1507 !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1508 printf("%s: individual address setup command failed\n", 1509 sc->sc_dev.dv_xname); 1510 return 0; 1511 } 1512 } 1513 1514 /* 1515 * Now run the time-domain reflectometer. 1516 */ 1517 if (ie_run_tdr) 1518 run_tdr(sc, ptr); 1519 1520 /* 1521 * Acknowledge any interrupts we have generated thus far. 1522 */ 1523 ie_ack(sc, IE_ST_WHENCE); 1524 1525 /* 1526 * Set up the transmit and recv buffers. 1527 */ 1528 iememinit(sc); 1529 1530 /* tell higher levels that we are here */ 1531 ifp->if_flags |= IFF_RUNNING; 1532 ifp->if_flags &= ~IFF_OACTIVE; 1533 1534 sc->scb->ie_recv_list = 1535 vtop16sw(sc, (void*) sc->rframes[0]); 1536 cmd_and_wait(sc, IE_RU_START, 0, 0); 1537 1538 ie_ack(sc, IE_ST_WHENCE); 1539 1540 if (sc->run_586) 1541 (sc->run_586)(sc); 1542 1543 return 0; 1544 } 1545 1546 static void 1547 iestop(sc) 1548 struct ie_softc *sc; 1549 { 1550 1551 cmd_and_wait(sc, IE_RU_DISABLE, 0, 0); 1552 } 1553 1554 static int 1555 ieioctl(ifp, cmd, data) 1556 struct ifnet *ifp; 1557 u_long cmd; 1558 caddr_t data; 1559 { 1560 struct ie_softc *sc = ifp->if_softc; 1561 struct ifaddr *ifa = (struct ifaddr *)data; 1562 struct ifreq *ifr = (struct ifreq *)data; 1563 int s, error = 0; 1564 1565 s = splnet(); 1566 1567 switch (cmd) { 1568 1569 case SIOCSIFADDR: 1570 ifp->if_flags |= IFF_UP; 1571 1572 switch (ifa->ifa_addr->sa_family) { 1573 #ifdef INET 1574 case AF_INET: 1575 ieinit(sc); 1576 arp_ifinit(ifp, ifa); 1577 break; 1578 #endif 1579 #ifdef NS 1580 /* XXX - This code is probably wrong. */ 1581 case AF_NS: 1582 { 1583 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1584 1585 if (ns_nullhost(*ina)) 1586 ina->x_host = 1587 *(union ns_host *)LLADDR(ifp->if_sadl); 1588 else 1589 memcpy(LLADDR(ifp->if_sadl), 1590 ina->x_host.c_host, ETHER_ADDR_LEN); 1591 /* Set new address. */ 1592 ieinit(sc); 1593 break; 1594 } 1595 #endif /* NS */ 1596 default: 1597 ieinit(sc); 1598 break; 1599 } 1600 break; 1601 1602 case SIOCSIFFLAGS: 1603 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); 1604 1605 if ((ifp->if_flags & IFF_UP) == 0 && 1606 (ifp->if_flags & IFF_RUNNING) != 0) { 1607 /* 1608 * If interface is marked down and it is running, then 1609 * stop it. 1610 */ 1611 iestop(sc); 1612 ifp->if_flags &= ~IFF_RUNNING; 1613 } else if ((ifp->if_flags & IFF_UP) != 0 && 1614 (ifp->if_flags & IFF_RUNNING) == 0) { 1615 /* 1616 * If interface is marked up and it is stopped, then 1617 * start it. 1618 */ 1619 ieinit(sc); 1620 } else { 1621 /* 1622 * Reset the interface to pick up changes in any other 1623 * flags that affect hardware registers. 1624 */ 1625 iestop(sc); 1626 ieinit(sc); 1627 } 1628 #ifdef IEDEBUG 1629 if (ifp->if_flags & IFF_DEBUG) 1630 sc->sc_debug = IED_ALL; 1631 else 1632 sc->sc_debug = ie_debug_flags; 1633 #endif 1634 break; 1635 1636 case SIOCADDMULTI: 1637 case SIOCDELMULTI: 1638 error = (cmd == SIOCADDMULTI) ? 1639 ether_addmulti(ifr, &sc->sc_ethercom) : 1640 ether_delmulti(ifr, &sc->sc_ethercom); 1641 1642 if (error == ENETRESET) { 1643 /* 1644 * Multicast list has changed; set the hardware filter 1645 * accordingly. 1646 */ 1647 mc_reset(sc); 1648 error = 0; 1649 } 1650 break; 1651 1652 default: 1653 error = EINVAL; 1654 } 1655 splx(s); 1656 return error; 1657 } 1658 1659 static void 1660 mc_reset(sc) 1661 struct ie_softc *sc; 1662 { 1663 struct ether_multi *enm; 1664 struct ether_multistep step; 1665 struct ifnet *ifp; 1666 1667 ifp = &sc->sc_if; 1668 1669 /* 1670 * Step through the list of addresses. 1671 */ 1672 sc->mcast_count = 0; 1673 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1674 while (enm) { 1675 if (sc->mcast_count >= MAXMCAST || 1676 ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) { 1677 ifp->if_flags |= IFF_ALLMULTI; 1678 ieioctl(ifp, SIOCSIFFLAGS, (void *)0); 1679 goto setflag; 1680 } 1681 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 1682 ETHER_ADDR_LEN); 1683 sc->mcast_count++; 1684 ETHER_NEXT_MULTI(step, enm); 1685 } 1686 setflag: 1687 sc->want_mcsetup = 1; 1688 } 1689 1690 #ifdef IEDEBUG 1691 void 1692 print_rbd(rbd) 1693 volatile struct ie_recv_buf_desc *rbd; 1694 { 1695 1696 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n" 1697 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual, 1698 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length, 1699 rbd->mbz); 1700 } 1701 #endif 1702