1 /* $NetBSD: if_ie.c,v 1.61 2016/12/15 09:28:04 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.61 2016/12/15 09:28:04 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 /* 924 * Finally pass this packet up to higher layers. 925 */ 926 if_percpuq_enqueue((&sc->sc_if)->if_percpuq, m); 927 } 928 929 static void 930 ie_drop_packet_buffer(struct ie_softc *sc) 931 { 932 int i; 933 934 do { 935 /* 936 * This means we are somehow out of sync. So, we reset the 937 * adapter. 938 */ 939 if ((sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED) 940 == 0) { 941 #ifdef IEDEBUG 942 print_rbd(sc->rbuffs[sc->rbhead]); 943 #endif 944 log(LOG_ERR, 945 "%s: receive descriptors out of sync at %d\n", 946 device_xname(sc->sc_dev), sc->rbhead); 947 iereset(sc); 948 return; 949 } 950 951 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST; 952 953 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST; 954 sc->rbuffs[sc->rbhead]->ie_rbd_actual = SWAP(0); 955 sc->rbhead = (sc->rbhead + 1) % sc->nrxbuf; 956 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; 957 sc->rbtail = (sc->rbtail + 1) % sc->nrxbuf; 958 } while (i == 0); 959 } 960 961 /* 962 * Start transmission on an interface. 963 */ 964 static void 965 iestart(struct ifnet *ifp) 966 { 967 struct ie_softc *sc = ifp->if_softc; 968 struct mbuf *m0, *m; 969 uint8_t *buffer; 970 uint16_t len; 971 972 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 973 return; 974 975 for (;;) { 976 if (sc->xmit_busy == sc->ntxbuf) { 977 ifp->if_flags |= IFF_OACTIVE; 978 break; 979 } 980 981 IF_DEQUEUE(&ifp->if_snd, m0); 982 if (m0 == 0) 983 break; 984 985 /* We need to use m->m_pkthdr.len, so require the header */ 986 if ((m0->m_flags & M_PKTHDR) == 0) 987 panic("%s: no header mbuf", __func__); 988 989 /* Tap off here if there is a BPF listener. */ 990 bpf_mtap(ifp, m0); 991 992 #ifdef IEDEBUG 993 if (sc->sc_debug & IED_ENQ) 994 printf("%s: fill buffer %d\n", device_xname(sc->sc_dev), 995 sc->xchead); 996 #endif 997 998 buffer = sc->xmit_cbuffs[sc->xchead]; 999 for (m = m0; m != 0; m = m->m_next) { 1000 (sc->sc_memcpy)(buffer, mtod(m, void *), m->m_len); 1001 buffer += m->m_len; 1002 } 1003 if (m0->m_pkthdr.len < ETHER_MIN_LEN - ETHER_CRC_LEN) { 1004 sc->sc_memset(buffer, 0, 1005 ETHER_MIN_LEN - ETHER_CRC_LEN - m0->m_pkthdr.len); 1006 len = ETHER_MIN_LEN - ETHER_CRC_LEN; 1007 } else 1008 len = m0->m_pkthdr.len; 1009 1010 m_freem(m0); 1011 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = SWAP(len); 1012 1013 /* Start the first packet transmitting. */ 1014 if (sc->xmit_busy == 0) 1015 iexmit(sc); 1016 1017 sc->xchead = (sc->xchead + 1) % sc->ntxbuf; 1018 sc->xmit_busy++; 1019 } 1020 } 1021 1022 static void 1023 iereset(struct ie_softc *sc) 1024 { 1025 int s; 1026 1027 s = splnet(); 1028 1029 /* No message here. The caller does that. */ 1030 iestop(sc); 1031 1032 /* 1033 * Stop i82586 dead in its tracks. 1034 */ 1035 if (cmd_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0)) 1036 printf("%s: abort commands timed out\n", 1037 device_xname(sc->sc_dev)); 1038 1039 if (cmd_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0)) 1040 printf("%s: disable commands timed out\n", 1041 device_xname(sc->sc_dev)); 1042 1043 ieinit(sc); 1044 1045 splx(s); 1046 } 1047 1048 /* 1049 * Send a command to the controller and wait for it to either 1050 * complete or be accepted, depending on the command. If the 1051 * command pointer is null, then pretend that the command is 1052 * not an action command. If the command pointer is not null, 1053 * and the command is an action command, wait for 1054 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK 1055 * to become true. 1056 */ 1057 static int 1058 cmd_and_wait(struct ie_softc *sc, int cmd, void *pcmd, int mask) 1059 { 1060 volatile struct ie_cmd_common *cc = pcmd; 1061 volatile struct ie_sys_ctl_block *scb = sc->scb; 1062 int tmo; 1063 1064 scb->ie_command = (uint16_t)cmd; 1065 (sc->chan_attn)(sc); 1066 1067 /* Wait for the command to be accepted by the CU. */ 1068 tmo = 10; 1069 while (scb->ie_command && --tmo) 1070 delay(10); 1071 if (scb->ie_command) { 1072 #ifdef IEDEBUG 1073 printf("%s: cmd_and_wait, CU stuck (1)\n", 1074 device_xname(sc->sc_dev)); 1075 #endif 1076 return -1; /* timed out */ 1077 } 1078 1079 /* 1080 * If asked, also wait for it to finish. 1081 */ 1082 if (IE_ACTION_COMMAND(cmd) && pcmd) { 1083 1084 /* 1085 * According to the packet driver, the minimum timeout should 1086 * be .369 seconds, which we round up to .4. 1087 */ 1088 tmo = 36900; 1089 1090 /* 1091 * Now spin-lock waiting for status. This is not a very nice 1092 * thing to do, but I haven't figured out how, or indeed if, we 1093 * can put the process waiting for action to sleep. (We may 1094 * be getting called through some other timeout running in the 1095 * kernel.) 1096 */ 1097 while (((cc->ie_cmd_status & mask) == 0) && --tmo) 1098 delay(10); 1099 1100 if ((cc->ie_cmd_status & mask) == 0) { 1101 #ifdef IEDEBUG 1102 printf("%s: cmd_and_wait, CU stuck (2)\n", 1103 device_xname(sc->sc_dev)); 1104 #endif 1105 return -1; /* timed out */ 1106 } 1107 } 1108 return 0; 1109 } 1110 1111 /* 1112 * Run the time-domain reflectometer. 1113 */ 1114 static void 1115 run_tdr(struct ie_softc *sc, struct ie_tdr_cmd *cmd) 1116 { 1117 int result; 1118 1119 cmd->com.ie_cmd_status = SWAP(0); 1120 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST; 1121 cmd->com.ie_cmd_link = SWAP(0xffff); 1122 1123 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1124 cmd->ie_tdr_time = SWAP(0); 1125 1126 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1127 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) 1128 result = 0x10000; /* impossible value */ 1129 else 1130 result = cmd->ie_tdr_time; 1131 1132 ie_ack(sc, IE_ST_WHENCE); 1133 1134 if (result & IE_TDR_SUCCESS) 1135 return; 1136 1137 if (result & 0x10000) { 1138 printf("%s: TDR command failed\n", device_xname(sc->sc_dev)); 1139 } else if (result & IE_TDR_XCVR) { 1140 printf("%s: transceiver problem\n", device_xname(sc->sc_dev)); 1141 } else if (result & IE_TDR_OPEN) { 1142 printf("%s: TDR detected an open %d clocks away\n", 1143 device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME)); 1144 } else if (result & IE_TDR_SHORT) { 1145 printf("%s: TDR detected a short %d clocks away\n", 1146 device_xname(sc->sc_dev), SWAP(result & IE_TDR_TIME)); 1147 } else { 1148 printf("%s: TDR returned unknown status 0x%x\n", 1149 device_xname(sc->sc_dev), result); 1150 } 1151 } 1152 1153 /* 1154 * iememinit: set up the buffers 1155 * 1156 * we have a block of KVA at sc->buf_area which is of size sc->buf_area_sz. 1157 * this is to be used for the buffers. the chip indexs its control data 1158 * structures with 16 bit offsets, and it indexes actual buffers with 1159 * 24 bit addresses. so we should allocate control buffers first so that 1160 * we don't overflow the 16 bit offset field. The number of transmit 1161 * buffers is fixed at compile time. 1162 * 1163 * note: this function was written to be easy to understand, rather than 1164 * highly efficient (it isn't in the critical path). 1165 * 1166 * The memory layout is: tbufs, rbufs, (gap), control blocks 1167 * [tbuf0, tbuf1] [rbuf0,...rbufN] gap [rframes] [tframes] 1168 * XXX - This needs review... 1169 */ 1170 static void 1171 iememinit(struct ie_softc *sc) 1172 { 1173 uint8_t *ptr; 1174 int i; 1175 uint16_t nxt; 1176 1177 /* First, zero all the memory. */ 1178 ptr = sc->buf_area; 1179 (sc->sc_memset)(ptr, 0, sc->buf_area_sz); 1180 1181 /* Allocate tx/rx buffers. */ 1182 for (i = 0; i < NTXBUF; i++) { 1183 sc->xmit_cbuffs[i] = ptr; 1184 ptr += IE_TBUF_SIZE; 1185 } 1186 for (i = 0; i < sc->nrxbuf; i++) { 1187 sc->cbuffs[i] = ptr; 1188 ptr += IE_RBUF_SIZE; 1189 } 1190 1191 /* Small pad (Don't trust the chip...) */ 1192 ptr += 16; 1193 1194 /* Allocate and fill in xmit buffer descriptors. */ 1195 for (i = 0; i < NTXBUF; i++) { 1196 sc->xmit_buffs[i] = (volatile void *)ptr; 1197 ptr = Align(ptr + sizeof(*sc->xmit_buffs[i])); 1198 sc->xmit_buffs[i]->ie_xmit_buf = 1199 Swap32(vtop24(sc, sc->xmit_cbuffs[i])); 1200 sc->xmit_buffs[i]->ie_xmit_next = SWAP(0xffff); 1201 } 1202 1203 /* Allocate and fill in recv buffer descriptors. */ 1204 for (i = 0; i < sc->nrxbuf; i++) { 1205 sc->rbuffs[i] = (volatile void *)ptr; 1206 ptr = Align(ptr + sizeof(*sc->rbuffs[i])); 1207 sc->rbuffs[i]->ie_rbd_buffer = 1208 Swap32(vtop24(sc, sc->cbuffs[i])); 1209 sc->rbuffs[i]->ie_rbd_length = SWAP(IE_RBUF_SIZE); 1210 } 1211 1212 /* link together recv bufs and set EOL on last */ 1213 i = sc->nrxbuf - 1; 1214 sc->rbuffs[i]->ie_rbd_length |= IE_RBD_LAST; 1215 nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0])); 1216 do { 1217 sc->rbuffs[i]->ie_rbd_next = nxt; 1218 nxt = vtop16sw(sc, __UNVOLATILE(sc->rbuffs[i])); 1219 } while (--i >= 0); 1220 1221 /* Allocate transmit commands. */ 1222 for (i = 0; i < NTXBUF; i++) { 1223 sc->xmit_cmds[i] = (volatile void *)ptr; 1224 ptr = Align(ptr + sizeof(*sc->xmit_cmds[i])); 1225 sc->xmit_cmds[i]->com.ie_cmd_link = SWAP(0xffff); 1226 } 1227 1228 /* Allocate receive frames. */ 1229 for (i = 0; i < sc->nframes; i++) { 1230 sc->rframes[i] = (volatile void *)ptr; 1231 ptr = Align(ptr + sizeof(*sc->rframes[i])); 1232 } 1233 1234 /* Link together recv frames and set EOL on last */ 1235 i = sc->nframes - 1; 1236 sc->rframes[i]->ie_fd_last |= IE_FD_LAST; 1237 nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[0])); 1238 do { 1239 sc->rframes[i]->ie_fd_next = nxt; 1240 nxt = vtop16sw(sc, __UNVOLATILE(sc->rframes[i])); 1241 } while (--i >= 0); 1242 1243 1244 /* Pointers to last packet sent and next available transmit buffer. */ 1245 sc->xchead = sc->xctail = 0; 1246 1247 /* Clear transmit-busy flag. */ 1248 sc->xmit_busy = 0; 1249 1250 /* 1251 * Set the head and tail pointers on receive to keep track of 1252 * the order in which RFDs and RBDs are used. link the 1253 * recv frames and buffer into the scb. 1254 */ 1255 sc->rfhead = 0; 1256 sc->rftail = sc->nframes - 1; 1257 sc->rbhead = 0; 1258 sc->rbtail = sc->nrxbuf - 1; 1259 1260 sc->scb->ie_recv_list = 1261 vtop16sw(sc, __UNVOLATILE(sc->rframes[0])); 1262 sc->rframes[0]->ie_fd_buf_desc = 1263 vtop16sw(sc, __UNVOLATILE(sc->rbuffs[0])); 1264 1265 i = (ptr - sc->buf_area); 1266 #ifdef IEDEBUG 1267 printf("IE_DEBUG: used %d of %d bytes\n", i, sc->buf_area_sz); 1268 #endif 1269 if (i > sc->buf_area_sz) 1270 panic("ie: iememinit, out of space"); 1271 } 1272 1273 /* 1274 * Run the multicast setup command. 1275 * Called at splnet(). 1276 */ 1277 static int 1278 mc_setup(struct ie_softc *sc, void *ptr) 1279 { 1280 struct ie_mcast_cmd *cmd = ptr; /* XXX - Was volatile */ 1281 1282 cmd->com.ie_cmd_status = SWAP(0); 1283 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST; 1284 cmd->com.ie_cmd_link = SWAP(0xffff); 1285 1286 (sc->sc_memcpy)((void *)cmd->ie_mcast_addrs, 1287 (void *)sc->mcast_addrs, 1288 sc->mcast_count * sizeof *sc->mcast_addrs); 1289 1290 cmd->ie_mcast_bytes = 1291 SWAP(sc->mcast_count * ETHER_ADDR_LEN); /* grrr... */ 1292 1293 sc->scb->ie_command_list = vtop16sw(sc, cmd); 1294 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1295 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) { 1296 printf("%s: multicast address setup command failed\n", 1297 device_xname(sc->sc_dev)); 1298 return 0; 1299 } 1300 return 1; 1301 } 1302 1303 static inline void 1304 ie_setup_config(struct ie_config_cmd *cmd, int promiscuous, int manchester) 1305 { 1306 1307 /* 1308 * these are all char's so no need to byte-swap 1309 */ 1310 cmd->ie_config_count = 0x0c; 1311 cmd->ie_fifo = 8; 1312 cmd->ie_save_bad = 0x40; 1313 cmd->ie_addr_len = 0x2e; 1314 cmd->ie_priority = 0; 1315 cmd->ie_ifs = 0x60; 1316 cmd->ie_slot_low = 0; 1317 cmd->ie_slot_high = 0xf2; 1318 cmd->ie_promisc = promiscuous | manchester << 2; 1319 cmd->ie_crs_cdt = 0; 1320 cmd->ie_min_len = 64; 1321 cmd->ie_junk = 0xff; 1322 } 1323 1324 /* 1325 * This routine inits the ie. 1326 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, 1327 * starting the receiver unit, and clearing interrupts. 1328 * 1329 * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER. 1330 */ 1331 static int 1332 ieinit(struct ie_softc *sc) 1333 { 1334 volatile struct ie_sys_ctl_block *scb = sc->scb; 1335 void *ptr; 1336 struct ifnet *ifp; 1337 1338 ifp = &sc->sc_if; 1339 ptr = sc->buf_area; /* XXX - Use scb instead? */ 1340 1341 /* 1342 * Send the configure command first. 1343 */ 1344 { 1345 struct ie_config_cmd *cmd = ptr; /* XXX - Was volatile */ 1346 1347 scb->ie_command_list = vtop16sw(sc, cmd); 1348 cmd->com.ie_cmd_status = SWAP(0); 1349 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST; 1350 cmd->com.ie_cmd_link = SWAP(0xffff); 1351 1352 ie_setup_config(cmd, (sc->promisc != 0), 0); 1353 1354 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1355 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) { 1356 printf("%s: configure command failed\n", 1357 device_xname(sc->sc_dev)); 1358 return 0; 1359 } 1360 } 1361 1362 /* 1363 * Now send the Individual Address Setup command. 1364 */ 1365 { 1366 struct ie_iasetup_cmd *cmd = ptr; /* XXX - Was volatile */ 1367 1368 scb->ie_command_list = vtop16sw(sc, cmd); 1369 cmd->com.ie_cmd_status = SWAP(0); 1370 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; 1371 cmd->com.ie_cmd_link = SWAP(0xffff); 1372 1373 (sc->sc_memcpy)((void *)&cmd->ie_address, 1374 CLLADDR(ifp->if_sadl), sizeof(cmd->ie_address)); 1375 1376 if (cmd_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) || 1377 (cmd->com.ie_cmd_status & IE_STAT_OK) == 0) { 1378 printf("%s: individual address setup command failed\n", 1379 device_xname(sc->sc_dev)); 1380 return 0; 1381 } 1382 } 1383 1384 /* 1385 * Now run the time-domain reflectometer. 1386 */ 1387 if (ie_run_tdr) 1388 run_tdr(sc, ptr); 1389 1390 /* 1391 * Acknowledge any interrupts we have generated thus far. 1392 */ 1393 ie_ack(sc, IE_ST_WHENCE); 1394 1395 /* 1396 * Set up the transmit and recv buffers. 1397 */ 1398 iememinit(sc); 1399 1400 /* tell higher levels that we are here */ 1401 ifp->if_flags |= IFF_RUNNING; 1402 ifp->if_flags &= ~IFF_OACTIVE; 1403 1404 sc->scb->ie_recv_list = 1405 vtop16sw(sc, __UNVOLATILE(sc->rframes[0])); 1406 cmd_and_wait(sc, IE_RU_START, 0, 0); 1407 1408 ie_ack(sc, IE_ST_WHENCE); 1409 1410 if (sc->run_586) 1411 (sc->run_586)(sc); 1412 1413 return 0; 1414 } 1415 1416 static void 1417 iestop(struct ie_softc *sc) 1418 { 1419 1420 cmd_and_wait(sc, IE_RU_DISABLE, 0, 0); 1421 } 1422 1423 static int 1424 ieioctl(struct ifnet *ifp, u_long cmd, void *data) 1425 { 1426 struct ie_softc *sc = ifp->if_softc; 1427 struct ifaddr *ifa = (struct ifaddr *)data; 1428 int s, error = 0; 1429 1430 s = splnet(); 1431 1432 switch (cmd) { 1433 1434 case SIOCINITIFADDR: 1435 ifp->if_flags |= IFF_UP; 1436 1437 switch (ifa->ifa_addr->sa_family) { 1438 #ifdef INET 1439 case AF_INET: 1440 ieinit(sc); 1441 arp_ifinit(ifp, ifa); 1442 break; 1443 #endif 1444 default: 1445 ieinit(sc); 1446 break; 1447 } 1448 break; 1449 1450 case SIOCSIFFLAGS: 1451 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 1452 break; 1453 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); 1454 1455 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 1456 case IFF_RUNNING: 1457 /* 1458 * If interface is marked down and it is running, then 1459 * stop it. 1460 */ 1461 iestop(sc); 1462 ifp->if_flags &= ~IFF_RUNNING; 1463 break; 1464 case IFF_UP: 1465 /* 1466 * If interface is marked up and it is stopped, then 1467 * start it. 1468 */ 1469 ieinit(sc); 1470 break; 1471 default: 1472 /* 1473 * Reset the interface to pick up changes in any other 1474 * flags that affect hardware registers. 1475 */ 1476 iestop(sc); 1477 ieinit(sc); 1478 break; 1479 } 1480 #ifdef IEDEBUG 1481 if (ifp->if_flags & IFF_DEBUG) 1482 sc->sc_debug = IED_ALL; 1483 else 1484 sc->sc_debug = ie_debug_flags; 1485 #endif 1486 break; 1487 1488 case SIOCADDMULTI: 1489 case SIOCDELMULTI: 1490 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 1491 /* 1492 * Multicast list has changed; set the hardware filter 1493 * accordingly. 1494 */ 1495 if (ifp->if_flags & IFF_RUNNING) 1496 mc_reset(sc); 1497 error = 0; 1498 } 1499 break; 1500 1501 default: 1502 error = ether_ioctl(ifp, cmd, data); 1503 break; 1504 } 1505 splx(s); 1506 return error; 1507 } 1508 1509 static void 1510 mc_reset(struct ie_softc *sc) 1511 { 1512 struct ether_multi *enm; 1513 struct ether_multistep step; 1514 struct ifnet *ifp; 1515 1516 ifp = &sc->sc_if; 1517 1518 /* 1519 * Step through the list of addresses. 1520 */ 1521 sc->mcast_count = 0; 1522 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1523 while (enm) { 1524 if (sc->mcast_count >= MAXMCAST || 1525 ether_cmp(enm->enm_addrlo, enm->enm_addrhi) != 0) { 1526 ifp->if_flags |= IFF_ALLMULTI; 1527 ieioctl(ifp, SIOCSIFFLAGS, NULL); 1528 goto setflag; 1529 } 1530 memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 1531 ETHER_ADDR_LEN); 1532 sc->mcast_count++; 1533 ETHER_NEXT_MULTI(step, enm); 1534 } 1535 setflag: 1536 sc->want_mcsetup = 1; 1537 } 1538 1539 #ifdef IEDEBUG 1540 void 1541 print_rbd(volatile struct ie_recv_buf_desc *rbd) 1542 { 1543 1544 printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n" 1545 "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual, 1546 rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length, 1547 rbd->mbz); 1548 } 1549 #endif 1550