The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isa/if_ie.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 28d0661eafc2322549c6da770347db0b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.