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

Cache object: f6693f365c4104fc2b4e81608fac3f74


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