LCOV - code coverage report
Current view: top level - dev/pci - if_de.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 2199 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 76 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13