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