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

Cache object: 0157e3cfbe5f56ab8f07fcdd559e9995


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