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