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