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/i386/isa/if_le.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 /*-
    2  * Copyright (c) 1994 Matt Thomas (thomas@lkg.dec.com)
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. The name of the author may not be used to endorse or promote products
   11  *    derived from this software withough specific prior written permission
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  *
   24  * $FreeBSD: src/sys/i386/isa/if_le.c,v 1.34.2.1 1999/09/05 08:12:56 peter Exp $
   25  */
   26 
   27 /*
   28  * DEC EtherWORKS 2 Ethernet Controllers
   29  * DEC EtherWORKS 3 Ethernet Controllers
   30  *
   31  * Written by Matt Thomas
   32  * BPF support code stolen directly from if_ec.c
   33  *
   34  *   This driver supports the DEPCA, DE100, DE101, DE200, DE201,
   35  *   DE2002, DE203, DE204, DE205, and DE422 cards.
   36  */
   37 
   38 #include "le.h"
   39 #if NLE > 0
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h>
   43 #include <sys/conf.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/protosw.h>
   46 #include <sys/socket.h>
   47 #include <sys/ioccom.h>
   48 #include <sys/sockio.h>
   49 #include <sys/errno.h>
   50 #include <sys/malloc.h>
   51 #include <sys/syslog.h>
   52 
   53 #include <net/if.h>
   54 #include <net/if_types.h>
   55 #include <net/if_dl.h>
   56 #include <net/route.h>
   57 
   58 #include "bpfilter.h"
   59 
   60 #ifdef INET
   61 #include <netinet/in.h>
   62 #include <netinet/in_systm.h>
   63 #include <netinet/in_var.h>
   64 #include <netinet/ip.h>
   65 #include <netinet/if_ether.h>
   66 #endif
   67 
   68 #ifdef IPX
   69 #include <netipx/ipx.h>
   70 #include <netipx/ipx_if.h>
   71 #endif
   72 
   73 #ifdef NS
   74 #include <netns/ns.h>
   75 #include <netns/ns_if.h>
   76 #endif
   77 
   78 #include <machine/clock.h>
   79 
   80 #include <i386/isa/isa_device.h>
   81 #include <i386/isa/icu.h>
   82 
   83 #include <vm/vm.h>
   84 #include <vm/vm_param.h>
   85 #include <vm/pmap.h>
   86 
   87 #if NBPFILTER > 0
   88 #include <net/bpf.h>
   89 #include <net/bpfdesc.h>
   90 #endif
   91 
   92 /* Forward declarations */
   93 typedef struct le_softc le_softc_t;
   94 typedef struct le_board le_board_t;
   95 
   96 typedef u_short le_mcbits_t;
   97 #define LE_MC_NBPW_LOG2         4
   98 #define LE_MC_NBPW              (1 << LE_MC_NBPW_LOG2)
   99 #if __FreeBSD__ > 1
  100 #define IF_RESET_ARGS   int unit
  101 #define LE_RESET(ifp)   (((sc)->if_reset)((sc)->le_if.if_unit))
  102 #else
  103 #define IF_RESET_ARGS   int unit, int dummy
  104 #define LE_RESET(ifp)   (((sc)->if_reset)((sc)->le_if.if_unit, 0))
  105 #endif
  106 
  107 #if !defined(LE_NOLEMAC)
  108 /*
  109  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  110  *
  111  * Start of DEC EtherWORKS III (LEMAC) dependent structures
  112  *
  113  */
  114 #include "i386/isa/ic/lemac.h"          /* Include LEMAC definitions */
  115 
  116 static int lemac_probe(le_softc_t *sc, const le_board_t *bd, int *msize);
  117 
  118 struct le_lemac_info {
  119     u_int lemac__lastpage;              /* last 2K page */
  120     u_int lemac__memmode;               /* Are we in 2K, 32K, or 64K mode */
  121     u_int lemac__membase;               /* Physical address of start of RAM */
  122     u_int lemac__txctl;                 /* Transmit Control Byte */
  123     u_int lemac__txmax;                 /* Maximum # of outstanding transmits */
  124     le_mcbits_t lemac__mctbl[LEMAC_MCTBL_SIZE/sizeof(le_mcbits_t)];
  125                                         /* local copy of multicast table */
  126     u_char lemac__eeprom[LEMAC_EEP_SIZE]; /* local copy eeprom */
  127     char lemac__prodname[LEMAC_EEP_PRDNMSZ+1]; /* prodname name */
  128 #define lemac_lastpage          le_un.un_lemac.lemac__lastpage
  129 #define lemac_memmode           le_un.un_lemac.lemac__memmode
  130 #define lemac_membase           le_un.un_lemac.lemac__membase
  131 #define lemac_txctl             le_un.un_lemac.lemac__txctl
  132 #define lemac_txmax             le_un.un_lemac.lemac__txmax
  133 #define lemac_mctbl             le_un.un_lemac.lemac__mctbl
  134 #define lemac_eeprom            le_un.un_lemac.lemac__eeprom
  135 #define lemac_prodname          le_un.un_lemac.lemac__prodname
  136 };
  137 #endif /* !defined(LE_NOLEMAC) */
  138 
  139 #if !defined(LE_NOLANCE)
  140 /*
  141  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  142  *
  143  * Start of DEC EtherWORKS II (LANCE) dependent structures
  144  *
  145  */
  146 
  147 #include "i386/isa/ic/am7990.h"
  148 
  149 #ifndef LN_DOSTATS
  150 #define LN_DOSTATS      1
  151 #endif
  152 
  153 static int depca_probe(le_softc_t *sc, const le_board_t *bd, int *msize);
  154 
  155 typedef struct lance_descinfo lance_descinfo_t;
  156 typedef struct lance_ring lance_ring_t;
  157 
  158 typedef unsigned lance_addr_t;
  159 
  160 struct lance_descinfo {
  161     caddr_t di_addr;                    /* address of descriptor */
  162     lance_addr_t di_bufaddr;            /* LANCE address of buffer owned by descriptor */
  163     unsigned di_buflen;                 /* size of buffer owned by descriptor */
  164     struct mbuf *di_mbuf;               /* mbuf being transmitted/received */
  165 };
  166 
  167 struct lance_ring {
  168     lance_descinfo_t *ri_first;         /* Pointer to first descriptor in ring */
  169     lance_descinfo_t *ri_last;          /* Pointer to last + 1 descriptor in ring */
  170     lance_descinfo_t *ri_nextin;        /* Pointer to next one to be given to HOST */
  171     lance_descinfo_t *ri_nextout;       /* Pointer to next one to be given to LANCE */
  172     unsigned ri_max;                    /* Size of Ring - 1 */
  173     unsigned ri_free;                   /* Number of free rings entires (owned by HOST) */
  174     lance_addr_t ri_heap;                       /* Start of RAM for this ring */
  175     lance_addr_t ri_heapend;            /* End + 1 of RAM for this ring */
  176     lance_addr_t ri_outptr;                     /* Pointer to first output byte */
  177     unsigned ri_outsize;                /* Space remaining for output */
  178 };
  179 
  180 struct le_lance_info {
  181     unsigned lance__csr1;               /* LANCE Address of init block (low 16) */
  182     unsigned lance__csr2;               /* LANCE Address of init block (high 8) */
  183     unsigned lance__csr3;               /* Copy of CSR3 */
  184     unsigned lance__rap;                /* IO Port Offset of RAP */
  185     unsigned lance__rdp;                /* IO Port Offset of RDP */
  186     unsigned lance__ramoffset;          /* Offset to valid LANCE RAM */
  187     unsigned lance__ramsize;            /* Amount of RAM shared by LANCE */
  188     unsigned lance__rxbufsize;          /* Size of a receive buffer */
  189     ln_initb_t lance__initb;            /* local copy of LANCE initblock */
  190     ln_initb_t *lance__raminitb;        /* copy to board's LANCE initblock (debugging) */
  191     ln_desc_t *lance__ramdesc;          /* copy to board's LANCE descriptors (debugging) */
  192     lance_ring_t lance__rxinfo;         /* Receive ring information */
  193     lance_ring_t lance__txinfo;         /* Transmit ring information */
  194 #define lance_csr1              le_un.un_lance.lance__csr1
  195 #define lance_csr2              le_un.un_lance.lance__csr2
  196 #define lance_csr3              le_un.un_lance.lance__csr3
  197 #define lance_rap               le_un.un_lance.lance__rap
  198 #define lance_rdp               le_un.un_lance.lance__rdp
  199 #define lance_ramoffset         le_un.un_lance.lance__ramoffset
  200 #define lance_ramsize           le_un.un_lance.lance__ramsize
  201 #define lance_rxbufsize         le_un.un_lance.lance__rxbufsize
  202 #define lance_initb             le_un.un_lance.lance__initb
  203 #define lance_raminitb          le_un.un_lance.lance__raminitb
  204 #define lance_ramdesc           le_un.un_lance.lance__ramdesc
  205 #define lance_rxinfo            le_un.un_lance.lance__rxinfo
  206 #define lance_txinfo            le_un.un_lance.lance__txinfo
  207 };
  208 #endif /* !defined(LE_NOLANCE) */
  209 
  210 /*
  211  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  212  *
  213  * Start of Common Code
  214  *
  215  */
  216 
  217 static void (*le_intrvec[NLE])(le_softc_t *sc);
  218 
  219 /*
  220  * Ethernet status, per interface.
  221  */
  222 struct le_softc {
  223     struct arpcom le_ac;                /* Common Ethernet/ARP Structure */
  224     void (*if_init) __P((int));         /* Interface init routine */
  225     void (*if_reset) __P((int));        /* Interface reset routine */
  226     caddr_t le_membase;                 /* Starting memory address (virtual) */
  227     unsigned le_iobase;                 /* Starting I/O base address */
  228     unsigned le_irq;                    /* Interrupt Request Value */
  229     unsigned le_flags;                  /* local copy of if_flags */
  230 #define LE_BRDCSTONLY   0x01000000      /* If only broadcast is enabled */
  231     u_int le_mcmask;                    /* bit mask for CRC-32 for multicast hash */
  232     le_mcbits_t *le_mctbl;              /* pointer to multicast table */
  233     const char *le_prodname;            /* product name DE20x-xx */
  234     u_char le_hwaddr[6];                /* local copy of hwaddr */
  235     unsigned le_scast_drops;            /* singlecast drops */
  236     unsigned le_mcast_drops;            /* multicast drops */
  237     unsigned le_bcast_drops;            /* broadcast drops */
  238     union {
  239 #if !defined(LE_NOLEMAC)
  240         struct le_lemac_info un_lemac;  /* LEMAC specific information */
  241 #endif
  242 #if !defined(LE_NOLANCE)
  243         struct le_lance_info un_lance;  /* Am7990 specific information */
  244 #endif
  245     } le_un;
  246 };
  247 #define le_if           le_ac.ac_if
  248 
  249 
  250 static int le_probe(struct isa_device *dvp);
  251 static int le_attach(struct isa_device *dvp);
  252 static int le_ioctl(struct ifnet *ifp, int command, caddr_t data);
  253 static void le_input(le_softc_t *sc, caddr_t seg1, size_t total_len,
  254                      size_t len2, caddr_t seg2);
  255 static void le_multi_filter(le_softc_t *sc);
  256 static void le_multi_op(le_softc_t *sc, const u_char *mca, int oper_flg);
  257 static int le_read_macaddr(le_softc_t *sc, int ioreg, int skippat);
  258 
  259 #define LE_CRC32_POLY           0xEDB88320UL    /* CRC-32 Poly -- Little Endian */
  260 
  261 struct le_board {
  262     int (*bd_probe)(le_softc_t *sc, const le_board_t *bd, int *msize);
  263 };
  264 
  265 
  266 static le_softc_t le_softc[NLE];
  267 
  268 static const le_board_t le_boards[] = {
  269 #if !defined(LE_NOLEMAC)
  270     { lemac_probe },                    /* DE20[345] */
  271 #endif
  272 #if !defined(LE_NOLANCE)
  273     { depca_probe },                    /* DE{20[012],422} */
  274 #endif
  275     { NULL }                            /* Must Be Last! */
  276 };
  277 
  278 /*
  279  * This tells the autoconf code how to set us up.
  280  */
  281 struct isa_driver ledriver = {
  282     le_probe, le_attach, "le",
  283 };
  284 
  285 static unsigned le_intrs[NLE];
  286 
  287 #define LE_ADDREQUAL(a1, a2) \
  288         (((u_short *)a1)[0] == ((u_short *)a2)[0] \
  289          || ((u_short *)a1)[1] == ((u_short *)a2)[1] \
  290          || ((u_short *)a1)[2] == ((u_short *)a2)[2])
  291 #define LE_ADDRBRDCST(a1) \
  292         (((u_short *)a1)[0] == 0xFFFFU \
  293          || ((u_short *)a1)[1] == 0xFFFFU \
  294          || ((u_short *)a1)[2] == 0xFFFFU)
  295 
  296 #define LE_INL(sc, reg) \
  297 ({ u_long data; \
  298         __asm __volatile("inl %1, %0": "=a" (data): "d" ((u_short)((sc)->le_iobase + (reg)))); \
  299         data; })
  300 
  301 
  302 #define LE_OUTL(sc, reg, data) \
  303         ({__asm __volatile("outl %0, %1"::"a" ((u_long)(data)), "d" ((u_short)((sc)->le_iobase + (reg))));})
  304 
  305 #define LE_INW(sc, reg) \
  306 ({ u_short data; \
  307         __asm __volatile("inw %1, %0": "=a" (data): "d" ((u_short)((sc)->le_iobase + (reg)))); \
  308         data; })
  309 
  310 
  311 #define LE_OUTW(sc, reg, data) \
  312         ({__asm __volatile("outw %0, %1"::"a" ((u_short)(data)), "d" ((u_short)((sc)->le_iobase + (reg))));})
  313 
  314 #define LE_INB(sc, reg) \
  315 ({ u_char data; \
  316         __asm __volatile("inb %1, %0": "=a" (data): "d" ((u_short)((sc)->le_iobase + (reg)))); \
  317         data; })
  318 
  319 
  320 #define LE_OUTB(sc, reg, data) \
  321         ({__asm __volatile("outb %0, %1"::"a" ((u_char)(data)), "d" ((u_short)((sc)->le_iobase + (reg))));})
  322 
  323 #define MEMCPY(to, from, len)           bcopy(from, to, len)
  324 #define MEMSET(where, what, howmuch)    bzero(where, howmuch)
  325 #define MEMCMP(l, r, len)               bcmp(l, r, len)
  326 
  327 
  328 static int
  329 le_probe(
  330     struct isa_device *dvp)
  331 {
  332     le_softc_t *sc = &le_softc[dvp->id_unit];
  333     const le_board_t *bd;
  334     int iospace;
  335 
  336     if (dvp->id_unit >= NLE) {
  337         printf("%s%d not configured -- too many devices\n",
  338                ledriver.name, dvp->id_unit);
  339         return 0;
  340     }
  341 
  342     sc->le_iobase = dvp->id_iobase;
  343     sc->le_membase = (u_char *) dvp->id_maddr;
  344     sc->le_irq = dvp->id_irq;
  345     sc->le_if.if_name = ledriver.name;
  346     sc->le_if.if_unit = dvp->id_unit;
  347 
  348     /*
  349      * Find and Initialize board..
  350      */
  351 
  352     sc->le_flags &= ~(IFF_UP|IFF_ALLMULTI);
  353 
  354     for (bd = le_boards; bd->bd_probe != NULL; bd++) {
  355         if ((iospace = (*bd->bd_probe)(sc, bd, &dvp->id_msize)) != 0) {
  356             return iospace;
  357         }
  358     }
  359 
  360     return 0;
  361 }
  362 
  363 static int
  364 le_attach(
  365     struct isa_device *dvp)
  366 {
  367     le_softc_t *sc = &le_softc[dvp->id_unit];
  368     struct ifnet *ifp = &sc->le_if;
  369 
  370     ifp->if_softc = sc;
  371     ifp->if_mtu = ETHERMTU;
  372     printf("%s%d: %s ethernet address %6D\n",
  373            ifp->if_name, ifp->if_unit,
  374            sc->le_prodname,
  375            sc->le_ac.ac_enaddr, ":");
  376 
  377     ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  378     ifp->if_output = ether_output;
  379     ifp->if_ioctl = le_ioctl;
  380     ifp->if_type = IFT_ETHER;
  381     ifp->if_addrlen = 6;
  382     ifp->if_hdrlen = 14;
  383 
  384 #if NBPFILTER > 0
  385     bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
  386 #endif
  387 
  388     if_attach(ifp);
  389     ether_ifattach(ifp);
  390 
  391     return 1;
  392 }
  393 
  394 void
  395 le_intr(
  396     int unit)
  397 {
  398     int s = splimp();
  399 
  400     le_intrs[unit]++;
  401     (*le_intrvec[unit])(&le_softc[unit]);
  402 
  403     splx(s);
  404 }
  405 
  406 #define LE_XTRA         0
  407 
  408 static void
  409 le_input(
  410     le_softc_t *sc,
  411     caddr_t seg1,
  412     size_t total_len,
  413     size_t len1,
  414     caddr_t seg2)
  415 {
  416     struct ether_header eh;
  417     struct mbuf *m;
  418 
  419     if (total_len - sizeof(eh) > ETHERMTU
  420             || total_len - sizeof(eh) < ETHERMIN) {
  421         sc->le_if.if_ierrors++;
  422         return;
  423     }
  424     MEMCPY(&eh, seg1, sizeof(eh));
  425 
  426 #if NBPFILTER > 0
  427     if (sc->le_if.if_bpf != NULL && seg2 == NULL) {
  428         bpf_tap(&sc->le_if, seg1, total_len);
  429         /*
  430          * If this is single cast but not to us
  431          * drop it!
  432          */
  433         if ((eh.ether_dhost[0] & 1) == 0) {
  434             if (!LE_ADDREQUAL(eh.ether_dhost, sc->le_ac.ac_enaddr)) {
  435                 sc->le_scast_drops++;
  436                 return;
  437             }
  438         } else if ((sc->le_flags & IFF_MULTICAST) == 0) {
  439             sc->le_mcast_drops++;
  440             return;
  441         } else if (sc->le_flags & LE_BRDCSTONLY) {
  442             if (!LE_ADDRBRDCST(eh.ether_dhost)) {
  443                 sc->le_bcast_drops++;
  444                 return;
  445             }
  446         }
  447     }
  448 #endif
  449     seg1 += sizeof(eh); total_len -= sizeof(eh); len1 -= sizeof(eh);
  450 
  451     MGETHDR(m, M_DONTWAIT, MT_DATA);
  452     if (m == NULL) {
  453         sc->le_if.if_ierrors++;
  454         return;
  455     }
  456     m->m_pkthdr.len = total_len;
  457     m->m_pkthdr.rcvif = &sc->le_if;
  458     if (total_len + LE_XTRA > MHLEN /* >= MINCLSIZE */) {
  459         MCLGET(m, M_DONTWAIT);
  460         if ((m->m_flags & M_EXT) == 0) {
  461             m_free(m);
  462             sc->le_if.if_ierrors++;
  463             return;
  464         }
  465     } else if (total_len + LE_XTRA > MHLEN && MINCLSIZE == (MHLEN+MLEN)) {
  466         MGET(m->m_next, M_DONTWAIT, MT_DATA);
  467         if (m->m_next == NULL) {
  468             m_free(m);
  469             sc->le_if.if_ierrors++;
  470             return;
  471         }
  472         m->m_next->m_len = total_len - MHLEN - LE_XTRA;
  473         len1 = total_len = MHLEN - LE_XTRA;
  474         MEMCPY(mtod(m->m_next, caddr_t), &seg1[MHLEN-LE_XTRA], m->m_next->m_len);
  475     } else if (total_len + LE_XTRA > MHLEN) {
  476         panic("le_input: pkt of unknown length");
  477     }
  478     m->m_data += LE_XTRA;
  479     m->m_len = total_len;
  480     MEMCPY(mtod(m, caddr_t), seg1, len1);
  481     if (seg2 != NULL)
  482         MEMCPY(mtod(m, caddr_t) + len1, seg2, total_len - len1);
  483 #if NBPFILTER > 0
  484     if (sc->le_if.if_bpf != NULL && seg2 != NULL) {
  485         bpf_mtap(&sc->le_if, m);
  486         /*
  487          * If this is single cast but not to us
  488          * drop it!
  489          */
  490         if ((eh.ether_dhost[0] & 1) == 0) {
  491             if (!LE_ADDREQUAL(eh.ether_dhost, sc->le_ac.ac_enaddr)) {
  492                 sc->le_scast_drops++;
  493                 m_freem(m);
  494                 return;
  495             }
  496         } else if ((sc->le_flags & IFF_MULTICAST) == 0) {
  497             sc->le_mcast_drops++;
  498             m_freem(m);
  499             return;
  500         } else if (sc->le_flags & LE_BRDCSTONLY) {
  501             if (!LE_ADDRBRDCST(eh.ether_dhost)) {
  502                 sc->le_bcast_drops++;
  503                 m_freem(m);
  504                 return;
  505             }
  506         }
  507     }
  508 #endif
  509     ether_input(&sc->le_if, &eh, m);
  510 }
  511 
  512 static int
  513 le_ioctl(
  514     struct ifnet *ifp,
  515     int cmd,
  516     caddr_t data)
  517 {
  518     le_softc_t *sc = ifp->if_softc;
  519     int s, error = 0;
  520 
  521     if ((sc->le_flags & IFF_UP) == 0)
  522         return EIO;
  523 
  524     s = splimp();
  525 
  526     switch (cmd) {
  527         case SIOCSIFADDR: {
  528             struct ifaddr *ifa = (struct ifaddr *)data;
  529 
  530             ifp->if_flags |= IFF_UP;
  531             switch(ifa->ifa_addr->sa_family) {
  532 #ifdef INET
  533                 case AF_INET: {
  534                     (*sc->if_init)(ifp->if_unit);
  535                     arp_ifinit((struct arpcom *)ifp, ifa);
  536                     break;
  537                 }
  538 #endif /* INET */
  539 #ifdef IPX
  540                 /* This magic copied from if_is.c; I don't use XNS,
  541                  * so I have no way of telling if this actually
  542                  * works or not.
  543                  */
  544                 case AF_IPX: {
  545                     struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
  546                     if (ipx_nullhost(*ina)) {
  547                         ina->x_host = *(union ipx_host *)(sc->le_ac.ac_enaddr);
  548                     } else {
  549                         ifp->if_flags &= ~IFF_RUNNING;
  550                         bcopy((caddr_t)ina->x_host.c_host,
  551                               (caddr_t)sc->le_ac.ac_enaddr,
  552                               sizeof sc->le_ac.ac_enaddr);
  553                     }
  554 
  555                     (*sc->if_init)(ifp->if_unit);
  556                     break;
  557                 }
  558 #endif /* IPX */
  559 #ifdef NS
  560                 /* This magic copied from if_is.c; I don't use XNS,
  561                  * so I have no way of telling if this actually
  562                  * works or not.
  563                  */
  564                 case AF_NS: {
  565                     struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
  566                     if (ns_nullhost(*ina)) {
  567                         ina->x_host = *(union ns_host *)(sc->le_ac.ac_enaddr);
  568                     } else {
  569                         ifp->if_flags &= ~IFF_RUNNING;
  570                         bcopy((caddr_t)ina->x_host.c_host,
  571                               (caddr_t)sc->le_ac.ac_enaddr,
  572                               sizeof sc->le_ac.ac_enaddr);
  573                     }
  574 
  575                     (*sc->if_init)(ifp->if_unit);
  576                     break;
  577                 }
  578 #endif /* NS */
  579                 default: {
  580                     (*sc->if_init)(ifp->if_unit);
  581                     break;
  582                 }
  583             }
  584             break;
  585         }
  586 
  587         case SIOCSIFFLAGS: {
  588             (*sc->if_init)(ifp->if_unit);
  589             break;
  590         }
  591 
  592         case SIOCADDMULTI:
  593         case SIOCDELMULTI: {
  594             /*
  595              * Update multicast listeners
  596              */
  597             if (cmd == SIOCADDMULTI)
  598                 error = ether_addmulti((struct ifreq *)data, &sc->le_ac);
  599             else
  600                 error = ether_delmulti((struct ifreq *)data, &sc->le_ac);
  601 
  602             if (error == ENETRESET) {
  603                 /* reset multicast filtering */
  604                 (*sc->if_init)(ifp->if_unit);
  605                 error = 0;
  606             }
  607             break;
  608         }
  609 
  610         default: {
  611             error = EINVAL;
  612         }
  613     }
  614 
  615     splx(s);
  616     return error;
  617 }
  618 
  619 /*
  620  *  This is the standard method of reading the DEC Address ROMS.
  621  *  I don't understand it but it does work.
  622  */
  623 static int
  624 le_read_macaddr(
  625     le_softc_t *sc,
  626     int ioreg,
  627     int skippat)
  628 {
  629     int cksum, rom_cksum;
  630 
  631     if (!skippat) {
  632         int idx, idx2, found, octet;
  633         static u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
  634         idx2 = found = 0;
  635 
  636         for (idx = 0; idx < 32; idx++) {
  637             octet = LE_INB(sc, ioreg);
  638 
  639             if (octet == testpat[idx2]) {
  640                 if (++idx2 == sizeof testpat) {
  641                     ++found;
  642                     break;
  643                 }
  644             } else {
  645                 idx2 = 0;
  646             }
  647         }
  648 
  649         if (!found)
  650             return -1;
  651     }
  652 
  653     cksum = 0;
  654     sc->le_hwaddr[0] = LE_INB(sc, ioreg);
  655     sc->le_hwaddr[1] = LE_INB(sc, ioreg);
  656 
  657     cksum = *(u_short *) &sc->le_hwaddr[0];
  658 
  659     sc->le_hwaddr[2] = LE_INB(sc, ioreg);
  660     sc->le_hwaddr[3] = LE_INB(sc, ioreg);
  661     cksum *= 2;
  662     if (cksum > 65535) cksum -= 65535;
  663     cksum += *(u_short *) &sc->le_hwaddr[2];
  664     if (cksum > 65535) cksum -= 65535;
  665 
  666     sc->le_hwaddr[4] = LE_INB(sc, ioreg);
  667     sc->le_hwaddr[5] = LE_INB(sc, ioreg);
  668     cksum *= 2;
  669     if (cksum > 65535) cksum -= 65535;
  670     cksum += *(u_short *) &sc->le_hwaddr[4];
  671     if (cksum >= 65535) cksum -= 65535;
  672 
  673     rom_cksum = LE_INB(sc, ioreg);
  674     rom_cksum |= LE_INB(sc, ioreg) << 8;
  675 
  676     if (cksum != rom_cksum)
  677         return -1;
  678     return 0;
  679 }
  680 
  681 static void
  682 le_multi_filter(
  683     le_softc_t *sc)
  684 {
  685     struct ether_multistep step;
  686     struct ether_multi *enm;
  687 #ifdef ISO
  688     extern char all_es_snpa[];
  689 #endif
  690 
  691     MEMSET(sc->le_mctbl, 0, (sc->le_mcmask + 1) / 8);
  692 
  693     if (sc->le_if.if_flags & IFF_ALLMULTI) {
  694         sc->le_flags |= IFF_MULTICAST|IFF_ALLMULTI;
  695         return;
  696     }
  697     sc->le_flags &= ~IFF_MULTICAST;
  698     /* if (interface has had an address assigned) { */
  699         le_multi_op(sc, etherbroadcastaddr, TRUE);
  700         sc->le_flags |= LE_BRDCSTONLY|IFF_MULTICAST;
  701     /* } */
  702 #ifdef ISO
  703     le_multi_op(sc, all_es_snpa, TRUE);
  704 #endif
  705 
  706     ETHER_FIRST_MULTI(step, &sc->le_ac, enm);
  707     if (enm != NULL)
  708         sc->le_flags |= IFF_MULTICAST;
  709     while (enm != NULL) {
  710         if (MEMCMP(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
  711             sc->le_flags |= IFF_ALLMULTI;
  712             return;
  713         }
  714         le_multi_op(sc, enm->enm_addrlo, TRUE);
  715         ETHER_NEXT_MULTI(step, enm);
  716         sc->le_flags &= ~LE_BRDCSTONLY;
  717     }
  718     sc->le_flags &= ~IFF_ALLMULTI;
  719 }
  720 
  721 static void
  722 le_multi_op(
  723     le_softc_t *sc,
  724     const u_char *mca,
  725     int enable)
  726 {
  727     u_int idx, bit, data, crc = 0xFFFFFFFFUL;
  728 
  729 #ifdef __alpha
  730     for (data = *(__unaligned u_long *) mca, bit = 0; bit < 48; bit++, data >>=
  731 1)
  732         crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LE_CRC32_POLY : 0);
  733 #else
  734     for (idx = 0; idx < 6; idx++)
  735         for (data = *mca++, bit = 0; bit < 8; bit++, data >>= 1)
  736             crc = (crc >> 1) ^ (((crc ^ data) & 1) ? LE_CRC32_POLY : 0);
  737 #endif
  738     /*
  739      * The following two line convert the N bit index into a longword index
  740      * and a longword mask.
  741      */
  742     crc &= sc->le_mcmask;
  743     bit = 1 << (crc & (LE_MC_NBPW -1));
  744     idx = crc >> (LE_MC_NBPW_LOG2);
  745 
  746     /*
  747      * Set or clear hash filter bit in our table.
  748      */
  749     if (enable) {
  750         sc->le_mctbl[idx] |= bit;               /* Set Bit */
  751     } else {
  752         sc->le_mctbl[idx] &= ~bit;              /* Clear Bit */
  753     }
  754 }
  755 
  756 #if !defined(LE_NOLEMAC)
  757 /*
  758  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  759  *
  760  * Start of DEC EtherWORKS III (LEMAC) dependent code
  761  *
  762  */
  763 
  764 #define LEMAC_INTR_ENABLE(sc) \
  765         LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) | LEMAC_IC_ALL)
  766 
  767 #define LEMAC_INTR_DISABLE(sc) \
  768         LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) & ~LEMAC_IC_ALL)
  769 
  770 #define LEMAC_64K_MODE(mbase)   (((mbase) >= 0x0A) && ((mbase) <= 0x0F))
  771 #define LEMAC_32K_MODE(mbase)   (((mbase) >= 0x14) && ((mbase) <= 0x1F))
  772 #define LEMAC_2K_MODE(mbase)    ( (mbase) >= 0x40)
  773 
  774 static void lemac_init(int unit);
  775 static void lemac_start(struct ifnet *ifp);
  776 static void lemac_reset(IF_RESET_ARGS);
  777 static void lemac_intr(le_softc_t *sc);
  778 static void lemac_rne_intr(le_softc_t *sc);
  779 static void lemac_tne_intr(le_softc_t *sc);
  780 static void lemac_txd_intr(le_softc_t *sc, unsigned cs_value);
  781 static void lemac_rxd_intr(le_softc_t *sc, unsigned cs_value);
  782 static int  lemac_read_eeprom(le_softc_t *sc);
  783 static void lemac_init_adapmem(le_softc_t *sc);
  784 
  785 #define LE_MCBITS_ALL_1S        ((le_mcbits_t)~(le_mcbits_t)0)
  786 
  787 static const le_mcbits_t lemac_allmulti_mctbl[16] =  {
  788     LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
  789     LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
  790     LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
  791     LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S, LE_MCBITS_ALL_1S,
  792 };
  793 /*
  794  * An IRQ mapping table.  Less space than switch statement.
  795  */
  796 static const int lemac_irqs[] = { IRQ5, IRQ10, IRQ11, IRQ15 };
  797 
  798 /*
  799  * Some tuning/monitoring variables.
  800  */
  801 static unsigned lemac_deftxmax = 16;    /* see lemac_max above */
  802 static unsigned lemac_txnospc = 0;      /* total # of tranmit starvations */
  803 
  804 static unsigned lemac_tne_intrs = 0;    /* total # of tranmit done intrs */
  805 static unsigned lemac_rne_intrs = 0;    /* total # of receive done intrs */
  806 static unsigned lemac_txd_intrs = 0;    /* total # of tranmit error intrs */
  807 static unsigned lemac_rxd_intrs = 0;    /* total # of receive error intrs */
  808 
  809 
  810 static int
  811 lemac_probe(
  812     le_softc_t *sc,
  813     const le_board_t *bd,
  814     int *msize)
  815 {
  816     int irq, portval;
  817 
  818     LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEINIT);
  819     DELAY(LEMAC_EEP_DELAY);
  820 
  821     /*
  822      *  Read Ethernet address if card is present.
  823      */
  824     if (le_read_macaddr(sc, LEMAC_REG_APD, 0) < 0)
  825         return 0;
  826 
  827     MEMCPY(sc->le_ac.ac_enaddr, sc->le_hwaddr, 6);
  828     /*
  829      *  Clear interrupts and set IRQ.
  830      */
  831 
  832     portval = LE_INB(sc, LEMAC_REG_IC) & LEMAC_IC_IRQMSK;
  833     irq = lemac_irqs[portval >> 5];
  834     LE_OUTB(sc, LEMAC_REG_IC, portval);
  835 
  836     /*
  837      *  Make sure settings match.
  838      */
  839 
  840     if (irq != sc->le_irq) {
  841         printf("%s%d: lemac configuration error: expected IRQ 0x%x actual 0x%x\n",
  842                sc->le_if.if_name, sc->le_if.if_unit, sc->le_irq, irq);
  843         return 0;
  844     }
  845 
  846     /*
  847      * Try to reset the unit
  848      */
  849     sc->if_init = lemac_init;
  850     sc->le_if.if_start = lemac_start;
  851     sc->if_reset = lemac_reset;
  852     sc->lemac_memmode = 2;
  853     LE_RESET(sc);
  854     if ((sc->le_flags & IFF_UP) == 0)
  855         return 0;
  856 
  857     /*
  858      *  Check for correct memory base configuration.
  859      */
  860     if (vtophys(sc->le_membase) != sc->lemac_membase) {
  861         printf("%s%d: lemac configuration error: expected iomem 0x%x actual 0x%x\n",
  862                sc->le_if.if_name, sc->le_if.if_unit,
  863                vtophys(sc->le_membase), sc->lemac_membase);
  864         return 0;
  865     }
  866 
  867     sc->le_prodname = sc->lemac_prodname;
  868     sc->le_mctbl = sc->lemac_mctbl;
  869     sc->le_mcmask = (1 << LEMAC_MCTBL_BITS) - 1;
  870     sc->lemac_txmax = lemac_deftxmax;
  871     *msize = 2048;
  872     le_intrvec[sc->le_if.if_unit] = lemac_intr;
  873 
  874     return LEMAC_IOSPACE;
  875 }
  876 
  877 /*
  878  * Do a hard reset of the board;
  879  */
  880 static void
  881 lemac_reset(
  882     IF_RESET_ARGS)
  883 {
  884     le_softc_t *sc = &le_softc[unit];
  885     int portval, cksum;
  886 
  887     /*
  888      * Initialize board..
  889      */
  890 
  891     sc->le_flags &= IFF_UP;
  892     sc->le_if.if_flags &= ~IFF_OACTIVE;
  893     LEMAC_INTR_DISABLE(sc);
  894 
  895     LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEINIT);
  896     DELAY(LEMAC_EEP_DELAY);
  897 
  898     /* Disable Interrupts */
  899     /* LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) & ICR_IRQ_SEL); */
  900 
  901     /*
  902      * Read EEPROM information.  NOTE - the placement of this function
  903      * is important because functions hereafter may rely on information
  904      * read from the EEPROM.
  905      */
  906     if ((cksum = lemac_read_eeprom(sc)) != LEMAC_EEP_CKSUM) {
  907         printf("%s%d: reset: EEPROM checksum failed (0x%x)\n",
  908                sc->le_if.if_name, sc->le_if.if_unit, cksum);
  909         return;
  910     }
  911 
  912     /*
  913      *  Force to 2K mode if not already configured.
  914      */
  915 
  916     portval = LE_INB(sc, LEMAC_REG_MBR);
  917     if (!LEMAC_2K_MODE(portval)) {
  918         if (LEMAC_64K_MODE(portval)) {
  919             portval = (((portval * 2) & 0xF) << 4);
  920             sc->lemac_memmode = 64;
  921         } else if (LEMAC_32K_MODE(portval)) {
  922             portval = ((portval & 0xF) << 4);
  923             sc->lemac_memmode = 32;
  924         }
  925         LE_OUTB(sc, LEMAC_REG_MBR, portval);
  926     }
  927     sc->lemac_membase = portval * (2 * 1024) + (512 * 1024);
  928 
  929     /*
  930      *  Initialize Free Memory Queue, Init mcast table with broadcast.
  931      */
  932 
  933     lemac_init_adapmem(sc);
  934     sc->le_flags |= IFF_UP;
  935     return;
  936 }
  937 
  938 static void
  939 lemac_init(
  940     int unit)
  941 {
  942     le_softc_t *sc = &le_softc[unit];
  943     int s;
  944 
  945     if ((sc->le_flags & IFF_UP) == 0)
  946         return;
  947 
  948     s = splimp();
  949 
  950     /*
  951      * If the interface has the up flag
  952      */
  953     if (sc->le_if.if_flags & IFF_UP) {
  954         int saved_cs = LE_INB(sc, LEMAC_REG_CS);
  955         LE_OUTB(sc, LEMAC_REG_CS, saved_cs | (LEMAC_CS_TXD | LEMAC_CS_RXD));
  956         LE_OUTB(sc, LEMAC_REG_PA0, sc->le_ac.ac_enaddr[0]);
  957         LE_OUTB(sc, LEMAC_REG_PA1, sc->le_ac.ac_enaddr[1]);
  958         LE_OUTB(sc, LEMAC_REG_PA2, sc->le_ac.ac_enaddr[2]);
  959         LE_OUTB(sc, LEMAC_REG_PA3, sc->le_ac.ac_enaddr[3]);
  960         LE_OUTB(sc, LEMAC_REG_PA4, sc->le_ac.ac_enaddr[4]);
  961         LE_OUTB(sc, LEMAC_REG_PA5, sc->le_ac.ac_enaddr[5]);
  962 
  963         LE_OUTB(sc, LEMAC_REG_IC, LE_INB(sc, LEMAC_REG_IC) | LEMAC_IC_IE);
  964 
  965         if (sc->le_if.if_flags & IFF_PROMISC) {
  966             LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_MCE | LEMAC_CS_PME);
  967         } else {
  968             LEMAC_INTR_DISABLE(sc);
  969             le_multi_filter(sc);
  970             LE_OUTB(sc, LEMAC_REG_MPN, 0);
  971             if ((sc->le_flags | sc->le_if.if_flags) & IFF_ALLMULTI) {
  972                 MEMCPY(&sc->le_membase[LEMAC_MCTBL_OFF], lemac_allmulti_mctbl, sizeof(lemac_allmulti_mctbl));
  973             } else {
  974                 MEMCPY(&sc->le_membase[LEMAC_MCTBL_OFF], sc->lemac_mctbl, sizeof(sc->lemac_mctbl));
  975             }
  976             LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_MCE);
  977         }
  978 
  979         LE_OUTB(sc, LEMAC_REG_CTL, LE_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
  980 
  981         LEMAC_INTR_ENABLE(sc);
  982         sc->le_if.if_flags |= IFF_RUNNING;
  983     } else {
  984         LE_OUTB(sc, LEMAC_REG_CS, LEMAC_CS_RXD|LEMAC_CS_TXD);
  985 
  986         LEMAC_INTR_DISABLE(sc);
  987         sc->le_if.if_flags &= ~IFF_RUNNING;
  988     }
  989     splx(s);
  990 }
  991 
  992 /*
  993  * What to do upon receipt of an interrupt.
  994  */
  995 static void
  996 lemac_intr(
  997     le_softc_t *sc)
  998 {
  999     int cs_value;
 1000 
 1001     LEMAC_INTR_DISABLE(sc);     /* Mask interrupts */
 1002 
 1003     /*
 1004      * Determine cause of interrupt.  Receive events take
 1005      * priority over Transmit.
 1006      */
 1007 
 1008     cs_value = LE_INB(sc, LEMAC_REG_CS);
 1009 
 1010     /*
 1011      * Check for Receive Queue not being empty.
 1012      * Check for Transmit Done Queue not being empty.
 1013      */
 1014 
 1015     if (cs_value & LEMAC_CS_RNE)
 1016         lemac_rne_intr(sc);
 1017     if (cs_value & LEMAC_CS_TNE)
 1018         lemac_tne_intr(sc);
 1019 
 1020     /*
 1021      * Check for Transmitter Disabled.
 1022      * Check for Receiver Disabled.
 1023      */
 1024 
 1025     if (cs_value & LEMAC_CS_TXD)
 1026         lemac_txd_intr(sc, cs_value);
 1027     if (cs_value & LEMAC_CS_RXD)
 1028         lemac_rxd_intr(sc, cs_value);
 1029 
 1030     /*
 1031      * Toggle LED and unmask interrupts.
 1032      */
 1033 
 1034     LE_OUTB(sc, LEMAC_REG_CTL, LE_INB(sc, LEMAC_REG_CTL) ^ LEMAC_CTL_LED);
 1035     LEMAC_INTR_ENABLE(sc);              /* Unmask interrupts */
 1036 }
 1037 
 1038 static void
 1039 lemac_rne_intr(
 1040     le_softc_t *sc)
 1041 {
 1042     int rxcount, rxlen, rxpg;
 1043     u_char *rxptr;
 1044 
 1045     lemac_rne_intrs++;
 1046     rxcount = LE_INB(sc, LEMAC_REG_RQC);
 1047     while (rxcount--) {
 1048         rxpg = LE_INB(sc, LEMAC_REG_RQ);
 1049         LE_OUTB(sc, LEMAC_REG_MPN, rxpg);
 1050 
 1051         rxptr = sc->le_membase;
 1052         sc->le_if.if_ipackets++;
 1053         if (*rxptr & LEMAC_RX_OK) {
 1054 
 1055             /*
 1056              * Get receive length - subtract out checksum.
 1057              */
 1058 
 1059             rxlen = ((*(u_int *)rxptr >> 8) & 0x7FF) - 4;
 1060             le_input(sc, rxptr + sizeof(u_int), rxlen, rxlen, NULL);
 1061         } else { /* end if (*rxptr & LEMAC_RX_OK) */
 1062             sc->le_if.if_ierrors++;
 1063         }
 1064         LE_OUTB(sc, LEMAC_REG_FMQ, rxpg);  /* Return this page to Free Memory Queue */
 1065     }  /* end while (recv_count--) */
 1066 
 1067     return;
 1068 }
 1069 
 1070 static void
 1071 lemac_rxd_intr(
 1072     le_softc_t *sc,
 1073     unsigned cs_value)
 1074 {
 1075     /*
 1076      * Handle CS_RXD (Receiver disabled) here.
 1077      *
 1078      * Check Free Memory Queue Count. If not equal to zero
 1079      * then just turn Receiver back on. If it is equal to
 1080      * zero then check to see if transmitter is disabled.
 1081      * Process transmit TXD loop once more.  If all else
 1082      * fails then do software init (0xC0 to EEPROM Init)
 1083      * and rebuild Free Memory Queue.
 1084      */
 1085 
 1086     lemac_rxd_intrs++;
 1087 
 1088     /*
 1089      *  Re-enable Receiver.
 1090      */
 1091 
 1092     cs_value &= ~LEMAC_CS_RXD;
 1093     LE_OUTB(sc, LEMAC_REG_CS, cs_value);
 1094 
 1095     if (LE_INB(sc, LEMAC_REG_FMC) > 0)
 1096         return;
 1097 
 1098     if (cs_value & LEMAC_CS_TXD)
 1099         lemac_txd_intr(sc, cs_value);
 1100 
 1101     if ((LE_INB(sc, LEMAC_REG_CS) & LEMAC_CS_RXD) == 0)
 1102         return;
 1103 
 1104     printf("%s%d: fatal RXD error, attempting recovery\n",
 1105            sc->le_if.if_name, sc->le_if.if_unit);
 1106 
 1107     LE_RESET(sc);
 1108     if (sc->le_flags & IFF_UP) {
 1109         lemac_init(sc->le_if.if_unit);
 1110         return;
 1111     }
 1112 
 1113     /*
 1114      *  Error during initializion.  Mark card as disabled.
 1115      */
 1116     printf("%s%d: recovery failed -- board disabled\n",
 1117            sc->le_if.if_name, sc->le_if.if_unit);
 1118     return;
 1119 }
 1120 
 1121 static void
 1122 lemac_start(
 1123     struct ifnet *ifp)
 1124 {
 1125     le_softc_t *sc = (le_softc_t *) ifp;
 1126     struct ifqueue *ifq = &ifp->if_snd;
 1127 
 1128     if ((ifp->if_flags & IFF_RUNNING) == 0)
 1129         return;
 1130 
 1131     LEMAC_INTR_DISABLE(sc);
 1132 
 1133     while (ifq->ifq_head != NULL) {
 1134         struct mbuf  *m;
 1135         int tx_pg;
 1136         u_int txhdr, txoff;
 1137 
 1138         if (LE_INB(sc, LEMAC_REG_TQC) >= sc->lemac_txmax) {
 1139             ifp->if_flags |= IFF_OACTIVE;
 1140             break;
 1141         }
 1142 
 1143         tx_pg = LE_INB(sc, LEMAC_REG_FMQ);      /* get free memory page */
 1144         /*
 1145          * Check for good transmit page.
 1146          */
 1147         if (tx_pg == 0 || tx_pg > sc->lemac_lastpage) {
 1148             lemac_txnospc++;
 1149             ifp->if_flags |= IFF_OACTIVE;
 1150             break;
 1151         }
 1152 
 1153         IF_DEQUEUE(ifq, m);
 1154         LE_OUTB(sc, LEMAC_REG_MPN, tx_pg);      /* Shift 2K window. */
 1155 
 1156         /*
 1157          * The first four bytes of each transmit buffer are for
 1158          * control information.  The first byte is the control
 1159          * byte, then the length (why not word aligned??), then
 1160          * the off to the buffer.
 1161          */
 1162 
 1163         txoff = (mtod(m, u_int) & (sizeof(u_long) - 1)) + LEMAC_TX_HDRSZ;
 1164         txhdr = sc->lemac_txctl | (m->m_pkthdr.len << 8) | (txoff << 24);
 1165         *(u_int *) sc->le_membase = txhdr;
 1166 
 1167         /*
 1168          * Copy the packet to the board
 1169          */
 1170 
 1171         m_copydata(m, 0, m->m_pkthdr.len, sc->le_membase + txoff);
 1172 
 1173         LE_OUTB(sc, LEMAC_REG_TQ, tx_pg);       /* tell chip to transmit this packet */
 1174 
 1175 #if NBPFILTER > 0
 1176         if (sc->le_if.if_bpf)
 1177                 bpf_mtap(&sc->le_if, m);
 1178 #endif
 1179 
 1180         m_freem(m);                     /* free the mbuf */
 1181     }
 1182     LEMAC_INTR_ENABLE(sc);
 1183 }
 1184 
 1185 static void
 1186 lemac_tne_intr(
 1187     le_softc_t *sc)
 1188 {
 1189     int txsts, txcount = LE_INB(sc, LEMAC_REG_TDC);
 1190 
 1191     lemac_tne_intrs++;
 1192     while (txcount--) {
 1193         txsts = LE_INB(sc, LEMAC_REG_TDQ);
 1194         sc->le_if.if_opackets++;                /* another one done */
 1195         if ((txsts & LEMAC_TDQ_COL) != LEMAC_TDQ_NOCOL)
 1196             sc->le_if.if_collisions++;
 1197     }
 1198     sc->le_if.if_flags &= ~IFF_OACTIVE;
 1199     lemac_start(&sc->le_if);
 1200 }
 1201 
 1202 static void
 1203 lemac_txd_intr(
 1204     le_softc_t *sc,
 1205     unsigned cs_value)
 1206 {
 1207     /*
 1208      * Read transmit status, remove transmit buffer from
 1209      * transmit queue and place on free memory queue,
 1210      * then reset transmitter.
 1211      * Increment appropriate counters.
 1212      */
 1213 
 1214     lemac_txd_intrs++;
 1215     sc->le_if.if_oerrors++;
 1216     if (LE_INB(sc, LEMAC_REG_TS) & LEMAC_TS_ECL)
 1217         sc->le_if.if_collisions++;
 1218     sc->le_if.if_flags &= ~IFF_OACTIVE;
 1219 
 1220     LE_OUTB(sc, LEMAC_REG_FMQ, LE_INB(sc, LEMAC_REG_TQ));
 1221                                 /* Get Page number and write it back out */
 1222 
 1223     LE_OUTB(sc, LEMAC_REG_CS, cs_value & ~LEMAC_CS_TXD);
 1224                                 /* Turn back on transmitter */
 1225     return;
 1226 }
 1227 
 1228 static int
 1229 lemac_read_eeprom(
 1230     le_softc_t *sc)
 1231 {
 1232     int word_off, cksum;
 1233 
 1234     u_char *ep;
 1235 
 1236     cksum = 0;
 1237     ep = sc->lemac_eeprom;
 1238     for (word_off = 0; word_off < LEMAC_EEP_SIZE / 2; word_off++) {
 1239         LE_OUTB(sc, LEMAC_REG_PI1, word_off);
 1240         LE_OUTB(sc, LEMAC_REG_IOP, LEMAC_IOP_EEREAD);
 1241 
 1242         DELAY(LEMAC_EEP_DELAY);
 1243 
 1244         *ep = LE_INB(sc, LEMAC_REG_EE1);        cksum += *ep++;
 1245         *ep = LE_INB(sc, LEMAC_REG_EE2);        cksum += *ep++;
 1246     }
 1247 
 1248     /*
 1249      *  Set up Transmit Control Byte for use later during transmit.
 1250      */
 1251 
 1252     sc->lemac_txctl |= LEMAC_TX_FLAGS;
 1253 
 1254     if ((sc->lemac_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_SQE) == 0)
 1255         sc->lemac_txctl &= ~LEMAC_TX_SQE;
 1256 
 1257     if (sc->lemac_eeprom[LEMAC_EEP_SWFLAGS] & LEMAC_EEP_SW_LAB)
 1258         sc->lemac_txctl |= LEMAC_TX_LAB;
 1259 
 1260     MEMCPY(sc->lemac_prodname, &sc->lemac_eeprom[LEMAC_EEP_PRDNM], LEMAC_EEP_PRDNMSZ);
 1261     sc->lemac_prodname[LEMAC_EEP_PRDNMSZ] = '\0';
 1262 
 1263     return cksum % 256;
 1264 }
 1265 
 1266 static void
 1267 lemac_init_adapmem(
 1268     le_softc_t *sc)
 1269 {
 1270     int pg, conf;
 1271 
 1272     conf = LE_INB(sc, LEMAC_REG_CNF);
 1273 
 1274     if ((sc->lemac_eeprom[LEMAC_EEP_SETUP] & LEMAC_EEP_ST_DRAM) == 0) {
 1275         sc->lemac_lastpage = 63;
 1276         conf &= ~LEMAC_CNF_DRAM;
 1277     } else {
 1278         sc->lemac_lastpage = 127;
 1279         conf |= LEMAC_CNF_DRAM;
 1280     }
 1281 
 1282     LE_OUTB(sc, LEMAC_REG_CNF, conf);
 1283 
 1284     for (pg = 1; pg <= sc->lemac_lastpage; pg++)
 1285         LE_OUTB(sc, LEMAC_REG_FMQ, pg);
 1286 
 1287     return;
 1288 }
 1289 #endif /* !defined(LE_NOLEMAC) */
 1290 
 1291 #if !defined(LE_NOLANCE)
 1292 /*
 1293  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 1294  *
 1295  * Start of DEPCA (DE200/DE201/DE202/DE422 etal) support.
 1296  *
 1297  */
 1298 static void depca_intr(le_softc_t *sc);
 1299 static int  lance_init_adapmem(le_softc_t *sc);
 1300 static int  lance_init_ring(le_softc_t *sc, ln_ring_t *rp, lance_ring_t *ri,
 1301                             unsigned ndescs, unsigned bufoffset,
 1302                             unsigned descoffset);
 1303 static void lance_init(int unit);
 1304 static void lance_reset(IF_RESET_ARGS);
 1305 static void lance_intr(le_softc_t *sc);
 1306 static int  lance_rx_intr(le_softc_t *sc);
 1307 static void lance_start(struct ifnet *ifp);
 1308 static int  lance_tx_intr(le_softc_t *sc);
 1309 
 1310 #define LN_BUFSIZE              /* 380 */ 304   /* 1520 / 4 */
 1311 #define LN_TXDESC_RATIO         2048
 1312 #define LN_DESC_MAX             128
 1313 
 1314 #if LN_DOSTATS
 1315 static struct {
 1316     unsigned lance_rx_misses;
 1317     unsigned lance_rx_badcrc;
 1318     unsigned lance_rx_badalign;
 1319     unsigned lance_rx_badframe;
 1320     unsigned lance_rx_buferror;
 1321     unsigned lance_tx_deferred;
 1322     unsigned lance_tx_single_collisions;
 1323     unsigned lance_tx_multiple_collisions;
 1324     unsigned lance_tx_excessive_collisions;
 1325     unsigned lance_tx_late_collisions;
 1326 
 1327     unsigned lance_memory_errors;
 1328     unsigned lance_inits;
 1329     unsigned lance_tx_intrs;
 1330     unsigned lance_tx_nospc[2];
 1331     unsigned lance_tx_drains[2];
 1332     unsigned lance_tx_orphaned;
 1333     unsigned lance_tx_adoptions;
 1334     unsigned lance_tx_emptied;
 1335     unsigned lance_tx_deftxint;
 1336     unsigned lance_tx_buferror;
 1337     unsigned lance_high_txoutptr;
 1338     unsigned lance_low_txheapsize;
 1339     unsigned lance_low_txfree;
 1340     unsigned lance_tx_intr_hidescs;
 1341     /* unsigned lance_tx_intr_descs[LN_DESC_MAX]; */
 1342 
 1343     unsigned lance_rx_intrs;
 1344     unsigned lance_rx_badsop;
 1345     unsigned lance_rx_contig;
 1346     unsigned lance_rx_noncontig;
 1347     unsigned lance_rx_intr_hidescs;
 1348     unsigned lance_rx_ndescs[4096 / LN_BUFSIZE];
 1349     /* unsigned lance_rx_intr_descs[LN_DESC_MAX]; */
 1350 } lance_stats;
 1351 
 1352 #define LN_STAT(stat)   (lance_stats.lance_ ## stat)
 1353 #define LN_MINSTAT(stat, val)   (LN_STAT(stat > (val)) ? LN_STAT(stat = (val)) : 0)
 1354 #define LN_MAXSTAT(stat, val)   (LN_STAT(stat < (val)) ? LN_STAT(stat = (val)) : 0)
 1355 
 1356 #else
 1357 #define LN_STAT(stat)   0
 1358 #define LN_MINSTAT(stat, val)   0
 1359 #define LN_MAXSTAT(stat, val)   0
 1360 #endif
 1361 
 1362 #define LN_SELCSR(sc, csrno)            (LE_OUTW(sc, sc->lance_rap, csrno))
 1363 #define LN_INQCSR(sc)                   (LE_INW(sc, sc->lance_rap))
 1364 
 1365 #define LN_WRCSR(sc, val)               (LE_OUTW(sc, sc->lance_rdp, val))
 1366 #define LN_RDCSR(sc)                    (LE_INW(sc, sc->lance_rdp))
 1367 
 1368 
 1369 #define LN_ZERO(sc, vaddr, len)         bzero(vaddr, len)
 1370 #define LN_COPYTO(sc, from, to, len)    bcopy(from, to, len)
 1371 
 1372 #define LN_SETFLAG(sc, vaddr, val) \
 1373         (((volatile u_char *) vaddr)[3] = (val))
 1374 
 1375 #define LN_PUTDESC(sc, desc, vaddr) \
 1376         (((volatile u_short *) vaddr)[0] = ((u_short *) desc)[0], \
 1377          ((volatile u_short *) vaddr)[2] = ((u_short *) desc)[2], \
 1378          ((volatile u_short *) vaddr)[1] = ((u_short *) desc)[1])
 1379 
 1380 /*
 1381  * Only get the descriptor flags and length/status.  All else
 1382  * read-only.
 1383  */
 1384 #define LN_GETDESC(sc, desc, vaddr) \
 1385         (((u_short *) desc)[1] = ((volatile u_short *) vaddr)[1], \
 1386          ((u_short *) desc)[3] = ((volatile u_short *) vaddr)[3])
 1387 
 1388 
 1389 /*
 1390  *  These definitions are specific to the DEC "DEPCA-style" NICs.
 1391  *      (DEPCA, DE10x, DE20[012], DE422)
 1392  *
 1393  */
 1394 #define DEPCA_REG_NICSR         0               /* (RW;16) NI Control / Status */
 1395 #define DEPCA_REG_RDP           4               /* (RW:16) LANCE RDP (data) register */
 1396 #define DEPCA_REG_RAP           6               /* (RW:16) LANCE RAP (address) register */
 1397 #define DEPCA_REG_ADDRROM       12              /* (R : 8) DEPCA Ethernet Address ROM */
 1398 #define DEPCA_IOSPACE           16              /* DEPCAs use 16 bytes of IO space */
 1399 
 1400 #define DEPCA_NICSR_LED         0x0001          /* Light the LED on the back of the DEPCA */
 1401 #define DEPCA_NICSR_ENABINTR    0x0002          /* Enable Interrupts */
 1402 #define DEPCA_NICSR_MASKINTR    0x0004          /* Mask Interrupts */
 1403 #define DEPCA_NICSR_AAC         0x0008          /* Address Counter Clear */
 1404 #define DEPCA_NICSR_REMOTEBOOT  0x0010          /* Remote Boot Enabled (ignored) */
 1405 #define DEPCA_NICSR_32KRAM      0x0020          /* DEPCA LANCE RAM size 64K (C) / 32K (S) */
 1406 #define DEPCA_NICSR_LOW32K      0x0040          /* Bank Select (A15 = !This Bit) */
 1407 #define DEPCA_NICSR_SHE         0x0080          /* Shared RAM Enabled (ie hide ROM) */
 1408 #define DEPCA_NICSR_BOOTTMO     0x0100          /* Remote Boot Timeout (ignored) */
 1409 
 1410 #define DEPCA_RDNICSR(sc)       (LE_INW(sc, DEPCA_REG_NICSR))
 1411 #define DEPCA_WRNICSR(sc, val)  (LE_OUTW(sc, DEPCA_REG_NICSR, val))
 1412 
 1413 #define DEPCA_IDSTR_OFFSET      0xC006          /* ID String Offset */
 1414 
 1415 #define DEPCA_REG_EISAID        0x80
 1416 #define DEPCA_EISAID_MASK       0xf0ffffff
 1417 #define DEPCA_EISAID_DE422      0x2042A310
 1418 
 1419 typedef enum {
 1420     DEPCA_CLASSIC,
 1421     DEPCA_DE100, DEPCA_DE101,
 1422     DEPCA_EE100,
 1423     DEPCA_DE200, DEPCA_DE201, DEPCA_DE202,
 1424     DEPCA_DE422,
 1425     DEPCA_UNKNOWN
 1426 } depca_t;
 1427 
 1428 static const char *depca_signatures[] = {
 1429     "DEPCA",
 1430     "DE100", "DE101",
 1431     "EE100",
 1432     "DE200", "DE201", "DE202",
 1433     "DE422",
 1434     NULL
 1435 };
 1436 
 1437 static int
 1438 depca_probe(
 1439     le_softc_t *sc,
 1440     const le_board_t *bd,
 1441     int *msize)
 1442 {
 1443     unsigned nicsr, idx, idstr_offset = DEPCA_IDSTR_OFFSET;
 1444 
 1445     /*
 1446      *  Find out how memory we are dealing with.  Adjust
 1447      *  the ID string offset approriately if we are at
 1448      *  32K.  Make sure the ROM is enabled.
 1449      */
 1450     nicsr = DEPCA_RDNICSR(sc);
 1451     nicsr &= ~(DEPCA_NICSR_SHE|DEPCA_NICSR_LED|DEPCA_NICSR_ENABINTR);
 1452 
 1453     if (nicsr & DEPCA_NICSR_32KRAM) {
 1454         /*
 1455          * Make we are going to read the upper
 1456          * 32K so we do read the ROM.
 1457          */
 1458         sc->lance_ramsize = 32 * 1024;
 1459         nicsr &= ~DEPCA_NICSR_LOW32K;
 1460         sc->lance_ramoffset = 32 * 1024;
 1461         idstr_offset -= sc->lance_ramsize;
 1462     } else {
 1463         sc->lance_ramsize = 64 * 1024;
 1464         sc->lance_ramoffset = 0;
 1465     }
 1466     DEPCA_WRNICSR(sc, nicsr);
 1467 
 1468     sc->le_prodname = NULL;
 1469     for (idx = 0; depca_signatures[idx] != NULL; idx++) {
 1470         if (bcmp(depca_signatures[idx], sc->le_membase + idstr_offset, 5) == 0) {
 1471             sc->le_prodname = depca_signatures[idx];
 1472             break;
 1473         }
 1474     }
 1475 
 1476     if (sc->le_prodname == NULL) {
 1477         /*
 1478          * Try to get the EISA device if it's a DE422.
 1479          */
 1480         if (sc->le_iobase > 0x1000 && (sc->le_iobase & 0x0F00) == 0x0C00
 1481             && (LE_INL(sc, DEPCA_REG_EISAID) & DEPCA_EISAID_MASK)
 1482              == DEPCA_EISAID_DE422) {
 1483             sc->le_prodname = "DE422";
 1484         } else {
 1485             return 0;
 1486         }
 1487     }
 1488     if (idx == DEPCA_CLASSIC)
 1489         sc->lance_ramsize -= 16384;     /* Can't use the ROM area on a DEPCA */
 1490 
 1491     /*
 1492      * Try to read the address ROM.
 1493      *   Stop the LANCE, reset the Address ROM Counter (AAC),
 1494      *   read the NICSR to "clock" in the reset, and then
 1495      *   re-enable the Address ROM Counter.  Now read the
 1496      *   address ROM.
 1497      */
 1498     sc->lance_rdp = DEPCA_REG_RDP;
 1499     sc->lance_rap = DEPCA_REG_RAP;
 1500     sc->lance_csr3 = LN_CSR3_ALE;
 1501     sc->le_mctbl = sc->lance_initb.ln_multi_mask;
 1502     sc->le_mcmask = LN_MC_MASK;
 1503     LN_SELCSR(sc, LN_CSR0);
 1504     LN_WRCSR(sc, LN_CSR0_STOP);
 1505 
 1506     if (idx < DEPCA_DE200) {
 1507         DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) & ~DEPCA_NICSR_AAC);
 1508         DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) | DEPCA_NICSR_AAC);
 1509     }
 1510 
 1511     if (le_read_macaddr(sc, DEPCA_REG_ADDRROM, idx == DEPCA_CLASSIC) < 0)
 1512         return 0;
 1513 
 1514     MEMCPY(sc->le_ac.ac_enaddr, sc->le_hwaddr, 6);
 1515     /*
 1516      * Renable shared RAM.
 1517      */
 1518     DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) | DEPCA_NICSR_SHE);
 1519 
 1520     le_intrvec[sc->le_if.if_unit] = depca_intr;
 1521     if (!lance_init_adapmem(sc))
 1522         return 0;
 1523 
 1524     sc->if_reset = lance_reset;
 1525     sc->if_init = lance_init;
 1526     sc->le_if.if_start = lance_start;
 1527     DEPCA_WRNICSR(sc, DEPCA_NICSR_SHE | DEPCA_NICSR_ENABINTR);
 1528     LE_RESET(sc);
 1529 
 1530     LN_STAT(low_txfree = sc->lance_txinfo.ri_max);
 1531     LN_STAT(low_txheapsize = 0xFFFFFFFF);
 1532     *msize = sc->lance_ramsize;
 1533     return DEPCA_IOSPACE;
 1534 }
 1535 
 1536 static void
 1537 depca_intr(
 1538     le_softc_t *sc)
 1539 {
 1540     DEPCA_WRNICSR(sc, DEPCA_RDNICSR(sc) ^ DEPCA_NICSR_LED);
 1541     lance_intr(sc);
 1542 }
 1543 
 1544 /*
 1545  * Here's as good a place to describe our paritioning of the
 1546  * LANCE shared RAM space.  (NOTE: this driver does not yet support
 1547  * the concept of a LANCE being able to DMA).
 1548  *
 1549  * First is the 24 (00:23) bytes for LANCE Initialization Block
 1550  * Next are the recieve descriptors.  The number is calculated from
 1551  * how many LN_BUFSIZE buffers we can allocate (this number must
 1552  * be a power of 2).  Next are the transmit descriptors.  The amount
 1553  * of transmit descriptors is derived from the size of the RAM
 1554  * divided by 1K.  Now come the receive buffers (one for each receive
 1555  * descriptor).  Finally is the transmit heap.  (no fixed buffers are
 1556  * allocated so as to make the most use of the limited space).
 1557  */
 1558 static int
 1559 lance_init_adapmem(
 1560     le_softc_t *sc)
 1561 {
 1562     lance_addr_t rxbufoffset;
 1563     lance_addr_t rxdescoffset, txdescoffset;
 1564     unsigned rxdescs, txdescs;
 1565 
 1566     /*
 1567      * First calculate how many descriptors we heap.
 1568      * Note this assumes the ramsize is a power of two.
 1569      */
 1570     sc->lance_rxbufsize = LN_BUFSIZE;
 1571     rxdescs = 1;
 1572     while (rxdescs * sc->lance_rxbufsize < sc->lance_ramsize)
 1573         rxdescs *= 2;
 1574     rxdescs /= 2;
 1575     if (rxdescs > LN_DESC_MAX) {
 1576         sc->lance_rxbufsize *= rxdescs / LN_DESC_MAX;
 1577         rxdescs = LN_DESC_MAX;
 1578     }
 1579     txdescs = sc->lance_ramsize / LN_TXDESC_RATIO;
 1580     if (txdescs > LN_DESC_MAX)
 1581         txdescs = LN_DESC_MAX;
 1582 
 1583     /*
 1584      * Now calculate where everything goes in memory
 1585      */
 1586     rxdescoffset = sizeof(ln_initb_t);
 1587     txdescoffset = rxdescoffset + sizeof(ln_desc_t) * rxdescs;
 1588     rxbufoffset  = txdescoffset + sizeof(ln_desc_t) * txdescs;
 1589 
 1590     sc->le_mctbl = (le_mcbits_t *) sc->lance_initb.ln_multi_mask;
 1591     /*
 1592      * Remember these for debugging.
 1593      */
 1594     sc->lance_raminitb = (ln_initb_t *) sc->le_membase;
 1595     sc->lance_ramdesc = (ln_desc_t *) (sc->le_membase + rxdescoffset);
 1596 
 1597     /*
 1598      * Initialize the rings.
 1599      */
 1600     if (!lance_init_ring(sc, &sc->lance_initb.ln_rxring, &sc->lance_rxinfo,
 1601                    rxdescs, rxbufoffset, rxdescoffset))
 1602         return 0;
 1603     sc->lance_rxinfo.ri_heap = rxbufoffset;
 1604     sc->lance_rxinfo.ri_heapend = rxbufoffset + sc->lance_rxbufsize * rxdescs;
 1605 
 1606     if (!lance_init_ring(sc, &sc->lance_initb.ln_txring, &sc->lance_txinfo,
 1607                    txdescs, 0, txdescoffset))
 1608         return 0;
 1609     sc->lance_txinfo.ri_heap = sc->lance_rxinfo.ri_heapend;
 1610     sc->lance_txinfo.ri_heapend = sc->lance_ramsize;
 1611 
 1612     /*
 1613      * Set CSR1 and CSR2 to the address of the init block (which
 1614      * for us is always 0.
 1615      */
 1616     sc->lance_csr1 = LN_ADDR_LO(0 + sc->lance_ramoffset);
 1617     sc->lance_csr2 = LN_ADDR_HI(0 + sc->lance_ramoffset);
 1618     return 1;
 1619 }
 1620 
 1621 static int
 1622 lance_init_ring(
 1623     le_softc_t *sc,
 1624     ln_ring_t *rp,
 1625     lance_ring_t *ri,
 1626     unsigned ndescs,
 1627     lance_addr_t bufoffset,
 1628     lance_addr_t descoffset)
 1629 {
 1630     lance_descinfo_t *di;
 1631 
 1632     /*
 1633      * Initialize the ring pointer in the LANCE InitBlock
 1634      */
 1635     rp->r_addr_lo = LN_ADDR_LO(descoffset + sc->lance_ramoffset);
 1636     rp->r_addr_hi = LN_ADDR_HI(descoffset + sc->lance_ramoffset);
 1637     rp->r_log2_size = ffs(ndescs) - 1;
 1638 
 1639     /*
 1640      * Allocate the ring entry descriptors and initialize
 1641      * our ring information data structure.  All these are
 1642      * our copies and do not live in the LANCE RAM.
 1643      */
 1644     ri->ri_first = (lance_descinfo_t *) malloc(ndescs * sizeof(*di), M_DEVBUF, M_NOWAIT);
 1645     if (ri->ri_first == NULL) {
 1646         printf("lance_init_ring: malloc(%d) failed\n", ndescs * sizeof(*di));
 1647         return 0;
 1648     }
 1649     ri->ri_free = ri->ri_max = ndescs;
 1650     ri->ri_last = ri->ri_first + ri->ri_max;
 1651     for (di = ri->ri_first; di < ri->ri_last; di++) {
 1652         di->di_addr = sc->le_membase + descoffset;
 1653         di->di_mbuf = NULL;
 1654         if (bufoffset) {
 1655             di->di_bufaddr = bufoffset;
 1656             di->di_buflen = sc->lance_rxbufsize;
 1657             bufoffset += sc->lance_rxbufsize;
 1658         }
 1659         descoffset += sizeof(ln_desc_t);
 1660     }
 1661     return 1;
 1662 }
 1663 
 1664 static void
 1665 lance_dumpcsrs(
 1666     le_softc_t *sc,
 1667     const char *id)
 1668 {
 1669     printf("%s%d: %s: nicsr=%04x",
 1670            sc->le_if.if_name, sc->le_if.if_unit,
 1671            id, DEPCA_RDNICSR(sc));
 1672     LN_SELCSR(sc, LN_CSR0); printf(" csr0=%04x", LN_RDCSR(sc));
 1673     LN_SELCSR(sc, LN_CSR1); printf(" csr1=%04x", LN_RDCSR(sc));
 1674     LN_SELCSR(sc, LN_CSR2); printf(" csr2=%04x", LN_RDCSR(sc));
 1675     LN_SELCSR(sc, LN_CSR3); printf(" csr3=%04x\n", LN_RDCSR(sc));
 1676     LN_SELCSR(sc, LN_CSR0);
 1677 }
 1678 
 1679 static void
 1680 lance_reset(
 1681     IF_RESET_ARGS)
 1682 {
 1683     le_softc_t *sc = &le_softc[unit];
 1684     register int cnt, csr;
 1685 
 1686     /* lance_dumpcsrs(sc, "lance_reset: start"); */
 1687 
 1688     LN_WRCSR(sc, LN_RDCSR(sc) & ~LN_CSR0_ENABINTR);
 1689     LN_WRCSR(sc, LN_CSR0_STOP);
 1690     DELAY(100);
 1691 
 1692     sc->le_flags &= ~IFF_UP;
 1693     sc->le_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
 1694 
 1695     le_multi_filter(sc);                /* initialize the multicast table */
 1696     if ((sc->le_flags | sc->le_if.if_flags) & IFF_ALLMULTI) {
 1697         sc->lance_initb.ln_multi_mask[0] = 0xFFFFU;
 1698         sc->lance_initb.ln_multi_mask[1] = 0xFFFFU;
 1699         sc->lance_initb.ln_multi_mask[2] = 0xFFFFU;
 1700         sc->lance_initb.ln_multi_mask[3] = 0xFFFFU;
 1701     }
 1702     sc->lance_initb.ln_physaddr[0] = ((u_short *) sc->le_ac.ac_enaddr)[0];
 1703     sc->lance_initb.ln_physaddr[1] = ((u_short *) sc->le_ac.ac_enaddr)[1];
 1704     sc->lance_initb.ln_physaddr[2] = ((u_short *) sc->le_ac.ac_enaddr)[2];
 1705     if (sc->le_if.if_flags & IFF_PROMISC) {
 1706         sc->lance_initb.ln_mode |= LN_MODE_PROMISC;
 1707     } else {
 1708         sc->lance_initb.ln_mode &= ~LN_MODE_PROMISC;
 1709     }
 1710     /*
 1711      * We force the init block to be at the start
 1712      * of the LANCE's RAM buffer.
 1713      */
 1714     LN_COPYTO(sc, &sc->lance_initb, sc->le_membase, sizeof(sc->lance_initb));
 1715     LN_SELCSR(sc, LN_CSR1); LN_WRCSR(sc, sc->lance_csr1);
 1716     LN_SELCSR(sc, LN_CSR2); LN_WRCSR(sc, sc->lance_csr2);
 1717     LN_SELCSR(sc, LN_CSR3); LN_WRCSR(sc, sc->lance_csr3);
 1718 
 1719     /* lance_dumpcsrs(sc, "lance_reset: preinit"); */
 1720 
 1721     /*
 1722      * clear INITDONE and INIT the chip
 1723      */
 1724     LN_SELCSR(sc, LN_CSR0);
 1725     LN_WRCSR(sc, LN_CSR0_INIT|LN_CSR0_INITDONE);
 1726 
 1727     csr = 0;
 1728     cnt = 100;
 1729     while (cnt-- > 0) {
 1730         if (((csr = LN_RDCSR(sc)) & LN_CSR0_INITDONE) != 0)
 1731             break;
 1732         DELAY(10000);
 1733     }
 1734 
 1735     if ((csr & LN_CSR0_INITDONE) == 0) {    /* make sure we got out okay */
 1736         lance_dumpcsrs(sc, "lance_reset: reset failure");
 1737     } else {
 1738         /* lance_dumpcsrs(sc, "lance_reset: end"); */
 1739         sc->le_if.if_flags |= IFF_UP;
 1740         sc->le_flags |= IFF_UP;
 1741     }
 1742 }
 1743 
 1744 static void
 1745 lance_init(
 1746     int unit)
 1747 {
 1748     le_softc_t *sc = &le_softc[unit];
 1749     lance_ring_t *ri;
 1750     lance_descinfo_t *di;
 1751     ln_desc_t desc;
 1752 
 1753     LN_STAT(inits++);
 1754     if (sc->le_if.if_flags & IFF_RUNNING) {
 1755         LE_RESET(sc);
 1756         lance_tx_intr(sc);
 1757         /*
 1758          * If we were running, requeue any pending transmits.
 1759          */
 1760         ri = &sc->lance_txinfo;
 1761         di = ri->ri_nextout;
 1762         while (ri->ri_free < ri->ri_max) {
 1763             if (--di == ri->ri_first)
 1764                 di = ri->ri_nextout - 1;
 1765             if (di->di_mbuf == NULL)
 1766                 break;
 1767             IF_PREPEND(&sc->le_if.if_snd, di->di_mbuf);
 1768             di->di_mbuf = NULL;
 1769             ri->ri_free++;
 1770         }
 1771     } else {
 1772         LE_RESET(sc);
 1773     }
 1774 
 1775     /*
 1776      * Reset the transmit ring.  Make sure we own all the buffers.
 1777      * Also reset the transmit heap.
 1778      */
 1779     sc->le_if.if_flags &= ~IFF_OACTIVE;
 1780     ri = &sc->lance_txinfo;
 1781     for (di = ri->ri_first; di < ri->ri_last; di++) {
 1782         if (di->di_mbuf != NULL) {
 1783             m_freem(di->di_mbuf);
 1784             di->di_mbuf = NULL;
 1785         }
 1786         desc.d_flag = 0;
 1787         desc.d_addr_lo = LN_ADDR_LO(ri->ri_heap + sc->lance_ramoffset);
 1788         desc.d_addr_hi = LN_ADDR_HI(ri->ri_heap + sc->lance_ramoffset);
 1789         desc.d_buflen = 0;
 1790         LN_PUTDESC(sc, &desc, di->di_addr);
 1791     }
 1792     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
 1793     ri->ri_free = ri->ri_max;
 1794     ri->ri_outptr = ri->ri_heap;
 1795     ri->ri_outsize = ri->ri_heapend - ri->ri_heap;
 1796 
 1797     ri = &sc->lance_rxinfo;
 1798     desc.d_flag = LN_DFLAG_OWNER;
 1799     desc.d_buflen = 0 - sc->lance_rxbufsize;
 1800     for (di = ri->ri_first; di < ri->ri_last; di++) {
 1801         desc.d_addr_lo = LN_ADDR_LO(di->di_bufaddr + sc->lance_ramoffset);
 1802         desc.d_addr_hi = LN_ADDR_HI(di->di_bufaddr + sc->lance_ramoffset);
 1803         LN_PUTDESC(sc, &desc, di->di_addr);
 1804     }
 1805     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
 1806     ri->ri_outptr = ri->ri_heap;
 1807     ri->ri_outsize = ri->ri_heapend - ri->ri_heap;
 1808     ri->ri_free = 0;
 1809 
 1810     if (sc->le_if.if_flags & IFF_UP) {
 1811         sc->le_if.if_flags |= IFF_RUNNING;
 1812         LN_WRCSR(sc, LN_CSR0_START|LN_CSR0_INITDONE|LN_CSR0_ENABINTR);
 1813         /* lance_dumpcsrs(sc, "lance_init: up"); */
 1814         lance_start(&sc->le_if);
 1815     } else {
 1816         /* lance_dumpcsrs(sc, "lance_init: down"); */
 1817         sc->le_if.if_flags &= ~IFF_RUNNING;
 1818     }
 1819 }
 1820 
 1821 static void
 1822 lance_intr(
 1823     le_softc_t *sc)
 1824 {
 1825     unsigned oldcsr;
 1826 
 1827     oldcsr = LN_RDCSR(sc);
 1828     oldcsr &= ~LN_CSR0_ENABINTR;
 1829     LN_WRCSR(sc, oldcsr);
 1830     LN_WRCSR(sc, LN_CSR0_ENABINTR);
 1831 
 1832     if (oldcsr & LN_CSR0_ERRSUM) {
 1833         if (oldcsr & LN_CSR0_MISS) {
 1834             /*
 1835              *  LN_CSR0_MISS is signaled when the LANCE receiver
 1836              *  loses a packet because it doesn't own a receive
 1837              *  descriptor. Rev. D LANCE chips, which are no
 1838              *  longer used, require a chip reset as described
 1839              *  below.
 1840              */
 1841             LN_STAT(rx_misses++);
 1842         }
 1843         if (oldcsr & LN_CSR0_MEMERROR) {
 1844             LN_STAT(memory_errors++);
 1845             if (oldcsr & (LN_CSR0_RXON|LN_CSR0_TXON)) {
 1846                 lance_init(sc->le_if.if_unit);
 1847                 return;
 1848             }
 1849         }
 1850     }
 1851 
 1852     if ((oldcsr & LN_CSR0_RXINT) && lance_rx_intr(sc)) {
 1853         lance_init(sc->le_if.if_unit);
 1854         return;
 1855     }
 1856 
 1857     if (oldcsr & LN_CSR0_TXINT) {
 1858         if (lance_tx_intr(sc))
 1859             lance_start(&sc->le_if);
 1860     }
 1861 
 1862     if (oldcsr == (LN_CSR0_PENDINTR|LN_CSR0_RXON|LN_CSR0_TXON))
 1863         printf("%s%d: lance_intr: stray interrupt\n",
 1864                sc->le_if.if_name, sc->le_if.if_unit);
 1865 }
 1866 
 1867 static int
 1868 lance_rx_intr(
 1869     le_softc_t *sc)
 1870 {
 1871     lance_ring_t *ri = &sc->lance_rxinfo;
 1872     lance_descinfo_t *eop;
 1873     ln_desc_t desc;
 1874     int ndescs, total_len, rxdescs;
 1875 
 1876     LN_STAT(rx_intrs++);
 1877 
 1878     for (rxdescs = 0;;) {
 1879         /*
 1880          * Now to try to find the end of this packet chain.
 1881          */
 1882         for (ndescs = 1, eop = ri->ri_nextin;; ndescs++) {
 1883             /*
 1884              * If we don't own this descriptor, the packet ain't
 1885              * all here so return because we are done.
 1886              */
 1887             LN_GETDESC(sc, &desc, eop->di_addr);
 1888             if (desc.d_flag & LN_DFLAG_OWNER)
 1889                 return 0;
 1890             /*
 1891              * In case we have missed a packet and gotten the
 1892              * LANCE confused, make sure we are pointing at the
 1893              * start of a packet. If we aren't, something is really
 1894              * strange so reinit the LANCE.
 1895              */
 1896             if (desc.d_flag & LN_DFLAG_RxBUFERROR) {
 1897                 LN_STAT(rx_buferror++);
 1898                 return 1;
 1899             }
 1900             if ((desc.d_flag & LN_DFLAG_SOP) && eop != ri->ri_nextin) {
 1901                 LN_STAT(rx_badsop++);
 1902                 return 1;
 1903             }
 1904             if (desc.d_flag & LN_DFLAG_EOP)
 1905                 break;
 1906             if (++eop == ri->ri_last)
 1907                 eop = ri->ri_first;
 1908         }
 1909 
 1910         total_len = (desc.d_status & LN_DSTS_RxLENMASK) - 4;
 1911         if ((desc.d_flag & LN_DFLAG_RxERRSUM) == 0) {
 1912             /*
 1913              * Valid Packet -- If the SOP is less than or equal to the EOP
 1914              * or the length is less than the receive buffer size, then the
 1915              * packet is contiguous in memory and can be copied in one shot.
 1916              * Otherwise we need to copy two segments to get the entire
 1917              * packet.
 1918              */
 1919             if (ri->ri_nextin <= eop || total_len <= ri->ri_heapend - ri->ri_nextin->di_bufaddr) {
 1920                 le_input(sc, sc->le_membase + ri->ri_nextin->di_bufaddr,
 1921                          total_len, total_len, NULL);
 1922                 LN_STAT(rx_contig++);
 1923             } else {
 1924                 le_input(sc, sc->le_membase + ri->ri_nextin->di_bufaddr,
 1925                          total_len,
 1926                          ri->ri_heapend - ri->ri_nextin->di_bufaddr,
 1927                          sc->le_membase + ri->ri_first->di_bufaddr);
 1928                 LN_STAT(rx_noncontig++);
 1929             }
 1930         } else {
 1931             /*
 1932              * If the packet is bad, increment the
 1933              * counters.
 1934              */
 1935             sc->le_if.if_ierrors++;
 1936             if (desc.d_flag & LN_DFLAG_RxBADCRC)
 1937                 LN_STAT(rx_badcrc++);
 1938             if (desc.d_flag & LN_DFLAG_RxOVERFLOW)
 1939                 LN_STAT(rx_badalign++);
 1940             if (desc.d_flag & LN_DFLAG_RxFRAMING)
 1941                 LN_STAT(rx_badframe++);
 1942         }
 1943         sc->le_if.if_ipackets++;
 1944         LN_STAT(rx_ndescs[ndescs-1]++);
 1945         rxdescs += ndescs;
 1946         while (ndescs-- > 0) {
 1947             LN_SETFLAG(sc, ri->ri_nextin->di_addr, LN_DFLAG_OWNER);
 1948             if (++ri->ri_nextin == ri->ri_last)
 1949                 ri->ri_nextin = ri->ri_first;
 1950         }
 1951     }
 1952     /* LN_STAT(rx_intr_descs[rxdescs]++); */
 1953     LN_MAXSTAT(rx_intr_hidescs, rxdescs);
 1954 
 1955     return 0;
 1956 }
 1957 
 1958 static void
 1959 lance_start(
 1960     struct ifnet *ifp)
 1961 {
 1962     le_softc_t *sc = (le_softc_t *) ifp;
 1963     struct ifqueue *ifq = &ifp->if_snd;
 1964     lance_ring_t *ri = &sc->lance_txinfo;
 1965     lance_descinfo_t *di;
 1966     ln_desc_t desc;
 1967     unsigned len, slop;
 1968     struct mbuf *m, *m0;
 1969     caddr_t bp;
 1970 
 1971     if ((ifp->if_flags & IFF_RUNNING) == 0)
 1972         return;
 1973 
 1974     for (;;) {
 1975         IF_DEQUEUE(ifq, m);
 1976         if (m == NULL)
 1977             break;
 1978 
 1979         /*
 1980          * Make the packet meets the minimum size for Ethernet.
 1981          * The slop is so that we also use an even number of longwards.
 1982          */
 1983         len = ETHERMIN + sizeof(struct ether_header);
 1984         if (m->m_pkthdr.len > len)
 1985             len = m->m_pkthdr.len;
 1986 
 1987         slop = (8 - len) & 3;
 1988         /*
 1989          * If there are no free ring entries (there must be always
 1990          * one owned by the host), or there's not enough space for
 1991          * this packet, or this packet would wrap around the end
 1992          * of LANCE RAM then wait for the transmits to empty for
 1993          * space and ring entries to become available.
 1994          */
 1995         if (ri->ri_free == 1 || len + slop > ri->ri_outsize) {
 1996             /*
 1997              * Try to see if we can free up anything off the transit ring.
 1998              */
 1999             if (lance_tx_intr(sc) > 0) {
 2000                 LN_STAT(tx_drains[0]++);
 2001                 IF_PREPEND(ifq, m);
 2002                 continue;
 2003             }
 2004             LN_STAT(tx_nospc[0]++);
 2005             break;
 2006         }
 2007 
 2008         if (len + slop > ri->ri_heapend - ri->ri_outptr) {
 2009             /*
 2010              * Since the packet won't fit in the end of the transmit
 2011              * heap, see if there is space at the beginning of the transmit
 2012              * heap.  If not, try again when there is space.
 2013              */
 2014             LN_STAT(tx_orphaned++);
 2015             slop += ri->ri_heapend - ri->ri_outptr;
 2016             if (len + slop > ri->ri_outsize) {
 2017                 LN_STAT(tx_nospc[1]++);
 2018                 break;
 2019             }
 2020             /*
 2021              * Point to the beginning of the heap
 2022              */
 2023             ri->ri_outptr = ri->ri_heap;
 2024             LN_STAT(tx_adoptions++);
 2025         }
 2026 
 2027         /*
 2028          * Initialize the descriptor (saving the buffer address,
 2029          * buffer length, and mbuf) and write the packet out
 2030          * to the board.
 2031          */
 2032         di = ri->ri_nextout;
 2033         di->di_bufaddr = ri->ri_outptr;
 2034         di->di_buflen = len + slop;
 2035         di->di_mbuf = m;
 2036         bp = sc->le_membase + di->di_bufaddr;
 2037         for (m0 = m; m0 != NULL; m0 = m0->m_next) {
 2038             LN_COPYTO(sc, mtod(m0, caddr_t), bp, m0->m_len);
 2039             bp += m0->m_len;
 2040         }
 2041         /*
 2042          * Zero out the remainder if needed (< ETHERMIN).
 2043          */
 2044         if (m->m_pkthdr.len < len)
 2045             LN_ZERO(sc, bp, len - m->m_pkthdr.len);
 2046 
 2047         /*
 2048          * Finally, copy out the descriptor and tell the
 2049          * LANCE to transmit!.
 2050          */
 2051         desc.d_buflen = 0 - len;
 2052         desc.d_addr_lo = LN_ADDR_LO(di->di_bufaddr + sc->lance_ramoffset);
 2053         desc.d_addr_hi = LN_ADDR_HI(di->di_bufaddr + sc->lance_ramoffset);
 2054         desc.d_flag = LN_DFLAG_SOP|LN_DFLAG_EOP|LN_DFLAG_OWNER;
 2055         LN_PUTDESC(sc, &desc, di->di_addr);
 2056         LN_WRCSR(sc, LN_CSR0_TXDEMAND|LN_CSR0_ENABINTR);
 2057 
 2058         /*
 2059          * Do our bookkeeping with our transmit heap.
 2060          * (if we wrap, point back to the beginning).
 2061          */
 2062         ri->ri_outptr += di->di_buflen;
 2063         ri->ri_outsize -= di->di_buflen;
 2064         LN_MAXSTAT(high_txoutptr, ri->ri_outptr);
 2065         LN_MINSTAT(low_txheapsize, ri->ri_outsize);
 2066 
 2067         if (ri->ri_outptr == ri->ri_heapend)
 2068             ri->ri_outptr = ri->ri_heap;
 2069 
 2070         ri->ri_free--;
 2071         if (++ri->ri_nextout == ri->ri_last)
 2072             ri->ri_nextout = ri->ri_first;
 2073         LN_MINSTAT(low_txfree, ri->ri_free);
 2074     }
 2075     if (m != NULL) {
 2076         ifp->if_flags |= IFF_OACTIVE;
 2077         IF_PREPEND(ifq, m);
 2078     }
 2079 }
 2080 
 2081 static int
 2082 lance_tx_intr(
 2083     le_softc_t *sc)
 2084 {
 2085     lance_ring_t *ri = &sc->lance_txinfo;
 2086     unsigned xmits;
 2087 
 2088     LN_STAT(tx_intrs++);
 2089     for (xmits = 0; ri->ri_free < ri->ri_max; ) {
 2090         ln_desc_t desc;
 2091 
 2092         LN_GETDESC(sc, &desc, ri->ri_nextin->di_addr);
 2093         if (desc.d_flag & LN_DFLAG_OWNER)
 2094             break;
 2095 
 2096         if (desc.d_flag & (LN_DFLAG_TxONECOLL|LN_DFLAG_TxMULTCOLL))
 2097             sc->le_if.if_collisions++;
 2098         if (desc.d_flag & LN_DFLAG_TxDEFERRED)
 2099             LN_STAT(tx_deferred++);
 2100         if (desc.d_flag & LN_DFLAG_TxONECOLL)
 2101             LN_STAT(tx_single_collisions++);
 2102         if (desc.d_flag & LN_DFLAG_TxMULTCOLL)
 2103             LN_STAT(tx_multiple_collisions++);
 2104 
 2105         if (desc.d_flag & LN_DFLAG_TxERRSUM) {
 2106             if (desc.d_status & (LN_DSTS_TxUNDERFLOW|LN_DSTS_TxBUFERROR|
 2107                                  LN_DSTS_TxEXCCOLL|LN_DSTS_TxLATECOLL)) {
 2108                 if (desc.d_status & LN_DSTS_TxEXCCOLL) {
 2109                     unsigned tdr;
 2110                     LN_STAT(tx_excessive_collisions++);
 2111                     if ((tdr = (desc.d_status & LN_DSTS_TxTDRMASK)) > 0) {
 2112                         tdr *= 100;
 2113                         printf("%s%d: lance: warning: excessive collisions: TDR %dns (%d-%dm)\n",
 2114                                sc->le_if.if_name, sc->le_if.if_unit,
 2115                                tdr, (tdr*99)/1000, (tdr*117)/1000);
 2116                     }
 2117                 }
 2118                 if (desc.d_status & LN_DSTS_TxBUFERROR)
 2119                     LN_STAT(tx_buferror++);
 2120                 sc->le_if.if_oerrors++;
 2121                 if ((desc.d_status & LN_DSTS_TxLATECOLL) == 0) {
 2122                     lance_init(sc->le_if.if_unit);
 2123                     return 0;
 2124                 } else {
 2125                     LN_STAT(tx_late_collisions++);
 2126                 }
 2127             }
 2128         }
 2129         m_freem(ri->ri_nextin->di_mbuf);
 2130         ri->ri_nextin->di_mbuf = NULL;
 2131         sc->le_if.if_opackets++;
 2132         ri->ri_free++;
 2133         ri->ri_outsize += ri->ri_nextin->di_buflen;
 2134         if (++ri->ri_nextin == ri->ri_last)
 2135             ri->ri_nextin = ri->ri_first;
 2136         sc->le_if.if_flags &= ~IFF_OACTIVE;
 2137         xmits++;
 2138     }
 2139     if (ri->ri_free == ri->ri_max)
 2140         LN_STAT(tx_emptied++);
 2141     /* LN_STAT(tx_intr_descs[xmits]++); */
 2142     LN_MAXSTAT(tx_intr_hidescs, xmits);
 2143     return xmits;
 2144 }
 2145 #endif /* !defined(LE_NOLANCE) */
 2146 #endif /* NLE > 0 */

Cache object: 6776edf690cc803b8a0a45d3e3bdaef6


[ 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.