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