GC TULIP_BUS_DMA.
[dragonfly.git] / sys / dev / netif / de / if_de.c
1 /*      $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $       */
2
3 /* $FreeBSD: src/sys/pci/if_de.c,v 1.123.2.4 2000/08/04 23:25:09 peter Exp $ */
4 /* $DragonFly: src/sys/dev/netif/de/if_de.c,v 1.23 2005/02/21 04:58:34 joerg Exp $ */
5
6 /*-
7  * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name of the author may not be used to endorse or promote products
16  *    derived from this software withough specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Id: if_de.c,v 1.94 1997/07/03 16:55:07 thomas Exp
30  *
31  */
32
33 /*
34  * DEC 21040 PCI Ethernet Controller
35  *
36  * Written by Matt Thomas
37  * BPF support code stolen directly from if_ec.c
38  *
39  *   This driver supports the DEC DE435 or any other PCI
40  *   board which support 21040, 21041, or 21140 (mostly).
41  */
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/mbuf.h>
46 #include <sys/socket.h>
47 #include <sys/sockio.h>
48 #include <sys/malloc.h>
49 #include <sys/kernel.h>
50 #include <sys/eventhandler.h>
51 #include <machine/clock.h>
52 #include <machine/bus.h>
53 #include <machine/resource.h>
54 #include <sys/bus.h>
55 #include <sys/rman.h>
56
57 #include "opt_inet.h"
58 #include "opt_ipx.h"
59
60 #include <net/if.h>
61 #include <net/if_media.h>
62 #include <net/if_dl.h>
63
64 #include <net/bpf.h>
65
66 #ifdef INET
67 #include <netinet/in.h>
68 #include <netinet/if_ether.h>
69 #endif
70
71 #ifdef IPX
72 #include <netproto/ipx/ipx.h>
73 #include <netproto/ipx/ipx_if.h>
74 #endif
75
76 #ifdef NS
77 #include <netproto/ns/ns.h>
78 #include <netproto/ns/ns_if.h>
79 #endif
80
81 #include <vm/vm.h>
82
83 #include <net/if_var.h>
84 #include <vm/pmap.h>
85 #include <bus/pci/pcivar.h>
86 #include <bus/pci/pcireg.h>
87 #include <bus/pci/dc21040reg.h>
88
89 /*
90  * Intel CPUs should use I/O mapped access.
91  */
92 #if defined(__i386__)
93 #define TULIP_IOMAPPED
94 #endif
95
96 #if 0
97 /*
98  * This turns on all sort of debugging stuff and make the
99  * driver much larger.
100  */
101 #define TULIP_DEBUG
102 #endif
103
104 #if 0
105 #define TULIP_PERFSTATS
106 #endif
107
108 #define TULIP_HZ        10
109
110 #include "if_devar.h"
111
112 /*
113  * This module supports
114  *      the DEC 21040 PCI Ethernet Controller.
115  *      the DEC 21041 PCI Ethernet Controller.
116  *      the DEC 21140 PCI Fast Ethernet Controller.
117  */
118 static void tulip_mii_autonegotiate(tulip_softc_t * const sc, const unsigned phyaddr);
119 static void tulip_intr_shared(void *arg);
120 static void tulip_intr_normal(void *arg);
121 static void tulip_init(tulip_softc_t * const sc);
122 static void tulip_reset(tulip_softc_t * const sc);
123 static void tulip_ifstart(struct ifnet *ifp);
124 static struct mbuf *tulip_txput(tulip_softc_t * const sc, struct mbuf *m);
125 static void tulip_txput_setup(tulip_softc_t * const sc);
126 static void tulip_rx_intr(tulip_softc_t * const sc);
127 static void tulip_addr_filter(tulip_softc_t * const sc);
128 static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno);
129 static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data);
130 static int tulip_mii_map_abilities(tulip_softc_t * const sc, unsigned abilities);
131 static tulip_media_t tulip_mii_phy_readspecific(tulip_softc_t * const sc);
132 static int tulip_srom_decode(tulip_softc_t * const sc);
133 static int tulip_ifmedia_change(struct ifnet * const ifp);
134 static void tulip_ifmedia_status(struct ifnet * const ifp, struct ifmediareq *req);
135 /* static void tulip_21140_map_media(tulip_softc_t *sc); */
136 \f
137 static void
138 tulip_timeout_callback(
139     void *arg)
140 {
141     tulip_softc_t * const sc = arg;
142     int s = splimp();
143
144     sc->tulip_flags &= ~TULIP_TIMEOUTPENDING;
145     sc->tulip_probe_timeout -= 1000 / TULIP_HZ;
146     (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_TIMER);
147     splx(s);
148 }
149
150 static void
151 tulip_timeout(
152     tulip_softc_t * const sc)
153 {
154     if (sc->tulip_flags & TULIP_TIMEOUTPENDING)
155         return;
156     sc->tulip_flags |= TULIP_TIMEOUTPENDING;
157     callout_reset(&sc->tulip_timer, (hz + TULIP_HZ / 2) / TULIP_HZ,
158             tulip_timeout_callback, sc);
159 }
160
161 #if defined(TULIP_NEED_FASTTIMEOUT)
162 static void
163 tulip_fasttimeout_callback(
164     void *arg)
165 {
166     tulip_softc_t * const sc = arg;
167     int s = splimp();
168
169     sc->tulip_flags &= ~TULIP_FASTTIMEOUTPENDING;
170     (sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_FASTTIMER);
171     splx(s);
172 }
173
174 static void
175 tulip_fasttimeout(
176     tulip_softc_t * const sc)
177 {
178     if (sc->tulip_flags & TULIP_FASTTIMEOUTPENDING)
179         return;
180     sc->tulip_flags |= TULIP_FASTTIMEOUTPENDING;
181     callout_reset(&sc->tulip_fast_timer, 1, tulip_fasttimeout_callback, sc);
182 }
183 #endif
184 \f
185 static int
186 tulip_txprobe(
187     tulip_softc_t * const sc)
188 {
189     struct mbuf *m;
190     /*
191      * Before we are sure this is the right media we need
192      * to send a small packet to make sure there's carrier.
193      * Strangely, BNC and AUI will "see" receive data if
194      * either is connected so the transmit is the only way
195      * to verify the connectivity.
196      */
197     MGETHDR(m, MB_DONTWAIT, MT_DATA);
198     if (m == NULL)
199         return 0;
200     /*
201      * Construct a LLC TEST message which will point to ourselves.
202      */
203     bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_dhost, 6);
204     bcopy(sc->tulip_enaddr, mtod(m, struct ether_header *)->ether_shost, 6);
205     mtod(m, struct ether_header *)->ether_type = htons(3);
206     mtod(m, unsigned char *)[14] = 0;
207     mtod(m, unsigned char *)[15] = 0;
208     mtod(m, unsigned char *)[16] = 0xE3;        /* LLC Class1 TEST (no poll) */
209     m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
210     /*
211      * send it!
212      */
213     sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
214     sc->tulip_intrmask |= TULIP_STS_TXINTR;
215     sc->tulip_flags |= TULIP_TXPROBE_ACTIVE;
216     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
217     TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
218     if ((m = tulip_txput(sc, m)) != NULL)
219         m_freem(m);
220     sc->tulip_probe.probe_txprobes++;
221     return 1;
222 }
223 \f
224 #ifdef BIG_PACKET
225 #define TULIP_SIAGEN_WATCHDOG   (sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)
226 #else
227 #define TULIP_SIAGEN_WATCHDOG   0
228 #endif
229
230 static void
231 tulip_media_set(
232     tulip_softc_t * const sc,
233     tulip_media_t media)
234 {
235     const tulip_media_info_t *mi = sc->tulip_mediums[media];
236
237     if (mi == NULL)
238         return;
239
240     /*
241      * If we are switching media, make sure we don't think there's
242      * any stale RX activity
243      */
244     sc->tulip_flags &= ~TULIP_RXACT;
245     if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
246         TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
247         TULIP_CSR_WRITE(sc, csr_sia_tx_rx,        mi->mi_sia_tx_rx);
248         if (sc->tulip_features & TULIP_HAVE_SIAGP) {
249             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_control|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
250             DELAY(50);
251             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_gp_data|mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
252         } else {
253             TULIP_CSR_WRITE(sc, csr_sia_general,  mi->mi_sia_general|TULIP_SIAGEN_WATCHDOG);
254         }
255         TULIP_CSR_WRITE(sc, csr_sia_connectivity, mi->mi_sia_connectivity);
256     } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
257 #define TULIP_GPR_CMDBITS       (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)
258         /*
259          * If the cmdmode bits don't match the currently operating mode,
260          * set the cmdmode appropriately and reset the chip.
261          */
262         if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
263             sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
264             sc->tulip_cmdmode |= mi->mi_cmdmode;
265             tulip_reset(sc);
266         }
267         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
268         DELAY(10);
269         TULIP_CSR_WRITE(sc, csr_gp, (u_int8_t) mi->mi_gpdata);
270     } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
271         /*
272          * If the cmdmode bits don't match the currently operating mode,
273          * set the cmdmode appropriately and reset the chip.
274          */
275         if (((mi->mi_cmdmode ^ TULIP_CSR_READ(sc, csr_command)) & TULIP_GPR_CMDBITS) != 0) {
276             sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
277             sc->tulip_cmdmode |= mi->mi_cmdmode;
278             tulip_reset(sc);
279         }
280         TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpcontrol);
281         TULIP_CSR_WRITE(sc, csr_sia_general, mi->mi_gpdata);
282     } else if (mi->mi_type == TULIP_MEDIAINFO_MII
283                && sc->tulip_probe_state != TULIP_PROBE_INACTIVE) {
284         int idx;
285         if (sc->tulip_features & TULIP_HAVE_SIAGP) {
286             const u_int8_t *dp;
287             dp = &sc->tulip_rombuf[mi->mi_reset_offset];
288             for (idx = 0; idx < mi->mi_reset_length; idx++, dp += 2) {
289                 DELAY(10);
290                 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
291             }
292             sc->tulip_phyaddr = mi->mi_phyaddr;
293             dp = &sc->tulip_rombuf[mi->mi_gpr_offset];
294             for (idx = 0; idx < mi->mi_gpr_length; idx++, dp += 2) {
295                 DELAY(10);
296                 TULIP_CSR_WRITE(sc, csr_sia_general, (dp[0] + 256 * dp[1]) << 16);
297             }
298         } else {
299             for (idx = 0; idx < mi->mi_reset_length; idx++) {
300                 DELAY(10);
301                 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx]);
302             }
303             sc->tulip_phyaddr = mi->mi_phyaddr;
304             for (idx = 0; idx < mi->mi_gpr_length; idx++) {
305                 DELAY(10);
306                 TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx]);
307             }
308         }
309         if (sc->tulip_flags & TULIP_TRYNWAY) {
310             tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
311         } else if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {
312             u_int32_t data = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_CONTROL);
313             data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX|PHYCTL_AUTONEG_ENABLE);
314             sc->tulip_flags &= ~TULIP_DIDNWAY;
315             if (TULIP_IS_MEDIA_FD(media))
316                 data |= PHYCTL_FULL_DUPLEX;
317             if (TULIP_IS_MEDIA_100MB(media))
318                 data |= PHYCTL_SELECT_100MB;
319             tulip_mii_writereg(sc, sc->tulip_phyaddr, PHYREG_CONTROL, data);
320         }
321     }
322 }
323 \f
324 static void
325 tulip_linkup(
326     tulip_softc_t * const sc,
327     tulip_media_t media)
328 {
329     if ((sc->tulip_flags & TULIP_LINKUP) == 0)
330         sc->tulip_flags |= TULIP_PRINTLINKUP;
331     sc->tulip_flags |= TULIP_LINKUP;
332     sc->tulip_if.if_flags &= ~IFF_OACTIVE;
333 #if 0 /* XXX how does with work with ifmedia? */
334     if ((sc->tulip_flags & TULIP_DIDNWAY) == 0) {
335         if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) {
336             if (TULIP_CAN_MEDIA_FD(media)
337                     && sc->tulip_mediums[TULIP_FD_MEDIA_OF(media)] != NULL)
338                 media = TULIP_FD_MEDIA_OF(media);
339         } else {
340             if (TULIP_IS_MEDIA_FD(media)
341                     && sc->tulip_mediums[TULIP_HD_MEDIA_OF(media)] != NULL)
342                 media = TULIP_HD_MEDIA_OF(media);
343         }
344     }
345 #endif
346     if (sc->tulip_media != media) {
347 #ifdef TULIP_DEBUG
348         sc->tulip_dbg.dbg_last_media = sc->tulip_media;
349 #endif
350         sc->tulip_media = media;
351         sc->tulip_flags |= TULIP_PRINTMEDIA;
352         if (TULIP_IS_MEDIA_FD(sc->tulip_media)) {
353             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
354         } else if (sc->tulip_chipid != TULIP_21041 || (sc->tulip_flags & TULIP_DIDNWAY) == 0) {
355             sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
356         }
357     }
358     /*
359      * We could set probe_timeout to 0 but setting to 3000 puts this
360      * in one central place and the only matters is tulip_link is
361      * followed by a tulip_timeout.  Therefore setting it should not
362      * result in aberrant behavour.
363      */
364     sc->tulip_probe_timeout = 3000;
365     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
366     sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TRYNWAY);
367     if (sc->tulip_flags & TULIP_INRESET) {
368         tulip_media_set(sc, sc->tulip_media);
369     } else if (sc->tulip_probe_media != sc->tulip_media) {
370         /*
371          * No reason to change media if we have the right media.
372          */
373         tulip_reset(sc);
374     }
375     tulip_init(sc);
376 }
377 \f
378 static void
379 tulip_media_print(
380     tulip_softc_t * const sc)
381 {
382     if ((sc->tulip_flags & TULIP_LINKUP) == 0)
383         return;
384     if (sc->tulip_flags & TULIP_PRINTMEDIA) {
385         printf("%s%d: enabling %s port\n",
386                sc->tulip_name, sc->tulip_unit,
387                tulip_mediums[sc->tulip_media]);
388         sc->tulip_flags &= ~(TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
389     } else if (sc->tulip_flags & TULIP_PRINTLINKUP) {
390         printf("%s%d: link up\n", sc->tulip_name, sc->tulip_unit);
391         sc->tulip_flags &= ~TULIP_PRINTLINKUP;
392     }
393 }
394 \f
395 #if defined(TULIP_DO_GPR_SENSE)
396 static tulip_media_t
397 tulip_21140_gpr_media_sense(
398     tulip_softc_t * const sc)
399 {
400     tulip_media_t maybe_media = TULIP_MEDIA_UNKNOWN;
401     tulip_media_t last_media = TULIP_MEDIA_UNKNOWN;
402     tulip_media_t media;
403
404     /*
405      * If one of the media blocks contained a default media flag,
406      * use that.
407      */
408     for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
409         const tulip_media_info_t *mi;
410         /*
411          * Media is not supported (or is full-duplex).
412          */
413         if ((mi = sc->tulip_mediums[media]) == NULL || TULIP_IS_MEDIA_FD(media))
414             continue;
415         if (mi->mi_type != TULIP_MEDIAINFO_GPR)
416             continue;
417
418         /*
419          * Remember the media is this is the "default" media.
420          */
421         if (mi->mi_default && maybe_media == TULIP_MEDIA_UNKNOWN)
422             maybe_media = media;
423
424         /*
425          * No activity mask?  Can't see if it is active if there's no mask.
426          */
427         if (mi->mi_actmask == 0)
428             continue;
429
430         /*
431          * Does the activity data match?
432          */
433         if ((TULIP_CSR_READ(sc, csr_gp) & mi->mi_actmask) != mi->mi_actdata)
434             continue;
435
436 #if defined(TULIP_DEBUG)
437         printf("%s%d: gpr_media_sense: %s: 0x%02x & 0x%02x == 0x%02x\n",
438                sc->tulip_name, sc->tulip_unit, tulip_mediums[media],
439                TULIP_CSR_READ(sc, csr_gp) & 0xFF,
440                mi->mi_actmask, mi->mi_actdata);
441 #endif
442         /*
443          * It does!  If this is the first media we detected, then 
444          * remember this media.  If isn't the first, then there were
445          * multiple matches which we equate to no match (since we don't
446          * which to select (if any).
447          */
448         if (last_media == TULIP_MEDIA_UNKNOWN) {
449             last_media = media;
450         } else if (last_media != media) {
451             last_media = TULIP_MEDIA_UNKNOWN;
452         }
453     }
454     return (last_media != TULIP_MEDIA_UNKNOWN) ? last_media : maybe_media;
455 }
456 #endif /* TULIP_DO_GPR_SENSE */
457 \f
458 static tulip_link_status_t
459 tulip_media_link_monitor(
460     tulip_softc_t * const sc)
461 {
462     const tulip_media_info_t * const mi = sc->tulip_mediums[sc->tulip_media];
463     tulip_link_status_t linkup = TULIP_LINK_DOWN;
464
465     if (mi == NULL) {
466 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
467         panic("tulip_media_link_monitor: %s: botch at line %d\n",
468               tulip_mediums[sc->tulip_media],__LINE__);
469 #endif
470         return TULIP_LINK_UNKNOWN;
471     }
472
473
474     /*
475      * Have we seen some packets?  If so, the link must be good.
476      */
477     if ((sc->tulip_flags & (TULIP_RXACT|TULIP_LINKUP)) == (TULIP_RXACT|TULIP_LINKUP)) {
478         sc->tulip_flags &= ~TULIP_RXACT;
479         sc->tulip_probe_timeout = 3000;
480         return TULIP_LINK_UP;
481     }
482
483     sc->tulip_flags &= ~TULIP_RXACT;
484     if (mi->mi_type == TULIP_MEDIAINFO_MII) {
485         u_int32_t status;
486         /*
487          * Read the PHY status register.
488          */
489         status = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_STATUS);
490         if (status & PHYSTS_AUTONEG_DONE) {
491             /*
492              * If the PHY has completed autonegotiation, see the if the
493              * remote systems abilities have changed.  If so, upgrade or
494              * downgrade as appropriate.
495              */
496             u_int32_t abilities = tulip_mii_readreg(sc, sc->tulip_phyaddr, PHYREG_AUTONEG_ABILITIES);
497             abilities = (abilities << 6) & status;
498             if (abilities != sc->tulip_abilities) {
499 #if defined(TULIP_DEBUG)
500                 loudprintf("%s%d(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n",
501                            sc->tulip_name, sc->tulip_unit, sc->tulip_phyaddr,
502                            sc->tulip_abilities, abilities);
503 #endif
504                 if (tulip_mii_map_abilities(sc, abilities)) {
505                     tulip_linkup(sc, sc->tulip_probe_media);
506                     return TULIP_LINK_UP;
507                 }
508                 /*
509                  * if we had selected media because of autonegotiation,
510                  * we need to probe for the new media.
511                  */
512                 sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
513                 if (sc->tulip_flags & TULIP_DIDNWAY)
514                     return TULIP_LINK_DOWN;
515             }
516         }
517         /*
518          * The link is now up.  If was down, say its back up.
519          */
520         if ((status & (PHYSTS_LINK_UP|PHYSTS_REMOTE_FAULT)) == PHYSTS_LINK_UP)
521             linkup = TULIP_LINK_UP;
522     } else if (mi->mi_type == TULIP_MEDIAINFO_GPR) {
523         /*
524          * No activity sensor?  Assume all's well.
525          */
526         if (mi->mi_actmask == 0)
527             return TULIP_LINK_UNKNOWN;
528         /*
529          * Does the activity data match?
530          */
531         if ((TULIP_CSR_READ(sc, csr_gp) & mi->mi_actmask) == mi->mi_actdata)
532             linkup = TULIP_LINK_UP;
533     } else if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
534         /*
535          * Assume non TP ok for now.
536          */
537         if (!TULIP_IS_MEDIA_TP(sc->tulip_media))
538             return TULIP_LINK_UNKNOWN;
539         if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0)
540             linkup = TULIP_LINK_UP;
541 #if defined(TULIP_DEBUG)
542         if (sc->tulip_probe_timeout <= 0)
543             printf("%s%d: sia status = 0x%08x\n", sc->tulip_name,
544                     sc->tulip_unit, TULIP_CSR_READ(sc, csr_sia_status));
545 #endif
546     } else if (mi->mi_type == TULIP_MEDIAINFO_SYM) {
547         return TULIP_LINK_UNKNOWN;
548     }
549     /*
550      * We will wait for 3 seconds until the link goes into suspect mode.
551      */
552     if (sc->tulip_flags & TULIP_LINKUP) {
553         if (linkup == TULIP_LINK_UP)
554             sc->tulip_probe_timeout = 3000;
555         if (sc->tulip_probe_timeout > 0)
556             return TULIP_LINK_UP;
557
558         sc->tulip_flags &= ~TULIP_LINKUP;
559         printf("%s%d: link down: cable problem?\n", sc->tulip_name, sc->tulip_unit);
560     }
561 #if defined(TULIP_DEBUG)
562     sc->tulip_dbg.dbg_link_downed++;
563 #endif
564     return TULIP_LINK_DOWN;
565 }
566 \f
567 static void
568 tulip_media_poll(
569     tulip_softc_t * const sc,
570     tulip_mediapoll_event_t event)
571 {
572 #if defined(TULIP_DEBUG)
573     sc->tulip_dbg.dbg_events[event]++;
574 #endif
575     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE
576             && event == TULIP_MEDIAPOLL_TIMER) {
577         switch (tulip_media_link_monitor(sc)) {
578             case TULIP_LINK_DOWN: {
579                 /*
580                  * Link Monitor failed.  Probe for new media.
581                  */
582                 event = TULIP_MEDIAPOLL_LINKFAIL;
583                 break;
584             }
585             case TULIP_LINK_UP: {
586                 /*
587                  * Check again soon.
588                  */
589                 tulip_timeout(sc);
590                 return;
591             }
592             case TULIP_LINK_UNKNOWN: {
593                 /*
594                  * We can't tell so don't bother.
595                  */
596                 return;
597             }
598         }
599     }
600
601     if (event == TULIP_MEDIAPOLL_LINKFAIL) {
602         if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE) {
603             if (TULIP_DO_AUTOSENSE(sc)) {
604 #if defined(TULIP_DEBUG)
605                 sc->tulip_dbg.dbg_link_failures++;
606 #endif
607                 sc->tulip_media = TULIP_MEDIA_UNKNOWN;
608                 if (sc->tulip_if.if_flags & IFF_UP)
609                     tulip_reset(sc);    /* restart probe */
610             }
611             return;
612         }
613 #if defined(TULIP_DEBUG)
614         sc->tulip_dbg.dbg_link_pollintrs++;
615 #endif
616     }
617
618     if (event == TULIP_MEDIAPOLL_START) {
619         sc->tulip_if.if_flags |= IFF_OACTIVE;
620         if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE)
621             return;
622         sc->tulip_probe_mediamask = 0;
623         sc->tulip_probe_passes = 0;
624 #if defined(TULIP_DEBUG)
625         sc->tulip_dbg.dbg_media_probes++;
626 #endif
627         /*
628          * If the SROM contained an explicit media to use, use it.
629          */
630         sc->tulip_cmdmode &= ~(TULIP_CMD_RXRUN|TULIP_CMD_FULLDUPLEX);
631         sc->tulip_flags |= TULIP_TRYNWAY|TULIP_PROBE1STPASS;
632         sc->tulip_flags &= ~(TULIP_DIDNWAY|TULIP_PRINTMEDIA|TULIP_PRINTLINKUP);
633         /*
634          * connidx is defaulted to a media_unknown type.
635          */
636         sc->tulip_probe_media = tulip_srom_conninfo[sc->tulip_connidx].sc_media;
637         if (sc->tulip_probe_media != TULIP_MEDIA_UNKNOWN) {
638             tulip_linkup(sc, sc->tulip_probe_media);
639             tulip_timeout(sc);
640             return;
641         }
642
643         if (sc->tulip_features & TULIP_HAVE_GPR) {
644             sc->tulip_probe_state = TULIP_PROBE_GPRTEST;
645             sc->tulip_probe_timeout = 2000;
646         } else {
647             sc->tulip_probe_media = TULIP_MEDIA_MAX;
648             sc->tulip_probe_timeout = 0;
649             sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
650         }
651     }
652
653     /*
654      * Ignore txprobe failures or spurious callbacks.
655      */
656     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED
657             && sc->tulip_probe_state != TULIP_PROBE_MEDIATEST) {
658         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
659         return;
660     }
661
662     /*
663      * If we really transmitted a packet, then that's the media we'll use.
664      */
665     if (event == TULIP_MEDIAPOLL_TXPROBE_OK || event == TULIP_MEDIAPOLL_LINKPASS) {
666         if (event == TULIP_MEDIAPOLL_LINKPASS) {
667             /* XXX Check media status just to be sure */
668             sc->tulip_probe_media = TULIP_MEDIA_10BASET;
669 #if defined(TULIP_DEBUG)
670         } else {
671             sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
672 #endif
673         }
674         tulip_linkup(sc, sc->tulip_probe_media);
675         tulip_timeout(sc);
676         return;
677     }
678
679     if (sc->tulip_probe_state == TULIP_PROBE_GPRTEST) {
680 #if defined(TULIP_DO_GPR_SENSE)
681         /*
682          * Check for media via the general purpose register.
683          *
684          * Try to sense the media via the GPR.  If the same value
685          * occurs 3 times in a row then just use that.
686          */
687         if (sc->tulip_probe_timeout > 0) {
688             tulip_media_t new_probe_media = tulip_21140_gpr_media_sense(sc);
689 #if defined(TULIP_DEBUG)
690             printf("%s%d: media_poll: gpr sensing = %s\n",
691                    sc->tulip_name, sc->tulip_unit, tulip_mediums[new_probe_media]);
692 #endif
693             if (new_probe_media != TULIP_MEDIA_UNKNOWN) {
694                 if (new_probe_media == sc->tulip_probe_media) {
695                     if (--sc->tulip_probe_count == 0)
696                         tulip_linkup(sc, sc->tulip_probe_media);
697                 } else {
698                     sc->tulip_probe_count = 10;
699                 }
700             }
701             sc->tulip_probe_media = new_probe_media;
702             tulip_timeout(sc);
703             return;
704         }
705 #endif /* TULIP_DO_GPR_SENSE */
706         /*
707          * Brute force.  We cycle through each of the media types
708          * and try to transmit a packet.
709          */
710         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
711         sc->tulip_probe_media = TULIP_MEDIA_MAX;
712         sc->tulip_probe_timeout = 0;
713         tulip_timeout(sc);
714         return;
715     }
716
717     if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST
718            && (sc->tulip_features & TULIP_HAVE_MII)) {
719         tulip_media_t old_media = sc->tulip_probe_media;
720         tulip_mii_autonegotiate(sc, sc->tulip_phyaddr);
721         switch (sc->tulip_probe_state) {
722             case TULIP_PROBE_FAILED:
723             case TULIP_PROBE_MEDIATEST: {
724                 /*
725                  * Try the next media.
726                  */
727                 sc->tulip_probe_mediamask |= sc->tulip_mediums[sc->tulip_probe_media]->mi_mediamask;
728                 sc->tulip_probe_timeout = 0;
729 #ifdef notyet
730                 if (sc->tulip_probe_state == TULIP_PROBE_FAILED)
731                     break;
732                 if (sc->tulip_probe_media != tulip_mii_phy_readspecific(sc))
733                     break;
734                 sc->tulip_probe_timeout = TULIP_IS_MEDIA_TP(sc->tulip_probe_media) ? 2500 : 300;
735 #endif
736                 break;
737             }
738             case TULIP_PROBE_PHYAUTONEG: {
739                 return;
740             }
741             case TULIP_PROBE_INACTIVE: {
742                 /*
743                  * Only probe if we autonegotiated a media that hasn't failed.
744                  */
745                 sc->tulip_probe_timeout = 0;
746                 if (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media)) {
747                     sc->tulip_probe_media = old_media;
748                     break;
749                 }
750                 tulip_linkup(sc, sc->tulip_probe_media);
751                 tulip_timeout(sc);
752                 return;
753             }
754             default: {
755 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
756                 panic("tulip_media_poll: botch at line %d\n", __LINE__);
757 #endif
758                 break;
759             }
760         }
761     }
762
763     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED) {
764 #if defined(TULIP_DEBUG)
765         sc->tulip_dbg.dbg_txprobes_failed[sc->tulip_probe_media]++;
766 #endif
767         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
768         return;
769     }
770
771     /*
772      * switch to another media if we tried this one enough.
773      */
774     if (/* event == TULIP_MEDIAPOLL_TXPROBE_FAILED || */ sc->tulip_probe_timeout <= 0) {
775 #if defined(TULIP_DEBUG)
776         if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
777             printf("%s%d: poll media unknown!\n",
778                    sc->tulip_name, sc->tulip_unit);
779             sc->tulip_probe_media = TULIP_MEDIA_MAX;
780         }
781 #endif
782         /*
783          * Find the next media type to check for.  Full Duplex
784          * types are not allowed.
785          */
786         do {
787             sc->tulip_probe_media -= 1;
788             if (sc->tulip_probe_media == TULIP_MEDIA_UNKNOWN) {
789                 if (++sc->tulip_probe_passes == 3) {
790                     printf("%s%d: autosense failed: cable problem?\n",
791                            sc->tulip_name, sc->tulip_unit);
792                     if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
793                         sc->tulip_if.if_flags &= ~IFF_RUNNING;
794                         sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
795                         return;
796                     }
797                 }
798                 sc->tulip_flags ^= TULIP_TRYNWAY;       /* XXX */
799                 sc->tulip_probe_mediamask = 0;
800                 sc->tulip_probe_media = TULIP_MEDIA_MAX - 1;
801             }
802         } while (sc->tulip_mediums[sc->tulip_probe_media] == NULL
803                  || (sc->tulip_probe_mediamask & TULIP_BIT(sc->tulip_probe_media))
804                  || TULIP_IS_MEDIA_FD(sc->tulip_probe_media));
805
806 #if defined(TULIP_DEBUG)
807         printf("%s%d: %s: probing %s\n", sc->tulip_name, sc->tulip_unit,
808                event == TULIP_MEDIAPOLL_TXPROBE_FAILED ? "txprobe failed" : "timeout",
809                tulip_mediums[sc->tulip_probe_media]);
810 #endif
811         sc->tulip_probe_timeout = TULIP_IS_MEDIA_TP(sc->tulip_probe_media) ? 2500 : 1000;
812         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
813         sc->tulip_probe.probe_txprobes = 0;
814         tulip_reset(sc);
815         tulip_media_set(sc, sc->tulip_probe_media);
816         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
817     }
818     tulip_timeout(sc);
819
820     /*
821      * If this is hanging off a phy, we know are doing NWAY and we have
822      * forced the phy to a specific speed.  Wait for link up before
823      * before sending a packet.
824      */
825     switch (sc->tulip_mediums[sc->tulip_probe_media]->mi_type) {
826         case TULIP_MEDIAINFO_MII: {
827             if (sc->tulip_probe_media != tulip_mii_phy_readspecific(sc))
828                 return;
829             break;
830         }
831         case TULIP_MEDIAINFO_SIA: {
832             if (TULIP_IS_MEDIA_TP(sc->tulip_probe_media)) {
833                 if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL)
834                     return;
835                 tulip_linkup(sc, sc->tulip_probe_media);
836 #ifdef notyet
837                 if (sc->tulip_features & TULIP_HAVE_MII)
838                     tulip_timeout(sc);
839 #endif
840                 return;
841             }
842             break;
843         }
844         case TULIP_MEDIAINFO_RESET:
845         case TULIP_MEDIAINFO_SYM:
846         case TULIP_MEDIAINFO_NONE:
847         case TULIP_MEDIAINFO_GPR: {
848             break;
849         }
850     }
851     /*
852      * Try to send a packet.
853      */
854     tulip_txprobe(sc);
855 }
856 \f
857 static void
858 tulip_media_select(
859     tulip_softc_t * const sc)
860 {
861     if (sc->tulip_features & TULIP_HAVE_GPR) {
862         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET|sc->tulip_gpinit);
863         DELAY(10);
864         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpdata);
865     }
866     /*
867      * If this board has no media, just return
868      */
869     if (sc->tulip_features & TULIP_HAVE_NOMEDIA)
870         return;
871
872     if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
873         TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
874         (*sc->tulip_boardsw->bd_media_poll)(sc, TULIP_MEDIAPOLL_START);
875     } else {
876         tulip_media_set(sc, sc->tulip_media);
877     }
878 }
879 \f
880 static void
881 tulip_21040_mediainfo_init(
882     tulip_softc_t * const sc,
883     tulip_media_t media)
884 {
885     sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160
886         |TULIP_CMD_BACKOFFCTR;
887     sc->tulip_if.if_baudrate = 10000000;
888
889     if (media == TULIP_MEDIA_10BASET || media == TULIP_MEDIA_UNKNOWN) {
890         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[0], 21040, 10BASET);
891         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[1], 21040, 10BASET_FD);
892         sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
893     }
894
895     if (media == TULIP_MEDIA_AUIBNC || media == TULIP_MEDIA_UNKNOWN) {
896         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[2], 21040, AUIBNC);
897     }
898
899     if (media == TULIP_MEDIA_UNKNOWN) {
900         TULIP_MEDIAINFO_SIA_INIT(sc, &sc->tulip_mediainfo[3], 21040, EXTSIA);
901     }
902 }
903
904 static void
905 tulip_21040_media_probe(
906     tulip_softc_t * const sc)
907 {
908     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_UNKNOWN);
909     return;
910 }
911
912 static void
913 tulip_21040_10baset_only_media_probe(
914     tulip_softc_t * const sc)
915 {
916     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_10BASET);
917     tulip_media_set(sc, TULIP_MEDIA_10BASET);
918     sc->tulip_media = TULIP_MEDIA_10BASET;
919 }
920
921 static void
922 tulip_21040_10baset_only_media_select(
923     tulip_softc_t * const sc)
924 {
925     sc->tulip_flags |= TULIP_LINKUP;
926     if (sc->tulip_media == TULIP_MEDIA_10BASET_FD) {
927         sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
928         sc->tulip_flags &= ~TULIP_SQETEST;
929     } else {
930         sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
931         sc->tulip_flags |= TULIP_SQETEST;
932     }
933     tulip_media_set(sc, sc->tulip_media);
934 }
935
936 static void
937 tulip_21040_auibnc_only_media_probe(
938     tulip_softc_t * const sc)
939 {
940     tulip_21040_mediainfo_init(sc, TULIP_MEDIA_AUIBNC);
941     sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP;
942     tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
943     sc->tulip_media = TULIP_MEDIA_AUIBNC;
944 }
945
946 static void
947 tulip_21040_auibnc_only_media_select(
948     tulip_softc_t * const sc)
949 {
950     tulip_media_set(sc, TULIP_MEDIA_AUIBNC);
951     sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
952 }
953
954 static const tulip_boardsw_t tulip_21040_boardsw = {
955     TULIP_21040_GENERIC,
956     tulip_21040_media_probe,
957     tulip_media_select,
958     tulip_media_poll,
959 };
960
961 static const tulip_boardsw_t tulip_21040_10baset_only_boardsw = {
962     TULIP_21040_GENERIC,
963     tulip_21040_10baset_only_media_probe,
964     tulip_21040_10baset_only_media_select,
965     NULL,
966 };
967
968 static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw = {
969     TULIP_21040_GENERIC,
970     tulip_21040_auibnc_only_media_probe,
971     tulip_21040_auibnc_only_media_select,
972     NULL,
973 };
974 \f
975 static void
976 tulip_21041_mediainfo_init(
977     tulip_softc_t * const sc)
978 {
979     tulip_media_info_t * const mi = sc->tulip_mediainfo;
980
981 #ifdef notyet
982     if (sc->tulip_revinfo >= 0x20) {
983         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, 10BASET);
984         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041P2, 10BASET_FD);
985         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041P2, AUI);
986         TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041P2, BNC);
987         return;
988     }
989 #endif
990     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[0], 21041, 10BASET);
991     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[1], 21041, 10BASET_FD);
992     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[2], 21041, AUI);
993     TULIP_MEDIAINFO_SIA_INIT(sc, &mi[3], 21041, BNC);
994 }
995 \f
996 static void
997 tulip_21041_media_probe(
998     tulip_softc_t * const sc)
999 {
1000     sc->tulip_if.if_baudrate = 10000000;
1001     sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT
1002         |TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR;
1003     sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
1004     tulip_21041_mediainfo_init(sc);
1005 }
1006
1007 static void
1008 tulip_21041_media_poll(
1009     tulip_softc_t * const sc,
1010     const tulip_mediapoll_event_t event)
1011 {
1012     u_int32_t sia_status;
1013
1014 #if defined(TULIP_DEBUG)
1015     sc->tulip_dbg.dbg_events[event]++;
1016 #endif
1017
1018     if (event == TULIP_MEDIAPOLL_LINKFAIL) {
1019         if (sc->tulip_probe_state != TULIP_PROBE_INACTIVE
1020                 || !TULIP_DO_AUTOSENSE(sc))
1021             return;
1022         sc->tulip_media = TULIP_MEDIA_UNKNOWN;
1023         tulip_reset(sc);        /* start probe */
1024         return;
1025     }
1026
1027     /*
1028      * If we've been been asked to start a poll or link change interrupt
1029      * restart the probe (and reset the tulip to a known state).
1030      */
1031     if (event == TULIP_MEDIAPOLL_START) {
1032         sc->tulip_if.if_flags |= IFF_OACTIVE;
1033         sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_RXRUN);
1034 #ifdef notyet
1035         if (sc->tulip_revinfo >= 0x20) {
1036             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX;
1037             sc->tulip_flags |= TULIP_DIDNWAY;
1038         }
1039 #endif
1040         TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1041         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1042         sc->tulip_probe_media = TULIP_MEDIA_10BASET;
1043         sc->tulip_probe_timeout = TULIP_21041_PROBE_10BASET_TIMEOUT;
1044         tulip_media_set(sc, TULIP_MEDIA_10BASET);
1045         tulip_timeout(sc);
1046         return;
1047     }
1048
1049     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
1050         return;
1051
1052     if (event == TULIP_MEDIAPOLL_TXPROBE_OK) {
1053 #if defined(TULIP_DEBUG)
1054         sc->tulip_dbg.dbg_txprobes_ok[sc->tulip_probe_media]++;
1055 #endif
1056         tulip_linkup(sc, sc->tulip_probe_media);
1057         return;
1058     }
1059
1060     sia_status = TULIP_CSR_READ(sc, csr_sia_status);
1061     TULIP_CSR_WRITE(sc, csr_sia_status, sia_status);
1062     if ((sia_status & TULIP_SIASTS_LINKFAIL) == 0) {
1063         if (sc->tulip_revinfo >= 0x20) {
1064             if (sia_status & (PHYSTS_10BASET_FD << (16 - 6)))
1065                 sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
1066         }
1067         /*
1068          * If the link has passed LinkPass, 10baseT is the
1069          * proper media to use.
1070          */
1071         tulip_linkup(sc, sc->tulip_probe_media);
1072         return;
1073     }
1074
1075     /*
1076      * wait for up to 2.4 seconds for the link to reach pass state.
1077      * Only then start scanning the other media for activity.
1078      * choose media with receive activity over those without.
1079      */
1080     if (sc->tulip_probe_media == TULIP_MEDIA_10BASET) {
1081         if (event != TULIP_MEDIAPOLL_TIMER)
1082             return;
1083         if (sc->tulip_probe_timeout > 0
1084                 && (sia_status & TULIP_SIASTS_OTHERRXACTIVITY) == 0) {
1085             tulip_timeout(sc);
1086             return;
1087         }
1088         sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1089         sc->tulip_flags |= TULIP_WANTRXACT;
1090         if (sia_status & TULIP_SIASTS_OTHERRXACTIVITY) {
1091             sc->tulip_probe_media = TULIP_MEDIA_BNC;
1092         } else {
1093             sc->tulip_probe_media = TULIP_MEDIA_AUI;
1094         }
1095         tulip_media_set(sc, sc->tulip_probe_media);
1096         tulip_timeout(sc);
1097         return;
1098     }
1099
1100     /*
1101      * If we failed, clear the txprobe active flag.
1102      */
1103     if (event == TULIP_MEDIAPOLL_TXPROBE_FAILED)
1104         sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1105
1106
1107     if (event == TULIP_MEDIAPOLL_TIMER) {
1108         /*
1109          * If we've received something, then that's our link!
1110          */
1111         if (sc->tulip_flags & TULIP_RXACT) {
1112             tulip_linkup(sc, sc->tulip_probe_media);
1113             return;
1114         }
1115         /*
1116          * if no txprobe active  
1117          */
1118         if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0
1119                 && ((sc->tulip_flags & TULIP_WANTRXACT) == 0
1120                     || (sia_status & TULIP_SIASTS_RXACTIVITY))) {
1121             sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1122             tulip_txprobe(sc);
1123             tulip_timeout(sc);
1124             return;
1125         }
1126         /*
1127          * Take 2 passes through before deciding to not
1128          * wait for receive activity.  Then take another
1129          * two passes before spitting out a warning.
1130          */
1131         if (sc->tulip_probe_timeout <= 0) {
1132             if (sc->tulip_flags & TULIP_WANTRXACT) {
1133                 sc->tulip_flags &= ~TULIP_WANTRXACT;
1134                 sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1135             } else {
1136                 printf("%s%d: autosense failed: cable problem?\n",
1137                        sc->tulip_name, sc->tulip_unit);
1138                 if ((sc->tulip_if.if_flags & IFF_UP) == 0) {
1139                     sc->tulip_if.if_flags &= ~IFF_RUNNING;
1140                     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1141                     return;
1142                 }
1143             }
1144         }
1145     }
1146     
1147     /*
1148      * Since this media failed to probe, try the other one.
1149      */
1150     sc->tulip_probe_timeout = TULIP_21041_PROBE_AUIBNC_TIMEOUT;
1151     if (sc->tulip_probe_media == TULIP_MEDIA_AUI) {
1152         sc->tulip_probe_media = TULIP_MEDIA_BNC;
1153     } else {
1154         sc->tulip_probe_media = TULIP_MEDIA_AUI;
1155     }
1156     tulip_media_set(sc, sc->tulip_probe_media);
1157     sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1158     tulip_timeout(sc);
1159 }
1160
1161 static const tulip_boardsw_t tulip_21041_boardsw = {
1162     TULIP_21041_GENERIC,
1163     tulip_21041_media_probe,
1164     tulip_media_select,
1165     tulip_21041_media_poll
1166 };
1167 \f
1168 static const tulip_phy_attr_t tulip_mii_phy_attrlist[] = {
1169     { 0x20005c00, 0,            /* 08-00-17 */
1170       {
1171         { 0x19, 0x0040, 0x0040 },       /* 10TX */
1172         { 0x19, 0x0040, 0x0000 },       /* 100TX */
1173       },
1174 #if defined(TULIP_DEBUG)
1175       "NS DP83840",
1176 #endif
1177     },
1178     { 0x0281F400, 0,            /* 00-A0-7D */
1179       {
1180         { 0x12, 0x0010, 0x0000 },       /* 10T */
1181         { },                            /* 100TX */
1182         { 0x12, 0x0010, 0x0010 },       /* 100T4 */
1183         { 0x12, 0x0008, 0x0008 },       /* FULL_DUPLEX */
1184       },
1185 #if defined(TULIP_DEBUG)
1186       "Seeq 80C240"
1187 #endif
1188     },
1189 #if 0
1190     { 0x0015F420, 0,    /* 00-A0-7D */
1191       {
1192         { 0x12, 0x0010, 0x0000 },       /* 10T */
1193         { },                            /* 100TX */
1194         { 0x12, 0x0010, 0x0010 },       /* 100T4 */
1195         { 0x12, 0x0008, 0x0008 },       /* FULL_DUPLEX */
1196       },
1197 #if defined(TULIP_DEBUG)
1198       "Broadcom BCM5000"
1199 #endif
1200     },
1201 #endif
1202     { 0x0281F400, 0,            /* 00-A0-BE */
1203       {
1204         { 0x11, 0x8000, 0x0000 },       /* 10T */
1205         { 0x11, 0x8000, 0x8000 },       /* 100TX */
1206         { },                            /* 100T4 */
1207         { 0x11, 0x4000, 0x4000 },       /* FULL_DUPLEX */
1208       },
1209 #if defined(TULIP_DEBUG)
1210       "ICS 1890"
1211 #endif 
1212     },
1213     { 0 }
1214 };
1215 \f
1216 static tulip_media_t
1217 tulip_mii_phy_readspecific(
1218     tulip_softc_t * const sc)
1219 {
1220     const tulip_phy_attr_t *attr;
1221     u_int16_t data;
1222     u_int32_t id;
1223     unsigned idx = 0;
1224     static const tulip_media_t table[] = {
1225         TULIP_MEDIA_UNKNOWN,
1226         TULIP_MEDIA_10BASET,
1227         TULIP_MEDIA_100BASETX,
1228         TULIP_MEDIA_100BASET4,
1229         TULIP_MEDIA_UNKNOWN,
1230         TULIP_MEDIA_10BASET_FD,
1231         TULIP_MEDIA_100BASETX_FD,
1232         TULIP_MEDIA_UNKNOWN
1233     };
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 \f
1277 static unsigned
1278 tulip_mii_get_phyaddr(
1279     tulip_softc_t * const sc,
1280     unsigned offset)
1281 {
1282     unsigned phyaddr;
1283
1284     for (phyaddr = 1; phyaddr < 32; phyaddr++) {
1285         unsigned status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1286         if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
1287             continue;
1288         if (offset == 0)
1289             return phyaddr;
1290         offset--;
1291     }
1292     if (offset == 0) {
1293         unsigned status = tulip_mii_readreg(sc, 0, PHYREG_STATUS);
1294         if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET)
1295             return TULIP_MII_NOPHY;
1296         return 0;
1297     }
1298     return TULIP_MII_NOPHY;
1299 }
1300 \f
1301 static int
1302 tulip_mii_map_abilities(
1303     tulip_softc_t * const sc,
1304     unsigned abilities)
1305 {
1306     sc->tulip_abilities = abilities;
1307     if (abilities & PHYSTS_100BASETX_FD) {
1308         sc->tulip_probe_media = TULIP_MEDIA_100BASETX_FD;
1309     } else if (abilities & PHYSTS_100BASET4) {
1310         sc->tulip_probe_media = TULIP_MEDIA_100BASET4;
1311     } else if (abilities & PHYSTS_100BASETX) {
1312         sc->tulip_probe_media = TULIP_MEDIA_100BASETX;
1313     } else if (abilities & PHYSTS_10BASET_FD) {
1314         sc->tulip_probe_media = TULIP_MEDIA_10BASET_FD;
1315     } else if (abilities & PHYSTS_10BASET) {
1316         sc->tulip_probe_media = TULIP_MEDIA_10BASET;
1317     } else {
1318         sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1319         return 0;
1320     }
1321     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
1322     return 1;
1323 }
1324
1325 static void
1326 tulip_mii_autonegotiate(
1327     tulip_softc_t * const sc,
1328     const unsigned phyaddr)
1329 {
1330     switch (sc->tulip_probe_state) {
1331         case TULIP_PROBE_MEDIATEST:
1332         case TULIP_PROBE_INACTIVE: {
1333             sc->tulip_flags |= TULIP_DIDNWAY;
1334             tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, PHYCTL_RESET);
1335             sc->tulip_probe_timeout = 3000;
1336             sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_NORMALINTR;
1337             sc->tulip_probe_state = TULIP_PROBE_PHYRESET;
1338             /* FALL THROUGH */
1339         }
1340         case TULIP_PROBE_PHYRESET: {
1341             u_int32_t status;
1342             u_int32_t data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
1343             if (data & PHYCTL_RESET) {
1344                 if (sc->tulip_probe_timeout > 0) {
1345                     tulip_timeout(sc);
1346                     return;
1347                 }
1348                 printf("%s%d(phy%d): error: reset of PHY never completed!\n",
1349                            sc->tulip_name, sc->tulip_unit, phyaddr);
1350                 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE;
1351                 sc->tulip_probe_state = TULIP_PROBE_FAILED;
1352                 sc->tulip_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
1353                 return;
1354             }
1355             status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1356             if ((status & PHYSTS_CAN_AUTONEG) == 0) {
1357 #if defined(TULIP_DEBUG)
1358                 loudprintf("%s%d(phy%d): autonegotiation disabled\n",
1359                            sc->tulip_name, sc->tulip_unit, phyaddr);
1360 #endif
1361                 sc->tulip_flags &= ~TULIP_DIDNWAY;
1362                 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1363                 return;
1364             }
1365             if (tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT) != ((status >> 6) | 0x01))
1366                 tulip_mii_writereg(sc, phyaddr, PHYREG_AUTONEG_ADVERTISEMENT, (status >> 6) | 0x01);
1367             tulip_mii_writereg(sc, phyaddr, PHYREG_CONTROL, data|PHYCTL_AUTONEG_RESTART|PHYCTL_AUTONEG_ENABLE);
1368             data = tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL);
1369 #if defined(TULIP_DEBUG)
1370             if ((data & PHYCTL_AUTONEG_ENABLE) == 0)
1371                 loudprintf("%s%d(phy%d): oops: enable autonegotiation failed: 0x%04x\n",
1372                            sc->tulip_name, sc->tulip_unit, phyaddr, data);
1373             else
1374                 loudprintf("%s%d(phy%d): autonegotiation restarted: 0x%04x\n",
1375                            sc->tulip_name, sc->tulip_unit, phyaddr, data);
1376             sc->tulip_dbg.dbg_nway_starts++;
1377 #endif
1378             sc->tulip_probe_state = TULIP_PROBE_PHYAUTONEG;
1379             sc->tulip_probe_timeout = 3000;
1380             /* FALL THROUGH */
1381         }
1382         case TULIP_PROBE_PHYAUTONEG: {
1383             u_int32_t status = tulip_mii_readreg(sc, phyaddr, PHYREG_STATUS);
1384             u_int32_t data;
1385             if ((status & PHYSTS_AUTONEG_DONE) == 0) {
1386                 if (sc->tulip_probe_timeout > 0) {
1387                     tulip_timeout(sc);
1388                     return;
1389                 }
1390 #if defined(TULIP_DEBUG)
1391                 loudprintf("%s%d(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n",
1392                            sc->tulip_name, sc->tulip_unit, phyaddr, status,
1393                            tulip_mii_readreg(sc, phyaddr, PHYREG_CONTROL));
1394 #endif
1395                 sc->tulip_flags &= ~TULIP_DIDNWAY;
1396                 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST;
1397                 return;
1398             }
1399             data = tulip_mii_readreg(sc, phyaddr, PHYREG_AUTONEG_ABILITIES);
1400 #if defined(TULIP_DEBUG)
1401             loudprintf("%s%d(phy%d): autonegotiation complete: 0x%04x\n",
1402                        sc->tulip_name, sc->tulip_unit, phyaddr, data);
1403 #endif
1404             data = (data << 6) & status;
1405             if (!tulip_mii_map_abilities(sc, data))
1406                 sc->tulip_flags &= ~TULIP_DIDNWAY;
1407             return;
1408         }
1409         default: {
1410 #if defined(DIAGNOSTIC)
1411             panic("tulip_media_poll: botch at line %d\n", __LINE__);
1412 #endif
1413             break;
1414         }
1415     }
1416 #if defined(TULIP_DEBUG)
1417     loudprintf("%s%d(phy%d): autonegotiation failure: state = %d\n",
1418                sc->tulip_name, sc->tulip_unit, phyaddr, sc->tulip_probe_state);
1419             sc->tulip_dbg.dbg_nway_failures++;
1420 #endif
1421 }
1422 \f
1423 static void
1424 tulip_2114x_media_preset(
1425     tulip_softc_t * const sc)
1426 {
1427     const tulip_media_info_t *mi = NULL;
1428     tulip_media_t media = sc->tulip_media;
1429
1430     if (sc->tulip_probe_state == TULIP_PROBE_INACTIVE)
1431         media = sc->tulip_media;
1432     else
1433         media = sc->tulip_probe_media;
1434     
1435     sc->tulip_cmdmode &= ~TULIP_CMD_PORTSELECT;
1436     sc->tulip_flags &= ~TULIP_SQETEST;
1437     if (media != TULIP_MEDIA_UNKNOWN && media != TULIP_MEDIA_MAX) {
1438 #if defined(TULIP_DEBUG)
1439         if (media < TULIP_MEDIA_MAX && sc->tulip_mediums[media] != NULL) {
1440 #endif
1441             mi = sc->tulip_mediums[media];
1442             if (mi->mi_type == TULIP_MEDIAINFO_MII) {
1443                 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
1444             } else if (mi->mi_type == TULIP_MEDIAINFO_GPR
1445                        || mi->mi_type == TULIP_MEDIAINFO_SYM) {
1446                 sc->tulip_cmdmode &= ~TULIP_GPR_CMDBITS;
1447                 sc->tulip_cmdmode |= mi->mi_cmdmode;
1448             } else if (mi->mi_type == TULIP_MEDIAINFO_SIA) {
1449                 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET);
1450             }
1451 #if defined(TULIP_DEBUG)
1452         } else {
1453             printf("%s%d: preset: bad media %d!\n",
1454                    sc->tulip_name, sc->tulip_unit, media);
1455         }
1456 #endif
1457     }
1458     switch (media) {
1459         case TULIP_MEDIA_BNC:
1460         case TULIP_MEDIA_AUI:
1461         case TULIP_MEDIA_10BASET: {
1462             sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX;
1463             sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL;
1464             sc->tulip_if.if_baudrate = 10000000;
1465             sc->tulip_flags |= TULIP_SQETEST;
1466             break;
1467         }
1468         case TULIP_MEDIA_10BASET_FD: {
1469             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL;
1470             sc->tulip_if.if_baudrate = 10000000;
1471             break;
1472         }
1473         case TULIP_MEDIA_100BASEFX:
1474         case TULIP_MEDIA_100BASET4:
1475         case TULIP_MEDIA_100BASETX: {
1476             sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL);
1477             sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT;
1478             sc->tulip_if.if_baudrate = 100000000;
1479             break;
1480         }
1481         case TULIP_MEDIA_100BASEFX_FD:
1482         case TULIP_MEDIA_100BASETX_FD: {
1483             sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_PORTSELECT;
1484             sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL;
1485             sc->tulip_if.if_baudrate = 100000000;
1486             break;
1487         }
1488         default: {
1489             break;
1490         }
1491     }
1492     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
1493 }
1494 \f
1495 /*
1496  ********************************************************************
1497  *  Start of 21140/21140A support which does not use the MII interface 
1498  */
1499 \f
1500 static void
1501 tulip_null_media_poll(
1502     tulip_softc_t * const sc,
1503     tulip_mediapoll_event_t event)
1504 {
1505 #if defined(TULIP_DEBUG)
1506     sc->tulip_dbg.dbg_events[event]++;
1507 #endif
1508 #if defined(DIAGNOSTIC)
1509     printf("%s%d: botch(media_poll) at line %d\n",
1510            sc->tulip_name, sc->tulip_unit, __LINE__);
1511 #endif
1512 }
1513
1514 __inline__ static void
1515 tulip_21140_mediainit(
1516     tulip_softc_t * const sc,
1517     tulip_media_info_t * const mip,
1518     tulip_media_t const media,
1519     unsigned gpdata,
1520     unsigned cmdmode)
1521 {
1522     sc->tulip_mediums[media] = mip;
1523     mip->mi_type = TULIP_MEDIAINFO_GPR;
1524     mip->mi_cmdmode = cmdmode;
1525     mip->mi_gpdata = gpdata;
1526 }
1527 \f
1528 static void
1529 tulip_21140_evalboard_media_probe(
1530     tulip_softc_t * const sc)
1531 {
1532     tulip_media_info_t *mip = sc->tulip_mediainfo;
1533
1534     sc->tulip_gpinit = TULIP_GP_EB_PINS;
1535     sc->tulip_gpdata = TULIP_GP_EB_INIT;
1536     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1537     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1538     TULIP_CSR_WRITE(sc, csr_command,
1539         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1540         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1541     TULIP_CSR_WRITE(sc, csr_command,
1542         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1543     DELAY(1000000);
1544     if ((TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_EB_OK100) != 0) {
1545         sc->tulip_media = TULIP_MEDIA_10BASET;
1546     } else {
1547         sc->tulip_media = TULIP_MEDIA_100BASETX;
1548     }
1549     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1550                           TULIP_GP_EB_INIT,
1551                           TULIP_CMD_TXTHRSHLDCTL);
1552     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1553                           TULIP_GP_EB_INIT,
1554                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1555     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1556                           TULIP_GP_EB_INIT,
1557                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1558                               |TULIP_CMD_SCRAMBLER);
1559     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1560                           TULIP_GP_EB_INIT,
1561                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1562                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1563 }
1564
1565 static const tulip_boardsw_t tulip_21140_eb_boardsw = {
1566     TULIP_21140_DEC_EB,
1567     tulip_21140_evalboard_media_probe,
1568     tulip_media_select,
1569     tulip_null_media_poll,
1570     tulip_2114x_media_preset,
1571 };
1572 \f
1573 static void
1574 tulip_21140_accton_media_probe(
1575     tulip_softc_t * const sc)
1576 {
1577     tulip_media_info_t *mip = sc->tulip_mediainfo;
1578     unsigned gpdata;
1579
1580     sc->tulip_gpinit = TULIP_GP_EB_PINS;
1581     sc->tulip_gpdata = TULIP_GP_EB_INIT;
1582     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS);
1583     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT);
1584     TULIP_CSR_WRITE(sc, csr_command,
1585         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1586         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1587     TULIP_CSR_WRITE(sc, csr_command,
1588         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1589     DELAY(1000000);
1590     gpdata = TULIP_CSR_READ(sc, csr_gp);
1591     if ((gpdata & TULIP_GP_EN1207_UTP_INIT) == 0) {
1592         sc->tulip_media = TULIP_MEDIA_10BASET;
1593     } else {
1594         if ((gpdata & TULIP_GP_EN1207_BNC_INIT) == 0) {
1595                 sc->tulip_media = TULIP_MEDIA_BNC;
1596         } else {
1597                 sc->tulip_media = TULIP_MEDIA_100BASETX;
1598         }
1599     }
1600     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_BNC,
1601                           TULIP_GP_EN1207_BNC_INIT,
1602                           TULIP_CMD_TXTHRSHLDCTL);
1603     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1604                           TULIP_GP_EN1207_UTP_INIT,
1605                           TULIP_CMD_TXTHRSHLDCTL);
1606     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1607                           TULIP_GP_EN1207_UTP_INIT,
1608                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1609     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1610                           TULIP_GP_EN1207_100_INIT,
1611                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1612                               |TULIP_CMD_SCRAMBLER);
1613     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1614                           TULIP_GP_EN1207_100_INIT,
1615                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1616                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1617 }
1618
1619 static const tulip_boardsw_t tulip_21140_accton_boardsw = {
1620     TULIP_21140_EN1207,
1621     tulip_21140_accton_media_probe,
1622     tulip_media_select,
1623     tulip_null_media_poll,
1624     tulip_2114x_media_preset,
1625 };
1626 \f
1627 static void
1628 tulip_21140_smc9332_media_probe(
1629     tulip_softc_t * const sc)
1630 {
1631     tulip_media_info_t *mip = sc->tulip_mediainfo;
1632     int idx, cnt = 0;
1633
1634     TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT|TULIP_CMD_MUSTBEONE);
1635     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
1636     DELAY(10);  /* Wait 10 microseconds (actually 50 PCI cycles but at 
1637                    33MHz that comes to two microseconds but wait a
1638                    bit longer anyways) */
1639     TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT |
1640         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1641     sc->tulip_gpinit = TULIP_GP_SMC_9332_PINS;
1642     sc->tulip_gpdata = TULIP_GP_SMC_9332_INIT;
1643     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS|TULIP_GP_PINSET);
1644     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT);
1645     DELAY(200000);
1646     for (idx = 1000; idx > 0; idx--) {
1647         u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
1648         if ((csr & (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) == (TULIP_GP_SMC_9332_OK10|TULIP_GP_SMC_9332_OK100)) {
1649             if (++cnt > 100)
1650                 break;
1651         } else if ((csr & TULIP_GP_SMC_9332_OK10) == 0) {
1652             break;
1653         } else {
1654             cnt = 0;
1655         }
1656         DELAY(1000);
1657     }
1658     sc->tulip_media = cnt > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
1659     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1660                           TULIP_GP_SMC_9332_INIT,
1661                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1662                               |TULIP_CMD_SCRAMBLER);
1663     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1664                           TULIP_GP_SMC_9332_INIT,
1665                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1666                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1667     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1668                           TULIP_GP_SMC_9332_INIT,
1669                           TULIP_CMD_TXTHRSHLDCTL);
1670     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1671                           TULIP_GP_SMC_9332_INIT,
1672                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1673 }
1674  
1675 static const tulip_boardsw_t tulip_21140_smc9332_boardsw = {
1676     TULIP_21140_SMC_9332,
1677     tulip_21140_smc9332_media_probe,
1678     tulip_media_select,
1679     tulip_null_media_poll,
1680     tulip_2114x_media_preset,
1681 };
1682 \f
1683 static void
1684 tulip_21140_cogent_em100_media_probe(
1685     tulip_softc_t * const sc)
1686 {
1687     tulip_media_info_t *mip = sc->tulip_mediainfo;
1688     u_int32_t cmdmode = TULIP_CSR_READ(sc, csr_command);
1689
1690     sc->tulip_gpinit = TULIP_GP_EM100_PINS;
1691     sc->tulip_gpdata = TULIP_GP_EM100_INIT;
1692     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS);
1693     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT);
1694
1695     cmdmode = TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_MUSTBEONE;
1696     cmdmode &= ~(TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_SCRAMBLER);
1697     if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
1698         TULIP_CSR_WRITE(sc, csr_command, cmdmode);
1699         sc->tulip_media = TULIP_MEDIA_100BASEFX;
1700
1701         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX,
1702                           TULIP_GP_EM100_INIT,
1703                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION);
1704         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASEFX_FD,
1705                           TULIP_GP_EM100_INIT,
1706                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1707                               |TULIP_CMD_FULLDUPLEX);
1708     } else {
1709         TULIP_CSR_WRITE(sc, csr_command, cmdmode|TULIP_CMD_SCRAMBLER);
1710         sc->tulip_media = TULIP_MEDIA_100BASETX;
1711         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1712                           TULIP_GP_EM100_INIT,
1713                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1714                               |TULIP_CMD_SCRAMBLER);
1715         tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1716                           TULIP_GP_EM100_INIT,
1717                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1718                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1719     }
1720 }
1721
1722 static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw = {
1723     TULIP_21140_COGENT_EM100,
1724     tulip_21140_cogent_em100_media_probe,
1725     tulip_media_select,
1726     tulip_null_media_poll,
1727     tulip_2114x_media_preset
1728 };
1729 \f
1730 static void
1731 tulip_21140_znyx_zx34x_media_probe(
1732     tulip_softc_t * const sc)
1733 {
1734     tulip_media_info_t *mip = sc->tulip_mediainfo;
1735     int cnt10 = 0, cnt100 = 0, idx;
1736
1737     sc->tulip_gpinit = TULIP_GP_ZX34X_PINS;
1738     sc->tulip_gpdata = TULIP_GP_ZX34X_INIT;
1739     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS);
1740     TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT);
1741     TULIP_CSR_WRITE(sc, csr_command,
1742         TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT |
1743         TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE);
1744     TULIP_CSR_WRITE(sc, csr_command,
1745         TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL);
1746
1747     DELAY(200000);
1748     for (idx = 1000; idx > 0; idx--) {
1749         u_int32_t csr = TULIP_CSR_READ(sc, csr_gp);
1750         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)) {
1751             if (++cnt100 > 100)
1752                 break;
1753         } else if ((csr & TULIP_GP_ZX34X_LNKFAIL) == 0) {
1754             if (++cnt10 > 100)
1755                 break;
1756         } else {
1757             cnt10 = 0;
1758             cnt100 = 0;
1759         }
1760         DELAY(1000);
1761     }
1762     sc->tulip_media = cnt100 > 100 ? TULIP_MEDIA_100BASETX : TULIP_MEDIA_10BASET;
1763     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET,
1764                           TULIP_GP_ZX34X_INIT,
1765                           TULIP_CMD_TXTHRSHLDCTL);
1766     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_10BASET_FD,
1767                           TULIP_GP_ZX34X_INIT,
1768                           TULIP_CMD_TXTHRSHLDCTL|TULIP_CMD_FULLDUPLEX);
1769     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX,
1770                           TULIP_GP_ZX34X_INIT,
1771                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1772                               |TULIP_CMD_SCRAMBLER);
1773     tulip_21140_mediainit(sc, mip++, TULIP_MEDIA_100BASETX_FD,
1774                           TULIP_GP_ZX34X_INIT,
1775                           TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION
1776                               |TULIP_CMD_SCRAMBLER|TULIP_CMD_FULLDUPLEX);
1777 }
1778
1779 static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw = {
1780     TULIP_21140_ZNYX_ZX34X,
1781     tulip_21140_znyx_zx34x_media_probe,
1782     tulip_media_select,
1783     tulip_null_media_poll,
1784     tulip_2114x_media_preset,
1785 };
1786 \f
1787 static void
1788 tulip_2114x_media_probe(
1789     tulip_softc_t * const sc)
1790 {
1791     sc->tulip_cmdmode |= TULIP_CMD_MUSTBEONE
1792         |TULIP_CMD_BACKOFFCTR|TULIP_CMD_THRSHLD72;
1793 }
1794
1795 static const tulip_boardsw_t tulip_2114x_isv_boardsw = {
1796     TULIP_21140_ISV,
1797     tulip_2114x_media_probe,
1798     tulip_media_select,
1799     tulip_media_poll,
1800     tulip_2114x_media_preset,
1801 };
1802 \f
1803 /*
1804  * ******** END of chip-specific handlers. ***********
1805  */
1806 \f
1807 /*
1808  * Code the read the SROM and MII bit streams (I2C)
1809  */
1810 #define EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); DELAY(1); } while (0)
1811
1812 static void
1813 tulip_srom_idle(
1814     tulip_softc_t * const sc)
1815 {
1816     unsigned bit, csr;
1817     
1818     csr  = SROMSEL ; EMIT;
1819     csr  = SROMSEL | SROMRD; EMIT;  
1820     csr ^= SROMCS; EMIT;
1821     csr ^= SROMCLKON; EMIT;
1822
1823     /*
1824      * Write 25 cycles of 0 which will force the SROM to be idle.
1825      */
1826     for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
1827         csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
1828         csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
1829     }
1830     csr ^= SROMCLKOFF; EMIT;
1831     csr ^= SROMCS; EMIT;
1832     csr  = 0; EMIT;
1833 }
1834
1835      
1836 static void
1837 tulip_srom_read(
1838     tulip_softc_t * const sc)
1839 {   
1840     unsigned idx; 
1841     const unsigned bitwidth = SROM_BITWIDTH;
1842     const unsigned cmdmask = (SROMCMD_RD << bitwidth);
1843     const unsigned msb = 1 << (bitwidth + 3 - 1);
1844     unsigned lastidx = (1 << bitwidth) - 1;
1845
1846     tulip_srom_idle(sc);
1847
1848     for (idx = 0; idx <= lastidx; idx++) {
1849         unsigned lastbit, data, bits, bit, csr;
1850         csr  = SROMSEL ;                EMIT;
1851         csr  = SROMSEL | SROMRD;        EMIT;
1852         csr ^= SROMCSON;                EMIT;
1853         csr ^=            SROMCLKON;    EMIT;
1854     
1855         lastbit = 0;
1856         for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1) {
1857             const unsigned thisbit = bits & msb;
1858             csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
1859             if (thisbit != lastbit) {
1860                 csr ^= SROMDOUT; EMIT;  /* clock low; invert data */
1861             } else {
1862                 EMIT;
1863             }
1864             csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
1865             lastbit = thisbit;
1866         }
1867         csr ^= SROMCLKOFF; EMIT;
1868
1869         for (data = 0, bits = 0; bits < 16; bits++) {
1870             data <<= 1;
1871             csr ^= SROMCLKON; EMIT;     /* clock high; data valid */ 
1872             data |= TULIP_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
1873             csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
1874         }
1875         sc->tulip_rombuf[idx*2] = data & 0xFF;
1876         sc->tulip_rombuf[idx*2+1] = data >> 8;
1877         csr  = SROMSEL | SROMRD; EMIT;
1878         csr  = 0; EMIT;
1879     }
1880     tulip_srom_idle(sc);
1881 }
1882 \f
1883 #define MII_EMIT    do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); DELAY(1); } while (0)
1884
1885 static void
1886 tulip_mii_writebits(
1887     tulip_softc_t * const sc,
1888     unsigned data,
1889     unsigned bits)
1890 {
1891     unsigned msb = 1 << (bits - 1);
1892     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1893     unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
1894
1895     csr |= MII_WR; MII_EMIT;            /* clock low; assert write */
1896
1897     for (; bits > 0; bits--, data <<= 1) {
1898         const unsigned thisbit = data & msb;
1899         if (thisbit != lastbit) {
1900             csr ^= MII_DOUT; MII_EMIT;  /* clock low; invert data */
1901         }
1902         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
1903         lastbit = thisbit;
1904         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
1905     }
1906 }
1907
1908 static void
1909 tulip_mii_turnaround(
1910     tulip_softc_t * const sc,
1911     unsigned cmd)
1912 {
1913     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1914
1915     if (cmd == MII_WRCMD) {
1916         csr |= MII_DOUT; MII_EMIT;      /* clock low; change data */
1917         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
1918         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
1919         csr ^= MII_DOUT; MII_EMIT;      /* clock low; change data */
1920     } else {
1921         csr |= MII_RD; MII_EMIT;        /* clock low; switch to read */
1922     }
1923     csr ^= MII_CLKON; MII_EMIT;         /* clock high; data valid */
1924     csr ^= MII_CLKOFF; MII_EMIT;        /* clock low; data not valid */
1925 }
1926
1927 static unsigned
1928 tulip_mii_readbits(
1929     tulip_softc_t * const sc)
1930 {
1931     unsigned data;
1932     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1933     int idx;
1934
1935     for (idx = 0, data = 0; idx < 16; idx++) {
1936         data <<= 1;     /* this is NOOP on the first pass through */
1937         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
1938         if (TULIP_CSR_READ(sc, csr_srom_mii) & MII_DIN)
1939             data |= 1;
1940         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
1941     }
1942     csr ^= MII_RD; MII_EMIT;            /* clock low; turn off read */
1943
1944     return data;
1945 }
1946
1947 static unsigned
1948 tulip_mii_readreg(
1949     tulip_softc_t * const sc,
1950     unsigned devaddr,
1951     unsigned regno)
1952 {
1953     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1954     unsigned data;
1955
1956     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
1957     tulip_mii_writebits(sc, MII_PREAMBLE, 32);
1958     tulip_mii_writebits(sc, MII_RDCMD, 8);
1959     tulip_mii_writebits(sc, devaddr, 5);
1960     tulip_mii_writebits(sc, regno, 5);
1961     tulip_mii_turnaround(sc, MII_RDCMD);
1962
1963     data = tulip_mii_readbits(sc);
1964 #if defined(TULIP_DEBUG)
1965     sc->tulip_dbg.dbg_phyregs[regno][0] = data;
1966     sc->tulip_dbg.dbg_phyregs[regno][1]++;
1967 #endif
1968     return data;
1969 }
1970
1971 static void
1972 tulip_mii_writereg(
1973     tulip_softc_t * const sc,
1974     unsigned devaddr,
1975     unsigned regno,
1976     unsigned data)
1977 {
1978     unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
1979     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
1980     tulip_mii_writebits(sc, MII_PREAMBLE, 32);
1981     tulip_mii_writebits(sc, MII_WRCMD, 8);
1982     tulip_mii_writebits(sc, devaddr, 5);
1983     tulip_mii_writebits(sc, regno, 5);
1984     tulip_mii_turnaround(sc, MII_WRCMD);
1985     tulip_mii_writebits(sc, data, 16);
1986 #if defined(TULIP_DEBUG)
1987     sc->tulip_dbg.dbg_phyregs[regno][2] = data;
1988     sc->tulip_dbg.dbg_phyregs[regno][3]++;
1989 #endif
1990 }
1991 \f
1992 #define tulip_mchash(mca)       (ether_crc32_le(mca, 6) & 0x1FF)
1993 #define tulip_srom_crcok(databuf)       ( \
1994     ((ether_crc32_le(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
1995      ((databuf)[126] | ((databuf)[127] << 8)))
1996 \f
1997 static void
1998 tulip_identify_dec_nic(
1999     tulip_softc_t * const sc)
2000 {
2001     strcpy(sc->tulip_boardid, "DEC ");
2002 #define D0      4
2003     if (sc->tulip_chipid <= TULIP_21040)
2004         return;
2005     if (bcmp(sc->tulip_rombuf + 29, "DE500", 5) == 0
2006         || bcmp(sc->tulip_rombuf + 29, "DE450", 5) == 0) {
2007         bcopy(sc->tulip_rombuf + 29, &sc->tulip_boardid[D0], 8);
2008         sc->tulip_boardid[D0+8] = ' ';
2009     }
2010 #undef D0
2011 }
2012 \f
2013 static void
2014 tulip_identify_znyx_nic(
2015     tulip_softc_t * const sc)
2016 {
2017     unsigned id = 0;
2018     strcpy(sc->tulip_boardid, "ZNYX ZX3XX ");
2019     if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
2020         unsigned znyx_ptr;
2021         sc->tulip_boardid[8] = '4';
2022         znyx_ptr = sc->tulip_rombuf[124] + 256 * sc->tulip_rombuf[125];
2023         if (znyx_ptr < 26 || znyx_ptr > 116) {
2024             sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
2025             return;
2026         }
2027         /* ZX344 = 0010 .. 0013FF
2028          */
2029         if (sc->tulip_rombuf[znyx_ptr] == 0x4A
2030                 && sc->tulip_rombuf[znyx_ptr + 1] == 0x52
2031                 && sc->tulip_rombuf[znyx_ptr + 2] == 0x01) {
2032             id = sc->tulip_rombuf[znyx_ptr + 5] + 256 * sc->tulip_rombuf[znyx_ptr + 4];
2033             if ((id >> 8) == (TULIP_ZNYX_ID_ZX342 >> 8)) {
2034                 sc->tulip_boardid[9] = '2';
2035                 if (id == TULIP_ZNYX_ID_ZX342B) {
2036                     sc->tulip_boardid[10] = 'B';
2037                     sc->tulip_boardid[11] = ' ';
2038                 }
2039                 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
2040             } else if (id == TULIP_ZNYX_ID_ZX344) {
2041                 sc->tulip_boardid[10] = '4';
2042                 sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
2043             } else if (id == TULIP_ZNYX_ID_ZX345) {
2044                 sc->tulip_boardid[9] = (sc->tulip_rombuf[19] > 1) ? '8' : '5';
2045             } else if (id == TULIP_ZNYX_ID_ZX346) {
2046                 sc->tulip_boardid[9] = '6';
2047             } else if (id == TULIP_ZNYX_ID_ZX351) {
2048                 sc->tulip_boardid[8] = '5';
2049                 sc->tulip_boardid[9] = '1';
2050             }
2051         }
2052         if (id == 0) {
2053             /*
2054              * Assume it's a ZX342...
2055              */
2056             sc->tulip_boardsw = &tulip_21140_znyx_zx34x_boardsw;
2057         }
2058         return;
2059     }
2060     sc->tulip_boardid[8] = '1';
2061     if (sc->tulip_chipid == TULIP_21041) {
2062         sc->tulip_boardid[10] = '1';
2063         return;
2064     }
2065     if (sc->tulip_rombuf[32] == 0x4A && sc->tulip_rombuf[33] == 0x52) {
2066         id = sc->tulip_rombuf[37] + 256 * sc->tulip_rombuf[36];
2067         if (id == TULIP_ZNYX_ID_ZX312T) {
2068             sc->tulip_boardid[9] = '2';
2069             sc->tulip_boardid[10] = 'T';
2070             sc->tulip_boardid[11] = ' ';
2071             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2072         } else if (id == TULIP_ZNYX_ID_ZX314_INTA) {
2073             sc->tulip_boardid[9] = '4';
2074             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2075             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2076         } else if (id == TULIP_ZNYX_ID_ZX314) {
2077             sc->tulip_boardid[9] = '4';
2078             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2079             sc->tulip_features |= TULIP_HAVE_BASEROM;
2080         } else if (id == TULIP_ZNYX_ID_ZX315_INTA) {
2081             sc->tulip_boardid[9] = '5';
2082             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2083         } else if (id == TULIP_ZNYX_ID_ZX315) {
2084             sc->tulip_boardid[9] = '5';
2085             sc->tulip_features |= TULIP_HAVE_BASEROM;
2086         } else {
2087             id = 0;
2088         }
2089     }               
2090     if (id == 0) {
2091         if ((sc->tulip_enaddr[3] & ~3) == 0xF0 && (sc->tulip_enaddr[5] & 2) == 0) {
2092             sc->tulip_boardid[9] = '4';
2093             sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2094             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2095         } else if ((sc->tulip_enaddr[3] & ~3) == 0xF4 && (sc->tulip_enaddr[5] & 1) == 0) {
2096             sc->tulip_boardid[9] = '5';
2097             sc->tulip_boardsw = &tulip_21040_boardsw;
2098             sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2099         } else if ((sc->tulip_enaddr[3] & ~3) == 0xEC) {
2100             sc->tulip_boardid[9] = '2';
2101             sc->tulip_boardsw = &tulip_21040_boardsw;
2102         }
2103     }
2104 }
2105 \f
2106 static void
2107 tulip_identify_smc_nic(
2108     tulip_softc_t * const sc)
2109 {
2110     u_int32_t id1, id2, ei;
2111     int auibnc = 0, utp = 0;
2112     char *cp;
2113
2114     strcpy(sc->tulip_boardid, "SMC ");
2115     if (sc->tulip_chipid == TULIP_21041)
2116         return;
2117     if (sc->tulip_chipid != TULIP_21040) {
2118         if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
2119             strcpy(&sc->tulip_boardid[4], "9332DST ");
2120             sc->tulip_boardsw = &tulip_21140_smc9332_boardsw;
2121         } else if (sc->tulip_features & (TULIP_HAVE_BASEROM|TULIP_HAVE_SLAVEDROM)) {
2122             strcpy(&sc->tulip_boardid[4], "9334BDT ");
2123         } else {
2124             strcpy(&sc->tulip_boardid[4], "9332BDT ");
2125         }
2126         return;
2127     }
2128     id1 = sc->tulip_rombuf[0x60] | (sc->tulip_rombuf[0x61] << 8);
2129     id2 = sc->tulip_rombuf[0x62] | (sc->tulip_rombuf[0x63] << 8);
2130     ei  = sc->tulip_rombuf[0x66] | (sc->tulip_rombuf[0x67] << 8);
2131
2132     strcpy(&sc->tulip_boardid[4], "8432");
2133     cp = &sc->tulip_boardid[8];
2134     if ((id1 & 1) == 0)
2135         *cp++ = 'B', auibnc = 1;
2136     if ((id1 & 0xFF) > 0x32)
2137         *cp++ = 'T', utp = 1;
2138     if ((id1 & 0x4000) == 0)
2139         *cp++ = 'A', auibnc = 1;
2140     if (id2 == 0x15) {
2141         sc->tulip_boardid[7] = '4';
2142         *cp++ = '-';
2143         *cp++ = 'C';
2144         *cp++ = 'H';
2145         *cp++ = (ei ? '2' : '1');
2146     }
2147     *cp++ = ' ';
2148     *cp = '\0';
2149     if (utp && !auibnc)
2150         sc->tulip_boardsw = &tulip_21040_10baset_only_boardsw;
2151     else if (!utp && auibnc)
2152         sc->tulip_boardsw = &tulip_21040_auibnc_only_boardsw;
2153 }
2154 \f
2155 static void
2156 tulip_identify_cogent_nic(
2157     tulip_softc_t * const sc)
2158 {
2159     strcpy(sc->tulip_boardid, "Cogent ");
2160     if (sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A) {
2161         if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100TX_ID) {
2162             strcat(sc->tulip_boardid, "EM100TX ");
2163             sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2164 #if defined(TULIP_COGENT_EM110TX_ID)
2165         } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM110TX_ID) {
2166             strcat(sc->tulip_boardid, "EM110TX ");
2167             sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2168 #endif
2169         } else if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100FX_ID) {
2170             strcat(sc->tulip_boardid, "EM100FX ");
2171             sc->tulip_boardsw = &tulip_21140_cogent_em100_boardsw;
2172         }
2173         /*
2174          * Magic number (0x24001109U) is the SubVendor (0x2400) and
2175          * SubDevId (0x1109) for the ANA6944TX (EM440TX).
2176          */
2177         if (*(u_int32_t *) sc->tulip_rombuf == 0x24001109U
2178                 && (sc->tulip_features & TULIP_HAVE_BASEROM)) {
2179             /*
2180              * Cogent (Adaptec) is still mapping all INTs to INTA of
2181              * first 21140.  Dumb!  Dumb!
2182              */
2183             strcat(sc->tulip_boardid, "EM440TX ");
2184             sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
2185         }
2186     } else if (sc->tulip_chipid == TULIP_21040) {
2187         sc->tulip_features |= TULIP_HAVE_SHAREDINTR|TULIP_HAVE_BASEROM;
2188     }
2189 }
2190 \f
2191 static void
2192 tulip_identify_accton_nic(
2193     tulip_softc_t * const sc)
2194 {
2195     strcpy(sc->tulip_boardid, "ACCTON ");
2196     switch (sc->tulip_chipid) {
2197         case TULIP_21140A:
2198             strcat(sc->tulip_boardid, "EN1207 ");
2199             if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw)
2200                 sc->tulip_boardsw = &tulip_21140_accton_boardsw;
2201             break;
2202         case TULIP_21140:
2203             strcat(sc->tulip_boardid, "EN1207TX ");
2204             if (sc->tulip_boardsw != &tulip_2114x_isv_boardsw)
2205                 sc->tulip_boardsw = &tulip_21140_eb_boardsw;
2206             break;
2207         case TULIP_21040:
2208             strcat(sc->tulip_boardid, "EN1203 ");
2209             sc->tulip_boardsw = &tulip_21040_boardsw;
2210             break;
2211         case TULIP_21041:
2212             strcat(sc->tulip_boardid, "EN1203 ");
2213             sc->tulip_boardsw = &tulip_21041_boardsw;
2214             break;
2215         default:
2216             sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2217             break;
2218     }
2219 }
2220 \f
2221 static void
2222 tulip_identify_asante_nic(
2223     tulip_softc_t * const sc)
2224 {
2225     strcpy(sc->tulip_boardid, "Asante ");
2226     if ((sc->tulip_chipid == TULIP_21140 || sc->tulip_chipid == TULIP_21140A)
2227             && sc->tulip_boardsw != &tulip_2114x_isv_boardsw) {
2228         tulip_media_info_t *mi = sc->tulip_mediainfo;
2229         int idx;
2230         /*
2231          * The Asante Fast Ethernet doesn't always ship with a valid
2232          * new format SROM.  So if isn't in the new format, we cheat
2233          * set it up as if we had.
2234          */
2235
2236         sc->tulip_gpinit = TULIP_GP_ASANTE_PINS;
2237         sc->tulip_gpdata = 0;
2238
2239         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PINS|TULIP_GP_PINSET);
2240         TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ASANTE_PHYRESET);
2241         DELAY(100);
2242         TULIP_CSR_WRITE(sc, csr_gp, 0);
2243
2244         mi->mi_type = TULIP_MEDIAINFO_MII;
2245         mi->mi_gpr_length = 0;
2246         mi->mi_gpr_offset = 0;
2247         mi->mi_reset_length = 0;
2248         mi->mi_reset_offset = 0;;
2249
2250         mi->mi_phyaddr = TULIP_MII_NOPHY;
2251         for (idx = 20; idx > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx--) {
2252             DELAY(10000);
2253             mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, 0);
2254         }
2255         if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2256             printf("%s%d: can't find phy 0\n", sc->tulip_name, sc->tulip_unit);
2257             return;
2258         }
2259
2260         sc->tulip_features |= TULIP_HAVE_MII;
2261         mi->mi_capabilities  = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
2262         mi->mi_advertisement = PHYSTS_10BASET|PHYSTS_10BASET_FD|PHYSTS_100BASETX|PHYSTS_100BASETX_FD;
2263         mi->mi_full_duplex   = PHYSTS_10BASET_FD|PHYSTS_100BASETX_FD;
2264         mi->mi_tx_threshold  = PHYSTS_10BASET|PHYSTS_10BASET_FD;
2265         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2266         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2267         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2268         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2269         TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2270         mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2271             tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2272
2273         sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2274     }
2275 }
2276 \f
2277 static void
2278 tulip_identify_compex_nic(
2279     tulip_softc_t * const sc)
2280 {
2281     strcpy(sc->tulip_boardid, "COMPEX ");
2282     if (sc->tulip_chipid == TULIP_21140A) {
2283         int root_unit;
2284         tulip_softc_t *root_sc = NULL;
2285
2286         strcat(sc->tulip_boardid, "400TX/PCI ");
2287         /*
2288          * All 4 chips on these boards share an interrupt.  This code
2289          * copied from tulip_read_macaddr.
2290          */
2291         sc->tulip_features |= TULIP_HAVE_SHAREDINTR;
2292         for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
2293             root_sc = tulips[root_unit];
2294             if (root_sc == NULL
2295                 || !(root_sc->tulip_features & TULIP_HAVE_SLAVEDINTR))
2296                 break;
2297             root_sc = NULL;
2298         }
2299         if (root_sc != NULL
2300             && root_sc->tulip_chipid == sc->tulip_chipid
2301             && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
2302             sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
2303             sc->tulip_slaves = root_sc->tulip_slaves;
2304             root_sc->tulip_slaves = sc;
2305         } else if(sc->tulip_features & TULIP_HAVE_SLAVEDINTR) {
2306             printf("\nCannot find master device for de%d interrupts",
2307                    sc->tulip_unit);
2308         }
2309     } else {
2310         strcat(sc->tulip_boardid, "unknown ");
2311     }
2312     /*      sc->tulip_boardsw = &tulip_21140_eb_boardsw; */
2313     return;
2314 }
2315 \f
2316 static int
2317 tulip_srom_decode(
2318     tulip_softc_t * const sc)
2319 {
2320     unsigned idx1, idx2, idx3;
2321
2322     const tulip_srom_header_t *shp = (const tulip_srom_header_t *) &sc->tulip_rombuf[0];
2323     const tulip_srom_adapter_info_t *saip = (const tulip_srom_adapter_info_t *) (shp + 1);
2324     tulip_srom_media_t srom_media;
2325     tulip_media_info_t *mi = sc->tulip_mediainfo;
2326     const u_int8_t *dp;
2327     u_int32_t leaf_offset, blocks, data;
2328
2329     for (idx1 = 0; idx1 < shp->sh_adapter_count; idx1++, saip++) {
2330         if (shp->sh_adapter_count == 1)
2331             break;
2332         if (saip->sai_device == sc->tulip_pci_devno)
2333             break;
2334     }
2335     /*
2336      * Didn't find the right media block for this card.
2337      */
2338     if (idx1 == shp->sh_adapter_count)
2339         return 0;
2340
2341     /*
2342      * Save the hardware address.
2343      */
2344     bcopy(shp->sh_ieee802_address, sc->tulip_enaddr, 6);
2345     /*
2346      * If this is a multiple port card, add the adapter index to the last
2347      * byte of the hardware address.  (if it isn't multiport, adding 0
2348      * won't hurt.
2349      */
2350     sc->tulip_enaddr[5] += idx1;
2351
2352     leaf_offset = saip->sai_leaf_offset_lowbyte
2353         + saip->sai_leaf_offset_highbyte * 256;
2354     dp = sc->tulip_rombuf + leaf_offset;
2355         
2356     sc->tulip_conntype = (tulip_srom_connection_t) (dp[0] + dp[1] * 256); dp += 2;
2357
2358     for (idx2 = 0;; idx2++) {
2359         if (tulip_srom_conninfo[idx2].sc_type == sc->tulip_conntype
2360                 || tulip_srom_conninfo[idx2].sc_type == TULIP_SROM_CONNTYPE_NOT_USED)
2361             break;
2362     }
2363     sc->tulip_connidx = idx2;
2364
2365     if (sc->tulip_chipid == TULIP_21041) {
2366         blocks = *dp++;
2367         for (idx2 = 0; idx2 < blocks; idx2++) {
2368             tulip_media_t media;
2369             data = *dp++;
2370             srom_media = (tulip_srom_media_t) (data & 0x3F);
2371             for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2372                 if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2373                     break;
2374             }
2375             media = tulip_srom_mediums[idx3].sm_type;
2376             if (media != TULIP_MEDIA_UNKNOWN) {
2377                 if (data & TULIP_SROM_21041_EXTENDED) {
2378                     mi->mi_type = TULIP_MEDIAINFO_SIA;
2379                     sc->tulip_mediums[media] = mi;
2380                     mi->mi_sia_connectivity = dp[0] + dp[1] * 256;
2381                     mi->mi_sia_tx_rx        = dp[2] + dp[3] * 256;
2382                     mi->mi_sia_general      = dp[4] + dp[5] * 256;
2383                     mi++;
2384                 } else {
2385                     switch (media) {
2386                         case TULIP_MEDIA_BNC: {
2387                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, BNC);
2388                             mi++;
2389                             break;
2390                         }
2391                         case TULIP_MEDIA_AUI: {
2392                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, AUI);
2393                             mi++;
2394                             break;
2395                         }
2396                         case TULIP_MEDIA_10BASET: {
2397                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET);
2398                             mi++;
2399                             break;
2400                         }
2401                         case TULIP_MEDIA_10BASET_FD: {
2402                             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET_FD);
2403                             mi++;
2404                             break;
2405                         }
2406                         default: {
2407                             break;
2408                         }
2409                     }
2410                 }
2411             }
2412             if (data & TULIP_SROM_21041_EXTENDED)       
2413                 dp += 6;
2414         }
2415 #ifdef notdef
2416         if (blocks == 0) {
2417             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, BNC); mi++;
2418             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, AUI); mi++;
2419             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET); mi++;
2420             TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21041, 10BASET_FD); mi++;
2421         }
2422 #endif
2423     } else {
2424         unsigned length, type;
2425         tulip_media_t gp_media = TULIP_MEDIA_UNKNOWN;
2426         if (sc->tulip_features & TULIP_HAVE_GPR)
2427             sc->tulip_gpinit = *dp++;
2428         blocks = *dp++;
2429         for (idx2 = 0; idx2 < blocks; idx2++) {
2430             const u_int8_t *ep;
2431             if ((*dp & 0x80) == 0) {
2432                 length = 4;
2433                 type = 0;
2434             } else {
2435                 length = (*dp++ & 0x7f) - 1;
2436                 type = *dp++ & 0x3f;
2437             }
2438             ep = dp + length;
2439             switch (type & 0x3f) {
2440                 case 0: {       /* 21140[A] GPR block */
2441                     tulip_media_t media;
2442                     srom_media = (tulip_srom_media_t)(dp[0] & 0x3f);
2443                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2444                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2445                             break;
2446                     }
2447                     media = tulip_srom_mediums[idx3].sm_type;
2448                     if (media == TULIP_MEDIA_UNKNOWN)
2449                         break;
2450                     mi->mi_type = TULIP_MEDIAINFO_GPR;
2451                     sc->tulip_mediums[media] = mi;
2452                     mi->mi_gpdata = dp[1];
2453                     if (media > gp_media && !TULIP_IS_MEDIA_FD(media)) {
2454                         sc->tulip_gpdata = mi->mi_gpdata;
2455                         gp_media = media;
2456                     }
2457                     data = dp[2] + dp[3] * 256;
2458                     mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
2459                     if (data & TULIP_SROM_2114X_NOINDICATOR) {
2460                         mi->mi_actmask = 0;
2461                     } else {
2462 #if 0
2463                         mi->mi_default = (data & TULIP_SROM_2114X_DEFAULT) != 0;
2464 #endif
2465                         mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
2466                         mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
2467                     }
2468                     mi++;
2469                     break;
2470                 }
2471                 case 1: {       /* 21140[A] MII block */
2472                     const unsigned phyno = *dp++;
2473                     mi->mi_type = TULIP_MEDIAINFO_MII;
2474                     mi->mi_gpr_length = *dp++;
2475                     mi->mi_gpr_offset = dp - sc->tulip_rombuf;
2476                     dp += mi->mi_gpr_length;
2477                     mi->mi_reset_length = *dp++;
2478                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
2479                     dp += mi->mi_reset_length;
2480
2481                     /*
2482                      * Before we probe for a PHY, use the GPR information
2483                      * to select it.  If we don't, it may be inaccessible.
2484                      */
2485                     TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_gpinit|TULIP_GP_PINSET);
2486                     for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++) {
2487                         DELAY(10);
2488                         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_reset_offset + idx3]);
2489                     }
2490                     sc->tulip_phyaddr = mi->mi_phyaddr;
2491                     for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++) {
2492                         DELAY(10);
2493                         TULIP_CSR_WRITE(sc, csr_gp, sc->tulip_rombuf[mi->mi_gpr_offset + idx3]);
2494                     }
2495
2496                     /*
2497                      * At least write something!
2498                      */
2499                     if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
2500                         TULIP_CSR_WRITE(sc, csr_gp, 0);
2501
2502                     mi->mi_phyaddr = TULIP_MII_NOPHY;
2503                     for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
2504                         DELAY(10000);
2505                         mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
2506                     }
2507                     if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2508 #if defined(TULIP_DEBUG)
2509                         printf("%s%d: can't find phy %d\n",
2510                                sc->tulip_name, sc->tulip_unit, phyno);
2511 #endif
2512                         break;
2513                     }
2514                     sc->tulip_features |= TULIP_HAVE_MII;
2515                     mi->mi_capabilities  = dp[0] + dp[1] * 256; dp += 2;
2516                     mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
2517                     mi->mi_full_duplex   = dp[0] + dp[1] * 256; dp += 2;
2518                     mi->mi_tx_threshold  = dp[0] + dp[1] * 256; dp += 2;
2519                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2520                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2521                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2522                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2523                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2524                     mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2525                         tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2526                     mi++;
2527                     break;
2528                 }
2529                 case 2: {       /* 2114[23] SIA block */
2530                     tulip_media_t media;
2531                     srom_media = (tulip_srom_media_t)(dp[0] & 0x3f);
2532                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2533                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2534                             break;
2535                     }
2536                     media = tulip_srom_mediums[idx3].sm_type;
2537                     if (media == TULIP_MEDIA_UNKNOWN)
2538                         break;
2539                     mi->mi_type = TULIP_MEDIAINFO_SIA;
2540                     sc->tulip_mediums[media] = mi;
2541                     if (dp[0] & 0x40) {
2542                         mi->mi_sia_connectivity = dp[1] + dp[2] * 256;
2543                         mi->mi_sia_tx_rx        = dp[3] + dp[4] * 256;
2544                         mi->mi_sia_general      = dp[5] + dp[6] * 256;
2545                         dp += 6;
2546                     } else {
2547                         switch (media) {
2548                             case TULIP_MEDIA_BNC: {
2549                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, BNC);
2550                                 break;
2551                             }
2552                             case TULIP_MEDIA_AUI: {
2553                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, AUI);
2554                                 break;
2555                             }
2556                             case TULIP_MEDIA_10BASET: {
2557                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET);
2558                                 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2559                                 break;
2560                             }
2561                             case TULIP_MEDIA_10BASET_FD: {
2562                                 TULIP_MEDIAINFO_SIA_INIT(sc, mi, 21142, 10BASET_FD);
2563                                 sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2564                                 break;
2565                             }
2566                             default: {
2567                                 goto bad_media;
2568                             }
2569                         }
2570                     }
2571                     mi->mi_sia_gp_control = (dp[1] + dp[2] * 256) << 16;
2572                     mi->mi_sia_gp_data    = (dp[3] + dp[4] * 256) << 16;
2573                     mi++;
2574                   bad_media:
2575                     break;
2576                 }
2577                 case 3: {       /* 2114[23] MII PHY block */
2578                     const unsigned phyno = *dp++;
2579                     const u_int8_t *dp0;
2580                     mi->mi_type = TULIP_MEDIAINFO_MII;
2581                     mi->mi_gpr_length = *dp++;
2582                     mi->mi_gpr_offset = dp - sc->tulip_rombuf;
2583                     dp += 2 * mi->mi_gpr_length;
2584                     mi->mi_reset_length = *dp++;
2585                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
2586                     dp += 2 * mi->mi_reset_length;
2587
2588                     dp0 = &sc->tulip_rombuf[mi->mi_reset_offset];
2589                     for (idx3 = 0; idx3 < mi->mi_reset_length; idx3++, dp0 += 2) {
2590                         DELAY(10);
2591                         TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
2592                     }
2593                     sc->tulip_phyaddr = mi->mi_phyaddr;
2594                     dp0 = &sc->tulip_rombuf[mi->mi_gpr_offset];
2595                     for (idx3 = 0; idx3 < mi->mi_gpr_length; idx3++, dp0 += 2) {
2596                         DELAY(10);
2597                         TULIP_CSR_WRITE(sc, csr_sia_general, (dp0[0] + 256 * dp0[1]) << 16);
2598                     }
2599
2600                     if (mi->mi_reset_length == 0 && mi->mi_gpr_length == 0)
2601                         TULIP_CSR_WRITE(sc, csr_sia_general, 0);
2602
2603                     mi->mi_phyaddr = TULIP_MII_NOPHY;
2604                     for (idx3 = 20; idx3 > 0 && mi->mi_phyaddr == TULIP_MII_NOPHY; idx3--) {
2605                         DELAY(10000);
2606                         mi->mi_phyaddr = tulip_mii_get_phyaddr(sc, phyno);
2607                     }
2608                     if (mi->mi_phyaddr == TULIP_MII_NOPHY) {
2609 #if defined(TULIP_DEBUG)
2610                         printf("%s%d: can't find phy %d\n",
2611                                sc->tulip_name, sc->tulip_unit, phyno);
2612 #endif
2613                         break;
2614                     }
2615                     sc->tulip_features |= TULIP_HAVE_MII;
2616                     mi->mi_capabilities  = dp[0] + dp[1] * 256; dp += 2;
2617                     mi->mi_advertisement = dp[0] + dp[1] * 256; dp += 2;
2618                     mi->mi_full_duplex   = dp[0] + dp[1] * 256; dp += 2;
2619                     mi->mi_tx_threshold  = dp[0] + dp[1] * 256; dp += 2;
2620                     mi->mi_mii_interrupt = dp[0] + dp[1] * 256; dp += 2;
2621                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX_FD);
2622                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASETX);
2623                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 100BASET4);
2624                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET_FD);
2625                     TULIP_MEDIAINFO_ADD_CAPABILITY(sc, mi, 10BASET);
2626                     mi->mi_phyid = (tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDLOW) << 16) |
2627                         tulip_mii_readreg(sc, mi->mi_phyaddr, PHYREG_IDHIGH);
2628                     mi++;
2629                     break;
2630                 }
2631                 case 4: {       /* 21143 SYM block */
2632                     tulip_media_t media;
2633                     srom_media = (tulip_srom_media_t) dp[0];
2634                     for (idx3 = 0; tulip_srom_mediums[idx3].sm_type != TULIP_MEDIA_UNKNOWN; idx3++) {
2635                         if (tulip_srom_mediums[idx3].sm_srom_type == srom_media)
2636                             break;
2637                     }
2638                     media = tulip_srom_mediums[idx3].sm_type;
2639                     if (media == TULIP_MEDIA_UNKNOWN)
2640                         break;
2641                     mi->mi_type = TULIP_MEDIAINFO_SYM;
2642                     sc->tulip_mediums[media] = mi;
2643                     mi->mi_gpcontrol = (dp[1] + dp[2] * 256) << 16;
2644                     mi->mi_gpdata    = (dp[3] + dp[4] * 256) << 16;
2645                     data = dp[5] + dp[6] * 256;
2646                     mi->mi_cmdmode = TULIP_SROM_2114X_CMDBITS(data);
2647                     if (data & TULIP_SROM_2114X_NOINDICATOR) {
2648                         mi->mi_actmask = 0;
2649                     } else {
2650                         mi->mi_default = (data & TULIP_SROM_2114X_DEFAULT) != 0;
2651                         mi->mi_actmask = TULIP_SROM_2114X_BITPOS(data);
2652                         mi->mi_actdata = (data & TULIP_SROM_2114X_POLARITY) ? 0 : mi->mi_actmask;
2653                     }
2654                     if (TULIP_IS_MEDIA_TP(media))
2655                         sc->tulip_intrmask |= TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL;
2656                     mi++;
2657                     break;
2658                 }
2659 #if 0
2660                 case 5: {       /* 21143 Reset block */
2661                     mi->mi_type = TULIP_MEDIAINFO_RESET;
2662                     mi->mi_reset_length = *dp++;
2663                     mi->mi_reset_offset = dp - sc->tulip_rombuf;
2664                     dp += 2 * mi->mi_reset_length;
2665                     mi++;
2666                     break;
2667                 }
2668 #endif
2669                 default: {
2670                 }
2671             }
2672             dp = ep;
2673         }
2674     }
2675     return mi - sc->tulip_mediainfo;
2676 }
2677 \f
2678 static const struct {
2679     void (*vendor_identify_nic)(tulip_softc_t * const sc);
2680     unsigned char vendor_oui[3];
2681 } tulip_vendors[] = {
2682     { tulip_identify_dec_nic,           { 0x08, 0x00, 0x2B } },
2683     { tulip_identify_dec_nic,           { 0x00, 0x00, 0xF8 } },
2684     { tulip_identify_smc_nic,           { 0x00, 0x00, 0xC0 } },
2685     { tulip_identify_smc_nic,           { 0x00, 0xE0, 0x29 } },
2686     { tulip_identify_znyx_nic,          { 0x00, 0xC0, 0x95 } },
2687     { tulip_identify_cogent_nic,        { 0x00, 0x00, 0x92 } },
2688     { tulip_identify_asante_nic,        { 0x00, 0x00, 0x94 } },
2689     { tulip_identify_cogent_nic,        { 0x00, 0x00, 0xD1 } },
2690     { tulip_identify_accton_nic,        { 0x00, 0x00, 0xE8 } },
2691     { tulip_identify_compex_nic,        { 0x00, 0x80, 0x48 } },
2692     { NULL }
2693 };
2694
2695 /*
2696  * This deals with the vagaries of the address roms and the
2697  * brain-deadness that various vendors commit in using them.
2698  */
2699 static int
2700 tulip_read_macaddr(
2701     tulip_softc_t * const sc)
2702 {
2703     unsigned cksum, rom_cksum, idx;
2704     u_int32_t csr;
2705     unsigned char tmpbuf[8];
2706     static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
2707
2708     sc->tulip_connidx = TULIP_SROM_LASTCONNIDX;
2709
2710     if (sc->tulip_chipid == TULIP_21040) {
2711         TULIP_CSR_WRITE(sc, csr_enetrom, 1);
2712         for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
2713             int cnt = 0;
2714             while (((csr = TULIP_CSR_READ(sc, csr_enetrom)) & 0x80000000L) && cnt < 10000)
2715                 cnt++;
2716             sc->tulip_rombuf[idx] = csr & 0xFF;
2717         }
2718         sc->tulip_boardsw = &tulip_21040_boardsw;
2719     } else {
2720         if (sc->tulip_chipid == TULIP_21041) {
2721             /*
2722              * Thankfully all 21041's act the same.
2723              */
2724             sc->tulip_boardsw = &tulip_21041_boardsw;
2725         } else {
2726             /*
2727              * Assume all 21140 board are compatible with the
2728              * DEC 10/100 evaluation board.  Not really valid but
2729              * it's the best we can do until every one switches to
2730              * the new SROM format.
2731              */
2732
2733             sc->tulip_boardsw = &tulip_21140_eb_boardsw;
2734         }
2735         tulip_srom_read(sc);
2736         if (tulip_srom_crcok(sc->tulip_rombuf)) {
2737             /*
2738              * SROM CRC is valid therefore it must be in the
2739              * new format.
2740              */
2741             sc->tulip_features |= TULIP_HAVE_ISVSROM|TULIP_HAVE_OKSROM;
2742         } else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) {
2743             /*
2744              * No checksum is present.  See if the SROM id checks out;
2745              * the first 18 bytes should be 0 followed by a 1 followed
2746              * by the number of adapters (which we don't deal with yet).
2747              */
2748             for (idx = 0; idx < 18; idx++) {
2749                 if (sc->tulip_rombuf[idx] != 0)
2750                     break;
2751             }
2752             if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0)
2753                 sc->tulip_features |= TULIP_HAVE_ISVSROM;
2754         } else if (sc->tulip_chipid >= TULIP_21142) {
2755             sc->tulip_features |= TULIP_HAVE_ISVSROM;
2756             sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2757         }
2758         if ((sc->tulip_features & TULIP_HAVE_ISVSROM) && tulip_srom_decode(sc)) {
2759             if (sc->tulip_chipid != TULIP_21041)
2760                 sc->tulip_boardsw = &tulip_2114x_isv_boardsw;
2761
2762             /*
2763              * If the SROM specifies more than one adapter, tag this as a
2764              * BASE rom.
2765              */
2766             if (sc->tulip_rombuf[19] > 1)
2767                 sc->tulip_features |= TULIP_HAVE_BASEROM;
2768             if (sc->tulip_boardsw == NULL)
2769                 return -6;
2770             goto check_oui;
2771         }
2772     }
2773
2774
2775     if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) {
2776         /*
2777          * Some folks don't use the standard ethernet rom format
2778          * but instead just put the address in the first 6 bytes
2779          * of the rom and let the rest be all 0xffs.  (Can we say
2780          * ZNYX?) (well sometimes they put in a checksum so we'll
2781          * start at 8).
2782          */
2783         for (idx = 8; idx < 32; idx++) {
2784             if (sc->tulip_rombuf[idx] != 0xFF)
2785                 return -4;
2786         }
2787         /*
2788          * Make sure the address is not multicast or locally assigned
2789          * that the OUI is not 00-00-00.
2790          */
2791         if ((sc->tulip_rombuf[0] & 3) != 0)
2792             return -4;
2793         if (sc->tulip_rombuf[0] == 0 && sc->tulip_rombuf[1] == 0
2794                 && sc->tulip_rombuf[2] == 0)
2795             return -4;
2796         bcopy(sc->tulip_rombuf, sc->tulip_enaddr, 6);
2797         sc->tulip_features |= TULIP_HAVE_OKROM;
2798         goto check_oui;
2799     } else {
2800         /*
2801          * A number of makers of multiport boards (ZNYX and Cogent)
2802          * only put on one address ROM on their 21040 boards.  So
2803          * if the ROM is all zeros (or all 0xFFs), look at the
2804          * previous configured boards (as long as they are on the same
2805          * PCI bus and the bus number is non-zero) until we find the
2806          * master board with address ROM.  We then use its address ROM
2807          * as the base for this board.  (we add our relative board
2808          * to the last byte of its address).
2809          */
2810         for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) {
2811             if (sc->tulip_rombuf[idx] != 0 && sc->tulip_rombuf[idx] != 0xFF)
2812                 break;
2813         }
2814         if (idx == sizeof(sc->tulip_rombuf)) {
2815             int root_unit;
2816             tulip_softc_t *root_sc = NULL;
2817             for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) {
2818                 root_sc = tulips[root_unit];
2819                 if (root_sc == NULL || (root_sc->tulip_features & (TULIP_HAVE_OKROM|TULIP_HAVE_SLAVEDROM)) == TULIP_HAVE_OKROM)
2820                     break;
2821                 root_sc = NULL;
2822             }
2823             if (root_sc != NULL && (root_sc->tulip_features & TULIP_HAVE_BASEROM)
2824                     && root_sc->tulip_chipid == sc->tulip_chipid
2825                     && root_sc->tulip_pci_busno == sc->tulip_pci_busno) {
2826                 sc->tulip_features |= TULIP_HAVE_SLAVEDROM;
2827                 sc->tulip_boardsw = root_sc->tulip_boardsw;
2828                 strcpy(sc->tulip_boardid, root_sc->tulip_boardid);
2829                 if (sc->tulip_boardsw->bd_type == TULIP_21140_ISV) {
2830                     bcopy(root_sc->tulip_rombuf, sc->tulip_rombuf,
2831                           sizeof(sc->tulip_rombuf));
2832                     if (!tulip_srom_decode(sc))
2833                         return -5;
2834                 } else {
2835                     bcopy(root_sc->tulip_enaddr, sc->tulip_enaddr, 6);
2836                     sc->tulip_enaddr[5] += sc->tulip_unit - root_sc->tulip_unit;
2837                 }
2838                 /*
2839                  * Now for a truly disgusting kludge: all 4 21040s on
2840                  * the ZX314 share the same INTA line so the mapping
2841                  * setup by the BIOS on the PCI bridge is worthless.
2842                  * Rather than reprogramming the value in the config
2843                  * register, we will handle this internally.
2844                  */
2845                 if (root_sc->tulip_features & TULIP_HAVE_SHAREDINTR) {
2846                     sc->tulip_slaves = root_sc->tulip_slaves;
2847                     root_sc->tulip_slaves = sc;
2848                     sc->tulip_features |= TULIP_HAVE_SLAVEDINTR;
2849                 }
2850                 return 0;
2851             }
2852         }
2853     }
2854
2855     /*
2856      * This is the standard DEC address ROM test.
2857      */
2858
2859     if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0)
2860         return -3;
2861
2862     tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14];
2863     tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12];
2864     tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10];
2865     tmpbuf[6] = sc->tulip_rombuf[9];  tmpbuf[7] = sc->tulip_rombuf[8];
2866     if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0)
2867         return -2;
2868
2869     bcopy(sc->tulip_rombuf, sc->tulip_enaddr, 6);
2870
2871     cksum = *(u_int16_t *) &sc->tulip_enaddr[0];
2872     cksum *= 2;
2873     if (cksum > 65535) cksum -= 65535;
2874     cksum += *(u_int16_t *) &sc->tulip_enaddr[2];
2875     if (cksum > 65535) cksum -= 65535;
2876     cksum *= 2;
2877     if (cksum > 65535) cksum -= 65535;
2878     cksum += *(u_int16_t *) &sc->tulip_enaddr[4];
2879     if (cksum >= 65535) cksum -= 65535;
2880
2881     rom_cksum = *(u_int16_t *) &sc->tulip_rombuf[6];
2882         
2883     if (cksum != rom_cksum)
2884         return -1;
2885
2886   check_oui:
2887     /*
2888      * Check for various boards based on OUI.  Did I say braindead?
2889      */
2890     for (idx = 0; tulip_vendors[idx].vendor_identify_nic != NULL; idx++) {
2891         if (bcmp(sc->tulip_enaddr, tulip_vendors[idx].vendor_oui, 3) == 0) {
2892             (*tulip_vendors[idx].vendor_identify_nic)(sc);
2893             break;
2894         }
2895     }
2896
2897     sc->tulip_features |= TULIP_HAVE_OKROM;
2898     return 0;
2899 }
2900 \f
2901 static void
2902 tulip_ifmedia_add(
2903     tulip_softc_t * const sc)
2904 {
2905     tulip_media_t media;
2906     int medias = 0;
2907
2908     for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
2909         if (sc->tulip_mediums[media] != NULL) {
2910             ifmedia_add(&sc->tulip_ifmedia, tulip_media_to_ifmedia[media],
2911                         0, 0);
2912             medias++;
2913         }
2914     }
2915     if (medias == 0) {
2916         sc->tulip_features |= TULIP_HAVE_NOMEDIA;
2917         ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE, 0, 0);
2918         ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_NONE);
2919     } else if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) {
2920         ifmedia_add(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO, 0, 0);
2921         ifmedia_set(&sc->tulip_ifmedia, IFM_ETHER | IFM_AUTO);
2922     } else {
2923         ifmedia_set(&sc->tulip_ifmedia, tulip_media_to_ifmedia[sc->tulip_media]);
2924         sc->tulip_flags |= TULIP_PRINTMEDIA;
2925         tulip_linkup(sc, sc->tulip_media);
2926     }
2927 }
2928
2929 static int
2930 tulip_ifmedia_change(
2931     struct ifnet * const ifp)
2932 {
2933     tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc;
2934
2935     sc->tulip_flags |= TULIP_NEEDRESET;
2936     sc->tulip_probe_state = TULIP_PROBE_INACTIVE;
2937     sc->tulip_media = TULIP_MEDIA_UNKNOWN;
2938     if (IFM_SUBTYPE(sc->tulip_ifmedia.ifm_media) != IFM_AUTO) {
2939         tulip_media_t media;
2940         for (media = TULIP_MEDIA_UNKNOWN; media < TULIP_MEDIA_MAX; media++) {
2941             if (sc->tulip_mediums[media] != NULL
2942                 && sc->tulip_ifmedia.ifm_media == tulip_media_to_ifmedia[media]) {
2943                 sc->tulip_flags |= TULIP_PRINTMEDIA;
2944                 sc->tulip_flags &= ~TULIP_DIDNWAY;
2945                 tulip_linkup(sc, media);
2946                 return 0;
2947             }
2948         }
2949     }
2950     sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_WANTRXACT);
2951     tulip_reset(sc);
2952     tulip_init(sc);
2953     return 0;
2954 }
2955 \f
2956 /*
2957  * Media status callback
2958  */
2959 static void
2960 tulip_ifmedia_status(
2961     struct ifnet * const ifp,
2962     struct ifmediareq *req)
2963 {
2964     tulip_softc_t *sc = (tulip_softc_t *)ifp->if_softc;
2965
2966     if (sc->tulip_media == TULIP_MEDIA_UNKNOWN)
2967         return;
2968
2969     req->ifm_status = IFM_AVALID;
2970     if (sc->tulip_flags & TULIP_LINKUP)
2971         req->ifm_status |= IFM_ACTIVE;
2972
2973     req->ifm_active = tulip_media_to_ifmedia[sc->tulip_media];
2974 }
2975 \f
2976 static void
2977 tulip_addr_filter(
2978     tulip_softc_t * const sc)
2979 {
2980     struct ifmultiaddr *ifma;
2981     u_char *addrp;
2982     int multicnt;
2983
2984     sc->tulip_flags &= ~(TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY|TULIP_ALLMULTI);
2985     sc->tulip_flags |= TULIP_WANTSETUP|TULIP_WANTTXSTART;
2986     sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
2987     sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
2988 #if defined(IFF_ALLMULTI)    
2989     if (sc->tulip_if.if_flags & IFF_ALLMULTI)
2990         sc->tulip_flags |= TULIP_ALLMULTI ;
2991 #endif
2992
2993     multicnt = 0;
2994     for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
2995          ifma = ifma->ifma_link.le_next) {
2996
2997             if (ifma->ifma_addr->sa_family == AF_LINK)
2998                 multicnt++;
2999     }
3000
3001     sc->tulip_if.if_start = tulip_ifstart;      /* so the setup packet gets queued */
3002     if (multicnt > 14) {
3003         u_int32_t *sp = sc->tulip_setupdata;
3004         unsigned hash;
3005         /*
3006          * Some early passes of the 21140 have broken implementations of
3007          * hash-perfect mode.  When we get too many multicasts for perfect
3008          * filtering with these chips, we need to switch into hash-only
3009          * mode (this is better than all-multicast on network with lots
3010          * of multicast traffic).
3011          */
3012         if (sc->tulip_features & TULIP_HAVE_BROKEN_HASH)
3013             sc->tulip_flags |= TULIP_WANTHASHONLY;
3014         else
3015             sc->tulip_flags |= TULIP_WANTHASHPERFECT;
3016         /*
3017          * If we have more than 14 multicasts, we have
3018          * go into hash perfect mode (512 bit multicast
3019          * hash and one perfect hardware).
3020          */
3021         bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata));
3022
3023         for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
3024              ifma = ifma->ifma_link.le_next) {
3025
3026                 if (ifma->ifma_addr->sa_family != AF_LINK)
3027                         continue;
3028
3029                 hash = tulip_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
3030 #if BYTE_ORDER == BIG_ENDIAN
3031                 sp[hash >> 4] |= bswap32(1 << (hash & 0xF));
3032 #else
3033                 sp[hash >> 4] |= 1 << (hash & 0xF);
3034 #endif
3035         }
3036         /*
3037          * No reason to use a hash if we are going to be
3038          * receiving every multicast.
3039          */
3040         if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
3041             hash = tulip_mchash(sc->tulip_if.if_broadcastaddr);
3042 #if BYTE_ORDER == BIG_ENDIAN
3043             sp[hash >> 4] |= bswap32(1 << (hash & 0xF));
3044 #else
3045             sp[hash >> 4] |= 1 << (hash & 0xF);
3046 #endif
3047             if (sc->tulip_flags & TULIP_WANTHASHONLY) {
3048                 hash = tulip_mchash(sc->tulip_enaddr);
3049 #if BYTE_ORDER == BIG_ENDIAN
3050                 sp[hash >> 4] |= bswap32(1 << (hash & 0xF));
3051 #else
3052                 sp[hash >> 4] |= 1 << (hash & 0xF);
3053 #endif
3054             } else {
3055 #if BYTE_ORDER == BIG_ENDIAN
3056                 sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0] << 16;
3057                 sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1] << 16;
3058                 sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2] << 16;
3059 #else
3060                 sp[39] = ((u_int16_t *) sc->tulip_enaddr)[0]; 
3061                 sp[40] = ((u_int16_t *) sc->tulip_enaddr)[1]; 
3062                 sp[41] = ((u_int16_t *) sc->tulip_enaddr)[2];
3063 #endif
3064             }
3065         }
3066     }
3067     if ((sc->tulip_flags & (TULIP_WANTHASHPERFECT|TULIP_WANTHASHONLY)) == 0) {
3068         u_int32_t *sp = sc->tulip_setupdata;
3069         int idx = 0;
3070         if ((sc->tulip_flags & TULIP_ALLMULTI) == 0) {
3071             /*
3072              * Else can get perfect filtering for 16 addresses.
3073              */
3074             for (ifma = sc->tulip_if.if_multiaddrs.lh_first; ifma != NULL;
3075                  ifma = ifma->ifma_link.le_next) {
3076                     if (ifma->ifma_addr->sa_family != AF_LINK)
3077                             continue;
3078                     addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr);
3079 #if BYTE_ORDER == BIG_ENDIAN
3080                     *sp++ = ((u_int16_t *) addrp)[0] << 16;
3081                     *sp++ = ((u_int16_t *) addrp)[1] << 16;
3082                     *sp++ = ((u_int16_t *) addrp)[2] << 16;
3083 #else
3084                     *sp++ = ((u_int16_t *) addrp)[0]; 
3085                     *sp++ = ((u_int16_t *) addrp)[1]; 
3086                     *sp++ = ((u_int16_t *) addrp)[2];
3087 #endif
3088                     idx++;
3089             }
3090             /*
3091              * Add the broadcast address.
3092              */
3093             idx++;
3094 #if BYTE_ORDER == BIG_ENDIAN
3095             *sp++ = 0xFFFF << 16;
3096             *sp++ = 0xFFFF << 16;
3097             *sp++ = 0xFFFF << 16;
3098 #else
3099             *sp++ = 0xFFFF;
3100             *sp++ = 0xFFFF;
3101             *sp++ = 0xFFFF;
3102 #endif
3103         }
3104         /*
3105          * Pad the rest with our hardware address
3106          */
3107         for (; idx < 16; idx++) {
3108 #if BYTE_ORDER == BIG_ENDIAN
3109             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0] << 16;
3110             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1] << 16;
3111             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2] << 16;
3112 #else
3113             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[0]; 
3114             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[1]; 
3115             *sp++ = ((u_int16_t *) sc->tulip_enaddr)[2];
3116 #endif
3117         }
3118     }
3119 #if defined(IFF_ALLMULTI)
3120     if (sc->tulip_flags & TULIP_ALLMULTI)
3121         sc->tulip_if.if_flags |= IFF_ALLMULTI;
3122 #endif
3123 }
3124 \f
3125 static void
3126 tulip_reset(
3127     tulip_softc_t * const sc)
3128 {
3129     tulip_ringinfo_t *ri;
3130     tulip_desc_t *di;
3131     u_int32_t inreset = (sc->tulip_flags & TULIP_INRESET);
3132
3133     /*
3134      * Brilliant.  Simply brilliant.  When switching modes/speeds
3135      * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
3136      * bits in CSR6 and then do a software reset to get the 21140
3137      * to properly reset its internal pathways to the right places.
3138      *   Grrrr.
3139      */
3140     if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0
3141             && sc->tulip_boardsw->bd_media_preset != NULL)
3142         (*sc->tulip_boardsw->bd_media_preset)(sc);
3143
3144     TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
3145     DELAY(10);  /* Wait 10 microseconds (actually 50 PCI cycles but at 
3146                    33MHz that comes to two microseconds but wait a
3147                    bit longer anyways) */
3148
3149     if (!inreset) {
3150         sc->tulip_flags |= TULIP_INRESET;
3151         sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW);
3152         sc->tulip_if.if_flags &= ~IFF_OACTIVE;
3153         sc->tulip_if.if_start = tulip_ifstart;
3154     }
3155
3156     TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0]));
3157     TULIP_CSR_WRITE(sc, csr_rxlist, TULIP_KVATOPHYS(sc, &sc->tulip_rxinfo.ri_first[0]));
3158     TULIP_CSR_WRITE(sc, csr_busmode,
3159                     (1 << (3 /*pci_max_burst_len*/ + 8))
3160                     |TULIP_BUSMODE_CACHE_ALIGN8
3161                     |TULIP_BUSMODE_READMULTIPLE
3162                     |(BYTE_ORDER != LITTLE_ENDIAN ?
3163                       TULIP_BUSMODE_DESC_BIGENDIAN : 0));
3164
3165     sc->tulip_txtimer = 0;
3166     sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS;
3167     /*
3168      * Free all the mbufs that were on the transmit ring.
3169      */
3170     for (;;) {
3171         struct mbuf *m;
3172         IF_DEQUEUE(&sc->tulip_txq, m);
3173         if (m == NULL)
3174             break;
3175         m_freem(m);
3176     }
3177
3178     ri = &sc->tulip_txinfo;
3179     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3180     ri->ri_free = ri->ri_max;
3181     for (di = ri->ri_first; di < ri->ri_last; di++)
3182         di->d_status = 0;
3183
3184     /*
3185      * We need to collect all the mbufs were on the 
3186      * receive ring before we reinit it either to put
3187      * them back on or to know if we have to allocate
3188      * more.
3189      */
3190     ri = &sc->tulip_rxinfo;
3191     ri->ri_nextin = ri->ri_nextout = ri->ri_first;
3192     ri->ri_free = ri->ri_max;
3193     for (di = ri->ri_first; di < ri->ri_last; di++) {
3194         di->d_status = 0;
3195         di->d_length1 = 0; di->d_addr1 = 0;
3196         di->d_length2 = 0; di->d_addr2 = 0;
3197     }
3198     for (;;) {
3199         struct mbuf *m;
3200         IF_DEQUEUE(&sc->tulip_rxq, m);
3201         if (m == NULL)
3202             break;
3203         m_freem(m);
3204     }
3205
3206     /*
3207      * If tulip_reset is being called recurisvely, exit quickly knowing
3208      * that when the outer tulip_reset returns all the right stuff will
3209      * have happened.
3210      */
3211     if (inreset)
3212         return;
3213
3214     sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR
3215         |TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED
3216         |TULIP_STS_TXUNDERFLOW|TULIP_STS_TXBABBLE
3217         |TULIP_STS_RXSTOPPED;
3218
3219     if ((sc->tulip_flags & TULIP_DEVICEPROBE) == 0)
3220         (*sc->tulip_boardsw->bd_media_select)(sc);
3221 #if defined(TULIP_DEBUG)
3222     if ((sc->tulip_flags & TULIP_NEEDRESET) == TULIP_NEEDRESET)
3223         printf("%s%d: tulip_reset: additional reset needed?!?\n",
3224                sc->tulip_name, sc->tulip_unit);
3225 #endif
3226     tulip_media_print(sc);
3227     if (sc->tulip_features & TULIP_HAVE_DUALSENSE)
3228         TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status));
3229
3230     sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET
3231                          |TULIP_RXACT);
3232     tulip_addr_filter(sc);
3233 }
3234 \f
3235 static void
3236 tulip_init(
3237     tulip_softc_t * const sc)
3238 {
3239     if (sc->tulip_if.if_flags & IFF_UP) {
3240         if ((sc->tulip_if.if_flags & IFF_RUNNING) == 0) {
3241             /* initialize the media */
3242             tulip_reset(sc);
3243         }
3244         sc->tulip_if.if_flags |= IFF_RUNNING;
3245         if (sc->tulip_if.if_flags & IFF_PROMISC) {
3246             sc->tulip_flags |= TULIP_PROMISC;
3247             sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS;
3248             sc->tulip_intrmask |= TULIP_STS_TXINTR;
3249         } else {
3250             sc->tulip_flags &= ~TULIP_PROMISC;
3251             sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS;
3252             if (sc->tulip_flags & TULIP_ALLMULTI) {
3253                 sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI;
3254             } else {
3255                 sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI;
3256             }
3257         }
3258         sc->tulip_cmdmode |= TULIP_CMD_TXRUN;
3259         if ((sc->tulip_flags & (TULIP_TXPROBE_ACTIVE|TULIP_WANTSETUP)) == 0) {
3260             tulip_rx_intr(sc);
3261             sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3262             sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3263         } else {
3264             sc->tulip_if.if_flags |= IFF_OACTIVE;
3265             sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN;
3266             sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED;
3267         }
3268         TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3269         TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3270         if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP)
3271             tulip_txput_setup(sc);
3272     } else {
3273         sc->tulip_if.if_flags &= ~IFF_RUNNING;
3274         tulip_reset(sc);
3275     }
3276 }
3277 \f
3278 static void
3279 tulip_rx_intr(
3280     tulip_softc_t * const sc)
3281 {
3282     tulip_ringinfo_t * const ri = &sc->tulip_rxinfo;
3283     struct ifnet * const ifp = &sc->tulip_if;
3284     int fillok = 1;
3285 #if defined(TULIP_DEBUG)
3286     int cnt = 0;
3287 #endif
3288
3289     for (;;) {
3290         struct ether_header eh;
3291         tulip_desc_t *eop = ri->ri_nextin;
3292         int total_len = 0, last_offset = 0;
3293         struct mbuf *ms = NULL, *me = NULL;
3294         int accept = 0;
3295
3296         if (fillok && sc->tulip_rxq.ifq_len < TULIP_RXQ_TARGET)
3297             goto queue_mbuf;
3298
3299 #if defined(TULIP_DEBUG)
3300         if (cnt == ri->ri_max)
3301             break;
3302 #endif
3303         /*
3304          * If the TULIP has no descriptors, there can't be any receive
3305          * descriptors to process.
3306          */
3307         if (eop == ri->ri_nextout)
3308             break;
3309
3310         /*
3311          * 90% of the packets will fit in one descriptor.  So we optimize
3312          * for that case.
3313          */
3314         TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3315         if ((((volatile tulip_desc_t *) eop)->d_status & (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
3316             IF_DEQUEUE(&sc->tulip_rxq, ms);
3317             me = ms;
3318         } else {
3319             /*
3320              * If still owned by the TULIP, don't touch it.
3321              */
3322             if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER)
3323                 break;
3324
3325             /*
3326              * It is possible (though improbable unless the BIG_PACKET support
3327              * is enabled or MCLBYTES < 1518) for a received packet to cross
3328              * more than one receive descriptor.  
3329              */
3330             while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) {
3331                 if (++eop == ri->ri_last)
3332                     eop = ri->ri_first;
3333                 TULIP_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
3334                 if (eop == ri->ri_nextout || ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER))) {
3335 #if defined(TULIP_DEBUG)
3336                     sc->tulip_dbg.dbg_rxintrs++;
3337                     sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
3338 #endif
3339                     return;
3340                 }
3341                 total_len++;
3342             }
3343
3344             /*
3345              * Dequeue the first buffer for the start of the packet.  Hopefully
3346              * this will be the only one we need to dequeue.  However, if the
3347              * packet consumed multiple descriptors, then we need to dequeue
3348              * those buffers and chain to the starting mbuf.  All buffers but
3349              * the last buffer have the same length so we can set that now.
3350              * (we add to last_offset instead of multiplying since we normally
3351              * won't go into the loop and thereby saving a ourselves from
3352              * doing a multiplication by 0 in the normal case).
3353              */
3354             IF_DEQUEUE(&sc->tulip_rxq, ms);
3355             for (me = ms; total_len > 0; total_len--) {
3356                 me->m_len = TULIP_RX_BUFLEN;
3357                 last_offset += TULIP_RX_BUFLEN;
3358                 IF_DEQUEUE(&sc->tulip_rxq, me->m_next);
3359                 me = me->m_next;
3360             }
3361         }
3362
3363         /*
3364          *  Now get the size of received packet (minus the CRC).
3365          */
3366         total_len = ((eop->d_status >> 16) & 0x7FFF) - 4;
3367         if ((sc->tulip_flags & TULIP_RXIGNORE) == 0
3368                 && ((eop->d_status & TULIP_DSTS_ERRSUM) == 0
3369 #ifdef BIG_PACKET
3370                      || (total_len <= sc->tulip_if.if_mtu + sizeof(struct ether_header) && 
3371                          (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxRUNT|
3372                                           TULIP_DSTS_RxCOLLSEEN|TULIP_DSTS_RxBADCRC|
3373                                           TULIP_DSTS_RxOVERFLOW)) == 0)
3374 #endif
3375                 )) {
3376             me->m_len = total_len - last_offset;
3377
3378             eh = *mtod(ms, struct ether_header *);
3379 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
3380             if (sc->tulip_if.if_bpf != NULL) {
3381                 if (me == ms)
3382                     bpf_tap(&sc->tulip_if, mtod(ms, caddr_t), total_len);
3383                 else
3384                     bpf_mtap(&sc->tulip_if, ms);
3385             }
3386 #endif
3387             sc->tulip_flags |= TULIP_RXACT;
3388             accept = 1;
3389         } else {
3390             ifp->if_ierrors++;
3391             if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) {
3392                 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3393             } else {
3394 #if defined(TULIP_VERBOSE)
3395                 const char *error = NULL;
3396 #endif
3397                 if (eop->d_status & TULIP_DSTS_RxTOOLONG) {
3398                     sc->tulip_dot3stats.dot3StatsFrameTooLongs++;
3399 #if defined(TULIP_VERBOSE)
3400                     error = "frame too long";
3401 #endif
3402                 }
3403                 if (eop->d_status & TULIP_DSTS_RxBADCRC) {
3404                     if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) {
3405                         sc->tulip_dot3stats.dot3StatsAlignmentErrors++;
3406 #if defined(TULIP_VERBOSE)
3407                         error = "alignment error";
3408 #endif
3409                     } else {
3410                         sc->tulip_dot3stats.dot3StatsFCSErrors++;
3411 #if defined(TULIP_VERBOSE)
3412                         error = "bad crc";
3413 #endif
3414                     }
3415                 }
3416 #if defined(TULIP_VERBOSE)
3417                 if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) {
3418                     printf("%s%d: receive: %6D: %s\n",
3419                            sc->tulip_name, sc->tulip_unit,
3420                            mtod(ms, u_char *) + 6, ":",
3421                            error);
3422                     sc->tulip_flags |= TULIP_NOMESSAGES;
3423                 }
3424 #endif
3425             }
3426         }
3427 #if defined(TULIP_DEBUG)
3428         cnt++;
3429 #endif
3430         ifp->if_ipackets++;
3431         if (++eop == ri->ri_last)
3432             eop = ri->ri_first;
3433         ri->ri_nextin = eop;
3434       queue_mbuf:
3435         /*
3436          * Either we are priming the TULIP with mbufs (m == NULL)
3437          * or we are about to accept an mbuf for the upper layers
3438          * so we need to allocate an mbuf to replace it.  If we
3439          * can't replace it, send up it anyways.  This may cause
3440          * us to drop packets in the future but that's better than
3441          * being caught in livelock.
3442          *
3443          * Note that if this packet crossed multiple descriptors
3444          * we don't even try to reallocate all the mbufs here.
3445          * Instead we rely on the test of the beginning of
3446          * the loop to refill for the extra consumed mbufs.
3447          */
3448         if (accept || ms == NULL) {
3449             struct mbuf *m0;
3450             MGETHDR(m0, MB_DONTWAIT, MT_DATA);
3451             if (m0 != NULL) {
3452 #if defined(TULIP_COPY_RXDATA)
3453                 if (!accept || total_len >= (MHLEN - 2)) {
3454 #endif
3455                     MCLGET(m0, MB_DONTWAIT);
3456                     if ((m0->m_flags & M_EXT) == 0) {
3457                         m_freem(m0);
3458                         m0 = NULL;
3459                     }
3460 #if defined(TULIP_COPY_RXDATA)
3461                 }
3462 #endif
3463             }
3464             if (accept
3465 #if defined(TULIP_COPY_RXDATA)
3466                 && m0 != NULL
3467 #endif
3468                 ) {
3469 #if !defined(TULIP_COPY_RXDATA)
3470                 ms->m_pkthdr.len = total_len;
3471                 ms->m_pkthdr.rcvif = ifp;
3472                 m_adj(ms, sizeof(struct ether_header));
3473                 ether_input(ifp, &eh, ms);
3474 #else
3475 #ifdef BIG_PACKET
3476 #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
3477 #endif
3478                 m0->m_data += 2;        /* align data after header */
3479                 m_copydata(ms, 0, total_len, mtod(m0, caddr_t));
3480                 m0->m_len = m0->m_pkthdr.len = total_len;
3481                 m0->m_pkthdr.rcvif = ifp;
3482                 m_adj(m0, sizeof(struct ether_header));
3483                 ether_input(ifp, &eh, m0);
3484                 m0 = ms;
3485 #endif /* ! TULIP_COPY_RXDATA */
3486             }
3487             ms = m0;
3488         }
3489         if (ms == NULL) {
3490             /*
3491              * Couldn't allocate a new buffer.  Don't bother 
3492              * trying to replenish the receive queue.
3493              */
3494             fillok = 0;
3495             sc->tulip_flags |= TULIP_RXBUFSLOW;
3496 #if defined(TULIP_DEBUG)
3497             sc->tulip_dbg.dbg_rxlowbufs++;
3498 #endif
3499             continue;
3500         }
3501         /*
3502          * Now give the buffer(s) to the TULIP and save in our
3503          * receive queue.
3504          */
3505         do {
3506             tulip_desc_t * const nextout = ri->ri_nextout;
3507             nextout->d_addr1 = TULIP_KVATOPHYS(sc, mtod(ms, caddr_t));
3508             nextout->d_length1 = TULIP_RX_BUFLEN;
3509             nextout->d_status = TULIP_DSTS_OWNER;
3510             TULIP_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
3511             if (++ri->ri_nextout == ri->ri_last)
3512                 ri->ri_nextout = ri->ri_first;
3513             me = ms->m_next;
3514             ms->m_next = NULL;
3515             IF_ENQUEUE(&sc->tulip_rxq, ms);
3516         } while ((ms = me) != NULL);
3517
3518         if (sc->tulip_rxq.ifq_len >= TULIP_RXQ_TARGET)
3519             sc->tulip_flags &= ~TULIP_RXBUFSLOW;
3520     }
3521
3522 #if defined(TULIP_DEBUG)
3523     sc->tulip_dbg.dbg_rxintrs++;
3524     sc->tulip_dbg.dbg_rxpktsperintr[cnt]++;
3525 #endif
3526 }
3527 \f
3528 static int
3529 tulip_tx_intr(
3530     tulip_softc_t * const sc)
3531 {
3532     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3533     struct mbuf *m;
3534     int xmits = 0;
3535     int descs = 0;
3536
3537     while (ri->ri_free < ri->ri_max) {
3538         u_int32_t d_flag;
3539
3540         TULIP_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
3541         if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER)
3542             break;
3543
3544         ri->ri_free++;
3545         descs++;
3546         d_flag = ri->ri_nextin->d_flag;
3547         if (d_flag & TULIP_DFLAG_TxLASTSEG) {
3548             if (d_flag & TULIP_DFLAG_TxSETUPPKT) {
3549                 /*
3550                  * We've just finished processing a setup packet.
3551                  * Mark that we finished it.  If there's not
3552                  * another pending, startup the TULIP receiver.
3553                  * Make sure we ack the RXSTOPPED so we won't get
3554                  * an abormal interrupt indication.
3555                  */
3556                 TULIP_TXMAP_POSTSYNC(sc, sc->tulip_setupmap);
3557                 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_HASHONLY);
3558                 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxINVRSFILT)
3559                     sc->tulip_flags |= TULIP_HASHONLY;
3560                 if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == 0) {
3561                     tulip_rx_intr(sc);
3562                     sc->tulip_cmdmode |= TULIP_CMD_RXRUN;
3563                     sc->tulip_intrmask |= TULIP_STS_RXSTOPPED;
3564                     TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3565                     TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
3566                     TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3567                 }
3568             } else {
3569                 const u_int32_t d_status = ri->ri_nextin->d_status;
3570                 IF_DEQUEUE(&sc->tulip_txq, m);
3571                 if (m != NULL) {
3572                     m_freem(m);
3573 #if defined(TULIP_DEBUG)
3574                 } else {
3575                     printf("%s%d: tx_intr: failed to dequeue mbuf?!?\n",
3576                             sc->tulip_name, sc->tulip_unit);
3577 #endif
3578                 }
3579                 if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
3580                     tulip_mediapoll_event_t event = TULIP_MEDIAPOLL_TXPROBE_OK;
3581                     if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) {
3582 #if defined(TULIP_DEBUG)
3583                         if (d_status & TULIP_DSTS_TxNOCARR)
3584                             sc->tulip_dbg.dbg_txprobe_nocarr++;
3585                         if (d_status & TULIP_DSTS_TxEXCCOLL)
3586                             sc->tulip_dbg.dbg_txprobe_exccoll++;
3587 #endif
3588                         event = TULIP_MEDIAPOLL_TXPROBE_FAILED;
3589                     }
3590                     (*sc->tulip_boardsw->bd_media_poll)(sc, event);
3591                     /*
3592                      * Escape from the loop before media poll has reset the TULIP!
3593                      */
3594                     break;
3595                 } else {
3596                     xmits++;
3597                     if (d_status & TULIP_DSTS_ERRSUM) {
3598                         sc->tulip_if.if_oerrors++;
3599                         if (d_status & TULIP_DSTS_TxEXCCOLL)
3600                             sc->tulip_dot3stats.dot3StatsExcessiveCollisions++;
3601                         if (d_status & TULIP_DSTS_TxLATECOLL)
3602                             sc->tulip_dot3stats.dot3StatsLateCollisions++;
3603                         if (d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS))
3604                             sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++;
3605                         if (d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE))
3606                             sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++;
3607                         if (d_status & TULIP_DSTS_TxUNDERFLOW)
3608                             sc->tulip_dot3stats.dot3StatsInternalTransmitUnderflows++;
3609                         if (d_status & TULIP_DSTS_TxBABBLE)
3610                             sc->tulip_dot3stats.dot3StatsInternalTransmitBabbles++;
3611                     } else {
3612                         u_int32_t collisions = 
3613                             (d_status & TULIP_DSTS_TxCOLLMASK)
3614                                 >> TULIP_DSTS_V_TxCOLLCNT;
3615                         sc->tulip_if.if_collisions += collisions;
3616                         if (collisions == 1)
3617                             sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++;
3618                         else if (collisions > 1)
3619                             sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++;
3620                         else if (d_status & TULIP_DSTS_TxDEFERRED)
3621                             sc->tulip_dot3stats.dot3StatsDeferredTransmissions++;
3622                         /*
3623                          * SQE is only valid for 10baseT/BNC/AUI when not
3624                          * running in full-duplex.  In order to speed up the
3625                          * test, the corresponding bit in tulip_flags needs to
3626                          * set as well to get us to count SQE Test Errors.
3627                          */
3628                         if (d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags)
3629                             sc->tulip_dot3stats.dot3StatsSQETestErrors++;
3630                     }
3631                 }
3632             }
3633         }
3634
3635         if (++ri->ri_nextin == ri->ri_last)
3636             ri->ri_nextin = ri->ri_first;
3637
3638         if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
3639             sc->tulip_if.if_flags &= ~IFF_OACTIVE;
3640     }
3641     /*
3642      * If nothing left to transmit, disable the timer.
3643      * Else if progress, reset the timer back to 2 ticks.
3644      */
3645     if (ri->ri_free == ri->ri_max || (sc->tulip_flags & TULIP_TXPROBE_ACTIVE))
3646         sc->tulip_txtimer = 0;
3647     else if (xmits > 0)
3648         sc->tulip_txtimer = TULIP_TXTIMER;
3649     sc->tulip_if.if_opackets += xmits;
3650     return descs;
3651 }
3652 \f
3653 static void
3654 tulip_print_abnormal_interrupt(
3655     tulip_softc_t * const sc,
3656     u_int32_t csr)
3657 {
3658     const char * const *msgp = tulip_status_bits;
3659     const char *sep;
3660     u_int32_t mask;
3661     const char thrsh[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
3662
3663     csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1;
3664     printf("%s%d: abnormal interrupt:", sc->tulip_name, sc->tulip_unit);
3665     for (sep = " ", mask = 1; mask <= csr; mask <<= 1, msgp++) {
3666         if ((csr & mask) && *msgp != NULL) {
3667             printf("%s%s", sep, *msgp);
3668             if (mask == TULIP_STS_TXUNDERFLOW && (sc->tulip_flags & TULIP_NEWTXTHRESH)) {
3669                 sc->tulip_flags &= ~TULIP_NEWTXTHRESH;
3670                 if (sc->tulip_cmdmode & TULIP_CMD_STOREFWD) {
3671                     printf(" (switching to store-and-forward mode)");
3672                 } else {
3673                     printf(" (raising TX threshold to %s)",
3674                            &thrsh[9 * ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) >> 14)]);
3675                 }
3676             }
3677             sep = ", ";
3678         }
3679     }
3680     printf("\n");
3681 }
3682
3683 static void
3684 tulip_intr_handler(
3685     tulip_softc_t * const sc,
3686     int *progress_p)
3687 {
3688     u_int32_t csr;
3689
3690     while ((csr = TULIP_CSR_READ(sc, csr_status)) & sc->tulip_intrmask) {
3691         *progress_p = 1;
3692         TULIP_CSR_WRITE(sc, csr_status, csr);
3693
3694         if (csr & TULIP_STS_SYSERROR) {
3695             sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
3696             if (sc->tulip_flags & TULIP_NOMESSAGES) {
3697                 sc->tulip_flags |= TULIP_SYSTEMERROR;
3698             } else {
3699                 printf("%s%d: system error: %s\n",
3700                        sc->tulip_name, sc->tulip_unit,
3701                        tulip_system_errors[sc->tulip_last_system_error]);
3702             }
3703             sc->tulip_flags |= TULIP_NEEDRESET;
3704             sc->tulip_system_errors++;
3705             break;
3706         }
3707         if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL) & sc->tulip_intrmask) {
3708 #if defined(TULIP_DEBUG)
3709             sc->tulip_dbg.dbg_link_intrs++;
3710 #endif
3711             if (sc->tulip_boardsw->bd_media_poll != NULL) {
3712                 (*sc->tulip_boardsw->bd_media_poll)(sc, csr & TULIP_STS_LINKFAIL
3713                                                     ? TULIP_MEDIAPOLL_LINKFAIL
3714                                                     : TULIP_MEDIAPOLL_LINKPASS);
3715                 csr &= ~TULIP_STS_ABNRMLINTR;
3716             }
3717             tulip_media_print(sc);
3718         }
3719         if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) {
3720             u_int32_t misses = TULIP_CSR_READ(sc, csr_missed_frames);
3721             if (csr & TULIP_STS_RXNOBUF)
3722                 sc->tulip_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
3723             /*
3724              * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
3725              * on receive overflows.
3726              */
3727            if ((misses & 0x0FFE0000) && (sc->tulip_features & TULIP_HAVE_RXBADOVRFLW)) {
3728                 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++;
3729                 /*
3730                  * Stop the receiver process and spin until it's stopped.
3731                  * Tell rx_intr to drop the packets it dequeues.
3732                  */
3733                 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN);
3734                 while ((TULIP_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
3735                     ;
3736                 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
3737                 sc->tulip_flags |= TULIP_RXIGNORE;
3738             }
3739             tulip_rx_intr(sc);
3740             if (sc->tulip_flags & TULIP_RXIGNORE) {
3741                 /*
3742                  * Restart the receiver.
3743                  */
3744                 sc->tulip_flags &= ~TULIP_RXIGNORE;
3745                 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3746             }
3747         }
3748         if (csr & TULIP_STS_ABNRMLINTR) {
3749             u_int32_t tmp = csr & sc->tulip_intrmask
3750                 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
3751             if (csr & TULIP_STS_TXUNDERFLOW) {
3752                 if ((sc->tulip_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
3753                     sc->tulip_cmdmode += TULIP_CMD_THRSHLD96;
3754                     sc->tulip_flags |= TULIP_NEWTXTHRESH;
3755                 } else if (sc->tulip_features & TULIP_HAVE_STOREFWD) {
3756                     sc->tulip_cmdmode |= TULIP_CMD_STOREFWD;
3757                     sc->tulip_flags |= TULIP_NEWTXTHRESH;
3758                 }
3759             }
3760             if (sc->tulip_flags & TULIP_NOMESSAGES) {
3761                 sc->tulip_statusbits |= tmp;
3762             } else {
3763                 tulip_print_abnormal_interrupt(sc, tmp);
3764                 sc->tulip_flags |= TULIP_NOMESSAGES;
3765             }
3766             TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode);
3767         }
3768         if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_TXPROBE_ACTIVE|TULIP_DOINGSETUP|TULIP_PROMISC)) {
3769             tulip_tx_intr(sc);
3770             if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0)
3771                 tulip_ifstart(&sc->tulip_if);
3772         }
3773     }
3774     if (sc->tulip_flags & TULIP_NEEDRESET) {
3775         tulip_reset(sc);
3776         tulip_init(sc);
3777     }
3778 }
3779
3780 static void
3781 tulip_intr_shared(
3782     void *arg)
3783 {
3784     tulip_softc_t * sc = arg;
3785     int progress = 0;
3786
3787     for (; sc != NULL; sc = sc->tulip_slaves) {
3788 #if defined(TULIP_DEBUG)
3789         sc->tulip_dbg.dbg_intrs++;
3790 #endif
3791         tulip_intr_handler(sc, &progress);
3792     }
3793 }
3794
3795 static void
3796 tulip_intr_normal(
3797     void *arg)
3798 {
3799     tulip_softc_t * sc = (tulip_softc_t *) arg;
3800     int progress = 0;
3801
3802 #if defined(TULIP_DEBUG)
3803     sc->tulip_dbg.dbg_intrs++;
3804 #endif
3805     tulip_intr_handler(sc, &progress);
3806 }
3807 \f
3808 static struct mbuf *
3809 tulip_mbuf_compress(
3810     struct mbuf *m)
3811 {
3812     struct mbuf *m0;
3813 #if MCLBYTES >= ETHERMTU + 18 && !defined(BIG_PACKET)
3814     MGETHDR(m0, MB_DONTWAIT, MT_DATA);
3815     if (m0 != NULL) {
3816         if (m->m_pkthdr.len > MHLEN) {
3817             MCLGET(m0, MB_DONTWAIT);
3818             if ((m0->m_flags & M_EXT) == 0) {
3819                 m_freem(m);
3820                 m_freem(m0);
3821                 return NULL;
3822             }
3823         }
3824         m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
3825         m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
3826     }
3827 #else
3828     int mlen = MHLEN;
3829     int len = m->m_pkthdr.len;
3830     struct mbuf **mp = &m0;
3831
3832     while (len > 0) {
3833         if (mlen == MHLEN) {
3834             MGETHDR(*mp, MB_DONTWAIT, MT_DATA);
3835         } else {
3836             MGET(*mp, MB_DONTWAIT, MT_DATA);
3837         }
3838         if (*mp == NULL) {
3839             m_freem(m0);
3840             m0 = NULL;
3841             break;
3842         }
3843         if (len > MLEN) {
3844             MCLGET(*mp, MB_DONTWAIT);
3845             if (((*mp)->m_flags & M_EXT) == 0) {
3846                 m_freem(m0);
3847                 m0 = NULL;
3848                 break;
3849             }
3850             (*mp)->m_len = len <= MCLBYTES ? len : MCLBYTES;
3851         } else {
3852             (*mp)->m_len = len <= mlen ? len : mlen;
3853         }
3854         m_copydata(m, m->m_pkthdr.len - len,
3855                    (*mp)->m_len, mtod((*mp), caddr_t));
3856         len -= (*mp)->m_len;
3857         mp = &(*mp)->m_next;
3858         mlen = MLEN;
3859     }
3860 #endif
3861     m_freem(m);
3862     return m0;
3863 }
3864 \f
3865 static struct mbuf *
3866 tulip_txput(
3867     tulip_softc_t * const sc,
3868     struct mbuf *m)
3869 {
3870     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
3871     tulip_desc_t *eop, *nextout;
3872     int segcnt, free;
3873     u_int32_t d_status;
3874     struct mbuf *m0;
3875
3876 #if defined(TULIP_DEBUG)
3877     if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
3878         printf("%s%d: txput%s: tx not running\n",
3879                sc->tulip_name, sc->tulip_unit,
3880                (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) ? "(probe)" : "");
3881         sc->tulip_flags |= TULIP_WANTTXSTART;
3882         sc->tulip_dbg.dbg_txput_finishes[0]++;
3883         goto finish;
3884     }
3885 #endif
3886
3887     /*
3888      * Now we try to fill in our transmit descriptors.  This is
3889      * a bit reminiscent of going on the Ark two by two
3890      * since each descriptor for the TULIP can describe
3891      * two buffers.  So we advance through packet filling
3892      * each of the two entries at a time to to fill each
3893      * descriptor.  Clear the first and last segment bits
3894      * in each descriptor (actually just clear everything
3895      * but the end-of-ring or chain bits) to make sure
3896      * we don't get messed up by previously sent packets.
3897      *
3898      * We may fail to put the entire packet on the ring if
3899      * there is either not enough ring entries free or if the
3900      * packet has more than MAX_TXSEG segments.  In the former
3901      * case we will just wait for the ring to empty.  In the
3902      * latter case we have to recopy.
3903      */
3904   again:
3905     m0 = m;
3906     d_status = 0;
3907     eop = nextout = ri->ri_nextout;
3908     segcnt = 0;
3909     free = ri->ri_free;
3910
3911     do {
3912         int len = m0->m_len;
3913         caddr_t addr = mtod(m0, caddr_t);
3914         unsigned clsize = PAGE_SIZE - (((uintptr_t) addr) & (PAGE_SIZE-1));
3915
3916         while (len > 0) {
3917             unsigned slen = min(len, clsize);
3918 #ifdef BIG_PACKET
3919             int partial = 0;
3920             if (slen >= 2048)
3921                 slen = 2040, partial = 1;
3922 #endif
3923             segcnt++;
3924             if (segcnt > TULIP_MAX_TXSEG) {
3925                 /*
3926                  * The packet exceeds the number of transmit buffer
3927                  * entries that we can use for one packet, so we have
3928                  * recopy it into one mbuf and then try again.
3929                  */
3930                 m = tulip_mbuf_compress(m);
3931                 if (m == NULL)
3932                     goto finish;
3933                 goto again;
3934             }
3935             if (segcnt & 1) {
3936                 if (--free == 0) {
3937                     /*
3938                      * See if there's any unclaimed space in the
3939                      * transmit ring.
3940                      */
3941                     if ((free += tulip_tx_intr(sc)) == 0) {
3942                         /*
3943                          * There's no more room but since nothing
3944                          * has been committed at this point, just
3945                          * show output is active, put back the
3946                          * mbuf and return.
3947                          */
3948                         sc->tulip_flags |= TULIP_WANTTXSTART;
3949 #if defined(TULIP_DEBUG)
3950                         sc->tulip_dbg.dbg_txput_finishes[1]++;
3951 #endif
3952                         goto finish;
3953                     }
3954                 }
3955                 eop = nextout;
3956                 if (++nextout == ri->ri_last)
3957                     nextout = ri->ri_first;
3958                 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
3959                 eop->d_status = d_status;
3960                 eop->d_addr1 = TULIP_KVATOPHYS(sc, addr);
3961                 eop->d_length1 = slen;
3962             } else {
3963                 /*
3964                  *  Fill in second half of descriptor
3965                  */
3966                 eop->d_addr2 = TULIP_KVATOPHYS(sc, addr);
3967                 eop->d_length2 = slen;
3968             }
3969             d_status = TULIP_DSTS_OWNER;
3970             len -= slen;
3971             addr += slen;
3972 #ifdef BIG_PACKET
3973             if (partial)
3974                 continue;
3975 #endif
3976             clsize = PAGE_SIZE;
3977         }
3978     } while ((m0 = m0->m_next) != NULL);
3979
3980     BPF_MTAP(&sc->tulip_if, m);
3981
3982     /*
3983      * The descriptors have been filled in.  Now get ready
3984      * to transmit.
3985      */
3986     IF_ENQUEUE(&sc->tulip_txq, m);
3987     m = NULL;
3988
3989     /*
3990      * Make sure the next descriptor after this packet is owned
3991      * by us since it may have been set up above if we ran out
3992      * of room in the ring.
3993      */
3994     nextout->d_status = 0;
3995     TULIP_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
3996
3997     /*
3998      * If we only used the first segment of the last descriptor,
3999      * make sure the second segment will not be used.
4000      */
4001     if (segcnt & 1) {
4002         eop->d_addr2 = 0;
4003         eop->d_length2 = 0;
4004     }
4005
4006     /*
4007      * Mark the last and first segments, indicate we want a transmit
4008      * complete interrupt, and tell it to transmit!
4009      */
4010     eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR;
4011
4012     /*
4013      * Note that ri->ri_nextout is still the start of the packet
4014      * and until we set the OWNER bit, we can still back out of
4015      * everything we have done.
4016      */
4017     ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG;
4018     ri->ri_nextout->d_status = TULIP_DSTS_OWNER;
4019     TULIP_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
4020
4021     /*
4022      * This advances the ring for us.
4023      */
4024     ri->ri_nextout = nextout;
4025     ri->ri_free = free;
4026
4027     if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) {
4028         TULIP_CSR_WRITE(sc, csr_txpoll, 1);
4029         sc->tulip_if.if_flags |= IFF_OACTIVE;
4030         sc->tulip_if.if_start = tulip_ifstart;
4031         return NULL;
4032     }
4033
4034     /*
4035      * switch back to the single queueing ifstart.
4036      */
4037     sc->tulip_flags &= ~TULIP_WANTTXSTART;
4038     if (sc->tulip_txtimer == 0)
4039         sc->tulip_txtimer = TULIP_TXTIMER;
4040 #if defined(TULIP_DEBUG)
4041     sc->tulip_dbg.dbg_txput_finishes[5]++;
4042 #endif
4043
4044     /*
4045      * If we want a txstart, there must be not enough space in the
4046      * transmit ring.  So we want to enable transmit done interrupts
4047      * so we can immediately reclaim some space.  When the transmit
4048      * interrupt is posted, the interrupt handler will call tx_intr
4049      * to reclaim space and then txstart (since WANTTXSTART is set).
4050      * txstart will move the packet into the transmit ring and clear
4051      * WANTTXSTART thereby causing TXINTR to be cleared.
4052      */
4053   finish:
4054 #if defined(TULIP_DEBUG)
4055     sc->tulip_dbg.dbg_txput_finishes[6]++;
4056 #endif
4057     if (sc->tulip_flags & (TULIP_WANTTXSTART|TULIP_DOINGSETUP)) {
4058         sc->tulip_if.if_flags |= IFF_OACTIVE;
4059         sc->tulip_if.if_start = tulip_ifstart;
4060         if ((sc->tulip_intrmask & TULIP_STS_TXINTR) == 0) {
4061             sc->tulip_intrmask |= TULIP_STS_TXINTR;
4062             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4063         }
4064     } else if ((sc->tulip_flags & TULIP_PROMISC) == 0) {
4065         if (sc->tulip_intrmask & TULIP_STS_TXINTR) {
4066             sc->tulip_intrmask &= ~TULIP_STS_TXINTR;
4067             TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask);
4068         }
4069     }
4070     TULIP_CSR_WRITE(sc, csr_txpoll, 1);
4071     return m;
4072 }
4073 \f
4074 static void
4075 tulip_txput_setup(
4076     tulip_softc_t * const sc)
4077 {
4078     tulip_ringinfo_t * const ri = &sc->tulip_txinfo;
4079     tulip_desc_t *nextout;
4080         
4081     /*
4082      * We will transmit, at most, one setup packet per call to ifstart.
4083      */
4084
4085 #if defined(TULIP_DEBUG)
4086     if ((sc->tulip_cmdmode & TULIP_CMD_TXRUN) == 0) {
4087         printf("%s%d: txput_setup: tx not running\n",
4088                sc->tulip_name, sc->tulip_unit);
4089         sc->tulip_flags |= TULIP_WANTTXSTART;
4090         sc->tulip_if.if_start = tulip_ifstart;
4091         return;
4092     }
4093 #endif
4094     /*
4095      * Try to reclaim some free descriptors..
4096      */
4097     if (ri->ri_free < 2)
4098         tulip_tx_intr(sc);
4099     if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) {
4100         sc->tulip_flags |= TULIP_WANTTXSTART;
4101         sc->tulip_if.if_start = tulip_ifstart;
4102         return;
4103     }
4104     bcopy(sc->tulip_setupdata, sc->tulip_setupbuf,
4105           sizeof(sc->tulip_setupbuf));
4106     /*
4107      * Clear WANTSETUP and set DOINGSETUP.  Set know that WANTSETUP is
4108      * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
4109      */
4110     sc->tulip_flags ^= TULIP_WANTSETUP|TULIP_DOINGSETUP;
4111     ri->ri_free--;
4112     nextout = ri->ri_nextout;
4113     nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN;
4114     nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG