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/pci/if_de.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 /*      $NetBSD: if_de.c,v 1.55 1997/10/16 22:02:27 matt Exp $  */
    2 /* $FreeBSD: src/sys/pci/if_de.c,v 1.54.2.14 1999/09/05 08:21:01 peter Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. The name of the author may not be used to endorse or promote products
   14  *    derived from this software withough specific prior written permission
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * Id: if_de.c,v 1.94 1997/07/03 16:55:07 thomas Exp
   28  *
   29  */
   30 
   31 /*
   32  * DEC 21040 PCI Ethernet Controller
   33  *
   34  * Written by Matt Thomas
   35  * BPF support code stolen directly from if_ec.c
   36  *
   37  *   This driver supports the DEC DE435 or any other PCI
   38  *   board which support 21040, 21041, or 21140 (mostly).
   39  */
   40 #define TULIP_HDR_DATA
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/protosw.h>
   46 #include <sys/socket.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/errno.h>
   49 #include <sys/malloc.h>
   50 #include <sys/kernel.h>
   51 #include <sys/proc.h>   /* only for declaration of wakeup() used by vm.h */
   52 #if defined(__FreeBSD__)
   53 #include <machine/clock.h>
   54 #elif defined(__bsdi__) || defined(__NetBSD__)
   55 #include <sys/device.h>
   56 #endif
   57 
   58 #if defined(__NetBSD__)
   59 #include "rnd.h"
   60 #if NRND > 0
   61 #include <sys/rnd.h>
   62 #endif
   63 #endif
   64 
   65 #include <net/if.h>
   66 #if defined(SIOCSIFMEDIA) && !defined(TULIP_NOIFMEDIA)
   67 #include <net/if_media.h>
   68 #endif
   69 #include <net/if_types.h>
   70 #include <net/if_dl.h>
   71 #include <net/route.h>
   72 #include <net/netisr.h>
   73 
   74 #if defined(__bsdi__) && _BSDI_VERSION >= 199701
   75 #include <dev/mii/mii.h>
   76 #include <dev/mii/miivar.h>
   77 #endif
   78 
   79 #include "bpfilter.h"
   80 #if NBPFILTER > 0
   81 #include <net/bpf.h>
   82 #include <net/bpfdesc.h>
   83 #endif
   84 
   85 #ifdef INET
   86 #include <netinet/in.h>
   87 #include <netinet/in_systm.h>
   88 #include <netinet/in_var.h>
   89 #include <netinet/ip.h>
   90 #endif
   91 
   92 #ifdef IPX
   93 #include <netipx/ipx.h>
   94 #include <netipx/ipx_if.h>
   95 #endif
   96 
   97 #ifdef NS
   98 #include <netns/ns.h>
   99 #include <netns/ns_if.h>
  100 #endif
  101 
  102 #include <vm/vm.h>
  103 #include <vm/vm_param.h>
  104 #include <vm/vm_kern.h>
  105 
  106 #if defined(__FreeBSD__)
  107 #include <vm/pmap.h>
  108 #include <pci.h>
  109 #include <netinet/if_ether.h>
  110 #if NPCI > 0
  111 #include <pci/pcivar.h>
  112 #include <pci/dc21040reg.h>
  113 #define DEVAR_INCLUDE   "pci/if_devar.h"
  114 #endif
  115 
  116 #ifdef BRIDGE
  117 #include <net/bridge.h>
  118 #endif
  119 #endif /* __FreeBSD__ */
  120 
  121 #if defined(__bsdi__)
  122 #include <netinet/if_ether.h>
  123 #include <i386/pci/ic/dc21040reg.h>
  124 #include <i386/isa/isa.h>
  125 #include <i386/isa/icu.h>
  126 #include <i386/isa/dma.h>
  127 #include <i386/isa/isavar.h>
  128 #include <i386/pci/pci.h>
  129 #if _BSDI_VERSION < 199510
  130 #include <eisa.h>
  131 #else
  132 #define NEISA 0
  133 #endif
  134 #if NEISA > 0 && _BSDI_VERSION >= 199401
  135 #include <i386/eisa/eisa.h>
  136 #define TULIP_EISA
  137 #endif
  138 #define DEVAR_INCLUDE   "i386/pci/if_devar.h"
  139 #endif /* __bsdi__ */
  140 
  141 #if defined(__NetBSD__)
  142 #include <net/if_ether.h>
  143 #if defined(INET)
  144 #include <netinet/if_inarp.h>
  145 #endif
  146 #include <machine/bus.h>
  147 #if defined(__alpha__)
  148 #include <machine/intr.h>
  149 #endif
  150 #include <dev/pci/pcireg.h>
  151 #include <dev/pci/pcivar.h>
  152 #include <dev/ic/dc21040reg.h>
  153 #define DEVAR_INCLUDE   "dev/pci/if_devar.h"
  154 #endif /* __NetBSD__ */
  155 
  156 /*
  157  * Intel CPUs should use I/O mapped access.
  158  */
  159 #if defined(__i386__) || defined(TULIP_EISA)
  160 #define TULIP_IOMAPPED
  161 #endif
  162 
  163 #if 0
  164 /*
  165  * This turns on all sort of debugging stuff and make the
  166  * driver much larger.
  167  */
  168 #define TULIP_DEBUG
  169 #endif
  170 
  171 #if 0
  172 #define TULIP_PERFSTATS
  173 #endif
  174 
  175 #if 0
  176 #define TULIP_USE_SOFTINTR
  177 #endif
  178 
  179 #define TULIP_HZ        10
  180 
  181 #include DEVAR_INCLUDE
  182 /*
  183  * This module supports
  184  *      the DEC 21040 PCI Ethernet Controller.
  185  *      the DEC 21041 PCI Ethernet Controller.
  186  *      the DEC 21140 PCI Fast Ethernet Controller.
  187  */
  188 static void tulip_mii_autonegotiate(tulip_softc_t * const sc, const unsigned phyaddr);
  189 static tulip_intrfunc_t tulip_intr_shared(void *arg);
  190 static tulip_intrfunc_t tulip_intr_normal(void *arg);
  191 static void tulip_init(tulip_softc_t * const sc);
  192 static void tulip_reset(tulip_softc_t * const sc);
  193 static ifnet_ret_t tulip_ifstart_one(struct ifnet *ifp);
  194 static ifnet_ret_t tulip_ifstart(struct ifnet *ifp);
  195 static struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m);
  196 static void tulip_txput_setup(tulip_softc_t * const sc);
  197 static void tulip_rx_intr(tulip_softc_t * const sc);
  198 static void tulip_addr_filter(tulip_softc_t * const sc);
  199 static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);
  200 static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data);
  201 static int tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities);
  202 static tulip_media_t tulip_mii_phy_readspecific(tulip_softc_t * const sc);
  203 static int tulip_srom_decode(tulip_softc_t * const sc);
  204 #if defined(IFM_ETHER)
  205 static int tulip_ifmedia_change(struct ifnet * const ifp);
  206 static void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req);
  207 #endif
  208 /* static void tulip_21140_map_media(tulip_softc_t *sc); */
  209 
  210 static void
  211 tulip_timeout_callback(
  212     void *arg)
  213 {
  214     tulip_softc_t * const sc = arg;
  215     tulip_spl_t s = TULIP_RAISESPL();
  216 
  217     TULIP_PERFSTART(timeout)
  218 
  219     sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;
  220     sc->tulip_probe_timeout -= 1000 / TULIP_HZ;
  221     (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);
  222 
  223     TULIP_PERFEND(timeout);
  224     TULIP_RESTORESPL(s);
  225 }
  226 
  227 static void
  228 tulip_timeout(
  229     tulip_softc_t * const sc)
  230 {
  231     if (sc->tulip_flags & TULIP_TIMEOUTPENDING)
  232         return;
  233     sc->tulip_flags |= TULIP_TIMEOUTPENDING;
  234     timeout(tulip_timeout_callback, sc, (hz + TULIP_HZ / 2) / TULIP_HZ);
  235 }
  236 
  237 #if defined(TULIP_NEED_FASTTIMEOUT)
  238 static void
  239 tulip_fasttimeout_callback(
  240     void *arg)
  241 {
  242     tulip_softc_t * const sc = arg;
  243     tulip_spl_t s = TULIP_RAISESPL();
  244 
  245     sc->tulip_flags &= ~TULIP_FASTTIMEOUTPENDING;
  246     (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_FASTTIMER);
  247     TULIP_RESTORESPL(s);
  248 }
  249 
  250 static void
  251 tulip_fasttimeout(
  252     tulip_softc_t * const sc)
  253 {
  254     if (sc->tulip_flags & TULIP_FASTTIMEOUTPENDING)
  255         return;
  256     sc->tulip_flags |= TULIP_FASTTIMEOUTPENDING;
  257     timeout(tulip_fasttimeout_callback, sc, 1);
  258 }
  259 #endif
  260 
  261 static int
  262 tulip_txprobe(
  263     tulip_softc_t * const sc)
  264 {
  265     struct mbuf *m;
  266     /*
  267      * Before we are sure this is the right media we need
  268      * to send a small packet to make sure there's carrier.
  269      * Strangely, BNC and AUI will "see" receive data if
  270      * either is connected so the transmit is the only way
  271      * to verify the connectivity.
  272      */
  273     MGETHDR(m, M_DONTWAIT, MT_DATA);
  274     if (m == NULL)
  275         return 0;
  276     /*
  277      * Construct a LLC TEST message which will point to ourselves.
  278      */
  279     bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_dhost, 6);
  280     bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_shost, 6);
  281     mtod(m, struct ether_header *)->ether_type = htons(3);
  282     mtod(m, unsigned char *)[14] = 0;
  283     mtod(m, unsigned char *)[15] = 0;
  284     mtod(m, unsigned char *)[16] = 0xE3;        /* LLC Class1 TEST (no poll) */
  285     m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
  286     /*
  287      * send it!
  288      */
  289     sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
  290     sc->tulip_intrmask |= TULIP_STS_TXINTR;
  291     sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
  292     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
  293     TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
  294     if ((m = tulip_txput(sc, m)) != NULL)
  295         m_freem(m);
  296     sc->tulip_probe.probe_txprobes++;
  297     return 1;
  298 }
  299 
  300 #ifdef BIG_PACKET
  301 #define TULIP_SIAGEN_WATCHDOG   (sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)
  302 #else
  303 #define TULIP_SIAGEN_WATCHDOG   0
  304 #endif
  305 
  306 static void
  307 tulip_media_set(
  308     tulip_softc_t * const sc,
  309     tulip_media_t media)
  310 {
  311     const tulip_media_info_t *mi = sc->tulip_mediums[media];
  312 
  313     if (mi == NULL)
  314         return;
  315 
  316     /*
  317      * If we are switching media, make sure we don't think there's
  318      * any stale RX activity
  319      */
  320     sc->tulip_flags &= ~TULIP_RXACT;
  321     if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
  322         TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
  323         TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        mi->mi_sia_tx_rx);
  324         if (sc->tulip_features & TULIP_HAVE_SIAGP) {
  325             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
  326             DELAY(50);
  327             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
  328         } else {
  329             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
  330         }
  331         TULIP_CSR_WRITE(sc, csr_sia_connectivity, mi->mi_sia_connectivity);
  332     } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
  333 #define TULIP_GPR_CMDBITS       (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)
  334         /*
  335          * If the cmdmode bits don't match the currently operating mode,
  336          * set the cmdmode appropriately and reset the chip.
  337          */
  338         if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
  339             sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
  340             sc->tulip_cmdmode |= mi->mi_cmdmode;
  341             tulip_reset(sc);
  342         }
  343         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
  344         DELAY(10);
  345         TULIP_CSR_WRITE(sc, csr_gp, (u_int8_t) mi->mi_gpdata);
  346     } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
  347         /*
  348          * If the cmdmode bits don't match the currently operating mode,
  349          * set the cmdmode appropriately and reset the chip.
  350          */
  351         if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
  352             sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
  353             sc->tulip_cmdmode |= mi->mi_cmdmode;
  354             tulip_reset(sc);
  355         }
  356         TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol);
  357         TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata);
  358     } else if (mi->mi_type == TULIP_MEDIAINFO_MII
  359                && sc->tulip_probe_state != TULIP_PROBE_INACTIVE) {
  360         int idx;
  361         if (sc->tulip_features & TULIP_HAVE_SIAGP) {
  362             const u_int8_t *dp;
  363             dp = &sc->tulip_rombuf[mi->mi_reset_offset];
  364             for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) {
  365                 DELAY(10);
  366                 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
  367             }
  368             sc->tulip_phyaddr = mi->mi_phyaddr;
  369             dp = &sc->tulip_rombuf[mi->mi_gpr_offset];
  370             for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) {
  371                 DELAY(10);
  372                 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
  373             }
  374         } else {
  375             for (idx = 0; idx < mi->mi_reset_length; idx++) {
  376                 DELAY(10);
  377                 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]);
  378             }
  379             sc->tulip_phyaddr = mi->mi_phyaddr;
  380             for (idx = 0; idx < mi->mi_gpr_length; idx++) {
  381                 DELAY(10);
  382                 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]);
  383             }
  384         }
  385         if (sc->tulip_flags & TULIP_TRYNWAY) {
  386             tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
  387         } else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {
  388             u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL);
  389             data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE);
  390             sc->tulip_flags &= ~TULIP_DIDNWAY;
  391             if (TULIP_IS_MEDIA_FD(media))
  392                 data |= PHYCTL_FULL_DUPLEX;
  393             if (TULIP_IS_MEDIA_100MB(media))
  394                 data |= PHYCTL_SELECT_100MB;
  395             tulip_mii_writereg(sc, sc->tulip_phyaddr, PHYREG_CONTROL, data);
  396         }
  397     }
  398 }
  399 
  400 static void
  401 tulip_linkup(
  402     tulip_softc_t * const sc,
  403     tulip_media_t media)
  404 {
  405     if ((sc->tulip_flags & TULIP_LINKUP) == 0)
  406         sc->tulip_flags |= TULIP_PRINTLINKUP;
  407     sc->tulip_flags |= TULIP_LINKUP;
  408     sc->tulip_if.if_flags &= ~IFF_OACTIVE;
  409 #if 0 /* XXX how does with work with ifmedia? */
  410     if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {
  411         if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
  412             if (TULIP_CAN_MEDIA_FD(media)
  413                     && sc->tulip_mediums[TULIP_FD_MEDIA_OF(media)] != NULL)
  414                 media = TULIP_FD_MEDIA_OF(media);
  415         } else {
  416             if (TULIP_IS_MEDIA_FD(media)
  417                     && sc->tulip_mediums[TULIP_HD_MEDIA_OF(media)] != NULL)
  418                 media = TULIP_HD_MEDIA_OF(media);
  419         }
  420     }
  421 #endif
  422     if (sc->tulip_media != media) {
  423 #ifdef TULIP_DEBUG
  424         sc->tulip_dbg.dbg_last_media = sc->tulip_media;
  425 #endif
  426         sc->tulip_media = media;
  427         sc->tulip_flags |= TULIP_PRINTMEDIA;
  428         if (TULIP_IS_MEDIA_FD(sc->tulip_media)) {
  429             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
  430         } else if (sc->tulip_chipid != TULIP_21041 || (sc->tulip_flags & TULIP_DIDNWAY) == 0) {
  431             sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
  432         }
  433     }
  434     /*
  435      * We could set probe_timeout to 0 but setting to 3000 puts this
  436      * in one central place and the only matters is tulip_link is
  437      * followed by a tulip_timeout.  Therefore setting it should not
  438      * result in aberrant behavour.
  439      */
  440     sc->tulip_probe_timeout = 3000;
  441     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
  442     sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TRYNWAY);
  443     if (sc->tulip_flags & TULIP_INRESET) {
  444         tulip_media_set(sc, sc->tulip_media);
  445     } else if (sc->tulip_probe_media != sc->tulip_media) {
  446         /*
  447          * No reason to change media if we have the right media.
  448          */
  449         tulip_reset(sc);
  450     }
  451     tulip_init(sc);
  452 }
  453 
  454 static void
  455 tulip_media_print(
  456     tulip_softc_t * const sc)
  457 {
  458     if ((sc->tulip_flags & TULIP_LINKUP) == 0)
  459         return;
  460     if (sc->tulip_flags & TULIP_PRINTMEDIA) {
  461         printf(TULIP_PRINTF_FMT ": enabling %s port\n",
  462                TULIP_PRINTF_ARGS,
  463                tulip_mediums[sc->tulip_media]);
  464         sc->tulip_flags &= ~(TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
  465     } else if (sc->tulip_flags & TULIP_PRINTLINKUP) {
  466         printf(TULIP_PRINTF_FMT ": link up\n", TULIP_PRINTF_ARGS);
  467         sc->tulip_flags &= ~TULIP_PRINTLINKUP;
  468     }
  469 }
  470 
  471 #if defined(TULIP_DO_GPR_SENSE)
  472 static tulip_media_t
  473 tulip_21140_gpr_media_sense(
  474     tulip_softc_t * const sc)
  475 {
  476     tulip_media_t maybe_media = TULIP_MEDIA_UNKNOWN;
  477     tulip_media_t last_media = TULIP_MEDIA_UNKNOWN;
  478     tulip_media_t media;
  479 
  480     /*
  481      * If one of the media blocks contained a default media flag,
  482      * use that.
  483      */
  484     for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
  485         const tulip_media_info_t *mi;
  486         /*
  487          * Media is not supported (or is full-duplex).
  488          */
  489         if ((mi = sc->tulip_mediums[media]) == NULL || TULIP_IS_MEDIA_FD(media))
  490             continue;
  491         if (mi->mi_type != TULIP_MEDIAINFO_GPR)
  492             continue;
  493 
  494         /*
  495          * Remember the media is this is the "default" media.
  496          */
  497         if (mi->mi_default && maybe_media == TULIP_MEDIA_UNKNOWN)
  498             maybe_media = media;
  499 
  500         /*
  501          * No activity mask?  Can't see if it is active if there's no mask.
  502          */
  503         if (mi->mi_actmask == 0)
  504             continue;
  505 
  506         /*
  507          * Does the activity data match?
  508          */
  509         if ((TULIP_CSR_READ(sc, csr_gp) & mi->mi_actmask) != mi->mi_actdata)
  510             continue;
  511 
  512 #if defined(TULIP_DEBUG)
  513         printf(TULIP_PRINTF_FMT ": gpr_media_sense: %s: 0x%02x & 0x%02x == 0x%02x\n",
  514                TULIP_PRINTF_ARGS, tulip_mediums[media],
  515                TULIP_CSR_READ(sc, csr_gp) & 0xFF,
  516                mi->mi_actmask, mi->mi_actdata);
  517 #endif
  518         /*
  519          * It does!  If this is the first media we detected, then 
  520          * remember this media.  If isn't the first, then there were
  521          * multiple matches which we equate to no match (since we don't
  522          * which to select (if any).
  523          */
  524         if (last_media == TULIP_MEDIA_UNKNOWN) {
  525             last_media = media;
  526         } else if (last_media != media) {
  527             last_media = TULIP_MEDIA_UNKNOWN;
  528         }
  529     }
  530     return (last_media != TULIP_MEDIA_UNKNOWN) ? last_media : maybe_media;
  531 }
  532 #endif /* TULIP_DO_GPR_SENSE */
  533 
  534 static tulip_link_status_t
  535 tulip_media_link_monitor(
  536     tulip_softc_t * const sc)
  537 {
  538     const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media];
  539     tulip_link_status_t linkup = TULIP_LINK_DOWN;
  540 
  541     if (mi == NULL) {
  542 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
  543         panic("tulip_media_link_monitor: %s: botch at line %d\n",
  544               tulip_mediums[sc->tulip_media],__LINE__);
  545 #endif
  546         return TULIP_LINK_UNKNOWN;
  547     }
  548 
  549 
  550     /*
  551      * Have we seen some packets?  If so, the link must be good.
  552      */
  553     if ((sc->tulip_flags & (TULIP_RXACT|TULIP_LINKUP)) == (TULIP_RXACT|TULIP_LINKUP)) {
  554         sc->tulip_flags &= ~TULIP_RXACT;
  555         sc->tulip_probe_timeout = 3000;
  556         return TULIP_LINK_UP;
  557     }
  558 
  559     sc->tulip_flags &= ~TULIP_RXACT;
  560     if (mi->mi_type == TULIP_MEDIAINFO_MII) {
  561         u_int32_t status;
  562         /*
  563          * Read the PHY status register.
  564          */
  565         status = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS);
  566         if (status & PHYSTS_AUTONEG_DONE) {
  567             /*
  568              * If the PHY has completed autonegotiation, see the if the
  569              * remote systems abilities have changed.  If so, upgrade or
  570              * downgrade as appropriate.
  571              */
  572             u_int32_t abilities = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_AUTONEG_ABILITIES);
  573             abilities = (abilities << 6) & status;
  574             if (abilities != sc->tulip_abilities) {
  575 #if defined(TULIP_DEBUG)
  576                 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n",
  577                            TULIP_PRINTF_ARGS, sc->tulip_phyaddr,
  578                            sc->tulip_abilities, abilities);
  579 #endif
  580                 if (tulip_mii_map_abilities(sc, abilities)) {
  581                     tulip_linkup(sc, sc->tulip_probe_media);
  582                     return TULIP_LINK_UP;
  583                 }
  584                 /*
  585                  * if we had selected media because of autonegotiation,
  586                  * we need to probe for the new media.
  587                  */
  588                 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
  589                 if (sc->tulip_flags & TULIP_DIDNWAY)
  590                     return TULIP_LINK_DOWN;
  591             }
  592         }
  593         /*
  594          * The link is now up.  If was down, say its back up.
  595          */
  596         if ((status & (PHYSTS_LINK_UP|PHYSTS_REMOTE_FAULT)) == PHYSTS_LINK_UP)
  597             linkup = TULIP_LINK_UP;
  598     } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
  599         /*
  600          * No activity sensor?  Assume all's well.
  601          */
  602         if (mi->mi_actmask == 0)
  603             return TULIP_LINK_UNKNOWN;
  604         /*
  605          * Does the activity data match?
  606          */
  607         if ((TULIP_CSR_READ(sc, csr_gp) & mi->mi_actmask) == mi->mi_actdata)
  608             linkup = TULIP_LINK_UP;
  609     } else if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
  610         /*
  611          * Assume non TP ok for now.
  612          */
  613         if (!TULIP_IS_MEDIA_TP(sc->tulip_media))
  614             return TULIP_LINK_UNKNOWN;
  615         if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0)
  616             linkup = TULIP_LINK_UP;
  617 #if defined(TULIP_DEBUG)
  618         if (sc->tulip_probe_timeout <= 0)
  619             printf(TULIP_PRINTF_FMT ": sia status = 0x%08x\n", TULIP_PRINTF_ARGS, TULIP_CSR_READ(sc, csr_sia_status));
  620 #endif
  621     } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
  622         return TULIP_LINK_UNKNOWN;
  623     }
  624     /*
  625      * We will wait for 3 seconds until the link goes into suspect mode.
  626      */
  627     if (sc->tulip_flags & TULIP_LINKUP) {
  628         if (linkup == TULIP_LINK_UP)
  629             sc->tulip_probe_timeout = 3000;
  630         if (sc->tulip_probe_timeout > 0)
  631             return TULIP_LINK_UP;
  632 
  633         sc->tulip_flags &= ~TULIP_LINKUP;
  634         printf(TULIP_PRINTF_FMT ": link down: cable problem?\n", TULIP_PRINTF_ARGS);
  635     }
  636 #if defined(TULIP_DEBUG)
  637     sc->tulip_dbg.dbg_link_downed++;
  638 #endif
  639     return TULIP_LINK_DOWN;
  640 }
  641 
  642 static void
  643 tulip_media_poll(
  644     tulip_softc_t * const sc,
  645     tulip_mediapoll_event_t event)
  646 {
  647 #if defined(TULIP_DEBUG)
  648     sc->tulip_dbg.dbg_events[event]++;
  649 #endif
  650     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE
  651             && event == TULIP_MEDIAPOLL_TIMER) {
  652         switch (tulip_media_link_monitor(sc)) {
  653             case TULIP_LINK_DOWN: {
  654                 /*
  655                  * Link Monitor failed.  Probe for new media.
  656                  */
  657                 event = TULIP_MEDIAPOLL_LINKFAIL;
  658                 break;
  659             }
  660             case TULIP_LINK_UP: {
  661                 /*
  662                  * Check again soon.
  663                  */
  664                 tulip_timeout(sc);
  665                 return;
  666             }
  667             case TULIP_LINK_UNKNOWN: {
  668                 /*
  669                  * We can't tell so don't bother.
  670                  */
  671                 return;
  672             }
  673         }
  674     }
  675 
  676     if (event == TULIP_MEDIAPOLL_LINKFAIL) {
  677         if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE) {
  678             if (TULIP_DO_AUTOSENSE(sc)) {
  679 #if defined(TULIP_DEBUG)
  680                 sc->tulip_dbg.dbg_link_failures++;
  681 #endif
  682                 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
  683                 tulip_reset(sc);        /* restart probe */
  684             }
  685             return;
  686         }
  687 #if defined(TULIP_DEBUG)
  688         sc->tulip_dbg.dbg_link_pollintrs++;
  689 #endif
  690     }
  691 
  692     if (event == TULIP_MEDIAPOLL_START) {
  693         sc->tulip_if.if_flags |= IFF_OACTIVE;
  694         if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE)
  695             return;
  696         sc->tulip_probe_mediamask = 0;
  697         sc->tulip_probe_passes = 0;
  698 #if defined(TULIP_DEBUG)
  699         sc->tulip_dbg.dbg_media_probes++;
  700 #endif
  701         /*
  702          * If the SROM contained an explicit media to use, use it.
  703          */
  704         sc->tulip_cmdmode &= ~(TULIP_CMD_RXRUN|TULIP_CMD_FULLDUPLEX);
  705         sc->tulip_flags |= TULIP_TRYNWAY|TULIP_PROBE1STPASS;
  706         sc->tulip_flags &= ~(TULIP_DIDNWAY|TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
  707         /*
  708          * connidx is defaulted to a media_unknown type.
  709          */
  710         sc->tulip_probe_media = tulip_srom_conninfo[sc->tulip_connidx].sc_media;
  711         if (sc->tulip_probe_media != TULIP_MEDIA_UNKNOWN) {
  712             tulip_linkup(sc, sc->tulip_probe_media);
  713             tulip_timeout(sc);
  714             return;
  715         }
  716 
  717         if (sc->tulip_features & TULIP_HAVE_GPR) {
  718             sc->tulip_probe_state = TULIP_PROBE_GPRTEST;
  719             sc->tulip_probe_timeout = 2000;
  720         } else {
  721             sc->tulip_probe_media = TULIP_MEDIA_MAX;
  722             sc->tulip_probe_timeout = 0;
  723             sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
  724         }
  725     }
  726 
  727     /*
  728      * Ignore txprobe failures or spurious callbacks.
  729      */
  730     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED
  731             && sc->tulip_probe_state != TULIP_PROBE_MEDIATEST) {
  732         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
  733         return;
  734     }
  735 
  736     /*
  737      * If we really transmitted a packet, then that's the media we'll use.
  738      */
  739     if (event == TULIP_MEDIAPOLL_TXPROBE_OK || event == TULIP_MEDIAPOLL_LINKPASS) {
  740         if (event == TULIP_MEDIAPOLL_LINKPASS)
  741             sc->tulip_probe_media = TULIP_MEDIA_10BASET;
  742 #if defined(TULIP_DEBUG)
  743         else
  744             sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
  745 #endif
  746         tulip_linkup(sc, sc->tulip_probe_media);
  747         tulip_timeout(sc);
  748         return;
  749     }
  750 
  751     if (sc->tulip_probe_state == TULIP_PROBE_GPRTEST) {
  752 #if defined(TULIP_DO_GPR_SENSE)
  753         /*
  754          * Check for media via the general purpose register.
  755          *
  756          * Try to sense the media via the GPR.  If the same value
  757          * occurs 3 times in a row then just use that.
  758          */
  759         if (sc->tulip_probe_timeout > 0) {
  760             tulip_media_t new_probe_media = tulip_21140_gpr_media_sense(sc);
  761 #if defined(TULIP_DEBUG)
  762             printf(TULIP_PRINTF_FMT ": media_poll: gpr sensing = %s\n",
  763                    TULIP_PRINTF_ARGS, tulip_mediums[new_probe_media]);
  764 #endif
  765             if (new_probe_media != TULIP_MEDIA_UNKNOWN) {
  766                 if (new_probe_media == sc->tulip_probe_media) {
  767                     if (--sc->tulip_probe_count == 0)
  768                         tulip_linkup(sc, sc->tulip_probe_media);
  769                 } else {
  770                     sc->tulip_probe_count = 10;
  771                 }
  772             }
  773             sc->tulip_probe_media = new_probe_media;
  774             tulip_timeout(sc);
  775             return;
  776         }
  777 #endif /* TULIP_DO_GPR_SENSE */
  778         /*
  779          * Brute force.  We cycle through each of the media types
  780          * and try to transmit a packet.
  781          */
  782         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
  783         sc->tulip_probe_media = TULIP_MEDIA_MAX;
  784         sc->tulip_probe_timeout = 0;
  785         tulip_timeout(sc);
  786         return;
  787     }
  788 
  789     if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST
  790            && (sc->tulip_features & TULIP_HAVE_MII)) {
  791         tulip_media_t old_media = sc->tulip_probe_media;
  792         tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
  793         switch (sc->tulip_probe_state) {
  794             case TULIP_PROBE_FAILED:
  795             case TULIP_PROBE_MEDIATEST: {
  796                 /*
  797                  * Try the next media.
  798                  */
  799                 sc->tulip_probe_mediamask |= sc->tulip_mediums[sc->tulip_probe_media]->mi_mediamask;
  800                 sc->tulip_probe_timeout = 0;
  801 #ifdef notyet
  802                 if (sc->tulip_probe_state == TULIP_PROBE_FAILED)
  803                     break;
  804                 if (sc->tulip_probe_media != tulip_mii_phy_readspecific(sc))
  805                     break;
  806                 sc->tulip_probe_timeout = TULIP_IS_MEDIA_TP(sc->tulip_probe_media) ? 2500 : 300;
  807 #endif
  808                 break;
  809             }
  810             case TULIP_PROBE_PHYAUTONEG: {
  811                 return;
  812             }
  813             case TULIP_PROBE_INACTIVE: {
  814                 /*
  815                  * Only probe if we autonegotiated a media that hasn't failed.
  816                  */
  817                 sc->tulip_probe_timeout = 0;
  818                 if (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media)) {
  819                     sc->tulip_probe_media = old_media;
  820                     break;
  821                 }
  822                 tulip_linkup(sc, sc->tulip_probe_media);
  823                 tulip_timeout(sc);
  824                 return;
  825             }
  826             default: {
  827 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
  828                 panic("tulip_media_poll: botch at line %d\n", __LINE__);
  829 #endif
  830                 break;
  831             }
  832         }
  833     }
  834 
  835     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED) {
  836 #if defined(TULIP_DEBUG)
  837         sc->tulip_dbg.dbg_txprobes_failed[sc->tulip_probe_media]++;
  838 #endif
  839         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
  840         return;
  841     }
  842 
  843     /*
  844      * switch to another media if we tried this one enough.
  845      */
  846     if (/* event == TULIP_MEDIAPOLL_TXPROBE_FAILED || */ sc->tulip_probe_timeout <= 0) {
  847 #if defined(TULIP_DEBUG)
  848         if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
  849             printf(TULIP_PRINTF_FMT ": poll media unknown!\n",
  850                    TULIP_PRINTF_ARGS);
  851             sc->tulip_probe_media = TULIP_MEDIA_MAX;
  852         }
  853 #endif
  854         /*
  855          * Find the next media type to check for.  Full Duplex
  856          * types are not allowed.
  857          */
  858         do {
  859             sc->tulip_probe_media -= 1;
  860             if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
  861                 if (++sc->tulip_probe_passes == 3) {
  862                     printf(TULIP_PRINTF_FMT ": autosense failed: cable problem?\n",
  863                            TULIP_PRINTF_ARGS);
  864                     if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
  865                         sc->tulip_if.if_flags &= ~IFF_RUNNING;
  866                         sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
  867                         return;
  868                     }
  869                 }
  870                 sc->tulip_flags ^= TULIP_TRYNWAY;       /* XXX */
  871                 sc->tulip_probe_mediamask = 0;
  872                 sc->tulip_probe_media = TULIP_MEDIA_MAX - 1;
  873             }
  874         } while (sc->tulip_mediums[sc->tulip_probe_media] == NULL
  875                  || (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media))
  876                  || TULIP_IS_MEDIA_FD(sc->tulip_probe_media));
  877 
  878 #if defined(TULIP_DEBUG)
  879         printf(TULIP_PRINTF_FMT ": %s: probing %s\n", TULIP_PRINTF_ARGS,
  880                event == TULIP_MEDIAPOLL_TXPROBE_FAILED ? "txprobe failed" : "timeout",
  881                tulip_mediums[sc->tulip_probe_media]);
  882 #endif
  883         sc->tulip_probe_timeout = TULIP_IS_MEDIA_TP(sc->tulip_probe_media) ? 2500 : 1000;
  884         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
  885         sc->tulip_probe.probe_txprobes = 0;
  886         tulip_reset(sc);
  887         tulip_media_set(sc, sc->tulip_probe_media);
  888         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
  889     }
  890     tulip_timeout(sc);
  891 
  892     /*
  893      * If this is hanging off a phy, we know are doing NWAY and we have
  894      * forced the phy to a specific speed.  Wait for link up before
  895      * before sending a packet.
  896      */
  897     switch (sc->tulip_mediums[sc->tulip_probe_media]->mi_type) {
  898         case TULIP_MEDIAINFO_MII: {
  899             if (sc->tulip_probe_media != tulip_mii_phy_readspecific(sc))
  900                 return;
  901             break;
  902         }
  903         case TULIP_MEDIAINFO_SIA: {
  904             if (TULIP_IS_MEDIA_TP(sc->tulip_probe_media)) {
  905                 if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL)
  906                     return;
  907                 tulip_linkup(sc, sc->tulip_probe_media);
  908 #ifdef notyet
  909                 if (sc->tulip_features & TULIP_HAVE_MII)
  910                     tulip_timeout(sc);
  911 #endif
  912                 return;
  913             }
  914             break;
  915         }
  916         case TULIP_MEDIAINFO_RESET:
  917         case TULIP_MEDIAINFO_SYM:
  918         case TULIP_MEDIAINFO_NONE:
  919         case TULIP_MEDIAINFO_GPR: {
  920             break;
  921         }
  922     }
  923     /*
  924      * Try to send a packet.
  925      */
  926     tulip_txprobe(sc);
  927 }
  928 
  929 static void
  930 tulip_media_select(
  931     tulip_softc_t * const sc)
  932 {
  933     if (sc->tulip_features & TULIP_HAVE_GPR) {
  934         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
  935         DELAY(10);
  936         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpdata);
  937     }
  938     /*
  939      * If this board has no media, just return
  940      */
  941     if (sc->tulip_features & TULIP_HAVE_NOMEDIA)
  942         return;
  943 
  944     if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
  945         TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
  946         (*sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_START);
  947     } else {
  948         tulip_media_set(sc, sc->tulip_media);
  949     }
  950 }
  951 
  952 static void
  953 tulip_21040_mediainfo_init(
  954     tulip_softc_t * const sc,
  955     tulip_media_t media)
  956 {
  957     sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
  958         |TULIP_CMD_BACKOFFCTR;
  959     sc->tulip_if.if_baudrate = 10000000;
  960 
  961     if (media == TULIP_MEDIA_10BASET || media == TULIP_MEDIA_UNKNOWN) {
  962         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[0], 21040, 10BASET);
  963         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[1], 21040, 10BASET_FD);
  964     }
  965 
  966     if (media == TULIP_MEDIA_AUIBNC || media == TULIP_MEDIA_UNKNOWN) {
  967         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[2], 21040, AUIBNC);
  968     }
  969 
  970     if (media == TULIP_MEDIA_UNKNOWN) {
  971         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[3], 21040, EXTSIA);
  972     }
  973 }
  974 
  975 static void
  976 tulip_21040_media_probe(
  977     tulip_softc_t * const sc)
  978 {
  979     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN);
  980     return;
  981 }
  982 
  983 static void
  984 tulip_21040_10baset_only_media_probe(
  985     tulip_softc_t * const sc)
  986 {
  987     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET);
  988     tulip_media_set(sc, TULIP_MEDIA_10BASET);
  989     sc->tulip_media = TULIP_MEDIA_10BASET;
  990 }
  991 
  992 static void
  993 tulip_21040_10baset_only_media_select(
  994     tulip_softc_t * const sc)
  995 {
  996     sc->tulip_flags |= TULIP_LINKUP;
  997     if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) {
  998         sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
  999         sc->tulip_flags &= ~TULIP_SQETEST;
 1000     } else {
 1001         sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
 1002         sc->tulip_flags |= TULIP_SQETEST;
 1003     }
 1004     tulip_media_set(sc, sc->tulip_media);
 1005 }
 1006 
 1007 static void
 1008 tulip_21040_auibnc_only_media_probe(
 1009     tulip_softc_t * const sc)
 1010 {
 1011     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC);
 1012     sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
 1013     tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
 1014     sc->tulip_media = TULIP_MEDIA_AUIBNC;
 1015 }
 1016 
 1017 static void
 1018 tulip_21040_auibnc_only_media_select(
 1019     tulip_softc_t * const sc)
 1020 {
 1021     tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
 1022     sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
 1023 }
 1024 
 1025 static const tulip_boardsw_t tulip_21040_boardsw = {
 1026     TULIP_21040_GENERIC,
 1027     tulip_21040_media_probe,
 1028     tulip_media_select,
 1029     tulip_media_poll,
 1030 };
 1031 
 1032 static const tulip_boardsw_t tulip_21040_10baset_only_boardsw = {
 1033     TULIP_21040_GENERIC,
 1034     tulip_21040_10baset_only_media_probe,
 1035     tulip_21040_10baset_only_media_select,
 1036     NULL,
 1037 };
 1038 
 1039 static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw = {
 1040     TULIP_21040_GENERIC,
 1041     tulip_21040_auibnc_only_media_probe,
 1042     tulip_21040_auibnc_only_media_select,
 1043     NULL,
 1044 };
 1045 
 1046 static void
 1047 tulip_21041_mediainfo_init(
 1048     tulip_softc_t * const sc)
 1049 {
 1050     tulip_media_info_t * const mi = sc->tulip_mediainfo;
 1051 
 1052 #ifdef notyet
 1053     if (sc->tulip_revinfo >= 0x20) {
 1054         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, 10BASET);
 1055         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041P2, 10BASET_FD);
 1056         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, AUI);
 1057         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041P2, BNC);
 1058         return;
 1059     }
 1060 #endif
 1061     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041, 10BASET);
 1062     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041, 10BASET_FD);
 1063     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[2], 21041, AUI);
 1064     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[3], 21041, BNC);
 1065 }
 1066 
 1067 static void
 1068 tulip_21041_media_probe(
 1069     tulip_softc_t * const sc)
 1070 {
 1071     sc->tulip_if.if_baudrate = 10000000;
 1072     sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
 1073         |TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
 1074     sc->tulip_intrmask |= TULIP_STS_LINKPASS;
 1075     tulip_21041_mediainfo_init(sc);
 1076 }
 1077 
 1078 static void
 1079 tulip_21041_media_poll(
 1080     tulip_softc_t * const sc,
 1081     const tulip_mediapoll_event_t event)
 1082 {
 1083     u_int32_t sia_status;
 1084 
 1085 #if defined(TULIP_DEBUG)
 1086     sc->tulip_dbg.dbg_events[event]++;
 1087 #endif
 1088 
 1089     if (event == TULIP_MEDIAPOLL_LINKFAIL) {
 1090         if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE
 1091                 || !TULIP_DO_AUTOSENSE(sc))
 1092             return;
 1093         sc->tulip_media = TULIP_MEDIA_UNKNOWN;
 1094         tulip_reset(sc);        /* start probe */
 1095         return;
 1096     }
 1097 
 1098     /*
 1099      * If we've been been asked to start a poll or link change interrupt
 1100      * restart the probe (and reset the tulip to a known state).
 1101      */
 1102     if (event == TULIP_MEDIAPOLL_START) {
 1103         sc->tulip_if.if_flags |= IFF_OACTIVE;
 1104         sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_RXRUN);
 1105 #ifdef notyet
 1106         if (sc->tulip_revinfo >= 0x20) {
 1107             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
 1108             sc->tulip_flags |= TULIP_DIDNWAY;
 1109         }
 1110 #endif
 1111         TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 1112         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
 1113         sc->tulip_probe_media = TULIP_MEDIA_10BASET;
 1114         sc->tulip_probe_timeout = TULIP_21041_PROBE_10BASET_TIMEOUT;
 1115         tulip_media_set(sc, TULIP_MEDIA_10BASET);
 1116         tulip_timeout(sc);
 1117         return;
 1118     }
 1119 
 1120     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
 1121         return;
 1122 
 1123     if (event == TULIP_MEDIAPOLL_TXPROBE_OK) {
 1124 #if defined(TULIP_DEBUG)
 1125         sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
 1126 #endif
 1127         tulip_linkup(sc, sc->tulip_probe_media);
 1128         return;
 1129     }
 1130 
 1131     sia_status = TULIP_CSR_READ(sc, csr_sia_status);
 1132     TULIP_CSR_WRITE(sc, csr_sia_status, sia_status);
 1133     if ((sia_status & TULIP_SIASTS_LINKFAIL) == 0) {
 1134         if (sc->tulip_revinfo >= 0x20) {
 1135             if (sia_status & (PHYSTS_10BASET_FD << (16 - 6)))
 1136                 sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
 1137         }
 1138         /*
 1139          * If the link has passed LinkPass, 10baseT is the
 1140          * proper media to use.
 1141          */
 1142         tulip_linkup(sc, sc->tulip_probe_media);
 1143         return;
 1144     }
 1145 
 1146     /*
 1147      * wait for up to 2.4 seconds for the link to reach pass state.
 1148      * Only then start scanning the other media for activity.
 1149      * choose media with receive activity over those without.
 1150      */
 1151     if (sc->tulip_probe_media == TULIP_MEDIA_10BASET) {
 1152         if (event != TULIP_MEDIAPOLL_TIMER)
 1153             return;
 1154         if (sc->tulip_probe_timeout > 0
 1155                 && (sia_status & TULIP_SIASTS_OTHERRXACTIVITY) == 0) {
 1156             tulip_timeout(sc);
 1157             return;
 1158         }
 1159         sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
 1160         sc->tulip_flags |= TULIP_WANTRXACT;
 1161         if (sia_status & TULIP_SIASTS_OTHERRXACTIVITY) {
 1162             sc->tulip_probe_media = TULIP_MEDIA_BNC;
 1163         } else {
 1164             sc->tulip_probe_media = TULIP_MEDIA_AUI;
 1165         }
 1166         tulip_media_set(sc, sc->tulip_probe_media);
 1167         tulip_timeout(sc);
 1168         return;
 1169     }
 1170 
 1171     /*
 1172      * If we failed, clear the txprobe active flag.
 1173      */
 1174     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED)
 1175         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
 1176 
 1177 
 1178     if (event == TULIP_MEDIAPOLL_TIMER) {
 1179         /*
 1180          * If we've received something, then that's our link!
 1181          */
 1182         if (sc->tulip_flags & TULIP_RXACT) {
 1183             tulip_linkup(sc, sc->tulip_probe_media);
 1184             return;
 1185         }
 1186         /*
 1187          * if no txprobe active  
 1188          */
 1189         if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0
 1190                 && ((sc->tulip_flags & TULIP_WANTRXACT) == 0
 1191                     || (sia_status & TULIP_SIASTS_RXACTIVITY))) {
 1192             sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
 1193             tulip_txprobe(sc);
 1194             tulip_timeout(sc);
 1195             return;
 1196         }
 1197         /*
 1198          * Take 2 passes through before deciding to not
 1199          * wait for receive activity.  Then take another
 1200          * two passes before spitting out a warning.
 1201          */
 1202         if (sc->tulip_probe_timeout <= 0) {
 1203             if (sc->tulip_flags & TULIP_WANTRXACT) {
 1204                 sc->tulip_flags &= ~TULIP_WANTRXACT;
 1205                 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
 1206             } else {
 1207                 printf(TULIP_PRINTF_FMT ": autosense failed: cable problem?\n",
 1208                        TULIP_PRINTF_ARGS);
 1209                 if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
 1210                     sc->tulip_if.if_flags &= ~IFF_RUNNING;
 1211                     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
 1212                     return;
 1213                 }
 1214             }
 1215         }
 1216     }
 1217     
 1218     /*
 1219      * Since this media failed to probe, try the other one.
 1220      */
 1221     sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
 1222     if (sc->tulip_probe_media == TULIP_MEDIA_AUI) {
 1223         sc->tulip_probe_media = TULIP_MEDIA_BNC;
 1224     } else {
 1225         sc->tulip_probe_media = TULIP_MEDIA_AUI;
 1226     }
 1227     tulip_media_set(sc, sc->tulip_probe_media);
 1228     sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
 1229     tulip_timeout(sc);
 1230 }
 1231 
 1232 static const tulip_boardsw_t tulip_21041_boardsw = {
 1233     TULIP_21041_GENERIC,
 1234     tulip_21041_media_probe,
 1235     tulip_media_select,
 1236     tulip_21041_media_poll
 1237 };
 1238 
 1239 static const tulip_phy_attr_t tulip_mii_phy_attrlist[] = {
 1240     { 0x20005c00, 0,            /* 08-00-17 */
 1241       {
 1242         { 0x19, 0x0040, 0x0040 },       /* 10TX */
 1243         { 0x19, 0x0040, 0x0000 },       /* 100TX */
 1244       },
 1245 #if defined(TULIP_DEBUG)
 1246       "NS DP83840",
 1247 #endif
 1248     },
 1249     { 0x0281F400, 0,            /* 00-A0-7D */
 1250       {
 1251         { 0x12, 0x0010, 0x0000 },       /* 10T */
 1252         { },                            /* 100TX */
 1253         { 0x12, 0x0010, 0x0010 },       /* 100T4 */
 1254         { 0x12, 0x0008, 0x0008 },       /* FULL_DUPLEX */
 1255       },
 1256 #if defined(TULIP_DEBUG)
 1257       "Seeq 80C240"
 1258 #endif
 1259     },
 1260 #if 0
 1261     { 0x0015F420, 0,    /* 00-A0-7D */
 1262       {
 1263         { 0x12, 0x0010, 0x0000 },       /* 10T */
 1264         { },                            /* 100TX */
 1265         { 0x12, 0x0010, 0x0010 },       /* 100T4 */
 1266         { 0x12, 0x0008, 0x0008 },       /* FULL_DUPLEX */
 1267       },
 1268 #if defined(TULIP_DEBUG)
 1269       "Broadcom BCM5000"
 1270 #endif
 1271     },
 1272 #endif
 1273     { 0x0281F400, 0,            /* 00-A0-BE */
 1274       {
 1275         { 0x11, 0x8000, 0x0000 },       /* 10T */
 1276         { 0x11, 0x8000, 0x8000 },       /* 100TX */
 1277         { },                            /* 100T4 */
 1278         { 0x11, 0x4000, 0x4000 },       /* FULL_DUPLEX */
 1279       },
 1280 #if defined(TULIP_DEBUG)
 1281       "ICS 1890"
 1282 #endif 
 1283     },
 1284     { 0 }
 1285 };
 1286 
 1287 static tulip_media_t
 1288 tulip_mii_phy_readspecific(
 1289     tulip_softc_t * const sc)
 1290 {
 1291     const tulip_phy_attr_t *attr;
 1292     u_int16_t data;
 1293     u_int32_t id;
 1294     unsigned idx = 0;
 1295     static const tulip_media_t table[] = {
 1296         TULIP_MEDIA_UNKNOWN,
 1297         TULIP_MEDIA_10BASET,
 1298         TULIP_MEDIA_100BASETX,
 1299         TULIP_MEDIA_100BASET4,
 1300         TULIP_MEDIA_UNKNOWN,
 1301         TULIP_MEDIA_10BASET_FD,
 1302         TULIP_MEDIA_100BASETX_FD,
 1303         TULIP_MEDIA_UNKNOWN
 1304     };
 1305 
 1306     /*
 1307      * Don't read phy specific registers if link is not up.
 1308      */
 1309     data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS);
 1310     if ((data & (PHYSTS_LINK_UP|PHYSTS_EXTENDED_REGS)) != (PHYSTS_LINK_UP|PHYSTS_EXTENDED_REGS))
 1311         return TULIP_MEDIA_UNKNOWN;
 1312 
 1313     id = (tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_IDLOW) << 16) |
 1314         tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_IDHIGH);
 1315     for (attr = tulip_mii_phy_attrlist;; attr++) {
 1316         if (attr->attr_id == 0)
 1317             return TULIP_MEDIA_UNKNOWN;
 1318         if ((id & ~0x0F) == attr->attr_id)
 1319             break;
 1320     }
 1321 
 1322     if (attr->attr_modes[PHY_MODE_100TX].pm_regno) {
 1323         const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100TX];
 1324         data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
 1325         if ((data & pm->pm_mask) == pm->pm_value)
 1326             idx = 2;
 1327     }
 1328     if (idx == 0 && attr->attr_modes[PHY_MODE_100T4].pm_regno) {
 1329         const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100T4];
 1330         data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
 1331         if ((data & pm->pm_mask) == pm->pm_value)
 1332             idx = 3;
 1333     }
 1334     if (idx == 0 && attr->attr_modes[PHY_MODE_10T].pm_regno) {
 1335         const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_10T];
 1336         data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
 1337         if ((data & pm->pm_mask) == pm->pm_value)
 1338             idx = 1;
 1339     } 
 1340     if (idx != 0 && attr->attr_modes[PHY_MODE_FULLDUPLEX].pm_regno) {
 1341         const tulip_phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_FULLDUPLEX];
 1342         data = tulip_mii_readreg(sc, sc->tulip_phyaddr, pm->pm_regno);
 1343         idx += ((data & pm->pm_mask) == pm->pm_value ? 4 : 0);
 1344     }
 1345     return table[idx];
 1346 }
 1347 
 1348 static unsigned
 1349 tulip_mii_get_phyaddr(
 1350     tulip_softc_t * const sc,
 1351     unsigned offset)
 1352 {
 1353     unsigned phyaddr;
 1354 
 1355     for (phyaddr = 1; phyaddr < 32; phyaddr++) {
 1356         unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
 1357         if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
 1358             continue;
 1359         if (offset == 0)
 1360             return phyaddr;
 1361         offset--;
 1362     }
 1363     if (offset == 0) {
 1364         unsigned status = tulip_mii_readreg(sc, 0, PHYREG_STATUS);
 1365         if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
 1366             return TULIP_MII_NOPHY;
 1367         return 0;
 1368     }
 1369     return TULIP_MII_NOPHY;
 1370 }
 1371 
 1372 static int
 1373 tulip_mii_map_abilities(
 1374     tulip_softc_t * const sc,
 1375     unsigned abilities)
 1376 {
 1377     sc->tulip_abilities = abilities;
 1378     if (abilities & PHYSTS_100BASETX_FD) {
 1379         sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD;
 1380     } else if (abilities & PHYSTS_100BASET4) {
 1381         sc->tulip_probe_media = TULIP_MEDIA_100BASET4;
 1382     } else if (abilities & PHYSTS_100BASETX) {
 1383         sc->tulip_probe_media = TULIP_MEDIA_100BASETX;
 1384     } else if (abilities & PHYSTS_10BASET_FD) {
 1385         sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
 1386     } else if (abilities & PHYSTS_10BASET) {
 1387         sc->tulip_probe_media = TULIP_MEDIA_10BASET;
 1388     } else {
 1389         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
 1390         return 0;
 1391     }
 1392     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
 1393     return 1;
 1394 }
 1395 
 1396 static void
 1397 tulip_mii_autonegotiate(
 1398     tulip_softc_t * const sc,
 1399     const unsigned phyaddr)
 1400 {
 1401     switch (sc->tulip_probe_state) {
 1402         case TULIP_PROBE_MEDIATEST:
 1403         case TULIP_PROBE_INACTIVE: {
 1404             sc->tulip_flags |= TULIP_DIDNWAY;
 1405             tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, PHYCTL_RESET);
 1406             sc->tulip_probe_timeout = 3000;
 1407             sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_NORMALINTR;
 1408             sc->tulip_probe_state = TULIP_PROBE_PHYRESET;
 1409             /* FALL THROUGH */
 1410         }
 1411         case TULIP_PROBE_PHYRESET: {
 1412             u_int32_t status;
 1413             u_int32_t data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
 1414             if (data & PHYCTL_RESET) {
 1415                 if (sc->tulip_probe_timeout > 0) {
 1416                     tulip_timeout(sc);
 1417                     return;
 1418                 }
 1419                 printf(TULIP_PRINTF_FMT "(phy%d): error: reset of PHY never completed!\n",
 1420                            TULIP_PRINTF_ARGS, phyaddr);
 1421                 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
 1422                 sc->tulip_probe_state = TULIP_PROBE_FAILED;
 1423                 sc->tulip_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
 1424                 return;
 1425             }
 1426             status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
 1427             if ((status & PHYSTS_CAN_AUTONEG) == 0) {
 1428 #if defined(TULIP_DEBUG)
 1429                 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation disabled\n",
 1430                            TULIP_PRINTF_ARGS, phyaddr);
 1431 #endif
 1432                 sc->tulip_flags &= ~TULIP_DIDNWAY;
 1433                 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
 1434                 return;
 1435             }
 1436             if (tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT) != ((status >> 6) | 0x01))
 1437                 tulip_mii_writereg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT, (status >> 6) | 0x01);
 1438             tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, data|PHYCTL_AUTONEG_RESTART|PHYCTL_AUTONEG_ENABLE);
 1439             data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
 1440 #if defined(TULIP_DEBUG)
 1441             if ((data & PHYCTL_AUTONEG_ENABLE) == 0)
 1442                 loudprintf(TULIP_PRINTF_FMT "(phy%d): oops: enable autonegotiation failed: 0x%04x\n",
 1443                            TULIP_PRINTF_ARGS, phyaddr, data);
 1444             else
 1445                 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation restarted: 0x%04x\n",
 1446                            TULIP_PRINTF_ARGS, phyaddr, data);
 1447             sc->tulip_dbg.dbg_nway_starts++;
 1448 #endif
 1449             sc->tulip_probe_state = TULIP_PROBE_PHYAUTONEG;
 1450             sc->tulip_probe_timeout = 3000;
 1451             /* FALL THROUGH */
 1452         }
 1453         case TULIP_PROBE_PHYAUTONEG: {
 1454             u_int32_t status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
 1455             u_int32_t data;
 1456             if ((status & PHYSTS_AUTONEG_DONE) == 0) {
 1457                 if (sc->tulip_probe_timeout > 0) {
 1458                     tulip_timeout(sc);
 1459                     return;
 1460                 }
 1461 #if defined(TULIP_DEBUG)
 1462                 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n",
 1463                            TULIP_PRINTF_ARGS, phyaddr, status,
 1464                            tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL));
 1465 #endif
 1466                 sc->tulip_flags &= ~TULIP_DIDNWAY;
 1467                 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
 1468                 return;
 1469             }
 1470             data = tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ABILITIES);
 1471 #if defined(TULIP_DEBUG)
 1472             loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation complete: 0x%04x\n",
 1473                        TULIP_PRINTF_ARGS, phyaddr, data);
 1474 #endif
 1475             data = (data << 6) & status;
 1476             if (!tulip_mii_map_abilities(sc, data))
 1477                 sc->tulip_flags &= ~TULIP_DIDNWAY;
 1478             return;
 1479         }
 1480         default: {
 1481 #if defined(DIAGNOSTIC)
 1482             panic("tulip_media_poll: botch at line %d\n", __LINE__);
 1483 #endif
 1484             break;
 1485         }
 1486     }
 1487 #if defined(TULIP_DEBUG)
 1488     loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation failure: state = %d\n",
 1489                TULIP_PRINTF_ARGS, phyaddr, sc->tulip_probe_state);
 1490             sc->tulip_dbg.dbg_nway_failures++;
 1491 #endif
 1492 }
 1493 
 1494 static void
 1495 tulip_2114x_media_preset(
 1496     tulip_softc_t * const sc)
 1497 {
 1498     const tulip_media_info_t *mi = NULL;
 1499     tulip_media_t media = sc->tulip_media;
 1500 
 1501     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
 1502         media = sc->tulip_media;
 1503     else
 1504         media = sc->tulip_probe_media;
 1505     
 1506     sc->tulip_cmdmode &= ~TULIP_CMD_PORTSELECT;
 1507     sc->tulip_flags &= ~TULIP_SQETEST;
 1508     if (media != TULIP_MEDIA_UNKNOWN && media != TULIP_MEDIA_MAX) {
 1509 #if defined(TULIP_DEBUG)
 1510         if (media < TULIP_MEDIA_MAX && sc->tulip_mediums[media] != NULL) {
 1511 #endif
 1512             mi = sc->tulip_mediums[media];
 1513             if (mi->mi_type == TULIP_MEDIAINFO_MII) {
 1514                 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
 1515             } else if (mi->mi_type == TULIP_MEDIAINFO_GPR
 1516                        || mi->mi_type == TULIP_MEDIAINFO_SYM) {
 1517                 sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
 1518                 sc->tulip_cmdmode |= mi->mi_cmdmode;
 1519             } else if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
 1520                 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
 1521             }
 1522 #if defined(TULIP_DEBUG)
 1523         } else {
 1524             printf(TULIP_PRINTF_FMT ": preset: bad media %d!\n",
 1525                    TULIP_PRINTF_ARGS, media);
 1526         }
 1527 #endif
 1528     }
 1529     switch (media) {
 1530         case TULIP_MEDIA_BNC:
 1531         case TULIP_MEDIA_AUI:
 1532         case TULIP_MEDIA_10BASET: {
 1533             sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
 1534             sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
 1535             sc->tulip_if.if_baudrate = 10000000;
 1536             sc->tulip_flags |= TULIP_SQETEST;
 1537             break;
 1538         }
 1539         case TULIP_MEDIA_10BASET_FD: {
 1540             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL;
 1541             sc->tulip_if.if_baudrate = 10000000;
 1542             break;
 1543         }
 1544         case TULIP_MEDIA_100BASEFX:
 1545         case TULIP_MEDIA_100BASET4:
 1546         case TULIP_MEDIA_100BASETX: {
 1547             sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL);
 1548             sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
 1549             sc->tulip_if.if_baudrate = 100000000;
 1550             break;
 1551         }
 1552         case TULIP_MEDIA_100BASEFX_FD:
 1553         case TULIP_MEDIA_100BASETX_FD: {
 1554             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_PORTSELECT;
 1555             sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
 1556             sc->tulip_if.if_baudrate = 100000000;
 1557             break;
 1558         }
 1559         default: {
 1560             break;
 1561         }
 1562     }
 1563     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 1564 }
 1565 
 1566 /*
 1567  ********************************************************************
 1568  *  Start of 21140/21140A support which does not use the MII interface 
 1569  */
 1570 
 1571 static void
 1572 tulip_null_media_poll(
 1573     tulip_softc_t * const sc,
 1574     tulip_mediapoll_event_t event)
 1575 {
 1576 #if defined(TULIP_DEBUG)
 1577     sc->tulip_dbg.dbg_events[event]++;
 1578 #endif
 1579 #if defined(DIAGNOSTIC)
 1580     printf(TULIP_PRINTF_FMT ": botch(media_poll) at line %d\n",
 1581            TULIP_PRINTF_ARGS, __LINE__);
 1582 #endif
 1583 }
 1584 
 1585 __inline__ static void
 1586 tulip_21140_mediainit(
 1587     tulip_softc_t * const sc,
 1588     tulip_media_info_t * const mip,
 1589     tulip_media_t const media,
 1590     unsigned gpdata,
 1591     unsigned cmdmode)
 1592 {
 1593     sc->tulip_mediums[media] = mip;
 1594     mip->mi_type = TULIP_MEDIAINFO_GPR;
 1595     mip->mi_cmdmode = cmdmode;
 1596     mip->mi_gpdata = gpdata;
 1597 }
 1598 
 1599 static void
 1600 tulip_21140_evalboard_media_probe(
 1601     tulip_softc_t * const sc)
 1602 {
 1603     tulip_media_info_t *mip = sc->tulip_mediainfo;
 1604 
 1605     sc->tulip_gpinit = TULIP_GP_EB_PINS;
 1606     sc->tulip_gpdata = TULIP_GP_EB_INIT;
 1607     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
 1608     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
 1609     TULIP_CSR_WRITE(sc, csr_command,
 1610         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
 1611         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
 1612     TULIP_CSR_WRITE(sc, csr_command,
 1613         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
 1614     DELAY(1000000);
 1615     if ((TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_EB_OK100) != 0) {
 1616         sc->tulip_media = TULIP_MEDIA_10BASET;
 1617     } else {
 1618         sc->tulip_media = TULIP_MEDIA_100BASETX;
 1619     }
 1620     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
 1621                           TULIP_GP_EB_INIT,
 1622                           TULIP_CMD_TXTHRSHLDCTL);
 1623     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
 1624                           TULIP_GP_EB_INIT,
 1625                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
 1626     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
 1627                           TULIP_GP_EB_INIT,
 1628                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1629                               |TULIP_CMD_SCRAMBLER);
 1630     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
 1631                           TULIP_GP_EB_INIT,
 1632                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1633                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
 1634 }
 1635 
 1636 static const tulip_boardsw_t tulip_21140_eb_boardsw = {
 1637     TULIP_21140_DEC_EB,
 1638     tulip_21140_evalboard_media_probe,
 1639     tulip_media_select,
 1640     tulip_null_media_poll,
 1641     tulip_2114x_media_preset,
 1642 };
 1643 
 1644 static void
 1645 tulip_21140_accton_media_probe(
 1646     tulip_softc_t * const sc)
 1647 {
 1648     tulip_media_info_t *mip = sc->tulip_mediainfo;
 1649     unsigned gpdata;
 1650 
 1651     sc->tulip_gpinit = TULIP_GP_EB_PINS;
 1652     sc->tulip_gpdata = TULIP_GP_EB_INIT;
 1653     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
 1654     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
 1655     TULIP_CSR_WRITE(sc, csr_command,
 1656         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
 1657         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
 1658     TULIP_CSR_WRITE(sc, csr_command,
 1659         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
 1660     DELAY(1000000);
 1661     gpdata = TULIP_CSR_READ(sc, csr_gp);
 1662     if ((gpdata & TULIP_GP_EN1207_UTP_INIT) == 0) {
 1663         sc->tulip_media = TULIP_MEDIA_10BASET;
 1664     } else {
 1665         if ((gpdata & TULIP_GP_EN1207_BNC_INIT) == 0) {
 1666                 sc->tulip_media = TULIP_MEDIA_BNC;
 1667         } else {
 1668                 sc->tulip_media = TULIP_MEDIA_100BASETX;
 1669         }
 1670     }
 1671     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_BNC,
 1672                           TULIP_GP_EN1207_BNC_INIT,
 1673                           TULIP_CMD_TXTHRSHLDCTL);
 1674     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
 1675                           TULIP_GP_EN1207_UTP_INIT,
 1676                           TULIP_CMD_TXTHRSHLDCTL);
 1677     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
 1678                           TULIP_GP_EN1207_UTP_INIT,
 1679                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
 1680     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
 1681                           TULIP_GP_EN1207_100_INIT,
 1682                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1683                               |TULIP_CMD_SCRAMBLER);
 1684     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
 1685                           TULIP_GP_EN1207_100_INIT,
 1686                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1687                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
 1688 }
 1689 
 1690 static const tulip_boardsw_t tulip_21140_accton_boardsw = {
 1691     TULIP_21140_EN1207,
 1692     tulip_21140_accton_media_probe,
 1693     tulip_media_select,
 1694     tulip_null_media_poll,
 1695     tulip_2114x_media_preset,
 1696 };
 1697 
 1698 static void
 1699 tulip_21140_smc9332_media_probe(
 1700     tulip_softc_t * const sc)
 1701 {
 1702     tulip_media_info_t *mip = sc->tulip_mediainfo;
 1703     int idx, cnt = 0;
 1704 
 1705     TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE);
 1706     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
 1707     DELAY(10);  /* Wait 10 microseconds (actually 50 PCI cycles but at 
 1708                    33MHz that comes to two microseconds but wait a
 1709                    bit longer anyways) */
 1710     TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT |
 1711         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
 1712     sc->tulip_gpinit = TULIP_GP_SMC_9332_PINS;
 1713     sc->tulip_gpdata = TULIP_GP_SMC_9332_INIT;
 1714     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS|TULIP_GP_PINSET);
 1715     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT);
 1716     DELAY(200000);
 1717     for (idx = 1000; idx > 0; idx--) {
 1718         u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
 1719         if ((csr & (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) == (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) {
 1720             if (++cnt > 100)
 1721                 break;
 1722         } else if ((csr & TULIP_GP_SMC_9332_OK10) == 0) {
 1723             break;
 1724         } else {
 1725             cnt = 0;
 1726         }
 1727         DELAY(1000);
 1728     }
 1729     sc->tulip_media = cnt > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
 1730     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
 1731                           TULIP_GP_SMC_9332_INIT,
 1732                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1733                               |TULIP_CMD_SCRAMBLER);
 1734     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
 1735                           TULIP_GP_SMC_9332_INIT,
 1736                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1737                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
 1738     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
 1739                           TULIP_GP_SMC_9332_INIT,
 1740                           TULIP_CMD_TXTHRSHLDCTL);
 1741     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
 1742                           TULIP_GP_SMC_9332_INIT,
 1743                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
 1744 }
 1745  
 1746 static const tulip_boardsw_t tulip_21140_smc9332_boardsw = {
 1747     TULIP_21140_SMC_9332,
 1748     tulip_21140_smc9332_media_probe,
 1749     tulip_media_select,
 1750     tulip_null_media_poll,
 1751     tulip_2114x_media_preset,
 1752 };
 1753 
 1754 static void
 1755 tulip_21140_cogent_em100_media_probe(
 1756     tulip_softc_t * const sc)
 1757 {
 1758     tulip_media_info_t *mip = sc->tulip_mediainfo;
 1759     u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
 1760 
 1761     sc->tulip_gpinit = TULIP_GP_EM100_PINS;
 1762     sc->tulip_gpdata = TULIP_GP_EM100_INIT;
 1763     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
 1764     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT);
 1765 
 1766     cmdmode = TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_MUSTBEONE;
 1767     cmdmode &= ~(TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_SCRAMBLER);
 1768     if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
 1769         TULIP_CSR_WRITE(sc, csr_command, cmdmode);
 1770         sc->tulip_media = TULIP_MEDIA_100BASEFX;
 1771 
 1772         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX,
 1773                           TULIP_GP_EM100_INIT,
 1774                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION);
 1775         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX_FD,
 1776                           TULIP_GP_EM100_INIT,
 1777                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1778                               |TULIP_CMD_FULLDUPLEX);
 1779     } else {
 1780         TULIP_CSR_WRITE(sc, csr_command, cmdmode|TULIP_CMD_SCRAMBLER);
 1781         sc->tulip_media = TULIP_MEDIA_100BASETX;
 1782         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
 1783                           TULIP_GP_EM100_INIT,
 1784                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1785                               |TULIP_CMD_SCRAMBLER);
 1786         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
 1787                           TULIP_GP_EM100_INIT,
 1788                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1789                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
 1790     }
 1791 }
 1792 
 1793 static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw = {
 1794     TULIP_21140_COGENT_EM100,
 1795     tulip_21140_cogent_em100_media_probe,
 1796     tulip_media_select,
 1797     tulip_null_media_poll,
 1798     tulip_2114x_media_preset
 1799 };
 1800 
 1801 static void
 1802 tulip_21140_znyx_zx34x_media_probe(
 1803     tulip_softc_t * const sc)
 1804 {
 1805     tulip_media_info_t *mip = sc->tulip_mediainfo;
 1806     int cnt10 = 0, cnt100 = 0, idx;
 1807 
 1808     sc->tulip_gpinit = TULIP_GP_ZX34X_PINS;
 1809     sc->tulip_gpdata = TULIP_GP_ZX34X_INIT;
 1810     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
 1811     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT);
 1812     TULIP_CSR_WRITE(sc, csr_command,
 1813         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
 1814         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
 1815     TULIP_CSR_WRITE(sc, csr_command,
 1816         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
 1817 
 1818     DELAY(200000);
 1819     for (idx = 1000; idx > 0; idx--) {
 1820         u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
 1821         if ((csr & (TULIP_GP_ZX34X_LNKFAIL|TULIP_GP_ZX34X_SYMDET|TULIP_GP_ZX34X_SIGDET)) == (TULIP_GP_ZX34X_LNKFAIL|TULIP_GP_ZX34X_SYMDET|TULIP_GP_ZX34X_SIGDET)) {
 1822             if (++cnt100 > 100)
 1823                 break;
 1824         } else if ((csr & TULIP_GP_ZX34X_LNKFAIL) == 0) {
 1825             if (++cnt10 > 100)
 1826                 break;
 1827         } else {
 1828             cnt10 = 0;
 1829             cnt100 = 0;
 1830         }
 1831         DELAY(1000);
 1832     }
 1833     sc->tulip_media = cnt100 > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
 1834     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
 1835                           TULIP_GP_ZX34X_INIT,
 1836                           TULIP_CMD_TXTHRSHLDCTL);
 1837     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
 1838                           TULIP_GP_ZX34X_INIT,
 1839                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
 1840     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
 1841                           TULIP_GP_ZX34X_INIT,
 1842                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1843                               |TULIP_CMD_SCRAMBLER);
 1844     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
 1845                           TULIP_GP_ZX34X_INIT,
 1846                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
 1847                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
 1848 }
 1849 
 1850 static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw = {
 1851     TULIP_21140_ZNYX_ZX34X,
 1852     tulip_21140_znyx_zx34x_media_probe,
 1853     tulip_media_select,
 1854     tulip_null_media_poll,
 1855     tulip_2114x_media_preset,
 1856 };
 1857 
 1858 static void
 1859 tulip_2114x_media_probe(
 1860     tulip_softc_t * const sc)
 1861 {
 1862     sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE
 1863         |TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72;
 1864 }
 1865 
 1866 static const tulip_boardsw_t tulip_2114x_isv_boardsw = {
 1867     TULIP_21140_ISV,
 1868     tulip_2114x_media_probe,
 1869     tulip_media_select,
 1870     tulip_media_poll,
 1871     tulip_2114x_media_preset,
 1872 };
 1873 
 1874 /*
 1875  * ******** END of chip-specific handlers. ***********
 1876  */
 1877 
 1878 /*
 1879  * Code the read the SROM and MII bit streams (I2C)
 1880  */
 1881 static void
 1882 tulip_delay_300ns(
 1883     tulip_softc_t * const sc)
 1884 {
 1885     int idx;
 1886     for (idx = (300 / 33) + 1; idx > 0; idx--)
 1887         (void) TULIP_CSR_READ(sc, csr_busmode);
 1888 }
 1889 
 1890 #define EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
 1891 
 1892 static void
 1893 tulip_srom_idle(
 1894     tulip_softc_t * const sc)
 1895 {
 1896     unsigned bit, csr;
 1897     
 1898     csr  = SROMSEL ; EMIT;
 1899     csr  = SROMSEL | SROMRD; EMIT;  
 1900     csr ^= SROMCS; EMIT;
 1901     csr ^= SROMCLKON; EMIT;
 1902 
 1903     /*
 1904      * Write 25 cycles of 0 which will force the SROM to be idle.
 1905      */
 1906     for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
 1907         csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
 1908         csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
 1909     }
 1910     csr ^= SROMCLKOFF; EMIT;
 1911     csr ^= SROMCS; EMIT;
 1912     csr  = 0; EMIT;
 1913 }
 1914 
 1915      
 1916 static void
 1917 tulip_srom_read(
 1918     tulip_softc_t * const sc)
 1919 {   
 1920     unsigned idx; 
 1921     const unsigned bitwidth = SROM_BITWIDTH;
 1922     const unsigned cmdmask = (SROMCMD_RD << bitwidth);
 1923     const unsigned msb = 1 << (bitwidth + 3 - 1);
 1924     unsigned lastidx = (1 << bitwidth) - 1;
 1925 
 1926     tulip_srom_idle(sc);
 1927 
 1928     for (idx = 0; idx <= lastidx; idx++) {
 1929         unsigned lastbit, data, bits, bit, csr;
 1930         csr  = SROMSEL ;                EMIT;
 1931         csr  = SROMSEL | SROMRD;        EMIT;
 1932         csr ^= SROMCSON;                EMIT;
 1933         csr ^=            SROMCLKON;    EMIT;
 1934     
 1935         lastbit = 0;
 1936         for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1) {
 1937             const unsigned thisbit = bits & msb;
 1938             csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
 1939             if (thisbit != lastbit) {
 1940                 csr ^= SROMDOUT; EMIT;  /* clock low; invert data */
 1941             } else {
 1942                 EMIT;
 1943             }
 1944             csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
 1945             lastbit = thisbit;
 1946         }
 1947         csr ^= SROMCLKOFF; EMIT;
 1948 
 1949         for (data = 0, bits = 0; bits < 16; bits++) {
 1950             data <<= 1;
 1951             csr ^= SROMCLKON; EMIT;     /* clock high; data valid */ 
 1952             data |= TULIP_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
 1953             csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
 1954         }
 1955         sc->tulip_rombuf[idx*2] = data & 0xFF;
 1956         sc->tulip_rombuf[idx*2+1] = data >> 8;
 1957         csr  = SROMSEL | SROMRD; EMIT;
 1958         csr  = 0; EMIT;
 1959     }
 1960     tulip_srom_idle(sc);
 1961 }
 1962 
 1963 #define MII_EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
 1964 
 1965 static void
 1966 tulip_mii_writebits(
 1967     tulip_softc_t * const sc,
 1968     unsigned data,
 1969     unsigned bits)
 1970 {
 1971     unsigned msb = 1 << (bits - 1);
 1972     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
 1973     unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
 1974 
 1975     csr |= MII_WR; MII_EMIT;            /* clock low; assert write */
 1976 
 1977     for (; bits > 0; bits--, data <<= 1) {
 1978         const unsigned thisbit = data & msb;
 1979         if (thisbit != lastbit) {
 1980             csr ^= MII_DOUT; MII_EMIT;  /* clock low; invert data */
 1981         }
 1982         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
 1983         lastbit = thisbit;
 1984         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
 1985     }
 1986 }
 1987 
 1988 static void
 1989 tulip_mii_turnaround(
 1990     tulip_softc_t * const sc,
 1991     unsigned cmd)
 1992 {
 1993     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
 1994 
 1995     if (cmd == MII_WRCMD) {
 1996         csr |= MII_DOUT; MII_EMIT;      /* clock low; change data */
 1997         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
 1998         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
 1999         csr ^= MII_DOUT; MII_EMIT;      /* clock low; change data */
 2000     } else {
 2001         csr |= MII_RD; MII_EMIT;        /* clock low; switch to read */
 2002     }
 2003     csr ^= MII_CLKON; MII_EMIT;         /* clock high; data valid */
 2004     csr ^= MII_CLKOFF; MII_EMIT;        /* clock low; data not valid */
 2005 }
 2006 
 2007 static unsigned
 2008 tulip_mii_readbits(
 2009     tulip_softc_t * const sc)
 2010 {
 2011     unsigned data;
 2012     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
 2013     int idx;
 2014 
 2015     for (idx = 0, data = 0; idx < 16; idx++) {
 2016         data <<= 1;     /* this is NOOP on the first pass through */
 2017         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
 2018         if (TULIP_CSR_READ(sc, csr_srom_mii) & MII_DIN)
 2019             data |= 1;
 2020         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
 2021     }
 2022     csr ^= MII_RD; MII_EMIT;            /* clock low; turn off read */
 2023 
 2024     return data;
 2025 }
 2026 
 2027 static unsigned
 2028 tulip_mii_readreg(
 2029     tulip_softc_t * const sc,
 2030     unsigned devaddr,
 2031     unsigned regno)
 2032 {
 2033     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
 2034     unsigned data;
 2035 
 2036     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
 2037     tulip_mii_writebits(sc, MII_PREAMBLE, 32);
 2038     tulip_mii_writebits(sc, MII_RDCMD, 8);
 2039     tulip_mii_writebits(sc, devaddr, 5);
 2040     tulip_mii_writebits(sc, regno, 5);
 2041     tulip_mii_turnaround(sc, MII_RDCMD);
 2042 
 2043     data = tulip_mii_readbits(sc);
 2044 #if defined(TULIP_DEBUG)
 2045     sc->tulip_dbg.dbg_phyregs[regno][0] = data;
 2046     sc->tulip_dbg.dbg_phyregs[regno][1]++;
 2047 #endif
 2048     return data;
 2049 }
 2050 
 2051 static void
 2052 tulip_mii_writereg(
 2053     tulip_softc_t * const sc,
 2054     unsigned devaddr,
 2055     unsigned regno,
 2056     unsigned data)
 2057 {
 2058     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
 2059     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
 2060     tulip_mii_writebits(sc, MII_PREAMBLE, 32);
 2061     tulip_mii_writebits(sc, MII_WRCMD, 8);
 2062     tulip_mii_writebits(sc, devaddr, 5);
 2063     tulip_mii_writebits(sc, regno, 5);
 2064     tulip_mii_turnaround(sc, MII_WRCMD);
 2065     tulip_mii_writebits(sc, data, 16);
 2066 #if defined(TULIP_DEBUG)
 2067     sc->tulip_dbg.dbg_phyregs[regno][2] = data;
 2068     sc->tulip_dbg.dbg_phyregs[regno][3]++;
 2069 #endif
 2070 }
 2071 
 2072 #define tulip_mchash(mca)       (tulip_crc32(mca, 6) & 0x1FF)
 2073 #define tulip_srom_crcok(databuf)       ( \
 2074     ((tulip_crc32(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
 2075      ((databuf)[126] | ((databuf)[127] << 8)))
 2076 
 2077 static unsigned
 2078 tulip_crc32(
 2079     const unsigned char *databuf,
 2080     size_t datalen)
 2081 {
 2082     u_int idx, bit, data, crc = 0xFFFFFFFFUL;
 2083 
 2084     for (idx = 0; idx < datalen; idx++)
 2085         for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1)
 2086             crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0);
 2087     return crc;
 2088 }
 2089 
 2090 static void
 2091 tulip_identify_dec_nic(
 2092     tulip_softc_t * const sc)
 2093 {
 2094     strcpy(sc->tulip_boardid, "DEC ");
 2095 #define D0      4
 2096     if (sc->tulip_chipid <= TULIP_DE425)
 2097         return;
 2098     if (bcmp(sc->tulip_rombuf + 29, "DE500", 5) == 0
 2099         || bcmp(sc->tulip_rombuf + 29, "DE450", 5) == 0) {
 2100         bcopy(sc->tulip_rombuf + 29, &sc->tulip_boardid[D0], 8);
 2101         sc->tulip_boardid[D0+8] = ' ';
 2102     }
 2103 #undef D0
 2104 }
 2105 
 2106 static void
 2107 tulip_identify_znyx_nic(
 2108     tulip_softc_t * const sc)
 2109 {
 2110     unsigned id = 0;
 2111     strcpy(sc->tulip_boardid, "ZNYX ZX3XX ");
 2112     if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
 2113         unsigned znyx_ptr;
 2114         sc->tulip_boardid[8] = '4';
 2115         znyx_ptr = sc->tulip_rombuf[124] + 256 * sc->tulip_rombuf[125];
 2116         if (znyx_ptr < 26 || znyx_ptr > 116) {
 2117             sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
 2118             return;
 2119         }
 2120         /* ZX344 = 0010 .. 0013FF
 2121          */
 2122         if (sc->tulip_rombuf[znyx_ptr] == 0x4A
 2123                 && sc->tulip_rombuf[znyx_ptr + 1] == 0x52
 2124                 && sc->tulip_rombuf[znyx_ptr + 2] == 0x01) {
 2125             id = sc->tulip_rombuf[znyx_ptr + 5] + 256 * sc->tulip_rombuf[znyx_ptr + 4];
 2126             if ((id >> 8) == (TULIP_ZNYX_ID_ZX342 >> 8)) {
 2127                 sc->tulip_boardid[9] = '2';
 2128                 if (id == TULIP_ZNYX_ID_ZX342B) {
 2129                     sc->tulip_boardid[10] = 'B';
 2130                     sc->tulip_boardid[11] = ' ';
 2131                 }
 2132                 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
 2133             } else if (id == TULIP_ZNYX_ID_ZX344) {
 2134                 sc->tulip_boardid[10] = '4';
 2135                 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
 2136             } else if (id == TULIP_ZNYX_ID_ZX345) {
 2137                 sc->tulip_boardid[9] = (sc->tulip_rombuf[19] > 1) ? '8' : '5';
 2138             } else if (id == TULIP_ZNYX_ID_ZX346) {
 2139                 sc->tulip_boardid[9] = '6';
 2140             } else if (id == TULIP_ZNYX_ID_ZX351) {
 2141                 sc->tulip_boardid[8] = '5';
 2142                 sc->tulip_boardid[9] = '1';
 2143             }
 2144         }
 2145         if (id == 0) {
 2146             /*
 2147              * Assume it's a ZX342...
 2148              */
 2149             sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
 2150         }
 2151         return;
 2152     }
 2153     sc->tulip_boardid[8] = '1';
 2154     if (sc->tulip_chipid == TULIP_21041) {
 2155         sc->tulip_boardid[10] = '1';
 2156         return;
 2157     }
 2158     if (sc->tulip_rombuf[32] == 0x4A && sc->tulip_rombuf[33] == 0x52) {
 2159         id = sc->tulip_rombuf[37] + 256 * sc->tulip_rombuf[36];
 2160         if (id == TULIP_ZNYX_ID_ZX312T) {
 2161             sc->tulip_boardid[9] = '2';
 2162             sc->tulip_boardid[10] = 'T';
 2163             sc->tulip_boardid[11] = ' ';
 2164             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
 2165         } else if (id == TULIP_ZNYX_ID_ZX314_INTA) {
 2166             sc->tulip_boardid[9] = '4';
 2167             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
 2168             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
 2169         } else if (id == TULIP_ZNYX_ID_ZX314) {
 2170             sc->tulip_boardid[9] = '4';
 2171             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
 2172             sc->tulip_features |= TULIP_HAVE_BASEROM;
 2173         } else if (id == TULIP_ZNYX_ID_ZX315_INTA) {
 2174             sc->tulip_boardid[9] = '5';
 2175             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
 2176         } else if (id == TULIP_ZNYX_ID_ZX315) {
 2177             sc->tulip_boardid[9] = '5';
 2178             sc->tulip_features |= TULIP_HAVE_BASEROM;
 2179         } else {
 2180             id = 0;
 2181         }
 2182     }               
 2183     if (id == 0) {
 2184         if ((sc->tulip_enaddr[3] & ~3) == 0xF0 && (sc->tulip_enaddr[5] & 2) == 0) {
 2185             sc->tulip_boardid[9] = '4';
 2186             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
 2187             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
 2188         } else if ((sc->tulip_enaddr[3] & ~3) == 0xF4 && (sc->tulip_enaddr[5] & 1) == 0) {
 2189             sc->tulip_boardid[9] = '5';
 2190             sc->tulip_boardsw = &tulip_21040_boardsw;
 2191             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
 2192         } else if ((sc->tulip_enaddr[3] & ~3) == 0xEC) {
 2193             sc->tulip_boardid[9] = '2';
 2194             sc->tulip_boardsw = &tulip_21040_boardsw;
 2195         }
 2196     }
 2197 }
 2198 
 2199 static void
 2200 tulip_identify_smc_nic(
 2201     tulip_softc_t * const sc)
 2202 {
 2203     u_int32_t id1, id2, ei;
 2204     int auibnc = 0, utp = 0;
 2205     char *cp;
 2206 
 2207     strcpy(sc->tulip_boardid, "SMC ");
 2208     if (sc->tulip_chipid == TULIP_21041)
 2209         return;
 2210     if (sc->tulip_chipid != TULIP_21040) {
 2211         if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
 2212             strcpy(&sc->tulip_boardid[4], "9332DST ");
 2213             sc->tulip_boardsw = &tulip_21140_smc9332_boardsw;
 2214         } else if (sc->tulip_features & (TULIP_HAVE_BASEROM|TULIP_HAVE_SLAVEDROM)) {
 2215             strcpy(&sc->tulip_boardid[4], "9334BDT ");
 2216         } else {
 2217             strcpy(&sc->tulip_boardid[4], "9332BDT ");
 2218         }
 2219         return;
 2220     }
 2221     id1 = sc->tulip_rombuf[0x60] | (sc->tulip_rombuf[0x61] << 8);
 2222     id2 = sc->tulip_rombuf[0x62] | (sc->tulip_rombuf[0x63] << 8);
 2223     ei  = sc->tulip_rombuf[0x66] | (sc->tulip_rombuf[0x67] << 8);
 2224 
 2225     strcpy(&sc->tulip_boardid[4], "8432");
 2226     cp = &sc->tulip_boardid[8];
 2227     if ((id1 & 1) == 0)
 2228         *cp++ = 'B', auibnc = 1;
 2229     if ((id1 & 0xFF) > 0x32)
 2230         *cp++ = 'T', utp = 1;
 2231     if ((id1 & 0x4000) == 0)
 2232         *cp++ = 'A', auibnc = 1;
 2233     if (id2 == 0x15) {
 2234         sc->tulip_boardid[7] = '4';
 2235         *cp++ = '-';
 2236         *cp++ = 'C';
 2237         *cp++ = 'H';
 2238         *cp++ = (ei ? '2' : '1');
 2239     }
 2240     *cp++ = ' ';
 2241     *cp = '\0';
 2242     if (utp && !auibnc)
 2243         sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
 2244     else if (!utp && auibnc)
 2245         sc->tulip_boardsw = &tulip_21040_auibnc_only_boardsw;
 2246 }
 2247 
 2248 static void
 2249 tulip_identify_cogent_nic(
 2250     tulip_softc_t * const sc)
 2251 {
 2252     strcpy(sc->tulip_boardid, "Cogent ");
 2253     if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
 2254         if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) {
 2255             strcat(sc->tulip_boardid, "EM100FX ");
 2256             sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
 2257         } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
 2258             strcat(sc->tulip_boardid, "EM100FX ");
 2259             sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
 2260         }
 2261         /*
 2262          * Magic number (0x24001109U) is the SubVendor (0x2400) and
 2263          * SubDevId (0x1109) for the ANA6944TX (EM440TX).
 2264          */
 2265         if (*(u_int32_t *) sc->tulip_rombuf == 0x24001109U
 2266                 && (sc->tulip_features & TULIP_HAVE_BASEROM)) {
 2267             /*
 2268              * Cogent (Adaptec) is still mapping all INTs to INTA of
 2269              * first 21140.  Dumb!  Dumb!
 2270              */
 2271             strcat(sc->tulip_boardid, "EM440TX ");
 2272             sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
 2273         }
 2274     } else if (sc->tulip_chipid == TULIP_21040) {
 2275         sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
 2276     }
 2277 }
 2278 
 2279 static void
 2280 tulip_identify_accton_nic(
 2281     tulip_softc_t * const sc)
 2282 {
 2283     strcpy(sc->tulip_boardid, "ACCTON ");
 2284     switch (sc->tulip_chipid) {
 2285         case TULIP_21140A:
 2286             strcat(sc->tulip_boardid, "EN1207 ");
 2287             sc->tulip_boardsw = &tulip_21140_accton_boardsw;
 2288             break;
 2289         case TULIP_21140:
 2290             strcat(sc->tulip_boardid, "EN1207TX ");
 2291             sc->tulip_boardsw = &tulip_21140_eb_boardsw;
 2292             break;
 2293         case TULIP_21040:
 2294             strcat(sc->tulip_boardid, "EN1203 ");
 2295             sc->tulip_boardsw = &tulip_21040_boardsw;
 2296             break;
 2297         case TULIP_21041:
 2298             strcat(sc->tulip_boardid, "EN1203 ");
 2299             sc->tulip_boardsw = &tulip_21041_boardsw;
 2300             break;
 2301         default:
 2302             sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
 2303             break;
 2304     }
 2305 }
 2306 
 2307 static void
 2308 tulip_identify_asante_nic(
 2309     tulip_softc_t * const sc)
 2310 {
 2311     strcpy(sc->tulip_boardid, "Asante ");
 2312     if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A)
 2313             && sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
 2314         tulip_media_info_t *mi = sc->tulip_mediainfo;
 2315         int idx;
 2316         /*
 2317          * The Asante Fast Ethernet doesn't always ship with a valid
 2318          * new format SROM.  So if isn't in the new format, we cheat
 2319          * set it up as if we had.
 2320          */
 2321 
 2322         sc->tulip_gpinit = TULIP_GP_ASANTE_PINS;
 2323         sc->tulip_gpdata = 0;
 2324 
 2325         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PINS|TULIP_GP_PINSET);
 2326         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PHYRESET);
 2327         DELAY(100);
 2328         TULIP_CSR_WRITE(sc, csr_gp, 0);
 2329 
 2330         mi->mi_type = TULIP_MEDIAINFO_MII;
 2331         mi->mi_gpr_length = 0;
 2332         mi->mi_gpr_offset = 0;
 2333         mi->mi_reset_length = 0;
 2334         mi->mi_reset_offset = 0;;
 2335 
 2336         mi->mi_phyaddr = TULIP_MII_NOPHY;
 2337         for (idx = 20; idx > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx--) {
 2338             DELAY(10000);
 2339             mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, 0);
 2340         }
 2341         if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
 2342             printf(TULIP_PRINTF_FMT ": can't find phy 0\n", TULIP_PRINTF_ARGS);
 2343             return;
 2344         }
 2345 
 2346         sc->tulip_features |= TULIP_HAVE_MII;
 2347         mi->mi_capabilities  = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
 2348         mi->mi_advertisement = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
 2349         mi->mi_full_duplex   = PHYSTS_10BASET_FD|PHYSTS_100BASETX_FD;
 2350         mi->mi_tx_threshold  = PHYSTS_10BASET|PHYSTS_10BASET_FD;
 2351         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
 2352         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
 2353         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
 2354         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
 2355         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
 2356         mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
 2357             tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
 2358 
 2359         sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
 2360     }
 2361 }
 2362 
 2363 static int
 2364 tulip_srom_decode(
 2365     tulip_softc_t * const sc)
 2366 {
 2367     unsigned idx1, idx2, idx3;
 2368 
 2369     const tulip_srom_header_t *shp = (tulip_srom_header_t *) &sc->tulip_rombuf[0];
 2370     const tulip_srom_adapter_info_t *saip = (tulip_srom_adapter_info_t *) (shp + 1);
 2371     tulip_srom_media_t srom_media;
 2372     tulip_media_info_t *mi = sc->tulip_mediainfo;
 2373     const u_int8_t *dp;
 2374     u_int32_t leaf_offset, blocks, data;
 2375 
 2376     for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) {
 2377         if (shp->sh_adapter_count == 1)
 2378             break;
 2379         if (saip->sai_device == sc->tulip_pci_devno)
 2380             break;
 2381     }
 2382     /*
 2383      * Didn't find the right media block for this card.
 2384      */
 2385     if (idx1 == shp->sh_adapter_count)
 2386         return 0;
 2387 
 2388     /*
 2389      * Save the hardware address.
 2390      */
 2391     bcopy((caddr_t) shp->sh_ieee802_address, (caddr_t) sc->tulip_enaddr, 6);
 2392     /*
 2393      * If this is a multiple port card, add the adapter index to the last
 2394      * byte of the hardware address.  (if it isn't multiport, adding 0
 2395      * won't hurt.
 2396      */
 2397     sc->tulip_enaddr[5] += idx1;
 2398 
 2399     leaf_offset = saip->sai_leaf_offset_lowbyte
 2400         + saip->sai_leaf_offset_highbyte * 256;
 2401     dp = sc->tulip_rombuf + leaf_offset;
 2402         
 2403     sc->tulip_conntype = (tulip_srom_connection_t) (dp[0] + dp[1] * 256); dp += 2;
 2404 
 2405     for (idx2 = 0;; idx2++) {
 2406         if (tulip_srom_conninfo[idx2].sc_type == sc->tulip_conntype
 2407                 || tulip_srom_conninfo[idx2].sc_type == TULIP_SROM_CONNTYPE_NOT_USED)
 2408             break;
 2409     }
 2410     sc->tulip_connidx = idx2;
 2411 
 2412     if (sc->tulip_chipid == TULIP_21041) {
 2413         blocks = *dp++;
 2414         for (idx2 = 0; idx2 < blocks; idx2++) {
 2415             tulip_media_t media;
 2416             data = *dp++;
 2417             srom_media = (tulip_srom_media_t) (data & 0x3F);
 2418             for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
 2419                 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
 2420                     break;
 2421             }
 2422             media = tulip_srom_mediums[idx3].sm_type;
 2423             if (media != TULIP_MEDIA_UNKNOWN) {
 2424                 if (data & TULIP_SROM_21041_EXTENDED) {
 2425                     mi->mi_type = TULIP_MEDIAINFO_SIA;
 2426                     sc->tulip_mediums[media] = mi;
 2427                     mi->mi_sia_connectivity = dp[0] + dp[1] * 256;
 2428                     mi->mi_sia_tx_rx        = dp[2] + dp[3] * 256;
 2429                     mi->mi_sia_general      = dp[4] + dp[5] * 256;
 2430                     mi++;
 2431                 } else {
 2432                     switch (media) {
 2433                         case TULIP_MEDIA_BNC: {
 2434                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, BNC);
 2435                             mi++;
 2436                             break;
 2437                         }
 2438                         case TULIP_MEDIA_AUI: {
 2439                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, AUI);
 2440                             mi++;
 2441                             break;
 2442                         }
 2443                         case TULIP_MEDIA_10BASET: {
 2444                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET);
 2445                             mi++;
 2446                             break;
 2447                         }
 2448                         case TULIP_MEDIA_10BASET_FD: {
 2449                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET_FD);
 2450                             mi++;
 2451                             break;
 2452                         }
 2453                         default: {
 2454                             break;
 2455                         }
 2456                     }
 2457                 }
 2458             }
 2459             if (data & TULIP_SROM_21041_EXTENDED)       
 2460                 dp += 6;
 2461         }
 2462 #ifdef notdef
 2463         if (blocks == 0) {
 2464             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, BNC); mi++;
 2465             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, AUI); mi++;
 2466             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET); mi++;
 2467             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET_FD); mi++;
 2468         }
 2469 #endif
 2470     } else {
 2471         unsigned length, type;
 2472         tulip_media_t gp_media = TULIP_MEDIA_UNKNOWN;
 2473         if (sc->tulip_features & TULIP_HAVE_GPR)
 2474             sc->tulip_gpinit = *dp++;
 2475         blocks = *dp++;
 2476         for (idx2 = 0; idx2 < blocks; idx2++) {
 2477             const u_int8_t *ep;
 2478             if ((*dp & 0x80) == 0) {
 2479                 length = 4;
 2480                 type = 0;
 2481             } else {
 2482                 length = (*dp++ & 0x7f) - 1;
 2483                 type = *dp++ & 0x3f;
 2484             }
 2485             ep = dp + length;
 2486             switch (type & 0x3f) {
 2487                 case 0: {       /* 21140[A] GPR block */
 2488                     tulip_media_t media;
 2489                     srom_media = (tulip_srom_media_t) dp[0];
 2490                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
 2491                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
 2492                             break;
 2493                     }
 2494                     media = tulip_srom_mediums[idx3].sm_type;
 2495                     if (media == TULIP_MEDIA_UNKNOWN)
 2496                         break;
 2497                     mi->mi_type = TULIP_MEDIAINFO_GPR;
 2498                     sc->tulip_mediums[media] = mi;
 2499                     mi->mi_gpdata = dp[1];
 2500                     if (media > gp_media && !TULIP_IS_MEDIA_FD(media)) {
 2501                         sc->tulip_gpdata = mi->mi_gpdata;
 2502                         gp_media = media;
 2503                     }
 2504                     data = dp[2] + dp[3] * 256;
 2505                     mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
 2506                     if (data & TULIP_SROM_2114X_NOINDICATOR) {
 2507                         mi->mi_actmask = 0;
 2508                     } else {
 2509 #if 0
 2510                         mi->mi_default = (data & TULIP_SROM_2114X_DEFAULT) != 0;
 2511 #endif
 2512                         mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
 2513                         mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
 2514                     }
 2515                     mi++;
 2516                     break;
 2517                 }
 2518                 case 1: {       /* 21140[A] MII block */
 2519                     const unsigned phyno = *dp++;
 2520                     mi->mi_type = TULIP_MEDIAINFO_MII;
 2521                     mi->mi_gpr_length = *dp++;
 2522                     mi->mi_gpr_offset = dp - sc->tulip_rombuf;
 2523                     dp += mi->mi_gpr_length;
 2524                     mi->mi_reset_length = *dp++;
 2525                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
 2526                     dp += mi->mi_reset_length;
 2527 
 2528                     /*
 2529                      * Before we probe for a PHY, use the GPR information
 2530                      * to select it.  If we don't, it may be inaccessible.
 2531                      */
 2532                     TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpinit|TULIP_GP_PINSET);
 2533                     for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++) {
 2534                         DELAY(10);
 2535                         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx3]);
 2536                     }
 2537                     sc->tulip_phyaddr = mi->mi_phyaddr;
 2538                     for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++) {
 2539                         DELAY(10);
 2540                         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx3]);
 2541                     }
 2542 
 2543                     /*
 2544                      * At least write something!
 2545                      */
 2546                     if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
 2547                         TULIP_CSR_WRITE(sc, csr_gp, 0);
 2548 
 2549                     mi->mi_phyaddr = TULIP_MII_NOPHY;
 2550                     for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
 2551                         DELAY(10000);
 2552                         mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
 2553                     }
 2554                     if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
 2555                         printf(TULIP_PRINTF_FMT ": can't find phy %d\n",
 2556                                TULIP_PRINTF_ARGS, phyno);
 2557                         break;
 2558                     }
 2559                     sc->tulip_features |= TULIP_HAVE_MII;
 2560                     mi->mi_capabilities  = dp[0] + dp[1] * 256; dp += 2;
 2561                     mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
 2562                     mi->mi_full_duplex   = dp[0] + dp[1] * 256; dp += 2;
 2563                     mi->mi_tx_threshold  = dp[0] + dp[1] * 256; dp += 2;
 2564                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
 2565                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
 2566                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
 2567                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
 2568                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
 2569                     mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
 2570                         tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
 2571                     mi++;
 2572                     break;
 2573                 }
 2574                 case 2: {       /* 2114[23] SIA block */
 2575                     tulip_media_t media;
 2576                     srom_media = (tulip_srom_media_t) dp[0];
 2577                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
 2578                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
 2579                             break;
 2580                     }
 2581                     media = tulip_srom_mediums[idx3].sm_type;
 2582                     if (media == TULIP_MEDIA_UNKNOWN)
 2583                         break;
 2584                     mi->mi_type = TULIP_MEDIAINFO_SIA;
 2585                     sc->tulip_mediums[media] = mi;
 2586                     if (type & 0x40) {
 2587                         mi->mi_sia_connectivity = dp[0] + dp[1] * 256;
 2588                         mi->mi_sia_tx_rx        = dp[2] + dp[3] * 256;
 2589                         mi->mi_sia_general      = dp[4] + dp[5] * 256;
 2590                         dp += 6;
 2591                     } else {
 2592                         switch (media) {
 2593                             case TULIP_MEDIA_BNC: {
 2594                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, BNC);
 2595                                 break;
 2596                             }
 2597                             case TULIP_MEDIA_AUI: {
 2598                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, AUI);
 2599                                 break;
 2600                             }
 2601                             case TULIP_MEDIA_10BASET: {
 2602                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET);
 2603                                 break;
 2604                             }
 2605                             case TULIP_MEDIA_10BASET_FD: {
 2606                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET_FD);
 2607                                 break;
 2608                             }
 2609                             default: {
 2610                                 goto bad_media;
 2611                             }
 2612                         }
 2613                     }
 2614                     mi->mi_sia_gp_control = (dp[0] + dp[1] * 256) << 16;
 2615                     mi->mi_sia_gp_data    = (dp[2] + dp[3] * 256) << 16;
 2616                     mi++;
 2617                   bad_media:
 2618                     break;
 2619                 }
 2620                 case 3: {       /* 2114[23] MII PHY block */
 2621                     const unsigned phyno = *dp++;
 2622                     const u_int8_t *dp0;
 2623                     mi->mi_type = TULIP_MEDIAINFO_MII;
 2624                     mi->mi_gpr_length = *dp++;
 2625                     mi->mi_gpr_offset = dp - sc->tulip_rombuf;
 2626                     dp += 2 * mi->mi_gpr_length;
 2627                     mi->mi_reset_length = *dp++;
 2628                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
 2629                     dp += 2 * mi->mi_reset_length;
 2630 
 2631                     dp0 = &sc->tulip_rombuf[mi->mi_reset_offset];
 2632                     for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++, dp0 += 2) {
 2633                         DELAY(10);
 2634                         TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
 2635                     }
 2636                     sc->tulip_phyaddr = mi->mi_phyaddr;
 2637                     dp0 = &sc->tulip_rombuf[mi->mi_gpr_offset];
 2638                     for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++, dp0 += 2) {
 2639                         DELAY(10);
 2640                         TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
 2641                     }
 2642 
 2643                     if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
 2644                         TULIP_CSR_WRITE(sc, csr_sia_general, 0);
 2645 
 2646                     mi->mi_phyaddr = TULIP_MII_NOPHY;
 2647                     for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
 2648                         DELAY(10000);
 2649                         mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
 2650                     }
 2651                     if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
 2652                         printf(TULIP_PRINTF_FMT ": can't find phy %d\n",
 2653                                TULIP_PRINTF_ARGS, phyno);
 2654                         break;
 2655                     }
 2656                     sc->tulip_features |= TULIP_HAVE_MII;
 2657                     mi->mi_capabilities  = dp[0] + dp[1] * 256; dp += 2;
 2658                     mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
 2659                     mi->mi_full_duplex   = dp[0] + dp[1] * 256; dp += 2;
 2660                     mi->mi_tx_threshold  = dp[0] + dp[1] * 256; dp += 2;
 2661                     mi->mi_mii_interrupt = dp[0] + dp[1] * 256; dp += 2;
 2662                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
 2663                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
 2664                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
 2665                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
 2666                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
 2667                     mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
 2668                         tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
 2669                     mi++;
 2670                     break;
 2671                 }
 2672                 case 4: {       /* 21143 SYM block */
 2673                     tulip_media_t media;
 2674                     srom_media = (tulip_srom_media_t) dp[0];
 2675                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
 2676                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
 2677                             break;
 2678                     }
 2679                     media = tulip_srom_mediums[idx3].sm_type;
 2680                     if (media == TULIP_MEDIA_UNKNOWN)
 2681                         break;
 2682                     mi->mi_type = TULIP_MEDIAINFO_SYM;
 2683                     sc->tulip_mediums[media] = mi;
 2684                     mi->mi_gpcontrol = (dp[1] + dp[2] * 256) << 16;
 2685                     mi->mi_gpdata    = (dp[3] + dp[4] * 256) << 16;
 2686                     data = dp[5] + dp[6] * 256;
 2687                     mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
 2688                     if (data & TULIP_SROM_2114X_NOINDICATOR) {
 2689                         mi->mi_actmask = 0;
 2690                     } else {
 2691                         mi->mi_default = (data & TULIP_SROM_2114X_DEFAULT) != 0;
 2692                         mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
 2693                         mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
 2694                     }
 2695                     mi++;
 2696                     break;
 2697                 }
 2698 #if 0
 2699                 case 5: {       /* 21143 Reset block */
 2700                     mi->mi_type = TULIP_MEDIAINFO_RESET;
 2701                     mi->mi_reset_length = *dp++;
 2702                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
 2703                     dp += 2 * mi->mi_reset_length;
 2704                     mi++;
 2705                     break;
 2706                 }
 2707 #endif
 2708                 default: {
 2709                 }
 2710             }
 2711             dp = ep;
 2712         }
 2713     }
 2714     return mi - sc->tulip_mediainfo;
 2715 }
 2716 
 2717 static const struct {
 2718     void (*vendor_identify_nic)(tulip_softc_t * const sc);
 2719     unsigned char vendor_oui[3];
 2720 } tulip_vendors[] = {
 2721     { tulip_identify_dec_nic,           { 0x08, 0x00, 0x2B } },
 2722     { tulip_identify_dec_nic,           { 0x00, 0x00, 0xF8 } },
 2723     { tulip_identify_smc_nic,           { 0x00, 0x00, 0xC0 } },
 2724     { tulip_identify_smc_nic,           { 0x00, 0xE0, 0x29 } },
 2725     { tulip_identify_znyx_nic,          { 0x00, 0xC0, 0x95 } },
 2726     { tulip_identify_cogent_nic,        { 0x00, 0x00, 0x92 } },
 2727     { tulip_identify_asante_nic,        { 0x00, 0x00, 0x94 } },
 2728     { tulip_identify_cogent_nic,        { 0x00, 0x00, 0xD1 } },
 2729     { tulip_identify_accton_nic,        { 0x00, 0x00, 0xE8 } },
 2730     { NULL }
 2731 };
 2732 
 2733 /*
 2734  * This deals with the vagaries of the address roms and the
 2735  * brain-deadness that various vendors commit in using them.
 2736  */
 2737 static int
 2738 tulip_read_macaddr(
 2739     tulip_softc_t * const sc)
 2740 {
 2741     unsigned cksum, rom_cksum, idx;
 2742     u_int32_t csr;
 2743     unsigned char tmpbuf[8];
 2744     static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
 2745 
 2746     sc->tulip_connidx = TULIP_SROM_LASTCONNIDX;
 2747 
 2748     if (sc->tulip_chipid == TULIP_21040) {
 2749         TULIP_CSR_WRITE(sc, csr_enetrom, 1);
 2750         for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
 2751             int cnt = 0;
 2752             while (((csr = TULIP_CSR_READ(sc, csr_enetrom)) & 0x80000000L) && cnt < 10000)
 2753                 cnt++;
 2754             sc->tulip_rombuf[idx] = csr & 0xFF;
 2755         }
 2756         sc->tulip_boardsw = &tulip_21040_boardsw;
 2757 #if defined(TULIP_EISA)
 2758     } else if (sc->tulip_chipid == TULIP_DE425) {
 2759         int cnt;
 2760         for (idx = 0, cnt = 0; idx < sizeof(testpat) && cnt < 32; cnt++) {
 2761             tmpbuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
 2762             if (tmpbuf[idx] == testpat[idx])
 2763                 ++idx;
 2764             else
 2765                 idx = 0;
 2766         }
 2767         for (idx = 0; idx < 32; idx++)
 2768             sc->tulip_rombuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom);
 2769         sc->tulip_boardsw = &tulip_21040_boardsw;
 2770 #endif /* TULIP_EISA */
 2771     } else {
 2772         if (sc->tulip_chipid == TULIP_21041) {
 2773             /*
 2774              * Thankfully all 21041's act the same.
 2775              */
 2776             sc->tulip_boardsw = &tulip_21041_boardsw;
 2777         } else {
 2778             /*
 2779              * Assume all 21140 board are compatible with the
 2780              * DEC 10/100 evaluation board.  Not really valid but
 2781              * it's the best we can do until every one switches to
 2782              * the new SROM format.
 2783              */
 2784              
 2785             sc->tulip_boardsw = &tulip_21140_eb_boardsw;
 2786         }
 2787         tulip_srom_read(sc);
 2788         if (tulip_srom_crcok(sc->tulip_rombuf)) {
 2789             /*
 2790              * SROM CRC is valid therefore it must be in the
 2791              * new format.
 2792              */
 2793             sc->tulip_features |= TULIP_HAVE_ISVSROM;
 2794         } else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) {
 2795             /*
 2796              * No checksum is present.  See if the SROM id checks out;
 2797              * the first 18 bytes should be 0 followed by a 1 followed
 2798              * by the number of adapters (which we don't deal with yet).
 2799              */
 2800             for (idx = 0; idx < 18; idx++) {
 2801                 if (sc->tulip_rombuf[idx] != 0)
 2802                     break;
 2803             }
 2804             if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0)
 2805                 sc->tulip_features |= TULIP_HAVE_ISVSROM;
 2806         }
 2807         if ((sc->tulip_features & TULIP_HAVE_ISVSROM) && tulip_srom_decode(sc)) {
 2808             if (sc->tulip_chipid != TULIP_21041)
 2809                 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
 2810 
 2811             /*
 2812              * If the SROM specifies more than one adapter, tag this as a
 2813              * BASE rom.
 2814              */
 2815             if (sc->tulip_rombuf[19] > 1)
 2816                 sc->tulip_features |= TULIP_HAVE_BASEROM;
 2817             if (sc->tulip_boardsw == NULL)
 2818                 return -6;
 2819             goto check_oui;
 2820         }
 2821     }
 2822 
 2823 
 2824     if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) {
 2825         /*
 2826          * Some folks don't use the standard ethernet rom format
 2827          * but instead just put the address in the first 6 bytes
 2828          * of the rom and let the rest be all 0xffs.  (Can we say
 2829          * ZNYX???) (well sometimes they put in a checksum so we'll
 2830          * start at 8).
 2831          */
 2832         for (idx = 8; idx < 32; idx++) {
 2833             if (sc->tulip_rombuf[idx] != 0xFF)
 2834                 return -4;
 2835         }
 2836         /*
 2837          * Make sure the address is not multicast or locally assigned
 2838          * that the OUI is not 00-00-00.
 2839          */
 2840         if ((sc->tulip_rombuf[0] & 3) != 0)
 2841             return -4;
 2842         if (sc->tulip_rombuf[0] == 0 && sc->tulip_rombuf[1] == 0
 2843                 && sc->tulip_rombuf[2] == 0)
 2844             return -4;
 2845         bcopy(sc->tulip_rombuf, sc->tulip_enaddr, 6);
 2846         sc->tulip_features |= TULIP_HAVE_OKROM;
 2847         goto check_oui;
 2848     } else {
 2849         /*
 2850          * A number of makers of multiport boards (ZNYX and Cogent)
 2851          * only put on one address ROM on their 21040 boards.  So
 2852          * if the ROM is all zeros (or all 0xFFs), look at the
 2853          * previous configured boards (as long as they are on the same
 2854          * PCI bus and the bus number is non-zero) until we find the
 2855          * master board with address ROM.  We then use its address ROM
 2856          * as the base for this board.  (we add our relative board
 2857          * to the last byte of its address).
 2858          */
 2859         for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
 2860             if (sc->tulip_rombuf[idx] != 0 && sc->tulip_rombuf[idx] != 0xFF)
 2861                 break;
 2862         }
 2863         if (idx == sizeof(sc->tulip_rombuf)) {
 2864             int root_unit;
 2865             tulip_softc_t *root_sc = NULL;
 2866             for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
 2867                 root_sc = TULIP_UNIT_TO_SOFTC(root_unit);
 2868                 if (root_sc == NULL || (root_sc->tulip_features & (TULIP_HAVE_OKROM|TULIP_HAVE_SLAVEDROM)) == TULIP_HAVE_OKROM)
 2869                     break;
 2870                 root_sc = NULL;
 2871             }
 2872             if (root_sc != NULL && (root_sc->tulip_features & TULIP_HAVE_BASEROM)
 2873                     && root_sc->tulip_chipid == sc->tulip_chipid
 2874                     && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
 2875                 sc->tulip_features |= TULIP_HAVE_SLAVEDROM;
 2876                 sc->tulip_boardsw = root_sc->tulip_boardsw;
 2877                 strcpy(sc->tulip_boardid, root_sc->tulip_boardid);
 2878                 if (sc->tulip_boardsw->bd_type == TULIP_21140_ISV) {
 2879                     bcopy(root_sc->tulip_rombuf, sc->tulip_rombuf,
 2880                           sizeof(sc->tulip_rombuf));
 2881                     if (!tulip_srom_decode(sc))
 2882                         return -5;
 2883                 } else {
 2884                     bcopy(root_sc->tulip_enaddr, sc->tulip_enaddr, 6);
 2885                     sc->tulip_enaddr[5] += sc->tulip_unit - root_sc->tulip_unit;
 2886                 }
 2887                 /*
 2888                  * Now for a truly disgusting kludge: all 4 21040s on
 2889                  * the ZX314 share the same INTA line so the mapping
 2890                  * setup by the BIOS on the PCI bridge is worthless.
 2891                  * Rather than reprogramming the value in the config
 2892                  * register, we will handle this internally.
 2893                  */
 2894                 if (root_sc->tulip_features & TULIP_HAVE_SHAREDINTR) {
 2895                     sc->tulip_slaves = root_sc->tulip_slaves;
 2896                     root_sc->tulip_slaves = sc;
 2897                     sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
 2898                 }
 2899                 return 0;
 2900             }
 2901         }
 2902     }
 2903 
 2904     /*
 2905      * This is the standard DEC address ROM test.
 2906      */
 2907 
 2908     if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0)
 2909         return -3;
 2910 
 2911     tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14];
 2912     tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12];
 2913     tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10];
 2914     tmpbuf[6] = sc->tulip_rombuf[9];  tmpbuf[7] = sc->tulip_rombuf[8];
 2915     if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0)
 2916         return -2;
 2917 
 2918     bcopy(sc->tulip_rombuf, sc->tulip_enaddr, 6);
 2919 
 2920     cksum = *(u_int16_t *) &sc->tulip_enaddr[0];
 2921     cksum *= 2;
 2922     if (cksum > 65535) cksum -= 65535;
 2923     cksum += *(u_int16_t *) &sc->tulip_enaddr[2];
 2924     if (cksum > 65535) cksum -= 65535;
 2925     cksum *= 2;
 2926     if (cksum > 65535) cksum -= 65535;
 2927     cksum += *(u_int16_t *) &sc->tulip_enaddr[4];
 2928     if (cksum >= 65535) cksum -= 65535;
 2929 
 2930     rom_cksum = *(u_int16_t *) &sc->tulip_rombuf[6];
 2931         
 2932     if (cksum != rom_cksum)
 2933         return -1;
 2934 
 2935   check_oui:
 2936     /*
 2937      * Check for various boards based on OUI.  Did I say braindead?
 2938      */
 2939     for (idx = 0; tulip_vendors[idx].vendor_identify_nic != NULL; idx++) {
 2940         if (bcmp((caddr_t) sc->tulip_enaddr,
 2941                  (caddr_t) tulip_vendors[idx].vendor_oui, 3) == 0) {
 2942             (*tulip_vendors[idx].vendor_identify_nic)(sc);
 2943             break;
 2944         }
 2945     }
 2946 
 2947     sc->tulip_features |= TULIP_HAVE_OKROM;
 2948     return 0;
 2949 }
 2950 
 2951 #if defined(IFM_ETHER)
 2952 static void
 2953 tulip_ifmedia_add(
 2954     tulip_softc_t * const sc)
 2955 {
 2956     tulip_media_t media;
 2957     int medias = 0;
 2958 
 2959     for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
 2960         if (sc->tulip_mediums[media] != NULL) {
 2961             ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
 2962                         0, 0);
 2963             medias++;
 2964         }
 2965     }
 2966     if (medias == 0) {
 2967         sc->tulip_features |= TULIP_HAVE_NOMEDIA;
 2968         ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE, 0, 0);
 2969         ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE);
 2970     } else if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
 2971         ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
 2972         ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO);
 2973     } else {
 2974         ifmedia_set(&sc->tulip_ifmedia, tulip_media_to_ifmedia[sc->tulip_media]);
 2975         sc->tulip_flags |= TULIP_PRINTMEDIA;
 2976         tulip_linkup(sc, sc->tulip_media);
 2977     }
 2978 }
 2979 
 2980 static int
 2981 tulip_ifmedia_change(
 2982     struct ifnet * const ifp)
 2983 {
 2984     tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
 2985 
 2986     sc->tulip_flags |= TULIP_NEEDRESET;
 2987     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
 2988     sc->tulip_media = TULIP_MEDIA_UNKNOWN;
 2989     if (IFM_SUBTYPE(sc->tulip_ifmedia.ifm_media) != IFM_AUTO) {
 2990         tulip_media_t media;
 2991         for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
 2992             if (sc->tulip_mediums[media] != NULL
 2993                 && sc->tulip_ifmedia.ifm_media == tulip_media_to_ifmedia[media]) {
 2994                 sc->tulip_flags |= TULIP_PRINTMEDIA;
 2995                 sc->tulip_flags &= ~TULIP_DIDNWAY;
 2996                 tulip_linkup(sc, media);
 2997                 return 0;
 2998             }
 2999         }
 3000     }
 3001     sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
 3002     tulip_reset(sc);
 3003     tulip_init(sc);
 3004     return 0;
 3005 }
 3006 
 3007 /*
 3008  * Media status callback
 3009  */
 3010 static void
 3011 tulip_ifmedia_status(
 3012     struct ifnet * const ifp,
 3013     struct ifmediareq *req)
 3014 {
 3015     tulip_softc_t *sc = TULIP_IFP_TO_SOFTC(ifp);
 3016 
 3017 #if defined(__bsdi__)
 3018     if (sc->tulip_mii.mii_instance != 0) {
 3019         mii_pollstat(&sc->tulip_mii);
 3020         req->ifm_active = sc->tulip_mii.mii_media_active;
 3021         req->ifm_status = sc->tulip_mii.mii_media_status;
 3022         return;
 3023     }
 3024 #endif
 3025     if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
 3026         return;
 3027 
 3028     req->ifm_status = IFM_AVALID;
 3029     if (sc->tulip_flags & TULIP_LINKUP)
 3030         req->ifm_status |= IFM_ACTIVE;
 3031 
 3032     req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
 3033 }
 3034 #endif
 3035 
 3036 static void
 3037 tulip_addr_filter(
 3038     tulip_softc_t * const sc)
 3039 {
 3040     struct ether_multistep step;
 3041     struct ether_multi *enm;
 3042 
 3043     sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
 3044     sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
 3045     sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
 3046     sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
 3047 #if defined(IFF_ALLMULTI)    
 3048     sc->tulip_if.if_flags &= ~IFF_ALLMULTI;
 3049 #endif
 3050     sc->tulip_if.if_start = tulip_ifstart;      /* so the setup packet gets queued */
 3051     if (sc->tulip_multicnt > 14) {
 3052         u_int32_t *sp = sc->tulip_setupdata;
 3053         unsigned hash;
 3054         /*
 3055          * Some early passes of the 21140 have broken implementations of
 3056          * hash-perfect mode.  When we get too many multicasts for perfect
 3057          * filtering with these chips, we need to switch into hash-only
 3058          * mode (this is better than all-multicast on network with lots
 3059          * of multicast traffic).
 3060          */
 3061         if (sc->tulip_features & TULIP_HAVE_BROKEN_HASH)
 3062             sc->tulip_flags |= TULIP_WANTHASHONLY;
 3063         else
 3064             sc->tulip_flags |= TULIP_WANTHASHPERFECT;
 3065         /*
 3066          * If we have more than 14 multicasts, we have
 3067          * go into hash perfect mode (512 bit multicast
 3068          * hash and one perfect hardware).
 3069          */
 3070         bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
 3071         ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm);
 3072         while (enm != NULL) {
 3073                 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
 3074                     hash = tulip_mchash(enm->enm_addrlo);
 3075                     sp[hash >> 4] |= 1 << (hash & 0xF);
 3076                 } else {
 3077                     sc->tulip_flags |= TULIP_ALLMULTI;
 3078                     sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT);
 3079                     break;
 3080                 }
 3081                 ETHER_NEXT_MULTI(step, enm);
 3082         }
 3083         /*
 3084          * No reason to use a hash if we are going to be
 3085          * receiving every multicast.
 3086          */
 3087         if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
 3088             hash = tulip_mchash(etherbroadcastaddr);
 3089             sp[hash >> 4] |= 1 << (hash & 0xF);
 3090             if (sc->tulip_flags & TULIP_WANTHASHONLY) {
 3091                 hash = tulip_mchash(sc->tulip_enaddr);
 3092                 sp[hash >> 4] |= 1 << (hash & 0xF);
 3093             } else {
 3094                 sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0]; 
 3095                 sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1]; 
 3096                 sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2];
 3097             }
 3098         }
 3099     }
 3100     if ((sc->tulip_flags & (TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY)) == 0) {
 3101         u_int32_t *sp = sc->tulip_setupdata;
 3102         int idx = 0;
 3103         if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
 3104             /*
 3105              * Else can get perfect filtering for 16 addresses.
 3106              */
 3107             ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm);
 3108             for (; enm != NULL; idx++) {
 3109                 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
 3110                     *sp++ = ((u_int16_t *) enm->enm_addrlo)[0]; 
 3111                     *sp++ = ((u_int16_t *) enm->enm_addrlo)[1]; 
 3112                     *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
 3113                 } else {
 3114                     sc->tulip_flags |= TULIP_ALLMULTI;
 3115                     break;
 3116                 }
 3117                 ETHER_NEXT_MULTI(step, enm);
 3118             }
 3119             /*
 3120              * Add the broadcast address.
 3121              */
 3122             idx++;
 3123             *sp++ = 0xFFFF;
 3124             *sp++ = 0xFFFF;
 3125             *sp++ = 0xFFFF;
 3126         }
 3127         /*
 3128          * Pad the rest with our hardware address
 3129          */
 3130         for (; idx < 16; idx++) {
 3131             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0]; 
 3132             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1]; 
 3133             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2];
 3134         }
 3135     }
 3136 #if defined(IFF_ALLMULTI)
 3137     if (sc->tulip_flags & TULIP_ALLMULTI)
 3138         sc->tulip_if.if_flags |= IFF_ALLMULTI;
 3139 #endif
 3140 }
 3141 
 3142 static void
 3143 tulip_reset(
 3144     tulip_softc_t * const sc)
 3145 {
 3146     tulip_ringinfo_t *ri;
 3147     tulip_desc_t *di;
 3148     u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
 3149 
 3150     /*
 3151      * Brilliant.  Simply brilliant.  When switching modes/speeds
 3152      * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
 3153      * bits in CSR6 and then do a software reset to get the 21140
 3154      * to properly reset its internal pathways to the right places.
 3155      *   Grrrr.
 3156      */
 3157     if (sc->tulip_boardsw->bd_media_preset != NULL)
 3158         (*sc->tulip_boardsw->bd_media_preset)(sc);
 3159 
 3160     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
 3161     DELAY(10);  /* Wait 10 microseconds (actually 50 PCI cycles but at 
 3162                    33MHz that comes to two microseconds but wait a
 3163                    bit longer anyways) */
 3164 
 3165     if (!inreset) {
 3166         sc->tulip_flags |= TULIP_INRESET;
 3167         sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW);
 3168         sc->tulip_if.if_flags &= ~IFF_OACTIVE;
 3169     }
 3170 
 3171     TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0]));
 3172     TULIP_CSR_WRITE(sc, csr_rxlist, TULIP_KVATOPHYS(sc, &sc->tulip_rxinfo.ri_first[0]));
 3173     TULIP_CSR_WRITE(sc, csr_busmode,
 3174                     (1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8))
 3175                     |TULIP_BUSMODE_CACHE_ALIGN8
 3176                     |TULIP_BUSMODE_READMULTIPLE
 3177                     |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0));
 3178 
 3179     sc->tulip_txtimer = 0;
 3180     sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS;
 3181     /*
 3182      * Free all the mbufs that were on the transmit ring.
 3183      */
 3184     for (;;) {
 3185         struct mbuf *m;
 3186         IF_DEQUEUE(&sc->tulip_txq, m);
 3187         if (m == NULL)
 3188             break;
 3189         m_freem(m);
 3190     }
 3191 
 3192     ri = &sc->tulip_txinfo;
 3193     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
 3194     ri->ri_free = ri->ri_max;
 3195     for (di = ri->ri_first; di < ri->ri_last; di++)
 3196         di->d_status = 0;
 3197 
 3198     /*
 3199      * We need to collect all the mbufs were on the 
 3200      * receive ring before we reinit it either to put
 3201      * them back on or to know if we have to allocate
 3202      * more.
 3203      */
 3204     ri = &sc->tulip_rxinfo;
 3205     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
 3206     ri->ri_free = ri->ri_max;
 3207     for (di = ri->ri_first; di < ri->ri_last; di++) {
 3208         di->d_status = 0;
 3209         di->d_length1 = 0; di->d_addr1 = 0;
 3210         di->d_length2 = 0; di->d_addr2 = 0;
 3211     }
 3212     for (;;) {
 3213         struct mbuf *m;
 3214         IF_DEQUEUE(&sc->tulip_rxq, m);
 3215         if (m == NULL)
 3216             break;
 3217         m_freem(m);
 3218     }
 3219 
 3220     /*
 3221      * If tulip_reset is being called recurisvely, exit quickly knowing
 3222      * that when the outer tulip_reset returns all the right stuff will
 3223      * have happened.
 3224      */
 3225     if (inreset)
 3226         return;
 3227 
 3228     sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
 3229         |TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
 3230         |TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL
 3231         |TULIP_STS_RXSTOPPED;
 3232 
 3233     if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
 3234         (*sc->tulip_boardsw->bd_media_select)(sc);
 3235 #if defined(TULIP_DEBUG)
 3236     if ((sc->tulip_flags & TULIP_NEEDRESET) == TULIP_NEEDRESET)
 3237         printf(TULIP_PRINTF_FMT ": tulip_reset: additional reset needed?!?\n",
 3238                TULIP_PRINTF_ARGS);
 3239 #endif
 3240     tulip_media_print(sc);
 3241     if (sc->tulip_features & TULIP_HAVE_DUALSENSE)
 3242         TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
 3243 
 3244     sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
 3245                          |TULIP_RXACT);
 3246     tulip_addr_filter(sc);
 3247 }
 3248 
 3249 static void
 3250 tulip_init(
 3251     tulip_softc_t * const sc)
 3252 {
 3253     if (sc->tulip_if.if_flags & IFF_UP) {
 3254         if ((sc->tulip_if.if_flags & IFF_RUNNING) == 0) {
 3255             /* initialize the media */
 3256             tulip_reset(sc);
 3257         }
 3258         sc->tulip_if.if_flags |= IFF_RUNNING;
 3259         if (sc->tulip_if.if_flags & IFF_PROMISC) {
 3260             sc->tulip_flags |= TULIP_PROMISC;
 3261             sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
 3262             sc->tulip_intrmask |= TULIP_STS_TXINTR;
 3263         } else {
 3264             sc->tulip_flags &= ~TULIP_PROMISC;
 3265             sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
 3266             if (sc->tulip_flags & TULIP_ALLMULTI) {
 3267                 sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
 3268             } else {
 3269                 sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI;
 3270             }
 3271         }
 3272         sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
 3273         if ((sc->tulip_flags & (TULIP_TXPROBE_ACTIVE|TULIP_WANTSETUP)) == 0) {
 3274             tulip_rx_intr(sc);
 3275             sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
 3276             sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
 3277         } else {
 3278             sc->tulip_if.if_flags |= IFF_OACTIVE;
 3279             sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
 3280             sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
 3281         }
 3282         TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 3283         TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 3284         if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
 3285             tulip_txput_setup(sc);
 3286     } else {
 3287         sc->tulip_if.if_flags &= ~IFF_RUNNING;
 3288         tulip_reset(sc);
 3289     }
 3290 }
 3291 
 3292 static void
 3293 tulip_rx_intr(
 3294     tulip_softc_t * const sc)
 3295 {
 3296     TULIP_PERFSTART(rxintr)
 3297     tulip_ringinfo_t * const ri = &sc->tulip_rxinfo;
 3298     struct ifnet * const ifp = &sc->tulip_if;
 3299     int fillok = 1;
 3300 #if defined(TULIP_DEBUG)
 3301     int cnt = 0;
 3302 #endif
 3303 
 3304     for (;;) {
 3305         TULIP_PERFSTART(rxget)
 3306         struct ether_header eh;
 3307         tulip_desc_t *eop = ri->ri_nextin;
 3308         int total_len = 0, last_offset = 0;
 3309         struct mbuf *ms = NULL, *me = NULL;
 3310         int accept = 0;
 3311 
 3312         if (fillok && sc->tulip_rxq.ifq_len < TULIP_RXQ_TARGET)
 3313             goto queue_mbuf;
 3314 
 3315 #if defined(TULIP_DEBUG)
 3316         if (cnt == ri->ri_max)
 3317             break;
 3318 #endif
 3319         /*
 3320          * If the TULIP has no descriptors, there can't be any receive
 3321          * descriptors to process.
 3322          */
 3323         if (eop == ri->ri_nextout)
 3324             break;
 3325             
 3326         /*
 3327          * 90% of the packets will fit in one descriptor.  So we optimize
 3328          * for that case.
 3329          */
 3330         if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
 3331             IF_DEQUEUE(&sc->tulip_rxq, ms);
 3332             me = ms;
 3333         } else {
 3334             /*
 3335              * If still owned by the TULIP, don't touch it.
 3336              */
 3337             if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER)
 3338                 break;
 3339 
 3340             /*
 3341              * It is possible (though improbable unless the BIG_PACKET support
 3342              * is enabled or MCLBYTES < 1518) for a received packet to cross
 3343              * more than one receive descriptor.  
 3344              */
 3345             while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
 3346                 if (++eop == ri->ri_last)
 3347                     eop = ri->ri_first;
 3348                 if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
 3349 #if defined(TULIP_DEBUG)
 3350                     sc->tulip_dbg.dbg_rxintrs++;
 3351                     sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
 3352 #endif
 3353                     TULIP_PERFEND(rxget);
 3354                     TULIP_PERFEND(rxintr);
 3355                     return;
 3356                 }
 3357                 total_len++;
 3358             }
 3359 
 3360             /*
 3361              * Dequeue the first buffer for the start of the packet.  Hopefully
 3362              * this will be the only one we need to dequeue.  However, if the
 3363              * packet consumed multiple descriptors, then we need to dequeue
 3364              * those buffers and chain to the starting mbuf.  All buffers but
 3365              * the last buffer have the same length so we can set that now.
 3366              * (we add to last_offset instead of multiplying since we normally
 3367              * won't go into the loop and thereby saving a ourselves from
 3368              * doing a multiplication by 0 in the normal case).
 3369              */
 3370             IF_DEQUEUE(&sc->tulip_rxq, ms);
 3371             for (me = ms; total_len > 0; total_len--) {
 3372                 me->m_len = TULIP_RX_BUFLEN;
 3373                 last_offset += TULIP_RX_BUFLEN;
 3374                 IF_DEQUEUE(&sc->tulip_rxq, me->m_next);
 3375                 me = me->m_next;
 3376             }
 3377         }
 3378 
 3379         /*
 3380          *  Now get the size of received packet (minus the CRC).
 3381          */
 3382         total_len = ((eop->d_status >> 16) & 0x7FFF) - 4;
 3383         if ((sc->tulip_flags & TULIP_RXIGNORE) == 0
 3384                 && ((eop->d_status & TULIP_DSTS_ERRSUM) == 0
 3385 #ifdef BIG_PACKET
 3386                      || (total_len <= sc->tulip_if.if_mtu + sizeof(struct ether_header) && 
 3387                          (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxRUNT|
 3388                                           TULIP_DSTS_RxCOLLSEEN|TULIP_DSTS_RxBADCRC|
 3389                                           TULIP_DSTS_RxOVERFLOW)) == 0)
 3390 #endif
 3391                 )) {
 3392             me->m_len = total_len - last_offset;
 3393             eh = *mtod(ms, struct ether_header *);
 3394 #if NBPFILTER > 0
 3395             if (sc->tulip_bpf != NULL)
 3396                 if (me == ms)
 3397                     TULIP_BPF_TAP(sc, mtod(ms, caddr_t), total_len);
 3398                 else
 3399                     TULIP_BPF_MTAP(sc, ms);
 3400 #endif
 3401             sc->tulip_flags |= TULIP_RXACT;
 3402 #ifdef BRIDGE /* see code in if_ed.c */
 3403             ms->m_pkthdr.rcvif = ifp; /* XXX */
 3404             ms->m_pkthdr.len = total_len; /* XXX */
 3405             if (do_bridge) {
 3406                 struct ifnet *bdg_ifp ;
 3407                 bdg_ifp = bridge_in(ms);
 3408                 if (bdg_ifp == BDG_DROP)
 3409                     goto next ; /* and drop */
 3410                 if (bdg_ifp != BDG_LOCAL)
 3411                     bdg_forward(&ms, bdg_ifp);
 3412                 if (bdg_ifp != BDG_LOCAL && bdg_ifp != BDG_BCAST &&
 3413                         bdg_ifp != BDG_MCAST)
 3414                     goto next ; /* and drop */
 3415                 /* all others accepted locally */
 3416             } else
 3417 #endif
 3418             if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY))
 3419                     && (eh.ether_dhost[0] & 1) == 0
 3420                     && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr))
 3421                     goto next;
 3422             accept = 1;
 3423             total_len -= sizeof(struct ether_header);
 3424         } else {
 3425             ifp->if_ierrors++;
 3426             if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
 3427                 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
 3428             } else {
 3429                 const char *error = NULL;
 3430                 if (eop->d_status & TULIP_DSTS_RxTOOLONG) {
 3431                     sc->tulip_dot3stats.dot3StatsFrameTooLongs++;
 3432                     error = "frame too long";
 3433                 }
 3434                 if (eop->d_status & TULIP_DSTS_RxBADCRC) {
 3435                     if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) {
 3436                         sc->tulip_dot3stats.dot3StatsAlignmentErrors++;
 3437                         error = "alignment error";
 3438                     } else {
 3439                         sc->tulip_dot3stats.dot3StatsFCSErrors++;
 3440                         error = "bad crc";
 3441                     }
 3442                 }
 3443                 if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) {
 3444                     printf(TULIP_PRINTF_FMT ": receive: " TULIP_EADDR_FMT ": %s\n",
 3445                            TULIP_PRINTF_ARGS,
 3446                            TULIP_EADDR_ARGS(mtod(ms, u_char *) + 6),
 3447                            error);
 3448                     sc->tulip_flags |= TULIP_NOMESSAGES;
 3449                 }
 3450             }
 3451         }
 3452       next:
 3453 #if defined(TULIP_DEBUG)
 3454         cnt++;
 3455 #endif
 3456         ifp->if_ipackets++;
 3457         if (++eop == ri->ri_last)
 3458             eop = ri->ri_first;
 3459         ri->ri_nextin = eop;
 3460       queue_mbuf:
 3461         /*
 3462          * Either we are priming the TULIP with mbufs (m == NULL)
 3463          * or we are about to accept an mbuf for the upper layers
 3464          * so we need to allocate an mbuf to replace it.  If we
 3465          * can't replace it, send up it anyways.  This may cause
 3466          * us to drop packets in the future but that's better than
 3467          * being caught in livelock.
 3468          *
 3469          * Note that if this packet crossed multiple descriptors
 3470          * we don't even try to reallocate all the mbufs here.
 3471          * Instead we rely on the test of the beginning of
 3472          * the loop to refill for the extra consumed mbufs.
 3473          */
 3474         if (accept || ms == NULL) {
 3475             struct mbuf *m0;
 3476             MGETHDR(m0, M_DONTWAIT, MT_DATA);
 3477             if (m0 != NULL) {
 3478 #if defined(TULIP_COPY_RXDATA)
 3479                 if (!accept || total_len >= MHLEN) {
 3480 #endif
 3481                     MCLGET(m0, M_DONTWAIT);
 3482                     if ((m0->m_flags & M_EXT) == 0) {
 3483                         m_freem(m0);
 3484                         m0 = NULL;
 3485                     }
 3486 #if defined(TULIP_COPY_RXDATA)
 3487                 }
 3488 #endif
 3489             }
 3490             if (accept
 3491 #if defined(TULIP_COPY_RXDATA)
 3492                 && m0 != NULL
 3493 #endif
 3494                 ) {
 3495 #if defined(__bsdi__)
 3496                 eh.ether_type = ntohs(eh.ether_type);
 3497 #endif
 3498 #if !defined(TULIP_COPY_RXDATA)
 3499                 ms->m_data += sizeof(struct ether_header);
 3500                 ms->m_len -= sizeof(struct ether_header);
 3501                 ms->m_pkthdr.len = total_len;
 3502                 ms->m_pkthdr.rcvif = ifp;
 3503                 ether_input(ifp, &eh, ms);
 3504 #else
 3505 #ifdef BIG_PACKET
 3506 #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
 3507 #endif
 3508                 if (ms == me)
 3509                     bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
 3510                           mtod(m0, caddr_t), total_len);
 3511                 else
 3512                     m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
 3513                 m0->m_len = m0->m_pkthdr.len = total_len;
 3514                 m0->m_pkthdr.rcvif = ifp;
 3515                 ether_input(ifp, &eh, m0);
 3516                 m0 = ms;
 3517 #endif
 3518             }
 3519             ms = m0;
 3520         }
 3521         if (ms == NULL) {
 3522             /*
 3523              * Couldn't allocate a new buffer.  Don't bother 
 3524              * trying to replenish the receive queue.
 3525              */
 3526             fillok = 0;
 3527             sc->tulip_flags |= TULIP_RXBUFSLOW;
 3528 #if defined(TULIP_DEBUG)
 3529             sc->tulip_dbg.dbg_rxlowbufs++;
 3530 #endif
 3531             TULIP_PERFEND(rxget);
 3532             continue;
 3533         }
 3534         /*
 3535          * Now give the buffer(s) to the TULIP and save in our
 3536          * receive queue.
 3537          */
 3538         do {
 3539             ri->ri_nextout->d_length1 = TULIP_RX_BUFLEN;
 3540             ri->ri_nextout->d_addr1 = TULIP_KVATOPHYS(sc, mtod(ms, caddr_t));
 3541             ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
 3542             if (++ri->ri_nextout == ri->ri_last)
 3543                 ri->ri_nextout = ri->ri_first;
 3544             me = ms->m_next;
 3545             ms->m_next = NULL;
 3546             IF_ENQUEUE(&sc->tulip_rxq, ms);
 3547         } while ((ms = me) != NULL);
 3548 
 3549         if (sc->tulip_rxq.ifq_len >= TULIP_RXQ_TARGET)
 3550             sc->tulip_flags &= ~TULIP_RXBUFSLOW;
 3551         TULIP_PERFEND(rxget);
 3552     }
 3553 
 3554 #if defined(TULIP_DEBUG)
 3555     sc->tulip_dbg.dbg_rxintrs++;
 3556     sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
 3557 #endif
 3558     TULIP_PERFEND(rxintr);
 3559 }
 3560 
 3561 static int
 3562 tulip_tx_intr(
 3563     tulip_softc_t * const sc)
 3564 {
 3565     TULIP_PERFSTART(txintr)
 3566     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
 3567     struct mbuf *m;
 3568     int xmits = 0;
 3569     int descs = 0;
 3570 
 3571     while (ri->ri_free < ri->ri_max) {
 3572         u_int32_t d_flag;
 3573         if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
 3574             break;
 3575 
 3576         d_flag = ri->ri_nextin->d_flag;
 3577         if (d_flag & TULIP_DFLAG_TxLASTSEG) {
 3578             if (d_flag & TULIP_DFLAG_TxSETUPPKT) {
 3579                 /*
 3580                  * We've just finished processing a setup packet.
 3581                  * Mark that we finished it.  If there's not
 3582                  * another pending, startup the TULIP receiver.
 3583                  * Make sure we ack the RXSTOPPED so we won't get
 3584                  * an abormal interrupt indication.
 3585                  */
 3586                 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_HASHONLY);
 3587                 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxINVRSFILT)
 3588                     sc->tulip_flags |= TULIP_HASHONLY;
 3589                 if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == 0) {
 3590                     tulip_rx_intr(sc);
 3591                     sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
 3592                     sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
 3593                     TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
 3594                     TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 3595                     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 3596                 }
 3597             } else {
 3598                 const u_int32_t d_status = ri->ri_nextin->d_status;
 3599                 IF_DEQUEUE(&sc->tulip_txq, m);
 3600                 if (m != NULL) {
 3601 #if NBPFILTER > 0
 3602                     if (sc->tulip_bpf != NULL)
 3603                         TULIP_BPF_MTAP(sc, m);
 3604 #endif
 3605                     m_freem(m);
 3606 #if defined(TULIP_DEBUG)
 3607                 } else {
 3608                     printf(TULIP_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", TULIP_PRINTF_ARGS);
 3609 #endif
 3610                 }
 3611                 if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
 3612                     tulip_mediapoll_event_t event = TULIP_MEDIAPOLL_TXPROBE_OK;
 3613                     if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) {
 3614 #if defined(TULIP_DEBUG)
 3615                         if (d_status & TULIP_DSTS_TxNOCARR)
 3616                             sc->tulip_dbg.dbg_txprobe_nocarr++;
 3617                         if (d_status & TULIP_DSTS_TxEXCCOLL)
 3618                             sc->tulip_dbg.dbg_txprobe_exccoll++;
 3619 #endif
 3620                         event = TULIP_MEDIAPOLL_TXPROBE_FAILED;
 3621                     }
 3622                     (*sc->tulip_boardsw->bd_media_poll)(sc, event);
 3623                     /*
 3624                      * Escape from the loop before media poll has reset the TULIP!
 3625                      */
 3626                     break;
 3627                 } else {
 3628                     xmits++;
 3629                     if (d_status & TULIP_DSTS_ERRSUM) {
 3630                         sc->tulip_if.if_oerrors++;
 3631                         if (d_status & TULIP_DSTS_TxEXCCOLL)
 3632                             sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
 3633                         if (d_status & TULIP_DSTS_TxLATECOLL)
 3634                             sc->tulip_dot3stats.dot3StatsLateCollisions++;
 3635                         if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS))
 3636                             sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
 3637                         if (d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
 3638                             sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
 3639                         if (d_status & TULIP_DSTS_TxUNDERFLOW)
 3640                             sc->tulip_dot3stats.dot3StatsInternalTransmitUnderflows++;
 3641                         if (d_status & TULIP_DSTS_TxBABBLE)
 3642                             sc->tulip_dot3stats.dot3StatsInternalTransmitBabbles++;
 3643                     } else {
 3644                         u_int32_t collisions = 
 3645                             (d_status & TULIP_DSTS_TxCOLLMASK)
 3646                                 >> TULIP_DSTS_V_TxCOLLCNT;
 3647                         sc->tulip_if.if_collisions += collisions;
 3648                         if (collisions == 1)
 3649                             sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++;
 3650                         else if (collisions > 1)
 3651                             sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++;
 3652                         else if (d_status & TULIP_DSTS_TxDEFERRED)
 3653                             sc->tulip_dot3stats.dot3StatsDeferredTransmissions++;
 3654                         /*
 3655                          * SQE is only valid for 10baseT/BNC/AUI when not
 3656                          * running in full-duplex.  In order to speed up the
 3657                          * test, the corresponding bit in tulip_flags needs to
 3658                          * set as well to get us to count SQE Test Errors.
 3659                          */
 3660                         if (d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags)
 3661                             sc->tulip_dot3stats.dot3StatsSQETestErrors++;
 3662                     }
 3663                 }
 3664             }
 3665         }
 3666 
 3667         if (++ri->ri_nextin == ri->ri_last)
 3668             ri->ri_nextin = ri->ri_first;
 3669 
 3670         ri->ri_free++;
 3671         descs++;
 3672         if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
 3673             sc->tulip_if.if_flags &= ~IFF_OACTIVE;
 3674     }
 3675     /*
 3676      * If nothing left to transmit, disable the timer.
 3677      * Else if progress, reset the timer back to 2 ticks.
 3678      */
 3679     if (ri->ri_free == ri->ri_max || (sc->tulip_flags & TULIP_TXPROBE_ACTIVE))
 3680         sc->tulip_txtimer = 0;
 3681     else if (xmits > 0)
 3682         sc->tulip_txtimer = TULIP_TXTIMER;
 3683     sc->tulip_if.if_opackets += xmits;
 3684     TULIP_PERFEND(txintr);
 3685     return descs;
 3686 }
 3687 
 3688 static void
 3689 tulip_print_abnormal_interrupt(
 3690     tulip_softc_t * const sc,
 3691     u_int32_t csr)
 3692 {
 3693     const char * const *msgp = tulip_status_bits;
 3694     const char *sep;
 3695     u_int32_t mask;
 3696     const char thrsh[] = "72|128\0\0\096|256\0\0\0128|512\0\0160|1024\0";
 3697 
 3698     csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
 3699     printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS);
 3700     for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
 3701         if ((csr & mask) && *msgp != NULL) {
 3702             printf("%s%s", sep, *msgp);
 3703             if (mask == TULIP_STS_TXUNDERFLOW && (sc->tulip_flags & TULIP_NEWTXTHRESH)) {
 3704                 sc->tulip_flags &= ~TULIP_NEWTXTHRESH;
 3705                 if (sc->tulip_cmdmode & TULIP_CMD_STOREFWD) {
 3706                     printf(" (switching to store-and-forward mode)");
 3707                 } else {
 3708                     printf(" (raising TX threshold to %s)",
 3709                            &thrsh[9 * ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) >> 14)]);
 3710                 }
 3711             }
 3712             sep = ", ";
 3713         }
 3714     }
 3715     printf("\n");
 3716 }
 3717 
 3718 static void
 3719 tulip_intr_handler(
 3720     tulip_softc_t * const sc,
 3721     int *progress_p)
 3722 {
 3723     TULIP_PERFSTART(intr)
 3724     u_int32_t csr;
 3725 #if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
 3726     int only_once;
 3727 
 3728     only_once = 1;
 3729 #endif
 3730 
 3731     while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
 3732 #if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
 3733         if (only_once == 1) {
 3734 #if NRND > 0
 3735             rnd_add_uint32(&sc->tulip_rndsource, csr);
 3736 #endif
 3737             only_once = 0;
 3738         }
 3739 #endif
 3740 
 3741         *progress_p = 1;
 3742         TULIP_CSR_WRITE(sc, csr_status, csr);
 3743 
 3744         if (csr & TULIP_STS_SYSERROR) {
 3745             sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
 3746             if (sc->tulip_flags & TULIP_NOMESSAGES) {
 3747                 sc->tulip_flags |= TULIP_SYSTEMERROR;
 3748             } else {
 3749                 printf(TULIP_PRINTF_FMT ": system error: %s\n",
 3750                        TULIP_PRINTF_ARGS,
 3751                        tulip_system_errors[sc->tulip_last_system_error]);
 3752             }
 3753             sc->tulip_flags |= TULIP_NEEDRESET;
 3754             sc->tulip_system_errors++;
 3755             break;
 3756         }
 3757         if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) {
 3758 #if defined(TULIP_DEBUG)
 3759             sc->tulip_dbg.dbg_link_intrs++;
 3760 #endif
 3761             if (sc->tulip_boardsw->bd_media_poll != NULL) {
 3762                 (*sc->tulip_boardsw->bd_media_poll)(sc, csr & TULIP_STS_LINKFAIL
 3763                                                     ? TULIP_MEDIAPOLL_LINKFAIL
 3764                                                     : TULIP_MEDIAPOLL_LINKPASS);
 3765                 csr &= ~TULIP_STS_ABNRMLINTR;
 3766             }
 3767             tulip_media_print(sc);
 3768         }
 3769         if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
 3770             u_int32_t misses = TULIP_CSR_READ(sc, csr_missed_frames);
 3771             if (csr & TULIP_STS_RXNOBUF)
 3772                 sc->tulip_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
 3773             /*
 3774              * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
 3775              * on receive overflows.
 3776              */
 3777            if ((misses & 0x0FFE0000) && (sc->tulip_features & TULIP_HAVE_RXBADOVRFLW)) {
 3778                 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
 3779                 /*
 3780                  * Stop the receiver process and spin until it's stopped.
 3781                  * Tell rx_intr to drop the packets it dequeues.
 3782                  */
 3783                 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN);
 3784                 while ((TULIP_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
 3785                     ;
 3786                 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
 3787                 sc->tulip_flags |= TULIP_RXIGNORE;
 3788             }
 3789             tulip_rx_intr(sc);
 3790             if (sc->tulip_flags & TULIP_RXIGNORE) {
 3791                 /*
 3792                  * Restart the receiver.
 3793                  */
 3794                 sc->tulip_flags &= ~TULIP_RXIGNORE;
 3795                 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 3796             }
 3797         }
 3798         if (csr & TULIP_STS_ABNRMLINTR) {
 3799             u_int32_t tmp = csr & sc->tulip_intrmask
 3800                 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
 3801             if (csr & TULIP_STS_TXUNDERFLOW) {
 3802                 if ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
 3803                     sc->tulip_cmdmode += TULIP_CMD_THRSHLD96;
 3804                     sc->tulip_flags |= TULIP_NEWTXTHRESH;
 3805                 } else if (sc->tulip_features & TULIP_HAVE_STOREFWD) {
 3806                     sc->tulip_cmdmode |= TULIP_CMD_STOREFWD;
 3807                     sc->tulip_flags |= TULIP_NEWTXTHRESH;
 3808                 }
 3809             }
 3810             if (sc->tulip_flags & TULIP_NOMESSAGES) {
 3811                 sc->tulip_statusbits |= tmp;
 3812             } else {
 3813                 tulip_print_abnormal_interrupt(sc, tmp);
 3814                 sc->tulip_flags |= TULIP_NOMESSAGES;
 3815             }
 3816             TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
 3817         }
 3818         if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_TXPROBE_ACTIVE|TULIP_DOINGSETUP|TULIP_PROMISC)) {
 3819             tulip_tx_intr(sc);
 3820             if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
 3821                 tulip_ifstart(&sc->tulip_if);
 3822         }
 3823     }
 3824     if (sc->tulip_flags & TULIP_NEEDRESET) {
 3825         tulip_reset(sc);
 3826         tulip_init(sc);
 3827     }
 3828     TULIP_PERFEND(intr);
 3829 }
 3830 
 3831 #if defined(TULIP_USE_SOFTINTR)
 3832 /*
 3833  * This is a experimental idea to alleviate problems due to interrupt
 3834  * livelock.  What is interrupt livelock?  It's when you spend all your
 3835  * time servicing device interrupts and never drop below device ipl
 3836  * to do "useful" work.
 3837  *
 3838  * So what we do here is see if the device needs service and if so,
 3839  * disable interrupts (dismiss the interrupt), place it in a list of devices
 3840  * needing service, and issue a network software interrupt.
 3841  *
 3842  * When our network software interrupt routine gets called, we simply
 3843  * walk done the list of devices that we have created and deal with them
 3844  * at splnet/splsoftnet.
 3845  *
 3846  */
 3847 static void
 3848 tulip_hardintr_handler(
 3849     tulip_softc_t * const sc,
 3850     int *progress_p)
 3851 {
 3852     if (TULIP_CSR_READ(sc, csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR) == 0)
 3853         return;
 3854     *progress_p = 1;
 3855     /*
 3856      * disable interrupts
 3857      */
 3858     TULIP_CSR_WRITE(sc, csr_intr, 0);
 3859     /*
 3860      * mark it as needing a software interrupt
 3861      */
 3862     tulip_softintr_mask |= (1U << sc->tulip_unit);
 3863 
 3864 #if defined(__NetBSD__) && NRND > 0
 3865     /*
 3866      * This isn't all that random (the value we feed in) but it is
 3867      * better than a constant probably.  It isn't used in entropy
 3868      * calculation anyway, just to add something to the pool.
 3869      */
 3870     rnd_add_uint32(&sc->tulip_rndsource, sc->tulip_flags);
 3871 #endif
 3872 }
 3873 
 3874 static void
 3875 tulip_softintr(
 3876     void)
 3877 {
 3878     u_int32_t softintr_mask, mask;
 3879     int progress = 0;
 3880     int unit;
 3881     tulip_spl_t s;
 3882 
 3883     /*
 3884      * Copy mask to local copy and reset global one to 0.
 3885      */
 3886     s = TULIP_RAISESPL();
 3887     softintr_mask = tulip_softintr_mask;
 3888     tulip_softintr_mask = 0;
 3889     TULIP_RESTORESPL(s);
 3890 
 3891     /*
 3892      * Optimize for the single unit case.
 3893      */
 3894     if (tulip_softintr_max_unit == 0) {
 3895         if (softintr_mask & 1) {
 3896             tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(0);
 3897             /*
 3898              * Handle the "interrupt" and then reenable interrupts
 3899              */
 3900             softintr_mask = 0;
 3901             tulip_intr_handler(sc, &progress);
 3902             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 3903         }
 3904         return;
 3905     }
 3906 
 3907     /*
 3908      * Handle all "queued" interrupts in a round robin fashion.
 3909      * This is done so as not to favor a particular interface.
 3910      */
 3911     unit = tulip_softintr_last_unit;
 3912     mask = (1U << unit);
 3913     while (softintr_mask != 0) {
 3914         if (tulip_softintr_max_unit == unit) {
 3915             unit  = 0; mask   = 1;
 3916         } else {
 3917             unit += 1; mask <<= 1;
 3918         }
 3919         if (softintr_mask & mask) {
 3920             tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(unit);
 3921             /*
 3922              * Handle the "interrupt" and then reenable interrupts
 3923              */
 3924             softintr_mask ^= mask;
 3925             tulip_intr_handler(sc, &progress);
 3926             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 3927         }
 3928     }
 3929 
 3930     /*
 3931      * Save where we ending up.
 3932      */
 3933     tulip_softintr_last_unit = unit;
 3934 }
 3935 #endif  /* TULIP_USE_SOFTINTR */
 3936 
 3937 static tulip_intrfunc_t
 3938 tulip_intr_shared(
 3939     void *arg)
 3940 {
 3941     tulip_softc_t * sc = arg;
 3942     int progress = 0;
 3943 
 3944     for (; sc != NULL; sc = sc->tulip_slaves) {
 3945 #if defined(TULIP_DEBUG)
 3946         sc->tulip_dbg.dbg_intrs++;
 3947 #endif
 3948 #if defined(TULIP_USE_SOFTINTR)
 3949         tulip_hardintr_handler(sc, &progress);
 3950 #else
 3951         tulip_intr_handler(sc, &progress);
 3952 #endif
 3953     }
 3954 #if defined(TULIP_USE_SOFTINTR)
 3955     if (progress)
 3956         schednetisr(NETISR_DE);
 3957 #endif
 3958 #if !defined(TULIP_VOID_INTRFUNC)
 3959     return progress;
 3960 #endif
 3961 }
 3962 
 3963 static tulip_intrfunc_t
 3964 tulip_intr_normal(
 3965     void *arg)
 3966 {
 3967     tulip_softc_t * sc = (tulip_softc_t *) arg;
 3968     int progress = 0;
 3969 
 3970 #if defined(TULIP_DEBUG)
 3971     sc->tulip_dbg.dbg_intrs++;
 3972 #endif
 3973 #if defined(TULIP_USE_SOFTINTR)
 3974     tulip_hardintr_handler(sc, &progress);
 3975     if (progress)
 3976         schednetisr(NETISR_DE);
 3977 #else
 3978     tulip_intr_handler(sc, &progress);
 3979 #endif
 3980 #if !defined(TULIP_VOID_INTRFUNC)
 3981     return progress;
 3982 #endif
 3983 }
 3984 
 3985 static struct mbuf *
 3986 tulip_mbuf_compress(
 3987     struct mbuf *m)
 3988 {
 3989     struct mbuf *m0;
 3990 #if MCLBYTES >= ETHERMTU + 18 && !defined(BIG_PACKET)
 3991     MGETHDR(m0, M_DONTWAIT, MT_DATA);
 3992     if (m0 != NULL) {
 3993         if (m->m_pkthdr.len > MHLEN) {
 3994             MCLGET(m0, M_DONTWAIT);
 3995             if ((m0->m_flags & M_EXT) == 0) {
 3996                 m_freem(m);
 3997                 m_freem(m0);
 3998                 return NULL;
 3999             }
 4000         }
 4001         m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
 4002         m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
 4003     }
 4004 #else
 4005     int mlen = MHLEN;
 4006     int len = m->m_pkthdr.len;
 4007     struct mbuf **mp = &m0;
 4008 
 4009     while (len > 0) {
 4010         if (mlen == MHLEN) {
 4011             MGETHDR(*mp, M_DONTWAIT, MT_DATA);
 4012         } else {
 4013             MGET(*mp, M_DONTWAIT, MT_DATA);
 4014         }
 4015         if (*mp == NULL) {
 4016             m_freem(m0);
 4017             m0 = NULL;
 4018             break;
 4019         }
 4020         if (len > MLEN) {
 4021             MCLGET(*mp, M_DONTWAIT);
 4022             if (((*mp)->m_flags & M_EXT) == 0) {
 4023                 m_freem(m0);
 4024                 m0 = NULL;
 4025                 break;
 4026             }
 4027             (*mp)->m_len = len <= MCLBYTES ? len : MCLBYTES;
 4028         } else {
 4029             (*mp)->m_len = len <= mlen ? len : mlen;
 4030         }
 4031         m_copydata(m, m->m_pkthdr.len - len,
 4032                    (*mp)->m_len, mtod((*mp), caddr_t));
 4033         len -= (*mp)->m_len;
 4034         mp = &(*mp)->m_next;
 4035         mlen = MLEN;
 4036     }
 4037 #endif
 4038     m_freem(m);
 4039     return m0;
 4040 }
 4041 
 4042 static struct mbuf *
 4043 tulip_txput(
 4044     tulip_softc_t * const sc,
 4045     struct mbuf *m)
 4046 {
 4047     TULIP_PERFSTART(txput)
 4048     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
 4049     tulip_desc_t *eop, *nextout;
 4050     int segcnt, free;
 4051     u_int32_t d_status;
 4052     struct mbuf *m0;
 4053 
 4054 #if defined(TULIP_DEBUG)
 4055     if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
 4056         printf(TULIP_PRINTF_FMT ": txput%s: tx not running\n",
 4057                TULIP_PRINTF_ARGS,
 4058                (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
 4059         sc->tulip_flags |= TULIP_WANTTXSTART;
 4060         goto finish;
 4061     }
 4062 #endif
 4063 
 4064     /*
 4065      * Now we try to fill in our transmit descriptors.  This is
 4066      * a bit reminiscent of going on the Ark two by two
 4067      * since each descriptor for the TULIP can describe
 4068      * two buffers.  So we advance through packet filling
 4069      * each of the two entries at a time to to fill each
 4070      * descriptor.  Clear the first and last segment bits
 4071      * in each descriptor (actually just clear everything
 4072      * but the end-of-ring or chain bits) to make sure
 4073      * we don't get messed up by previously sent packets.
 4074      *
 4075      * We may fail to put the entire packet on the ring if
 4076      * there is either not enough ring entries free or if the
 4077      * packet has more than MAX_TXSEG segments.  In the former
 4078      * case we will just wait for the ring to empty.  In the
 4079      * latter case we have to recopy.
 4080      */
 4081   again:
 4082     d_status = 0;
 4083     eop = nextout = ri->ri_nextout;
 4084     m0 = m;
 4085     segcnt = 0;
 4086     free = ri->ri_free;
 4087     do {
 4088         int len = m0->m_len;
 4089         caddr_t addr = mtod(m0, caddr_t);
 4090         unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1));
 4091 
 4092         while (len > 0) {
 4093             unsigned slen = min(len, clsize);
 4094 #ifdef BIG_PACKET
 4095             int partial = 0;
 4096             if (slen >= 2048)
 4097                 slen = 2040, partial = 1;
 4098 #endif
 4099             segcnt++;
 4100             if (segcnt > TULIP_MAX_TXSEG) {
 4101                 /*
 4102                  * The packet exceeds the number of transmit buffer
 4103                  * entries that we can use for one packet, so we have
 4104                  * recopy it into one mbuf and then try again.
 4105                  */
 4106                 m = tulip_mbuf_compress(m);
 4107                 if (m == NULL)
 4108                     goto finish;
 4109                 goto again;
 4110             }
 4111             if (segcnt & 1) {
 4112                 if (--free == 0) {
 4113                     /*
 4114                      * See if there's any unclaimed space in the
 4115                      * transmit ring.
 4116                      */
 4117                     if ((free += tulip_tx_intr(sc)) == 0) {
 4118                         /*
 4119                          * There's no more room but since nothing
 4120                          * has been committed at this point, just
 4121                          * show output is active, put back the
 4122                          * mbuf and return.
 4123                          */
 4124                         sc->tulip_flags |= TULIP_WANTTXSTART;
 4125                         goto finish;
 4126                     }
 4127                 }
 4128                 eop = nextout;
 4129                 if (++nextout == ri->ri_last)
 4130                     nextout = ri->ri_first;
 4131                 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
 4132                 eop->d_status = d_status;
 4133                 eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
 4134                 eop->d_length1 = slen;
 4135             } else {
 4136                 /*
 4137                  *  Fill in second half of descriptor
 4138                  */
 4139                 eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
 4140                 eop->d_length2 = slen;
 4141             }
 4142             d_status = TULIP_DSTS_OWNER;
 4143             len -= slen;
 4144             addr += slen;
 4145 #ifdef BIG_PACKET
 4146             if (partial)
 4147                 continue;
 4148 #endif
 4149             clsize = CLBYTES;
 4150         }
 4151     } while ((m0 = m0->m_next) != NULL);
 4152 
 4153 
 4154     /*
 4155      * The descriptors have been filled in.  Now get ready
 4156      * to transmit.
 4157      */
 4158     IF_ENQUEUE(&sc->tulip_txq, m);
 4159     m = NULL;
 4160 
 4161     /*
 4162      * Make sure the next descriptor after this packet is owned
 4163      * by us since it may have been set up above if we ran out
 4164      * of room in the ring.
 4165      */
 4166     nextout->d_status = 0;
 4167 
 4168     /*
 4169      * If we only used the first segment of the last descriptor,
 4170      * make sure the second segment will not be used.
 4171      */
 4172     if (segcnt & 1) {
 4173         eop->d_addr2 = 0;
 4174         eop->d_length2 = 0;
 4175     }
 4176 
 4177     /*
 4178      * Mark the last and first segments, indicate we want a transmit
 4179      * complete interrupt, and tell it to transmit!
 4180      */
 4181     eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
 4182 
 4183     /*
 4184      * Note that ri->ri_nextout is still the start of the packet
 4185      * and until we set the OWNER bit, we can still back out of
 4186      * everything we have done.
 4187      */
 4188     ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
 4189     ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
 4190 
 4191     TULIP_CSR_WRITE(sc, csr_txpoll, 1);
 4192 
 4193     /*
 4194      * This advances the ring for us.
 4195      */
 4196     ri->ri_nextout = nextout;
 4197     ri->ri_free = free;
 4198 
 4199     TULIP_PERFEND(txput);
 4200 
 4201     if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
 4202         sc->tulip_if.if_flags |= IFF_OACTIVE;
 4203         TULIP_PERFEND(txput);
 4204         return NULL;
 4205     }
 4206 
 4207     /*
 4208      * switch back to the single queueing ifstart.
 4209      */
 4210     sc->tulip_flags &= ~TULIP_WANTTXSTART;
 4211     sc->tulip_if.if_start = tulip_ifstart_one;
 4212     if (sc->tulip_txtimer == 0)
 4213         sc->tulip_txtimer = TULIP_TXTIMER;
 4214 
 4215     /*
 4216      * If we want a txstart, there must be not enough space in the
 4217      * transmit ring.  So we want to enable transmit done interrupts
 4218      * so we can immediately reclaim some space.  When the transmit
 4219      * interrupt is posted, the interrupt handler will call tx_intr
 4220      * to reclaim space and then txstart (since WANTTXSTART is set).
 4221      * txstart will move the packet into the transmit ring and clear
 4222      * WANTTXSTART thereby causing TXINTR to be cleared.
 4223      */
 4224   finish:
 4225     if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) {
 4226         sc->tulip_if.if_flags |= IFF_OACTIVE;
 4227         sc->tulip_if.if_start = tulip_ifstart;
 4228         if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
 4229             sc->tulip_intrmask |= TULIP_STS_TXINTR;
 4230             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 4231         }
 4232     } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) {
 4233         if (sc->tulip_intrmask & TULIP_STS_TXINTR) {
 4234             sc->tulip_intrmask &= ~TULIP_STS_TXINTR;
 4235             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 4236         }
 4237     }
 4238     TULIP_PERFEND(txput);
 4239     return m;
 4240 }
 4241 
 4242 static void
 4243 tulip_txput_setup(
 4244     tulip_softc_t * const sc)
 4245 {
 4246     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
 4247     tulip_desc_t *nextout;
 4248         
 4249     /*
 4250      * We will transmit, at most, one setup packet per call to ifstart.
 4251      */
 4252 
 4253 #if defined(TULIP_DEBUG)
 4254     if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
 4255         printf(TULIP_PRINTF_FMT ": txput_setup: tx not running\n",
 4256                TULIP_PRINTF_ARGS);
 4257         sc->tulip_flags |= TULIP_WANTTXSTART;
 4258         sc->tulip_if.if_start = tulip_ifstart;
 4259         return;
 4260     }
 4261 #endif
 4262     /*
 4263      * Try to reclaim some free descriptors..
 4264      */
 4265     if (ri->ri_free < 2)
 4266         tulip_tx_intr(sc);
 4267     if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
 4268         sc->tulip_flags |= TULIP_WANTTXSTART;
 4269         sc->tulip_if.if_start = tulip_ifstart;
 4270         return;
 4271     }
 4272     bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
 4273           sizeof(sc->tulip_setupbuf));
 4274     /*
 4275      * Clear WANTSETUP and set DOINGSETUP.  Set know that WANTSETUP is
 4276      * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
 4277      */
 4278     sc->tulip_flags ^= TULIP_WANTSETUP|TULIP_DOINGSETUP;
 4279     ri->ri_free--;
 4280     nextout = ri->ri_nextout;
 4281     nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
 4282     nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
 4283         |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
 4284     if (sc->tulip_flags & TULIP_WANTHASHPERFECT)
 4285         nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
 4286     else if (sc->tulip_flags & TULIP_WANTHASHONLY)
 4287         nextout->d_flag |= TULIP_DFLAG_TxHASHFILT|TULIP_DFLAG_TxINVRSFILT;
 4288 
 4289     nextout->d_length1 = sizeof(sc->tulip_setupbuf);
 4290     nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf);
 4291     nextout->d_length2 = 0;
 4292     nextout->d_addr2 = 0;
 4293 
 4294     /*
 4295      * Advance the ring for the next transmit packet.
 4296      */
 4297     if (++ri->ri_nextout == ri->ri_last)
 4298         ri->ri_nextout = ri->ri_first;
 4299 
 4300     /*
 4301      * Make sure the next descriptor is owned by us since it
 4302      * may have been set up above if we ran out of room in the
 4303      * ring.
 4304      */
 4305     ri->ri_nextout->d_status = 0;
 4306     nextout->d_status = TULIP_DSTS_OWNER;
 4307     TULIP_CSR_WRITE(sc, csr_txpoll, 1);
 4308     if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
 4309         sc->tulip_intrmask |= TULIP_STS_TXINTR;
 4310         TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
 4311     }
 4312 }
 4313 
 4314 
 4315 /*
 4316  * This routine is entered at splnet() (splsoftnet() on NetBSD)
 4317  * and thereby imposes no problems when TULIP_USE_SOFTINTR is 
 4318  * defined or not.
 4319  */
 4320 static int
 4321 tulip_ifioctl(
 4322     struct ifnet * ifp,
 4323     ioctl_cmd_t cmd,
 4324     caddr_t data)
 4325 {
 4326     TULIP_PERFSTART(ifioctl)
 4327     tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
 4328     struct ifaddr *ifa = (struct ifaddr *)data;
 4329     struct ifreq *ifr = (struct ifreq *) data;
 4330     tulip_spl_t s;
 4331     int error = 0;
 4332 
 4333 #if defined(TULIP_USE_SOFTINTR)
 4334     s = TULIP_RAISESOFTSPL();
 4335 #else
 4336     s = TULIP_RAISESPL();
 4337 #endif
 4338     switch (cmd) {
 4339         case SIOCSIFADDR: {
 4340             ifp->if_flags |= IFF_UP;
 4341             switch(ifa->ifa_addr->sa_family) {
 4342 #ifdef INET
 4343                 case AF_INET: {
 4344                     tulip_init(sc);
 4345                     TULIP_ARP_IFINIT(sc, ifa);
 4346                     break;
 4347                 }
 4348 #endif /* INET */
 4349 
 4350 #ifdef IPX
 4351                 case AF_IPX: {
 4352                     struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
 4353                     if (ipx_nullhost(*ina)) {
 4354                         ina->x_host = *(union ipx_host *)(sc->tulip_enaddr);
 4355                     } else {
 4356                         ifp->if_flags &= ~IFF_RUNNING;
 4357                         bcopy((caddr_t)ina->x_host.c_host,
 4358                               (caddr_t)sc->tulip_enaddr,
 4359                               sizeof(sc->tulip_enaddr));
 4360                     }
 4361                     tulip_init(sc);
 4362                     break;
 4363                 }
 4364 #endif /* IPX */
 4365 
 4366 #ifdef NS
 4367                 /*
 4368                  * This magic copied from if_is.c; I don't use XNS,
 4369                  * so I have no way of telling if this actually
 4370                  * works or not.
 4371                  */
 4372                 case AF_NS: {
 4373                     struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
 4374                     if (ns_nullhost(*ina)) {
 4375                         ina->x_host = *(union ns_host *)(sc->tulip_enaddr);
 4376                     } else {
 4377                         ifp->if_flags &= ~IFF_RUNNING;
 4378                         bcopy((caddr_t)ina->x_host.c_host,
 4379                               (caddr_t)sc->tulip_enaddr,
 4380                               sizeof(sc->tulip_enaddr));
 4381                     }
 4382                     tulip_init(sc);
 4383                     break;
 4384                 }
 4385 #endif /* NS */
 4386 
 4387                 default: {
 4388                     tulip_init(sc);
 4389                     break;
 4390                 }
 4391             }
 4392             break;
 4393         }
 4394         case SIOCGIFADDR: {
 4395             bcopy((caddr_t) sc->tulip_enaddr,
 4396                   (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
 4397                   6);
 4398             break;
 4399         }
 4400 
 4401         case SIOCSIFFLAGS: {
 4402 #if !defined(IFM_ETHER)
 4403             int flags = 0;
 4404             if (ifp->if_flags & IFF_LINK0) flags |= 1;
 4405             if (ifp->if_flags & IFF_LINK1) flags |= 2;
 4406             if (ifp->if_flags & IFF_LINK2) flags |= 4;
 4407             if (flags == 7) {
 4408                 ifp->if_flags &= ~(IFF_LINK0|IFF_LINK1|IFF_LINK2);
 4409                 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
 4410                 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
 4411                 sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP|TULIP_NOAUTOSENSE);
 4412                 tulip_reset(sc);
 4413             } else if (flags) {
 4414                 tulip_media_t media;
 4415                 for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
 4416                     if (sc->tulip_mediums[media] != NULL && --flags == 0) {
 4417                         sc->tulip_flags |= TULIP_NOAUTOSENSE;
 4418                         if (sc->tulip_media != media || (sc->tulip_flags & TULIP_DIDNWAY)) {
 4419                             sc->tulip_flags &= ~TULIP_DIDNWAY;
 4420                             tulip_linkup(sc, media);
 4421                         }
 4422                         break;
 4423                     }
 4424                 }
 4425                 if (flags)
 4426                     printf(TULIP_PRINTF_FMT ": ignored invalid media request\n", TULIP_PRINTF_ARGS);
 4427             }
 4428 #endif
 4429             tulip_init(sc);
 4430             break;
 4431         }
 4432 
 4433 #if defined(SIOCSIFMEDIA)
 4434         case SIOCSIFMEDIA:
 4435         case SIOCGIFMEDIA: {
 4436             error = ifmedia_ioctl(ifp, ifr, &sc->tulip_ifmedia, cmd);
 4437             break;
 4438         }
 4439 #endif
 4440 
 4441         case SIOCADDMULTI:
 4442         case SIOCDELMULTI: {
 4443             /*
 4444              * Update multicast listeners
 4445              */
 4446             if (cmd == SIOCADDMULTI)
 4447                 error = ether_addmulti(ifr, TULIP_ETHERCOM(sc));
 4448             else
 4449                 error = ether_delmulti(ifr, TULIP_ETHERCOM(sc));
 4450 
 4451             if (error == ENETRESET) {
 4452                 tulip_addr_filter(sc);          /* reset multicast filtering */
 4453                 tulip_init(sc);
 4454                 error = 0;
 4455             }
 4456             break;
 4457         }
 4458 #if defined(SIOCSIFMTU)
 4459 #if !defined(ifr_mtu)
 4460 #define ifr_mtu ifr_metric
 4461 #endif
 4462         case SIOCSIFMTU:
 4463             /*
 4464              * Set the interface MTU.
 4465              */
 4466             if (ifr->ifr_mtu > ETHERMTU
 4467 #ifdef BIG_PACKET
 4468                     && sc->tulip_chipid != TULIP_21140
 4469                     && sc->tulip_chipid != TULIP_21140A
 4470                     && sc->tulip_chipid != TULIP_21041
 4471 #endif
 4472                 ) {
 4473                 error = EINVAL;
 4474                 break;
 4475             }
 4476             ifp->if_mtu = ifr->ifr_mtu;
 4477 #ifdef BIG_PACKET
 4478             tulip_reset(sc);
 4479             tulip_init(sc);
 4480 #endif
 4481             break;
 4482 #endif /* SIOCSIFMTU */
 4483 
 4484 #ifdef SIOCGADDRROM
 4485         case SIOCGADDRROM: {
 4486             error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));
 4487             break;
 4488         }
 4489 #endif
 4490 #ifdef SIOCGCHIPID
 4491         case SIOCGCHIPID: {
 4492             ifr->ifr_metric = (int) sc->tulip_chipid;
 4493             break;
 4494         }
 4495 #endif
 4496         default: {
 4497             error = EINVAL;
 4498             break;
 4499         }
 4500     }
 4501 
 4502     TULIP_RESTORESPL(s);
 4503     TULIP_PERFEND(ifioctl);
 4504     return error;
 4505 }
 4506 
 4507 /*
 4508  * These routines gets called at device spl (from ether_output).  This might
 4509  * pose a problem for TULIP_USE_SOFTINTR if ether_output is called at
 4510  * device spl from another driver.
 4511  */
 4512 
 4513 static ifnet_ret_t
 4514 tulip_ifstart(
 4515     struct ifnet * const ifp)
 4516 {
 4517     TULIP_PERFSTART(ifstart)
 4518     tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
 4519 
 4520     if (sc->tulip_if.if_flags & IFF_RUNNING) {
 4521 
 4522         if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
 4523             tulip_txput_setup(sc);
 4524 
 4525         while (sc->tulip_if.if_snd.ifq_head != NULL) {
 4526             struct mbuf *m;
 4527             IF_DEQUEUE(&sc->tulip_if.if_snd, m);
 4528             if ((m = tulip_txput(sc, m)) != NULL) {
 4529                 IF_PREPEND(&sc->tulip_if.if_snd, m);
 4530                 break;
 4531             }
 4532         }
 4533     }
 4534 
 4535     TULIP_PERFEND(ifstart);
 4536 }
 4537 
 4538 static ifnet_ret_t
 4539 tulip_ifstart_one(
 4540     struct ifnet * const ifp)
 4541 {
 4542     TULIP_PERFSTART(ifstart_one)
 4543     tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
 4544 
 4545     if ((sc->tulip_if.if_flags & IFF_RUNNING)
 4546             && sc->tulip_if.if_snd.ifq_head != NULL) {
 4547         struct mbuf *m;
 4548         IF_DEQUEUE(&sc->tulip_if.if_snd, m);
 4549         if ((m = tulip_txput(sc, m)) != NULL)
 4550             IF_PREPEND(&sc->tulip_if.if_snd, m);
 4551     }
 4552     TULIP_PERFEND(ifstart_one);
 4553 }
 4554 
 4555 /*
 4556  * Even though this routine runs at device spl, it does not break
 4557  * our use of splnet (splsoftnet under NetBSD) for the majority
 4558  * of this driver (if TULIP_USE_SOFTINTR defined) since 
 4559  * if_watcbog is called from if_watchdog which is called from
 4560  * splsoftclock which is below spl[soft]net.
 4561  */
 4562 static void
 4563 tulip_ifwatchdog(
 4564     struct ifnet *ifp)
 4565 {
 4566     TULIP_PERFSTART(ifwatchdog)
 4567     tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
 4568 
 4569 #if defined(TULIP_DEBUG)
 4570     u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
 4571     if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
 4572         sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
 4573     sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
 4574 #endif /* TULIP_DEBUG */
 4575 
 4576     sc->tulip_if.if_timer = 1;
 4577     /*
 4578      * These should be rare so do a bulk test up front so we can just skip
 4579      * them if needed.
 4580      */
 4581     if (sc->tulip_flags & (TULIP_SYSTEMERROR|TULIP_RXBUFSLOW|TULIP_NOMESSAGES)) {
 4582         /*
 4583          * If the number of receive buffer is low, try to refill
 4584          */
 4585         if (sc->tulip_flags & TULIP_RXBUFSLOW)
 4586             tulip_rx_intr(sc);
 4587 
 4588         if (sc->tulip_flags & TULIP_SYSTEMERROR) {
 4589             printf(TULIP_PRINTF_FMT ": %d system errors: last was %s\n",
 4590                    TULIP_PRINTF_ARGS, sc->tulip_system_errors,
 4591                    tulip_system_errors[sc->tulip_last_system_error]);
 4592         }
 4593         if (sc->tulip_statusbits) {
 4594             tulip_print_abnormal_interrupt(sc, sc->tulip_statusbits);
 4595             sc->tulip_statusbits = 0;
 4596         }
 4597 
 4598         sc->tulip_flags &= ~(TULIP_NOMESSAGES|TULIP_SYSTEMERROR);
 4599     }
 4600 
 4601     if (sc->tulip_txtimer)
 4602         tulip_tx_intr(sc);
 4603     if (sc->tulip_txtimer && --sc->tulip_txtimer == 0) {
 4604         printf(TULIP_PRINTF_FMT ": transmission timeout\n", TULIP_PRINTF_ARGS);
 4605         if (TULIP_DO_AUTOSENSE(sc)) {
 4606             sc->tulip_media = TULIP_MEDIA_UNKNOWN;
 4607             sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
 4608             sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP);
 4609         }
 4610         tulip_reset(sc);
 4611         tulip_init(sc);
 4612     }
 4613 
 4614     TULIP_PERFEND(ifwatchdog);
 4615     TULIP_PERFMERGE(sc, perf_intr_cycles);
 4616     TULIP_PERFMERGE(sc, perf_ifstart_cycles);
 4617     TULIP_PERFMERGE(sc, perf_ifioctl_cycles);
 4618     TULIP_PERFMERGE(sc, perf_ifwatchdog_cycles);
 4619     TULIP_PERFMERGE(sc, perf_timeout_cycles);
 4620     TULIP_PERFMERGE(sc, perf_ifstart_one_cycles);
 4621     TULIP_PERFMERGE(sc, perf_txput_cycles);
 4622     TULIP_PERFMERGE(sc, perf_txintr_cycles);
 4623     TULIP_PERFMERGE(sc, perf_rxintr_cycles);
 4624     TULIP_PERFMERGE(sc, perf_rxget_cycles);
 4625     TULIP_PERFMERGE(sc, perf_intr);
 4626     TULIP_PERFMERGE(sc, perf_ifstart);
 4627     TULIP_PERFMERGE(sc, perf_ifioctl);
 4628     TULIP_PERFMERGE(sc, perf_ifwatchdog);
 4629     TULIP_PERFMERGE(sc, perf_timeout);
 4630     TULIP_PERFMERGE(sc, perf_ifstart_one);
 4631     TULIP_PERFMERGE(sc, perf_txput);
 4632     TULIP_PERFMERGE(sc, perf_txintr);
 4633     TULIP_PERFMERGE(sc, perf_rxintr);
 4634     TULIP_PERFMERGE(sc, perf_rxget);
 4635 }
 4636 
 4637 #if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506)
 4638 static ifnet_ret_t
 4639 tulip_ifwatchdog_wrapper(
 4640     int unit)
 4641 {
 4642     tulip_ifwatchdog(&TULIP_UNIT_TO_SOFTC(unit)->tulip_if);
 4643 }
 4644 #define tulip_ifwatchdog        tulip_ifwatchdog_wrapper
 4645 #endif
 4646 
 4647 /*
 4648  * All printf's are real as of now!
 4649  */
 4650 #ifdef printf
 4651 #undef printf
 4652 #endif
 4653 #if !defined(IFF_NOTRAILERS)
 4654 #define IFF_NOTRAILERS          0
 4655 #endif
 4656 
 4657 static void
 4658 tulip_attach(
 4659     tulip_softc_t * const sc)
 4660 {
 4661     struct ifnet * const ifp = &sc->tulip_if;
 4662 
 4663     ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
 4664     ifp->if_ioctl = tulip_ifioctl;
 4665     ifp->if_start = tulip_ifstart;
 4666     ifp->if_watchdog = tulip_ifwatchdog;
 4667     ifp->if_timer = 1;
 4668 #if !defined(__bsdi__) || _BSDI_VERSION < 199401
 4669     ifp->if_output = ether_output;
 4670 #endif
 4671 #if defined(__bsdi__) && _BSDI_VERSION < 199401
 4672     ifp->if_mtu = ETHERMTU;
 4673 #endif
 4674   
 4675 #if defined(__bsdi__) && _BSDI_VERSION >= 199510
 4676     aprint_naive(": DEC Ethernet");
 4677     aprint_normal(": %s%s", sc->tulip_boardid,
 4678         tulip_chipdescs[sc->tulip_chipid]);
 4679     aprint_verbose(" pass %d.%d", (sc->tulip_revinfo & 0xF0) >> 4,
 4680         sc->tulip_revinfo & 0x0F);
 4681     printf("\n");
 4682     sc->tulip_pf = aprint_normal;
 4683     aprint_normal(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
 4684                   TULIP_PRINTF_ARGS,
 4685                   TULIP_EADDR_ARGS(sc->tulip_enaddr));
 4686 #else
 4687     printf(
 4688 #if defined(__bsdi__)
 4689            "\n"
 4690 #endif
 4691            TULIP_PRINTF_FMT ": %s%s pass %d.%d\n",
 4692            TULIP_PRINTF_ARGS,
 4693            sc->tulip_boardid,
 4694            tulip_chipdescs[sc->tulip_chipid],
 4695            (sc->tulip_revinfo & 0xF0) >> 4,
 4696            sc->tulip_revinfo & 0x0F);
 4697     printf(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
 4698            TULIP_PRINTF_ARGS,
 4699            TULIP_EADDR_ARGS(sc->tulip_enaddr));
 4700 #endif
 4701 
 4702 #if defined(__alpha__)
 4703     /*
 4704      * In case the SRM console told us about a bogus media,
 4705      * we need to check to be safe.
 4706      */
 4707     if (sc->tulip_mediums[sc->tulip_media] == NULL)
 4708         sc->tulip_media = TULIP_MEDIA_UNKNOWN;
 4709 #endif
 4710 
 4711     (*sc->tulip_boardsw->bd_media_probe)(sc);
 4712 #if defined(IFM_ETHER)
 4713     ifmedia_init(&sc->tulip_ifmedia, 0,
 4714                  tulip_ifmedia_change,
 4715                  tulip_ifmedia_status);
 4716 #else
 4717     {
 4718         tulip_media_t media;
 4719         int cnt;
 4720         printf(TULIP_PRINTF_FMT ": media:", TULIP_PRINTF_ARGS);
 4721         for (media = TULIP_MEDIA_UNKNOWN, cnt = 1; cnt < 7 && media < TULIP_MEDIA_MAX; media++) {
 4722             if (sc->tulip_mediums[media] != NULL) {
 4723                 printf(" %d=\"%s\"", cnt, tulip_mediums[media]);
 4724                 cnt++;
 4725             }
 4726         }
 4727         if (cnt == 1) {
 4728             sc->tulip_features |= TULIP_HAVE_NOMEDIA;
 4729             printf(" none\n");
 4730         } else {
 4731             printf("\n");
 4732         }
 4733     }
 4734 #endif
 4735     sc->tulip_flags &= ~TULIP_DEVICEPROBE;
 4736 #if defined(IFM_ETHER)
 4737     tulip_ifmedia_add(sc);
 4738 #endif
 4739 
 4740     tulip_reset(sc);
 4741 
 4742 #if defined(__bsdi__) && _BSDI_VERSION >= 199510
 4743     sc->tulip_pf = printf;
 4744     TULIP_ETHER_IFATTACH(sc);
 4745 #else
 4746     if_attach(ifp);
 4747 #if defined(__NetBSD__) || (defined(__FreeBSD__) && BSD >= 199506)
 4748     TULIP_ETHER_IFATTACH(sc);
 4749 #endif
 4750 #endif /* __bsdi__ */
 4751 
 4752 #if NBPFILTER > 0
 4753     TULIP_BPF_ATTACH(sc);
 4754 #endif
 4755 
 4756 #if defined(__NetBSD__) && NRND > 0
 4757     rnd_attach_source(&sc->tulip_rndsource, sc->tulip_dev.dv_xname,
 4758                       RND_TYPE_NET);
 4759 #endif
 4760 }
 4761 
 4762 static void
 4763 tulip_initcsrs(
 4764     tulip_softc_t * const sc,
 4765     tulip_csrptr_t csr_base,
 4766     size_t csr_size)
 4767 {
 4768     sc->tulip_csrs.csr_busmode          = csr_base +  0 * csr_size;
 4769     sc->tulip_csrs.csr_txpoll           = csr_base +  1 * csr_size;
 4770     sc->tulip_csrs.csr_rxpoll           = csr_base +  2 * csr_size;
 4771     sc->tulip_csrs.csr_rxlist           = csr_base +  3 * csr_size;
 4772     sc->tulip_csrs.csr_txlist           = csr_base +  4 * csr_size;
 4773     sc->tulip_csrs.csr_status           = csr_base +  5 * csr_size;
 4774     sc->tulip_csrs.csr_command          = csr_base +  6 * csr_size;
 4775     sc->tulip_csrs.csr_intr             = csr_base +  7 * csr_size;
 4776     sc->tulip_csrs.csr_missed_frames    = csr_base +  8 * csr_size;
 4777     sc->tulip_csrs.csr_9                = csr_base +  9 * csr_size;
 4778     sc->tulip_csrs.csr_10               = csr_base + 10 * csr_size;
 4779     sc->tulip_csrs.csr_11               = csr_base + 11 * csr_size;
 4780     sc->tulip_csrs.csr_12               = csr_base + 12 * csr_size;
 4781     sc->tulip_csrs.csr_13               = csr_base + 13 * csr_size;
 4782     sc->tulip_csrs.csr_14               = csr_base + 14 * csr_size;
 4783     sc->tulip_csrs.csr_15               = csr_base + 15 * csr_size;
 4784 #if defined(TULIP_EISA)
 4785     sc->tulip_csrs.csr_enetrom          = csr_base + DE425_ENETROM_OFFSET;
 4786 #endif
 4787 }
 4788 
 4789 static void
 4790 tulip_initring(
 4791     tulip_softc_t * const sc,
 4792     tulip_ringinfo_t * const ri,
 4793     tulip_desc_t *descs,
 4794     int ndescs)
 4795 {
 4796     ri->ri_max = ndescs;
 4797     ri->ri_first = descs;
 4798     ri->ri_last = ri->ri_first + ri->ri_max;
 4799     bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
 4800     ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
 4801 }
 4802 
 4803 /*
 4804  * This is the PCI configuration support.  Since the 21040 is available
 4805  * on both EISA and PCI boards, one must be careful in how defines the
 4806  * 21040 in the config file.
 4807  */
 4808 
 4809 #define PCI_CFID        0x00    /* Configuration ID */
 4810 #define PCI_CFCS        0x04    /* Configurtion Command/Status */
 4811 #define PCI_CFRV        0x08    /* Configuration Revision */
 4812 #define PCI_CFLT        0x0c    /* Configuration Latency Timer */
 4813 #define PCI_CBIO        0x10    /* Configuration Base IO Address */
 4814 #define PCI_CBMA        0x14    /* Configuration Base Memory Address */
 4815 #define PCI_CFIT        0x3c    /* Configuration Interrupt */
 4816 #define PCI_CFDA        0x40    /* Configuration Driver Area */
 4817 
 4818 #if defined(TULIP_EISA)
 4819 static const int tulip_eisa_irqs[4] = { IRQ5, IRQ9, IRQ10, IRQ11 };
 4820 #endif
 4821 
 4822 #if defined(__FreeBSD__)
 4823 
 4824 #define TULIP_PCI_ATTACH_ARGS   pcici_t config_id, int unit
 4825 #define TULIP_SHUTDOWN_ARGS     int howto, void * arg
 4826 
 4827 #if defined(TULIP_DEVCONF)
 4828 static void tulip_shutdown(TULIP_SHUTDOWN_ARGS);
 4829 
 4830 static int
 4831 tulip_pci_shutdown(
 4832     struct kern_devconf * const kdc,
 4833     int force)
 4834 {
 4835     if (kdc->kdc_unit < TULIP_MAX_DEVICES) {
 4836         tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(kdc->kdc_unit);
 4837         if (sc != NULL)
 4838             tulip_shutdown(0, sc);
 4839     }
 4840     (void) dev_detach(kdc);
 4841     return 0;
 4842 }
 4843 #endif
 4844 
 4845 static char*
 4846 tulip_pci_probe(
 4847     pcici_t config_id,
 4848     pcidi_t device_id)
 4849 {
 4850     if (PCI_VENDORID(device_id) != DEC_VENDORID)
 4851         return NULL;
 4852     if (PCI_CHIPID(device_id) == CHIPID_21040)
 4853         return "Digital 21040 Ethernet";
 4854     if (PCI_CHIPID(device_id) == CHIPID_21041)
 4855         return "Digital 21041 Ethernet";
 4856     if (PCI_CHIPID(device_id) == CHIPID_21140) {
 4857         u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
 4858         if (revinfo >= 0x20)
 4859             return "Digital 21140A Fast Ethernet";
 4860         else
 4861             return "Digital 21140 Fast Ethernet";
 4862     }
 4863     if (PCI_CHIPID(device_id) == CHIPID_21142) {
 4864         u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
 4865         if (revinfo >= 0x20)
 4866             return "Digital 21143 Fast Ethernet";
 4867         else
 4868             return "Digital 21142 Fast Ethernet";
 4869     }
 4870     return NULL;
 4871 }
 4872 
 4873 static void  tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
 4874 static u_long tulip_pci_count;
 4875 
 4876 struct pci_device dedevice = {
 4877     "de",
 4878     tulip_pci_probe,
 4879     tulip_pci_attach,
 4880    &tulip_pci_count,
 4881 #if defined(TULIP_DEVCONF)
 4882     tulip_pci_shutdown,
 4883 #endif
 4884 };
 4885 
 4886 DATA_SET (pcidevice_set, dedevice);
 4887 #endif /* __FreeBSD__ */
 4888 
 4889 #if defined(__bsdi__)
 4890 #define TULIP_PCI_ATTACH_ARGS   struct device * const parent, struct device * const self, void * const aux
 4891 #define TULIP_SHUTDOWN_ARGS     void *arg
 4892 
 4893 static int
 4894 tulip_pci_match(
 4895     pci_devaddr_t *pa)
 4896 {
 4897     int irq;
 4898     unsigned id;
 4899 
 4900     id = pci_inl(pa, PCI_VENDOR_ID);
 4901     if (PCI_VENDORID(id) != DEC_VENDORID)
 4902         return 0;
 4903     id = PCI_CHIPID(id);
 4904     if (id != CHIPID_21040 && id != CHIPID_21041
 4905             && id != CHIPID_21140 && id != CHIPID_21142)
 4906         return 0;
 4907     irq = pci_inl(pa, PCI_I_LINE) & 0xFF;
 4908     if (irq == 0 || irq >= 16) {
 4909         printf("de?: invalid IRQ %d; skipping\n", irq);
 4910         return 0;
 4911     }
 4912     return 1;
 4913 }
 4914 
 4915 static int
 4916 tulip_probe(
 4917     struct device *parent,
 4918     struct cfdata *cf,
 4919     void *aux)
 4920 {
 4921     struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
 4922     unsigned irq, slot;
 4923     pci_devaddr_t *pa;
 4924 
 4925 #if _BSDI_VERSION >= 199401
 4926     switch (ia->ia_bustype) {
 4927     case BUS_PCI:
 4928 #endif
 4929         pa = pci_scan(tulip_pci_match);
 4930         if (pa == NULL)
 4931             return 0;
 4932 
 4933         irq = (1 << (pci_inl(pa, PCI_I_LINE) & 0xFF));
 4934 
 4935         /* Get the base address; assume the BIOS set it up correctly */
 4936 #if defined(TULIP_IOMAPPED)
 4937         ia->ia_maddr = NULL;
 4938         ia->ia_msize = 0;
 4939         ia->ia_iobase = pci_inl(pa, PCI_CBIO) & ~7;
 4940         pci_outl(pa, PCI_CBIO, 0xFFFFFFFF);
 4941         ia->ia_iosize = ((~pci_inl(pa, PCI_CBIO)) | 7) + 1;
 4942         pci_outl(pa, PCI_CBIO, (int) ia->ia_iobase);
 4943 
 4944         /* Disable memory space access */
 4945         pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~2);
 4946 #else
 4947         ia->ia_maddr = (caddr_t) (pci_inl(pa, PCI_CBMA) & ~7);
 4948         pci_outl(pa, PCI_CBMA, 0xFFFFFFFF);
 4949         ia->ia_msize = ((~pci_inl(pa, PCI_CBMA)) | 7) + 1;
 4950         pci_outl(pa, PCI_CBMA, (int) ia->ia_maddr);
 4951         ia->ia_iobase = 0;
 4952         ia->ia_iosize = 0;
 4953 
 4954         /* Disable I/O space access */
 4955         pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~1);
 4956 #endif /* TULIP_IOMAPPED */
 4957 
 4958         ia->ia_aux = (void *) pa;
 4959 #if _BSDI_VERSION >= 199401
 4960         break;
 4961 
 4962 #if defined(TULIP_EISA)
 4963     case BUS_EISA: {
 4964         unsigned tmp;
 4965 
 4966         if ((slot = eisa_match(cf, ia)) == 0)
 4967             return 0;
 4968         ia->ia_iobase = slot << 12;
 4969         ia->ia_iosize = EISA_NPORT;
 4970         eisa_slotalloc(slot);
 4971         tmp = inb(ia->ia_iobase + DE425_CFG0);
 4972         irq = tulip_eisa_irqs[(tmp >> 1) & 0x03];
 4973         /*
 4974          * Until BSD/OS likes level interrupts, force
 4975          * the DE425 into edge-triggered mode.
 4976          */
 4977         if ((tmp & 1) == 0)
 4978             outb(ia->ia_iobase + DE425_CFG0, tmp | 1);
 4979         /*
 4980          * CBIO needs to map to the EISA slot
 4981          * enable I/O access and Master
 4982          */
 4983         outl(ia->ia_iobase + DE425_CBIO, ia->ia_iobase);
 4984         outl(ia->ia_iobase + DE425_CFCS, 5 | inl(ia->ia_iobase + DE425_CFCS));
 4985         ia->ia_aux = NULL;
 4986         break;
 4987     }
 4988 #endif /* TULIP_EISA */
 4989     default:
 4990         return 0;
 4991     }
 4992 #endif
 4993 
 4994     /* PCI bus masters don't use host DMA channels */
 4995     ia->ia_drq = DRQNONE;
 4996 
 4997     if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) {
 4998         printf("de%d: error: desired IRQ of %d does not match device's "
 4999             "actual IRQ of %d,\n",
 5000                cf->cf_unit,
 5001                ffs(ia->ia_irq) - 1, ffs(irq) - 1);
 5002         return 0;
 5003     }
 5004     if (ia->ia_irq == IRQUNK)
 5005         ia->ia_irq = irq;
 5006 #ifdef IRQSHARE
 5007     ia->ia_irq |= IRQSHARE;
 5008 #endif
 5009     return 1;
 5010 }
 5011 
 5012 static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
 5013 
 5014 #if defined(TULIP_EISA)
 5015 static char *tulip_eisa_ids[] = {
 5016     "DEC4250",
 5017     NULL
 5018 };
 5019 #endif
 5020 
 5021 struct cfdriver decd = {
 5022     0, "de", tulip_probe, tulip_pci_attach,
 5023 #if _BSDI_VERSION >= 199401
 5024     DV_IFNET,
 5025 #endif
 5026     sizeof(tulip_softc_t),
 5027 #if defined(TULIP_EISA)
 5028     tulip_eisa_ids
 5029 #endif
 5030 };
 5031 
 5032 #endif /* __bsdi__ */
 5033 
 5034 #if defined(__NetBSD__)
 5035 #define TULIP_PCI_ATTACH_ARGS   struct device * const parent, struct device * const self, void * const aux
 5036 #define TULIP_SHUTDOWN_ARGS     void *arg
 5037 static int
 5038 tulip_pci_probe(
 5039     struct device *parent,
 5040 #ifdef __BROKEN_INDIRECT_CONFIG
 5041     void *match,
 5042 #else
 5043     struct cfdata *match,
 5044 #endif
 5045     void *aux)
 5046 {
 5047     struct pci_attach_args *pa = (struct pci_attach_args *) aux;
 5048 
 5049     if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID)
 5050         return 0;
 5051     if (PCI_CHIPID(pa->pa_id) == CHIPID_21040
 5052             || PCI_CHIPID(pa->pa_id) == CHIPID_21041
 5053             || PCI_CHIPID(pa->pa_id) == CHIPID_21140
 5054             || PCI_CHIPID(pa->pa_id) == CHIPID_21142)
 5055         return 1;
 5056 
 5057     return 0;
 5058 }
 5059 
 5060 static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
 5061 
 5062 struct cfattach de_ca = {
 5063     sizeof(tulip_softc_t), tulip_pci_probe, tulip_pci_attach
 5064 };
 5065 
 5066 struct cfdriver de_cd = {
 5067     0, "de", DV_IFNET
 5068 };
 5069 
 5070 #endif /* __NetBSD__ */
 5071 
 5072 static void
 5073 tulip_shutdown(
 5074     TULIP_SHUTDOWN_ARGS)
 5075 {
 5076     tulip_softc_t * const sc = arg;
 5077     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
 5078     DELAY(10);  /* Wait 10 microseconds (actually 50 PCI cycles but at 
 5079                    33MHz that comes to two microseconds but wait a
 5080                    bit longer anyways) */
 5081 }
 5082 
 5083 static void
 5084 tulip_pci_attach(
 5085     TULIP_PCI_ATTACH_ARGS)
 5086 {
 5087 #if defined(__FreeBSD__)
 5088     tulip_softc_t *sc;
 5089 #define PCI_CONF_WRITE(r, v)    pci_conf_write(config_id, (r), (v))
 5090 #define PCI_CONF_READ(r)        pci_conf_read(config_id, (r))
 5091 #define PCI_GETBUSDEVINFO(sc)   ((void)((sc)->tulip_pci_busno = ((config_id.cfg1 >> 16) & 0xFF), /* XXX */ \
 5092                                         (sc)->tulip_pci_devno = ((config_id.cfg1 >> 11) & 0x1F))) /* XXX */
 5093 #endif
 5094 #if defined(__bsdi__)
 5095     tulip_softc_t * const sc = (tulip_softc_t *) self;
 5096     struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
 5097     pci_devaddr_t *pa = (pci_devaddr_t *) ia->ia_aux;
 5098     const int unit = sc->tulip_dev.dv_unit;
 5099 #define PCI_CONF_WRITE(r, v)    pci_outl(pa, (r), (v))
 5100 #define PCI_CONF_READ(r)        pci_inl(pa, (r))
 5101 #define PCI_GETBUSDEVINFO(sc)   ((void)((sc)->tulip_pci_busno = pa->d_bus, \
 5102                                         (sc)->tulip_pci_devno = pa->d_agent))
 5103 #endif
 5104 #if defined(__NetBSD__)
 5105     tulip_softc_t * const sc = (tulip_softc_t *) self;
 5106     struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
 5107     const int unit = sc->tulip_dev.dv_unit;
 5108 #define PCI_CONF_WRITE(r, v)    pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
 5109 #define PCI_CONF_READ(r)        pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
 5110 #define PCI_GETBUSDEVINFO(sc)   do { \
 5111         (sc)->tulip_pci_busno = parent; \
 5112         (sc)->tulip_pci_devno = pa->pa_device; \
 5113     } while (0)
 5114 #endif /* __NetBSD__ */
 5115 #if defined(__alpha__)
 5116     tulip_media_t media = TULIP_MEDIA_UNKNOWN;
 5117 #endif
 5118     int retval, idx;
 5119     u_int32_t revinfo, cfdainfo, id;
 5120 #if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__)
 5121     vm_offset_t pa_csrs;
 5122 #endif
 5123     unsigned csroffset = TULIP_PCI_CSROFFSET;
 5124     unsigned csrsize = TULIP_PCI_CSRSIZE;
 5125     tulip_csrptr_t csr_base;
 5126     tulip_chipid_t chipid = TULIP_CHIPID_UNKNOWN;
 5127 
 5128     if (unit >= TULIP_MAX_DEVICES) {
 5129 #ifdef __FreeBSD__
 5130         printf("de%d", unit);
 5131 #endif
 5132         printf(": not configured; limit of %d reached or exceeded\n",
 5133                TULIP_MAX_DEVICES);
 5134         return;
 5135     }
 5136 
 5137 #if defined(__bsdi__)
 5138     if (pa != NULL) {
 5139         revinfo = pci_inl(pa, PCI_CFRV) & 0xFF;
 5140         id = pci_inl(pa, PCI_CFID);
 5141         cfdainfo = pci_inl(pa, PCI_CFDA);
 5142 #if defined(TULIP_EISA)
 5143     } else {
 5144         revinfo = inl(ia->ia_iobase + DE425_CFRV) & 0xFF;
 5145         csroffset = TULIP_EISA_CSROFFSET;
 5146         csrsize = TULIP_EISA_CSRSIZE;
 5147         chipid = TULIP_DE425;
 5148         cfdainfo = 0;
 5149 #endif /* TULIP_EISA */
 5150     }
 5151 #else /* __bsdi__ */
 5152     revinfo  = PCI_CONF_READ(PCI_CFRV) & 0xFF;
 5153     id       = PCI_CONF_READ(PCI_CFID);
 5154     cfdainfo = PCI_CONF_READ(PCI_CFDA);
 5155 #endif /* __bsdi__ */
 5156 
 5157     if (PCI_VENDORID(id) == DEC_VENDORID) {
 5158         if (PCI_CHIPID(id) == CHIPID_21040) chipid = TULIP_21040;
 5159         else if (PCI_CHIPID(id) == CHIPID_21140) {
 5160             chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140;
 5161         } else if (PCI_CHIPID(id) == CHIPID_21142) {
 5162             chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142;
 5163         }
 5164         else if (PCI_CHIPID(id) == CHIPID_21041) chipid = TULIP_21041;
 5165         else if (PCI_CHIPID(id) == CHIPID_21142) chipid = TULIP_21142;
 5166     }
 5167     if (chipid == TULIP_CHIPID_UNKNOWN)
 5168         return;
 5169 
 5170     if ((chipid == TULIP_21040 || chipid == TULIP_DE425) && revinfo < 0x20) {
 5171 #ifdef __FreeBSD__
 5172         printf("de%d", unit);
 5173 #endif
 5174         printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
 5175                revinfo >> 4, revinfo & 0x0f);
 5176         return;
 5177     } else if (chipid == TULIP_21140 && revinfo < 0x11) {
 5178 #ifndef __FreeBSD__
 5179         printf("\n");
 5180 #endif
 5181         printf("de%d: not configured; 21140 pass 1.1 required (%d.%d found)\n",
 5182                unit, revinfo >> 4, revinfo & 0x0f);
 5183         return;
 5184     }
 5185 
 5186 #if defined(__FreeBSD__)
 5187     sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
 5188     if (sc == NULL)
 5189         return;
 5190     bzero(sc, sizeof(*sc));                             /* Zero out the softc*/
 5191     sc->tulip_rxdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT);
 5192     sc->tulip_txdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_TXDESCS, M_DEVBUF, M_NOWAIT);
 5193     if (sc->tulip_rxdescs == NULL || sc->tulip_txdescs == NULL) {
 5194         if (sc->tulip_rxdescs)
 5195             free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
 5196         if (sc->tulip_txdescs)
 5197             free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
 5198         free((caddr_t) sc, M_DEVBUF);
 5199         return;
 5200     }
 5201 #endif
 5202 
 5203     PCI_GETBUSDEVINFO(sc);
 5204     sc->tulip_chipid = chipid;
 5205     sc->tulip_flags |= TULIP_DEVICEPROBE;
 5206     if (chipid == TULIP_21140 || chipid == TULIP_21140A)
 5207         sc->tulip_features |= TULIP_HAVE_GPR|TULIP_HAVE_STOREFWD;
 5208     if (chipid == TULIP_21140A && revinfo <= 0x22)
 5209         sc->tulip_features |= TULIP_HAVE_RXBADOVRFLW;
 5210     if (chipid == TULIP_21140)
 5211         sc->tulip_features |= TULIP_HAVE_BROKEN_HASH;
 5212     if (chipid != TULIP_21040 && chipid != TULIP_DE425 && chipid != TULIP_21140)
 5213         sc->tulip_features |= TULIP_HAVE_POWERMGMT;
 5214     if (chipid == TULIP_21041 || chipid == TULIP_21142 || chipid == TULIP_21143) {
 5215         sc->tulip_features |= TULIP_HAVE_DUALSENSE;
 5216         if (chipid != TULIP_21041 || sc->tulip_revinfo >= 0x20)
 5217             sc->tulip_features |= TULIP_HAVE_SIANWAY;
 5218         if (chipid != TULIP_21041)
 5219             sc->tulip_features |= TULIP_HAVE_SIAGP|TULIP_HAVE_RXBADOVRFLW|TULIP_HAVE_STOREFWD;
 5220         if (chipid != TULIP_21041 && sc->tulip_revinfo >= 0x20)
 5221             sc->tulip_features |= TULIP_HAVE_SIA100;
 5222     }
 5223 
 5224     if (sc->tulip_features & TULIP_HAVE_POWERMGMT
 5225             && (cfdainfo & (TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE))) {
 5226         cfdainfo &= ~(TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE);
 5227         PCI_CONF_WRITE(PCI_CFDA, cfdainfo);
 5228         DELAY(11*1000);
 5229     }
 5230 #if defined(__alpha__) && defined(__NetBSD__)
 5231     /*
 5232      * The Alpha SRM console encodes a console set media in the driver
 5233      * part of the CFDA register.  Note that the Multia presents a
 5234      * problem in that its BNC mode is really EXTSIA.  So in that case
 5235      * force a probe.
 5236      */
 5237     switch ((cfdainfo >> 8) & 0xff) {
 5238     case 1: media = chipid > TULIP_DE425 ?
 5239         TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC; break;
 5240     case 2: media = chipid > TULIP_DE425 ?
 5241         TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN; break;
 5242     case 3: media = TULIP_MEDIA_10BASET; break;
 5243     case 4: media = TULIP_MEDIA_10BASET_FD; break;
 5244     case 5: media = TULIP_MEDIA_100BASETX; break;
 5245     case 6: media = TULIP_MEDIA_100BASETX_FD; break;
 5246     }
 5247 #endif
 5248 
 5249 #if defined(__NetBSD__)
 5250     bcopy(self->dv_xname, sc->tulip_if.if_xname, IFNAMSIZ);
 5251     sc->tulip_if.if_softc = sc;
 5252     sc->tulip_pc = pa->pa_pc;
 5253 #else
 5254     sc->tulip_unit = unit;
 5255     sc->tulip_name = "de";
 5256 #endif
 5257     sc->tulip_revinfo = revinfo;
 5258 #if defined(__FreeBSD__)
 5259 #if BSD >= 199506
 5260     sc->tulip_if.if_softc = sc;
 5261 #endif
 5262 #if defined(TULIP_IOMAPPED)
 5263     retval = pci_map_port(config_id, PCI_CBIO, &csr_base);
 5264 #else
 5265     retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &csr_base, &pa_csrs);
 5266 #endif
 5267     if (!retval) {
 5268         free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
 5269         free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
 5270         free((caddr_t) sc, M_DEVBUF);
 5271         return;
 5272     }
 5273     tulips[unit] = sc;
 5274 #endif /* __FreeBSD__ */
 5275 
 5276 #if defined(__bsdi__)
 5277     sc->tulip_pf = printf;
 5278 #if defined(TULIP_IOMAPPED)
 5279     csr_base = ia->ia_iobase;
 5280 #else
 5281     csr_base = (vm_offset_t) mapphys((vm_offset_t) ia->ia_maddr, ia->ia_msize);
 5282 #endif
 5283 #endif /* __bsdi__ */
 5284 
 5285 #if defined(__NetBSD__)
 5286     csr_base = 0;
 5287     {
 5288         bus_space_tag_t iot, memt;
 5289         bus_space_handle_t ioh, memh;
 5290         int ioh_valid, memh_valid;
 5291 
 5292         ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
 5293                                     &iot, &ioh, NULL, NULL) == 0);
 5294         memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
 5295                                      PCI_MAPREG_TYPE_MEM |
 5296                                      PCI_MAPREG_MEM_TYPE_32BIT,
 5297                                      0, &memt, &memh, NULL, NULL) == 0);
 5298         if (memh_valid) {
 5299             sc->tulip_bustag = memt;
 5300             sc->tulip_bushandle = memh;
 5301         } else if (ioh_valid) {
 5302             sc->tulip_bustag = iot;
 5303             sc->tulip_bushandle = ioh;
 5304         } else {
 5305             printf(": unable to map device registers\n");
 5306             return;
 5307         }
 5308     }
 5309 #endif /* __NetBSD__ */
 5310 
 5311     tulip_initcsrs(sc, csr_base + csroffset, csrsize);
 5312     tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS);
 5313     tulip_initring(sc, &sc->tulip_txinfo, sc->tulip_txdescs, TULIP_TXDESCS);
 5314 
 5315     /*
 5316      * Make sure there won't be any interrupts or such...
 5317      */
 5318     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
 5319     DELAY(100); /* Wait 10 microseconds (actually 50 PCI cycles but at 
 5320                    33MHz that comes to two microseconds but wait a
 5321                    bit longer anyways) */
 5322 
 5323     if ((retval = tulip_read_macaddr(sc)) < 0) {
 5324 #if defined(__FreeBSD__)
 5325         printf(TULIP_PRINTF_FMT, TULIP_PRINTF_ARGS);
 5326 #endif
 5327         printf(": can't read ENET ROM (why=%d) (", retval);
 5328         for (idx = 0; idx < 32; idx++)
 5329             printf("%02x", sc->tulip_rombuf[idx]);
 5330         printf("\n");
 5331         printf(TULIP_PRINTF_FMT ": %s%s pass %d.%d\n",
 5332                TULIP_PRINTF_ARGS,
 5333                sc->tulip_boardid, tulip_chipdescs[sc->tulip_chipid],
 5334                (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
 5335         printf(TULIP_PRINTF_FMT ": address unknown\n", TULIP_PRINTF_ARGS);
 5336     } else {
 5337         tulip_spl_t s;
 5338         tulip_intrfunc_t (*intr_rtn)(void *) = tulip_intr_normal;
 5339 
 5340         if (sc->tulip_features & TULIP_HAVE_SHAREDINTR)
 5341             intr_rtn = tulip_intr_shared;
 5342 
 5343 #if defined(__NetBSD__)
 5344         if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
 5345             pci_intr_handle_t intrhandle;
 5346             const char *intrstr;
 5347 
 5348             if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
 5349                              pa->pa_intrline, &intrhandle)) {
 5350                 printf(": couldn't map interrupt\n");
 5351                 return;
 5352             }
 5353             intrstr = pci_intr_string(pa->pa_pc, intrhandle);
 5354             sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
 5355                                               intr_rtn, sc);
 5356             if (sc->tulip_ih == NULL)
 5357                 printf(": couldn't establish interrupt");
 5358             if (intrstr != NULL)
 5359                 printf(" at %s", intrstr);
 5360             printf("\n");
 5361             if (sc->tulip_ih == NULL)
 5362                 return;
 5363         }
 5364         sc->tulip_ats = shutdownhook_establish(tulip_shutdown, sc);
 5365         if (sc->tulip_ats == NULL)
 5366             printf("\n%s: warning: couldn't establish shutdown hook\n",
 5367                    sc->tulip_xname);
 5368 #endif
 5369 #if defined(__FreeBSD__)
 5370         if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
 5371             if (!pci_map_int (config_id, intr_rtn, (void*) sc, &net_imask)) {
 5372                 printf(TULIP_PRINTF_FMT ": couldn't map interrupt\n",
 5373                        TULIP_PRINTF_ARGS);
 5374                 return;
 5375             }
 5376         }
 5377 #if !defined(TULIP_DEVCONF)
 5378         at_shutdown(tulip_shutdown, sc, SHUTDOWN_POST_SYNC);
 5379 #endif
 5380 #endif
 5381 #if defined(__bsdi__)
 5382         if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
 5383             isa_establish(&sc->tulip_id, &sc->tulip_dev);
 5384 
 5385             sc->tulip_ih.ih_fun = intr_rtn;
 5386             sc->tulip_ih.ih_arg = (void *) sc;
 5387             intr_establish(ia->ia_irq, &sc->tulip_ih, DV_NET);
 5388         }
 5389 
 5390         sc->tulip_ats.func = tulip_shutdown;
 5391         sc->tulip_ats.arg = (void *) sc;
 5392         atshutdown(&sc->tulip_ats, ATSH_ADD);
 5393 #endif
 5394 #if defined(TULIP_USE_SOFTINTR)
 5395         if (sc->tulip_unit > tulip_softintr_max_unit)
 5396             tulip_softintr_max_unit = sc->tulip_unit;
 5397 #endif
 5398 
 5399         s = TULIP_RAISESPL();
 5400         tulip_reset(sc);
 5401         tulip_attach(sc);
 5402 #if defined(__alpha__) && defined(__NetBSD__)
 5403         if (media != TULIP_MEDIA_UNKNOWN)
 5404             tulip_linkup(sc, media);
 5405 #endif
 5406         TULIP_RESTORESPL(s);
 5407     }
 5408 }

Cache object: ac0d361632c9f9dbe1df0fc288a75716


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