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