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