if_de.c revision 43391
1/*	$NetBSD: if_de.c,v 1.80 1998/09/25 18:06:53 matt Exp $	*/
2/*	$Id: if_de.c,v 1.97 1999/01/29 08:29:05 bde 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 = (const tulip_srom_header_t *) &sc->tulip_rombuf[0];
2394    const tulip_srom_adapter_info_t *saip = (const 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(shp->sh_ieee802_address, 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(sc->tulip_enaddr, tulip_vendors[idx].vendor_oui, 3) == 0) {
2976	    (*tulip_vendors[idx].vendor_identify_nic)(sc);
2977	    break;
2978	}
2979    }
2980
2981    sc->tulip_features |= TULIP_HAVE_OKROM;
2982    return 0;
2983}
2984
2985#if defined(IFM_ETHER)
2986static void
2987tulip_ifmedia_add(
2988    tulip_softc_t * const sc)
2989{
2990    tulip_media_t media;
2991    int medias = 0;
2992
2993    for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
2994	if (sc->tulip_mediums[media] != NULL) {
2995	    ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
2996			0, 0);
2997	    medias++;
2998	}
2999    }
3000    if (medias == 0) {
3001	sc->tulip_features |= TULIP_HAVE_NOMEDIA;
3002	ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE, 0, 0);
3003	ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE);
3004    } else if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
3005	ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
3006	ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO);
3007    } else {
3008	ifmedia_set(&sc->tulip_ifmedia, tulip_media_to_ifmedia[sc->tulip_media]);
3009	sc->tulip_flags |= TULIP_PRINTMEDIA;
3010	tulip_linkup(sc, sc->tulip_media);
3011    }
3012}
3013
3014static int
3015tulip_ifmedia_change(
3016    struct ifnet * const ifp)
3017{
3018    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
3019
3020    sc->tulip_flags |= TULIP_NEEDRESET;
3021    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
3022    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
3023    if (IFM_SUBTYPE(sc->tulip_ifmedia.ifm_media) != IFM_AUTO) {
3024	tulip_media_t media;
3025	for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
3026	    if (sc->tulip_mediums[media] != NULL
3027		&& sc->tulip_ifmedia.ifm_media == tulip_media_to_ifmedia[media]) {
3028		sc->tulip_flags |= TULIP_PRINTMEDIA;
3029		sc->tulip_flags &= ~TULIP_DIDNWAY;
3030		tulip_linkup(sc, media);
3031		return 0;
3032	    }
3033	}
3034    }
3035    sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
3036    tulip_reset(sc);
3037    tulip_init(sc);
3038    return 0;
3039}
3040
3041/*
3042 * Media status callback
3043 */
3044static void
3045tulip_ifmedia_status(
3046    struct ifnet * const ifp,
3047    struct ifmediareq *req)
3048{
3049    tulip_softc_t *sc = TULIP_IFP_TO_SOFTC(ifp);
3050
3051#if defined(__bsdi__)
3052    if (sc->tulip_mii.mii_instance != 0) {
3053	mii_pollstat(&sc->tulip_mii);
3054	req->ifm_active = sc->tulip_mii.mii_media_active;
3055	req->ifm_status = sc->tulip_mii.mii_media_status;
3056	return;
3057    }
3058#endif
3059    if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
3060	return;
3061
3062    req->ifm_status = IFM_AVALID;
3063    if (sc->tulip_flags & TULIP_LINKUP)
3064	req->ifm_status |= IFM_ACTIVE;
3065
3066    req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
3067}
3068#endif
3069
3070static void
3071tulip_addr_filter(
3072    tulip_softc_t * const sc)
3073{
3074#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
3075    struct ifmultiaddr *ifma;
3076    u_char *addrp;
3077#else
3078    struct ether_multistep step;
3079    struct ether_multi *enm;
3080#endif
3081    int multicnt;
3082
3083    sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
3084    sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
3085    sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
3086    sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
3087#if defined(IFF_ALLMULTI)
3088    sc->tulip_if.if_flags &= ~IFF_ALLMULTI;
3089#endif
3090
3091#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
3092    multicnt = 0;
3093    for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
3094	 ifma = ifma->ifma_link.le_next) {
3095
3096	    if (ifma->ifma_addr->sa_family == AF_LINK)
3097		multicnt++;
3098    }
3099#else
3100    multicnt = sc->tulip_multicnt;
3101#endif
3102
3103    sc->tulip_if.if_start = tulip_ifstart;	/* so the setup packet gets queued */
3104    if (multicnt > 14) {
3105	u_int32_t *sp = sc->tulip_setupdata;
3106	unsigned hash;
3107	/*
3108	 * Some early passes of the 21140 have broken implementations of
3109	 * hash-perfect mode.  When we get too many multicasts for perfect
3110	 * filtering with these chips, we need to switch into hash-only
3111	 * mode (this is better than all-multicast on network with lots
3112	 * of multicast traffic).
3113	 */
3114	if (sc->tulip_features & TULIP_HAVE_BROKEN_HASH)
3115	    sc->tulip_flags |= TULIP_WANTHASHONLY;
3116	else
3117	    sc->tulip_flags |= TULIP_WANTHASHPERFECT;
3118	/*
3119	 * If we have more than 14 multicasts, we have
3120	 * go into hash perfect mode (512 bit multicast
3121	 * hash and one perfect hardware).
3122	 */
3123	bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
3124
3125#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
3126	for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
3127	     ifma = ifma->ifma_link.le_next) {
3128
3129		if (ifma->ifma_addr->sa_family != AF_LINK)
3130			continue;
3131
3132		hash = tulip_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
3133		sp[hash >> 4] |= 1 << (hash & 0xF);
3134	}
3135#else
3136	ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm);
3137	while (enm != NULL) {
3138		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
3139		    hash = tulip_mchash(enm->enm_addrlo);
3140		    sp[hash >> 4] |= 1 << (hash & 0xF);
3141		} else {
3142		    sc->tulip_flags |= TULIP_ALLMULTI;
3143		    sc->tulip_flags &= ~(TULIP_WANTHASHONLY|TULIP_WANTHASHPERFECT);
3144		    break;
3145		}
3146		ETHER_NEXT_MULTI(step, enm);
3147	}
3148#endif
3149	/*
3150	 * No reason to use a hash if we are going to be
3151	 * receiving every multicast.
3152	 */
3153	if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
3154	    hash = tulip_mchash(etherbroadcastaddr);
3155	    sp[hash >> 4] |= 1 << (hash & 0xF);
3156	    if (sc->tulip_flags & TULIP_WANTHASHONLY) {
3157		hash = tulip_mchash(sc->tulip_enaddr);
3158		sp[hash >> 4] |= 1 << (hash & 0xF);
3159	    } else {
3160		sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0];
3161		sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1];
3162		sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2];
3163	    }
3164	}
3165    }
3166    if ((sc->tulip_flags & (TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY)) == 0) {
3167	u_int32_t *sp = sc->tulip_setupdata;
3168	int idx = 0;
3169	if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
3170	    /*
3171	     * Else can get perfect filtering for 16 addresses.
3172	     */
3173#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
3174	    for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
3175		 ifma = ifma->ifma_link.le_next) {
3176		    if (ifma->ifma_addr->sa_family != AF_LINK)
3177			    continue;
3178		    addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
3179		    *sp++ = ((u_int16_t *) addrp)[0];
3180		    *sp++ = ((u_int16_t *) addrp)[1];
3181		    *sp++ = ((u_int16_t *) addrp)[2];
3182		    idx++;
3183	    }
3184#else
3185	    ETHER_FIRST_MULTI(step, TULIP_ETHERCOM(sc), enm);
3186	    for (; enm != NULL; idx++) {
3187		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
3188		    *sp++ = ((u_int16_t *) enm->enm_addrlo)[0];
3189		    *sp++ = ((u_int16_t *) enm->enm_addrlo)[1];
3190		    *sp++ = ((u_int16_t *) enm->enm_addrlo)[2];
3191		} else {
3192		    sc->tulip_flags |= TULIP_ALLMULTI;
3193		    break;
3194		}
3195		ETHER_NEXT_MULTI(step, enm);
3196	    }
3197#endif
3198	    /*
3199	     * Add the broadcast address.
3200	     */
3201	    idx++;
3202	    *sp++ = 0xFFFF;
3203	    *sp++ = 0xFFFF;
3204	    *sp++ = 0xFFFF;
3205	}
3206	/*
3207	 * Pad the rest with our hardware address
3208	 */
3209	for (; idx < 16; idx++) {
3210	    *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0];
3211	    *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1];
3212	    *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2];
3213	}
3214    }
3215#if defined(IFF_ALLMULTI)
3216    if (sc->tulip_flags & TULIP_ALLMULTI)
3217	sc->tulip_if.if_flags |= IFF_ALLMULTI;
3218#endif
3219}
3220
3221static void
3222tulip_reset(
3223    tulip_softc_t * const sc)
3224{
3225    tulip_ringinfo_t *ri;
3226    tulip_desc_t *di;
3227    u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
3228
3229    /*
3230     * Brilliant.  Simply brilliant.  When switching modes/speeds
3231     * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
3232     * bits in CSR6 and then do a software reset to get the 21140
3233     * to properly reset its internal pathways to the right places.
3234     *   Grrrr.
3235     */
3236    if (sc->tulip_boardsw->bd_media_preset != NULL)
3237	(*sc->tulip_boardsw->bd_media_preset)(sc);
3238
3239    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3240    DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
3241		   33MHz that comes to two microseconds but wait a
3242		   bit longer anyways) */
3243
3244    if (!inreset) {
3245	sc->tulip_flags |= TULIP_INRESET;
3246	sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW);
3247	sc->tulip_if.if_flags &= ~IFF_OACTIVE;
3248	sc->tulip_if.if_start = tulip_ifstart;
3249    }
3250
3251#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3252    TULIP_CSR_WRITE(sc, csr_txlist, sc->tulip_txdescmap->dm_segs[0].ds_addr);
3253#else
3254    TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0]));
3255#endif
3256#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3257    TULIP_CSR_WRITE(sc, csr_rxlist, sc->tulip_rxdescmap->dm_segs[0].ds_addr);
3258#else
3259    TULIP_CSR_WRITE(sc, csr_rxlist, TULIP_KVATOPHYS(sc, &sc->tulip_rxinfo.ri_first[0]));
3260#endif
3261    TULIP_CSR_WRITE(sc, csr_busmode,
3262		    (1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8))
3263		    |TULIP_BUSMODE_CACHE_ALIGN8
3264		    |TULIP_BUSMODE_READMULTIPLE
3265		    |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0));
3266
3267    sc->tulip_txtimer = 0;
3268    sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS;
3269    /*
3270     * Free all the mbufs that were on the transmit ring.
3271     */
3272    for (;;) {
3273#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3274	bus_dmamap_t map;
3275#endif
3276	struct mbuf *m;
3277	IF_DEQUEUE(&sc->tulip_txq, m);
3278	if (m == NULL)
3279	    break;
3280#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3281	map = M_GETCTX(m, bus_dmamap_t);
3282	bus_dmamap_unload(sc->tulip_dmatag, map);
3283	sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
3284#endif
3285	m_freem(m);
3286    }
3287
3288    ri = &sc->tulip_txinfo;
3289    ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3290    ri->ri_free = ri->ri_max;
3291    for (di = ri->ri_first; di < ri->ri_last; di++)
3292	di->d_status = 0;
3293#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3294    bus_dmamap_sync(sc->tulip_dmatag, sc->tulip_txdescmap,
3295		    0, sc->tulip_txdescmap->dm_mapsize,
3296		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3297#endif
3298
3299    /*
3300     * We need to collect all the mbufs were on the
3301     * receive ring before we reinit it either to put
3302     * them back on or to know if we have to allocate
3303     * more.
3304     */
3305    ri = &sc->tulip_rxinfo;
3306    ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3307    ri->ri_free = ri->ri_max;
3308    for (di = ri->ri_first; di < ri->ri_last; di++) {
3309	di->d_status = 0;
3310	di->d_length1 = 0; di->d_addr1 = 0;
3311	di->d_length2 = 0; di->d_addr2 = 0;
3312    }
3313#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3314    bus_dmamap_sync(sc->tulip_dmatag, sc->tulip_rxdescmap,
3315		    0, sc->tulip_rxdescmap->dm_mapsize,
3316		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3317#endif
3318    for (;;) {
3319#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3320	bus_dmamap_t map;
3321#endif
3322	struct mbuf *m;
3323	IF_DEQUEUE(&sc->tulip_rxq, m);
3324	if (m == NULL)
3325	    break;
3326#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3327	map = M_GETCTX(m, bus_dmamap_t);
3328	bus_dmamap_unload(sc->tulip_dmatag, map);
3329	sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map;
3330#endif
3331	m_freem(m);
3332    }
3333
3334    /*
3335     * If tulip_reset is being called recurisvely, exit quickly knowing
3336     * that when the outer tulip_reset returns all the right stuff will
3337     * have happened.
3338     */
3339    if (inreset)
3340	return;
3341
3342    sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
3343	|TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
3344	|TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE
3345	|TULIP_STS_RXSTOPPED;
3346
3347    if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
3348	(*sc->tulip_boardsw->bd_media_select)(sc);
3349#if defined(TULIP_DEBUG)
3350    if ((sc->tulip_flags & TULIP_NEEDRESET) == TULIP_NEEDRESET)
3351	printf(TULIP_PRINTF_FMT ": tulip_reset: additional reset needed?!?\n",
3352	       TULIP_PRINTF_ARGS);
3353#endif
3354    tulip_media_print(sc);
3355    if (sc->tulip_features & TULIP_HAVE_DUALSENSE)
3356	TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
3357
3358    sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
3359			 |TULIP_RXACT);
3360    tulip_addr_filter(sc);
3361}
3362
3363static void
3364tulip_init(
3365    tulip_softc_t * const sc)
3366{
3367    if (sc->tulip_if.if_flags & IFF_UP) {
3368	if ((sc->tulip_if.if_flags & IFF_RUNNING) == 0) {
3369	    /* initialize the media */
3370	    tulip_reset(sc);
3371	}
3372	sc->tulip_if.if_flags |= IFF_RUNNING;
3373	if (sc->tulip_if.if_flags & IFF_PROMISC) {
3374	    sc->tulip_flags |= TULIP_PROMISC;
3375	    sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
3376	    sc->tulip_intrmask |= TULIP_STS_TXINTR;
3377	} else {
3378	    sc->tulip_flags &= ~TULIP_PROMISC;
3379	    sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
3380	    if (sc->tulip_flags & TULIP_ALLMULTI) {
3381		sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
3382	    } else {
3383		sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI;
3384	    }
3385	}
3386	sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
3387	if ((sc->tulip_flags & (TULIP_TXPROBE_ACTIVE|TULIP_WANTSETUP)) == 0) {
3388	    tulip_rx_intr(sc);
3389	    sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3390	    sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3391	} else {
3392	    sc->tulip_if.if_flags |= IFF_OACTIVE;
3393	    sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
3394	    sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
3395	}
3396	TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3397	TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3398	if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
3399	    tulip_txput_setup(sc);
3400    } else {
3401	sc->tulip_if.if_flags &= ~IFF_RUNNING;
3402	tulip_reset(sc);
3403    }
3404}
3405
3406static void
3407tulip_rx_intr(
3408    tulip_softc_t * const sc)
3409{
3410    TULIP_PERFSTART(rxintr)
3411    tulip_ringinfo_t * const ri = &sc->tulip_rxinfo;
3412    struct ifnet * const ifp = &sc->tulip_if;
3413    int fillok = 1;
3414#if defined(TULIP_DEBUG)
3415    int cnt = 0;
3416#endif
3417
3418    for (;;) {
3419	TULIP_PERFSTART(rxget)
3420	struct ether_header eh;
3421	tulip_desc_t *eop = ri->ri_nextin;
3422	int total_len = 0, last_offset = 0;
3423	struct mbuf *ms = NULL, *me = NULL;
3424	int accept = 0;
3425#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3426	bus_dmamap_t map;
3427	int error;
3428#endif
3429
3430	if (fillok && sc->tulip_rxq.ifq_len < TULIP_RXQ_TARGET)
3431	    goto queue_mbuf;
3432
3433#if defined(TULIP_DEBUG)
3434	if (cnt == ri->ri_max)
3435	    break;
3436#endif
3437	/*
3438	 * If the TULIP has no descriptors, there can't be any receive
3439	 * descriptors to process.
3440 	 */
3441	if (eop == ri->ri_nextout)
3442	    break;
3443
3444	/*
3445	 * 90% of the packets will fit in one descriptor.  So we optimize
3446	 * for that case.
3447	 */
3448	TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3449	if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
3450	    IF_DEQUEUE(&sc->tulip_rxq, ms);
3451	    me = ms;
3452	} else {
3453	    /*
3454	     * If still owned by the TULIP, don't touch it.
3455	     */
3456	    if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER)
3457		break;
3458
3459	    /*
3460	     * It is possible (though improbable unless the BIG_PACKET support
3461	     * is enabled or MCLBYTES < 1518) for a received packet to cross
3462	     * more than one receive descriptor.
3463	     */
3464	    while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
3465		if (++eop == ri->ri_last)
3466		    eop = ri->ri_first;
3467		TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3468		if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
3469#if defined(TULIP_DEBUG)
3470		    sc->tulip_dbg.dbg_rxintrs++;
3471		    sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
3472#endif
3473		    TULIP_PERFEND(rxget);
3474		    TULIP_PERFEND(rxintr);
3475		    return;
3476		}
3477		total_len++;
3478	    }
3479
3480	    /*
3481	     * Dequeue the first buffer for the start of the packet.  Hopefully
3482	     * this will be the only one we need to dequeue.  However, if the
3483	     * packet consumed multiple descriptors, then we need to dequeue
3484	     * those buffers and chain to the starting mbuf.  All buffers but
3485	     * the last buffer have the same length so we can set that now.
3486	     * (we add to last_offset instead of multiplying since we normally
3487	     * won't go into the loop and thereby saving a ourselves from
3488	     * doing a multiplication by 0 in the normal case).
3489	     */
3490	    IF_DEQUEUE(&sc->tulip_rxq, ms);
3491	    for (me = ms; total_len > 0; total_len--) {
3492#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3493		map = M_GETCTX(me, bus_dmamap_t);
3494		TULIP_RXMAP_POSTSYNC(sc, map);
3495		bus_dmamap_unload(sc->tulip_dmatag, map);
3496		sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map;
3497#if defined(DIAGNOSTIC)
3498		M_SETCTX(me, NULL);
3499#endif
3500#endif /* TULIP_BUS_DMA */
3501		me->m_len = TULIP_RX_BUFLEN;
3502		last_offset += TULIP_RX_BUFLEN;
3503		IF_DEQUEUE(&sc->tulip_rxq, me->m_next);
3504		me = me->m_next;
3505	    }
3506	}
3507
3508	/*
3509	 *  Now get the size of received packet (minus the CRC).
3510	 */
3511	total_len = ((eop->d_status >> 16) & 0x7FFF) - 4;
3512	if ((sc->tulip_flags & TULIP_RXIGNORE) == 0
3513		&& ((eop->d_status & TULIP_DSTS_ERRSUM) == 0
3514#ifdef BIG_PACKET
3515		     || (total_len <= sc->tulip_if.if_mtu + sizeof(struct ether_header) &&
3516			 (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxRUNT|
3517					  TULIP_DSTS_RxCOLLSEEN|TULIP_DSTS_RxBADCRC|
3518					  TULIP_DSTS_RxOVERFLOW)) == 0)
3519#endif
3520		)) {
3521	    me->m_len = total_len - last_offset;
3522
3523#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3524	    map = M_GETCTX(me, bus_dmamap_t);
3525	    bus_dmamap_sync(sc->tulip_dmatag, map, 0, me->m_len,
3526			    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3527	    bus_dmamap_unload(sc->tulip_dmatag, map);
3528	    sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map;
3529#if defined(DIAGNOSTIC)
3530	    M_SETCTX(me, NULL);
3531#endif
3532#endif /* TULIP_BUS_DMA */
3533
3534	    eh = *mtod(ms, struct ether_header *);
3535#if NBPFILTER > 0
3536	    if (sc->tulip_bpf != NULL) {
3537		if (me == ms)
3538		    TULIP_BPF_TAP(sc, mtod(ms, caddr_t), total_len);
3539		else
3540		    TULIP_BPF_MTAP(sc, ms);
3541	    }
3542#endif
3543	    sc->tulip_flags |= TULIP_RXACT;
3544	    if ((sc->tulip_flags & (TULIP_PROMISC|TULIP_HASHONLY))
3545		    && (eh.ether_dhost[0] & 1) == 0
3546		    && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_enaddr))
3547		    goto next;
3548	    accept = 1;
3549	    total_len -= sizeof(struct ether_header);
3550	} else {
3551	    ifp->if_ierrors++;
3552	    if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
3553		sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3554	    } else {
3555#if defined(TULIP_VERBOSE)
3556		const char *error = NULL;
3557#endif
3558		if (eop->d_status & TULIP_DSTS_RxTOOLONG) {
3559		    sc->tulip_dot3stats.dot3StatsFrameTooLongs++;
3560#if defined(TULIP_VERBOSE)
3561		    error = "frame too long";
3562#endif
3563		}
3564		if (eop->d_status & TULIP_DSTS_RxBADCRC) {
3565		    if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) {
3566			sc->tulip_dot3stats.dot3StatsAlignmentErrors++;
3567#if defined(TULIP_VERBOSE)
3568			error = "alignment error";
3569#endif
3570		    } else {
3571			sc->tulip_dot3stats.dot3StatsFCSErrors++;
3572#if defined(TULIP_VERBOSE)
3573			error = "bad crc";
3574#endif
3575		    }
3576		}
3577#if defined(TULIP_VERBOSE)
3578		if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) {
3579		    printf(TULIP_PRINTF_FMT ": receive: " TULIP_EADDR_FMT ": %s\n",
3580			   TULIP_PRINTF_ARGS,
3581			   TULIP_EADDR_ARGS(mtod(ms, u_char *) + 6),
3582			   error);
3583		    sc->tulip_flags |= TULIP_NOMESSAGES;
3584		}
3585#endif
3586	    }
3587
3588#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3589	    map = M_GETCTX(me, bus_dmamap_t);
3590	    bus_dmamap_unload(sc->tulip_dmatag, map);
3591	    sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map;
3592#if defined(DIAGNOSTIC)
3593	    M_SETCTX(me, NULL);
3594#endif
3595#endif /* TULIP_BUS_DMA */
3596	}
3597      next:
3598#if defined(TULIP_DEBUG)
3599	cnt++;
3600#endif
3601	ifp->if_ipackets++;
3602	if (++eop == ri->ri_last)
3603	    eop = ri->ri_first;
3604	ri->ri_nextin = eop;
3605      queue_mbuf:
3606	/*
3607	 * Either we are priming the TULIP with mbufs (m == NULL)
3608	 * or we are about to accept an mbuf for the upper layers
3609	 * so we need to allocate an mbuf to replace it.  If we
3610	 * can't replace it, send up it anyways.  This may cause
3611	 * us to drop packets in the future but that's better than
3612	 * being caught in livelock.
3613	 *
3614	 * Note that if this packet crossed multiple descriptors
3615	 * we don't even try to reallocate all the mbufs here.
3616	 * Instead we rely on the test of the beginning of
3617	 * the loop to refill for the extra consumed mbufs.
3618	 */
3619	if (accept || ms == NULL) {
3620	    struct mbuf *m0;
3621	    MGETHDR(m0, M_DONTWAIT, MT_DATA);
3622	    if (m0 != NULL) {
3623#if defined(TULIP_COPY_RXDATA)
3624		if (!accept || total_len >= MHLEN) {
3625#endif
3626		    MCLGET(m0, M_DONTWAIT);
3627		    if ((m0->m_flags & M_EXT) == 0) {
3628			m_freem(m0);
3629			m0 = NULL;
3630		    }
3631#if defined(TULIP_COPY_RXDATA)
3632		}
3633#endif
3634	    }
3635	    if (accept
3636#if defined(TULIP_COPY_RXDATA)
3637		&& m0 != NULL
3638#endif
3639		) {
3640#if defined(__bsdi__)
3641		eh.ether_type = ntohs(eh.ether_type);
3642#endif
3643#if !defined(TULIP_COPY_RXDATA)
3644		ms->m_data += sizeof(struct ether_header);
3645		ms->m_len -= sizeof(struct ether_header);
3646		ms->m_pkthdr.len = total_len;
3647		ms->m_pkthdr.rcvif = ifp;
3648		ether_input(ifp, &eh, ms);
3649#else
3650#ifdef BIG_PACKET
3651#error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
3652#endif
3653		if (ms == me)
3654		    bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header),
3655			  mtod(m0, caddr_t), total_len);
3656		else
3657		    m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
3658		m0->m_len = m0->m_pkthdr.len = total_len;
3659		m0->m_pkthdr.rcvif = ifp;
3660		ether_input(ifp, &eh, m0);
3661		m0 = ms;
3662#endif
3663	    }
3664	    ms = m0;
3665	}
3666	if (ms == NULL) {
3667	    /*
3668	     * Couldn't allocate a new buffer.  Don't bother
3669	     * trying to replenish the receive queue.
3670	     */
3671	    fillok = 0;
3672	    sc->tulip_flags |= TULIP_RXBUFSLOW;
3673#if defined(TULIP_DEBUG)
3674	    sc->tulip_dbg.dbg_rxlowbufs++;
3675#endif
3676	    TULIP_PERFEND(rxget);
3677	    continue;
3678	}
3679	/*
3680	 * Now give the buffer(s) to the TULIP and save in our
3681	 * receive queue.
3682	 */
3683	do {
3684	    tulip_desc_t * const nextout = ri->ri_nextout;
3685#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3686	    if (sc->tulip_rxmaps_free > 0) {
3687		map = sc->tulip_rxmaps[--sc->tulip_rxmaps_free];
3688	    } else {
3689		m_freem(ms);
3690		sc->tulip_flags |= TULIP_RXBUFSLOW;
3691#if defined(TULIP_DEBUG)
3692		sc->tulip_dbg.dbg_rxlowbufs++;
3693#endif
3694		break;
3695	    }
3696	    M_SETCTX(ms, map);
3697	    error = bus_dmamap_load(sc->tulip_dmatag, map, mtod(ms, void *),
3698				    TULIP_RX_BUFLEN, NULL, BUS_DMA_NOWAIT);
3699	    if (error) {
3700		printf(TULIP_PRINTF_FMT ": unable to load rx map, "
3701		       "error = %d\n", TULIP_PRINTF_ARGS, error);
3702		panic("tulip_rx_intr");		/* XXX */
3703	    }
3704	    nextout->d_addr1 = map->dm_segs[0].ds_addr;
3705	    nextout->d_length1 = map->dm_segs[0].ds_len;
3706	    if (map->dm_nsegs == 2) {
3707		nextout->d_addr2 = map->dm_segs[1].ds_addr;
3708		nextout->d_length2 = map->dm_segs[1].ds_len;
3709	    } else {
3710		nextout->d_addr2 = 0;
3711		nextout->d_length2 = 0;
3712	    }
3713	    TULIP_RXDESC_POSTSYNC(sc, nextout, sizeof(*nextout));
3714#else /* TULIP_BUS_DMA */
3715	    nextout->d_addr1 = TULIP_KVATOPHYS(sc, mtod(ms, caddr_t));
3716	    nextout->d_length1 = TULIP_RX_BUFLEN;
3717#endif /* TULIP_BUS_DMA */
3718	    nextout->d_status = TULIP_DSTS_OWNER;
3719	    TULIP_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
3720	    if (++ri->ri_nextout == ri->ri_last)
3721		ri->ri_nextout = ri->ri_first;
3722	    me = ms->m_next;
3723	    ms->m_next = NULL;
3724	    IF_ENQUEUE(&sc->tulip_rxq, ms);
3725	} while ((ms = me) != NULL);
3726
3727	if (sc->tulip_rxq.ifq_len >= TULIP_RXQ_TARGET)
3728	    sc->tulip_flags &= ~TULIP_RXBUFSLOW;
3729	TULIP_PERFEND(rxget);
3730    }
3731
3732#if defined(TULIP_DEBUG)
3733    sc->tulip_dbg.dbg_rxintrs++;
3734    sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
3735#endif
3736    TULIP_PERFEND(rxintr);
3737}
3738
3739static int
3740tulip_tx_intr(
3741    tulip_softc_t * const sc)
3742{
3743    TULIP_PERFSTART(txintr)
3744    tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3745    struct mbuf *m;
3746    int xmits = 0;
3747    int descs = 0;
3748
3749    while (ri->ri_free < ri->ri_max) {
3750	u_int32_t d_flag;
3751
3752	TULIP_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
3753	if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
3754	    break;
3755
3756	ri->ri_free++;
3757	descs++;
3758	d_flag = ri->ri_nextin->d_flag;
3759	if (d_flag & TULIP_DFLAG_TxLASTSEG) {
3760	    if (d_flag & TULIP_DFLAG_TxSETUPPKT) {
3761		/*
3762		 * We've just finished processing a setup packet.
3763		 * Mark that we finished it.  If there's not
3764		 * another pending, startup the TULIP receiver.
3765		 * Make sure we ack the RXSTOPPED so we won't get
3766		 * an abormal interrupt indication.
3767		 */
3768		TULIP_TXMAP_POSTSYNC(sc, sc->tulip_setupmap);
3769		sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_HASHONLY);
3770		if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxINVRSFILT)
3771		    sc->tulip_flags |= TULIP_HASHONLY;
3772		if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == 0) {
3773		    tulip_rx_intr(sc);
3774		    sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3775		    sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3776		    TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3777		    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3778		    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3779		}
3780	    } else {
3781		const u_int32_t d_status = ri->ri_nextin->d_status;
3782		IF_DEQUEUE(&sc->tulip_txq, m);
3783		if (m != NULL) {
3784#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3785		    bus_dmamap_t map = M_GETCTX(m, bus_dmamap_t);
3786		    TULIP_TXMAP_POSTSYNC(sc, map);
3787		    sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
3788#endif /* TULIP_BUS_DMA */
3789#if NBPFILTER > 0
3790		    if (sc->tulip_bpf != NULL)
3791			TULIP_BPF_MTAP(sc, m);
3792#endif
3793		    m_freem(m);
3794#if defined(TULIP_DEBUG)
3795		} else {
3796		    printf(TULIP_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", TULIP_PRINTF_ARGS);
3797#endif
3798		}
3799		if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
3800		    tulip_mediapoll_event_t event = TULIP_MEDIAPOLL_TXPROBE_OK;
3801		    if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) {
3802#if defined(TULIP_DEBUG)
3803			if (d_status & TULIP_DSTS_TxNOCARR)
3804			    sc->tulip_dbg.dbg_txprobe_nocarr++;
3805			if (d_status & TULIP_DSTS_TxEXCCOLL)
3806			    sc->tulip_dbg.dbg_txprobe_exccoll++;
3807#endif
3808			event = TULIP_MEDIAPOLL_TXPROBE_FAILED;
3809		    }
3810		    (*sc->tulip_boardsw->bd_media_poll)(sc, event);
3811		    /*
3812		     * Escape from the loop before media poll has reset the TULIP!
3813		     */
3814		    break;
3815		} else {
3816		    xmits++;
3817		    if (d_status & TULIP_DSTS_ERRSUM) {
3818			sc->tulip_if.if_oerrors++;
3819			if (d_status & TULIP_DSTS_TxEXCCOLL)
3820			    sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
3821			if (d_status & TULIP_DSTS_TxLATECOLL)
3822			    sc->tulip_dot3stats.dot3StatsLateCollisions++;
3823			if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS))
3824			    sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
3825			if (d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
3826			    sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
3827			if (d_status & TULIP_DSTS_TxUNDERFLOW)
3828			    sc->tulip_dot3stats.dot3StatsInternalTransmitUnderflows++;
3829			if (d_status & TULIP_DSTS_TxBABBLE)
3830			    sc->tulip_dot3stats.dot3StatsInternalTransmitBabbles++;
3831		    } else {
3832			u_int32_t collisions =
3833			    (d_status & TULIP_DSTS_TxCOLLMASK)
3834				>> TULIP_DSTS_V_TxCOLLCNT;
3835			sc->tulip_if.if_collisions += collisions;
3836			if (collisions == 1)
3837			    sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++;
3838			else if (collisions > 1)
3839			    sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++;
3840			else if (d_status & TULIP_DSTS_TxDEFERRED)
3841			    sc->tulip_dot3stats.dot3StatsDeferredTransmissions++;
3842			/*
3843			 * SQE is only valid for 10baseT/BNC/AUI when not
3844			 * running in full-duplex.  In order to speed up the
3845			 * test, the corresponding bit in tulip_flags needs to
3846			 * set as well to get us to count SQE Test Errors.
3847			 */
3848			if (d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags)
3849			    sc->tulip_dot3stats.dot3StatsSQETestErrors++;
3850		    }
3851		}
3852	    }
3853	}
3854
3855	if (++ri->ri_nextin == ri->ri_last)
3856	    ri->ri_nextin = ri->ri_first;
3857
3858	if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
3859	    sc->tulip_if.if_flags &= ~IFF_OACTIVE;
3860    }
3861    /*
3862     * If nothing left to transmit, disable the timer.
3863     * Else if progress, reset the timer back to 2 ticks.
3864     */
3865    if (ri->ri_free == ri->ri_max || (sc->tulip_flags & TULIP_TXPROBE_ACTIVE))
3866	sc->tulip_txtimer = 0;
3867    else if (xmits > 0)
3868	sc->tulip_txtimer = TULIP_TXTIMER;
3869    sc->tulip_if.if_opackets += xmits;
3870    TULIP_PERFEND(txintr);
3871    return descs;
3872}
3873
3874static void
3875tulip_print_abnormal_interrupt(
3876    tulip_softc_t * const sc,
3877    u_int32_t csr)
3878{
3879    const char * const *msgp = tulip_status_bits;
3880    const char *sep;
3881    u_int32_t mask;
3882    const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
3883
3884    csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
3885    printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS);
3886    for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
3887	if ((csr & mask) && *msgp != NULL) {
3888	    printf("%s%s", sep, *msgp);
3889	    if (mask == TULIP_STS_TXUNDERFLOW && (sc->tulip_flags & TULIP_NEWTXTHRESH)) {
3890		sc->tulip_flags &= ~TULIP_NEWTXTHRESH;
3891		if (sc->tulip_cmdmode & TULIP_CMD_STOREFWD) {
3892		    printf(" (switching to store-and-forward mode)");
3893		} else {
3894		    printf(" (raising TX threshold to %s)",
3895			   &thrsh[9 * ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) >> 14)]);
3896		}
3897	    }
3898	    sep = ", ";
3899	}
3900    }
3901    printf("\n");
3902}
3903
3904static void
3905tulip_intr_handler(
3906    tulip_softc_t * const sc,
3907    int *progress_p)
3908{
3909    TULIP_PERFSTART(intr)
3910    u_int32_t csr;
3911#if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
3912    int only_once;
3913
3914    only_once = 1;
3915#endif
3916
3917    while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
3918#if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
3919        if (only_once == 1) {
3920#if NRND > 0
3921	    rnd_add_uint32(&sc->tulip_rndsource, csr);
3922#endif
3923	    only_once = 0;
3924	}
3925#endif
3926
3927	*progress_p = 1;
3928	TULIP_CSR_WRITE(sc, csr_status, csr);
3929
3930	if (csr & TULIP_STS_SYSERROR) {
3931	    sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
3932	    if (sc->tulip_flags & TULIP_NOMESSAGES) {
3933		sc->tulip_flags |= TULIP_SYSTEMERROR;
3934	    } else {
3935		printf(TULIP_PRINTF_FMT ": system error: %s\n",
3936		       TULIP_PRINTF_ARGS,
3937		       tulip_system_errors[sc->tulip_last_system_error]);
3938	    }
3939	    sc->tulip_flags |= TULIP_NEEDRESET;
3940	    sc->tulip_system_errors++;
3941	    break;
3942	}
3943	if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL) & sc->tulip_intrmask) {
3944#if defined(TULIP_DEBUG)
3945	    sc->tulip_dbg.dbg_link_intrs++;
3946#endif
3947	    if (sc->tulip_boardsw->bd_media_poll != NULL) {
3948		(*sc->tulip_boardsw->bd_media_poll)(sc, csr & TULIP_STS_LINKFAIL
3949						    ? TULIP_MEDIAPOLL_LINKFAIL
3950						    : TULIP_MEDIAPOLL_LINKPASS);
3951		csr &= ~TULIP_STS_ABNRMLINTR;
3952	    }
3953	    tulip_media_print(sc);
3954	}
3955	if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
3956	    u_int32_t misses = TULIP_CSR_READ(sc, csr_missed_frames);
3957	    if (csr & TULIP_STS_RXNOBUF)
3958		sc->tulip_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
3959	    /*
3960	     * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
3961	     * on receive overflows.
3962	     */
3963	   if ((misses & 0x0FFE0000) && (sc->tulip_features & TULIP_HAVE_RXBADOVRFLW)) {
3964		sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3965		/*
3966		 * Stop the receiver process and spin until it's stopped.
3967		 * Tell rx_intr to drop the packets it dequeues.
3968		 */
3969		TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN);
3970		while ((TULIP_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
3971		    ;
3972		TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3973		sc->tulip_flags |= TULIP_RXIGNORE;
3974	    }
3975	    tulip_rx_intr(sc);
3976	    if (sc->tulip_flags & TULIP_RXIGNORE) {
3977		/*
3978		 * Restart the receiver.
3979		 */
3980		sc->tulip_flags &= ~TULIP_RXIGNORE;
3981		TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3982	    }
3983	}
3984	if (csr & TULIP_STS_ABNRMLINTR) {
3985	    u_int32_t tmp = csr & sc->tulip_intrmask
3986		& ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
3987	    if (csr & TULIP_STS_TXUNDERFLOW) {
3988		if ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
3989		    sc->tulip_cmdmode += TULIP_CMD_THRSHLD96;
3990		    sc->tulip_flags |= TULIP_NEWTXTHRESH;
3991		} else if (sc->tulip_features & TULIP_HAVE_STOREFWD) {
3992		    sc->tulip_cmdmode |= TULIP_CMD_STOREFWD;
3993		    sc->tulip_flags |= TULIP_NEWTXTHRESH;
3994		}
3995	    }
3996	    if (sc->tulip_flags & TULIP_NOMESSAGES) {
3997		sc->tulip_statusbits |= tmp;
3998	    } else {
3999		tulip_print_abnormal_interrupt(sc, tmp);
4000		sc->tulip_flags |= TULIP_NOMESSAGES;
4001	    }
4002	    TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
4003	}
4004	if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_TXPROBE_ACTIVE|TULIP_DOINGSETUP|TULIP_PROMISC)) {
4005	    tulip_tx_intr(sc);
4006	    if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
4007		tulip_ifstart(&sc->tulip_if);
4008	}
4009    }
4010    if (sc->tulip_flags & TULIP_NEEDRESET) {
4011	tulip_reset(sc);
4012	tulip_init(sc);
4013    }
4014    TULIP_PERFEND(intr);
4015}
4016
4017#if defined(TULIP_USE_SOFTINTR)
4018/*
4019 * This is a experimental idea to alleviate problems due to interrupt
4020 * livelock.  What is interrupt livelock?  It's when you spend all your
4021 * time servicing device interrupts and never drop below device ipl
4022 * to do "useful" work.
4023 *
4024 * So what we do here is see if the device needs service and if so,
4025 * disable interrupts (dismiss the interrupt), place it in a list of devices
4026 * needing service, and issue a network software interrupt.
4027 *
4028 * When our network software interrupt routine gets called, we simply
4029 * walk done the list of devices that we have created and deal with them
4030 * at splnet/splsoftnet.
4031 *
4032 */
4033static void
4034tulip_hardintr_handler(
4035    tulip_softc_t * const sc,
4036    int *progress_p)
4037{
4038    if (TULIP_CSR_READ(sc, csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR) == 0)
4039	return;
4040    *progress_p = 1;
4041    /*
4042     * disable interrupts
4043     */
4044    TULIP_CSR_WRITE(sc, csr_intr, 0);
4045    /*
4046     * mark it as needing a software interrupt
4047     */
4048    tulip_softintr_mask |= (1U << sc->tulip_unit);
4049
4050#if defined(__NetBSD__) && NRND > 0
4051    /*
4052     * This isn't all that random (the value we feed in) but it is
4053     * better than a constant probably.  It isn't used in entropy
4054     * calculation anyway, just to add something to the pool.
4055     */
4056    rnd_add_uint32(&sc->tulip_rndsource, sc->tulip_flags);
4057#endif
4058}
4059
4060static void
4061tulip_softintr(
4062    void)
4063{
4064    u_int32_t softintr_mask, mask;
4065    int progress = 0;
4066    int unit;
4067    tulip_spl_t s;
4068
4069    /*
4070     * Copy mask to local copy and reset global one to 0.
4071     */
4072    s = TULIP_RAISESPL();
4073    softintr_mask = tulip_softintr_mask;
4074    tulip_softintr_mask = 0;
4075    TULIP_RESTORESPL(s);
4076
4077    /*
4078     * Optimize for the single unit case.
4079     */
4080    if (tulip_softintr_max_unit == 0) {
4081	if (softintr_mask & 1) {
4082	    tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(0);
4083	    /*
4084	     * Handle the "interrupt" and then reenable interrupts
4085	     */
4086	    softintr_mask = 0;
4087	    tulip_intr_handler(sc, &progress);
4088	    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4089	}
4090	return;
4091    }
4092
4093    /*
4094     * Handle all "queued" interrupts in a round robin fashion.
4095     * This is done so as not to favor a particular interface.
4096     */
4097    unit = tulip_softintr_last_unit;
4098    mask = (1U << unit);
4099    while (softintr_mask != 0) {
4100	if (tulip_softintr_max_unit == unit) {
4101	    unit  = 0; mask   = 1;
4102	} else {
4103	    unit += 1; mask <<= 1;
4104	}
4105	if (softintr_mask & mask) {
4106	    tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(unit);
4107	    /*
4108	     * Handle the "interrupt" and then reenable interrupts
4109	     */
4110	    softintr_mask ^= mask;
4111	    tulip_intr_handler(sc, &progress);
4112	    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4113	}
4114    }
4115
4116    /*
4117     * Save where we ending up.
4118     */
4119    tulip_softintr_last_unit = unit;
4120}
4121#endif	/* TULIP_USE_SOFTINTR */
4122
4123static tulip_intrfunc_t
4124tulip_intr_shared(
4125    void *arg)
4126{
4127    tulip_softc_t * sc = arg;
4128    int progress = 0;
4129
4130    for (; sc != NULL; sc = sc->tulip_slaves) {
4131#if defined(TULIP_DEBUG)
4132	sc->tulip_dbg.dbg_intrs++;
4133#endif
4134#if defined(TULIP_USE_SOFTINTR)
4135	tulip_hardintr_handler(sc, &progress);
4136#else
4137	tulip_intr_handler(sc, &progress);
4138#endif
4139    }
4140#if defined(TULIP_USE_SOFTINTR)
4141    if (progress)
4142	schednetisr(NETISR_DE);
4143#endif
4144#if !defined(TULIP_VOID_INTRFUNC)
4145    return progress;
4146#endif
4147}
4148
4149static tulip_intrfunc_t
4150tulip_intr_normal(
4151    void *arg)
4152{
4153    tulip_softc_t * sc = (tulip_softc_t *) arg;
4154    int progress = 0;
4155
4156#if defined(TULIP_DEBUG)
4157    sc->tulip_dbg.dbg_intrs++;
4158#endif
4159#if defined(TULIP_USE_SOFTINTR)
4160    tulip_hardintr_handler(sc, &progress);
4161    if (progress)
4162	schednetisr(NETISR_DE);
4163#else
4164    tulip_intr_handler(sc, &progress);
4165#endif
4166#if !defined(TULIP_VOID_INTRFUNC)
4167    return progress;
4168#endif
4169}
4170
4171static struct mbuf *
4172tulip_mbuf_compress(
4173    struct mbuf *m)
4174{
4175    struct mbuf *m0;
4176#if MCLBYTES >= ETHERMTU + 18 && !defined(BIG_PACKET)
4177    MGETHDR(m0, M_DONTWAIT, MT_DATA);
4178    if (m0 != NULL) {
4179	if (m->m_pkthdr.len > MHLEN) {
4180	    MCLGET(m0, M_DONTWAIT);
4181	    if ((m0->m_flags & M_EXT) == 0) {
4182		m_freem(m);
4183		m_freem(m0);
4184		return NULL;
4185	    }
4186	}
4187	m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
4188	m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
4189    }
4190#else
4191    int mlen = MHLEN;
4192    int len = m->m_pkthdr.len;
4193    struct mbuf **mp = &m0;
4194
4195    while (len > 0) {
4196	if (mlen == MHLEN) {
4197	    MGETHDR(*mp, M_DONTWAIT, MT_DATA);
4198	} else {
4199	    MGET(*mp, M_DONTWAIT, MT_DATA);
4200	}
4201	if (*mp == NULL) {
4202	    m_freem(m0);
4203	    m0 = NULL;
4204	    break;
4205	}
4206	if (len > MLEN) {
4207	    MCLGET(*mp, M_DONTWAIT);
4208	    if (((*mp)->m_flags & M_EXT) == 0) {
4209		m_freem(m0);
4210		m0 = NULL;
4211		break;
4212	    }
4213	    (*mp)->m_len = len <= MCLBYTES ? len : MCLBYTES;
4214	} else {
4215	    (*mp)->m_len = len <= mlen ? len : mlen;
4216	}
4217	m_copydata(m, m->m_pkthdr.len - len,
4218		   (*mp)->m_len, mtod((*mp), caddr_t));
4219	len -= (*mp)->m_len;
4220	mp = &(*mp)->m_next;
4221	mlen = MLEN;
4222    }
4223#endif
4224    m_freem(m);
4225    return m0;
4226}
4227
4228static struct mbuf *
4229tulip_txput(
4230    tulip_softc_t * const sc,
4231    struct mbuf *m)
4232{
4233    TULIP_PERFSTART(txput)
4234    tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
4235    tulip_desc_t *eop, *nextout;
4236    int segcnt, free;
4237    u_int32_t d_status;
4238#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4239    bus_dmamap_t map;
4240    int error;
4241#else
4242    struct mbuf *m0;
4243#endif
4244
4245#if defined(TULIP_DEBUG)
4246    if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
4247	printf(TULIP_PRINTF_FMT ": txput%s: tx not running\n",
4248	       TULIP_PRINTF_ARGS,
4249	       (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
4250	sc->tulip_flags |= TULIP_WANTTXSTART;
4251	sc->tulip_dbg.dbg_txput_finishes[0]++;
4252	goto finish;
4253    }
4254#endif
4255
4256    /*
4257     * Now we try to fill in our transmit descriptors.  This is
4258     * a bit reminiscent of going on the Ark two by two
4259     * since each descriptor for the TULIP can describe
4260     * two buffers.  So we advance through packet filling
4261     * each of the two entries at a time to to fill each
4262     * descriptor.  Clear the first and last segment bits
4263     * in each descriptor (actually just clear everything
4264     * but the end-of-ring or chain bits) to make sure
4265     * we don't get messed up by previously sent packets.
4266     *
4267     * We may fail to put the entire packet on the ring if
4268     * there is either not enough ring entries free or if the
4269     * packet has more than MAX_TXSEG segments.  In the former
4270     * case we will just wait for the ring to empty.  In the
4271     * latter case we have to recopy.
4272     */
4273#if !defined(TULIP_BUS_DMA) || defined(TULIP_BUS_DMA_NOTX)
4274  again:
4275    m0 = m;
4276#endif
4277    d_status = 0;
4278    eop = nextout = ri->ri_nextout;
4279    segcnt = 0;
4280    free = ri->ri_free;
4281
4282#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4283    /*
4284     * Reclaim some dma maps from if we are out.
4285     */
4286    if (sc->tulip_txmaps_free == 0) {
4287#if defined(TULIP_DEBUG)
4288	sc->tulip_dbg.dbg_no_txmaps++;
4289#endif
4290	free += tulip_tx_intr(sc);
4291    }
4292    if (sc->tulip_txmaps_free > 0) {
4293	map = sc->tulip_txmaps[sc->tulip_txmaps_free-1];
4294    } else {
4295	sc->tulip_flags |= TULIP_WANTTXSTART;
4296#if defined(TULIP_DEBUG)
4297	sc->tulip_dbg.dbg_txput_finishes[1]++;
4298#endif
4299	goto finish;
4300    }
4301    error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT);
4302    if (error != 0) {
4303	if (error == EFBIG) {
4304	    /*
4305	     * The packet exceeds the number of transmit buffer
4306	     * entries that we can use for one packet, so we have
4307	     * to recopy it into one mbuf and then try again.
4308	     */
4309	    m = tulip_mbuf_compress(m);
4310	    if (m == NULL) {
4311#if defined(TULIP_DEBUG)
4312		sc->tulip_dbg.dbg_txput_finishes[2]++;
4313#endif
4314		goto finish;
4315	    }
4316	    error = bus_dmamap_load_mbuf(sc->tulip_dmatag, map, m, BUS_DMA_NOWAIT);
4317	}
4318	if (error != 0) {
4319	    printf(TULIP_PRINTF_FMT ": unable to load tx map, "
4320		   "error = %d\n", TULIP_PRINTF_ARGS, error);
4321#if defined(TULIP_DEBUG)
4322	    sc->tulip_dbg.dbg_txput_finishes[3]++;
4323#endif
4324	    goto finish;
4325	}
4326    }
4327    if ((free -= (map->dm_nsegs + 1) / 2) <= 0
4328	    /*
4329	     * See if there's any unclaimed space in the transmit ring.
4330	     */
4331	    && (free += tulip_tx_intr(sc)) <= 0) {
4332	/*
4333	 * There's no more room but since nothing
4334	 * has been committed at this point, just
4335	 * show output is active, put back the
4336	 * mbuf and return.
4337	 */
4338	sc->tulip_flags |= TULIP_WANTTXSTART;
4339#if defined(TULIP_DEBUG)
4340	sc->tulip_dbg.dbg_txput_finishes[4]++;
4341#endif
4342	bus_dmamap_unload(sc->tulip_dmatag, map);
4343	goto finish;
4344    }
4345    for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
4346	eop = nextout;
4347	eop->d_flag   &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
4348	eop->d_status  = d_status;
4349	eop->d_addr1   = map->dm_segs[segcnt].ds_addr;
4350	eop->d_length1 = map->dm_segs[segcnt].ds_len;
4351	eop->d_addr2   = map->dm_segs[segcnt+1].ds_addr;
4352	eop->d_length2 = map->dm_segs[segcnt+1].ds_len;
4353	d_status = TULIP_DSTS_OWNER;
4354	if (++nextout == ri->ri_last)
4355	    nextout = ri->ri_first;
4356    }
4357    if (segcnt < map->dm_nsegs) {
4358	eop = nextout;
4359	eop->d_flag   &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
4360	eop->d_status  = d_status;
4361	eop->d_addr1   = map->dm_segs[segcnt].ds_addr;
4362	eop->d_length1 = map->dm_segs[segcnt].ds_len;
4363	eop->d_addr2   = 0;
4364	eop->d_length2 = 0;
4365	if (++nextout == ri->ri_last)
4366	    nextout = ri->ri_first;
4367    }
4368    TULIP_TXMAP_PRESYNC(sc, map);
4369    M_SETCTX(m, map);
4370    map = NULL;
4371    --sc->tulip_txmaps_free;		/* commit to using the dmamap */
4372
4373#else /* !TULIP_BUS_DMA */
4374
4375    do {
4376	int len = m0->m_len;
4377	caddr_t addr = mtod(m0, caddr_t);
4378	unsigned clsize = CLBYTES - (((uintptr_t) addr) & (CLBYTES-1));
4379
4380	while (len > 0) {
4381	    unsigned slen = min(len, clsize);
4382#ifdef BIG_PACKET
4383	    int partial = 0;
4384	    if (slen >= 2048)
4385		slen = 2040, partial = 1;
4386#endif
4387	    segcnt++;
4388	    if (segcnt > TULIP_MAX_TXSEG) {
4389		/*
4390		 * The packet exceeds the number of transmit buffer
4391		 * entries that we can use for one packet, so we have
4392		 * recopy it into one mbuf and then try again.
4393		 */
4394		m = tulip_mbuf_compress(m);
4395		if (m == NULL)
4396		    goto finish;
4397		goto again;
4398	    }
4399	    if (segcnt & 1) {
4400		if (--free == 0) {
4401		    /*
4402		     * See if there's any unclaimed space in the
4403		     * transmit ring.
4404		     */
4405		    if ((free += tulip_tx_intr(sc)) == 0) {
4406			/*
4407			 * There's no more room but since nothing
4408			 * has been committed at this point, just
4409			 * show output is active, put back the
4410			 * mbuf and return.
4411			 */
4412			sc->tulip_flags |= TULIP_WANTTXSTART;
4413#if defined(TULIP_DEBUG)
4414			sc->tulip_dbg.dbg_txput_finishes[1]++;
4415#endif
4416			goto finish;
4417		    }
4418		}
4419		eop = nextout;
4420		if (++nextout == ri->ri_last)
4421		    nextout = ri->ri_first;
4422		eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
4423		eop->d_status = d_status;
4424		eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
4425		eop->d_length1 = slen;
4426	    } else {
4427		/*
4428		 *  Fill in second half of descriptor
4429		 */
4430		eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
4431		eop->d_length2 = slen;
4432	    }
4433	    d_status = TULIP_DSTS_OWNER;
4434	    len -= slen;
4435	    addr += slen;
4436#ifdef BIG_PACKET
4437	    if (partial)
4438		continue;
4439#endif
4440	    clsize = CLBYTES;
4441	}
4442    } while ((m0 = m0->m_next) != NULL);
4443#endif /* TULIP_BUS_DMA */
4444
4445    /*
4446     * The descriptors have been filled in.  Now get ready
4447     * to transmit.
4448     */
4449    IF_ENQUEUE(&sc->tulip_txq, m);
4450    m = NULL;
4451
4452    /*
4453     * Make sure the next descriptor after this packet is owned
4454     * by us since it may have been set up above if we ran out
4455     * of room in the ring.
4456     */
4457    nextout->d_status = 0;
4458    TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
4459
4460#if !defined(TULIP_BUS_DMA) || defined(TULIP_BUS_DMA_NOTX)
4461    /*
4462     * If we only used the first segment of the last descriptor,
4463     * make sure the second segment will not be used.
4464     */
4465    if (segcnt & 1) {
4466	eop->d_addr2 = 0;
4467	eop->d_length2 = 0;
4468    }
4469#endif /* TULIP_BUS_DMA */
4470
4471    /*
4472     * Mark the last and first segments, indicate we want a transmit
4473     * complete interrupt, and tell it to transmit!
4474     */
4475    eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
4476
4477    /*
4478     * Note that ri->ri_nextout is still the start of the packet
4479     * and until we set the OWNER bit, we can still back out of
4480     * everything we have done.
4481     */
4482    ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
4483#if defined(TULIP_BUS_MAP) && !defined(TULIP_BUS_DMA_NOTX)
4484    if (eop < ri->ri_nextout) {
4485	TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout,
4486			     (caddr_t) ri->ri_last - (caddr_t) ri->ri_nextout);
4487	TULIP_TXDESC_PRESYNC(sc, ri->ri_first,
4488			     (caddr_t) (eop + 1) - (caddr_t) ri->ri_first);
4489    } else {
4490	TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout,
4491			     (caddr_t) (eop + 1) - (caddr_t) ri->ri_nextout);
4492    }
4493#endif
4494    ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
4495    TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
4496
4497    TULIP_CSR_WRITE(sc, csr_txpoll, 1);
4498
4499    /*
4500     * This advances the ring for us.
4501     */
4502    ri->ri_nextout = nextout;
4503    ri->ri_free = free;
4504
4505    TULIP_PERFEND(txput);
4506
4507    if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
4508	sc->tulip_if.if_flags |= IFF_OACTIVE;
4509	sc->tulip_if.if_start = tulip_ifstart;
4510	TULIP_PERFEND(txput);
4511	return NULL;
4512    }
4513
4514    /*
4515     * switch back to the single queueing ifstart.
4516     */
4517    sc->tulip_flags &= ~TULIP_WANTTXSTART;
4518    if (sc->tulip_txtimer == 0)
4519	sc->tulip_txtimer = TULIP_TXTIMER;
4520#if defined(TULIP_DEBUG)
4521    sc->tulip_dbg.dbg_txput_finishes[5]++;
4522#endif
4523
4524    /*
4525     * If we want a txstart, there must be not enough space in the
4526     * transmit ring.  So we want to enable transmit done interrupts
4527     * so we can immediately reclaim some space.  When the transmit
4528     * interrupt is posted, the interrupt handler will call tx_intr
4529     * to reclaim space and then txstart (since WANTTXSTART is set).
4530     * txstart will move the packet into the transmit ring and clear
4531     * WANTTXSTART thereby causing TXINTR to be cleared.
4532     */
4533  finish:
4534#if defined(TULIP_DEBUG)
4535    sc->tulip_dbg.dbg_txput_finishes[6]++;
4536#endif
4537    if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) {
4538	sc->tulip_if.if_flags |= IFF_OACTIVE;
4539	sc->tulip_if.if_start = tulip_ifstart;
4540	if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
4541	    sc->tulip_intrmask |= TULIP_STS_TXINTR;
4542	    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4543	}
4544    } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) {
4545	if (sc->tulip_intrmask & TULIP_STS_TXINTR) {
4546	    sc->tulip_intrmask &= ~TULIP_STS_TXINTR;
4547	    TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4548	}
4549    }
4550    TULIP_PERFEND(txput);
4551    return m;
4552}
4553
4554static void
4555tulip_txput_setup(
4556    tulip_softc_t * const sc)
4557{
4558    tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
4559    tulip_desc_t *nextout;
4560
4561    /*
4562     * We will transmit, at most, one setup packet per call to ifstart.
4563     */
4564
4565#if defined(TULIP_DEBUG)
4566    if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
4567	printf(TULIP_PRINTF_FMT ": txput_setup: tx not running\n",
4568	       TULIP_PRINTF_ARGS);
4569	sc->tulip_flags |= TULIP_WANTTXSTART;
4570	sc->tulip_if.if_start = tulip_ifstart;
4571	return;
4572    }
4573#endif
4574    /*
4575     * Try to reclaim some free descriptors..
4576     */
4577    if (ri->ri_free < 2)
4578	tulip_tx_intr(sc);
4579    if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
4580	sc->tulip_flags |= TULIP_WANTTXSTART;
4581	sc->tulip_if.if_start = tulip_ifstart;
4582	return;
4583    }
4584    bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
4585	  sizeof(sc->tulip_setupbuf));
4586    /*
4587     * Clear WANTSETUP and set DOINGSETUP.  Set know that WANTSETUP is
4588     * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
4589     */
4590    sc->tulip_flags ^= TULIP_WANTSETUP|TULIP_DOINGSETUP;
4591    ri->ri_free--;
4592    nextout = ri->ri_nextout;
4593    nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
4594    nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG
4595	|TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR;
4596    if (sc->tulip_flags & TULIP_WANTHASHPERFECT)
4597	nextout->d_flag |= TULIP_DFLAG_TxHASHFILT;
4598    else if (sc->tulip_flags & TULIP_WANTHASHONLY)
4599	nextout->d_flag |= TULIP_DFLAG_TxHASHFILT|TULIP_DFLAG_TxINVRSFILT;
4600
4601    nextout->d_length2 = 0;
4602    nextout->d_addr2 = 0;
4603#if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4604    nextout->d_length1 = sc->tulip_setupmap->dm_segs[0].ds_len;
4605    nextout->d_addr1 = sc->tulip_setupmap->dm_segs[0].ds_addr;
4606    if (sc->tulip_setupmap->dm_nsegs == 2) {
4607	nextout->d_length2 = sc->tulip_setupmap->dm_segs[1].ds_len;
4608	nextout->d_addr2 = sc->tulip_setupmap->dm_segs[1].ds_addr;
4609    }
4610    TULIP_TXMAP_PRESYNC(sc, sc->tulip_setupmap);
4611    TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(*nextout));
4612#else
4613    nextout->d_length1 = sizeof(sc->tulip_setupbuf);
4614    nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf);
4615#endif
4616
4617    /*
4618     * Advance the ring for the next transmit packet.
4619     */
4620    if (++ri->ri_nextout == ri->ri_last)
4621	ri->ri_nextout = ri->ri_first;
4622
4623    /*
4624     * Make sure the next descriptor is owned by us since it
4625     * may have been set up above if we ran out of room in the
4626     * ring.
4627     */
4628    ri->ri_nextout->d_status = 0;
4629    TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
4630    nextout->d_status = TULIP_DSTS_OWNER;
4631    /*
4632     * Flush the ownwership of the current descriptor
4633     */
4634    TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
4635    TULIP_CSR_WRITE(sc, csr_txpoll, 1);
4636    if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
4637	sc->tulip_intrmask |= TULIP_STS_TXINTR;
4638	TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4639    }
4640}
4641
4642
4643/*
4644 * This routine is entered at splnet() (splsoftnet() on NetBSD)
4645 * and thereby imposes no problems when TULIP_USE_SOFTINTR is
4646 * defined or not.
4647 */
4648static int
4649tulip_ifioctl(
4650    struct ifnet * ifp,
4651    ioctl_cmd_t cmd,
4652    caddr_t data)
4653{
4654    TULIP_PERFSTART(ifioctl)
4655    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4656    struct ifaddr *ifa = (struct ifaddr *)data;
4657    struct ifreq *ifr = (struct ifreq *) data;
4658    tulip_spl_t s;
4659    int error = 0;
4660
4661#if defined(TULIP_USE_SOFTINTR)
4662    s = TULIP_RAISESOFTSPL();
4663#else
4664    s = TULIP_RAISESPL();
4665#endif
4666    switch (cmd) {
4667	case SIOCSIFADDR: {
4668	    ifp->if_flags |= IFF_UP;
4669	    switch(ifa->ifa_addr->sa_family) {
4670#ifdef INET
4671		case AF_INET: {
4672		    tulip_init(sc);
4673		    TULIP_ARP_IFINIT(sc, ifa);
4674		    break;
4675		}
4676#endif /* INET */
4677
4678#ifdef IPX
4679		case AF_IPX: {
4680		    struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
4681		    if (ipx_nullhost(*ina)) {
4682			ina->x_host = *(union ipx_host *)(sc->tulip_enaddr);
4683		    } else {
4684			ifp->if_flags &= ~IFF_RUNNING;
4685			bcopy((caddr_t)ina->x_host.c_host,
4686			      (caddr_t)sc->tulip_enaddr,
4687			      sizeof(sc->tulip_enaddr));
4688		    }
4689		    tulip_init(sc);
4690		    break;
4691		}
4692#endif /* IPX */
4693
4694#ifdef NS
4695		/*
4696		 * This magic copied from if_is.c; I don't use XNS,
4697		 * so I have no way of telling if this actually
4698		 * works or not.
4699		 */
4700		case AF_NS: {
4701		    struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
4702		    if (ns_nullhost(*ina)) {
4703			ina->x_host = *(union ns_host *)(sc->tulip_enaddr);
4704		    } else {
4705			ifp->if_flags &= ~IFF_RUNNING;
4706			bcopy((caddr_t)ina->x_host.c_host,
4707			      (caddr_t)sc->tulip_enaddr,
4708			      sizeof(sc->tulip_enaddr));
4709		    }
4710		    tulip_init(sc);
4711		    break;
4712		}
4713#endif /* NS */
4714
4715		default: {
4716		    tulip_init(sc);
4717		    break;
4718		}
4719	    }
4720	    break;
4721	}
4722	case SIOCGIFADDR: {
4723	    bcopy((caddr_t) sc->tulip_enaddr,
4724		  (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data,
4725		  6);
4726	    break;
4727	}
4728
4729	case SIOCSIFFLAGS: {
4730#if !defined(IFM_ETHER)
4731	    int flags = 0;
4732	    if (ifp->if_flags & IFF_LINK0) flags |= 1;
4733	    if (ifp->if_flags & IFF_LINK1) flags |= 2;
4734	    if (ifp->if_flags & IFF_LINK2) flags |= 4;
4735	    if (flags == 7) {
4736		ifp->if_flags &= ~(IFF_LINK0|IFF_LINK1|IFF_LINK2);
4737		sc->tulip_media = TULIP_MEDIA_UNKNOWN;
4738		sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
4739		sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP|TULIP_NOAUTOSENSE);
4740		tulip_reset(sc);
4741	    } else if (flags) {
4742		tulip_media_t media;
4743		for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
4744		    if (sc->tulip_mediums[media] != NULL && --flags == 0) {
4745			sc->tulip_flags |= TULIP_NOAUTOSENSE;
4746			if (sc->tulip_media != media || (sc->tulip_flags & TULIP_DIDNWAY)) {
4747			    sc->tulip_flags &= ~TULIP_DIDNWAY;
4748			    tulip_linkup(sc, media);
4749			}
4750			break;
4751		    }
4752		}
4753		if (flags)
4754		    printf(TULIP_PRINTF_FMT ": ignored invalid media request\n", TULIP_PRINTF_ARGS);
4755	    }
4756#endif
4757	    tulip_init(sc);
4758	    break;
4759	}
4760
4761#if defined(SIOCSIFMEDIA)
4762	case SIOCSIFMEDIA:
4763	case SIOCGIFMEDIA: {
4764	    error = ifmedia_ioctl(ifp, ifr, &sc->tulip_ifmedia, cmd);
4765	    break;
4766	}
4767#endif
4768
4769	case SIOCADDMULTI:
4770	case SIOCDELMULTI: {
4771	    /*
4772	     * Update multicast listeners
4773	     */
4774#if defined(__FreeBSD__) && __FreeBSD_version >= 300000
4775	    tulip_addr_filter(sc);		/* reset multicast filtering */
4776	    tulip_init(sc);
4777	    error = 0;
4778#else
4779	    if (cmd == SIOCADDMULTI)
4780		error = ether_addmulti(ifr, TULIP_ETHERCOM(sc));
4781	    else
4782		error = ether_delmulti(ifr, TULIP_ETHERCOM(sc));
4783
4784	    if (error == ENETRESET) {
4785		tulip_addr_filter(sc);		/* reset multicast filtering */
4786		tulip_init(sc);
4787		error = 0;
4788	    }
4789#endif
4790	    break;
4791	}
4792#if defined(SIOCSIFMTU)
4793#if !defined(ifr_mtu)
4794#define ifr_mtu ifr_metric
4795#endif
4796	case SIOCSIFMTU:
4797	    /*
4798	     * Set the interface MTU.
4799	     */
4800	    if (ifr->ifr_mtu > ETHERMTU
4801#ifdef BIG_PACKET
4802		    && sc->tulip_chipid != TULIP_21140
4803		    && sc->tulip_chipid != TULIP_21140A
4804		    && sc->tulip_chipid != TULIP_21041
4805#endif
4806		) {
4807		error = EINVAL;
4808		break;
4809	    }
4810	    ifp->if_mtu = ifr->ifr_mtu;
4811#ifdef BIG_PACKET
4812	    tulip_reset(sc);
4813	    tulip_init(sc);
4814#endif
4815	    break;
4816#endif /* SIOCSIFMTU */
4817
4818#ifdef SIOCGADDRROM
4819	case SIOCGADDRROM: {
4820	    error = copyout(sc->tulip_rombuf, ifr->ifr_data, sizeof(sc->tulip_rombuf));
4821	    break;
4822	}
4823#endif
4824#ifdef SIOCGCHIPID
4825	case SIOCGCHIPID: {
4826	    ifr->ifr_metric = (int) sc->tulip_chipid;
4827	    break;
4828	}
4829#endif
4830	default: {
4831	    error = EINVAL;
4832	    break;
4833	}
4834    }
4835
4836    TULIP_RESTORESPL(s);
4837    TULIP_PERFEND(ifioctl);
4838    return error;
4839}
4840
4841/*
4842 * These routines gets called at device spl (from ether_output).  This might
4843 * pose a problem for TULIP_USE_SOFTINTR if ether_output is called at
4844 * device spl from another driver.
4845 */
4846
4847static ifnet_ret_t
4848tulip_ifstart(
4849    struct ifnet * const ifp)
4850{
4851    TULIP_PERFSTART(ifstart)
4852    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4853
4854    if (sc->tulip_if.if_flags & IFF_RUNNING) {
4855
4856	if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
4857	    tulip_txput_setup(sc);
4858
4859	while (sc->tulip_if.if_snd.ifq_head != NULL) {
4860	    struct mbuf *m;
4861	    IF_DEQUEUE(&sc->tulip_if.if_snd, m);
4862	    if ((m = tulip_txput(sc, m)) != NULL) {
4863		IF_PREPEND(&sc->tulip_if.if_snd, m);
4864		break;
4865	    }
4866	}
4867	if (sc->tulip_if.if_snd.ifq_head == NULL)
4868	    sc->tulip_if.if_start = tulip_ifstart_one;
4869    }
4870
4871    TULIP_PERFEND(ifstart);
4872}
4873
4874static ifnet_ret_t
4875tulip_ifstart_one(
4876    struct ifnet * const ifp)
4877{
4878    TULIP_PERFSTART(ifstart_one)
4879    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4880
4881    if ((sc->tulip_if.if_flags & IFF_RUNNING)
4882	    && sc->tulip_if.if_snd.ifq_head != NULL) {
4883	struct mbuf *m;
4884	IF_DEQUEUE(&sc->tulip_if.if_snd, m);
4885	if ((m = tulip_txput(sc, m)) != NULL)
4886	    IF_PREPEND(&sc->tulip_if.if_snd, m);
4887    }
4888    TULIP_PERFEND(ifstart_one);
4889}
4890
4891/*
4892 * Even though this routine runs at device spl, it does not break
4893 * our use of splnet (splsoftnet under NetBSD) for the majority
4894 * of this driver (if TULIP_USE_SOFTINTR defined) since
4895 * if_watcbog is called from if_watchdog which is called from
4896 * splsoftclock which is below spl[soft]net.
4897 */
4898static void
4899tulip_ifwatchdog(
4900    struct ifnet *ifp)
4901{
4902    TULIP_PERFSTART(ifwatchdog)
4903    tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp);
4904
4905#if defined(TULIP_DEBUG)
4906    u_int32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs;
4907    if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz)
4908	sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs;
4909    sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs;
4910#endif /* TULIP_DEBUG */
4911
4912    sc->tulip_if.if_timer = 1;
4913    /*
4914     * These should be rare so do a bulk test up front so we can just skip
4915     * them if needed.
4916     */
4917    if (sc->tulip_flags & (TULIP_SYSTEMERROR|TULIP_RXBUFSLOW|TULIP_NOMESSAGES)) {
4918	/*
4919	 * If the number of receive buffer is low, try to refill
4920	 */
4921	if (sc->tulip_flags & TULIP_RXBUFSLOW)
4922	    tulip_rx_intr(sc);
4923
4924	if (sc->tulip_flags & TULIP_SYSTEMERROR) {
4925	    printf(TULIP_PRINTF_FMT ": %d system errors: last was %s\n",
4926		   TULIP_PRINTF_ARGS, sc->tulip_system_errors,
4927		   tulip_system_errors[sc->tulip_last_system_error]);
4928	}
4929	if (sc->tulip_statusbits) {
4930	    tulip_print_abnormal_interrupt(sc, sc->tulip_statusbits);
4931	    sc->tulip_statusbits = 0;
4932	}
4933
4934	sc->tulip_flags &= ~(TULIP_NOMESSAGES|TULIP_SYSTEMERROR);
4935    }
4936
4937    if (sc->tulip_txtimer)
4938	tulip_tx_intr(sc);
4939    if (sc->tulip_txtimer && --sc->tulip_txtimer == 0) {
4940	printf(TULIP_PRINTF_FMT ": transmission timeout\n", TULIP_PRINTF_ARGS);
4941	if (TULIP_DO_AUTOSENSE(sc)) {
4942	    sc->tulip_media = TULIP_MEDIA_UNKNOWN;
4943	    sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
4944	    sc->tulip_flags &= ~(TULIP_WANTRXACT|TULIP_LINKUP);
4945	}
4946	tulip_reset(sc);
4947	tulip_init(sc);
4948    }
4949
4950    TULIP_PERFEND(ifwatchdog);
4951    TULIP_PERFMERGE(sc, perf_intr_cycles);
4952    TULIP_PERFMERGE(sc, perf_ifstart_cycles);
4953    TULIP_PERFMERGE(sc, perf_ifioctl_cycles);
4954    TULIP_PERFMERGE(sc, perf_ifwatchdog_cycles);
4955    TULIP_PERFMERGE(sc, perf_timeout_cycles);
4956    TULIP_PERFMERGE(sc, perf_ifstart_one_cycles);
4957    TULIP_PERFMERGE(sc, perf_txput_cycles);
4958    TULIP_PERFMERGE(sc, perf_txintr_cycles);
4959    TULIP_PERFMERGE(sc, perf_rxintr_cycles);
4960    TULIP_PERFMERGE(sc, perf_rxget_cycles);
4961    TULIP_PERFMERGE(sc, perf_intr);
4962    TULIP_PERFMERGE(sc, perf_ifstart);
4963    TULIP_PERFMERGE(sc, perf_ifioctl);
4964    TULIP_PERFMERGE(sc, perf_ifwatchdog);
4965    TULIP_PERFMERGE(sc, perf_timeout);
4966    TULIP_PERFMERGE(sc, perf_ifstart_one);
4967    TULIP_PERFMERGE(sc, perf_txput);
4968    TULIP_PERFMERGE(sc, perf_txintr);
4969    TULIP_PERFMERGE(sc, perf_rxintr);
4970    TULIP_PERFMERGE(sc, perf_rxget);
4971}
4972
4973#if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506)
4974static ifnet_ret_t
4975tulip_ifwatchdog_wrapper(
4976    int unit)
4977{
4978    tulip_ifwatchdog(&TULIP_UNIT_TO_SOFTC(unit)->tulip_if);
4979}
4980#define	tulip_ifwatchdog	tulip_ifwatchdog_wrapper
4981#endif
4982
4983/*
4984 * All printf's are real as of now!
4985 */
4986#ifdef printf
4987#undef printf
4988#endif
4989#if !defined(IFF_NOTRAILERS)
4990#define IFF_NOTRAILERS		0
4991#endif
4992
4993static void
4994tulip_attach(
4995    tulip_softc_t * const sc)
4996{
4997    struct ifnet * const ifp = &sc->tulip_if;
4998
4999    ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
5000    ifp->if_ioctl = tulip_ifioctl;
5001    ifp->if_start = tulip_ifstart;
5002    ifp->if_watchdog = tulip_ifwatchdog;
5003    ifp->if_timer = 1;
5004#if !defined(__bsdi__) || _BSDI_VERSION < 199401
5005    ifp->if_output = ether_output;
5006#endif
5007#if defined(__bsdi__) && _BSDI_VERSION < 199401
5008    ifp->if_mtu = ETHERMTU;
5009#endif
5010
5011#if defined(__bsdi__) && _BSDI_VERSION >= 199510
5012    aprint_naive(": DEC Ethernet");
5013    aprint_normal(": %s%s", sc->tulip_boardid,
5014        tulip_chipdescs[sc->tulip_chipid]);
5015    aprint_verbose(" pass %d.%d", (sc->tulip_revinfo & 0xF0) >> 4,
5016        sc->tulip_revinfo & 0x0F);
5017    printf("\n");
5018    sc->tulip_pf = aprint_normal;
5019    aprint_normal(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
5020		  TULIP_PRINTF_ARGS,
5021		  TULIP_EADDR_ARGS(sc->tulip_enaddr));
5022#else
5023    printf(
5024#if defined(__bsdi__)
5025	   "\n"
5026#endif
5027	   TULIP_PRINTF_FMT ": %s%s pass %d.%d%s\n",
5028	   TULIP_PRINTF_ARGS,
5029	   sc->tulip_boardid,
5030	   tulip_chipdescs[sc->tulip_chipid],
5031	   (sc->tulip_revinfo & 0xF0) >> 4,
5032	   sc->tulip_revinfo & 0x0F,
5033	   (sc->tulip_features & (TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM))
5034		 == TULIP_HAVE_ISVSROM ? " (invalid EESPROM checksum)" : "");
5035    printf(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n",
5036	   TULIP_PRINTF_ARGS,
5037	   TULIP_EADDR_ARGS(sc->tulip_enaddr));
5038#endif
5039
5040#if defined(__alpha__)
5041    /*
5042     * In case the SRM console told us about a bogus media,
5043     * we need to check to be safe.
5044     */
5045    if (sc->tulip_mediums[sc->tulip_media] == NULL)
5046	sc->tulip_media = TULIP_MEDIA_UNKNOWN;
5047#endif
5048
5049    (*sc->tulip_boardsw->bd_media_probe)(sc);
5050#if defined(IFM_ETHER)
5051    ifmedia_init(&sc->tulip_ifmedia, 0,
5052		 tulip_ifmedia_change,
5053		 tulip_ifmedia_status);
5054#else
5055    {
5056	tulip_media_t media;
5057	int cnt;
5058	printf(TULIP_PRINTF_FMT ": media:", TULIP_PRINTF_ARGS);
5059	for (media = TULIP_MEDIA_UNKNOWN, cnt = 1; cnt < 7 && media < TULIP_MEDIA_MAX; media++) {
5060	    if (sc->tulip_mediums[media] != NULL) {
5061		printf(" %d=\"%s\"", cnt, tulip_mediums[media]);
5062		cnt++;
5063	    }
5064	}
5065	if (cnt == 1) {
5066	    sc->tulip_features |= TULIP_HAVE_NOMEDIA;
5067	    printf(" none\n");
5068	} else {
5069	    printf("\n");
5070	}
5071    }
5072#endif
5073    sc->tulip_flags &= ~TULIP_DEVICEPROBE;
5074#if defined(IFM_ETHER)
5075    tulip_ifmedia_add(sc);
5076#endif
5077
5078    tulip_reset(sc);
5079
5080#if defined(__bsdi__) && _BSDI_VERSION >= 199510
5081    sc->tulip_pf = printf;
5082    TULIP_ETHER_IFATTACH(sc);
5083#else
5084    if_attach(ifp);
5085#if defined(__NetBSD__) || (defined(__FreeBSD__) && BSD >= 199506)
5086    TULIP_ETHER_IFATTACH(sc);
5087#endif
5088#endif /* __bsdi__ */
5089
5090#if NBPFILTER > 0
5091    TULIP_BPF_ATTACH(sc);
5092#endif
5093
5094#if defined(__NetBSD__) && NRND > 0
5095    rnd_attach_source(&sc->tulip_rndsource, sc->tulip_dev.dv_xname,
5096		      RND_TYPE_NET);
5097#endif
5098}
5099
5100#if defined(TULIP_BUS_DMA)
5101#if !defined(TULIP_BUS_DMA_NOTX) || !defined(TULIP_BUS_DMA_NORX)
5102static int
5103tulip_busdma_allocmem(
5104    tulip_softc_t * const sc,
5105    size_t size,
5106    bus_dmamap_t *map_p,
5107    tulip_desc_t **desc_p)
5108{
5109    bus_dma_segment_t segs[1];
5110    int nsegs, error;
5111    error = bus_dmamem_alloc(sc->tulip_dmatag, size, 1, CLBYTES,
5112			     segs, sizeof(segs)/sizeof(segs[0]),
5113			     &nsegs, BUS_DMA_NOWAIT);
5114    if (error == 0) {
5115	void *desc;
5116	error = bus_dmamem_map(sc->tulip_dmatag, segs, nsegs, size,
5117			       (void *) &desc, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
5118	if (error == 0) {
5119	    bus_dmamap_t map;
5120	    error = bus_dmamap_create(sc->tulip_dmatag, size, 1, size, 0,
5121				      BUS_DMA_NOWAIT, &map);
5122	    if (error == 0) {
5123		error = bus_dmamap_load(sc->tulip_dmatag, map, desc,
5124					size, NULL, BUS_DMA_NOWAIT);
5125		if (error)
5126		    bus_dmamap_destroy(sc->tulip_dmatag, map);
5127		else
5128		    *map_p = map;
5129	    }
5130	    if (error)
5131		bus_dmamem_unmap(sc->tulip_dmatag, desc, size);
5132	}
5133	if (error)
5134	    bus_dmamem_free(sc->tulip_dmatag, segs, nsegs);
5135	else
5136	    *desc_p = desc;
5137    }
5138    return error;
5139}
5140#endif
5141
5142static int
5143tulip_busdma_init(
5144    tulip_softc_t * const sc)
5145{
5146    int error = 0;
5147
5148#if !defined(TULIP_BUS_DMA_NOTX)
5149    /*
5150     * Allocate dmamap for setup descriptor
5151     */
5152    error = bus_dmamap_create(sc->tulip_dmatag, sizeof(sc->tulip_setupbuf), 2,
5153			      sizeof(sc->tulip_setupbuf), 0, BUS_DMA_NOWAIT,
5154			      &sc->tulip_setupmap);
5155    if (error == 0) {
5156	error = bus_dmamap_load(sc->tulip_dmatag, sc->tulip_setupmap,
5157				sc->tulip_setupbuf, sizeof(sc->tulip_setupbuf),
5158				NULL, BUS_DMA_NOWAIT);
5159	if (error)
5160	    bus_dmamap_destroy(sc->tulip_dmatag, sc->tulip_setupmap);
5161    }
5162    /*
5163     * Allocate space and dmamap for transmit ring
5164     */
5165    if (error == 0) {
5166	error = tulip_busdma_allocmem(sc, sizeof(tulip_desc_t) * TULIP_TXDESCS,
5167				      &sc->tulip_txdescmap,
5168				      &sc->tulip_txdescs);
5169    }
5170
5171    /*
5172     * Allocate dmamaps for each transmit descriptors
5173     */
5174    if (error == 0) {
5175	while (error == 0 && sc->tulip_txmaps_free < TULIP_TXDESCS) {
5176	    bus_dmamap_t map;
5177	    if ((error = TULIP_TXMAP_CREATE(sc, &map)) == 0)
5178		sc->tulip_txmaps[sc->tulip_txmaps_free++] = map;
5179	}
5180	if (error) {
5181	    while (sc->tulip_txmaps_free > 0)
5182		bus_dmamap_destroy(sc->tulip_dmatag,
5183				   sc->tulip_txmaps[--sc->tulip_txmaps_free]);
5184	}
5185    }
5186#else
5187    if (error == 0) {
5188	sc->tulip_txdescs = (tulip_desc_t *) malloc(TULIP_TXDESCS * sizeof(tulip_desc_t), M_DEVBUF, M_NOWAIT);
5189	if (sc->tulip_txdescs == NULL)
5190	    error = ENOMEM;
5191    }
5192#endif
5193#if !defined(TULIP_BUS_DMA_NORX)
5194    /*
5195     * Allocate space and dmamap for receive ring
5196     */
5197    if (error == 0) {
5198	error = tulip_busdma_allocmem(sc, sizeof(tulip_desc_t) * TULIP_RXDESCS,
5199				      &sc->tulip_rxdescmap,
5200				      &sc->tulip_rxdescs);
5201    }
5202
5203    /*
5204     * Allocate dmamaps for each receive descriptors
5205     */
5206    if (error == 0) {
5207	while (error == 0 && sc->tulip_rxmaps_free < TULIP_RXDESCS) {
5208	    bus_dmamap_t map;
5209	    if ((error = TULIP_RXMAP_CREATE(sc, &map)) == 0)
5210		sc->tulip_rxmaps[sc->tulip_rxmaps_free++] = map;
5211	}
5212	if (error) {
5213	    while (sc->tulip_rxmaps_free > 0)
5214		bus_dmamap_destroy(sc->tulip_dmatag,
5215				   sc->tulip_rxmaps[--sc->tulip_rxmaps_free]);
5216	}
5217    }
5218#else
5219    if (error == 0) {
5220	sc->tulip_rxdescs = (tulip_desc_t *) malloc(TULIP_RXDESCS * sizeof(tulip_desc_t), M_DEVBUF, M_NOWAIT);
5221	if (sc->tulip_rxdescs == NULL)
5222	    error = ENOMEM;
5223    }
5224#endif
5225    return error;
5226}
5227#endif /* TULIP_BUS_DMA */
5228
5229static void
5230tulip_initcsrs(
5231    tulip_softc_t * const sc,
5232    tulip_csrptr_t csr_base,
5233    size_t csr_size)
5234{
5235    sc->tulip_csrs.csr_busmode		= csr_base +  0 * csr_size;
5236    sc->tulip_csrs.csr_txpoll		= csr_base +  1 * csr_size;
5237    sc->tulip_csrs.csr_rxpoll		= csr_base +  2 * csr_size;
5238    sc->tulip_csrs.csr_rxlist		= csr_base +  3 * csr_size;
5239    sc->tulip_csrs.csr_txlist		= csr_base +  4 * csr_size;
5240    sc->tulip_csrs.csr_status		= csr_base +  5 * csr_size;
5241    sc->tulip_csrs.csr_command		= csr_base +  6 * csr_size;
5242    sc->tulip_csrs.csr_intr		= csr_base +  7 * csr_size;
5243    sc->tulip_csrs.csr_missed_frames	= csr_base +  8 * csr_size;
5244    sc->tulip_csrs.csr_9		= csr_base +  9 * csr_size;
5245    sc->tulip_csrs.csr_10		= csr_base + 10 * csr_size;
5246    sc->tulip_csrs.csr_11		= csr_base + 11 * csr_size;
5247    sc->tulip_csrs.csr_12		= csr_base + 12 * csr_size;
5248    sc->tulip_csrs.csr_13		= csr_base + 13 * csr_size;
5249    sc->tulip_csrs.csr_14		= csr_base + 14 * csr_size;
5250    sc->tulip_csrs.csr_15		= csr_base + 15 * csr_size;
5251#if defined(TULIP_EISA)
5252    sc->tulip_csrs.csr_enetrom		= csr_base + DE425_ENETROM_OFFSET;
5253#endif
5254}
5255
5256static void
5257tulip_initring(
5258    tulip_softc_t * const sc,
5259    tulip_ringinfo_t * const ri,
5260    tulip_desc_t *descs,
5261    int ndescs)
5262{
5263    ri->ri_max = ndescs;
5264    ri->ri_first = descs;
5265    ri->ri_last = ri->ri_first + ri->ri_max;
5266    bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
5267    ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING;
5268}
5269
5270/*
5271 * This is the PCI configuration support.  Since the 21040 is available
5272 * on both EISA and PCI boards, one must be careful in how defines the
5273 * 21040 in the config file.
5274 */
5275
5276#define	PCI_CFID	0x00	/* Configuration ID */
5277#define	PCI_CFCS	0x04	/* Configurtion Command/Status */
5278#define	PCI_CFRV	0x08	/* Configuration Revision */
5279#define	PCI_CFLT	0x0c	/* Configuration Latency Timer */
5280#define	PCI_CBIO	0x10	/* Configuration Base IO Address */
5281#define	PCI_CBMA	0x14	/* Configuration Base Memory Address */
5282#define	PCI_CFIT	0x3c	/* Configuration Interrupt */
5283#define	PCI_CFDA	0x40	/* Configuration Driver Area */
5284
5285#if defined(TULIP_EISA)
5286static const int tulip_eisa_irqs[4] = { IRQ5, IRQ9, IRQ10, IRQ11 };
5287#endif
5288
5289#if defined(__FreeBSD__)
5290
5291#define	TULIP_PCI_ATTACH_ARGS	pcici_t config_id, int unit
5292#define	TULIP_SHUTDOWN_ARGS	int howto, void * arg
5293
5294#if defined(TULIP_DEVCONF)
5295static void tulip_shutdown(TULIP_SHUTDOWN_ARGS);
5296
5297static int
5298tulip_pci_shutdown(
5299    struct kern_devconf * const kdc,
5300    int force)
5301{
5302    if (kdc->kdc_unit < TULIP_MAX_DEVICES) {
5303	tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(kdc->kdc_unit);
5304	if (sc != NULL)
5305	    tulip_shutdown(0, sc);
5306    }
5307    (void) dev_detach(kdc);
5308    return 0;
5309}
5310#endif
5311
5312static const char*
5313tulip_pci_probe(
5314    pcici_t config_id,
5315    pcidi_t device_id)
5316{
5317    if (PCI_VENDORID(device_id) != DEC_VENDORID)
5318	return NULL;
5319    if (PCI_CHIPID(device_id) == CHIPID_21040)
5320	return "Digital 21040 Ethernet";
5321    if (PCI_CHIPID(device_id) == CHIPID_21041)
5322	return "Digital 21041 Ethernet";
5323    if (PCI_CHIPID(device_id) == CHIPID_21140) {
5324	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
5325	if (revinfo >= 0x20)
5326	    return "Digital 21140A Fast Ethernet";
5327	else
5328	    return "Digital 21140 Fast Ethernet";
5329    }
5330    if (PCI_CHIPID(device_id) == CHIPID_21142) {
5331	u_int32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF;
5332	if (revinfo >= 0x20)
5333	    return "Digital 21143 Fast Ethernet";
5334	else
5335	    return "Digital 21142 Fast Ethernet";
5336    }
5337    return NULL;
5338}
5339
5340static void  tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
5341static u_long tulip_pci_count;
5342
5343static struct pci_device dedevice = {
5344    "de",
5345    tulip_pci_probe,
5346    tulip_pci_attach,
5347   &tulip_pci_count,
5348#if defined(TULIP_DEVCONF)
5349    tulip_pci_shutdown,
5350#endif
5351};
5352
5353DATA_SET (pcidevice_set, dedevice);
5354#endif /* __FreeBSD__ */
5355
5356#if defined(__bsdi__)
5357#define	TULIP_PCI_ATTACH_ARGS	struct device * const parent, struct device * const self, void * const aux
5358#define	TULIP_SHUTDOWN_ARGS	void *arg
5359
5360static int
5361tulip_pci_match(
5362    pci_devaddr_t *pa)
5363{
5364    int irq;
5365    unsigned id;
5366
5367    id = pci_inl(pa, PCI_VENDOR_ID);
5368    if (PCI_VENDORID(id) != DEC_VENDORID)
5369	return 0;
5370    id = PCI_CHIPID(id);
5371    if (id != CHIPID_21040 && id != CHIPID_21041
5372	    && id != CHIPID_21140 && id != CHIPID_21142)
5373	return 0;
5374    irq = pci_inl(pa, PCI_I_LINE) & 0xFF;
5375    if (irq == 0 || irq >= 16) {
5376	printf("de?: invalid IRQ %d; skipping\n", irq);
5377	return 0;
5378    }
5379    return 1;
5380}
5381
5382static int
5383tulip_probe(
5384    struct device *parent,
5385    struct cfdata *cf,
5386    void *aux)
5387{
5388    struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
5389    unsigned irq, slot;
5390    pci_devaddr_t *pa;
5391
5392#if _BSDI_VERSION >= 199401
5393    switch (ia->ia_bustype) {
5394    case BUS_PCI:
5395#endif
5396	pa = pci_scan(tulip_pci_match);
5397	if (pa == NULL)
5398	    return 0;
5399
5400	irq = (1 << (pci_inl(pa, PCI_I_LINE) & 0xFF));
5401
5402	/* Get the base address; assume the BIOS set it up correctly */
5403#if defined(TULIP_IOMAPPED)
5404	ia->ia_maddr = NULL;
5405	ia->ia_msize = 0;
5406	ia->ia_iobase = pci_inl(pa, PCI_CBIO) & ~7;
5407	pci_outl(pa, PCI_CBIO, 0xFFFFFFFF);
5408	ia->ia_iosize = ((~pci_inl(pa, PCI_CBIO)) | 7) + 1;
5409	pci_outl(pa, PCI_CBIO, (int) ia->ia_iobase);
5410
5411	/* Disable memory space access */
5412	pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~2);
5413#else
5414	ia->ia_maddr = (caddr_t) (pci_inl(pa, PCI_CBMA) & ~7);
5415	pci_outl(pa, PCI_CBMA, 0xFFFFFFFF);
5416	ia->ia_msize = ((~pci_inl(pa, PCI_CBMA)) | 7) + 1;
5417	pci_outl(pa, PCI_CBMA, (int) ia->ia_maddr);
5418	ia->ia_iobase = 0;
5419	ia->ia_iosize = 0;
5420
5421	/* Disable I/O space access */
5422	pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~1);
5423#endif /* TULIP_IOMAPPED */
5424
5425	ia->ia_aux = (void *) pa;
5426#if _BSDI_VERSION >= 199401
5427	break;
5428
5429#if defined(TULIP_EISA)
5430    case BUS_EISA: {
5431	unsigned tmp;
5432
5433	if ((slot = eisa_match(cf, ia)) == 0)
5434	    return 0;
5435	ia->ia_iobase = slot << 12;
5436	ia->ia_iosize = EISA_NPORT;
5437	eisa_slotalloc(slot);
5438	tmp = inb(ia->ia_iobase + DE425_CFG0);
5439	irq = tulip_eisa_irqs[(tmp >> 1) & 0x03];
5440	/*
5441	 * Until BSD/OS likes level interrupts, force
5442	 * the DE425 into edge-triggered mode.
5443	 */
5444	if ((tmp & 1) == 0)
5445	    outb(ia->ia_iobase + DE425_CFG0, tmp | 1);
5446	/*
5447	 * CBIO needs to map to the EISA slot
5448	 * enable I/O access and Master
5449	 */
5450	outl(ia->ia_iobase + DE425_CBIO, ia->ia_iobase);
5451	outl(ia->ia_iobase + DE425_CFCS, 5 | inl(ia->ia_iobase + DE425_CFCS));
5452	ia->ia_aux = NULL;
5453	break;
5454    }
5455#endif /* TULIP_EISA */
5456    default:
5457	return 0;
5458    }
5459#endif
5460
5461    /* PCI bus masters don't use host DMA channels */
5462    ia->ia_drq = DRQNONE;
5463
5464    if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) {
5465	printf("de%d: error: desired IRQ of %d does not match device's "
5466	    "actual IRQ of %d,\n",
5467	       cf->cf_unit,
5468	       ffs(ia->ia_irq) - 1, ffs(irq) - 1);
5469	return 0;
5470    }
5471    if (ia->ia_irq == IRQUNK)
5472	ia->ia_irq = irq;
5473#ifdef IRQSHARE
5474    ia->ia_irq |= IRQSHARE;
5475#endif
5476    return 1;
5477}
5478
5479static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
5480
5481#if defined(TULIP_EISA)
5482static char *tulip_eisa_ids[] = {
5483    "DEC4250",
5484    NULL
5485};
5486#endif
5487
5488struct cfdriver decd = {
5489    0, "de", tulip_probe, tulip_pci_attach,
5490#if _BSDI_VERSION >= 199401
5491    DV_IFNET,
5492#endif
5493    sizeof(tulip_softc_t),
5494#if defined(TULIP_EISA)
5495    tulip_eisa_ids
5496#endif
5497};
5498
5499#endif /* __bsdi__ */
5500
5501#if defined(__NetBSD__)
5502#define	TULIP_PCI_ATTACH_ARGS	struct device * const parent, struct device * const self, void * const aux
5503#define	TULIP_SHUTDOWN_ARGS	void *arg
5504static int
5505tulip_pci_probe(
5506    struct device *parent,
5507    struct cfdata *match,
5508    void *aux)
5509{
5510    struct pci_attach_args *pa = (struct pci_attach_args *) aux;
5511
5512    if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID)
5513	return 0;
5514    if (PCI_CHIPID(pa->pa_id) == CHIPID_21040
5515	    || PCI_CHIPID(pa->pa_id) == CHIPID_21041
5516	    || PCI_CHIPID(pa->pa_id) == CHIPID_21140
5517	    || PCI_CHIPID(pa->pa_id) == CHIPID_21142)
5518	return 1;
5519
5520    return 0;
5521}
5522
5523static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS);
5524
5525struct cfattach de_ca = {
5526    sizeof(tulip_softc_t), tulip_pci_probe, tulip_pci_attach
5527};
5528
5529#endif /* __NetBSD__ */
5530
5531static void
5532tulip_shutdown(
5533    TULIP_SHUTDOWN_ARGS)
5534{
5535    tulip_softc_t * const sc = arg;
5536    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
5537    DELAY(10);	/* Wait 10 microseconds (actually 50 PCI cycles but at
5538		   33MHz that comes to two microseconds but wait a
5539		   bit longer anyways) */
5540}
5541
5542static void
5543tulip_pci_attach(
5544    TULIP_PCI_ATTACH_ARGS)
5545{
5546#if defined(__FreeBSD__)
5547    tulip_softc_t *sc;
5548#define	PCI_CONF_WRITE(r, v)	pci_conf_write(config_id, (r), (v))
5549#define	PCI_CONF_READ(r)	pci_conf_read(config_id, (r))
5550#if __FreeBSD_version >= 300000
5551#define	PCI_GETBUSDEVINFO(sc)	((void)((sc)->tulip_pci_busno = (config_id->bus), /* XXX */ \
5552					(sc)->tulip_pci_devno = (config_id->slot))) /* XXX */
5553#else
5554#define	PCI_GETBUSDEVINFO(sc)	((void)((sc)->tulip_pci_busno = ((config_id.cfg1 >> 16) & 0xFF), /* XXX */ \
5555					(sc)->tulip_pci_devno = ((config_id.cfg1 >> 11) & 0x1F))) /* XXX */
5556#endif
5557#endif
5558#if defined(__bsdi__)
5559    tulip_softc_t * const sc = (tulip_softc_t *) self;
5560    struct isa_attach_args * const ia = (struct isa_attach_args *) aux;
5561    pci_devaddr_t *pa = (pci_devaddr_t *) ia->ia_aux;
5562    const int unit = sc->tulip_dev.dv_unit;
5563#define	PCI_CONF_WRITE(r, v)	pci_outl(pa, (r), (v))
5564#define	PCI_CONF_READ(r)	pci_inl(pa, (r))
5565#define	PCI_GETBUSDEVINFO(sc)	((void)((sc)->tulip_pci_busno = pa->d_bus, \
5566					(sc)->tulip_pci_devno = pa->d_agent))
5567#endif
5568#if defined(__NetBSD__)
5569    tulip_softc_t * const sc = (tulip_softc_t *) self;
5570    struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
5571    const int unit = sc->tulip_dev.dv_unit;
5572#define	PCI_CONF_WRITE(r, v)	pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
5573#define	PCI_CONF_READ(r)	pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
5574#define	PCI_GETBUSDEVINFO(sc)	do { \
5575	(sc)->tulip_pci_busno = parent; \
5576	(sc)->tulip_pci_devno = pa->pa_device; \
5577    } while (0)
5578#endif /* __NetBSD__ */
5579#if defined(__alpha__)
5580    tulip_media_t media = TULIP_MEDIA_UNKNOWN;
5581#endif
5582    int retval, idx;
5583    u_int32_t revinfo, cfdainfo, id;
5584#if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__)
5585    vm_offset_t pa_csrs;
5586#endif
5587    unsigned csroffset = TULIP_PCI_CSROFFSET;
5588    unsigned csrsize = TULIP_PCI_CSRSIZE;
5589    tulip_csrptr_t csr_base;
5590    tulip_chipid_t chipid = TULIP_CHIPID_UNKNOWN;
5591
5592    if (unit >= TULIP_MAX_DEVICES) {
5593#ifdef __FreeBSD__
5594	printf("de%d", unit);
5595#endif
5596	printf(": not configured; limit of %d reached or exceeded\n",
5597	       TULIP_MAX_DEVICES);
5598	return;
5599    }
5600
5601#if defined(__bsdi__)
5602    if (pa != NULL) {
5603	revinfo = pci_inl(pa, PCI_CFRV) & 0xFF;
5604	id = pci_inl(pa, PCI_CFID);
5605	cfdainfo = pci_inl(pa, PCI_CFDA);
5606#if defined(TULIP_EISA)
5607    } else {
5608	revinfo = inl(ia->ia_iobase + DE425_CFRV) & 0xFF;
5609	csroffset = TULIP_EISA_CSROFFSET;
5610	csrsize = TULIP_EISA_CSRSIZE;
5611	chipid = TULIP_DE425;
5612	cfdainfo = 0;
5613#endif /* TULIP_EISA */
5614    }
5615#else /* __bsdi__ */
5616    revinfo  = PCI_CONF_READ(PCI_CFRV) & 0xFF;
5617    id       = PCI_CONF_READ(PCI_CFID);
5618    cfdainfo = PCI_CONF_READ(PCI_CFDA);
5619#endif /* __bsdi__ */
5620
5621    if (PCI_VENDORID(id) == DEC_VENDORID) {
5622	if (PCI_CHIPID(id) == CHIPID_21040)
5623		chipid = TULIP_21040;
5624	else if (PCI_CHIPID(id) == CHIPID_21041)
5625		chipid = TULIP_21041;
5626	else if (PCI_CHIPID(id) == CHIPID_21140)
5627		chipid = (revinfo >= 0x20) ? TULIP_21140A : TULIP_21140;
5628	else if (PCI_CHIPID(id) == CHIPID_21142)
5629		chipid = (revinfo >= 0x20) ? TULIP_21143 : TULIP_21142;
5630    }
5631    if (chipid == TULIP_CHIPID_UNKNOWN)
5632	return;
5633
5634    if ((chipid == TULIP_21040 || chipid == TULIP_DE425) && revinfo < 0x20) {
5635#ifdef __FreeBSD__
5636	printf("de%d", unit);
5637#endif
5638	printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
5639	       revinfo >> 4, revinfo & 0x0f);
5640	return;
5641    } else if (chipid == TULIP_21140 && revinfo < 0x11) {
5642#ifndef __FreeBSD__
5643	printf("\n");
5644#endif
5645	printf("de%d: not configured; 21140 pass 1.1 required (%d.%d found)\n",
5646	       unit, revinfo >> 4, revinfo & 0x0f);
5647	return;
5648    }
5649
5650#if defined(__FreeBSD__)
5651    sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
5652    if (sc == NULL)
5653	return;
5654    bzero(sc, sizeof(*sc));				/* Zero out the softc*/
5655#endif
5656
5657    PCI_GETBUSDEVINFO(sc);
5658    sc->tulip_chipid = chipid;
5659    sc->tulip_flags |= TULIP_DEVICEPROBE;
5660    if (chipid == TULIP_21140 || chipid == TULIP_21140A)
5661	sc->tulip_features |= TULIP_HAVE_GPR|TULIP_HAVE_STOREFWD;
5662    if (chipid == TULIP_21140A && revinfo <= 0x22)
5663	sc->tulip_features |= TULIP_HAVE_RXBADOVRFLW;
5664    if (chipid == TULIP_21140)
5665	sc->tulip_features |= TULIP_HAVE_BROKEN_HASH;
5666    if (chipid != TULIP_21040 && chipid != TULIP_DE425 && chipid != TULIP_21140)
5667	sc->tulip_features |= TULIP_HAVE_POWERMGMT;
5668    if (chipid == TULIP_21041 || chipid == TULIP_21142 || chipid == TULIP_21143) {
5669	sc->tulip_features |= TULIP_HAVE_DUALSENSE;
5670	if (chipid != TULIP_21041 || revinfo >= 0x20)
5671	    sc->tulip_features |= TULIP_HAVE_SIANWAY;
5672	if (chipid != TULIP_21041)
5673	    sc->tulip_features |= TULIP_HAVE_SIAGP|TULIP_HAVE_RXBADOVRFLW|TULIP_HAVE_STOREFWD;
5674	if (chipid != TULIP_21041 && revinfo >= 0x20)
5675	    sc->tulip_features |= TULIP_HAVE_SIA100;
5676    }
5677
5678    if (sc->tulip_features & TULIP_HAVE_POWERMGMT
5679	    && (cfdainfo & (TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE))) {
5680	cfdainfo &= ~(TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE);
5681	PCI_CONF_WRITE(PCI_CFDA, cfdainfo);
5682	DELAY(11*1000);
5683    }
5684#if defined(__alpha__) && defined(__NetBSD__)
5685    /*
5686     * The Alpha SRM console encodes a console set media in the driver
5687     * part of the CFDA register.  Note that the Multia presents a
5688     * problem in that its BNC mode is really EXTSIA.  So in that case
5689     * force a probe.
5690     */
5691    switch ((cfdainfo >> 8) & 0xff) {
5692    case 1: media = chipid > TULIP_DE425 ?
5693        TULIP_MEDIA_AUI : TULIP_MEDIA_AUIBNC; break;
5694    case 2: media = chipid > TULIP_DE425 ?
5695        TULIP_MEDIA_BNC : TULIP_MEDIA_UNKNOWN; break;
5696    case 3: media = TULIP_MEDIA_10BASET; break;
5697    case 4: media = TULIP_MEDIA_10BASET_FD; break;
5698    case 5: media = TULIP_MEDIA_100BASETX; break;
5699    case 6: media = TULIP_MEDIA_100BASETX_FD; break;
5700    }
5701#endif
5702
5703#if defined(__NetBSD__)
5704    bcopy(self->dv_xname, sc->tulip_if.if_xname, IFNAMSIZ);
5705    sc->tulip_if.if_softc = sc;
5706    sc->tulip_pc = pa->pa_pc;
5707#if defined(TULIP_BUS_DMA)
5708    sc->tulip_dmatag = pa->pa_dmat;
5709#endif
5710#else
5711    sc->tulip_unit = unit;
5712    sc->tulip_name = "de";
5713#endif
5714    sc->tulip_revinfo = revinfo;
5715#if defined(__FreeBSD__)
5716#if BSD >= 199506
5717    sc->tulip_if.if_softc = sc;
5718#endif
5719#if defined(TULIP_IOMAPPED)
5720    retval = pci_map_port(config_id, PCI_CBIO, &csr_base);
5721#else
5722    retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &csr_base, &pa_csrs);
5723#endif
5724    if (!retval) {
5725	free((caddr_t) sc, M_DEVBUF);
5726	return;
5727    }
5728    tulips[unit] = sc;
5729#endif /* __FreeBSD__ */
5730
5731#if defined(__bsdi__)
5732    sc->tulip_pf = printf;
5733#if defined(TULIP_IOMAPPED)
5734    csr_base = ia->ia_iobase;
5735#else
5736    csr_base = (vm_offset_t) mapphys((vm_offset_t) ia->ia_maddr, ia->ia_msize);
5737#endif
5738#endif /* __bsdi__ */
5739
5740#if defined(__NetBSD__)
5741    csr_base = 0;
5742    {
5743	bus_space_tag_t iot, memt;
5744	bus_space_handle_t ioh, memh;
5745	int ioh_valid, memh_valid;
5746
5747	ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
5748				    &iot, &ioh, NULL, NULL) == 0);
5749	memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
5750				     PCI_MAPREG_TYPE_MEM |
5751				     PCI_MAPREG_MEM_TYPE_32BIT,
5752				     0, &memt, &memh, NULL, NULL) == 0);
5753	if (memh_valid) {
5754	    sc->tulip_bustag = memt;
5755	    sc->tulip_bushandle = memh;
5756	} else if (ioh_valid) {
5757	    sc->tulip_bustag = iot;
5758	    sc->tulip_bushandle = ioh;
5759	} else {
5760	    printf(": unable to map device registers\n");
5761	    return;
5762	}
5763    }
5764#endif /* __NetBSD__ */
5765
5766    tulip_initcsrs(sc, csr_base + csroffset, csrsize);
5767
5768#if defined(TULIP_BUS_DMA)
5769    if ((retval = tulip_busdma_init(sc)) != 0) {
5770	printf("error initing bus_dma: %d\n", retval);
5771	return;
5772    }
5773#else
5774#if defined(__FreeBSD__)
5775    sc->tulip_rxdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT);
5776    sc->tulip_txdescs = (tulip_desc_t *) malloc(sizeof(tulip_desc_t) * TULIP_TXDESCS, M_DEVBUF, M_NOWAIT);
5777    if (sc->tulip_rxdescs == NULL || sc->tulip_txdescs == NULL) {
5778	printf("malloc failed\n");
5779	if (sc->tulip_rxdescs)
5780	    free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
5781	if (sc->tulip_txdescs)
5782	    free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
5783	free((caddr_t) sc, M_DEVBUF);
5784	return;
5785    }
5786#else
5787    sc->tulip_txdescs = (tulip_desc_t *) malloc((TULIP_TXDESCS+TULIP_RXDESCS)*sizeof(tulip_desc_t), M_DEVBUF, M_WAITOK);
5788    sc->tulip_rxdescs = sc->tulip_txdescs + TULIP_TXDESCS;
5789#endif
5790#endif
5791
5792    tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS);
5793    tulip_initring(sc, &sc->tulip_txinfo, sc->tulip_txdescs, TULIP_TXDESCS);
5794
5795    /*
5796     * Make sure there won't be any interrupts or such...
5797     */
5798    TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
5799    DELAY(100);	/* Wait 10 microseconds (actually 50 PCI cycles but at
5800		   33MHz that comes to two microseconds but wait a
5801		   bit longer anyways) */
5802
5803    if ((retval = tulip_read_macaddr(sc)) < 0) {
5804#if defined(__FreeBSD__)
5805	printf(TULIP_PRINTF_FMT, TULIP_PRINTF_ARGS);
5806#endif
5807	printf(": can't read ENET ROM (why=%d) (", retval);
5808	for (idx = 0; idx < 32; idx++)
5809	    printf("%02x", sc->tulip_rombuf[idx]);
5810	printf("\n");
5811	printf(TULIP_PRINTF_FMT ": %s%s pass %d.%d\n",
5812	       TULIP_PRINTF_ARGS,
5813	       sc->tulip_boardid, tulip_chipdescs[sc->tulip_chipid],
5814	       (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F);
5815	printf(TULIP_PRINTF_FMT ": address unknown\n", TULIP_PRINTF_ARGS);
5816    } else {
5817	tulip_spl_t s;
5818	tulip_intrfunc_t (*intr_rtn)(void *) = tulip_intr_normal;
5819
5820	if (sc->tulip_features & TULIP_HAVE_SHAREDINTR)
5821	    intr_rtn = tulip_intr_shared;
5822
5823#if defined(__NetBSD__)
5824	if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
5825	    pci_intr_handle_t intrhandle;
5826	    const char *intrstr;
5827
5828	    printf("\n");
5829
5830	    if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
5831			     pa->pa_intrline, &intrhandle)) {
5832		printf("%s: couldn't map interrupt\n", sc->tulip_dev.dv_xname);
5833		return;
5834	    }
5835	    intrstr = pci_intr_string(pa->pa_pc, intrhandle);
5836	    sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
5837					      intr_rtn, sc);
5838	    if (sc->tulip_ih == NULL) {
5839		printf("%s: couldn't establish interrupt",
5840		       sc->tulip_dev.dv_xname);
5841		if (intrstr != NULL)
5842		    printf(" at %s", intrstr);
5843		printf("\n");
5844		return;
5845	    }
5846	    printf("%s: interrupting at %s\n", sc->tulip_dev.dv_xname, intrstr);
5847	}
5848	sc->tulip_ats = shutdownhook_establish(tulip_shutdown, sc);
5849	if (sc->tulip_ats == NULL)
5850	    printf("%s: warning: couldn't establish shutdown hook\n",
5851		   sc->tulip_xname);
5852#endif
5853#if defined(__FreeBSD__)
5854	if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
5855	    if (!pci_map_int (config_id, intr_rtn, (void*) sc, &net_imask)) {
5856		printf(TULIP_PRINTF_FMT ": couldn't map interrupt\n",
5857		       TULIP_PRINTF_ARGS);
5858		free((caddr_t) sc->tulip_rxdescs, M_DEVBUF);
5859		free((caddr_t) sc->tulip_txdescs, M_DEVBUF);
5860		free((caddr_t) sc, M_DEVBUF);
5861		return;
5862	    }
5863	}
5864#if !defined(TULIP_DEVCONF)
5865	at_shutdown(tulip_shutdown, sc, SHUTDOWN_POST_SYNC);
5866#endif
5867#endif
5868#if defined(__bsdi__)
5869	if ((sc->tulip_features & TULIP_HAVE_SLAVEDINTR) == 0) {
5870	    isa_establish(&sc->tulip_id, &sc->tulip_dev);
5871
5872	    sc->tulip_ih.ih_fun = intr_rtn;
5873	    sc->tulip_ih.ih_arg = (void *) sc;
5874	    intr_establish(ia->ia_irq, &sc->tulip_ih, DV_NET);
5875	}
5876
5877	sc->tulip_ats.func = tulip_shutdown;
5878	sc->tulip_ats.arg = (void *) sc;
5879	atshutdown(&sc->tulip_ats, ATSH_ADD);
5880#endif
5881#if defined(TULIP_USE_SOFTINTR)
5882	if (sc->tulip_unit > tulip_softintr_max_unit)
5883	    tulip_softintr_max_unit = sc->tulip_unit;
5884#endif
5885
5886	s = TULIP_RAISESPL();
5887	tulip_reset(sc);
5888	tulip_attach(sc);
5889#if defined(__alpha__) && defined(__NetBSD__)
5890	if (media != TULIP_MEDIA_UNKNOWN)
5891	    tulip_linkup(sc, media);
5892#endif
5893	TULIP_RESTORESPL(s);
5894    }
5895}
5896