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