if_ie.c revision 320923
1/*- 2 * Copyright (c) 1992, 1993, University of Vermont and State 3 * Agricultural College. 4 * Copyright (c) 1992, 1993, Garrett A. Wollman. 5 * 6 * Portions: 7 * Copyright (c) 1990, 1991, William F. Jolitz 8 * Copyright (c) 1990, The Regents of the University of California 9 * 10 * 3Com 3C507 support: 11 * Copyright (c) 1993, 1994, Charles M. Hannum 12 * 13 * EtherExpress 16 support: 14 * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes 15 * Copyright (c) 1997, Aaron C. Smith 16 * 17 * All rights reserved. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 1. Redistributions of source code must retain the above copyright 23 * notice, this list of conditions and the following disclaimer. 24 * 2. Redistributions in binary form must reproduce the above copyright 25 * notice, this list of conditions and the following disclaimer in the 26 * documentation and/or other materials provided with the distribution. 27 * 3. All advertising materials mentioning features or use of this software 28 * must display the following acknowledgement: 29 * This product includes software developed by the University of 30 * Vermont and State Agricultural College and Garrett A. Wollman, by 31 * William F. Jolitz, by the University of California, Berkeley, 32 * Lawrence Berkeley Laboratory, and their contributors, by 33 * Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith. 34 * 4. Neither the names of the Universities nor the names of the authors 35 * may be used to endorse or promote products derived from this software 36 * without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE 42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * 50 * MAINTAINER: Matthew N. Dodd <winter@jurai.net> 51 */ 52 53#include <sys/cdefs.h> 54__FBSDID("$FreeBSD: stable/10/sys/dev/ie/if_ie.c 320923 2017-07-12 22:16:54Z jhb $"); 55 56/* 57 * Intel 82586 Ethernet chip 58 * Register, bit, and structure definitions. 59 * 60 * Written by GAW with reference to the Clarkson Packet Driver code for this 61 * chip written by Russ Nelson and others. 62 * 63 * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes. 64 */ 65 66/* 67 * The i82586 is a very versatile chip, found in many implementations. 68 * Programming this chip is mostly the same, but certain details differ 69 * from card to card. This driver is written so that different cards 70 * can be automatically detected at run-time. 71 */ 72 73/* 74 * Mode of operation: 75 * 76 * We run the 82586 in a standard Ethernet mode. We keep NFRAMES 77 * received frame descriptors around for the receiver to use, and 78 * NRXBUFS associated receive buffer descriptors, both in a circular 79 * list. Whenever a frame is received, we rotate both lists as 80 * necessary. (The 586 treats both lists as a simple queue.) We also 81 * keep a transmit command around so that packets can be sent off 82 * quickly. 83 * 84 * We configure the adapter in AL-LOC = 1 mode, which means that the 85 * Ethernet/802.3 MAC header is placed at the beginning of the receive 86 * buffer rather than being split off into various fields in the RFD. 87 * This also means that we must include this header in the transmit 88 * buffer as well. 89 * 90 * By convention, all transmit commands, and only transmit commands, 91 * shall have the I (IE_CMD_INTR) bit set in the command. This way, 92 * when an interrupt arrives at ieintr(), it is immediately possible 93 * to tell what precisely caused it. ANY OTHER command-sending routines 94 * should run at splimp(), and should post an acknowledgement to every 95 * interrupt they generate. 96 * 97 * The 82586 has a 24-bit address space internally, and the adaptor's 98 * memory is located at the top of this region. However, the value 99 * we are given in configuration is normally the *bottom* of the adaptor 100 * RAM. So, we must go through a few gyrations to come up with a 101 * kernel virtual address which represents the actual beginning of the 102 * 586 address space. First, we autosize the RAM by running through 103 * several possible sizes and trying to initialize the adapter under 104 * the assumption that the selected size is correct. Then, knowing 105 * the correct RAM size, we set up our pointers in the softc `iomem' 106 * represents the computed base of the 586 address space. `iomembot' 107 * represents the actual configured base of adapter RAM. Finally, 108 * `iosize' represents the calculated size of 586 RAM. Then, when 109 * laying out commands, we use the interval [iomembot, iomembot + 110 * iosize); to make 24-pointers, we subtract iomem, and to make 111 * 16-pointers, we subtract iomem and and with 0xffff. 112 */ 113 114#include <sys/param.h> 115#include <sys/systm.h> 116#include <sys/eventhandler.h> 117#include <sys/kernel.h> 118#include <sys/malloc.h> 119#include <sys/mbuf.h> 120#include <sys/socket.h> 121#include <sys/sockio.h> 122#include <sys/syslog.h> 123 124#include <sys/module.h> 125#include <sys/bus.h> 126 127#include <machine/bus.h> 128#include <machine/resource.h> 129#include <sys/rman.h> 130 131#include <net/ethernet.h> 132#include <net/if.h> 133#include <net/if_types.h> 134#include <net/if_dl.h> 135 136#include <netinet/in.h> 137#include <netinet/if_ether.h> 138 139#include <dev/ic/i82586.h> 140#include <dev/ie/if_ievar.h> 141#include <dev/ie/if_iereg.h> 142#include <dev/ie/if_ie507.h> 143#include <dev/ie/if_iee16.h> 144#include <i386/isa/elink.h> 145 146#include <net/bpf.h> 147 148#ifdef DEBUG 149#define IED_RINT 0x01 150#define IED_TINT 0x02 151#define IED_RNR 0x04 152#define IED_CNA 0x08 153#define IED_READFRAME 0x10 154static int ie_debug = IED_RNR; 155 156#endif 157 158#define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */ 159 160/* XXX this driver uses `volatile' and `caddr_t' to a fault. */ 161typedef volatile char *v_caddr_t; /* core address, pointer to volatile */ 162 163/* Forward declaration */ 164struct ie_softc; 165 166static void ieinit (void *); 167static void ieinit_locked (struct ie_softc *); 168static void ie_stop (struct ie_softc *); 169static int ieioctl (struct ifnet *, u_long, caddr_t); 170static void iestart (struct ifnet *); 171static void iestart_locked (struct ifnet *); 172 173static __inline void 174 ee16_interrupt_enable (struct ie_softc *); 175 176static __inline void 177 ie_ack (struct ie_softc *, u_int); 178static void iereset (struct ie_softc *); 179static void ie_readframe (struct ie_softc *, int); 180static void ie_drop_packet_buffer (struct ie_softc *); 181static int command_and_wait (struct ie_softc *, 182 int, void volatile *, int); 183static void run_tdr (struct ie_softc *, 184 volatile struct ie_tdr_cmd *); 185static int ierint (struct ie_softc *); 186static int ietint (struct ie_softc *); 187static int iernr (struct ie_softc *); 188static void start_receiver (struct ie_softc *); 189static __inline int 190 ieget (struct ie_softc *, struct mbuf **); 191static v_caddr_t setup_rfa (struct ie_softc *, v_caddr_t); 192static int mc_setup (struct ie_softc *); 193static void ie_mc_reset (struct ie_softc *); 194 195#ifdef DEBUG 196static void print_rbd (volatile struct ie_recv_buf_desc * rbd); 197static int in_ierint = 0; 198static int in_ietint = 0; 199#endif 200 201static const char *ie_hardware_names[] = { 202 "None", 203 "StarLAN 10", 204 "EN100", 205 "StarLAN Fiber", 206 "3C507", 207 "NI5210", 208 "EtherExpress 16", 209 "Unknown" 210}; 211 212/* 213 * sizeof(iscp) == 1+1+2+4 == 8 214 * sizeof(scb) == 2+2+2+2+2+2+2+2 == 16 215 * NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384 216 * sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18 217 * sizeof(transmit buffer) == 1512 218 * sizeof(transmit buffer desc) == 8 219 * ----- 220 * 1946 221 * 222 * NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12 223 * NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256 224 * 225 * NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53 226 * 227 * With NRXBUFS == 48, this leaves us 1574 bytes for another command or 228 * more buffers. Another transmit command would be 18+8+1512 == 1538 229 * ---just barely fits! 230 * 231 * Obviously all these would have to be reduced for smaller memory sizes. 232 * With a larger memory, it would be possible to roughly double the number 233 * of both transmit and receive buffers. 234 */ 235 236#define NFRAMES 4 /* number of receive frames */ 237#define NRXBUFS 24 /* number of buffers to allocate */ 238#define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */ 239#define NTXBUFS 1 /* number of transmit commands */ 240#define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */ 241 242#define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base)) 243#define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr)) 244 245void 246ee16_shutdown(struct ie_softc *sc) 247{ 248 249 ee16_reset_586(sc); 250 outb(PORT(sc) + IEE16_ECTRL, IEE16_RESET_ASIC); 251 outb(PORT(sc) + IEE16_ECTRL, 0); 252} 253 254/* 255 * Taken almost exactly from Bill's if_is.c, then modified beyond recognition. 256 */ 257int 258ie_attach(device_t dev) 259{ 260 struct ie_softc * sc; 261 struct ifnet * ifp; 262 size_t allocsize; 263 int error, factor; 264 265 sc = device_get_softc(dev); 266 ifp = sc->ifp = if_alloc(IFT_ETHER); 267 if (ifp == NULL) { 268 device_printf(sc->dev, "can not if_alloc()\n"); 269 return (ENOSPC); 270 } 271 272 sc->dev = dev; 273 mtx_init(&sc->lock, device_get_nameunit(dev), MTX_NETWORK_LOCK, 274 MTX_DEF); 275 276 /* 277 * based on the amount of memory we have, allocate our tx and rx 278 * resources. 279 */ 280 factor = rman_get_size(sc->mem_res) / 8192; 281 sc->nframes = factor * NFRAMES; 282 sc->nrxbufs = factor * NRXBUFS; 283 sc->ntxbufs = factor * NTXBUFS; 284 285 /* 286 * Since all of these guys are arrays of pointers, allocate as one 287 * big chunk and dole out accordingly. 288 */ 289 allocsize = sizeof(void *) * (sc->nframes 290 + (sc->nrxbufs * 2) 291 + (sc->ntxbufs * 3)); 292 sc->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize, 293 M_DEVBUF, 294 M_NOWAIT); 295 if (sc->rframes == NULL) { 296 mtx_destroy(&sc->lock); 297 return (ENXIO); 298 } 299 sc->rbuffs = 300 (volatile struct ie_recv_buf_desc **)&sc->rframes[sc->nframes]; 301 sc->cbuffs = (volatile u_char **)&sc->rbuffs[sc->nrxbufs]; 302 sc->xmit_cmds = 303 (volatile struct ie_xmit_cmd **)&sc->cbuffs[sc->nrxbufs]; 304 sc->xmit_buffs = 305 (volatile struct ie_xmit_buf **)&sc->xmit_cmds[sc->ntxbufs]; 306 sc->xmit_cbuffs = (volatile u_char **)&sc->xmit_buffs[sc->ntxbufs]; 307 308 if (bootverbose) 309 device_printf(sc->dev, "hardware type %s, revision %d\n", 310 ie_hardware_names[sc->hard_type], sc->hard_vers + 1); 311 312 ifp->if_softc = sc; 313 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 314 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 315 ifp->if_start = iestart; 316 ifp->if_ioctl = ieioctl; 317 ifp->if_init = ieinit; 318 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 319 320 ether_ifattach(ifp, sc->enaddr); 321 322 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 323 NULL, ie_intr, sc, &sc->irq_ih); 324 if (error) { 325 device_printf(dev, "Unable to register interrupt handler\n"); 326 mtx_destroy(&sc->lock); 327 return (error); 328 } 329 device_printf(dev, 330 "WARNING: This driver is deprecated and will be removed.\n"); 331 332 return (0); 333} 334 335static __inline void 336ie_ack(struct ie_softc *sc, u_int mask) 337{ 338 339 sc->scb->ie_command = sc->scb->ie_status & mask; 340 (*sc->ie_chan_attn) (sc); 341} 342 343/* 344 * What to do upon receipt of an interrupt. 345 */ 346void 347ie_intr(void *xsc) 348{ 349 struct ie_softc *sc = (struct ie_softc *)xsc; 350 u_short status; 351 352 IE_LOCK(sc); 353 354 /* Clear the interrupt latch on the 3C507. */ 355 if (sc->hard_type == IE_3C507 356 && (inb(PORT(sc) + IE507_CTRL) & EL_CTRL_INTL)) 357 outb(PORT(sc) + IE507_ICTRL, 1); 358 359 /* disable interrupts on the EE16. */ 360 if (sc->hard_type == IE_EE16) 361 outb(PORT(sc) + IEE16_IRQ, sc->irq_encoded); 362 363 status = sc->scb->ie_status; 364 365loop: 366 367 /* Don't ack interrupts which we didn't receive */ 368 ie_ack(sc, IE_ST_WHENCE & status); 369 370 if (status & (IE_ST_RECV | IE_ST_RNR)) { 371#ifdef DEBUG 372 in_ierint++; 373 if (ie_debug & IED_RINT) 374 if_printf(sc->ifp, "rint\n"); 375#endif 376 ierint(sc); 377#ifdef DEBUG 378 in_ierint--; 379#endif 380 } 381 if (status & IE_ST_DONE) { 382#ifdef DEBUG 383 in_ietint++; 384 if (ie_debug & IED_TINT) 385 if_printf(sc->ifp, "tint\n"); 386#endif 387 ietint(sc); 388#ifdef DEBUG 389 in_ietint--; 390#endif 391 } 392 if (status & IE_ST_RNR) { 393#ifdef DEBUG 394 if (ie_debug & IED_RNR) 395 if_printf(sc->ifp, "rnr\n"); 396#endif 397 iernr(sc); 398 } 399#ifdef DEBUG 400 if ((status & IE_ST_ALLDONE) && (ie_debug & IED_CNA)) 401 if_printf(sc->ifp, "cna\n"); 402#endif 403 404 if ((status = sc->scb->ie_status) & IE_ST_WHENCE) 405 goto loop; 406 407 /* Clear the interrupt latch on the 3C507. */ 408 if (sc->hard_type == IE_3C507) 409 outb(PORT(sc) + IE507_ICTRL, 1); 410 411 /* enable interrupts on the EE16. */ 412 if (sc->hard_type == IE_EE16) 413 outb(PORT(sc) + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE); 414 IE_UNLOCK(sc); 415} 416 417/* 418 * Process a received-frame interrupt. 419 */ 420static int 421ierint(struct ie_softc *sc) 422{ 423 int i, status; 424 static int timesthru = 1024; 425 426 i = sc->rfhead; 427 while (1) { 428 status = sc->rframes[i]->ie_fd_status; 429 430 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) { 431 sc->ifp->if_ipackets++; 432 if (!--timesthru) { 433 sc->ifp->if_ierrors += 434 sc->scb->ie_err_crc + 435 sc->scb->ie_err_align + 436 sc->scb->ie_err_resource + 437 sc->scb->ie_err_overrun; 438 sc->scb->ie_err_crc = 0; 439 sc->scb->ie_err_align = 0; 440 sc->scb->ie_err_resource = 0; 441 sc->scb->ie_err_overrun = 0; 442 timesthru = 1024; 443 } 444 ie_readframe(sc, i); 445 } else { 446 if (status & IE_FD_RNR) { 447 if (!(sc->scb->ie_status & IE_RU_READY)) { 448 sc->rframes[0]->ie_fd_next = 449 MK_16(MEM(sc), sc->rbuffs[0]); 450 sc->scb->ie_recv_list = 451 MK_16(MEM(sc), sc->rframes[0]); 452 command_and_wait(sc, IE_RU_START, 0, 0); 453 } 454 } 455 break; 456 } 457 i = (i + 1) % sc->nframes; 458 } 459 return (0); 460} 461 462/* 463 * Process a command-complete interrupt. These are only generated by 464 * the transmission of frames. This routine is deceptively simple, since 465 * most of the real work is done by iestart(). 466 */ 467static int 468ietint(struct ie_softc *sc) 469{ 470 struct ifnet *ifp = sc->ifp; 471 int status; 472 int i; 473 474 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 475 476 for (i = 0; i < sc->xmit_count; i++) { 477 status = sc->xmit_cmds[i]->ie_xmit_status; 478 479 if (status & IE_XS_LATECOLL) { 480 if_printf(ifp, "late collision\n"); 481 ifp->if_collisions++; 482 ifp->if_oerrors++; 483 } else if (status & IE_XS_NOCARRIER) { 484 if_printf(ifp, "no carrier\n"); 485 ifp->if_oerrors++; 486 } else if (status & IE_XS_LOSTCTS) { 487 if_printf(ifp, "lost CTS\n"); 488 ifp->if_oerrors++; 489 } else if (status & IE_XS_UNDERRUN) { 490 if_printf(ifp, "DMA underrun\n"); 491 ifp->if_oerrors++; 492 } else if (status & IE_XS_EXCMAX) { 493 if_printf(ifp, "too many collisions\n"); 494 ifp->if_collisions += 16; 495 ifp->if_oerrors++; 496 } else { 497 ifp->if_opackets++; 498 ifp->if_collisions += status & IE_XS_MAXCOLL; 499 } 500 } 501 sc->xmit_count = 0; 502 503 /* 504 * If multicast addresses were added or deleted while we were 505 * transmitting, ie_mc_reset() set the want_mcsetup flag indicating 506 * that we should do it. 507 */ 508 if (sc->want_mcsetup) { 509 mc_setup(sc); 510 sc->want_mcsetup = 0; 511 } 512 /* Wish I knew why this seems to be necessary... */ 513 sc->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL; 514 515 iestart_locked(ifp); 516 return (0); /* shouldn't be necessary */ 517} 518 519/* 520 * Process a receiver-not-ready interrupt. I believe that we get these 521 * when there aren't enough buffers to go around. For now (FIXME), we 522 * just restart the receiver, and hope everything's ok. 523 */ 524static int 525iernr(struct ie_softc *sc) 526{ 527#ifdef doesnt_work 528 setup_rfa(sc, (v_caddr_t) sc->rframes[0]); 529 530 sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]); 531 command_and_wait(sc, IE_RU_START, 0, 0); 532#else 533 /* This doesn't work either, but it doesn't hang either. */ 534 command_and_wait(sc, IE_RU_DISABLE, 0, 0); /* just in case */ 535 setup_rfa(sc, (v_caddr_t) sc->rframes[0]); /* ignore cast-qual */ 536 537 sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]); 538 command_and_wait(sc, IE_RU_START, 0, 0); /* was ENABLE */ 539 540#endif 541 ie_ack(sc, IE_ST_WHENCE); 542 543 sc->ifp->if_ierrors++; 544 return (0); 545} 546 547/* 548 * Compare two Ether/802 addresses for equality, inlined and 549 * unrolled for speed. I'd love to have an inline assembler 550 * version of this... 551 */ 552static __inline int 553ether_equal(u_char * one, u_char * two) 554{ 555 if (one[0] != two[0]) 556 return (0); 557 if (one[1] != two[1]) 558 return (0); 559 if (one[2] != two[2]) 560 return (0); 561 if (one[3] != two[3]) 562 return (0); 563 if (one[4] != two[4]) 564 return (0); 565 if (one[5] != two[5]) 566 return (0); 567 return 1; 568} 569 570/* 571 * Determine quickly whether we should bother reading in this packet. 572 * This depends on whether BPF and/or bridging is enabled, whether we 573 * are receiving multicast address, and whether promiscuous mode is enabled. 574 * We assume that if IFF_PROMISC is set, then *somebody* wants to see 575 * all incoming packets. 576 */ 577static __inline int 578check_eh(struct ie_softc *sc, struct ether_header *eh) 579{ 580 /* Optimize the common case: normal operation. We've received 581 either a unicast with our dest or a multicast packet. */ 582 if (sc->promisc == 0) { 583 int i; 584 585 /* If not multicast, it's definitely for us */ 586 if ((eh->ether_dhost[0] & 1) == 0) 587 return (1); 588 589 /* Accept broadcasts (loose but fast check) */ 590 if (eh->ether_dhost[0] == 0xff) 591 return (1); 592 593 /* Compare against our multicast addresses */ 594 for (i = 0; i < sc->mcast_count; i++) { 595 if (ether_equal(eh->ether_dhost, 596 (u_char *)&sc->mcast_addrs[i])) 597 return (1); 598 } 599 return (0); 600 } 601 602 /* Always accept packets when in promiscuous mode */ 603 if ((sc->promisc & IFF_PROMISC) != 0) 604 return (1); 605 606 /* Always accept packets directed at us */ 607 if (ether_equal(eh->ether_dhost, IF_LLADDR(sc->ifp))) 608 return (1); 609 610 /* Must have IFF_ALLMULTI but not IFF_PROMISC set. The chip is 611 actually in promiscuous mode, so discard unicast packets. */ 612 return((eh->ether_dhost[0] & 1) != 0); 613} 614 615/* 616 * We want to isolate the bits that have meaning... This assumes that 617 * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds 618 * the size of the buffer, then we are screwed anyway. 619 */ 620static __inline int 621ie_buflen(struct ie_softc *sc, int head) 622{ 623 return (sc->rbuffs[head]->ie_rbd_actual 624 & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1))); 625} 626 627static __inline int 628ie_packet_len(struct ie_softc *sc) 629{ 630 int i; 631 int head = sc->rbhead; 632 int acc = 0; 633 634 do { 635 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) { 636#ifdef DEBUG 637 print_rbd(sc->rbuffs[sc->rbhead]); 638#endif 639 log(LOG_ERR, 640 "%s: receive descriptors out of sync at %d\n", 641 sc->ifp->if_xname, sc->rbhead); 642 iereset(sc); 643 return (-1); 644 } 645 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST; 646 647 acc += ie_buflen(sc, head); 648 head = (head + 1) % sc->nrxbufs; 649 } while (!i); 650 651 return (acc); 652} 653 654/* 655 * Read data off the interface, and turn it into an mbuf chain. 656 * 657 * This code is DRAMATICALLY different from the previous version; this 658 * version tries to allocate the entire mbuf chain up front, given the 659 * length of the data available. This enables us to allocate mbuf 660 * clusters in many situations where before we would have had a long 661 * chain of partially-full mbufs. This should help to speed up the 662 * operation considerably. (Provided that it works, of course.) 663 */ 664static __inline int 665ieget(struct ie_softc *sc, struct mbuf **mp) 666{ 667 struct ether_header eh; 668 struct mbuf *m, *top, **mymp; 669 int offset; 670 int totlen, resid; 671 int thismboff; 672 int head; 673 674 totlen = ie_packet_len(sc); 675 if (totlen <= 0) 676 return (-1); 677 678 /* 679 * Snarf the Ethernet header. 680 */ 681 bcopy(sc->cbuffs[sc->rbhead], &eh, sizeof(struct ether_header)); 682 /* ignore cast-qual warning here */ 683 684 /* 685 * As quickly as possible, check if this packet is for us. If not, 686 * don't waste a single cycle copying the rest of the packet in. 687 * This is only a consideration when FILTER is defined; i.e., when 688 * we are either running BPF or doing multicasting. 689 */ 690 if (!check_eh(sc, &eh)) { 691 ie_drop_packet_buffer(sc); 692 sc->ifp->if_ierrors--; /* just this case, it's not an 693 * error 694 */ 695 return (-1); 696 } 697 698 MGETHDR(m, M_NOWAIT, MT_DATA); 699 if (!m) { 700 ie_drop_packet_buffer(sc); 701 /* XXXX if_ierrors++; */ 702 return (-1); 703 } 704 705 *mp = m; 706 m->m_pkthdr.rcvif = sc->ifp; 707 m->m_len = MHLEN; 708 resid = m->m_pkthdr.len = totlen; 709 top = 0; 710 711 mymp = ⊤ 712 713 /* 714 * This loop goes through and allocates mbufs for all the data we 715 * will be copying in. It does not actually do the copying yet. 716 */ 717 do { /* while(resid > 0) */ 718 /* 719 * Try to allocate an mbuf to hold the data that we have. 720 * If we already allocated one, just get another one and 721 * stick it on the end (eventually). If we don't already 722 * have one, try to allocate an mbuf cluster big enough to 723 * hold the whole packet, if we think it's reasonable, or a 724 * single mbuf which may or may not be big enough. Got that? 725 */ 726 if (top) { 727 MGET(m, M_NOWAIT, MT_DATA); 728 if (!m) { 729 m_freem(top); 730 ie_drop_packet_buffer(sc); 731 return (-1); 732 } 733 m->m_len = MLEN; 734 } 735 if (resid >= MINCLSIZE) { 736 MCLGET(m, M_NOWAIT); 737 if (m->m_flags & M_EXT) 738 m->m_len = min(resid, MCLBYTES); 739 } else { 740 if (resid < m->m_len) { 741 if (!top && resid + max_linkhdr <= m->m_len) 742 m->m_data += max_linkhdr; 743 m->m_len = resid; 744 } 745 } 746 resid -= m->m_len; 747 *mymp = m; 748 mymp = &m->m_next; 749 } while (resid > 0); 750 751 resid = totlen; /* remaining data */ 752 offset = 0; /* packet offset */ 753 thismboff = 0; /* offset in m */ 754 755 m = top; /* current mbuf */ 756 head = sc->rbhead; /* current rx buffer */ 757 758 /* 759 * Now we take the mbuf chain (hopefully only one mbuf most of the 760 * time) and stuff the data into it. There are no possible failures 761 * at or after this point. 762 */ 763 while (resid > 0) { /* while there's stuff left */ 764 int thislen = ie_buflen(sc, head) - offset; 765 766 /* 767 * If too much data for the current mbuf, then fill the 768 * current one up, go to the next one, and try again. 769 */ 770 if (thislen > m->m_len - thismboff) { 771 int newlen = m->m_len - thismboff; 772 773 bcopy((v_caddr_t) (sc->cbuffs[head] + offset), 774 mtod(m, caddr_t) +thismboff, (unsigned) newlen); 775 /* ignore cast-qual warning */ 776 m = m->m_next; 777 thismboff = 0; /* new mbuf, so no offset */ 778 offset += newlen; /* we are now this far into 779 * the packet */ 780 resid -= newlen; /* so there is this much left 781 * to get */ 782 continue; 783 } 784 /* 785 * If there is more than enough space in the mbuf to hold 786 * the contents of this buffer, copy everything in, advance 787 * pointers, and so on. 788 */ 789 if (thislen < m->m_len - thismboff) { 790 bcopy((v_caddr_t) (sc->cbuffs[head] + offset), 791 mtod(m, caddr_t) +thismboff, (unsigned) thislen); 792 thismboff += thislen; /* we are this far into the 793 * mbuf */ 794 resid -= thislen; /* and this much is left */ 795 goto nextbuf; 796 } 797 /* 798 * Otherwise, there is exactly enough space to put this 799 * buffer's contents into the current mbuf. Do the 800 * combination of the above actions. 801 */ 802 bcopy((v_caddr_t) (sc->cbuffs[head] + offset), 803 mtod(m, caddr_t) + thismboff, (unsigned) thislen); 804 m = m->m_next; 805 thismboff = 0; /* new mbuf, start at the beginning */ 806 resid -= thislen; /* and we are this far through */ 807 808 /* 809 * Advance all the pointers. We can get here from either of 810 * the last two cases, but never the first. 811 */ 812nextbuf: 813 offset = 0; 814 sc->rbuffs[head]->ie_rbd_actual = 0; 815 sc->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST; 816 sc->rbhead = head = (head + 1) % sc->nrxbufs; 817 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; 818 sc->rbtail = (sc->rbtail + 1) % sc->nrxbufs; 819 } 820 821 /* 822 * Unless something changed strangely while we were doing the copy, 823 * we have now copied everything in from the shared memory. This 824 * means that we are done. 825 */ 826 return (0); 827} 828 829/* 830 * Read frame NUM from unit UNIT (pre-cached as IE). 831 * 832 * This routine reads the RFD at NUM, and copies in the buffers from 833 * the list of RBD, then rotates the RBD and RFD lists so that the receiver 834 * doesn't start complaining. Trailers are DROPPED---there's no point 835 * in wasting time on confusing code to deal with them. Hopefully, 836 * this machine will never ARP for trailers anyway. 837 */ 838static void 839ie_readframe(struct ie_softc *sc, int num/* frame number to read */) 840{ 841 struct ifnet *ifp = sc->ifp; 842 struct ie_recv_frame_desc rfd; 843 struct mbuf *m = 0; 844#ifdef DEBUG 845 struct ether_header *eh; 846#endif 847 848 bcopy((v_caddr_t) (sc->rframes[num]), &rfd, 849 sizeof(struct ie_recv_frame_desc)); 850 851 /* 852 * Immediately advance the RFD list, since we we have copied ours 853 * now. 854 */ 855 sc->rframes[num]->ie_fd_status = 0; 856 sc->rframes[num]->ie_fd_last |= IE_FD_LAST; 857 sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST; 858 sc->rftail = (sc->rftail + 1) % sc->nframes; 859 sc->rfhead = (sc->rfhead + 1) % sc->nframes; 860 861 if (rfd.ie_fd_status & IE_FD_OK) { 862 if (ieget(sc, &m)) { 863 sc->ifp->if_ierrors++; /* this counts as an 864 * error */ 865 return; 866 } 867 } 868#ifdef DEBUG 869 eh = mtod(m, struct ether_header *); 870 if (ie_debug & IED_READFRAME) { 871 if_printf(ifp, "frame from ether %6D type %x\n", 872 eh->ether_shost, ":", (unsigned) eh->ether_type); 873 } 874 if (ntohs(eh->ether_type) > ETHERTYPE_TRAIL 875 && ntohs(eh->ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER)) 876 printf("received trailer!\n"); 877#endif 878 879 if (!m) 880 return; 881 882 /* 883 * Finally pass this packet up to higher layers. 884 */ 885 IE_UNLOCK(sc); 886 (*ifp->if_input)(ifp, m); 887 IE_LOCK(sc); 888} 889 890static void 891ie_drop_packet_buffer(struct ie_softc *sc) 892{ 893 int i; 894 895 do { 896 /* 897 * This means we are somehow out of sync. So, we reset the 898 * adapter. 899 */ 900 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) { 901#ifdef DEBUG 902 print_rbd(sc->rbuffs[sc->rbhead]); 903#endif 904 log(LOG_ERR, "%s: receive descriptors out of sync at %d\n", 905 sc->ifp->if_xname, sc->rbhead); 906 iereset(sc); 907 return; 908 } 909 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST; 910 911 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST; 912 sc->rbuffs[sc->rbhead]->ie_rbd_actual = 0; 913 sc->rbhead = (sc->rbhead + 1) % sc->nrxbufs; 914 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; 915 sc->rbtail = (sc->rbtail + 1) % sc->nrxbufs; 916 } while (!i); 917} 918 919 920/* 921 * Start transmission on an interface. 922 */ 923static void 924iestart(struct ifnet *ifp) 925{ 926 struct ie_softc *sc = ifp->if_softc; 927 928 IE_LOCK(sc); 929 iestart_locked(ifp); 930 IE_UNLOCK(sc); 931} 932 933static void 934iestart_locked(struct ifnet *ifp) 935{ 936 struct ie_softc *sc = ifp->if_softc; 937 struct mbuf *m0, *m; 938 volatile unsigned char *buffer; 939 u_short len; 940 941 /* 942 * This is not really volatile, in this routine, but it makes gcc 943 * happy. 944 */ 945 volatile u_short *bptr = &sc->scb->ie_command_list; 946 947 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) 948 return; 949 if (ifp->if_drv_flags & IFF_DRV_OACTIVE) 950 return; 951 952 do { 953 IF_DEQUEUE(&sc->ifp->if_snd, m); 954 if (!m) 955 break; 956 957 buffer = sc->xmit_cbuffs[sc->xmit_count]; 958 len = 0; 959 960 for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) { 961 bcopy(mtod(m, caddr_t), buffer, m->m_len); 962 buffer += m->m_len; 963 len += m->m_len; 964 } 965 966 m_freem(m0); 967 len = max(len, ETHER_MIN_LEN); 968 969 /* 970 * See if bpf is listening on this interface, let it see the 971 * packet before we commit it to the wire. 972 */ 973 BPF_TAP(sc->ifp, 974 (void *)sc->xmit_cbuffs[sc->xmit_count], len); 975 976 sc->xmit_buffs[sc->xmit_count]->ie_xmit_flags = 977 IE_XMIT_LAST|len; 978 sc->xmit_buffs[sc->xmit_count]->ie_xmit_next = 0xffff; 979 sc->xmit_buffs[sc->xmit_count]->ie_xmit_buf = 980 MK_24(sc->iomem, sc->xmit_cbuffs[sc->xmit_count]); 981 982 sc->xmit_cmds[sc->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT; 983 sc->xmit_cmds[sc->xmit_count]->ie_xmit_status = 0; 984 sc->xmit_cmds[sc->xmit_count]->ie_xmit_desc = 985 MK_16(sc->iomem, sc->xmit_buffs[sc->xmit_count]); 986 987 *bptr = MK_16(sc->iomem, sc->xmit_cmds[sc->xmit_count]); 988 bptr = &sc->xmit_cmds[sc->xmit_count]->com.ie_cmd_link; 989 sc->xmit_count++; 990 } while (sc->xmit_count < sc->ntxbufs); 991 992 /* 993 * If we queued up anything for transmission, send it. 994 */ 995 if (sc->xmit_count) { 996 sc->xmit_cmds[sc->xmit_count - 1]->com.ie_cmd_cmd |= 997 IE_CMD_LAST | IE_CMD_INTR; 998 999 /* 1000 * By passing the command pointer as a null, we tell 1001 * command_and_wait() to pretend that this isn't an action 1002 * command. I wish I understood what was happening here. 1003 */ 1004 command_and_wait(sc, IE_CU_START, 0, 0); 1005 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1006 } 1007 return; 1008} 1009 1010/* 1011 * Check to see if there's an 82586 out there. 1012 */ 1013int 1014check_ie_present(struct ie_softc *sc) 1015{ 1016 volatile struct ie_sys_conf_ptr *scp; 1017 volatile struct ie_int_sys_conf_ptr *iscp; 1018 volatile struct ie_sys_ctl_block *scb; 1019 u_long realbase; 1020 1021 realbase = (uintptr_t) sc->iomembot + sc->iosize - (1 << 24); 1022 1023 scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t) 1024 (realbase + IE_SCP_ADDR); 1025 bzero((volatile char *) scp, sizeof *scp); 1026 1027 /* 1028 * First we put the ISCP at the bottom of memory; this tests to make 1029 * sure that our idea of the size of memory is the same as the 1030 * controller's. This is NOT where the ISCP will be in normal 1031 * operation. 1032 */ 1033 iscp = (volatile struct ie_int_sys_conf_ptr *) sc->iomembot; 1034 bzero((volatile char *)iscp, sizeof *iscp); 1035 1036 scb = (volatile struct ie_sys_ctl_block *) sc->iomembot; 1037 bzero((volatile char *)scb, sizeof *scb); 1038 1039 scp->ie_bus_use = sc->bus_use; /* 8-bit or 16-bit */ 1040 scp->ie_iscp_ptr = (caddr_t) (uintptr_t) 1041 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase); 1042 1043 iscp->ie_busy = 1; 1044 iscp->ie_scb_offset = MK_16(realbase, scb) + 256; 1045 1046 (*sc->ie_reset_586) (sc); 1047 (*sc->ie_chan_attn) (sc); 1048 1049 DELAY(100); /* wait a while... */ 1050 1051 if (iscp->ie_busy) { 1052 return (0); 1053 } 1054 /* 1055 * Now relocate the ISCP to its real home, and reset the controller 1056 * again. 1057 */ 1058 iscp = (void *) Align((caddr_t) (uintptr_t) 1059 (realbase + IE_SCP_ADDR - 1060 sizeof(struct ie_int_sys_conf_ptr))); 1061 bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */ 1062 1063 scp->ie_iscp_ptr = (caddr_t) (uintptr_t) 1064 ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase); 1065 1066 iscp->ie_busy = 1; 1067 iscp->ie_scb_offset = MK_16(realbase, scb); 1068 1069 (*sc->ie_reset_586) (sc); 1070 (*sc->ie_chan_attn) (sc); 1071 1072 DELAY(100); 1073 1074 if (iscp->ie_busy) { 1075 return (0); 1076 } 1077 sc->iomem = (caddr_t) (uintptr_t) realbase; 1078 1079 sc->iscp = iscp; 1080 sc->scb = scb; 1081 1082 /* 1083 * Acknowledge any interrupts we may have caused... 1084 */ 1085 ie_ack(sc, IE_ST_WHENCE); 1086 1087 return (1); 1088} 1089 1090void 1091el_reset_586(struct ie_softc *sc) 1092{ 1093 outb(PORT(sc) + IE507_CTRL, EL_CTRL_RESET); 1094 DELAY(100); 1095 outb(PORT(sc) + IE507_CTRL, EL_CTRL_NORMAL); 1096 DELAY(100); 1097} 1098 1099void 1100sl_reset_586(struct ie_softc *sc) 1101{ 1102 outb(PORT(sc) + IEATT_RESET, 0); 1103} 1104 1105void 1106ee16_reset_586(struct ie_softc *sc) 1107{ 1108 outb(PORT(sc) + IEE16_ECTRL, IEE16_RESET_586); 1109 DELAY(100); 1110 outb(PORT(sc) + IEE16_ECTRL, 0); 1111 DELAY(100); 1112} 1113 1114void 1115el_chan_attn(struct ie_softc *sc) 1116{ 1117 outb(PORT(sc) + IE507_ATTN, 1); 1118} 1119 1120void 1121sl_chan_attn(struct ie_softc *sc) 1122{ 1123 outb(PORT(sc) + IEATT_ATTN, 0); 1124} 1125 1126void 1127ee16_chan_attn(struct ie_softc *sc) 1128{ 1129 outb(PORT(sc) + IEE16_ATTN, 0); 1130} 1131 1132static __inline void 1133ee16_interrupt_enable(struct ie_softc *sc) 1134{ 1135 DELAY(100); 1136 outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE); 1137 DELAY(100); 1138} 1139 1140void 1141sl_read_ether(struct ie_softc *sc, unsigned char *addr) 1142{ 1143 int i; 1144 1145 for (i = 0; i < 6; i++) 1146 addr[i] = inb(PORT(sc) + i); 1147} 1148 1149static void 1150iereset(struct ie_softc *sc) 1151{ 1152 struct ifnet *ifp = sc->ifp; 1153 1154 if_printf(ifp, "reset\n"); 1155 ie_stop(sc); 1156 1157 /* 1158 * Stop i82586 dead in its tracks. 1159 */ 1160 if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0)) 1161 if_printf(ifp, "abort commands timed out\n"); 1162 1163 if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0)) 1164 if_printf(ifp, "disable commands timed out\n"); 1165 1166#ifdef notdef 1167 if (!check_ie_present(sc)) 1168 panic("ie disappeared!"); 1169#endif 1170 1171 if (ifp->if_flags & IFF_UP) 1172 ieinit_locked(sc); 1173 1174 return; 1175} 1176 1177/* 1178 * Send a command to the controller and wait for it to either 1179 * complete or be accepted, depending on the command. If the 1180 * command pointer is null, then pretend that the command is 1181 * not an action command. If the command pointer is not null, 1182 * and the command is an action command, wait for 1183 * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK 1184 * to become true. 1185 */ 1186static int 1187command_and_wait(struct ie_softc *sc, int cmd, volatile void *pcmd, int mask) 1188{ 1189 volatile struct ie_cmd_common *cc = pcmd; 1190 int i; 1191 1192 sc->scb->ie_command = (u_short) cmd; 1193 1194 if (IE_ACTION_COMMAND(cmd) && pcmd) { 1195 (*sc->ie_chan_attn) (sc); 1196 1197 /* 1198 * Now spin-lock waiting for status. This is not a very 1199 * nice thing to do, but I haven't figured out how, or 1200 * indeed if, we can put the process waiting for action to 1201 * sleep. (We may be getting called through some other 1202 * timeout running in the kernel.) 1203 * 1204 * According to the packet driver, the minimum timeout 1205 * should be .369 seconds, which we round up to .37. 1206 */ 1207 for (i = 0; i < 370; i++) { 1208 if (cc->ie_cmd_status & mask) 1209 return (0); 1210 DELAY(1000); 1211 } 1212 1213 return (1); 1214 } else { 1215 1216 /* 1217 * Otherwise, just wait for the command to be accepted. 1218 */ 1219 (*sc->ie_chan_attn) (sc); 1220 1221 while (sc->scb->ie_command); /* spin lock */ 1222 1223 return (0); 1224 } 1225} 1226 1227/* 1228 * Run the time-domain reflectometer... 1229 */ 1230static void 1231run_tdr(struct ie_softc *sc, volatile struct ie_tdr_cmd *cmd) 1232{ 1233 int result; 1234 1235 cmd->com.ie_cmd_status = 0; 1236 cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST; 1237 cmd->com.ie_cmd_link = 0xffff; 1238 cmd->ie_tdr_time = 0; 1239 1240 sc->scb->ie_command_list = MK_16(MEM(sc), cmd); 1241 cmd->ie_tdr_time = 0; 1242 1243 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL)) 1244 result = 0x2000; 1245 else 1246 result = cmd->ie_tdr_time; 1247 1248 ie_ack(sc, IE_ST_WHENCE); 1249 1250 if (result & IE_TDR_SUCCESS) 1251 return; 1252 1253 if (result & IE_TDR_XCVR) { 1254 if_printf(sc->ifp, "transceiver problem\n"); 1255 } else if (result & IE_TDR_OPEN) { 1256 if_printf(sc->ifp, "TDR detected an open %d clocks away\n", 1257 result & IE_TDR_TIME); 1258 } else if (result & IE_TDR_SHORT) { 1259 if_printf(sc->ifp, "TDR detected a short %d clocks away\n", 1260 result & IE_TDR_TIME); 1261 } else { 1262 if_printf(sc->ifp, "TDR returned unknown status %x\n", result); 1263 } 1264} 1265 1266static void 1267start_receiver(struct ie_softc *sc) 1268{ 1269 1270 sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]); 1271 command_and_wait(sc, IE_RU_START, 0, 0); 1272 1273 ie_ack(sc, IE_ST_WHENCE); 1274} 1275 1276/* 1277 * Here is a helper routine for iernr() and ieinit(). This sets up 1278 * the RFA. 1279 */ 1280static v_caddr_t 1281setup_rfa(struct ie_softc *sc, v_caddr_t ptr) 1282{ 1283 volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr; 1284 volatile struct ie_recv_buf_desc *rbd; 1285 int i; 1286 1287 /* First lay them out */ 1288 for (i = 0; i < sc->nframes; i++) { 1289 sc->rframes[i] = rfd; 1290 bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */ 1291 rfd++; 1292 } 1293 1294 ptr = Alignvol(rfd); /* ignore cast-qual */ 1295 1296 /* Now link them together */ 1297 for (i = 0; i < sc->nframes; i++) { 1298 sc->rframes[i]->ie_fd_next = 1299 MK_16(MEM(sc), sc->rframes[(i + 1) % sc->nframes]); 1300 } 1301 1302 /* Finally, set the EOL bit on the last one. */ 1303 sc->rframes[sc->nframes - 1]->ie_fd_last |= IE_FD_LAST; 1304 1305 /* 1306 * Now lay out some buffers for the incoming frames. Note that we 1307 * set aside a bit of slop in each buffer, to make sure that we have 1308 * enough space to hold a single frame in every buffer. 1309 */ 1310 rbd = (volatile void *) ptr; 1311 1312 for (i = 0; i < sc->nrxbufs; i++) { 1313 sc->rbuffs[i] = rbd; 1314 bzero((volatile char *)rbd, sizeof *rbd); 1315 ptr = Alignvol(ptr + sizeof *rbd); 1316 rbd->ie_rbd_length = IE_RBUF_SIZE; 1317 rbd->ie_rbd_buffer = MK_24(MEM(sc), ptr); 1318 sc->cbuffs[i] = (volatile void *) ptr; 1319 ptr += IE_RBUF_SIZE; 1320 rbd = (volatile void *) ptr; 1321 } 1322 1323 /* Now link them together */ 1324 for (i = 0; i < sc->nrxbufs; i++) { 1325 sc->rbuffs[i]->ie_rbd_next = 1326 MK_16(MEM(sc), sc->rbuffs[(i + 1) % sc->nrxbufs]); 1327 } 1328 1329 /* Tag EOF on the last one */ 1330 sc->rbuffs[sc->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST; 1331 1332 /* 1333 * We use the head and tail pointers on receive to keep track of the 1334 * order in which RFDs and RBDs are used. 1335 */ 1336 sc->rfhead = 0; 1337 sc->rftail = sc->nframes - 1; 1338 sc->rbhead = 0; 1339 sc->rbtail = sc->nrxbufs - 1; 1340 1341 sc->scb->ie_recv_list = MK_16(MEM(sc), sc->rframes[0]); 1342 sc->rframes[0]->ie_fd_buf_desc = MK_16(MEM(sc), sc->rbuffs[0]); 1343 1344 ptr = Alignvol(ptr); 1345 return (ptr); 1346} 1347 1348/* 1349 * Run the multicast setup command. 1350 */ 1351static int 1352mc_setup(struct ie_softc *sc) 1353{ 1354 volatile struct ie_mcast_cmd *cmd = (volatile void *)sc->xmit_cbuffs[0]; 1355 1356 cmd->com.ie_cmd_status = 0; 1357 cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST; 1358 cmd->com.ie_cmd_link = 0xffff; 1359 1360 /* ignore cast-qual */ 1361 bcopy((v_caddr_t) sc->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs, 1362 sc->mcast_count * sizeof *sc->mcast_addrs); 1363 1364 cmd->ie_mcast_bytes = sc->mcast_count * 6; /* grrr... */ 1365 1366 sc->scb->ie_command_list = MK_16(MEM(sc), cmd); 1367 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) 1368 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1369 if_printf(sc->ifp, "multicast address setup command failed\n"); 1370 return (0); 1371 } 1372 return (1); 1373} 1374 1375/* 1376 * This routine takes the environment generated by check_ie_present() 1377 * and adds to it all the other structures we need to operate the adapter. 1378 * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, 1379 * starting the receiver unit, and clearing interrupts. 1380 */ 1381static void 1382ieinit(xsc) 1383 void *xsc; 1384{ 1385 struct ie_softc *sc = xsc; 1386 1387 IE_LOCK(sc); 1388 ieinit_locked(sc); 1389 IE_UNLOCK(sc); 1390} 1391 1392static void 1393ieinit_locked(struct ie_softc *sc) 1394{ 1395 struct ifnet *ifp = sc->ifp; 1396 volatile struct ie_sys_ctl_block *scb = sc->scb; 1397 caddr_t ptr; 1398 int i; 1399 1400 ptr = Alignvol((volatile char *) scb + sizeof *scb); 1401 1402 /* 1403 * Send the configure command first. 1404 */ 1405 { 1406 volatile struct ie_config_cmd *cmd = (volatile void *) ptr; 1407 1408 ie_setup_config(cmd, sc->promisc, 1409 sc->hard_type == IE_STARLAN10); 1410 cmd->com.ie_cmd_status = 0; 1411 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST; 1412 cmd->com.ie_cmd_link = 0xffff; 1413 1414 scb->ie_command_list = MK_16(MEM(sc), cmd); 1415 1416 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) 1417 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1418 if_printf(ifp, "configure command failed\n"); 1419 return; 1420 } 1421 } 1422 /* 1423 * Now send the Individual Address Setup command. 1424 */ 1425 { 1426 volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr; 1427 1428 cmd->com.ie_cmd_status = 0; 1429 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; 1430 cmd->com.ie_cmd_link = 0xffff; 1431 1432 bcopy((volatile char *)IF_LLADDR(ifp), 1433 (volatile char *)&cmd->ie_address, sizeof cmd->ie_address); 1434 scb->ie_command_list = MK_16(MEM(sc), cmd); 1435 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) 1436 || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { 1437 if_printf(ifp, "individual address " 1438 "setup command failed\n"); 1439 return; 1440 } 1441 } 1442 1443 /* 1444 * Now run the time-domain reflectometer. 1445 */ 1446 run_tdr(sc, (volatile void *) ptr); 1447 1448 /* 1449 * Acknowledge any interrupts we have generated thus far. 1450 */ 1451 ie_ack(sc, IE_ST_WHENCE); 1452 1453 /* 1454 * Set up the RFA. 1455 */ 1456 ptr = setup_rfa(sc, ptr); 1457 1458 /* 1459 * Finally, the transmit command and buffer are the last little bit 1460 * of work. 1461 */ 1462 1463 /* transmit command buffers */ 1464 for (i = 0; i < sc->ntxbufs; i++) { 1465 sc->xmit_cmds[i] = (volatile void *) ptr; 1466 ptr += sizeof *sc->xmit_cmds[i]; 1467 ptr = Alignvol(ptr); 1468 sc->xmit_buffs[i] = (volatile void *)ptr; 1469 ptr += sizeof *sc->xmit_buffs[i]; 1470 ptr = Alignvol(ptr); 1471 } 1472 1473 /* transmit buffers */ 1474 for (i = 0; i < sc->ntxbufs - 1; i++) { 1475 sc->xmit_cbuffs[i] = (volatile void *)ptr; 1476 ptr += IE_BUF_LEN; 1477 ptr = Alignvol(ptr); 1478 } 1479 sc->xmit_cbuffs[sc->ntxbufs - 1] = (volatile void *) ptr; 1480 1481 for (i = 1; i < sc->ntxbufs; i++) { 1482 bzero((v_caddr_t) sc->xmit_cmds[i], sizeof *sc->xmit_cmds[i]); 1483 bzero((v_caddr_t) sc->xmit_buffs[i], sizeof *sc->xmit_buffs[i]); 1484 } 1485 1486 /* 1487 * This must be coordinated with iestart() and ietint(). 1488 */ 1489 sc->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL; 1490 1491 /* take the ee16 out of loopback */ 1492 if (sc->hard_type == IE_EE16) { 1493 u_int8_t bart_config; 1494 1495 bart_config = inb(PORT(sc) + IEE16_CONFIG); 1496 bart_config &= ~IEE16_BART_LOOPBACK; 1497 /* inb doesn't get bit! */ 1498 bart_config |= IEE16_BART_MCS16_TEST; 1499 outb(PORT(sc) + IEE16_CONFIG, bart_config); 1500 ee16_interrupt_enable(sc); 1501 ee16_chan_attn(sc); 1502 } 1503 ifp->if_drv_flags |= IFF_DRV_RUNNING; /* tell higher levels 1504 * we're here */ 1505 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 1506 1507 start_receiver(sc); 1508 1509 return; 1510} 1511 1512static void 1513ie_stop(struct ie_softc *sc) 1514{ 1515 struct ifnet *ifp = sc->ifp; 1516 1517 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1518 command_and_wait(sc, IE_RU_DISABLE, 0, 0); 1519} 1520 1521static int 1522ieioctl(struct ifnet *ifp, u_long command, caddr_t data) 1523{ 1524 int error = 0; 1525 struct ie_softc *sc = ifp->if_softc; 1526 1527 switch (command) { 1528 case SIOCSIFFLAGS: 1529 /* 1530 * Note that this device doesn't have an "all multicast" 1531 * mode, so we must turn on promiscuous mode and do the 1532 * filtering manually. 1533 */ 1534 IE_LOCK(sc); 1535 if ((ifp->if_flags & IFF_UP) == 0 && 1536 (ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1537 ie_stop(sc); 1538 } else if ((ifp->if_flags & IFF_UP) && 1539 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { 1540 sc->promisc = 1541 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); 1542 ieinit_locked(sc); 1543 } else if (sc->promisc ^ 1544 (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) { 1545 sc->promisc = 1546 ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); 1547 ieinit_locked(sc); 1548 } 1549 IE_UNLOCK(sc); 1550 break; 1551 1552 case SIOCADDMULTI: 1553 case SIOCDELMULTI: 1554 /* 1555 * Update multicast listeners 1556 */ 1557 /* reset multicast filtering */ 1558 IE_LOCK(sc); 1559 ie_mc_reset(sc); 1560 IE_UNLOCK(sc); 1561 error = 0; 1562 break; 1563 1564 default: 1565 error = ether_ioctl(ifp, command, data); 1566 break; 1567 } 1568 1569 return (error); 1570} 1571 1572static void 1573ie_mc_reset(struct ie_softc *sc) 1574{ 1575 struct ifmultiaddr *ifma; 1576 1577 /* 1578 * Step through the list of addresses. 1579 */ 1580 sc->mcast_count = 0; 1581 if_maddr_rlock(sc->ifp); 1582 TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { 1583 if (ifma->ifma_addr->sa_family != AF_LINK) 1584 continue; 1585 1586 /* XXX - this is broken... */ 1587 if (sc->mcast_count >= MAXMCAST) { 1588 sc->ifp->if_flags |= IFF_ALLMULTI; 1589 if (sc->ifp->if_flags & IFF_UP) 1590 ieinit_locked(sc); 1591 goto setflag; 1592 } 1593 bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), 1594 &(sc->mcast_addrs[sc->mcast_count]), 6); 1595 sc->mcast_count++; 1596 } 1597 if_maddr_runlock(sc->ifp); 1598 1599setflag: 1600 sc->want_mcsetup = 1; 1601} 1602 1603 1604#ifdef DEBUG 1605static void 1606print_rbd(volatile struct ie_recv_buf_desc * rbd) 1607{ 1608 printf("RBD at %p:\n" 1609 "actual %04x, next %04x, buffer %p\n" 1610 "length %04x, mbz %04x\n", 1611 (volatile void *) rbd, 1612 rbd->ie_rbd_actual, rbd->ie_rbd_next, 1613 (void *) rbd->ie_rbd_buffer, 1614 rbd->ie_rbd_length, rbd->mbz); 1615} 1616 1617#endif /* DEBUG */ 1618 1619int 1620ie_alloc_resources (device_t dev) 1621{ 1622 struct ie_softc * sc; 1623 int error; 1624 1625 error = 0; 1626 sc = device_get_softc(dev); 1627 1628 sc->io_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->io_rid, 1629 RF_ACTIVE); 1630 if (!sc->io_res) { 1631 device_printf(dev, "No I/O space?!\n"); 1632 error = ENOMEM; 1633 goto bad; 1634 } 1635 sc->io_bt = rman_get_bustag(sc->io_res); 1636 sc->io_bh = rman_get_bushandle(sc->io_res); 1637 1638 sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, 1639 RF_ACTIVE); 1640 if (!sc->mem_res) { 1641 device_printf(dev, "No Memory!\n"); 1642 error = ENOMEM; 1643 goto bad; 1644 } 1645 sc->mem_bt = rman_get_bustag(sc->mem_res); 1646 sc->mem_bh = rman_get_bushandle(sc->mem_res); 1647 1648 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, 1649 RF_ACTIVE); 1650 if (!sc->irq_res) { 1651 device_printf(dev, "No IRQ!\n"); 1652 error = ENOMEM; 1653 goto bad; 1654 } 1655 1656 sc->port = rman_get_start(sc->io_res); /* XXX hack */ 1657 sc->iomembot = rman_get_virtual(sc->mem_res); 1658 sc->iosize = rman_get_size(sc->mem_res); 1659 1660 return (0); 1661bad: 1662 return (error); 1663} 1664 1665void 1666ie_release_resources (device_t dev) 1667{ 1668 struct ie_softc * sc; 1669 1670 sc = device_get_softc(dev); 1671 1672 if (sc->irq_ih) 1673 bus_teardown_intr(dev, sc->irq_res, sc->irq_ih); 1674 if (sc->rframes) 1675 free(sc->rframes, M_DEVBUF); 1676 if (sc->io_res) 1677 bus_release_resource(dev, SYS_RES_IOPORT, 1678 sc->io_rid, sc->io_res); 1679 if (sc->irq_res) 1680 bus_release_resource(dev, SYS_RES_IRQ, 1681 sc->irq_rid, sc->irq_res); 1682 if (sc->mem_res) 1683 bus_release_resource(dev, SYS_RES_MEMORY, 1684 sc->mem_rid, sc->mem_res); 1685 if (sc->ifp) 1686 if_free(sc->ifp); 1687 1688 return; 1689} 1690 1691int 1692ie_detach (device_t dev) 1693{ 1694 struct ie_softc * sc; 1695 struct ifnet * ifp; 1696 1697 sc = device_get_softc(dev); 1698 ifp = sc->ifp; 1699 1700 IE_LOCK(sc); 1701 if (sc->hard_type == IE_EE16) 1702 ee16_shutdown(sc); 1703 1704 ie_stop(sc); 1705 IE_UNLOCK(sc); 1706 ether_ifdetach(ifp); 1707 ie_release_resources(dev); 1708 mtx_destroy(&sc->lock); 1709 1710 return (0); 1711} 1712