root/dev/isa/if_ie.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ie_setup_config
  2. ie_ack
  3. ieprobe
  4. sl_probe
  5. el_probe
  6. ee16_probe
  7. ieattach
  8. iewatchdog
  9. ieintr
  10. ierint
  11. ietint
  12. ether_equal
  13. check_eh
  14. ie_buflen
  15. ie_packet_len
  16. iexmit
  17. ieget
  18. ie_readframe
  19. ie_drop_packet_buffer
  20. iestart
  21. check_ie_present
  22. ie_find_mem_size
  23. el_reset_586
  24. sl_reset_586
  25. ee16_reset_586
  26. el_chan_attn
  27. sl_chan_attn
  28. ee16_chan_attn
  29. ee16_read_eeprom
  30. ee16_eeprom_outbits
  31. ee16_eeprom_inbits
  32. ee16_eeprom_clock
  33. ee16_interrupt_enable
  34. slel_get_address
  35. iereset
  36. command_and_wait
  37. run_tdr
  38. iememinit
  39. mc_setup
  40. ieinit
  41. iestop
  42. ieioctl
  43. mc_reset
  44. print_rbd

    1 /*      $OpenBSD: if_ie.c,v 1.33 2006/04/16 00:46:32 pascoe Exp $       */
    2 /*      $NetBSD: if_ie.c,v 1.51 1996/05/12 23:52:48 mycroft Exp $       */
    3 
    4 /*-
    5  * Copyright (c) 1993, 1994, 1995 Charles Hannum.
    6  * Copyright (c) 1992, 1993, University of Vermont and State
    7  *  Agricultural College.
    8  * Copyright (c) 1992, 1993, Garrett A. Wollman.
    9  *
   10  * Portions:
   11  * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes
   12  * Copyright (c) 1994, 1995, Rafal K. Boni
   13  * Copyright (c) 1990, 1991, William F. Jolitz
   14  * Copyright (c) 1990, The Regents of the University of California
   15  *
   16  * All rights reserved.
   17  *
   18  * Redistribution and use in source and binary forms, with or without
   19  * modification, are permitted provided that the following conditions
   20  * are met:
   21  * 1. Redistributions of source code must retain the above copyright
   22  *    notice, this list of conditions and the following disclaimer.
   23  * 2. Redistributions in binary form must reproduce the above copyright
   24  *    notice, this list of conditions and the following disclaimer in the
   25  *    documentation and/or other materials provided with the distribution.
   26  * 3. All advertising materials mentioning features or use of this software
   27  *    must display the following acknowledgement:
   28  *      This product includes software developed by Charles Hannum, by the
   29  *      University of Vermont and State Agricultural College and Garrett A.
   30  *      Wollman, by William F. Jolitz, and by the University of California,
   31  *      Berkeley, Lawrence Berkeley Laboratory, and its contributors.
   32  * 4. Neither the names of the Universities nor the names of the authors
   33  *    may be used to endorse or promote products derived from this software
   34  *    without specific prior written permission.
   35  *
   36  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   37  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   38  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   39  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
   40  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   41  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   42  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   44  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   45  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   46  * SUCH DAMAGE.
   47  */
   48 
   49 /*
   50  * Intel 82586 Ethernet chip
   51  * Register, bit, and structure definitions.
   52  *
   53  * Original StarLAN driver written by Garrett Wollman with reference to the
   54  * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
   55  *
   56  * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
   57  *
   58  * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
   59  *
   60  * Intel EtherExpress 16 support taken from FreeBSD's if_ix.c, written
   61  * by Rodney W. Grimes.
   62  *
   63  * Majorly cleaned up and 3C507 code merged by Charles Hannum.
   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 received frame
   77 descriptors around for the receiver to use, and NRXBUF associated receive
   78 buffer descriptors, both in a circular list.  Whenever a frame is received, we
   79 rotate both lists as necessary.  (The 586 treats both lists as a simple
   80 queue.)  We also keep a transmit command around so that packets can be sent
   81 off quickly.
   82 
   83 We configure the adapter in AL-LOC = 1 mode, which means that the
   84 Ethernet/802.3 MAC header is placed at the beginning of the receive buffer
   85 rather than being split off into various fields in the RFD.  This also means
   86 that we must include this header in the transmit buffer as well.
   87 
   88 By convention, all transmit commands, and only transmit commands, shall have
   89 the I (IE_CMD_INTR) bit set in the command.  This way, when an interrupt
   90 arrives at ieintr(), it is immediately possible to tell what precisely caused
   91 it.  ANY OTHER command-sending routines should run at splnet(), and should
   92 post an acknowledgement to every interrupt they generate.
   93 
   94 The 82586 has a 24-bit address space internally, and the adaptor's memory is
   95 located at the top of this region.  However, the value we are given in
   96 configuration is the CPU's idea of where the adaptor RAM is.  So, we must go
   97 through a few gyrations to come up with a kernel virtual address which
   98 represents the actual beginning of the 586 address space.  First, we autosize
   99 the RAM by running through several possible sizes and trying to initialize the
  100 adapter under the assumption that the selected size is correct.  Then, knowing
  101 the correct RAM size, we set up our pointers in the softc.  `sc_maddr'
  102 represents the computed base of the 586 address space.  `iomembot' represents
  103 the actual configured base of adapter RAM.  Finally, `sc_msize' represents the
  104 calculated size of 586 RAM.  Then, when laying out commands, we use the
  105 interval [sc_maddr, sc_maddr + sc_msize); to make 24-pointers, we subtract
  106 iomem, and to make 16-pointers, we subtract sc_maddr and and with 0xffff.
  107 */
  108 
  109 #include "bpfilter.h"
  110 
  111 #include <sys/param.h>
  112 #include <sys/systm.h>
  113 #include <sys/mbuf.h>
  114 #include <sys/buf.h>
  115 #include <sys/protosw.h>
  116 #include <sys/socket.h>
  117 #include <sys/ioctl.h>
  118 #include <sys/errno.h>
  119 #include <sys/syslog.h>
  120 #include <sys/device.h>
  121 #include <sys/timeout.h>
  122 
  123 #include <net/if.h>
  124 #include <net/if_types.h>
  125 #include <net/if_dl.h>
  126 #include <net/netisr.h>
  127 #include <net/route.h>
  128 
  129 #if NBPFILTER > 0
  130 #include <net/bpf.h>
  131 #endif
  132 
  133 #ifdef INET
  134 #include <netinet/in.h>
  135 #include <netinet/in_systm.h>
  136 #include <netinet/in_var.h>
  137 #include <netinet/ip.h>
  138 #include <netinet/if_ether.h>
  139 #endif
  140 
  141 #include <machine/cpu.h>
  142 #include <machine/bus.h>
  143 #include <machine/intr.h>
  144 
  145 #include <dev/isa/isareg.h>
  146 #include <dev/isa/isavar.h>
  147 #include <i386/isa/isa_machdep.h>       /* XXX USES ISA HOLE DIRECTLY */
  148 #include <dev/ic/i82586reg.h>
  149 #include <dev/isa/if_ieatt.h>
  150 #include <dev/isa/if_ie507.h>
  151 #include <dev/isa/if_iee16.h>
  152 #include <dev/isa/elink.h>
  153 
  154 #define IED_RINT        0x01
  155 #define IED_TINT        0x02
  156 #define IED_RNR         0x04
  157 #define IED_CNA         0x08
  158 #define IED_READFRAME   0x10
  159 #define IED_ENQ         0x20
  160 #define IED_XMIT        0x40
  161 #define IED_ALL         0x7f
  162 
  163 /*
  164 sizeof(iscp) == 1+1+2+4 == 8
  165 sizeof(scb) == 2+2+2+2+2+2+2+2 == 16
  166 NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384
  167 sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18
  168 sizeof(transmit buffer) == ETHER_MAX_LEN == 1518
  169 sizeof(transmit buffer desc) == 8
  170 -----
  171 1952
  172 
  173 NRXBUF * sizeof(rbd) == NRXBUF*(2+2+4+2+2) == NRXBUF*12
  174 NRXBUF * IE_RBUF_SIZE == NRXBUF*256
  175 
  176 NRXBUF should be (16384 - 1952) / (256 + 12) == 14432 / 268 == 53
  177 
  178 With NRXBUF == 48, this leaves us 1568 bytes for another command or
  179 more buffers.  Another transmit command would be 18+8+1518 == 1544
  180 ---just barely fits!
  181 
  182 Obviously all these would have to be reduced for smaller memory sizes.
  183 With a larger memory, it would be possible to roughly double the number of
  184 both transmit and receive buffers.
  185 */
  186 
  187 #define NFRAMES         16              /* number of receive frames */
  188 #define NRXBUF          48              /* number of buffers to allocate */
  189 #define IE_RBUF_SIZE    256             /* size of each receive buffer;
  190                                                 MUST BE POWER OF TWO */
  191 #define NTXBUF          2               /* number of transmit commands */
  192 #define IE_TBUF_SIZE    ETHER_MAX_LEN   /* length of transmit buffer */
  193 
  194 
  195 enum ie_hardware {
  196         IE_STARLAN10,
  197         IE_EN100,
  198         IE_SLFIBER,
  199         IE_3C507,
  200         IE_EE16,
  201         IE_UNKNOWN
  202 };
  203 
  204 const char *ie_hardware_names[] = {
  205         "StarLAN 10",
  206         "EN100",
  207         "StarLAN Fiber",
  208         "3C507",
  209         "EtherExpress 16",
  210         "Unknown"
  211 };
  212 
  213 /*
  214  * Ethernet status, per interface.
  215  */
  216 struct ie_softc {
  217         struct device sc_dev;
  218         void *sc_ih;
  219 
  220         int sc_iobase;
  221         caddr_t sc_maddr;
  222         u_int sc_msize;
  223 
  224         struct arpcom sc_arpcom;
  225 
  226         void (*reset_586)(struct ie_softc *);
  227         void (*chan_attn)(struct ie_softc *);
  228 
  229         enum ie_hardware hard_type;
  230         int hard_vers;
  231 
  232         int want_mcsetup;
  233         int promisc;
  234         volatile struct ie_int_sys_conf_ptr *iscp;
  235         volatile struct ie_sys_ctl_block *scb;
  236 
  237         int rfhead, rftail, rbhead, rbtail;
  238         volatile struct ie_recv_frame_desc *rframes[NFRAMES];
  239         volatile struct ie_recv_buf_desc *rbuffs[NRXBUF];
  240         volatile char *cbuffs[NRXBUF];
  241 
  242         int xmit_busy;
  243         int xchead, xctail;
  244         volatile struct ie_xmit_cmd *xmit_cmds[NTXBUF];
  245         volatile struct ie_xmit_buf *xmit_buffs[NTXBUF];
  246         u_char *xmit_cbuffs[NTXBUF];
  247 
  248         struct ie_en_addr mcast_addrs[MAXMCAST + 1];
  249         int mcast_count;
  250 
  251         u_short irq_encoded;            /* encoded interrupt on IEE16 */
  252 
  253 #ifdef IEDEBUG
  254         int sc_debug;
  255 #endif
  256 };
  257 
  258 void iewatchdog(struct ifnet *);
  259 int ieintr(void *);
  260 void iestop(struct ie_softc *);
  261 int ieinit(struct ie_softc *);
  262 int ieioctl(struct ifnet *, u_long, caddr_t);
  263 void iestart(struct ifnet *);
  264 static void el_reset_586(struct ie_softc *);
  265 static void sl_reset_586(struct ie_softc *);
  266 static void el_chan_attn(struct ie_softc *);
  267 static void sl_chan_attn(struct ie_softc *);
  268 static void slel_get_address(struct ie_softc *);
  269 
  270 static void ee16_reset_586(struct ie_softc *);
  271 static void ee16_chan_attn(struct ie_softc *);
  272 static void ee16_interrupt_enable(struct ie_softc *);
  273 void ee16_eeprom_outbits(struct ie_softc *, int, int);
  274 void ee16_eeprom_clock(struct ie_softc *, int);
  275 u_short ee16_read_eeprom(struct ie_softc *, int);
  276 int ee16_eeprom_inbits(struct ie_softc *);
  277 
  278 void iereset(struct ie_softc *);
  279 void ie_readframe(struct ie_softc *, int);
  280 void ie_drop_packet_buffer(struct ie_softc *);
  281 void ie_find_mem_size(struct ie_softc *);
  282 static int command_and_wait(struct ie_softc *, int,
  283     void volatile *, int);
  284 void ierint(struct ie_softc *);
  285 void ietint(struct ie_softc *);
  286 void iexmit(struct ie_softc *);
  287 struct mbuf *ieget(struct ie_softc *,
  288     struct ether_header *, int *);
  289 void iememinit(void *, struct ie_softc *);
  290 static int mc_setup(struct ie_softc *, void *);
  291 static void mc_reset(struct ie_softc *);
  292 
  293 #ifdef IEDEBUG
  294 void print_rbd(volatile struct ie_recv_buf_desc *);
  295 
  296 int in_ierint = 0;
  297 int in_ietint = 0;
  298 #endif
  299 
  300 int     ieprobe(struct device *, void *, void *);
  301 void    ieattach(struct device *, struct device *, void *);
  302 int     sl_probe(struct ie_softc *, struct isa_attach_args *);
  303 int     el_probe(struct ie_softc *, struct isa_attach_args *);
  304 int     ee16_probe(struct ie_softc *, struct isa_attach_args *);
  305 int     check_ie_present(struct ie_softc *, caddr_t, u_int);
  306 
  307 static __inline void ie_setup_config(volatile struct ie_config_cmd *,
  308     int, int);
  309 static __inline void ie_ack(struct ie_softc *, u_int);
  310 static __inline int ether_equal(u_char *, u_char *);
  311 static __inline int check_eh(struct ie_softc *, struct ether_header *,
  312     int *);
  313 static __inline int ie_buflen(struct ie_softc *, int);
  314 static __inline int ie_packet_len(struct ie_softc *);
  315 
  316 static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *);
  317 
  318 struct cfattach ie_isa_ca = {
  319         sizeof(struct ie_softc), ieprobe, ieattach
  320 };
  321 
  322 struct cfdriver ie_cd = {
  323         NULL, "ie", DV_IFNET
  324 };
  325 
  326 #define MK_24(base, ptr) ((caddr_t)((u_long)ptr - (u_long)base))
  327 #define MK_16(base, ptr) ((u_short)(u_long)MK_24(base, ptr))
  328 
  329 #define PORT    sc->sc_iobase
  330 #define MEM     sc->sc_maddr
  331 
  332 /*
  333  * Here are a few useful functions.  We could have done these as macros, but
  334  * since we have the inline facility, it makes sense to use that instead.
  335  */
  336 static __inline void
  337 ie_setup_config(cmd, promiscuous, manchester)
  338         volatile struct ie_config_cmd *cmd;
  339         int promiscuous, manchester;
  340 {
  341 
  342         cmd->ie_config_count = 0x0c;
  343         cmd->ie_fifo = 8;
  344         cmd->ie_save_bad = 0x40;
  345         cmd->ie_addr_len = 0x2e;
  346         cmd->ie_priority = 0;
  347         cmd->ie_ifs = 0x60;
  348         cmd->ie_slot_low = 0;
  349         cmd->ie_slot_high = 0xf2;
  350         cmd->ie_promisc = promiscuous | manchester << 2;
  351         cmd->ie_crs_cdt = 0;
  352         cmd->ie_min_len = 64;
  353         cmd->ie_junk = 0xff;
  354 }
  355 
  356 static __inline void
  357 ie_ack(sc, mask)
  358         struct ie_softc *sc;
  359         u_int mask;
  360 {
  361         volatile struct ie_sys_ctl_block *scb = sc->scb;
  362 
  363         scb->ie_command = scb->ie_status & mask;
  364         (sc->chan_attn)(sc);
  365 
  366         while (scb->ie_command)
  367                 ;               /* Spin Lock */
  368 }
  369 
  370 int
  371 ieprobe(parent, match, aux)
  372         struct device *parent;
  373         void *match, *aux;
  374 {
  375         struct ie_softc *sc = match;
  376         struct isa_attach_args *ia = aux;
  377 
  378         if (sl_probe(sc, ia))
  379                 return 1;
  380         if (el_probe(sc, ia))
  381                 return 1;
  382         if (ee16_probe(sc, ia))
  383                 return 1;
  384         return 0;
  385 }
  386 
  387 int
  388 sl_probe(sc, ia)
  389         struct ie_softc *sc;
  390         struct isa_attach_args *ia;
  391 {
  392         u_char c;
  393 
  394         sc->sc_iobase = ia->ia_iobase;
  395 
  396         /* Need this for part of the probe. */
  397         sc->reset_586 = sl_reset_586;
  398         sc->chan_attn = sl_chan_attn;
  399 
  400         c = inb(PORT + IEATT_REVISION);
  401         switch (SL_BOARD(c)) {
  402         case SL10_BOARD:
  403                 sc->hard_type = IE_STARLAN10;
  404                 break;
  405         case EN100_BOARD:
  406                 sc->hard_type = IE_EN100;
  407                 break;
  408         case SLFIBER_BOARD:
  409                 sc->hard_type = IE_SLFIBER;
  410                 break;
  411 
  412         default:
  413                 /* Anything else is not recognized or cannot be used. */
  414 #if 0
  415                 printf("%s: unknown AT&T board type code %d\n",
  416                     sc->sc_dev.dv_xname, SL_BOARD(c));
  417 #endif
  418                 return 0;
  419         }
  420 
  421         sc->hard_vers = SL_REV(c);
  422 
  423         if (ia->ia_irq == IRQUNK || ia->ia_maddr == MADDRUNK) {
  424                 printf("%s: %s does not have soft configuration\n",
  425                     sc->sc_dev.dv_xname, ie_hardware_names[sc->hard_type]);
  426                 return 0;
  427         }
  428 
  429         /*
  430          * Divine memory size on-board the card.  Ususally 16k.
  431          */
  432         sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
  433         ie_find_mem_size(sc);
  434 
  435         if (!sc->sc_msize) {
  436                 printf("%s: can't find shared memory\n", sc->sc_dev.dv_xname);
  437                 return 0;
  438         }
  439 
  440         if (!ia->ia_msize)
  441                 ia->ia_msize = sc->sc_msize;
  442         else if (ia->ia_msize != sc->sc_msize) {
  443                 printf("%s: msize mismatch; kernel configured %d != board configured %d\n",
  444                     sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
  445                 return 0;
  446         }
  447 
  448         slel_get_address(sc);
  449 
  450         ia->ia_iosize = 16;
  451         return 1;
  452 }
  453 
  454 int
  455 el_probe(sc, ia)
  456         struct ie_softc *sc;
  457         struct isa_attach_args *ia;
  458 {
  459         bus_space_tag_t iot = ia->ia_iot;
  460         bus_space_handle_t ioh;
  461         u_char c;
  462         int i, rval = 0;
  463         u_char signature[] = "*3COM*";
  464 
  465         sc->sc_iobase = ia->ia_iobase;
  466 
  467         /* Need this for part of the probe. */
  468         sc->reset_586 = el_reset_586;
  469         sc->chan_attn = el_chan_attn;
  470 
  471         /*
  472          * Map the Etherlink ID port for the probe sequence.
  473          */
  474         if (bus_space_map(iot, ELINK_ID_PORT, 1, 0, &ioh)) {
  475                 printf("3c507 probe: can't map Etherlink ID port\n");
  476                 return 0;
  477         }
  478 
  479         /*
  480          * Reset and put card in CONFIG state without changing address.
  481          * XXX Indirect brokenness here!
  482          */
  483         elink_reset(iot, ioh, sc->sc_dev.dv_parent->dv_unit);
  484         elink_idseq(iot, ioh, ELINK_507_POLY);
  485         elink_idseq(iot, ioh, ELINK_507_POLY);
  486         outb(ELINK_ID_PORT, 0xff);
  487 
  488         /* Check for 3COM signature before proceeding. */
  489         outb(PORT + IE507_CTRL, inb(PORT + IE507_CTRL) & 0xfc); /* XXX */
  490         for (i = 0; i < 6; i++)
  491                 if (inb(PORT + i) != signature[i])
  492                         goto out;
  493 
  494         c = inb(PORT + IE507_MADDR);
  495         if (c & 0x20) {
  496                 printf("%s: can't map 3C507 RAM in high memory\n",
  497                     sc->sc_dev.dv_xname);
  498                 goto out;
  499         }
  500 
  501         /* Go to RUN state. */
  502         outb(ELINK_ID_PORT, 0x00);
  503         elink_idseq(iot, ioh, ELINK_507_POLY);
  504         outb(ELINK_ID_PORT, 0x00);
  505 
  506         /* Set bank 2 for version info and read BCD version byte. */
  507         outb(PORT + IE507_CTRL, EL_CTRL_NRST | EL_CTRL_BNK2);
  508         i = inb(PORT + 3);
  509 
  510         sc->hard_type = IE_3C507;
  511         sc->hard_vers = 10*(i / 16) + (i % 16) - 1;
  512 
  513         i = inb(PORT + IE507_IRQ) & 0x0f;
  514 
  515         if (ia->ia_irq != IRQUNK) {
  516                 if (ia->ia_irq != i) {
  517                         printf("%s: irq mismatch; kernel configured %d != board configured %d\n",
  518                             sc->sc_dev.dv_xname, ia->ia_irq, i);
  519                         goto out;
  520                 }
  521         } else
  522                 ia->ia_irq = i;
  523 
  524         i = ((inb(PORT + IE507_MADDR) & 0x1c) << 12) + 0xc0000;
  525 
  526         if (ia->ia_maddr != MADDRUNK) {
  527                 if (ia->ia_maddr != i) {
  528                         printf("%s: maddr mismatch; kernel configured %x != board configured %x\n",
  529                             sc->sc_dev.dv_xname, ia->ia_maddr, i);
  530                         goto out;
  531                 }
  532         } else
  533                 ia->ia_maddr = i;
  534 
  535         outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
  536 
  537         /*
  538          * Divine memory size on-board the card.
  539          */
  540         sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
  541         ie_find_mem_size(sc);
  542 
  543         if (!sc->sc_msize) {
  544                 printf("%s: can't find shared memory\n", sc->sc_dev.dv_xname);
  545                 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
  546                 goto out;
  547         }
  548 
  549         if (!ia->ia_msize)
  550                 ia->ia_msize = sc->sc_msize;
  551         else if (ia->ia_msize != sc->sc_msize) {
  552                 printf("%s: msize mismatch; kernel configured %d != board configured %d\n",
  553                     sc->sc_dev.dv_xname, ia->ia_msize, sc->sc_msize);
  554                 outb(PORT + IE507_CTRL, EL_CTRL_NRST);
  555                 goto out;
  556         }
  557 
  558         slel_get_address(sc);
  559 
  560         /* Clear the interrupt latch just in case. */
  561         outb(PORT + IE507_ICTRL, 1);
  562 
  563         ia->ia_iosize = 16;
  564         rval = 1;
  565 
  566  out:
  567         bus_space_unmap(iot, ioh, 1);
  568         return rval;
  569 }
  570 
  571 /* Taken almost exactly from Rod's if_ix.c. */
  572 
  573 int
  574 ee16_probe(sc, ia)
  575         struct ie_softc *sc;
  576         struct isa_attach_args *ia;
  577 {
  578         int i;
  579         u_short board_id, id_var1, id_var2, checksum = 0;
  580         u_short eaddrtemp, irq;
  581         u_short pg, adjust, decode, edecode;
  582         u_char  bart_config;
  583 
  584         short   irq_translate[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
  585 
  586         /* Need this for part of the probe. */
  587         sc->reset_586 = ee16_reset_586;
  588         sc->chan_attn = ee16_chan_attn;
  589 
  590         /* reset any ee16 at the current iobase */
  591         outb(ia->ia_iobase + IEE16_ECTRL, IEE16_RESET_ASIC);
  592         outb(ia->ia_iobase + IEE16_ECTRL, 0);
  593         delay(240);
  594 
  595         /* now look for ee16. */
  596         board_id = id_var1 = id_var2 = 0;
  597         for (i=0; i<4 ; i++) {
  598                 id_var1 = inb(ia->ia_iobase + IEE16_ID_PORT);
  599                 id_var2 = ((id_var1 & 0x03) << 2);
  600                 board_id |= (( id_var1 >> 4)  << id_var2);
  601                 }
  602 
  603         if (board_id != IEE16_ID)
  604                 return 0;               
  605 
  606         /* need sc->sc_iobase for ee16_read_eeprom */
  607         sc->sc_iobase = ia->ia_iobase;
  608         sc->hard_type = IE_EE16;
  609 
  610         /*
  611          * If ia->maddr == MADDRUNK, use value in eeprom location 6.
  612          *
  613          * The shared RAM location on the EE16 is encoded into bits
  614          * 3-7 of EEPROM location 6.  We zero the upper byte, and 
  615          * shift the 5 bits right 3.  The resulting number tells us
  616          * the RAM location.  Because the EE16 supports either 16k or 32k
  617          * of shared RAM, we only worry about the 32k locations. 
  618          *
  619          * NOTE: if a 64k EE16 exists, it should be added to this switch.
  620          *       then the ia->ia_msize would need to be set per case statement.
  621          *
  622          *      value   msize   location
  623          *      =====   =====   ========
  624          *      0x03    0x8000  0xCC000
  625          *      0x06    0x8000  0xD0000
  626          *      0x0C    0x8000  0xD4000
  627          *      0x18    0x8000  0xD8000
  628          *
  629          */ 
  630 
  631         if ((ia->ia_maddr == MADDRUNK) || (ia->ia_msize == 0)) {
  632                 i = (ee16_read_eeprom(sc, 6) & 0x00ff ) >> 3;
  633                 switch(i) {
  634                         case 0x03:
  635                                 ia->ia_maddr = 0xCC000;
  636                                 break;
  637                         case 0x06:
  638                                 ia->ia_maddr = 0xD0000;
  639                                 break;
  640                         case 0x0c:
  641                                 ia->ia_maddr = 0xD4000;
  642                                 break;
  643                         case 0x18:
  644                                 ia->ia_maddr = 0xD8000;
  645                                 break;
  646                         default:
  647                                 return 0 ;
  648                                 break; /* NOTREACHED */
  649                 }
  650                 ia->ia_msize = 0x8000; 
  651         }
  652 
  653         /* need to set these after checking for MADDRUNK */
  654         sc->sc_maddr = ISA_HOLE_VADDR(ia->ia_maddr);
  655         sc->sc_msize = ia->ia_msize; 
  656 
  657         /* need to put the 586 in RESET, and leave it */
  658         outb( PORT + IEE16_ECTRL, IEE16_RESET_586);  
  659 
  660         /* read the eeprom and checksum it, should == IEE16_ID */
  661         for(i=0 ; i< 0x40 ; i++)
  662                 checksum += ee16_read_eeprom(sc, i);
  663 
  664         if (checksum != IEE16_ID)
  665                 return 0;       
  666 
  667         /*
  668          * Size and test the memory on the board.  The size of the memory
  669          * can be one of 16k, 32k, 48k or 64k.  It can be located in the
  670          * address range 0xC0000 to 0xEFFFF on 16k boundaries. 
  671          *
  672          * If the size does not match the passed in memory allocation size
  673          * issue a warning, but continue with the minimum of the two sizes.
  674          */
  675 
  676         switch (ia->ia_msize) {
  677                 case 65536:
  678                 case 32768: /* XXX Only support 32k and 64k right now */
  679                         break;
  680                 case 16384:
  681                 case 49512:
  682                 default:
  683                         printf("ieprobe mapped memory size out of range\n");
  684                         return 0;
  685                         break; /* NOTREACHED */
  686         }
  687 
  688         if ((kvtop(sc->sc_maddr) < 0xC0000) ||
  689             (kvtop(sc->sc_maddr) + sc->sc_msize > 0xF0000)) {
  690                 printf("ieprobe mapped memory address out of range\n");
  691                 return 0;
  692         }
  693 
  694         pg = (kvtop(sc->sc_maddr) & 0x3C000) >> 14;
  695         adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2;
  696         decode = ((1 << (sc->sc_msize / 16384)) - 1) << pg;
  697         edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
  698 
  699         /* ZZZ This should be checked against eeprom location 6, low byte */
  700         outb(PORT + IEE16_MEMDEC, decode & 0xFF);
  701         /* ZZZ This should be checked against eeprom location 1, low byte */
  702         outb(PORT + IEE16_MCTRL, adjust);
  703         /* ZZZ Now if I could find this one I would have it made */
  704         outb(PORT + IEE16_MPCTRL, (~decode & 0xFF));
  705         /* ZZZ I think this is location 6, high byte */
  706         outb(PORT + IEE16_MECTRL, edecode); /*XXX disable Exxx */
  707 
  708         /*
  709          * first prime the stupid bart DRAM controller so that it
  710          * works, then zero out all of memory.
  711          */
  712         bzero(sc->sc_maddr, 32);
  713         bzero(sc->sc_maddr, sc->sc_msize);
  714 
  715         /*
  716          * Get the encoded interrupt number from the EEPROM, check it
  717          * against the passed in IRQ.  Issue a warning if they do not
  718          * match, and fail the probe.  If irq is 'IRQUNK' then we
  719          * use the EEPROM irq, and continue.
  720          */
  721         irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1);
  722         irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT;
  723         sc->irq_encoded = irq;
  724         irq = irq_translate[irq];
  725         if (ia->ia_irq != IRQUNK) {
  726                 if (irq != ia->ia_irq) {
  727 #ifdef DIAGNOSTIC
  728                         printf("\nie%d: fatal: board IRQ %d does not match kernel\n", sc->sc_dev.dv_unit, irq);
  729 #endif /* DIAGNOSTIC */
  730                         return 0;       /* _must_ match or probe fails */
  731                 }
  732         } else
  733                 ia->ia_irq = irq;
  734 
  735         /*
  736          * Get the hardware ethernet address from the EEPROM and
  737          * save it in the softc for use by the 586 setup code.
  738          */
  739         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH);
  740         sc->sc_arpcom.ac_enaddr[1] = eaddrtemp & 0xFF;
  741         sc->sc_arpcom.ac_enaddr[0] = eaddrtemp >> 8;
  742         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID);
  743         sc->sc_arpcom.ac_enaddr[3] = eaddrtemp & 0xFF;
  744         sc->sc_arpcom.ac_enaddr[2] = eaddrtemp >> 8;
  745         eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW);
  746         sc->sc_arpcom.ac_enaddr[5] = eaddrtemp & 0xFF;
  747         sc->sc_arpcom.ac_enaddr[4] = eaddrtemp >> 8;
  748 
  749         /* disable the board interrupts */
  750         outb(PORT + IEE16_IRQ, sc->irq_encoded);
  751 
  752         /* enable loopback to keep bad packets off the wire */
  753         if(sc->hard_type == IE_EE16) {
  754                 bart_config = inb(PORT + IEE16_CONFIG);
  755                 bart_config |= IEE16_BART_LOOPBACK;
  756                 bart_config |= IEE16_BART_MCS16_TEST; /* inb doesn't get bit! */
  757                 outb(PORT + IEE16_CONFIG, bart_config);
  758                 bart_config = inb(PORT + IEE16_CONFIG);
  759         }
  760 
  761         outb(PORT + IEE16_ECTRL, 0);
  762         delay(100);
  763         if (!check_ie_present(sc, sc->sc_maddr, sc->sc_msize))
  764                 return 0;
  765 
  766         ia->ia_iosize = 16;     /* the number of I/O ports */
  767         return 1;               /* found */
  768 }
  769 
  770 /*
  771  * Taken almost exactly from Bill's if_is.c, then modified beyond recognition.
  772  */
  773 void
  774 ieattach(parent, self, aux)
  775         struct device *parent, *self;
  776         void *aux;
  777 {
  778         struct ie_softc *sc = (void *)self;
  779         struct isa_attach_args *ia = aux;
  780         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  781 
  782         bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  783         ifp->if_softc = sc;
  784         ifp->if_start = iestart;
  785         ifp->if_ioctl = ieioctl;
  786         ifp->if_watchdog = iewatchdog;
  787         ifp->if_flags =
  788             IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  789         IFQ_SET_READY(&ifp->if_snd);
  790 
  791         /* Attach the interface. */
  792         if_attach(ifp);
  793         ether_ifattach(ifp);
  794 
  795         printf(": address %s, type %s R%d\n",
  796             ether_sprintf(sc->sc_arpcom.ac_enaddr),
  797             ie_hardware_names[sc->hard_type], sc->hard_vers + 1);
  798 
  799         sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
  800             IPL_NET, ieintr, sc, sc->sc_dev.dv_xname);
  801 }
  802 
  803 /*
  804  * Device timeout/watchdog routine.  Entered if the device neglects to generate
  805  * an interrupt after a transmit has been started on it.
  806  */
  807 void
  808 iewatchdog(ifp)
  809         struct ifnet *ifp;
  810 {
  811         struct ie_softc *sc = ifp->if_softc;
  812 
  813         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
  814         ++sc->sc_arpcom.ac_if.if_oerrors;
  815         iereset(sc);
  816 }
  817 
  818 /*
  819  * What to do upon receipt of an interrupt.
  820  */
  821 int
  822 ieintr(arg)
  823         void *arg;
  824 {
  825         struct ie_softc *sc = arg;
  826         register u_short status;
  827 
  828         /* Clear the interrupt latch on the 3C507. */
  829         if (sc->hard_type == IE_3C507)
  830                 outb(PORT + IE507_ICTRL, 1);
  831 
  832         /* disable interrupts on the EE16. */
  833         if (sc->hard_type == IE_EE16)
  834                 outb(PORT + IEE16_IRQ, sc->irq_encoded);
  835 
  836         status = sc->scb->ie_status & IE_ST_WHENCE;
  837         if (status == 0)
  838                 return 0;
  839 
  840 loop:
  841         /* Ack interrupts FIRST in case we receive more during the ISR. */
  842         ie_ack(sc, status);
  843 
  844         if (status & (IE_ST_FR | IE_ST_RNR)) {
  845 #ifdef IEDEBUG
  846                 in_ierint++;
  847                 if (sc->sc_debug & IED_RINT)
  848                         printf("%s: rint\n", sc->sc_dev.dv_xname);
  849 #endif
  850                 ierint(sc);
  851 #ifdef IEDEBUG
  852                 in_ierint--;
  853 #endif
  854         }
  855 
  856         if (status & IE_ST_CX) {
  857 #ifdef IEDEBUG
  858                 in_ietint++;
  859                 if (sc->sc_debug & IED_TINT)
  860                         printf("%s: tint\n", sc->sc_dev.dv_xname);
  861 #endif
  862                 ietint(sc);
  863 #ifdef IEDEBUG
  864                 in_ietint--;
  865 #endif
  866         }
  867 
  868         if (status & IE_ST_RNR) {
  869                 printf("%s: receiver not ready\n", sc->sc_dev.dv_xname);
  870                 sc->sc_arpcom.ac_if.if_ierrors++;
  871                 iereset(sc);
  872         }
  873 
  874 #ifdef IEDEBUG
  875         if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
  876                 printf("%s: cna\n", sc->sc_dev.dv_xname);
  877 #endif
  878 
  879         /* Clear the interrupt latch on the 3C507. */
  880         if (sc->hard_type == IE_3C507)
  881                 outb(PORT + IE507_ICTRL, 1);
  882 
  883         status = sc->scb->ie_status & IE_ST_WHENCE;
  884         if (status == 0) {
  885                 /* enable interrupts on the EE16. */
  886                 if (sc->hard_type == IE_EE16)
  887                     outb(PORT + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
  888                 return 1;
  889         }
  890 
  891         goto loop;
  892 }
  893 
  894 /*
  895  * Process a received-frame interrupt.
  896  */
  897 void
  898 ierint(sc)
  899         struct ie_softc *sc;
  900 {
  901         volatile struct ie_sys_ctl_block *scb = sc->scb;
  902         int i, status;
  903         static int timesthru = 1024;
  904 
  905         i = sc->rfhead;
  906         for (;;) {
  907                 status = sc->rframes[i]->ie_fd_status;
  908 
  909                 if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) {
  910                         if (!--timesthru) {
  911                                 sc->sc_arpcom.ac_if.if_ierrors +=
  912                                     scb->ie_err_crc + scb->ie_err_align +
  913                                     scb->ie_err_resource + scb->ie_err_overrun;
  914                                 scb->ie_err_crc = scb->ie_err_align =
  915                                     scb->ie_err_resource = scb->ie_err_overrun =
  916                                     0;
  917                                 timesthru = 1024;
  918                         }
  919                         ie_readframe(sc, i);
  920                 } else {
  921                         if ((status & IE_FD_RNR) != 0 &&
  922                             (scb->ie_status & IE_RU_READY) == 0) {
  923                                 sc->rframes[0]->ie_fd_buf_desc =
  924                                                 MK_16(MEM, sc->rbuffs[0]);
  925                                 scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
  926                                 command_and_wait(sc, IE_RU_START, 0, 0);
  927                         }
  928                         break;
  929                 }
  930                 i = (i + 1) % NFRAMES;
  931         }
  932 }
  933 
  934 /*
  935  * Process a command-complete interrupt.  These are only generated by the
  936  * transmission of frames.  This routine is deceptively simple, since most of
  937  * the real work is done by iestart().
  938  */
  939 void
  940 ietint(sc)
  941         struct ie_softc *sc;
  942 {
  943         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  944         int status;
  945 
  946         ifp->if_timer = 0;
  947         ifp->if_flags &= ~IFF_OACTIVE;
  948 
  949         status = sc->xmit_cmds[sc->xctail]->ie_xmit_status;
  950 
  951         if (!(status & IE_STAT_COMPL) || (status & IE_STAT_BUSY))
  952                 printf("ietint: command still busy!\n");
  953 
  954         if (status & IE_STAT_OK) {
  955                 ifp->if_opackets++;
  956                 ifp->if_collisions += status & IE_XS_MAXCOLL;
  957         } else {
  958                 ifp->if_oerrors++;
  959                 /*
  960                  * XXX
  961                  * Check SQE and DEFERRED?
  962                  * What if more than one bit is set?
  963                  */
  964                 if (status & IE_STAT_ABORT)
  965                         printf("%s: send aborted\n", sc->sc_dev.dv_xname);
  966                 else if (status & IE_XS_LATECOLL)
  967                         printf("%s: late collision\n", sc->sc_dev.dv_xname);
  968                 else if (status & IE_XS_NOCARRIER)
  969                         printf("%s: no carrier\n", sc->sc_dev.dv_xname);
  970                 else if (status & IE_XS_LOSTCTS)
  971                         printf("%s: lost CTS\n", sc->sc_dev.dv_xname);
  972                 else if (status & IE_XS_UNDERRUN)
  973                         printf("%s: DMA underrun\n", sc->sc_dev.dv_xname);
  974                 else if (status & IE_XS_EXCMAX) {
  975                         printf("%s: too many collisions\n", sc->sc_dev.dv_xname);
  976                         ifp->if_collisions += 16;
  977                 }
  978         }
  979 
  980         /*
  981          * If multicast addresses were added or deleted while transmitting,
  982          * mc_reset() set the want_mcsetup flag indicating that we should do
  983          * it.
  984          */
  985         if (sc->want_mcsetup) {
  986                 mc_setup(sc, (caddr_t)sc->xmit_cbuffs[sc->xctail]);
  987                 sc->want_mcsetup = 0;
  988         }
  989 
  990         /* Done with the buffer. */
  991         sc->xmit_busy--;
  992         sc->xctail = (sc->xctail + 1) % NTXBUF;
  993 
  994         /* Start the next packet, if any, transmitting. */
  995         if (sc->xmit_busy > 0)
  996                 iexmit(sc);
  997 
  998         iestart(ifp);
  999 }
 1000 
 1001 /*
 1002  * Compare two Ether/802 addresses for equality, inlined and unrolled for
 1003  * speed.  I'd love to have an inline assembler version of this...
 1004  */
 1005 static __inline int
 1006 ether_equal(one, two)
 1007         u_char *one, *two;
 1008 {
 1009 
 1010         if (one[0] != two[0] || one[1] != two[1] || one[2] != two[2] ||
 1011             one[3] != two[3] || one[4] != two[4] || one[5] != two[5])
 1012                 return 0;
 1013         return 1;
 1014 }
 1015 
 1016 /*
 1017  * Check for a valid address.  to_bpf is filled in with one of the following:
 1018  *   0 -> BPF doesn't get this packet
 1019  *   1 -> BPF does get this packet
 1020  *   2 -> BPF does get this packet, but we don't
 1021  * Return value is true if the packet is for us, and false otherwise.
 1022  *
 1023  * This routine is a mess, but it's also critical that it be as fast
 1024  * as possible.  It could be made cleaner if we can assume that the
 1025  * only client which will fiddle with IFF_PROMISC is BPF.  This is
 1026  * probably a good assumption, but we do not make it here.  (Yet.)
 1027  */
 1028 static __inline int
 1029 check_eh(sc, eh, to_bpf)
 1030         struct ie_softc *sc;
 1031         struct ether_header *eh;
 1032         int *to_bpf;
 1033 {
 1034         int i;
 1035 
 1036         switch (sc->promisc) {
 1037         case IFF_ALLMULTI:
 1038                 /*
 1039                  * Receiving all multicasts, but no unicasts except those
 1040                  * destined for us.
 1041                  */
 1042 #if NBPFILTER > 0
 1043                 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0); /* BPF gets this packet if anybody cares */
 1044 #endif
 1045                 if (eh->ether_dhost[0] & 1)
 1046                         return 1;
 1047                 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
 1048                         return 1;
 1049                 return 0;
 1050 
 1051         case IFF_PROMISC:
 1052                 /*
 1053                  * Receiving all packets.  These need to be passed on to BPF.
 1054                  */
 1055 #if NBPFILTER > 0
 1056                 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
 1057                     (sc->sc_arpcom.ac_if.if_bridge != NULL);
 1058 #else
 1059                 *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
 1060 #endif
 1061                 /* If for us, accept and hand up to BPF */
 1062                 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
 1063                         return 1;
 1064 
 1065 #if NBPFILTER > 0
 1066                 if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
 1067                         *to_bpf = 2; /* we don't need to see it */
 1068 #endif
 1069 
 1070                 /*
 1071                  * Not a multicast, so BPF wants to see it but we don't.
 1072                  */
 1073                 if (!(eh->ether_dhost[0] & 1))
 1074                         return 1;
 1075 
 1076                 /*
 1077                  * If it's one of our multicast groups, accept it and pass it
 1078                  * up.
 1079                  */
 1080                 for (i = 0; i < sc->mcast_count; i++) {
 1081                         if (ether_equal(eh->ether_dhost, (u_char *)&sc->mcast_addrs[i])) {
 1082 #if NBPFILTER > 0
 1083                                 if (*to_bpf)
 1084                                         *to_bpf = 1;
 1085 #endif
 1086                                 return 1;
 1087                         }
 1088                 }
 1089                 return 1;
 1090 
 1091         case IFF_ALLMULTI | IFF_PROMISC:
 1092                 /*
 1093                  * Acting as a multicast router, and BPF running at the same
 1094                  * time.  Whew!  (Hope this is a fast machine...)
 1095                  */
 1096 #if NBPFILTER > 0
 1097                 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) ||
 1098                     (sc->sc_arpcom.ac_if.if_bridge != NULL);
 1099 #else
 1100                 *to_bpf = (sc->sc_arpcom.ac_if.if_bridge != NULL);
 1101 #endif
 1102                 /* We want to see multicasts. */
 1103                 if (eh->ether_dhost[0] & 1)
 1104                         return 1;
 1105 
 1106                 /* We want to see our own packets */
 1107                 if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr))
 1108                         return 1;
 1109 
 1110                 /* Anything else goes to BPF but nothing else. */
 1111 #if NBPFILTER > 0
 1112                 if (*to_bpf && sc->sc_arpcom.ac_if.if_bridge == NULL)
 1113                         *to_bpf = 2;
 1114 #endif
 1115                 return 1;
 1116 
 1117         case 0:
 1118                 /*
 1119                  * Only accept unicast packets destined for us, or multicasts
 1120                  * for groups that we belong to.  For now, we assume that the
 1121                  * '586 will only return packets that we asked it for.  This
 1122                  * isn't strictly true (it uses hashing for the multicast
 1123                  * filter), but it will do in this case, and we want to get out
 1124                  * of here as quickly as possible.
 1125                  */
 1126 #if NBPFILTER > 0
 1127                 *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0);
 1128 #endif
 1129                 return 1;
 1130         }
 1131 
 1132 #ifdef DIAGNOSTIC
 1133         panic("check_eh: impossible");
 1134 #endif
 1135         return 0;
 1136 }
 1137 
 1138 /*
 1139  * We want to isolate the bits that have meaning...  This assumes that
 1140  * IE_RBUF_SIZE is an even power of two.  If somehow the act_len exceeds
 1141  * the size of the buffer, then we are screwed anyway.
 1142  */
 1143 static __inline int
 1144 ie_buflen(sc, head)
 1145         struct ie_softc *sc;
 1146         int head;
 1147 {
 1148 
 1149         return (sc->rbuffs[head]->ie_rbd_actual
 1150             & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1)));
 1151 }
 1152 
 1153 static __inline int
 1154 ie_packet_len(sc)
 1155         struct ie_softc *sc;
 1156 {
 1157         int i;
 1158         int head = sc->rbhead;
 1159         int acc = 0;
 1160 
 1161         do {
 1162                 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED))
 1163                         return -1;
 1164 
 1165                 i = sc->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST;
 1166 
 1167                 acc += ie_buflen(sc, head);
 1168                 head = (head + 1) % NRXBUF;
 1169         } while (!i);
 1170 
 1171         return acc;
 1172 }
 1173 
 1174 /*
 1175  * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
 1176  * command to the chip to be executed.  On the way, if we have a BPF listener
 1177  * also give him a copy.
 1178  */
 1179 void
 1180 iexmit(sc)
 1181         struct ie_softc *sc;
 1182 {
 1183 
 1184 #ifdef IEDEBUG
 1185         if (sc->sc_debug & IED_XMIT)
 1186                 printf("%s: xmit buffer %d\n", sc->sc_dev.dv_xname,
 1187                     sc->xctail);
 1188 #endif
 1189 
 1190 #if NBPFILTER > 0
 1191         /*
 1192          * If BPF is listening on this interface, let it see the packet before
 1193          * we push it on the wire.
 1194          */
 1195         if (sc->sc_arpcom.ac_if.if_bpf)
 1196                 bpf_tap(sc->sc_arpcom.ac_if.if_bpf,
 1197                     sc->xmit_cbuffs[sc->xctail],
 1198                     sc->xmit_buffs[sc->xctail]->ie_xmit_flags,
 1199                     BPF_DIRECTION_OUT);
 1200 #endif
 1201 
 1202         sc->xmit_buffs[sc->xctail]->ie_xmit_flags |= IE_XMIT_LAST;
 1203         sc->xmit_buffs[sc->xctail]->ie_xmit_next = 0xffff;
 1204         sc->xmit_buffs[sc->xctail]->ie_xmit_buf =
 1205             MK_24(MEM, sc->xmit_cbuffs[sc->xctail]);
 1206 
 1207         sc->xmit_cmds[sc->xctail]->com.ie_cmd_link = 0xffff;
 1208         sc->xmit_cmds[sc->xctail]->com.ie_cmd_cmd =
 1209             IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST;
 1210 
 1211         sc->xmit_cmds[sc->xctail]->ie_xmit_status = 0;
 1212         sc->xmit_cmds[sc->xctail]->ie_xmit_desc =
 1213             MK_16(MEM, sc->xmit_buffs[sc->xctail]);
 1214 
 1215         sc->scb->ie_command_list = MK_16(MEM, sc->xmit_cmds[sc->xctail]);
 1216         command_and_wait(sc, IE_CU_START, 0, 0);
 1217 
 1218         sc->sc_arpcom.ac_if.if_timer = 5;
 1219 }
 1220 
 1221 /*
 1222  * Read data off the interface, and turn it into an mbuf chain.
 1223  *
 1224  * This code is DRAMATICALLY different from the previous version; this version
 1225  * tries to allocate the entire mbuf chain up front, given the length of the
 1226  * data available.  This enables us to allocate mbuf clusters in many
 1227  * situations where before we would have had a long chain of partially-full
 1228  * mbufs.  This should help to speed up the operation considerably.  (Provided
 1229  * that it works, of course.)
 1230  */
 1231 struct mbuf *
 1232 ieget(sc, ehp, to_bpf)
 1233         struct ie_softc *sc;
 1234         struct ether_header *ehp;
 1235         int *to_bpf;
 1236 {
 1237         struct mbuf *top, **mp, *m;
 1238         int len, totlen, resid;
 1239         int thisrboff, thismboff;
 1240         int head;
 1241 
 1242         resid = totlen = ie_packet_len(sc);
 1243         if (totlen <= 0)
 1244                 return 0;
 1245 
 1246         head = sc->rbhead;
 1247 
 1248         /*
 1249          * Snarf the Ethernet header.
 1250          */
 1251         bcopy((caddr_t)sc->cbuffs[head], (caddr_t)ehp, sizeof *ehp);
 1252 
 1253         /*
 1254          * As quickly as possible, check if this packet is for us.
 1255          * If not, don't waste a single cycle copying the rest of the
 1256          * packet in.
 1257          * This is only a consideration when FILTER is defined; i.e., when
 1258          * we are either running BPF or doing multicasting.
 1259          */
 1260         if (!check_eh(sc, ehp, to_bpf)) {
 1261                 sc->sc_arpcom.ac_if.if_ierrors--; /* just this case, it's not an error */
 1262                 return 0;
 1263         }
 1264 
 1265         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1266         if (m == 0)
 1267                 return 0;
 1268         m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
 1269         m->m_pkthdr.len = totlen;
 1270         len = MHLEN;
 1271         top = 0;
 1272         mp = &top;
 1273 
 1274         /*
 1275          * This loop goes through and allocates mbufs for all the data we will
 1276          * be copying in.  It does not actually do the copying yet.
 1277          */
 1278         while (totlen > 0) {
 1279                 if (top) {
 1280                         MGET(m, M_DONTWAIT, MT_DATA);
 1281                         if (m == 0) {
 1282                                 m_freem(top);
 1283                                 return 0;
 1284                         }
 1285                         len = MLEN;
 1286                 }
 1287                 if (totlen >= MINCLSIZE) {
 1288                         MCLGET(m, M_DONTWAIT);
 1289                         if (m->m_flags & M_EXT)
 1290                                 len = MCLBYTES;
 1291                 }
 1292                 m->m_len = len = min(totlen, len);
 1293                 totlen -= len;
 1294                 *mp = m;
 1295                 mp = &m->m_next;
 1296         }
 1297 
 1298         m = top;
 1299         thisrboff = 0;
 1300         thismboff = 0;
 1301 
 1302         /*
 1303          * Now we take the mbuf chain (hopefully only one mbuf most of the
 1304          * time) and stuff the data into it.  There are no possible failures at
 1305          * or after this point.
 1306          */
 1307         while (resid > 0) {
 1308                 int thisrblen = ie_buflen(sc, head) - thisrboff,
 1309                     thismblen = m->m_len - thismboff;
 1310                 len = min(thisrblen, thismblen);
 1311 
 1312                 bcopy((caddr_t)(sc->cbuffs[head] + thisrboff),
 1313                     mtod(m, caddr_t) + thismboff, (u_int)len);
 1314                 resid -= len;
 1315 
 1316                 if (len == thismblen) {
 1317                         m = m->m_next;
 1318                         thismboff = 0;
 1319                 } else
 1320                         thismboff += len;
 1321 
 1322                 if (len == thisrblen) {
 1323                         head = (head + 1) % NRXBUF;
 1324                         thisrboff = 0;
 1325                 } else
 1326                         thisrboff += len;
 1327         }
 1328 
 1329         /*
 1330          * Unless something changed strangely while we were doing the copy, we
 1331          * have now copied everything in from the shared memory.
 1332          * This means that we are done.
 1333          */
 1334         return top;
 1335 }
 1336 
 1337 /*
 1338  * Read frame NUM from unit UNIT (pre-cached as IE).
 1339  *
 1340  * This routine reads the RFD at NUM, and copies in the buffers from the list
 1341  * of RBD, then rotates the RBD and RFD lists so that the receiver doesn't
 1342  * start complaining.  Trailers are DROPPED---there's no point in wasting time
 1343  * on confusing code to deal with them.  Hopefully, this machine will never ARP
 1344  * for trailers anyway.
 1345  */
 1346 void
 1347 ie_readframe(sc, num)
 1348         struct ie_softc *sc;
 1349         int num;                        /* frame number to read */
 1350 {
 1351         int status;
 1352         struct mbuf *m = 0;
 1353         struct ether_header eh;
 1354 #if NBPFILTER > 0
 1355         int bpf_gets_it = 0;
 1356 #endif
 1357 
 1358         status = sc->rframes[num]->ie_fd_status;
 1359 
 1360         /* Advance the RFD list, since we're done with this descriptor. */
 1361         sc->rframes[num]->ie_fd_status = 0;
 1362         sc->rframes[num]->ie_fd_last |= IE_FD_LAST;
 1363         sc->rframes[sc->rftail]->ie_fd_last &= ~IE_FD_LAST;
 1364         sc->rftail = (sc->rftail + 1) % NFRAMES;
 1365         sc->rfhead = (sc->rfhead + 1) % NFRAMES;
 1366 
 1367         if (status & IE_FD_OK) {
 1368 #if NBPFILTER > 0
 1369                 m = ieget(sc, &eh, &bpf_gets_it);
 1370 #else
 1371                 m = ieget(sc, &eh, 0);
 1372 #endif
 1373                 ie_drop_packet_buffer(sc);
 1374         }
 1375         if (m == 0) {
 1376                 sc->sc_arpcom.ac_if.if_ierrors++;
 1377                 return;
 1378         }
 1379 
 1380 #ifdef IEDEBUG
 1381         if (sc->sc_debug & IED_READFRAME)
 1382                 printf("%s: frame from ether %s type %x\n", sc->sc_dev.dv_xname,
 1383                     ether_sprintf(eh.ether_shost), (u_int)eh.ether_type);
 1384 #endif
 1385 
 1386 #if NBPFILTER > 0
 1387         /* Check for a BPF filter; if so, hand it up. */
 1388         if (bpf_gets_it) {
 1389                 /* Pass it up. */
 1390                 bpf_mtap(sc->sc_arpcom.ac_if.if_bpf, m, BPF_DIRECTION_IN);
 1391 
 1392                 /*
 1393                  * A signal passed up from the filtering code indicating that
 1394                  * the packet is intended for BPF but not for the protocol
 1395                  * machinery.  We can save a few cycles by not handing it off
 1396                  * to them.
 1397                  */
 1398                 if (bpf_gets_it == 2) {
 1399                         m_freem(m);
 1400                         return;
 1401                 }
 1402         }
 1403 #endif /* NBPFILTER > 0 */
 1404 
 1405         /*
 1406          * In here there used to be code to check destination addresses upon
 1407          * receipt of a packet.  We have deleted that code, and replaced it
 1408          * with code to check the address much earlier in the cycle, before
 1409          * copying the data in; this saves us valuable cycles when operating
 1410          * as a multicast router or when using BPF.
 1411          */
 1412 
 1413         /*
 1414          * Finally pass this packet up to higher layers.
 1415          */
 1416         ether_input_mbuf(&sc->sc_arpcom.ac_if, m);
 1417         sc->sc_arpcom.ac_if.if_ipackets++;
 1418 }
 1419 
 1420 void
 1421 ie_drop_packet_buffer(sc)
 1422         struct ie_softc *sc;
 1423 {
 1424         int i;
 1425 
 1426         do {
 1427                 /*
 1428                  * This means we are somehow out of sync.  So, we reset the
 1429                  * adapter.
 1430                  */
 1431                 if (!(sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_USED)) {
 1432 #ifdef IEDEBUG
 1433                         print_rbd(sc->rbuffs[sc->rbhead]);
 1434 #endif
 1435                         log(LOG_ERR, "%s: receive descriptors out of sync at %d\n",
 1436                             sc->sc_dev.dv_xname, sc->rbhead);
 1437                         iereset(sc);
 1438                         return;
 1439                 }
 1440 
 1441                 i = sc->rbuffs[sc->rbhead]->ie_rbd_actual & IE_RBD_LAST;
 1442 
 1443                 sc->rbuffs[sc->rbhead]->ie_rbd_length |= IE_RBD_LAST;
 1444                 sc->rbuffs[sc->rbhead]->ie_rbd_actual = 0;
 1445                 sc->rbhead = (sc->rbhead + 1) % NRXBUF;
 1446                 sc->rbuffs[sc->rbtail]->ie_rbd_length &= ~IE_RBD_LAST;
 1447                 sc->rbtail = (sc->rbtail + 1) % NRXBUF;
 1448         } while (!i);
 1449 }
 1450 
 1451 /*
 1452  * Start transmission on an interface.
 1453  */
 1454 void
 1455 iestart(ifp)
 1456         struct ifnet *ifp;
 1457 {
 1458         struct ie_softc *sc = ifp->if_softc;
 1459         struct mbuf *m0, *m;
 1460         u_char *buffer;
 1461         u_short len;
 1462 
 1463         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
 1464                 return;
 1465 
 1466         for (;;) {
 1467                 if (sc->xmit_busy == NTXBUF) {
 1468                         ifp->if_flags |= IFF_OACTIVE;
 1469                         break;
 1470                 }
 1471 
 1472                 IFQ_DEQUEUE(&ifp->if_snd, m0);
 1473                 if (m0 == 0)
 1474                         break;
 1475 
 1476                 /* We need to use m->m_pkthdr.len, so require the header */
 1477                 if ((m0->m_flags & M_PKTHDR) == 0)
 1478                         panic("iestart: no header mbuf");
 1479 
 1480 #if NBPFILTER > 0
 1481                 /* Tap off here if there is a BPF listener. */
 1482                 if (ifp->if_bpf)
 1483                         bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
 1484 #endif
 1485 
 1486 #ifdef IEDEBUG
 1487                 if (sc->sc_debug & IED_ENQ)
 1488                         printf("%s: fill buffer %d\n", sc->sc_dev.dv_xname,
 1489                             sc->xchead);
 1490 #endif
 1491 
 1492                 len = 0;
 1493                 buffer = sc->xmit_cbuffs[sc->xchead];
 1494 
 1495                 for (m = m0; m != NULL && (len + m->m_len) < IE_TBUF_SIZE;
 1496                     m = m->m_next) {
 1497                         bcopy(mtod(m, caddr_t), buffer, m->m_len);
 1498                         buffer += m->m_len;
 1499                         len += m->m_len;
 1500                 }
 1501                 if (m != NULL)
 1502                         printf("%s: tbuf overflow\n", sc->sc_dev.dv_xname);
 1503 
 1504                 m_freem(m0);
 1505 
 1506                 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
 1507                         bzero(buffer, ETHER_MIN_LEN - ETHER_CRC_LEN - len);
 1508                         len = ETHER_MIN_LEN - ETHER_CRC_LEN;
 1509                         buffer += ETHER_MIN_LEN - ETHER_CRC_LEN;
 1510                 }
 1511 
 1512                 sc->xmit_buffs[sc->xchead]->ie_xmit_flags = len;
 1513 
 1514                 /* Start the first packet transmitting. */
 1515                 if (sc->xmit_busy == 0)
 1516                         iexmit(sc);
 1517 
 1518                 sc->xchead = (sc->xchead + 1) % NTXBUF;
 1519                 sc->xmit_busy++;
 1520         }
 1521 }
 1522 
 1523 /*
 1524  * Check to see if there's an 82586 out there.
 1525  */
 1526 int
 1527 check_ie_present(sc, where, size)
 1528         struct ie_softc *sc;
 1529         caddr_t where;
 1530         u_int size;
 1531 {
 1532         volatile struct ie_sys_conf_ptr *scp;
 1533         volatile struct ie_int_sys_conf_ptr *iscp;
 1534         volatile struct ie_sys_ctl_block *scb;
 1535         u_long realbase;
 1536         int s;
 1537 
 1538         s = splnet();
 1539 
 1540         realbase = (u_long)where + size - (1 << 24);
 1541 
 1542         scp = (volatile struct ie_sys_conf_ptr *)(realbase + IE_SCP_ADDR);
 1543         bzero((char *)scp, sizeof *scp);
 1544 
 1545         /*
 1546          * First we put the ISCP at the bottom of memory; this tests to make
 1547          * sure that our idea of the size of memory is the same as the
 1548          * controller's.  This is NOT where the ISCP will be in normal
 1549          * operation.
 1550          */
 1551         iscp = (volatile struct ie_int_sys_conf_ptr *)where;
 1552         bzero((char *)iscp, sizeof *iscp);
 1553 
 1554         scb = (volatile struct ie_sys_ctl_block *)where;
 1555         bzero((char *)scb, sizeof *scb);
 1556 
 1557         scp->ie_bus_use = 0;            /* 16-bit */
 1558         scp->ie_iscp_ptr = (caddr_t)((volatile caddr_t)iscp -
 1559             (volatile caddr_t)realbase);
 1560 
 1561         iscp->ie_busy = 1;
 1562         iscp->ie_scb_offset = MK_16(realbase, scb) + 256;
 1563 
 1564         (sc->reset_586)(sc);
 1565         (sc->chan_attn)(sc);
 1566 
 1567         delay(100);                     /* wait a while... */
 1568 
 1569         if (iscp->ie_busy) {
 1570                 splx(s);
 1571                 return 0;
 1572         }
 1573 
 1574         /*
 1575          * Now relocate the ISCP to its real home, and reset the controller
 1576          * again.
 1577          */
 1578         iscp = (void *)ALIGN(realbase + IE_SCP_ADDR - sizeof(*iscp));
 1579         bzero((char *)iscp, sizeof *iscp);
 1580 
 1581         scp->ie_iscp_ptr = (caddr_t)((caddr_t)iscp - (caddr_t)realbase);
 1582 
 1583         iscp->ie_busy = 1;
 1584         iscp->ie_scb_offset = MK_16(realbase, scb);
 1585 
 1586         (sc->reset_586)(sc);
 1587         (sc->chan_attn)(sc);
 1588 
 1589         delay(100);
 1590 
 1591         if (iscp->ie_busy) {
 1592                 splx(s);
 1593                 return 0;
 1594         }
 1595 
 1596         sc->sc_msize = size;
 1597         sc->sc_maddr = (caddr_t)realbase;
 1598 
 1599         sc->iscp = iscp;
 1600         sc->scb = scb;
 1601 
 1602         /*
 1603          * Acknowledge any interrupts we may have caused...
 1604          */
 1605         ie_ack(sc, IE_ST_WHENCE);
 1606         splx(s);
 1607 
 1608         return 1;
 1609 }
 1610 
 1611 /*
 1612  * Divine the memory size of ie board UNIT.
 1613  * Better hope there's nothing important hiding just below the ie card...
 1614  */
 1615 void
 1616 ie_find_mem_size(sc)
 1617         struct ie_softc *sc;
 1618 {
 1619         u_int size;
 1620 
 1621         sc->sc_msize = 0;
 1622 
 1623         for (size = 65536; size >= 16384; size -= 16384)
 1624                 if (check_ie_present(sc, sc->sc_maddr, size))
 1625                         return;
 1626 
 1627         return;
 1628 }
 1629 
 1630 void
 1631 el_reset_586(sc)
 1632         struct ie_softc *sc;
 1633 {
 1634 
 1635         outb(PORT + IE507_CTRL, EL_CTRL_RESET);
 1636         delay(100);
 1637         outb(PORT + IE507_CTRL, EL_CTRL_NORMAL);
 1638         delay(100);
 1639 }
 1640 
 1641 void
 1642 sl_reset_586(sc)
 1643         struct ie_softc *sc;
 1644 {
 1645 
 1646         outb(PORT + IEATT_RESET, 0);
 1647 }
 1648 
 1649 void
 1650 ee16_reset_586(sc)
 1651         struct ie_softc *sc;
 1652 {
 1653 
 1654         outb(PORT + IEE16_ECTRL, IEE16_RESET_586);
 1655         delay(100);
 1656         outb(PORT + IEE16_ECTRL, 0);
 1657         delay(100);
 1658 }
 1659 
 1660 void
 1661 el_chan_attn(sc)
 1662         struct ie_softc *sc;
 1663 {
 1664 
 1665         outb(PORT + IE507_ATTN, 1);
 1666 }
 1667 
 1668 void
 1669 sl_chan_attn(sc)
 1670         struct ie_softc *sc;
 1671 {
 1672 
 1673         outb(PORT + IEATT_ATTN, 0);
 1674 }
 1675 
 1676 void
 1677 ee16_chan_attn(sc)
 1678         struct ie_softc *sc;
 1679 {
 1680         outb(PORT + IEE16_ATTN, 0);
 1681 }
 1682 
 1683 u_short
 1684 ee16_read_eeprom(sc, location)
 1685         struct ie_softc *sc;
 1686         int location;
 1687 {
 1688         int ectrl, edata;
 1689 
 1690         ectrl = inb(PORT + IEE16_ECTRL);
 1691         ectrl &= IEE16_ECTRL_MASK;
 1692         ectrl |= IEE16_ECTRL_EECS;
 1693         outb(PORT + IEE16_ECTRL, ectrl);
 1694 
 1695         ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1);
 1696         ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE);
 1697         edata = ee16_eeprom_inbits(sc);
 1698         ectrl = inb(PORT + IEE16_ECTRL);
 1699         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS);
 1700         outb(PORT + IEE16_ECTRL, ectrl);
 1701         ee16_eeprom_clock(sc, 1);
 1702         ee16_eeprom_clock(sc, 0);
 1703         return edata;
 1704 }
 1705 
 1706 void
 1707 ee16_eeprom_outbits(sc, edata, count)
 1708         struct ie_softc *sc;
 1709         int edata, count;
 1710 {
 1711         int ectrl, i;
 1712 
 1713         ectrl = inb(PORT + IEE16_ECTRL);
 1714         ectrl &= ~IEE16_RESET_ASIC;
 1715         for (i = count - 1; i >= 0; i--) {
 1716                 ectrl &= ~IEE16_ECTRL_EEDI;
 1717                 if (edata & (1 << i)) {
 1718                         ectrl |= IEE16_ECTRL_EEDI;
 1719                 }
 1720                 outb(PORT + IEE16_ECTRL, ectrl);
 1721                 delay(1);       /* eeprom data must be setup for 0.4 uSec */
 1722                 ee16_eeprom_clock(sc, 1);
 1723                 ee16_eeprom_clock(sc, 0);
 1724         }
 1725         ectrl &= ~IEE16_ECTRL_EEDI;
 1726         outb(PORT + IEE16_ECTRL, ectrl);
 1727         delay(1);               /* eeprom data must be held for 0.4 uSec */
 1728 }
 1729 
 1730 int
 1731 ee16_eeprom_inbits(sc)
 1732         struct ie_softc *sc;
 1733 {
 1734         int ectrl, edata, i;
 1735 
 1736         ectrl = inb(PORT + IEE16_ECTRL);
 1737         ectrl &= ~IEE16_RESET_ASIC;
 1738         for (edata = 0, i = 0; i < 16; i++) {
 1739                 edata = edata << 1;
 1740                 ee16_eeprom_clock(sc, 1);
 1741                 ectrl = inb(PORT + IEE16_ECTRL);
 1742                 if (ectrl & IEE16_ECTRL_EEDO) {
 1743                         edata |= 1;
 1744                 }
 1745                 ee16_eeprom_clock(sc, 0);
 1746         }
 1747         return (edata);
 1748 }
 1749 
 1750 void
 1751 ee16_eeprom_clock(sc, state)
 1752         struct ie_softc *sc;
 1753         int state;
 1754 {
 1755         int ectrl;
 1756 
 1757         ectrl = inb(PORT + IEE16_ECTRL);
 1758         ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK);
 1759         if (state) {
 1760                 ectrl |= IEE16_ECTRL_EESK;
 1761         }
 1762         outb(PORT + IEE16_ECTRL, ectrl);
 1763         delay(9);               /* EESK must be stable for 8.38 uSec */
 1764 }
 1765 
 1766 static inline void
 1767 ee16_interrupt_enable(sc)
 1768         struct ie_softc *sc;
 1769 {
 1770         delay(100);
 1771         outb(PORT + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE);
 1772         delay(100);
 1773 }
 1774 void
 1775 slel_get_address(sc)
 1776         struct ie_softc *sc;
 1777 {
 1778         u_char *addr = sc->sc_arpcom.ac_enaddr;
 1779         int i;
 1780 
 1781         for (i = 0; i < ETHER_ADDR_LEN; i++)
 1782                 addr[i] = inb(PORT + i);
 1783 }
 1784 
 1785 void
 1786 iereset(sc)
 1787         struct ie_softc *sc;
 1788 {
 1789         int s = splnet();
 1790 
 1791         iestop(sc);
 1792 
 1793         /*
 1794          * Stop i82586 dead in its tracks.
 1795          */
 1796         if (command_and_wait(sc, IE_RU_ABORT | IE_CU_ABORT, 0, 0))
 1797                 printf("%s: abort commands timed out\n", sc->sc_dev.dv_xname);
 1798 
 1799         if (command_and_wait(sc, IE_RU_DISABLE | IE_CU_STOP, 0, 0))
 1800                 printf("%s: disable commands timed out\n", sc->sc_dev.dv_xname);
 1801 
 1802         ieinit(sc);
 1803 
 1804         splx(s);
 1805 }
 1806 
 1807 /*
 1808  * Send a command to the controller and wait for it to either complete or be
 1809  * accepted, depending on the command.  If the command pointer is null, then
 1810  * pretend that the command is not an action command.  If the command pointer
 1811  * is not null, and the command is an action command, wait for
 1812  * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK
 1813  * to become true.
 1814  */
 1815 static int
 1816 command_and_wait(sc, cmd, pcmd, mask)
 1817         struct ie_softc *sc;
 1818         int cmd;
 1819         volatile void *pcmd;
 1820         int mask;
 1821 {
 1822         volatile struct ie_cmd_common *cc = pcmd;
 1823         volatile struct ie_sys_ctl_block *scb = sc->scb;
 1824         int i;
 1825 
 1826         scb->ie_command = (u_short)cmd;
 1827 
 1828         if (IE_ACTION_COMMAND(cmd) && pcmd) {
 1829                 (sc->chan_attn)(sc);
 1830 
 1831                 /*
 1832                  * According to the packet driver, the minimum timeout should
 1833                  * be .369 seconds, which we round up to .4.
 1834                  *
 1835                  * Now spin-lock waiting for status.  This is not a very nice
 1836                  * thing to do, but I haven't figured out how, or indeed if, we
 1837                  * can put the process waiting for action to sleep.  (We may
 1838                  * be getting called through some other timeout running in the
 1839                  * kernel.)
 1840                  */
 1841                 for (i = 36900; i--; DELAY(10))
 1842                         if ((cc->ie_cmd_status & mask))
 1843                                 break;
 1844 
 1845                 return i < 0;
 1846         } else {
 1847                 /*
 1848                  * Otherwise, just wait for the command to be accepted.
 1849                  */
 1850                 (sc->chan_attn)(sc);
 1851 
 1852                 while (scb->ie_command)
 1853                         ;                               /* spin lock */
 1854 
 1855                 return 0;
 1856         }
 1857 }
 1858 
 1859 /*
 1860  * Run the time-domain reflectometer.
 1861  */
 1862 static void
 1863 run_tdr(sc, cmd)
 1864         struct ie_softc *sc;
 1865         struct ie_tdr_cmd *cmd;
 1866 {
 1867         int result;
 1868 
 1869         cmd->com.ie_cmd_status = 0;
 1870         cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST;
 1871         cmd->com.ie_cmd_link = 0xffff;
 1872 
 1873         sc->scb->ie_command_list = MK_16(MEM, cmd);
 1874         cmd->ie_tdr_time = 0;
 1875 
 1876         if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
 1877             !(cmd->com.ie_cmd_status & IE_STAT_OK))
 1878                 result = 0x10000;
 1879         else
 1880                 result = cmd->ie_tdr_time;
 1881 
 1882         ie_ack(sc, IE_ST_WHENCE);
 1883 
 1884         if (result & IE_TDR_SUCCESS)
 1885                 return;
 1886 
 1887         if (result & 0x10000)
 1888                 printf("%s: TDR command failed\n", sc->sc_dev.dv_xname);
 1889         else if (result & IE_TDR_XCVR)
 1890                 printf("%s: transceiver problem\n", sc->sc_dev.dv_xname);
 1891         else if (result & IE_TDR_OPEN)
 1892                 printf("%s: TDR detected an open %d clocks away\n",
 1893                     sc->sc_dev.dv_xname, result & IE_TDR_TIME);
 1894         else if (result & IE_TDR_SHORT)
 1895                 printf("%s: TDR detected a short %d clocks away\n",
 1896                     sc->sc_dev.dv_xname, result & IE_TDR_TIME);
 1897         else
 1898                 printf("%s: TDR returned unknown status %x\n",
 1899                     sc->sc_dev.dv_xname, result);
 1900 }
 1901 
 1902 #define _ALLOC(p, n)    (bzero(p, n), p += n, p - n)
 1903 #define ALLOC(p, n)     _ALLOC(p, ALIGN(n))
 1904 
 1905 /*
 1906  * Here is a helper routine for ieinit().  This sets up the buffers.
 1907  */
 1908 void
 1909 iememinit(ptr, sc)
 1910         void *ptr;
 1911         struct ie_softc *sc;
 1912 {
 1913         int i;
 1914 
 1915         /* First lay them out. */
 1916         for (i = 0; i < NFRAMES; i++)
 1917                 sc->rframes[i] = ALLOC(ptr, sizeof(*sc->rframes[i]));
 1918 
 1919         /* Now link them together. */
 1920         for (i = 0; i < NFRAMES; i++)
 1921                 sc->rframes[i]->ie_fd_next =
 1922                     MK_16(MEM, sc->rframes[(i + 1) % NFRAMES]);
 1923 
 1924         /* Finally, set the EOL bit on the last one. */
 1925         sc->rframes[NFRAMES - 1]->ie_fd_last |= IE_FD_LAST;
 1926 
 1927         /*
 1928          * Now lay out some buffers for the incoming frames.  Note that we set
 1929          * aside a bit of slop in each buffer, to make sure that we have enough
 1930          * space to hold a single frame in every buffer.
 1931          */
 1932         for (i = 0; i < NRXBUF; i++) {
 1933                 sc->rbuffs[i] = ALLOC(ptr, sizeof(*sc->rbuffs[i]));
 1934                 sc->rbuffs[i]->ie_rbd_length = IE_RBUF_SIZE;
 1935                 sc->rbuffs[i]->ie_rbd_buffer = MK_24(MEM, ptr);
 1936                 sc->cbuffs[i] = ALLOC(ptr, IE_RBUF_SIZE);
 1937         }
 1938 
 1939         /* Now link them together. */
 1940         for (i = 0; i < NRXBUF; i++)
 1941                 sc->rbuffs[i]->ie_rbd_next =
 1942                     MK_16(MEM, sc->rbuffs[(i + 1) % NRXBUF]);
 1943 
 1944         /* Tag EOF on the last one. */
 1945         sc->rbuffs[NRXBUF - 1]->ie_rbd_length |= IE_RBD_LAST;
 1946 
 1947         /*
 1948          * We use the head and tail pointers on receive to keep track of the
 1949          * order in which RFDs and RBDs are used.
 1950          */
 1951         sc->rfhead = 0;
 1952         sc->rftail = NFRAMES - 1;
 1953         sc->rbhead = 0;
 1954         sc->rbtail = NRXBUF - 1;
 1955 
 1956         sc->scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
 1957         sc->rframes[0]->ie_fd_buf_desc = MK_16(MEM, sc->rbuffs[0]);
 1958 
 1959         /*
 1960          * Finally, the transmit command and buffer are the last little bit of
 1961          * work.
 1962          */
 1963         for (i = 0; i < NTXBUF; i++) {
 1964                 sc->xmit_cmds[i] = ALLOC(ptr, sizeof(*sc->xmit_cmds[i]));
 1965                 sc->xmit_buffs[i] = ALLOC(ptr, sizeof(*sc->xmit_buffs[i]));
 1966         }
 1967 
 1968         for (i = 0; i < NTXBUF; i++)
 1969                 sc->xmit_cbuffs[i] = ALLOC(ptr, IE_TBUF_SIZE);
 1970 
 1971         /* Pointers to last packet sent and next available transmit buffer. */
 1972         sc->xchead = sc->xctail = 0;
 1973 
 1974         /* Clear transmit-busy flag and set number of free transmit buffers. */
 1975         sc->xmit_busy = 0;
 1976 }
 1977 
 1978 /*
 1979  * Run the multicast setup command.
 1980  * Called at splnet().
 1981  */
 1982 static int
 1983 mc_setup(sc, ptr)
 1984         struct ie_softc *sc;
 1985         void *ptr;
 1986 {
 1987         volatile struct ie_mcast_cmd *cmd = ptr;
 1988 
 1989         cmd->com.ie_cmd_status = 0;
 1990         cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST;
 1991         cmd->com.ie_cmd_link = 0xffff;
 1992 
 1993         bcopy((caddr_t)sc->mcast_addrs, (caddr_t)cmd->ie_mcast_addrs,
 1994             sc->mcast_count * sizeof *sc->mcast_addrs);
 1995 
 1996         cmd->ie_mcast_bytes = sc->mcast_count * ETHER_ADDR_LEN; /* grrr... */
 1997 
 1998         sc->scb->ie_command_list = MK_16(MEM, cmd);
 1999         if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
 2000             !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
 2001                 printf("%s: multicast address setup command failed\n",
 2002                     sc->sc_dev.dv_xname);
 2003                 return 0;
 2004         }
 2005         return 1;
 2006 }
 2007 
 2008 /*
 2009  * This routine takes the environment generated by check_ie_present() and adds
 2010  * to it all the other structures we need to operate the adapter.  This
 2011  * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
 2012  * the receiver unit, and clearing interrupts.
 2013  *
 2014  * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
 2015  */
 2016 int
 2017 ieinit(sc)
 2018         struct ie_softc *sc;
 2019 {
 2020         volatile struct ie_sys_ctl_block *scb = sc->scb;
 2021         void *ptr;
 2022 
 2023         ptr = (void *)ALIGN(scb + 1);
 2024 
 2025         /*
 2026          * Send the configure command first.
 2027          */
 2028         {
 2029                 volatile struct ie_config_cmd *cmd = ptr;
 2030 
 2031                 scb->ie_command_list = MK_16(MEM, cmd);
 2032                 cmd->com.ie_cmd_status = 0;
 2033                 cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST;
 2034                 cmd->com.ie_cmd_link = 0xffff;
 2035 
 2036                 ie_setup_config(cmd, sc->promisc != 0,
 2037                     sc->hard_type == IE_STARLAN10);
 2038 
 2039                 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
 2040                     !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
 2041                         printf("%s: configure command failed\n",
 2042                             sc->sc_dev.dv_xname);
 2043                         return 0;
 2044                 }
 2045         }
 2046 
 2047         /*
 2048          * Now send the Individual Address Setup command.
 2049          */
 2050         {
 2051                 volatile struct ie_iasetup_cmd *cmd = ptr;
 2052 
 2053                 scb->ie_command_list = MK_16(MEM, cmd);
 2054                 cmd->com.ie_cmd_status = 0;
 2055                 cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST;
 2056                 cmd->com.ie_cmd_link = 0xffff;
 2057 
 2058                 bcopy(sc->sc_arpcom.ac_enaddr, (caddr_t)&cmd->ie_address,
 2059                     sizeof cmd->ie_address);
 2060 
 2061                 if (command_and_wait(sc, IE_CU_START, cmd, IE_STAT_COMPL) ||
 2062                     !(cmd->com.ie_cmd_status & IE_STAT_OK)) {
 2063                         printf("%s: individual address setup command failed\n",
 2064                             sc->sc_dev.dv_xname);
 2065                         return 0;
 2066                 }
 2067         }
 2068 
 2069         /*
 2070          * Now run the time-domain reflectometer.
 2071          */
 2072         run_tdr(sc, ptr);
 2073 
 2074         /*
 2075          * Acknowledge any interrupts we have generated thus far.
 2076          */
 2077         ie_ack(sc, IE_ST_WHENCE);
 2078 
 2079         /*
 2080          * Set up the RFA.
 2081          */
 2082         iememinit(ptr, sc);
 2083 
 2084         sc->sc_arpcom.ac_if.if_flags |= IFF_RUNNING;
 2085         sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
 2086 
 2087         sc->scb->ie_recv_list = MK_16(MEM, sc->rframes[0]);
 2088         command_and_wait(sc, IE_RU_START, 0, 0);
 2089 
 2090         ie_ack(sc, IE_ST_WHENCE);
 2091 
 2092         /* take the ee16 out of loopback */
 2093         {
 2094         u_char  bart_config;
 2095 
 2096         if(sc->hard_type == IE_EE16) {
 2097                 bart_config = inb(PORT + IEE16_CONFIG);
 2098                 bart_config &= ~IEE16_BART_LOOPBACK;
 2099                 bart_config |= IEE16_BART_MCS16_TEST; /* inb doesn't get bit! */
 2100                 outb(PORT + IEE16_CONFIG, bart_config);
 2101                 ee16_interrupt_enable(sc); 
 2102                 ee16_chan_attn(sc);
 2103                 }
 2104         }
 2105         return 0;
 2106 }
 2107 
 2108 void
 2109 iestop(sc)
 2110         struct ie_softc *sc;
 2111 {
 2112 
 2113         command_and_wait(sc, IE_RU_DISABLE, 0, 0);
 2114 }
 2115 
 2116 int
 2117 ieioctl(ifp, cmd, data)
 2118         register struct ifnet *ifp;
 2119         u_long cmd;
 2120         caddr_t data;
 2121 {
 2122         struct ie_softc *sc = ifp->if_softc;
 2123         struct ifaddr *ifa = (struct ifaddr *)data;
 2124         struct ifreq *ifr = (struct ifreq *)data;
 2125         int s, error = 0;
 2126 
 2127         s = splnet();
 2128 
 2129         if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
 2130                 splx(s);
 2131                 return error;
 2132         }
 2133 
 2134         switch (cmd) {
 2135 
 2136         case SIOCSIFADDR:
 2137                 ifp->if_flags |= IFF_UP;
 2138 
 2139                 switch (ifa->ifa_addr->sa_family) {
 2140 #ifdef INET
 2141                 case AF_INET:
 2142                         ieinit(sc);
 2143                         arp_ifinit(&sc->sc_arpcom, ifa);
 2144                         break;
 2145 #endif
 2146                 default:
 2147                         ieinit(sc);
 2148                         break;
 2149                 }
 2150                 break;
 2151 
 2152         case SIOCSIFFLAGS:
 2153                 sc->promisc = ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI);
 2154                 if ((ifp->if_flags & IFF_UP) == 0 &&
 2155                     (ifp->if_flags & IFF_RUNNING) != 0) {
 2156                         /*
 2157                          * If interface is marked down and it is running, then
 2158                          * stop it.
 2159                          */
 2160                         iestop(sc);
 2161                         ifp->if_flags &= ~IFF_RUNNING;
 2162                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
 2163                            (ifp->if_flags & IFF_RUNNING) == 0) {
 2164                         /*
 2165                          * If interface is marked up and it is stopped, then
 2166                          * start it.
 2167                          */
 2168                         ieinit(sc);
 2169                 } else {
 2170                         /*
 2171                          * Reset the interface to pick up changes in any other
 2172                          * flags that affect hardware registers.
 2173                          */
 2174                         iestop(sc);
 2175                         ieinit(sc);
 2176                 }
 2177 #ifdef IEDEBUG
 2178                 if (ifp->if_flags & IFF_DEBUG)
 2179                         sc->sc_debug = IED_ALL;
 2180                 else
 2181                         sc->sc_debug = 0;
 2182 #endif
 2183                 break;
 2184 
 2185         case SIOCADDMULTI:
 2186         case SIOCDELMULTI:
 2187                 error = (cmd == SIOCADDMULTI) ?
 2188                     ether_addmulti(ifr, &sc->sc_arpcom):
 2189                     ether_delmulti(ifr, &sc->sc_arpcom);
 2190 
 2191                 if (error == ENETRESET) {
 2192                         /*
 2193                          * Multicast list has changed; set the hardware filter
 2194                          * accordingly.
 2195                          */
 2196                         if (ifp->if_flags & IFF_RUNNING)
 2197                                 mc_reset(sc);
 2198                         error = 0;
 2199                 }
 2200                 break;
 2201 
 2202         default:
 2203                 error = EINVAL;
 2204         }
 2205         splx(s);
 2206         return error;
 2207 }
 2208 
 2209 static void
 2210 mc_reset(sc)
 2211         struct ie_softc *sc;
 2212 {
 2213         struct ether_multi *enm;
 2214         struct ether_multistep step;
 2215 
 2216         /*
 2217          * Step through the list of addresses.
 2218          */
 2219         sc->mcast_count = 0;
 2220         ETHER_FIRST_MULTI(step, &sc->sc_arpcom, enm);
 2221         while (enm) {
 2222                 if (sc->mcast_count >= MAXMCAST ||
 2223                     bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
 2224                         sc->sc_arpcom.ac_if.if_flags |= IFF_ALLMULTI;
 2225                         ieioctl(&sc->sc_arpcom.ac_if, SIOCSIFFLAGS, (void *)0);
 2226                         goto setflag;
 2227                 }
 2228 
 2229                 bcopy(enm->enm_addrlo, &sc->mcast_addrs[sc->mcast_count], 6);
 2230                 sc->mcast_count++;
 2231                 ETHER_NEXT_MULTI(step, enm);
 2232         }
 2233 setflag:
 2234         sc->want_mcsetup = 1;
 2235 }
 2236 
 2237 #ifdef IEDEBUG
 2238 void
 2239 print_rbd(rbd)
 2240         volatile struct ie_recv_buf_desc *rbd;
 2241 {
 2242 
 2243         printf("RBD at %08lx:\nactual %04x, next %04x, buffer %08x\n"
 2244             "length %04x, mbz %04x\n", (u_long)rbd, rbd->ie_rbd_actual,
 2245             rbd->ie_rbd_next, rbd->ie_rbd_buffer, rbd->ie_rbd_length,
 2246             rbd->mbz);
 2247 }
 2248 #endif
 2249 

/* [<][>][^][v][top][bottom][index][help] */