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