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