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