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