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