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