1 /* $NetBSD: if_de.c,v 1.133 2009/05/12 08:23:00 cegger Exp $ */
4 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * Id: if_de.c,v 1.94 1997/07/03 16:55:07 thomas Exp
31 * DEC 21040 PCI Ethernet Controller
33 * Written by Matt Thomas
34 * BPF support code stolen directly from if_ec.c
36 * This driver supports the DEC DE435 or any other PCI
37 * board which support 21040, 21041, or 21140 (mostly).
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.133 2009/05/12 08:23:00 cegger Exp $");
42 #define TULIP_HDR_DATA
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/callout.h>
52 #include <sys/protosw.h>
53 #include <sys/socket.h>
54 #include <sys/ioctl.h>
55 #include <sys/errno.h>
56 #include <sys/malloc.h>
57 #include <sys/kernel.h>
58 #include <sys/proc.h> /* only for declaration of wakeup() used by vm.h */
59 #if defined(__FreeBSD__)
60 #include <machine/clock.h>
61 #elif defined(__bsdi__) || defined(__NetBSD__)
62 #include <sys/device.h>
65 #if defined(__NetBSD__)
73 #if defined(SIOCSIFMEDIA) && !defined(TULIP_NOIFMEDIA)
74 #include <net/if_media.h>
76 #include <net/if_types.h>
77 #include <net/if_dl.h>
78 #include <net/route.h>
79 #include <net/netisr.h>
81 #if defined(__bsdi__) && _BSDI_VERSION >= 199701
82 #include <dev/mii/mii.h>
83 #include <dev/mii/miivar.h>
89 #include <net/bpfdesc.h>
93 #include <netinet/in.h>
94 #include <netinet/in_systm.h>
95 #include <netinet/in_var.h>
96 #include <netinet/ip.h>
100 #if defined(__NetBSD__)
101 #include <uvm/uvm_extern.h>
104 #if defined(__FreeBSD__)
108 #include <netinet/if_ether.h>
110 #include <pci/pcivar.h>
111 #include <pci/dc21040reg.h>
112 #define DEVAR_INCLUDE "pci/if_devar.h"
114 #endif /* __FreeBSD__ */
116 #if defined(__bsdi__)
117 #include <netinet/if_ether.h>
118 #include <i386/pci/ic/dc21040reg.h>
119 #include <i386/isa/isa.h>
120 #include <i386/isa/icu.h>
121 #include <i386/isa/dma.h>
122 #include <i386/isa/isavar.h>
123 #include <i386/pci/pci.h>
124 #if _BSDI_VERSION < 199510
129 #if NEISA > 0 && _BSDI_VERSION >= 199401
130 #include <i386/eisa/eisa.h>
133 #define DEVAR_INCLUDE "i386/pci/if_devar.h"
134 #endif /* __bsdi__ */
136 #if defined(__NetBSD__)
137 #include <net/if_ether.h>
139 #include <netinet/if_inarp.h>
142 #include <sys/intr.h>
143 #include <dev/pci/pcireg.h>
144 #include <dev/pci/pcivar.h>
145 #include <dev/pci/pcidevs.h>
146 #include <dev/ic/dc21040reg.h>
147 #define DEVAR_INCLUDE "dev/pci/if_devar.h"
148 #endif /* __NetBSD__ */
151 * Intel CPUs should use I/O mapped access.
153 #if defined(__i386__) || defined(TULIP_EISA)
154 #define TULIP_IOMAPPED
159 * This turns on all sort of debugging stuff and make the
160 * driver much larger.
166 #define TULIP_PERFSTATS
170 #define TULIP_USE_SOFTINTR
175 #include DEVAR_INCLUDE
177 * This module supports
178 * the DEC 21040 PCI Ethernet Controller.
179 * the DEC 21041 PCI Ethernet Controller.
180 * the DEC 21140 PCI Fast Ethernet Controller.
182 static void tulip_mii_autonegotiate(tulip_softc_t
* const sc
, const unsigned phyaddr
);
183 static tulip_intrfunc_t
tulip_intr_shared(void *arg
);
184 static tulip_intrfunc_t
tulip_intr_normal(void *arg
);
185 static void tulip_init(tulip_softc_t
* const sc
);
186 static void tulip_reset(tulip_softc_t
* const sc
);
187 static ifnet_ret_t
tulip_ifstart_one(struct ifnet
*ifp
);
188 static ifnet_ret_t
tulip_ifstart(struct ifnet
*ifp
);
189 static struct mbuf
*tulip_txput(tulip_softc_t
* const sc
, struct mbuf
*m
);
190 static void tulip_txput_setup(tulip_softc_t
* const sc
);
191 static void tulip_rx_intr(tulip_softc_t
* const sc
);
192 static void tulip_addr_filter(tulip_softc_t
* const sc
);
193 static unsigned tulip_mii_readreg(tulip_softc_t
* const sc
, unsigned devaddr
, unsigned regno
);
194 static void tulip_mii_writereg(tulip_softc_t
* const sc
, unsigned devaddr
, unsigned regno
, unsigned data
);
195 static int tulip_mii_map_abilities(tulip_softc_t
* const sc
, unsigned abilities
);
196 static tulip_media_t
tulip_mii_phy_readspecific(tulip_softc_t
* const sc
);
197 static int tulip_srom_decode(tulip_softc_t
* const sc
);
198 #if defined(IFM_ETHER)
199 static int tulip_ifmedia_change(struct ifnet
* const ifp
);
200 static void tulip_ifmedia_status(struct ifnet
* const ifp
, struct ifmediareq
*req
);
202 /* static void tulip_21140_map_media(tulip_softc_t *sc); */
206 tulip_alloc_rxmap(tulip_softc_t
*sc
)
208 return (sc
->tulip_free_rxmaps
[--sc
->tulip_num_free_rxmaps
]);
212 tulip_free_rxmap(tulip_softc_t
*sc
, bus_dmamap_t map
)
214 sc
->tulip_free_rxmaps
[sc
->tulip_num_free_rxmaps
++] = map
;
218 tulip_alloc_txmap(tulip_softc_t
*sc
)
220 return (sc
->tulip_free_txmaps
[--sc
->tulip_num_free_txmaps
]);
224 tulip_free_txmap(tulip_softc_t
*sc
, bus_dmamap_t map
)
226 sc
->tulip_free_txmaps
[sc
->tulip_num_free_txmaps
++] = map
;
231 tulip_timeout_callback(
234 tulip_softc_t
* const sc
= arg
;
235 tulip_spl_t s
= TULIP_RAISESPL();
237 TULIP_PERFSTART(timeout
)
239 sc
->tulip_flags
&= ~TULIP_TIMEOUTPENDING
;
240 sc
->tulip_probe_timeout
-= 1000 / TULIP_HZ
;
241 (sc
->tulip_boardsw
->bd_media_poll
)(sc
, TULIP_MEDIAPOLL_TIMER
);
243 TULIP_PERFEND(timeout
);
249 tulip_softc_t
* const sc
)
251 if (sc
->tulip_flags
& TULIP_TIMEOUTPENDING
)
253 sc
->tulip_flags
|= TULIP_TIMEOUTPENDING
;
254 callout_reset(&sc
->tulip_to_ch
, (hz
+ TULIP_HZ
/ 2) / TULIP_HZ
,
255 tulip_timeout_callback
, sc
);
258 #if defined(TULIP_NEED_FASTTIMEOUT)
260 tulip_fasttimeout_callback(
263 tulip_softc_t
* const sc
= arg
;
264 tulip_spl_t s
= TULIP_RAISESPL();
266 sc
->tulip_flags
&= ~TULIP_FASTTIMEOUTPENDING
;
267 (sc
->tulip_boardsw
->bd_media_poll
)(sc
, TULIP_MEDIAPOLL_FASTTIMER
);
273 tulip_softc_t
* const sc
)
275 if (sc
->tulip_flags
& TULIP_FASTTIMEOUTPENDING
)
277 sc
->tulip_flags
|= TULIP_FASTTIMEOUTPENDING
;
278 callout_reset(&sc
->tulip_fto_ch
, 1, tulip_fasttimeout_callback
, sc
);
284 tulip_softc_t
* const sc
)
288 * Before we are sure this is the right media we need
289 * to send a small packet to make sure there's carrier.
290 * Strangely, BNC and AUI will "see" receive data if
291 * either is connected so the transmit is the only way
292 * to verify the connectivity.
294 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
298 * Construct a LLC TEST message which will point to ourselves.
300 memcpy(mtod(m
, struct ether_header
*)->ether_dhost
, sc
->tulip_enaddr
,
302 memcpy(mtod(m
, struct ether_header
*)->ether_shost
, sc
->tulip_enaddr
,
304 mtod(m
, struct ether_header
*)->ether_type
= htons(3);
305 mtod(m
, unsigned char *)[14] = 0;
306 mtod(m
, unsigned char *)[15] = 0;
307 mtod(m
, unsigned char *)[16] = 0xE3; /* LLC Class1 TEST (no poll) */
308 m
->m_len
= m
->m_pkthdr
.len
= sizeof(struct ether_header
) + 3;
312 sc
->tulip_cmdmode
|= TULIP_CMD_TXRUN
;
313 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
314 sc
->tulip_flags
|= TULIP_TXPROBE_ACTIVE
;
315 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
316 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
317 if ((m
= tulip_txput(sc
, m
)) != NULL
)
319 sc
->tulip_probe
.probe_txprobes
++;
324 #define TULIP_SIAGEN_WATCHDOG (sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0)
326 #define TULIP_SIAGEN_WATCHDOG 0
331 tulip_softc_t
* const sc
,
334 const tulip_media_info_t
*mi
= sc
->tulip_mediums
[media
];
339 /* Reset the SIA first
341 if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
|| (sc
->tulip_features
& TULIP_HAVE_SIANWAY
)) {
342 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, TULIP_SIACONN_RESET
);
345 /* Next, set full duplex if needed.
347 if (sc
->tulip_flags
& TULIP_FULLDUPLEX
) {
349 if (TULIP_CSR_READ(sc
, csr_command
) & (TULIP_CMD_RXRUN
|TULIP_CMD_TXRUN
)) {
350 printf(TULIP_PRINTF_FMT
": warning: board is running (FD).\n",
354 if ((TULIP_CSR_READ(sc
, csr_command
) & TULIP_CMD_FULLDUPLEX
) == 0) {
355 loudprintf(TULIP_PRINTF_FMT
": setting full duplex.\n",
358 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
359 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
& ~(TULIP_CMD_RXRUN
|TULIP_CMD_TXRUN
));
362 /* Now setup the media.
365 * If we are switching media, make sure we don't think there's
366 * any stale RX activity
368 sc
->tulip_flags
&= ~TULIP_RXACT
;
369 if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
370 TULIP_CSR_WRITE(sc
, csr_sia_tx_rx
, mi
->mi_sia_tx_rx
);
371 if (sc
->tulip_features
& TULIP_HAVE_SIAGP
) {
372 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_gp_control
|mi
->mi_sia_general
|TULIP_SIAGEN_WATCHDOG
);
374 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_gp_data
|mi
->mi_sia_general
|TULIP_SIAGEN_WATCHDOG
);
376 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_general
|TULIP_SIAGEN_WATCHDOG
);
378 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, mi
->mi_sia_connectivity
);
379 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
) {
380 #define TULIP_GPR_CMDBITS (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)
382 * If the cmdmode bits don't match the currently operating mode,
383 * set the cmdmode appropriately and reset the chip.
385 if (((mi
->mi_cmdmode
^ TULIP_CSR_READ(sc
, csr_command
)) & TULIP_GPR_CMDBITS
) != 0) {
386 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
387 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
390 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_PINSET
|sc
->tulip_gpinit
);
392 TULIP_CSR_WRITE(sc
, csr_gp
, (u_int8_t
) mi
->mi_gpdata
);
393 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
395 * If the cmdmode bits don't match the currently operating mode,
396 * set the cmdmode appropriately and reset the chip.
398 if (((mi
->mi_cmdmode
^ TULIP_CSR_READ(sc
, csr_command
)) & TULIP_GPR_CMDBITS
) != 0) {
399 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
400 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
403 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_gpcontrol
);
404 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_gpdata
);
405 } else if (mi
->mi_type
== TULIP_MEDIAINFO_MII
406 && sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
) {
408 if (sc
->tulip_features
& TULIP_HAVE_SIAGP
) {
410 dp
= &sc
->tulip_rombuf
[mi
->mi_reset_offset
];
411 for (idx
= 0; idx
< mi
->mi_reset_length
; idx
++, dp
+= 2) {
413 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp
[0] + 256 * dp
[1]) << 16);
415 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
416 dp
= &sc
->tulip_rombuf
[mi
->mi_gpr_offset
];
417 for (idx
= 0; idx
< mi
->mi_gpr_length
; idx
++, dp
+= 2) {
419 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp
[0] + 256 * dp
[1]) << 16);
422 for (idx
= 0; idx
< mi
->mi_reset_length
; idx
++) {
424 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_reset_offset
+ idx
]);
426 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
427 for (idx
= 0; idx
< mi
->mi_gpr_length
; idx
++) {
429 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_gpr_offset
+ idx
]);
433 if (sc
->tulip_features
& TULIP_HAVE_SIANWAY
) {
434 /* Set the SIA port into MII mode */
435 TULIP_CSR_WRITE(sc
, csr_sia_general
, 1);
436 TULIP_CSR_WRITE(sc
, csr_sia_tx_rx
, 0);
437 TULIP_CSR_WRITE(sc
, csr_sia_status
, 0);
440 if (sc
->tulip_flags
& TULIP_TRYNWAY
) {
441 tulip_mii_autonegotiate(sc
, sc
->tulip_phyaddr
);
442 } else if ((sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
443 u_int32_t data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_CONTROL
);
444 data
&= ~(PHYCTL_SELECT_100MB
|PHYCTL_FULL_DUPLEX
|PHYCTL_AUTONEG_ENABLE
);
445 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
446 if (TULIP_IS_MEDIA_FD(media
))
447 data
|= PHYCTL_FULL_DUPLEX
;
448 if (TULIP_IS_MEDIA_100MB(media
))
449 data
|= PHYCTL_SELECT_100MB
;
450 tulip_mii_writereg(sc
, sc
->tulip_phyaddr
, PHYREG_CONTROL
, data
);
457 tulip_softc_t
* const sc
,
460 if ((sc
->tulip_flags
& TULIP_LINKUP
) == 0)
461 sc
->tulip_flags
|= TULIP_PRINTLINKUP
;
462 sc
->tulip_flags
|= TULIP_LINKUP
;
463 sc
->tulip_if
.if_flags
&= ~IFF_OACTIVE
;
464 #if 0 /* XXX how does with work with ifmedia? */
465 if ((sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
466 if (sc
->tulip_if
.if_flags
& IFF_FULLDUPLEX
) {
467 if (TULIP_CAN_MEDIA_FD(media
)
468 && sc
->tulip_mediums
[TULIP_FD_MEDIA_OF(media
)] != NULL
)
469 media
= TULIP_FD_MEDIA_OF(media
);
471 if (TULIP_IS_MEDIA_FD(media
)
472 && sc
->tulip_mediums
[TULIP_HD_MEDIA_OF(media
)] != NULL
)
473 media
= TULIP_HD_MEDIA_OF(media
);
477 if (sc
->tulip_media
!= media
) {
479 sc
->tulip_dbg
.dbg_last_media
= sc
->tulip_media
;
481 sc
->tulip_media
= media
;
482 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
483 if (TULIP_IS_MEDIA_FD(sc
->tulip_media
)) {
484 sc
->tulip_flags
|= TULIP_FULLDUPLEX
;
485 } else if (sc
->tulip_chipid
!= TULIP_21041
|| (sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
486 sc
->tulip_flags
&= ~TULIP_FULLDUPLEX
;
490 * We could set probe_timeout to 0 but setting to 3000 puts this
491 * in one central place and the only matters is tulip_link is
492 * followed by a tulip_timeout. Therefore setting it should not
493 * result in aberrant behavour.
495 sc
->tulip_probe_timeout
= 3000;
496 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
497 sc
->tulip_flags
&= ~(TULIP_TXPROBE_ACTIVE
|TULIP_TRYNWAY
);
498 if (sc
->tulip_flags
& TULIP_INRESET
) {
499 tulip_media_set(sc
, sc
->tulip_media
);
500 } else if (sc
->tulip_probe_media
!= sc
->tulip_media
) {
502 * No reason to change media if we have the right media.
511 tulip_softc_t
* const sc
)
513 if ((sc
->tulip_flags
& TULIP_LINKUP
) == 0)
515 if (sc
->tulip_flags
& TULIP_PRINTMEDIA
) {
516 printf(TULIP_PRINTF_FMT
": enabling %s port\n",
518 tulip_mediums
[sc
->tulip_media
]);
519 sc
->tulip_flags
&= ~(TULIP_PRINTMEDIA
|TULIP_PRINTLINKUP
);
520 } else if (sc
->tulip_flags
& TULIP_PRINTLINKUP
) {
521 printf(TULIP_PRINTF_FMT
": link up\n", TULIP_PRINTF_ARGS
);
522 sc
->tulip_flags
&= ~TULIP_PRINTLINKUP
;
526 #if defined(TULIP_DO_GPR_SENSE)
528 tulip_21140_gpr_media_sense(
529 tulip_softc_t
* const sc
)
531 tulip_media_t maybe_media
= TULIP_MEDIA_UNKNOWN
;
532 tulip_media_t last_media
= TULIP_MEDIA_UNKNOWN
;
536 * If one of the media blocks contained a default media flag,
539 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
540 const tulip_media_info_t
*mi
;
542 * Media is not supported (or is full-duplex).
544 if ((mi
= sc
->tulip_mediums
[media
]) == NULL
|| TULIP_IS_MEDIA_FD(media
))
546 if (mi
->mi_type
!= TULIP_MEDIAINFO_GPR
)
550 * Remember the media is this is the "default" media.
552 if (mi
->mi_default
&& maybe_media
== TULIP_MEDIA_UNKNOWN
)
556 * No activity mask? Can't see if it is active if there's no mask.
558 if (mi
->mi_actmask
== 0)
562 * Does the activity data match?
564 if ((TULIP_CSR_READ(sc
, csr_gp
) & mi
->mi_actmask
) != mi
->mi_actdata
)
567 #if defined(TULIP_DEBUG)
568 printf(TULIP_PRINTF_FMT
": gpr_media_sense: %s: 0x%02x & 0x%02x == 0x%02x\n",
569 TULIP_PRINTF_ARGS
, tulip_mediums
[media
],
570 TULIP_CSR_READ(sc
, csr_gp
) & 0xFF,
571 mi
->mi_actmask
, mi
->mi_actdata
);
574 * It does! If this is the first media we detected, then
575 * remember this media. If isn't the first, then there were
576 * multiple matches which we equate to no match (since we don't
577 * which to select (if any).
579 if (last_media
== TULIP_MEDIA_UNKNOWN
) {
581 } else if (last_media
!= media
) {
582 last_media
= TULIP_MEDIA_UNKNOWN
;
585 return (last_media
!= TULIP_MEDIA_UNKNOWN
) ? last_media
: maybe_media
;
587 #endif /* TULIP_DO_GPR_SENSE */
589 static tulip_link_status_t
590 tulip_media_link_monitor(
591 tulip_softc_t
* const sc
)
593 const tulip_media_info_t
* const mi
= sc
->tulip_mediums
[sc
->tulip_media
];
594 tulip_link_status_t linkup
= TULIP_LINK_DOWN
;
597 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
598 panic("tulip_media_link_monitor: %s: botch at line %d",
599 tulip_mediums
[sc
->tulip_media
],__LINE__
);
601 return TULIP_LINK_UNKNOWN
;
606 * Have we seen some packets? If so, the link must be good.
608 if ((sc
->tulip_flags
& (TULIP_RXACT
|TULIP_LINKUP
)) == (TULIP_RXACT
|TULIP_LINKUP
)) {
609 sc
->tulip_flags
&= ~TULIP_RXACT
;
610 sc
->tulip_probe_timeout
= 3000;
611 return TULIP_LINK_UP
;
614 sc
->tulip_flags
&= ~TULIP_RXACT
;
615 if (mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
618 * Read the PHY status register.
620 status
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
)
621 | tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
);
622 if (status
& PHYSTS_AUTONEG_DONE
) {
624 * If the PHY has completed autonegotiation, see the if the
625 * remote systems abilities have changed. If so, upgrade or
626 * downgrade as appropriate.
628 u_int32_t abilities
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_AUTONEG_ABILITIES
);
629 abilities
= (abilities
<< 6) & status
;
630 if (abilities
!= sc
->tulip_abilities
) {
631 #if defined(TULIP_DEBUG)
632 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n",
633 TULIP_PRINTF_ARGS
, sc
->tulip_phyaddr
,
634 sc
->tulip_abilities
, abilities
);
636 if (tulip_mii_map_abilities(sc
, abilities
)) {
637 tulip_linkup(sc
, sc
->tulip_probe_media
);
638 return TULIP_LINK_UP
;
641 * if we had selected media because of autonegotiation,
642 * we need to probe for the new media.
644 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
645 if (sc
->tulip_flags
& TULIP_DIDNWAY
)
646 return TULIP_LINK_DOWN
;
650 * The link is now up. If was down, say its back up.
652 if ((status
& (PHYSTS_LINK_UP
|PHYSTS_REMOTE_FAULT
)) == PHYSTS_LINK_UP
)
653 linkup
= TULIP_LINK_UP
;
654 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
) {
656 * No activity sensor? Assume all's well.
658 if (mi
->mi_actmask
== 0)
659 return TULIP_LINK_UNKNOWN
;
661 * Does the activity data match?
663 if ((TULIP_CSR_READ(sc
, csr_gp
) & mi
->mi_actmask
) == mi
->mi_actdata
)
664 linkup
= TULIP_LINK_UP
;
665 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
667 * Assume non TP ok for now.
669 if (!TULIP_IS_MEDIA_TP(sc
->tulip_media
))
670 return TULIP_LINK_UNKNOWN
;
671 if ((TULIP_CSR_READ(sc
, csr_sia_status
) & TULIP_SIASTS_LINKFAIL
) == 0)
672 linkup
= TULIP_LINK_UP
;
673 #if defined(TULIP_DEBUG)
674 if (sc
->tulip_probe_timeout
<= 0)
675 printf(TULIP_PRINTF_FMT
": sia status = 0x%08x\n", TULIP_PRINTF_ARGS
, TULIP_CSR_READ(sc
, csr_sia_status
));
677 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
678 return TULIP_LINK_UNKNOWN
;
681 * We will wait for 3 seconds until the link goes into suspect mode.
683 if (sc
->tulip_flags
& TULIP_LINKUP
) {
684 if (linkup
== TULIP_LINK_UP
)
685 sc
->tulip_probe_timeout
= 3000;
686 if (sc
->tulip_probe_timeout
> 0)
687 return TULIP_LINK_UP
;
689 sc
->tulip_flags
&= ~TULIP_LINKUP
;
690 printf(TULIP_PRINTF_FMT
": link down: cable problem?\n", TULIP_PRINTF_ARGS
);
692 #if defined(TULIP_DEBUG)
693 sc
->tulip_dbg
.dbg_link_downed
++;
695 return TULIP_LINK_DOWN
;
700 tulip_softc_t
* const sc
,
701 tulip_mediapoll_event_t event
)
703 #if defined(TULIP_DEBUG)
704 sc
->tulip_dbg
.dbg_events
[event
]++;
706 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
707 && event
== TULIP_MEDIAPOLL_TIMER
) {
708 switch (tulip_media_link_monitor(sc
)) {
709 case TULIP_LINK_DOWN
: {
711 * Link Monitor failed. Probe for new media.
713 event
= TULIP_MEDIAPOLL_LINKFAIL
;
716 case TULIP_LINK_UP
: {
723 case TULIP_LINK_UNKNOWN
: {
725 * We can't tell so don't bother.
732 if (event
== TULIP_MEDIAPOLL_LINKFAIL
) {
733 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
) {
734 if (TULIP_DO_AUTOSENSE(sc
)) {
735 #if defined(TULIP_DEBUG)
736 sc
->tulip_dbg
.dbg_link_failures
++;
738 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
739 if (sc
->tulip_if
.if_flags
& IFF_UP
)
740 tulip_reset(sc
); /* restart probe */
744 #if defined(TULIP_DEBUG)
745 sc
->tulip_dbg
.dbg_link_pollintrs
++;
749 if (event
== TULIP_MEDIAPOLL_START
) {
750 sc
->tulip_if
.if_flags
|= IFF_OACTIVE
;
751 if (sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
)
753 sc
->tulip_probe_mediamask
= 0;
754 sc
->tulip_probe_passes
= 0;
755 #if defined(TULIP_DEBUG)
756 sc
->tulip_dbg
.dbg_media_probes
++;
759 * If the SROM contained an explicit media to use, use it.
761 sc
->tulip_cmdmode
&= ~(TULIP_CMD_RXRUN
|TULIP_CMD_FULLDUPLEX
);
762 sc
->tulip_flags
|= TULIP_TRYNWAY
|TULIP_PROBE1STPASS
;
763 sc
->tulip_flags
&= ~(TULIP_DIDNWAY
|TULIP_PRINTMEDIA
|TULIP_PRINTLINKUP
);
765 * connidx is defaulted to a media_unknown type.
767 sc
->tulip_probe_media
= tulip_srom_conninfo
[sc
->tulip_connidx
].sc_media
;
768 if (sc
->tulip_probe_media
!= TULIP_MEDIA_UNKNOWN
) {
769 tulip_linkup(sc
, sc
->tulip_probe_media
);
774 if (sc
->tulip_features
& TULIP_HAVE_GPR
) {
775 sc
->tulip_probe_state
= TULIP_PROBE_GPRTEST
;
776 sc
->tulip_probe_timeout
= 2000;
778 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
;
779 sc
->tulip_probe_timeout
= 0;
780 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
785 * Ignore txprobe failures or spurious callbacks.
787 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
788 && sc
->tulip_probe_state
!= TULIP_PROBE_MEDIATEST
) {
789 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
794 * If we really transmitted a packet, then that's the media we'll use.
796 if (event
== TULIP_MEDIAPOLL_TXPROBE_OK
|| event
== TULIP_MEDIAPOLL_LINKPASS
) {
797 if (event
== TULIP_MEDIAPOLL_LINKPASS
) {
798 /* XXX Check media status just to be sure */
799 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
800 #if defined(TULIP_DEBUG)
802 sc
->tulip_dbg
.dbg_txprobes_ok
[sc
->tulip_probe_media
]++;
805 tulip_linkup(sc
, sc
->tulip_probe_media
);
810 if (sc
->tulip_probe_state
== TULIP_PROBE_GPRTEST
) {
811 #if defined(TULIP_DO_GPR_SENSE)
813 * Check for media via the general purpose register.
815 * Try to sense the media via the GPR. If the same value
816 * occurs 3 times in a row then just use that.
818 if (sc
->tulip_probe_timeout
> 0) {
819 tulip_media_t new_probe_media
= tulip_21140_gpr_media_sense(sc
);
820 #if defined(TULIP_DEBUG)
821 printf(TULIP_PRINTF_FMT
": media_poll: gpr sensing = %s\n",
822 TULIP_PRINTF_ARGS
, tulip_mediums
[new_probe_media
]);
824 if (new_probe_media
!= TULIP_MEDIA_UNKNOWN
) {
825 if (new_probe_media
== sc
->tulip_probe_media
) {
826 if (--sc
->tulip_probe_count
== 0)
827 tulip_linkup(sc
, sc
->tulip_probe_media
);
829 sc
->tulip_probe_count
= 10;
832 sc
->tulip_probe_media
= new_probe_media
;
836 #endif /* TULIP_DO_GPR_SENSE */
838 * Brute force. We cycle through each of the media types
839 * and try to transmit a packet.
841 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
842 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
;
843 sc
->tulip_probe_timeout
= 0;
848 if (sc
->tulip_probe_state
!= TULIP_PROBE_MEDIATEST
849 && (sc
->tulip_features
& TULIP_HAVE_MII
)) {
850 tulip_media_t old_media
= sc
->tulip_probe_media
;
851 tulip_mii_autonegotiate(sc
, sc
->tulip_phyaddr
);
852 switch (sc
->tulip_probe_state
) {
853 case TULIP_PROBE_FAILED
:
854 case TULIP_PROBE_MEDIATEST
: {
856 * Try the next media.
858 sc
->tulip_probe_mediamask
|= sc
->tulip_mediums
[sc
->tulip_probe_media
]->mi_mediamask
;
859 sc
->tulip_probe_timeout
= 0;
861 if (sc
->tulip_probe_state
== TULIP_PROBE_FAILED
)
863 if (sc
->tulip_probe_media
!= tulip_mii_phy_readspecific(sc
))
865 sc
->tulip_probe_timeout
= TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
) ? 2500 : 300;
869 case TULIP_PROBE_PHYAUTONEG
: {
872 case TULIP_PROBE_INACTIVE
: {
874 * Only probe if we autonegotiated a media that hasn't failed.
876 sc
->tulip_probe_timeout
= 0;
877 if (sc
->tulip_probe_mediamask
& TULIP_BIT(sc
->tulip_probe_media
)) {
878 sc
->tulip_probe_media
= old_media
;
881 tulip_linkup(sc
, sc
->tulip_probe_media
);
886 #if defined(DIAGNOSTIC) || defined(TULIP_DEBUG)
887 panic("tulip_media_poll: botch at line %d", __LINE__
);
894 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
) {
895 #if defined(TULIP_DEBUG)
896 sc
->tulip_dbg
.dbg_txprobes_failed
[sc
->tulip_probe_media
]++;
898 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
903 * switch to another media if we tried this one enough.
905 if (/* event == TULIP_MEDIAPOLL_TXPROBE_FAILED || */ sc
->tulip_probe_timeout
<= 0) {
906 #if defined(TULIP_DEBUG)
907 if (sc
->tulip_probe_media
== TULIP_MEDIA_UNKNOWN
) {
908 printf(TULIP_PRINTF_FMT
": poll media unknown!\n",
910 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
;
914 * Find the next media type to check for. Full Duplex
915 * types are not allowed.
918 sc
->tulip_probe_media
-= 1;
919 if (sc
->tulip_probe_media
== TULIP_MEDIA_UNKNOWN
) {
920 if (++sc
->tulip_probe_passes
== 3) {
921 printf(TULIP_PRINTF_FMT
": autosense failed: cable problem?\n",
923 if ((sc
->tulip_if
.if_flags
& IFF_UP
) == 0) {
924 sc
->tulip_if
.if_flags
&= ~IFF_RUNNING
;
925 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
929 sc
->tulip_flags
^= TULIP_TRYNWAY
; /* XXX */
930 sc
->tulip_probe_mediamask
= 0;
931 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
- 1;
933 } while (sc
->tulip_mediums
[sc
->tulip_probe_media
] == NULL
934 || (sc
->tulip_probe_mediamask
& TULIP_BIT(sc
->tulip_probe_media
))
935 || TULIP_IS_MEDIA_FD(sc
->tulip_probe_media
));
937 #if defined(TULIP_DEBUG)
938 printf(TULIP_PRINTF_FMT
": %s: probing %s\n", TULIP_PRINTF_ARGS
,
939 event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
? "txprobe failed" : "timeout",
940 tulip_mediums
[sc
->tulip_probe_media
]);
942 sc
->tulip_probe_timeout
= TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
) ? 2500 : 1000;
943 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
944 sc
->tulip_probe
.probe_txprobes
= 0;
946 tulip_media_set(sc
, sc
->tulip_probe_media
);
947 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
952 * If this is hanging off a phy, we know are doing NWAY and we have
953 * forced the phy to a specific speed. Wait for link up before
954 * before sending a packet.
956 switch (sc
->tulip_mediums
[sc
->tulip_probe_media
]->mi_type
) {
957 case TULIP_MEDIAINFO_MII
: {
958 if (sc
->tulip_probe_media
!= tulip_mii_phy_readspecific(sc
))
962 case TULIP_MEDIAINFO_SIA
: {
963 if (TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
)) {
964 if (TULIP_CSR_READ(sc
, csr_sia_status
) & TULIP_SIASTS_LINKFAIL
)
966 tulip_linkup(sc
, sc
->tulip_probe_media
);
968 if (sc
->tulip_features
& TULIP_HAVE_MII
)
975 case TULIP_MEDIAINFO_RESET
:
976 case TULIP_MEDIAINFO_SYM
:
977 case TULIP_MEDIAINFO_NONE
:
978 case TULIP_MEDIAINFO_GPR
: {
983 * Try to send a packet.
990 tulip_softc_t
* const sc
)
992 if (sc
->tulip_features
& TULIP_HAVE_GPR
) {
993 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_PINSET
|sc
->tulip_gpinit
);
995 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_gpdata
);
998 * If this board has no media, just return
1000 if (sc
->tulip_features
& TULIP_HAVE_NOMEDIA
)
1003 if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
) {
1004 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
1005 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, TULIP_MEDIAPOLL_START
);
1007 tulip_media_set(sc
, sc
->tulip_media
);
1012 tulip_21040_mediainfo_init(
1013 tulip_softc_t
* const sc
,
1014 tulip_media_t media
)
1016 sc
->tulip_cmdmode
|= TULIP_CMD_CAPTREFFCT
|TULIP_CMD_THRSHLD160
1017 |TULIP_CMD_BACKOFFCTR
;
1018 sc
->tulip_if
.if_baudrate
= 10000000;
1020 if (media
== TULIP_MEDIA_10BASET
|| media
== TULIP_MEDIA_UNKNOWN
) {
1021 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[0], 21040, 10BASET
);
1022 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[1], 21040, 10BASET_FD
);
1023 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
1026 if (media
== TULIP_MEDIA_AUIBNC
|| media
== TULIP_MEDIA_UNKNOWN
) {
1027 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[2], 21040, AUIBNC
);
1030 if (media
== TULIP_MEDIA_UNKNOWN
) {
1031 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[3], 21040, EXTSIA
);
1036 tulip_21040_media_probe(
1037 tulip_softc_t
* const sc
)
1039 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_UNKNOWN
);
1044 tulip_21040_10baset_only_media_probe(
1045 tulip_softc_t
* const sc
)
1047 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_10BASET
);
1048 tulip_media_set(sc
, TULIP_MEDIA_10BASET
);
1049 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
1053 tulip_21040_10baset_only_media_select(
1054 tulip_softc_t
* const sc
)
1056 sc
->tulip_flags
|= TULIP_LINKUP
;
1057 if (sc
->tulip_media
== TULIP_MEDIA_10BASET_FD
) {
1058 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
1059 sc
->tulip_flags
&= ~TULIP_SQETEST
;
1061 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
1062 sc
->tulip_flags
|= TULIP_SQETEST
;
1064 tulip_media_set(sc
, sc
->tulip_media
);
1068 tulip_21040_auibnc_only_media_probe(
1069 tulip_softc_t
* const sc
)
1071 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_AUIBNC
);
1072 sc
->tulip_flags
|= TULIP_SQETEST
|TULIP_LINKUP
;
1073 tulip_media_set(sc
, TULIP_MEDIA_AUIBNC
);
1074 sc
->tulip_media
= TULIP_MEDIA_AUIBNC
;
1078 tulip_21040_auibnc_only_media_select(
1079 tulip_softc_t
* const sc
)
1081 tulip_media_set(sc
, TULIP_MEDIA_AUIBNC
);
1082 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
1085 static const tulip_boardsw_t tulip_21040_boardsw
= {
1086 TULIP_21040_GENERIC
,
1087 tulip_21040_media_probe
,
1093 static const tulip_boardsw_t tulip_21040_10baset_only_boardsw
= {
1094 TULIP_21040_GENERIC
,
1095 tulip_21040_10baset_only_media_probe
,
1096 tulip_21040_10baset_only_media_select
,
1101 static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw
= {
1102 TULIP_21040_GENERIC
,
1103 tulip_21040_auibnc_only_media_probe
,
1104 tulip_21040_auibnc_only_media_select
,
1110 tulip_21041_mediainfo_init(
1111 tulip_softc_t
* const sc
)
1113 tulip_media_info_t
* const mi
= sc
->tulip_mediainfo
;
1116 if (sc
->tulip_revinfo
>= 0x20) {
1117 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041P2
, 10BASET
);
1118 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041P2
, 10BASET_FD
);
1119 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041P2
, AUI
);
1120 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041P2
, BNC
);
1124 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041, 10BASET
);
1125 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041, 10BASET_FD
);
1126 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[2], 21041, AUI
);
1127 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[3], 21041, BNC
);
1131 tulip_21041_media_probe(
1132 tulip_softc_t
* const sc
)
1134 sc
->tulip_if
.if_baudrate
= 10000000;
1135 sc
->tulip_cmdmode
|= TULIP_CMD_CAPTREFFCT
|TULIP_CMD_ENHCAPTEFFCT
1136 |TULIP_CMD_THRSHLD160
|TULIP_CMD_BACKOFFCTR
;
1137 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
1138 tulip_21041_mediainfo_init(sc
);
1142 tulip_21041_media_poll(
1143 tulip_softc_t
* const sc
,
1144 const tulip_mediapoll_event_t event
)
1146 u_int32_t sia_status
;
1148 #if defined(TULIP_DEBUG)
1149 sc
->tulip_dbg
.dbg_events
[event
]++;
1152 if (event
== TULIP_MEDIAPOLL_LINKFAIL
) {
1153 if (sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
1154 || !TULIP_DO_AUTOSENSE(sc
))
1156 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
1157 tulip_reset(sc
); /* start probe */
1162 * If we've been been asked to start a poll or link change interrupt
1163 * restart the probe (and reset the tulip to a known state).
1165 if (event
== TULIP_MEDIAPOLL_START
) {
1166 sc
->tulip_if
.if_flags
|= IFF_OACTIVE
;
1167 sc
->tulip_cmdmode
&= ~(TULIP_CMD_FULLDUPLEX
|TULIP_CMD_RXRUN
);
1169 if (sc
->tulip_revinfo
>= 0x20) {
1170 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
1171 sc
->tulip_flags
|= TULIP_DIDNWAY
;
1174 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
1175 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1176 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
1177 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_10BASET_TIMEOUT
;
1178 tulip_media_set(sc
, TULIP_MEDIA_10BASET
);
1183 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
)
1186 if (event
== TULIP_MEDIAPOLL_TXPROBE_OK
) {
1187 #if defined(TULIP_DEBUG)
1188 sc
->tulip_dbg
.dbg_txprobes_ok
[sc
->tulip_probe_media
]++;
1190 tulip_linkup(sc
, sc
->tulip_probe_media
);
1194 sia_status
= TULIP_CSR_READ(sc
, csr_sia_status
);
1195 TULIP_CSR_WRITE(sc
, csr_sia_status
, sia_status
);
1196 if ((sia_status
& TULIP_SIASTS_LINKFAIL
) == 0) {
1197 if (sc
->tulip_revinfo
>= 0x20) {
1198 if (sia_status
& (PHYSTS_10BASET_FD
<< (16 - 6)))
1199 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET_FD
;
1202 * If the link has passed LinkPass, 10baseT is the
1203 * proper media to use.
1205 tulip_linkup(sc
, sc
->tulip_probe_media
);
1210 * wait for up to 2.4 seconds for the link to reach pass state.
1211 * Only then start scanning the other media for activity.
1212 * choose media with receive activity over those without.
1214 if (sc
->tulip_probe_media
== TULIP_MEDIA_10BASET
) {
1215 if (event
!= TULIP_MEDIAPOLL_TIMER
)
1217 if (sc
->tulip_probe_timeout
> 0
1218 && (sia_status
& TULIP_SIASTS_OTHERRXACTIVITY
) == 0) {
1222 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
1223 sc
->tulip_flags
|= TULIP_WANTRXACT
;
1224 if (sia_status
& TULIP_SIASTS_OTHERRXACTIVITY
) {
1225 sc
->tulip_probe_media
= TULIP_MEDIA_BNC
;
1227 sc
->tulip_probe_media
= TULIP_MEDIA_AUI
;
1229 tulip_media_set(sc
, sc
->tulip_probe_media
);
1235 * If we failed, clear the txprobe active flag.
1237 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
)
1238 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
1241 if (event
== TULIP_MEDIAPOLL_TIMER
) {
1243 * If we've received something, then that's our link!
1245 if (sc
->tulip_flags
& TULIP_RXACT
) {
1246 tulip_linkup(sc
, sc
->tulip_probe_media
);
1250 * if no txprobe active
1252 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0
1253 && ((sc
->tulip_flags
& TULIP_WANTRXACT
) == 0
1254 || (sia_status
& TULIP_SIASTS_RXACTIVITY
))) {
1255 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
1261 * Take 2 passes through before deciding to not
1262 * wait for receive activity. Then take another
1263 * two passes before spitting out a warning.
1265 if (sc
->tulip_probe_timeout
<= 0) {
1266 if (sc
->tulip_flags
& TULIP_WANTRXACT
) {
1267 sc
->tulip_flags
&= ~TULIP_WANTRXACT
;
1268 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
1270 printf(TULIP_PRINTF_FMT
": autosense failed: cable problem?\n",
1272 if ((sc
->tulip_if
.if_flags
& IFF_UP
) == 0) {
1273 sc
->tulip_if
.if_flags
&= ~IFF_RUNNING
;
1274 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
1282 * Since this media failed to probe, try the other one.
1284 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
1285 if (sc
->tulip_probe_media
== TULIP_MEDIA_AUI
) {
1286 sc
->tulip_probe_media
= TULIP_MEDIA_BNC
;
1288 sc
->tulip_probe_media
= TULIP_MEDIA_AUI
;
1290 tulip_media_set(sc
, sc
->tulip_probe_media
);
1291 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
1295 static const tulip_boardsw_t tulip_21041_boardsw
= {
1296 TULIP_21041_GENERIC
,
1297 tulip_21041_media_probe
,
1299 tulip_21041_media_poll
,
1303 static const tulip_phy_attr_t tulip_mii_phy_attrlist
[] = {
1304 { 0x20005c00, 0, /* 08-00-17 */
1306 { 0x19, 0x0040, 0x0040 }, /* 10TX */
1307 { 0x19, 0x0040, 0x0000 }, /* 100TX */
1309 #if defined(TULIP_DEBUG)
1313 { 0x0281F400, 0, /* 00-A0-7D */
1315 { 0x12, 0x0010, 0x0000 }, /* 10T */
1316 { 0, 0, 0 }, /* 100TX */
1317 { 0x12, 0x0010, 0x0010 }, /* 100T4 */
1318 { 0x12, 0x0008, 0x0008 }, /* FULL_DUPLEX */
1320 #if defined(TULIP_DEBUG)
1324 { 0x0281F400, 3, /* 00-A0-7D */
1326 { 0x12, 0x0080, 0x0000 }, /* 10T */
1327 { 0x12, 0x0080, 0x0080 }, /* 100TX */
1328 { 0, 0, 0 }, /* 100T4 */
1329 { 0x12, 0x0040, 0x0040 }, /* FULL_DUPLEX */
1331 #if defined(TULIP_DEBUG)
1336 { 0x0015F420, 0, /* 00-A0-7D */
1338 { 0x12, 0x0010, 0x0000 }, /* 10T */
1339 { 0, 0, 0 }, /* 100TX */
1340 { 0x12, 0x0010, 0x0010 }, /* 100T4 */
1341 { 0x12, 0x0008, 0x0008 }, /* FULL_DUPLEX */
1343 #if defined(TULIP_DEBUG)
1348 { 0x0281F400, 0, /* 00-A0-BE */
1350 { 0x11, 0x8000, 0x0000 }, /* 10T */
1351 { 0x11, 0x8000, 0x8000 }, /* 100TX */
1352 { 0, 0, 0 }, /* 100T4 */
1353 { 0x11, 0x4000, 0x4000 }, /* FULL_DUPLEX */
1355 #if defined(TULIP_DEBUG)
1359 { 0, 0, {{ 0, 0, 0},},
1360 #if defined(TULIP_DEBUG)
1366 static tulip_media_t
1367 tulip_mii_phy_readspecific(
1368 tulip_softc_t
* const sc
)
1370 const tulip_phy_attr_t
*attr
;
1374 static const tulip_media_t table
[] = {
1375 TULIP_MEDIA_UNKNOWN
,
1376 TULIP_MEDIA_10BASET
,
1377 TULIP_MEDIA_100BASETX
,
1378 TULIP_MEDIA_100BASET4
,
1379 TULIP_MEDIA_UNKNOWN
,
1380 TULIP_MEDIA_10BASET_FD
,
1381 TULIP_MEDIA_100BASETX_FD
,
1386 * Don't read phy specific registers if link is not up.
1388 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
)
1389 | tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
);
1390 if ((data
& (PHYSTS_LINK_UP
|PHYSTS_EXTENDED_REGS
)) != (PHYSTS_LINK_UP
|PHYSTS_EXTENDED_REGS
))
1391 return TULIP_MEDIA_UNKNOWN
;
1393 id
= (tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_IDLOW
) << 16) |
1394 tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_IDHIGH
);
1395 for (attr
= tulip_mii_phy_attrlist
;; attr
++) {
1396 if (attr
->attr_id
== 0)
1397 return TULIP_MEDIA_UNKNOWN
;
1398 if ((id
& ~0x0F) == attr
->attr_id
)
1402 if (attr
->attr_modes
[PHY_MODE_100TX
].pm_regno
) {
1403 const tulip_phy_modedata_t
* const pm
= &attr
->attr_modes
[PHY_MODE_100TX
];
1404 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1405 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1408 if (idx
== 0 && attr
->attr_modes
[PHY_MODE_100T4
].pm_regno
) {
1409 const tulip_phy_modedata_t
* const pm
= &attr
->attr_modes
[PHY_MODE_100T4
];
1410 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1411 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1414 if (idx
== 0 && attr
->attr_modes
[PHY_MODE_10T
].pm_regno
) {
1415 const tulip_phy_modedata_t
* const pm
= &attr
->attr_modes
[PHY_MODE_10T
];
1416 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1417 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1420 if (idx
!= 0 && attr
->attr_modes
[PHY_MODE_FULLDUPLEX
].pm_regno
) {
1421 const tulip_phy_modedata_t
* const pm
= &attr
->attr_modes
[PHY_MODE_FULLDUPLEX
];
1422 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1423 idx
+= ((data
& pm
->pm_mask
) == pm
->pm_value
? 4 : 0);
1429 tulip_mii_get_phyaddr(
1430 tulip_softc_t
* const sc
,
1435 for (phyaddr
= 1; phyaddr
< 32; phyaddr
++) {
1436 unsigned status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1437 if (status
== 0 || status
== 0xFFFF || status
< PHYSTS_10BASET
)
1444 unsigned status
= tulip_mii_readreg(sc
, 0, PHYREG_STATUS
);
1445 if (status
== 0 || status
== 0xFFFF || status
< PHYSTS_10BASET
)
1446 return TULIP_MII_NOPHY
;
1449 return TULIP_MII_NOPHY
;
1453 tulip_mii_map_abilities(
1454 tulip_softc_t
* const sc
,
1457 sc
->tulip_abilities
= abilities
;
1458 if (abilities
& PHYSTS_100BASETX_FD
) {
1459 sc
->tulip_probe_media
= TULIP_MEDIA_100BASETX_FD
;
1460 } else if (abilities
& PHYSTS_100BASET4
) {
1461 sc
->tulip_probe_media
= TULIP_MEDIA_100BASET4
;
1462 } else if (abilities
& PHYSTS_100BASETX
) {
1463 sc
->tulip_probe_media
= TULIP_MEDIA_100BASETX
;
1464 } else if (abilities
& PHYSTS_10BASET_FD
) {
1465 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET_FD
;
1466 } else if (abilities
& PHYSTS_10BASET
) {
1467 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
1469 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1472 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
1477 tulip_mii_autonegotiate(
1478 tulip_softc_t
* const sc
,
1479 const unsigned phyaddr
)
1481 switch (sc
->tulip_probe_state
) {
1482 case TULIP_PROBE_MEDIATEST
:
1483 case TULIP_PROBE_INACTIVE
: {
1484 sc
->tulip_flags
|= TULIP_DIDNWAY
;
1485 tulip_mii_writereg(sc
, phyaddr
, PHYREG_CONTROL
, PHYCTL_RESET
);
1486 sc
->tulip_probe_timeout
= 3000;
1487 sc
->tulip_intrmask
|= TULIP_STS_ABNRMLINTR
|TULIP_STS_NORMALINTR
;
1488 sc
->tulip_probe_state
= TULIP_PROBE_PHYRESET
;
1491 case TULIP_PROBE_PHYRESET
: {
1493 u_int32_t data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_CONTROL
);
1494 if (data
& PHYCTL_RESET
) {
1495 if (sc
->tulip_probe_timeout
> 0) {
1499 printf(TULIP_PRINTF_FMT
"(phy%d): error: reset of PHY never completed!\n",
1500 TULIP_PRINTF_ARGS
, phyaddr
);
1501 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
1502 sc
->tulip_probe_state
= TULIP_PROBE_FAILED
;
1503 sc
->tulip_if
.if_flags
&= ~(IFF_UP
|IFF_RUNNING
);
1506 status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
)
1507 | tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1508 if ((status
& PHYSTS_CAN_AUTONEG
) == 0) {
1509 #if defined(TULIP_DEBUG)
1510 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation disabled\n",
1511 TULIP_PRINTF_ARGS
, phyaddr
);
1513 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1514 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1517 if (tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ADVERTISEMENT
) != ((status
>> 6) | 0x01))
1518 tulip_mii_writereg(sc
, phyaddr
, PHYREG_AUTONEG_ADVERTISEMENT
, (status
>> 6) | 0x01);
1519 tulip_mii_writereg(sc
, phyaddr
, PHYREG_CONTROL
, data
|PHYCTL_AUTONEG_RESTART
|PHYCTL_AUTONEG_ENABLE
);
1520 data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_CONTROL
);
1521 #if defined(TULIP_DEBUG)
1522 if ((data
& PHYCTL_AUTONEG_ENABLE
) == 0)
1523 loudprintf(TULIP_PRINTF_FMT
"(phy%d): oops: enable autonegotiation failed: 0x%04x\n",
1524 TULIP_PRINTF_ARGS
, phyaddr
, data
);
1526 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation restarted: 0x%04x (ad=0x%04x)\n",
1527 TULIP_PRINTF_ARGS
, phyaddr
, data
,
1528 tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ADVERTISEMENT
));
1529 sc
->tulip_dbg
.dbg_nway_starts
++;
1531 sc
->tulip_probe_state
= TULIP_PROBE_PHYAUTONEG
;
1532 sc
->tulip_probe_timeout
= 3000;
1535 case TULIP_PROBE_PHYAUTONEG
: {
1536 u_int32_t status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
)
1537 | tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1539 if ((status
& PHYSTS_AUTONEG_DONE
) == 0) {
1540 if (sc
->tulip_probe_timeout
> 0) {
1544 #if defined(TULIP_DEBUG)
1545 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n",
1546 TULIP_PRINTF_ARGS
, phyaddr
, status
,
1547 tulip_mii_readreg(sc
, phyaddr
, PHYREG_CONTROL
));
1549 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1550 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1553 data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ABILITIES
)
1554 | tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ABILITIES
);
1555 #if defined(TULIP_DEBUG)
1556 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation complete: 0x%04x (sts=0x%04x)\n",
1557 TULIP_PRINTF_ARGS
, phyaddr
, data
, status
);
1559 data
= (data
<< 6) & status
;
1560 if (!tulip_mii_map_abilities(sc
, data
))
1561 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1565 #if defined(DIAGNOSTIC)
1566 panic("tulip_media_poll: botch at line %d", __LINE__
);
1571 #if defined(TULIP_DEBUG)
1572 loudprintf(TULIP_PRINTF_FMT
"(phy%d): autonegotiation failure: state = %d\n",
1573 TULIP_PRINTF_ARGS
, phyaddr
, sc
->tulip_probe_state
);
1574 sc
->tulip_dbg
.dbg_nway_failures
++;
1579 tulip_2114x_media_preset(
1580 tulip_softc_t
* const sc
)
1582 const tulip_media_info_t
*mi
= NULL
;
1583 tulip_media_t media
= sc
->tulip_media
;
1585 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
)
1586 media
= sc
->tulip_media
;
1588 media
= sc
->tulip_probe_media
;
1590 sc
->tulip_cmdmode
&= ~(TULIP_CMD_PORTSELECT
|TULIP_CMD_NOHEARTBEAT
1591 |TULIP_CMD_FULLDUPLEX
|TULIP_CMD_TXTHRSHLDCTL
);
1592 sc
->tulip_flags
&= ~(TULIP_SQETEST
|TULIP_FULLDUPLEX
);
1593 if (media
!= TULIP_MEDIA_UNKNOWN
&& media
!= TULIP_MEDIA_MAX
) {
1594 #if defined(TULIP_DEBUG)
1595 if (media
< TULIP_MEDIA_MAX
&& sc
->tulip_mediums
[media
] != NULL
) {
1597 mi
= sc
->tulip_mediums
[media
];
1598 if (mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
1599 sc
->tulip_cmdmode
|= TULIP_CMD_PORTSELECT
;
1600 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
1601 || mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
1602 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
1603 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
1604 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
1605 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, TULIP_SIACONN_RESET
);
1607 #if defined(TULIP_DEBUG)
1609 printf(TULIP_PRINTF_FMT
": preset: bad media %d!\n",
1610 TULIP_PRINTF_ARGS
, media
);
1615 case TULIP_MEDIA_BNC
:
1616 case TULIP_MEDIA_AUI
:
1617 case TULIP_MEDIA_10BASET
: {
1618 sc
->tulip_cmdmode
|= TULIP_CMD_TXTHRSHLDCTL
;
1619 sc
->tulip_if
.if_baudrate
= 10000000;
1620 sc
->tulip_flags
|= TULIP_SQETEST
;
1623 case TULIP_MEDIA_10BASET_FD
: {
1624 sc
->tulip_flags
|= TULIP_FULLDUPLEX
;
1625 sc
->tulip_cmdmode
|= TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
;
1626 sc
->tulip_if
.if_baudrate
= 10000000;
1629 case TULIP_MEDIA_100BASEFX
:
1630 case TULIP_MEDIA_100BASET4
:
1631 case TULIP_MEDIA_100BASETX
: {
1632 sc
->tulip_cmdmode
|= TULIP_CMD_PORTSELECT
;
1633 sc
->tulip_if
.if_baudrate
= 100000000;
1634 if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
1635 || mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
1636 sc
->tulip_cmdmode
|= TULIP_CMD_NOHEARTBEAT
;
1640 case TULIP_MEDIA_100BASEFX_FD
:
1641 case TULIP_MEDIA_100BASETX_FD
: {
1642 sc
->tulip_flags
|= TULIP_FULLDUPLEX
;
1643 sc
->tulip_cmdmode
|= TULIP_CMD_PORTSELECT
|TULIP_CMD_FULLDUPLEX
;
1644 sc
->tulip_if
.if_baudrate
= 100000000;
1645 if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
1646 || mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
1647 sc
->tulip_cmdmode
|= TULIP_CMD_NOHEARTBEAT
;
1655 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
1659 ********************************************************************
1660 * Start of 21140/21140A support which does not use the MII interface
1664 tulip_null_media_poll(
1665 tulip_softc_t
* const sc
,
1666 tulip_mediapoll_event_t event
)
1668 #if defined(TULIP_DEBUG)
1669 sc
->tulip_dbg
.dbg_events
[event
]++;
1671 #if defined(DIAGNOSTIC)
1672 printf(TULIP_PRINTF_FMT
": botch(media_poll) at line %d\n",
1673 TULIP_PRINTF_ARGS
, __LINE__
);
1678 tulip_21140_mediainit(
1679 tulip_softc_t
* const sc
,
1680 tulip_media_info_t
* const mip
,
1681 tulip_media_t
const media
,
1685 sc
->tulip_mediums
[media
] = mip
;
1686 mip
->mi_type
= TULIP_MEDIAINFO_GPR
;
1687 mip
->mi_cmdmode
= cmdmode
;
1688 mip
->mi_gpdata
= gpdata
;
1692 tulip_21140_evalboard_media_probe(
1693 tulip_softc_t
* const sc
)
1695 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1697 sc
->tulip_gpinit
= TULIP_GP_EB_PINS
;
1698 sc
->tulip_gpdata
= TULIP_GP_EB_INIT
;
1699 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_PINS
);
1700 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_INIT
);
1701 TULIP_CSR_WRITE(sc
, csr_command
,
1702 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1703 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1704 TULIP_CSR_WRITE(sc
, csr_command
,
1705 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1707 if ((TULIP_CSR_READ(sc
, csr_gp
) & TULIP_GP_EB_OK100
) != 0) {
1708 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
1710 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1712 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1714 TULIP_CMD_TXTHRSHLDCTL
);
1715 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1717 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1718 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1720 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1721 |TULIP_CMD_SCRAMBLER
);
1722 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1724 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1725 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1728 static const tulip_boardsw_t tulip_21140_eb_boardsw
= {
1730 tulip_21140_evalboard_media_probe
,
1732 tulip_null_media_poll
,
1733 tulip_2114x_media_preset
,
1737 tulip_21140_accton_media_probe(
1738 tulip_softc_t
* const sc
)
1740 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1743 sc
->tulip_gpinit
= TULIP_GP_EB_PINS
;
1744 sc
->tulip_gpdata
= TULIP_GP_EB_INIT
;
1745 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_PINS
);
1746 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_INIT
);
1747 TULIP_CSR_WRITE(sc
, csr_command
,
1748 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1749 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1750 TULIP_CSR_WRITE(sc
, csr_command
,
1751 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1753 gpdata
= TULIP_CSR_READ(sc
, csr_gp
);
1754 if ((gpdata
& TULIP_GP_EN1207_UTP_INIT
) == 0) {
1755 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
1757 if ((gpdata
& TULIP_GP_EN1207_BNC_INIT
) == 0) {
1758 sc
->tulip_media
= TULIP_MEDIA_BNC
;
1760 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1763 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_BNC
,
1764 TULIP_GP_EN1207_BNC_INIT
,
1765 TULIP_CMD_TXTHRSHLDCTL
);
1766 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1767 TULIP_GP_EN1207_UTP_INIT
,
1768 TULIP_CMD_TXTHRSHLDCTL
);
1769 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1770 TULIP_GP_EN1207_UTP_INIT
,
1771 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1772 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1773 TULIP_GP_EN1207_100_INIT
,
1774 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1775 |TULIP_CMD_SCRAMBLER
);
1776 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1777 TULIP_GP_EN1207_100_INIT
,
1778 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1779 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1782 static const tulip_boardsw_t tulip_21140_accton_boardsw
= {
1784 tulip_21140_accton_media_probe
,
1786 tulip_null_media_poll
,
1787 tulip_2114x_media_preset
,
1791 tulip_21140_smc9332_media_probe(
1792 tulip_softc_t
* const sc
)
1794 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1797 TULIP_CSR_WRITE(sc
, csr_command
, TULIP_CMD_PORTSELECT
|TULIP_CMD_MUSTBEONE
);
1798 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
1799 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
1800 33MHz that comes to two microseconds but wait a
1801 bit longer anyways) */
1802 TULIP_CSR_WRITE(sc
, csr_command
, TULIP_CMD_PORTSELECT
|
1803 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1804 sc
->tulip_gpinit
= TULIP_GP_SMC_9332_PINS
;
1805 sc
->tulip_gpdata
= TULIP_GP_SMC_9332_INIT
;
1806 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_SMC_9332_PINS
|TULIP_GP_PINSET
);
1807 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_SMC_9332_INIT
);
1809 for (idx
= 1000; idx
> 0; idx
--) {
1810 u_int32_t csr
= TULIP_CSR_READ(sc
, csr_gp
);
1811 if ((csr
& (TULIP_GP_SMC_9332_OK10
|TULIP_GP_SMC_9332_OK100
)) == (TULIP_GP_SMC_9332_OK10
|TULIP_GP_SMC_9332_OK100
)) {
1814 } else if ((csr
& TULIP_GP_SMC_9332_OK10
) == 0) {
1821 sc
->tulip_media
= cnt
> 100 ? TULIP_MEDIA_100BASETX
: TULIP_MEDIA_10BASET
;
1822 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1823 TULIP_GP_SMC_9332_INIT
,
1824 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1825 |TULIP_CMD_SCRAMBLER
);
1826 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1827 TULIP_GP_SMC_9332_INIT
,
1828 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1829 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1830 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1831 TULIP_GP_SMC_9332_INIT
,
1832 TULIP_CMD_TXTHRSHLDCTL
);
1833 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1834 TULIP_GP_SMC_9332_INIT
,
1835 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1838 static const tulip_boardsw_t tulip_21140_smc9332_boardsw
= {
1839 TULIP_21140_SMC_9332
,
1840 tulip_21140_smc9332_media_probe
,
1842 tulip_null_media_poll
,
1843 tulip_2114x_media_preset
,
1847 tulip_21140_cogent_em100_media_probe(
1848 tulip_softc_t
* const sc
)
1850 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1851 u_int32_t cmdmode
= TULIP_CSR_READ(sc
, csr_command
);
1853 sc
->tulip_gpinit
= TULIP_GP_EM100_PINS
;
1854 sc
->tulip_gpdata
= TULIP_GP_EM100_INIT
;
1855 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EM100_PINS
);
1856 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EM100_INIT
);
1858 cmdmode
= TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
|TULIP_CMD_MUSTBEONE
;
1859 cmdmode
&= ~(TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_SCRAMBLER
);
1860 if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100FX_ID
) {
1861 TULIP_CSR_WRITE(sc
, csr_command
, cmdmode
);
1862 sc
->tulip_media
= TULIP_MEDIA_100BASEFX
;
1864 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASEFX
,
1865 TULIP_GP_EM100_INIT
,
1866 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
);
1867 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASEFX_FD
,
1868 TULIP_GP_EM100_INIT
,
1869 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1870 |TULIP_CMD_FULLDUPLEX
);
1872 TULIP_CSR_WRITE(sc
, csr_command
, cmdmode
|TULIP_CMD_SCRAMBLER
);
1873 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1874 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1875 TULIP_GP_EM100_INIT
,
1876 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1877 |TULIP_CMD_SCRAMBLER
);
1878 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1879 TULIP_GP_EM100_INIT
,
1880 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1881 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1885 static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw
= {
1886 TULIP_21140_COGENT_EM100
,
1887 tulip_21140_cogent_em100_media_probe
,
1889 tulip_null_media_poll
,
1890 tulip_2114x_media_preset
1894 tulip_21140_znyx_zx34x_media_probe(
1895 tulip_softc_t
* const sc
)
1897 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1898 int cnt10
= 0, cnt100
= 0, idx
;
1900 sc
->tulip_gpinit
= TULIP_GP_ZX34X_PINS
;
1901 sc
->tulip_gpdata
= TULIP_GP_ZX34X_INIT
;
1902 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ZX34X_PINS
);
1903 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ZX34X_INIT
);
1904 TULIP_CSR_WRITE(sc
, csr_command
,
1905 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1906 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1907 TULIP_CSR_WRITE(sc
, csr_command
,
1908 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1911 for (idx
= 1000; idx
> 0; idx
--) {
1912 u_int32_t csr
= TULIP_CSR_READ(sc
, csr_gp
);
1913 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
)) {
1916 } else if ((csr
& TULIP_GP_ZX34X_LNKFAIL
) == 0) {
1925 sc
->tulip_media
= cnt100
> 100 ? TULIP_MEDIA_100BASETX
: TULIP_MEDIA_10BASET
;
1926 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1927 TULIP_GP_ZX34X_INIT
,
1928 TULIP_CMD_TXTHRSHLDCTL
);
1929 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1930 TULIP_GP_ZX34X_INIT
,
1931 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1932 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1933 TULIP_GP_ZX34X_INIT
,
1934 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1935 |TULIP_CMD_SCRAMBLER
);
1936 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1937 TULIP_GP_ZX34X_INIT
,
1938 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1939 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1942 static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw
= {
1943 TULIP_21140_ZNYX_ZX34X
,
1944 tulip_21140_znyx_zx34x_media_probe
,
1946 tulip_null_media_poll
,
1947 tulip_2114x_media_preset
,
1951 tulip_2114x_media_probe(
1952 tulip_softc_t
* const sc
)
1954 sc
->tulip_cmdmode
|= TULIP_CMD_MUSTBEONE
1955 |TULIP_CMD_BACKOFFCTR
|TULIP_CMD_THRSHLD72
;
1958 static const tulip_boardsw_t tulip_2114x_isv_boardsw
= {
1960 tulip_2114x_media_probe
,
1963 tulip_2114x_media_preset
,
1967 * ******** END of chip-specific handlers. ***********
1971 * Code the read the SROM and MII bit streams (I2C)
1975 tulip_softc_t
* const sc
)
1978 for (idx
= (300 / 33) + 1; idx
> 0; idx
--)
1979 (void) TULIP_CSR_READ(sc
, csr_busmode
);
1982 #define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
1986 tulip_softc_t
* const sc
)
1990 csr
= SROMSEL
; EMIT
;
1991 csr
= SROMSEL
| SROMRD
; EMIT
;
1992 csr
^= SROMCS
; EMIT
;
1993 csr
^= SROMCLKON
; EMIT
;
1996 * Write 25 cycles of 0 which will force the SROM to be idle.
1998 for (bit
= 3 + SROM_BITWIDTH
+ 16; bit
> 0; bit
--) {
1999 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
2000 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
2002 csr
^= SROMCLKOFF
; EMIT
;
2003 csr
^= SROMCS
; EMIT
;
2010 tulip_softc_t
* const sc
)
2013 const unsigned bitwidth
= SROM_BITWIDTH
;
2014 const unsigned cmdmask
= (SROMCMD_RD
<< bitwidth
);
2015 const unsigned msb
= 1 << (bitwidth
+ 3 - 1);
2016 unsigned lastidx
= (1 << bitwidth
) - 1;
2018 tulip_srom_idle(sc
);
2020 for (idx
= 0; idx
<= lastidx
; idx
++) {
2021 unsigned lastbit
, data
, bits
, bit
, csr
;
2022 csr
= SROMSEL
; EMIT
;
2023 csr
= SROMSEL
| SROMRD
; EMIT
;
2024 csr
^= SROMCSON
; EMIT
;
2025 csr
^= SROMCLKON
; EMIT
;
2028 for (bits
= idx
|cmdmask
, bit
= bitwidth
+ 3; bit
> 0; bit
--, bits
<<= 1) {
2029 const unsigned thisbit
= bits
& msb
;
2030 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
2031 if (thisbit
!= lastbit
) {
2032 csr
^= SROMDOUT
; EMIT
; /* clock low; invert data */
2036 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
2039 csr
^= SROMCLKOFF
; EMIT
;
2041 for (data
= 0, bits
= 0; bits
< 16; bits
++) {
2043 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
2044 data
|= TULIP_CSR_READ(sc
, csr_srom_mii
) & SROMDIN
? 1 : 0;
2045 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
2047 sc
->tulip_rombuf
[idx
*2] = data
& 0xFF;
2048 sc
->tulip_rombuf
[idx
*2+1] = data
>> 8;
2049 csr
= SROMSEL
| SROMRD
; EMIT
;
2052 tulip_srom_idle(sc
);
2055 #define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0)
2058 tulip_mii_writebits(
2059 tulip_softc_t
* const sc
,
2063 unsigned msb
= 1 << (bits
- 1);
2064 unsigned csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
2065 unsigned lastbit
= (csr
& MII_DOUT
) ? msb
: 0;
2067 csr
|= MII_WR
; MII_EMIT
; /* clock low; assert write */
2069 for (; bits
> 0; bits
--, data
<<= 1) {
2070 const unsigned thisbit
= data
& msb
;
2071 if (thisbit
!= lastbit
) {
2072 csr
^= MII_DOUT
; MII_EMIT
; /* clock low; invert data */
2074 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
2076 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
2081 tulip_mii_turnaround(
2082 tulip_softc_t
* const sc
,
2085 unsigned csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
2087 if (cmd
== MII_WRCMD
) {
2088 csr
|= MII_DOUT
; MII_EMIT
; /* clock low; change data */
2089 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
2090 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
2091 csr
^= MII_DOUT
; MII_EMIT
; /* clock low; change data */
2093 csr
|= MII_RD
; MII_EMIT
; /* clock low; switch to read */
2095 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
2096 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
2101 tulip_softc_t
* const sc
)
2104 unsigned csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
2107 for (idx
= 0, data
= 0; idx
< 16; idx
++) {
2108 data
<<= 1; /* this is NOOP on the first pass through */
2109 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
2110 if (TULIP_CSR_READ(sc
, csr_srom_mii
) & MII_DIN
)
2112 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
2114 csr
^= MII_RD
; MII_EMIT
; /* clock low; turn off read */
2121 tulip_softc_t
* const sc
,
2125 unsigned csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
2128 csr
&= ~(MII_RD
|MII_CLK
); MII_EMIT
;
2129 tulip_mii_writebits(sc
, MII_PREAMBLE
, 32);
2130 tulip_mii_writebits(sc
, MII_RDCMD
, 8);
2131 tulip_mii_writebits(sc
, devaddr
, 5);
2132 tulip_mii_writebits(sc
, regno
, 5);
2133 tulip_mii_turnaround(sc
, MII_RDCMD
);
2135 data
= tulip_mii_readbits(sc
);
2136 #if defined(TULIP_DEBUG)
2137 sc
->tulip_dbg
.dbg_phyregs
[regno
][0] = data
;
2138 sc
->tulip_dbg
.dbg_phyregs
[regno
][1]++;
2145 tulip_softc_t
* const sc
,
2150 unsigned csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
2151 csr
&= ~(MII_RD
|MII_CLK
); MII_EMIT
;
2152 tulip_mii_writebits(sc
, MII_PREAMBLE
, 32);
2153 tulip_mii_writebits(sc
, MII_WRCMD
, 8);
2154 tulip_mii_writebits(sc
, devaddr
, 5);
2155 tulip_mii_writebits(sc
, regno
, 5);
2156 tulip_mii_turnaround(sc
, MII_WRCMD
);
2157 tulip_mii_writebits(sc
, data
, 16);
2158 #if defined(TULIP_DEBUG)
2159 sc
->tulip_dbg
.dbg_phyregs
[regno
][2] = data
;
2160 sc
->tulip_dbg
.dbg_phyregs
[regno
][3]++;
2164 #define tulip_mchash(mca) (tulip_crc32(mca, 6) & 0x1FF)
2165 #define tulip_srom_crcok(databuf) ( \
2166 ((tulip_crc32(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
2167 ((databuf)[126] | ((databuf)[127] << 8)))
2171 const unsigned char *databuf
,
2174 u_int idx
, crc
= 0xFFFFFFFFUL
;
2175 static const u_int crctab
[] = {
2176 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
2177 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
2178 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
2179 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
2182 for (idx
= 0; idx
< datalen
; idx
++) {
2184 crc
= (crc
>> 4) ^ crctab
[crc
& 0xf];
2185 crc
= (crc
>> 4) ^ crctab
[crc
& 0xf];
2191 tulip_identify_dec_nic(
2192 tulip_softc_t
* const sc
)
2194 strlcpy(sc
->tulip_boardid
, "DEC ", sizeof(sc
->tulip_boardid
));
2196 if (sc
->tulip_chipid
<= TULIP_DE425
)
2198 if (memcmp(sc
->tulip_rombuf
+ 29, "DE500", 5) == 0
2199 || memcmp(sc
->tulip_rombuf
+ 29, "DE450", 5) == 0) {
2200 memcpy(&sc
->tulip_boardid
[D0
], sc
->tulip_rombuf
+ 29, 8);
2201 sc
->tulip_boardid
[D0
+8] = ' ';
2207 tulip_identify_znyx_nic(
2208 tulip_softc_t
* const sc
)
2211 strlcpy(sc
->tulip_boardid
, "ZNYX ZX3XX ", sizeof(sc
->tulip_boardid
));
2212 if (sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
) {
2214 sc
->tulip_boardid
[8] = '4';
2215 znyx_ptr
= sc
->tulip_rombuf
[124] + 256 * sc
->tulip_rombuf
[125];
2216 if (znyx_ptr
< 26 || znyx_ptr
> 116) {
2217 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
2220 /* ZX344 = 0010 .. 0013FF
2222 if (sc
->tulip_rombuf
[znyx_ptr
] == 0x4A
2223 && sc
->tulip_rombuf
[znyx_ptr
+ 1] == 0x52
2224 && sc
->tulip_rombuf
[znyx_ptr
+ 2] == 0x01) {
2225 id
= sc
->tulip_rombuf
[znyx_ptr
+ 5] + 256 * sc
->tulip_rombuf
[znyx_ptr
+ 4];
2226 if ((id
>> 8) == (TULIP_ZNYX_ID_ZX342
>> 8)) {
2227 sc
->tulip_boardid
[9] = '2';
2228 if (id
== TULIP_ZNYX_ID_ZX342B
) {
2229 sc
->tulip_boardid
[10] = 'B';
2230 sc
->tulip_boardid
[11] = ' ';
2232 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
2233 } else if (id
== TULIP_ZNYX_ID_ZX344
) {
2234 sc
->tulip_boardid
[10] = '4';
2235 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
2236 } else if (id
== TULIP_ZNYX_ID_ZX345
) {
2237 sc
->tulip_boardid
[9] = (sc
->tulip_rombuf
[19] > 1) ? '8' : '5';
2238 } else if (id
== TULIP_ZNYX_ID_ZX346
) {
2239 sc
->tulip_boardid
[9] = '6';
2240 } else if (id
== TULIP_ZNYX_ID_ZX351
) {
2241 sc
->tulip_boardid
[8] = '5';
2242 sc
->tulip_boardid
[9] = '1';
2247 * Assume it's a ZX342...
2249 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
2253 sc
->tulip_boardid
[8] = '1';
2254 if (sc
->tulip_chipid
== TULIP_21041
) {
2255 sc
->tulip_boardid
[10] = '1';
2258 if (sc
->tulip_rombuf
[32] == 0x4A && sc
->tulip_rombuf
[33] == 0x52) {
2259 id
= sc
->tulip_rombuf
[37] + 256 * sc
->tulip_rombuf
[36];
2260 if (id
== TULIP_ZNYX_ID_ZX312T
) {
2261 sc
->tulip_boardid
[9] = '2';
2262 sc
->tulip_boardid
[10] = 'T';
2263 sc
->tulip_boardid
[11] = ' ';
2264 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
2265 } else if (id
== TULIP_ZNYX_ID_ZX314_INTA
) {
2266 sc
->tulip_boardid
[9] = '4';
2267 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
2268 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
2269 } else if (id
== TULIP_ZNYX_ID_ZX314
) {
2270 sc
->tulip_boardid
[9] = '4';
2271 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
2272 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
2273 } else if (id
== TULIP_ZNYX_ID_ZX315_INTA
) {
2274 sc
->tulip_boardid
[9] = '5';
2275 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
2276 } else if (id
== TULIP_ZNYX_ID_ZX315
) {
2277 sc
->tulip_boardid
[9] = '5';
2278 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
2284 if ((sc
->tulip_enaddr
[3] & ~3) == 0xF0 && (sc
->tulip_enaddr
[5] & 3) == 0) {
2285 sc
->tulip_boardid
[9] = '4';
2286 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
2287 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
2288 } else if ((sc
->tulip_enaddr
[3] & ~3) == 0xF4 && (sc
->tulip_enaddr
[5] & 1) == 0) {
2289 sc
->tulip_boardid
[9] = '5';
2290 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2291 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
2292 } else if ((sc
->tulip_enaddr
[3] & ~3) == 0xEC) {
2293 sc
->tulip_boardid
[9] = '2';
2294 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2300 tulip_identify_smc_nic(
2301 tulip_softc_t
* const sc
)
2303 u_int32_t id1
, id2
, ei
;
2304 int auibnc
= 0, utp
= 0;
2307 strlcpy(sc
->tulip_boardid
, "SMC ", sizeof(sc
->tulip_boardid
));
2308 if (sc
->tulip_chipid
== TULIP_21041
)
2310 if (sc
->tulip_chipid
!= TULIP_21040
) {
2311 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
) {
2312 strlcat(sc
->tulip_boardid
, "9332DST ", sizeof(sc
->tulip_boardid
));
2313 sc
->tulip_boardsw
= &tulip_21140_smc9332_boardsw
;
2314 } else if (sc
->tulip_features
& (TULIP_HAVE_BASEROM
|TULIP_HAVE_SLAVEDROM
)) {
2315 strlcat(sc
->tulip_boardid
, "9334BDT ", sizeof(sc
->tulip_boardid
));
2317 strlcat(sc
->tulip_boardid
, "9332BDT ", sizeof(sc
->tulip_boardid
));
2321 id1
= sc
->tulip_rombuf
[0x60] | (sc
->tulip_rombuf
[0x61] << 8);
2322 id2
= sc
->tulip_rombuf
[0x62] | (sc
->tulip_rombuf
[0x63] << 8);
2323 ei
= sc
->tulip_rombuf
[0x66] | (sc
->tulip_rombuf
[0x67] << 8);
2325 strlcat(sc
->tulip_boardid
, "8432", sizeof(sc
->tulip_boardid
));
2326 cp
= &sc
->tulip_boardid
[8];
2328 *cp
++ = 'B', auibnc
= 1;
2329 if ((id1
& 0xFF) > 0x32)
2330 *cp
++ = 'T', utp
= 1;
2331 if ((id1
& 0x4000) == 0)
2332 *cp
++ = 'A', auibnc
= 1;
2334 sc
->tulip_boardid
[7] = '4';
2338 *cp
++ = (ei
? '2' : '1');
2343 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
2344 else if (!utp
&& auibnc
)
2345 sc
->tulip_boardsw
= &tulip_21040_auibnc_only_boardsw
;
2349 tulip_identify_cogent_nic(
2350 tulip_softc_t
* const sc
)
2352 strlcpy(sc
->tulip_boardid
, "Cogent ", sizeof(sc
->tulip_boardid
));
2353 if (sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
) {
2354 if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100TX_ID
) {
2355 strlcat(sc
->tulip_boardid
, "EM100TX ", sizeof(sc
->tulip_boardid
));
2356 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
2357 #if defined(TULIP_COGENT_EM110TX_ID)
2358 } else if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM110TX_ID
) {
2359 strlcat(sc
->tulip_boardid
, "EM110TX ", sizeof(sc
->tulip_boardid
));
2360 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
2362 } else if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100FX_ID
) {
2363 strlcat(sc
->tulip_boardid
, "EM100FX ", sizeof(sc
->tulip_boardid
));
2364 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
2367 * Magic number (0x24001109U) is the SubVendor (0x2400) and
2368 * SubDevId (0x1109) for the ANA6944TX (EM440TX).
2370 if (*(u_int32_t
*) sc
->tulip_rombuf
== 0x24001109U
2371 && (sc
->tulip_features
& TULIP_HAVE_BASEROM
)) {
2373 * Cogent (Adaptec) is still mapping all INTs to INTA of
2374 * first 21140. Dumb! Dumb!
2376 strlcat(sc
->tulip_boardid
, "EM440TX ", sizeof(sc
->tulip_boardid
));
2377 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
;
2379 } else if (sc
->tulip_chipid
== TULIP_21040
) {
2380 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
2385 tulip_identify_accton_nic(
2386 tulip_softc_t
* const sc
)
2388 strlcpy(sc
->tulip_boardid
, "ACCTON ", sizeof(sc
->tulip_boardid
));
2389 switch (sc
->tulip_chipid
) {
2391 strlcat(sc
->tulip_boardid
, "EN1207 ", sizeof(sc
->tulip_boardid
));
2392 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
)
2393 sc
->tulip_boardsw
= &tulip_21140_accton_boardsw
;
2396 strlcat(sc
->tulip_boardid
, "EN1207TX ", sizeof(sc
->tulip_boardid
));
2397 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
)
2398 sc
->tulip_boardsw
= &tulip_21140_eb_boardsw
;
2401 strlcat(sc
->tulip_boardid
, "EN1203 ", sizeof(sc
->tulip_boardid
));
2402 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2405 strlcat(sc
->tulip_boardid
, "EN1203 ", sizeof(sc
->tulip_boardid
));
2406 sc
->tulip_boardsw
= &tulip_21041_boardsw
;
2409 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2415 tulip_identify_asante_nic(
2416 tulip_softc_t
* const sc
)
2418 strlcpy(sc
->tulip_boardid
, "Asante ", sizeof(sc
->tulip_boardid
));
2419 if ((sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
)
2420 && sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
) {
2421 tulip_media_info_t
*mi
= sc
->tulip_mediainfo
;
2424 * The Asante Fast Ethernet doesn't always ship with a valid
2425 * new format SROM. So if isn't in the new format, we cheat
2426 * set it up as if we had.
2429 sc
->tulip_gpinit
= TULIP_GP_ASANTE_PINS
;
2430 sc
->tulip_gpdata
= 0;
2432 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ASANTE_PINS
|TULIP_GP_PINSET
);
2433 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ASANTE_PHYRESET
);
2435 TULIP_CSR_WRITE(sc
, csr_gp
, 0);
2437 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2438 mi
->mi_gpr_length
= 0;
2439 mi
->mi_gpr_offset
= 0;
2440 mi
->mi_reset_length
= 0;
2441 mi
->mi_reset_offset
= 0;
2443 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2444 for (idx
= 20; idx
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx
--) {
2446 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, 0);
2448 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
) {
2449 printf(TULIP_PRINTF_FMT
": can't find phy 0\n", TULIP_PRINTF_ARGS
);
2453 sc
->tulip_features
|= TULIP_HAVE_MII
;
2454 mi
->mi_capabilities
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
|PHYSTS_100BASETX
|PHYSTS_100BASETX_FD
;
2455 mi
->mi_advertisement
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
|PHYSTS_100BASETX
|PHYSTS_100BASETX_FD
;
2456 mi
->mi_full_duplex
= PHYSTS_10BASET_FD
|PHYSTS_100BASETX_FD
;
2457 mi
->mi_tx_threshold
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
;
2458 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2459 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2460 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2461 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2462 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2463 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2464 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2466 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2471 tulip_identify_compex_nic(
2472 tulip_softc_t
* const sc
)
2474 strlcpy(sc
->tulip_boardid
, "COMPEX ", sizeof(sc
->tulip_boardid
));
2475 if (sc
->tulip_chipid
== TULIP_21140A
) {
2477 tulip_softc_t
*root_sc
= NULL
;
2479 strlcat(sc
->tulip_boardid
, "400TX/PCI ", sizeof(sc
->tulip_boardid
));
2481 * All 4 chips on these boards share an interrupt. This code
2482 * copied from tulip_read_macaddr.
2484 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
;
2485 for (root_unit
= sc
->tulip_unit
- 1; root_unit
>= 0; root_unit
--) {
2486 root_sc
= TULIP_UNIT_TO_SOFTC(root_unit
);
2488 || !(root_sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
))
2493 && root_sc
->tulip_chipid
== sc
->tulip_chipid
2494 && root_sc
->tulip_pci_busno
== sc
->tulip_pci_busno
) {
2495 sc
->tulip_features
|= TULIP_HAVE_SLAVEDINTR
;
2496 sc
->tulip_slaves
= root_sc
->tulip_slaves
;
2497 root_sc
->tulip_slaves
= sc
;
2498 } else if(sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) {
2499 printf("\nCannot find master device for de%d interrupts",
2503 strlcat(sc
->tulip_boardid
, "unknown ", sizeof(sc
->tulip_boardid
));
2505 /* sc->tulip_boardsw = &tulip_21140_eb_boardsw; */
2511 tulip_softc_t
* const sc
)
2513 unsigned idx1
, idx2
, idx3
;
2515 const tulip_srom_header_t
*shp
= (tulip_srom_header_t
*) &sc
->tulip_rombuf
[0];
2516 const tulip_srom_adapter_info_t
*saip
=
2517 (const tulip_srom_adapter_info_t
*) (shp
+ 1);
2518 tulip_srom_media_t srom_media
;
2519 tulip_media_info_t
*mi
= sc
->tulip_mediainfo
;
2521 u_int32_t leaf_offset
, blocks
, data
;
2523 for (idx1
= 0; idx1
< shp
->sh_adapter_count
; idx1
++, saip
++) {
2524 if (shp
->sh_adapter_count
== 1)
2526 if (saip
->sai_device
== sc
->tulip_pci_devno
)
2530 * Didn't find the right media block for this card.
2532 if (idx1
== shp
->sh_adapter_count
)
2536 * Save the hardware address.
2538 memcpy((void *) sc
->tulip_enaddr
, shp
->sh_ieee802_address
,
2541 * If this is a multiple port card, add the adapter index to the last
2542 * byte of the hardware address. (if it isn't multiport, adding 0
2545 sc
->tulip_enaddr
[5] += idx1
;
2547 leaf_offset
= saip
->sai_leaf_offset_lowbyte
2548 + saip
->sai_leaf_offset_highbyte
* 256;
2549 dp
= sc
->tulip_rombuf
+ leaf_offset
;
2551 sc
->tulip_conntype
= (tulip_srom_connection_t
) (dp
[0] + dp
[1] * 256); dp
+= 2;
2553 for (idx2
= 0;; idx2
++) {
2554 if (tulip_srom_conninfo
[idx2
].sc_type
== sc
->tulip_conntype
2555 || tulip_srom_conninfo
[idx2
].sc_type
== TULIP_SROM_CONNTYPE_NOT_USED
)
2558 sc
->tulip_connidx
= idx2
;
2560 if (sc
->tulip_chipid
== TULIP_21041
) {
2562 for (idx2
= 0; idx2
< blocks
; idx2
++) {
2563 tulip_media_t media
;
2565 srom_media
= (tulip_srom_media_t
) (data
& 0x3F);
2566 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2567 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2570 media
= tulip_srom_mediums
[idx3
].sm_type
;
2571 if (media
!= TULIP_MEDIA_UNKNOWN
) {
2572 if (data
& TULIP_SROM_21041_EXTENDED
) {
2573 mi
->mi_type
= TULIP_MEDIAINFO_SIA
;
2574 sc
->tulip_mediums
[media
] = mi
;
2575 mi
->mi_sia_connectivity
= dp
[0] + dp
[1] * 256;
2576 mi
->mi_sia_tx_rx
= dp
[2] + dp
[3] * 256;
2577 mi
->mi_sia_general
= dp
[4] + dp
[5] * 256;
2581 case TULIP_MEDIA_BNC
: {
2582 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, BNC
);
2586 case TULIP_MEDIA_AUI
: {
2587 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, AUI
);
2591 case TULIP_MEDIA_10BASET
: {
2592 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET
);
2596 case TULIP_MEDIA_10BASET_FD
: {
2597 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET_FD
);
2607 if (data
& TULIP_SROM_21041_EXTENDED
)
2612 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, BNC
); mi
++;
2613 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, AUI
); mi
++;
2614 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET
); mi
++;
2615 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET_FD
); mi
++;
2619 unsigned length
, type
;
2620 tulip_media_t gp_media
= TULIP_MEDIA_UNKNOWN
;
2621 if (sc
->tulip_features
& TULIP_HAVE_GPR
)
2622 sc
->tulip_gpinit
= *dp
++;
2624 for (idx2
= 0; idx2
< blocks
; idx2
++) {
2626 if ((*dp
& 0x80) == 0) {
2630 length
= (*dp
++ & 0x7f) - 1;
2631 type
= *dp
++ & 0x3f;
2634 switch (type
& 0x3f) {
2635 case 0: { /* 21140[A] GPR block */
2636 tulip_media_t media
;
2637 srom_media
= (tulip_srom_media_t
)(dp
[0] & 0x3f);
2638 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2639 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2642 media
= tulip_srom_mediums
[idx3
].sm_type
;
2643 if (media
== TULIP_MEDIA_UNKNOWN
)
2645 mi
->mi_type
= TULIP_MEDIAINFO_GPR
;
2646 sc
->tulip_mediums
[media
] = mi
;
2647 mi
->mi_gpdata
= dp
[1];
2648 if (media
> gp_media
&& !TULIP_IS_MEDIA_FD(media
)) {
2649 sc
->tulip_gpdata
= mi
->mi_gpdata
;
2652 data
= dp
[2] + dp
[3] * 256;
2653 mi
->mi_cmdmode
= TULIP_SROM_2114X_CMDBITS(data
);
2654 if (data
& TULIP_SROM_2114X_NOINDICATOR
) {
2658 mi
->mi_default
= (data
& TULIP_SROM_2114X_DEFAULT
) != 0;
2660 mi
->mi_actmask
= TULIP_SROM_2114X_BITPOS(data
);
2661 mi
->mi_actdata
= (data
& TULIP_SROM_2114X_POLARITY
) ? 0 : mi
->mi_actmask
;
2666 case 1: { /* 21140[A] MII block */
2667 const unsigned phyno
= *dp
++;
2668 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2669 mi
->mi_gpr_length
= *dp
++;
2670 mi
->mi_gpr_offset
= dp
- sc
->tulip_rombuf
;
2671 dp
+= mi
->mi_gpr_length
;
2672 mi
->mi_reset_length
= *dp
++;
2673 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2674 dp
+= mi
->mi_reset_length
;
2677 * Before we probe for a PHY, use the GPR information
2678 * to select it. If we don't, it may be inaccessible.
2680 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_gpinit
|TULIP_GP_PINSET
);
2681 for (idx3
= 0; idx3
< mi
->mi_reset_length
; idx3
++) {
2683 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_reset_offset
+ idx3
]);
2685 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
2686 for (idx3
= 0; idx3
< mi
->mi_gpr_length
; idx3
++) {
2688 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_gpr_offset
+ idx3
]);
2692 * At least write something!
2694 if (mi
->mi_reset_length
== 0 && mi
->mi_gpr_length
== 0)
2695 TULIP_CSR_WRITE(sc
, csr_gp
, 0);
2697 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2698 for (idx3
= 20; idx3
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx3
--) {
2700 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, phyno
);
2702 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
) {
2703 #if defined(TULIP_DEBUG)
2704 printf(TULIP_PRINTF_FMT
": can't find phy %d\n",
2705 TULIP_PRINTF_ARGS
, phyno
);
2709 sc
->tulip_features
|= TULIP_HAVE_MII
;
2710 mi
->mi_capabilities
= dp
[0] + dp
[1] * 256; dp
+= 2;
2711 mi
->mi_advertisement
= dp
[0] + dp
[1] * 256; dp
+= 2;
2712 mi
->mi_full_duplex
= dp
[0] + dp
[1] * 256; dp
+= 2;
2713 mi
->mi_tx_threshold
= dp
[0] + dp
[1] * 256; dp
+= 2;
2714 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2715 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2716 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2717 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2718 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2719 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2720 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2724 case 2: { /* 2114[23] SIA block */
2725 tulip_media_t media
;
2726 srom_media
= (tulip_srom_media_t
)(dp
[0] & 0x3f);
2727 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2728 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2731 media
= tulip_srom_mediums
[idx3
].sm_type
;
2732 if (media
== TULIP_MEDIA_UNKNOWN
)
2734 mi
->mi_type
= TULIP_MEDIAINFO_SIA
;
2735 sc
->tulip_mediums
[media
] = mi
;
2737 mi
->mi_sia_connectivity
= dp
[1] + dp
[2] * 256;
2738 mi
->mi_sia_tx_rx
= dp
[3] + dp
[4] * 256;
2739 mi
->mi_sia_general
= dp
[5] + dp
[6] * 256;
2743 case TULIP_MEDIA_BNC
: {
2744 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, BNC
);
2747 case TULIP_MEDIA_AUI
: {
2748 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, AUI
);
2751 case TULIP_MEDIA_10BASET
: {
2752 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, 10BASET
);
2753 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2756 case TULIP_MEDIA_10BASET_FD
: {
2757 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, 10BASET_FD
);
2758 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2766 mi
->mi_sia_gp_control
= (dp
[1] + dp
[2] * 256) << 16;
2767 mi
->mi_sia_gp_data
= (dp
[3] + dp
[4] * 256) << 16;
2772 case 3: { /* 2114[23] MII PHY block */
2773 const unsigned phyno
= *dp
++;
2774 const u_int8_t
*dp0
;
2775 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2776 mi
->mi_gpr_length
= *dp
++;
2777 mi
->mi_gpr_offset
= dp
- sc
->tulip_rombuf
;
2778 dp
+= 2 * mi
->mi_gpr_length
;
2779 mi
->mi_reset_length
= *dp
++;
2780 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2781 dp
+= 2 * mi
->mi_reset_length
;
2783 dp0
= &sc
->tulip_rombuf
[mi
->mi_reset_offset
];
2784 for (idx3
= 0; idx3
< mi
->mi_reset_length
; idx3
++, dp0
+= 2) {
2786 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp0
[0] + 256 * dp0
[1]) << 16);
2788 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
2789 dp0
= &sc
->tulip_rombuf
[mi
->mi_gpr_offset
];
2790 for (idx3
= 0; idx3
< mi
->mi_gpr_length
; idx3
++, dp0
+= 2) {
2792 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp0
[0] + 256 * dp0
[1]) << 16);
2795 if (mi
->mi_reset_length
== 0 && mi
->mi_gpr_length
== 0)
2796 TULIP_CSR_WRITE(sc
, csr_sia_general
, 0);
2798 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2799 for (idx3
= 20; idx3
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx3
--) {
2801 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, phyno
);
2803 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
) {
2804 #if defined(TULIP_DEBUG)
2805 printf(TULIP_PRINTF_FMT
": can't find phy %d\n",
2806 TULIP_PRINTF_ARGS
, phyno
);
2810 sc
->tulip_features
|= TULIP_HAVE_MII
;
2811 mi
->mi_capabilities
= dp
[0] + dp
[1] * 256; dp
+= 2;
2812 mi
->mi_advertisement
= dp
[0] + dp
[1] * 256; dp
+= 2;
2813 mi
->mi_full_duplex
= dp
[0] + dp
[1] * 256; dp
+= 2;
2814 mi
->mi_tx_threshold
= dp
[0] + dp
[1] * 256; dp
+= 2;
2815 mi
->mi_mii_interrupt
= dp
[0] + dp
[1] * 256; dp
+= 2;
2816 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2817 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2818 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2819 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2820 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2821 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2822 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2826 case 4: { /* 21143 SYM block */
2827 tulip_media_t media
;
2828 srom_media
= (tulip_srom_media_t
) dp
[0];
2829 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2830 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2833 media
= tulip_srom_mediums
[idx3
].sm_type
;
2834 if (media
== TULIP_MEDIA_UNKNOWN
)
2836 mi
->mi_type
= TULIP_MEDIAINFO_SYM
;
2837 sc
->tulip_mediums
[media
] = mi
;
2838 mi
->mi_gpcontrol
= (dp
[1] + dp
[2] * 256) << 16;
2839 mi
->mi_gpdata
= (dp
[3] + dp
[4] * 256) << 16;
2840 data
= dp
[5] + dp
[6] * 256;
2841 mi
->mi_cmdmode
= TULIP_SROM_2114X_CMDBITS(data
);
2842 if (data
& TULIP_SROM_2114X_NOINDICATOR
) {
2845 mi
->mi_default
= (data
& TULIP_SROM_2114X_DEFAULT
) != 0;
2846 mi
->mi_actmask
= TULIP_SROM_2114X_BITPOS(data
);
2847 mi
->mi_actdata
= (data
& TULIP_SROM_2114X_POLARITY
) ? 0 : mi
->mi_actmask
;
2849 if (TULIP_IS_MEDIA_TP(media
))
2850 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2855 case 5: { /* 21143 Reset block */
2856 mi
->mi_type
= TULIP_MEDIAINFO_RESET
;
2857 mi
->mi_reset_length
= *dp
++;
2858 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2859 dp
+= 2 * mi
->mi_reset_length
;
2870 return mi
- sc
->tulip_mediainfo
;
2873 static const struct {
2874 void (*vendor_identify_nic
)(tulip_softc_t
* const sc
);
2875 unsigned char vendor_oui
[3];
2876 } tulip_vendors
[] = {
2877 { tulip_identify_dec_nic
, { 0x08, 0x00, 0x2B } },
2878 { tulip_identify_dec_nic
, { 0x00, 0x00, 0xF8 } },
2879 { tulip_identify_smc_nic
, { 0x00, 0x00, 0xC0 } },
2880 { tulip_identify_smc_nic
, { 0x00, 0xE0, 0x29 } },
2881 { tulip_identify_znyx_nic
, { 0x00, 0xC0, 0x95 } },
2882 { tulip_identify_cogent_nic
, { 0x00, 0x00, 0x92 } },
2883 { tulip_identify_asante_nic
, { 0x00, 0x00, 0x94 } },
2884 { tulip_identify_accton_nic
, { 0x00, 0x00, 0xE8 } },
2885 { tulip_identify_compex_nic
, { 0x00, 0x80, 0x48 } },
2886 { NULL
, { 0, 0, 0} }
2890 * This deals with the vagaries of the address roms and the
2891 * brain-deadness that various vendors commit in using them.
2895 tulip_softc_t
* const sc
)
2897 unsigned cksum
, rom_cksum
, idx
;
2899 unsigned char tmpbuf
[8];
2900 static const u_char testpat
[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
2902 sc
->tulip_connidx
= TULIP_SROM_LASTCONNIDX
;
2904 if (sc
->tulip_chipid
== TULIP_21040
) {
2905 TULIP_CSR_WRITE(sc
, csr_enetrom
, 1);
2906 for (idx
= 0; idx
< sizeof(sc
->tulip_rombuf
); idx
++) {
2908 while (((csr
= TULIP_CSR_READ(sc
, csr_enetrom
)) & 0x80000000L
) && cnt
< 10000)
2910 sc
->tulip_rombuf
[idx
] = csr
& 0xFF;
2912 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2913 #if defined(TULIP_EISA)
2914 } else if (sc
->tulip_chipid
== TULIP_DE425
) {
2916 for (idx
= 0, cnt
= 0; idx
< sizeof(testpat
) && cnt
< 32; cnt
++) {
2917 tmpbuf
[idx
] = TULIP_CSR_READBYTE(sc
, csr_enetrom
);
2918 if (tmpbuf
[idx
] == testpat
[idx
])
2923 for (idx
= 0; idx
< 32; idx
++)
2924 sc
->tulip_rombuf
[idx
] = TULIP_CSR_READBYTE(sc
, csr_enetrom
);
2925 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2926 #endif /* TULIP_EISA */
2928 if (sc
->tulip_chipid
== TULIP_21041
) {
2930 * Thankfully all 21041's act the same.
2932 sc
->tulip_boardsw
= &tulip_21041_boardsw
;
2935 * Assume all 21140 board are compatible with the
2936 * DEC 10/100 evaluation board. Not really valid but
2937 * it's the best we can do until every one switches to
2938 * the new SROM format.
2941 sc
->tulip_boardsw
= &tulip_21140_eb_boardsw
;
2943 tulip_srom_read(sc
);
2944 if (tulip_srom_crcok(sc
->tulip_rombuf
)) {
2946 * SROM CRC is valid therefore it must be in the
2949 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
|TULIP_HAVE_OKSROM
;
2950 } else if (sc
->tulip_rombuf
[126] == 0xff && sc
->tulip_rombuf
[127] == 0xFF) {
2952 * No checksum is present. See if the SROM id checks out;
2953 * the first 18 bytes should be 0 followed by a 1 followed
2954 * by the number of adapters (which we don't deal with yet).
2956 for (idx
= 0; idx
< 18; idx
++) {
2957 if (sc
->tulip_rombuf
[idx
] != 0)
2960 if (idx
== 18 && sc
->tulip_rombuf
[18] == 1 && sc
->tulip_rombuf
[19] != 0)
2961 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
;
2962 } else if (sc
->tulip_chipid
>= TULIP_21142
) {
2963 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
;
2964 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2966 if ((sc
->tulip_features
& TULIP_HAVE_ISVSROM
) && tulip_srom_decode(sc
)) {
2967 if (sc
->tulip_chipid
!= TULIP_21041
)
2968 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2971 * If the SROM specifies more than one adapter, tag this as a
2974 if (sc
->tulip_rombuf
[19] > 1)
2975 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
2976 if (sc
->tulip_boardsw
== NULL
)
2983 if (memcmp(&sc
->tulip_rombuf
[0], &sc
->tulip_rombuf
[16], 8) != 0) {
2985 * Some folks don't use the standard ethernet rom format
2986 * but instead just put the address in the first 6 bytes
2987 * of the rom and let the rest be all 0xffs. (Can we say
2988 * ZNYX???) (well sometimes they put in a checksum so we'll
2991 for (idx
= 8; idx
< 32; idx
++) {
2992 if (sc
->tulip_rombuf
[idx
] != 0xFF)
2996 * Make sure the address is not multicast or locally assigned
2997 * that the OUI is not 00-00-00.
2999 if ((sc
->tulip_rombuf
[0] & 3) != 0)
3001 if (sc
->tulip_rombuf
[0] == 0 && sc
->tulip_rombuf
[1] == 0
3002 && sc
->tulip_rombuf
[2] == 0)
3004 memcpy(sc
->tulip_enaddr
, sc
->tulip_rombuf
, ETHER_ADDR_LEN
);
3005 sc
->tulip_features
|= TULIP_HAVE_OKROM
;
3009 * A number of makers of multiport boards (ZNYX and Cogent)
3010 * only put on one address ROM on their 21040 boards. So
3011 * if the ROM is all zeros (or all 0xFFs), look at the
3012 * previous configured boards (as long as they are on the same
3013 * PCI bus and the bus number is non-zero) until we find the
3014 * master board with address ROM. We then use its address ROM
3015 * as the base for this board. (we add our relative board
3016 * to the last byte of its address).
3018 for (idx
= 0; idx
< sizeof(sc
->tulip_rombuf
); idx
++) {
3019 if (sc
->tulip_rombuf
[idx
] != 0 && sc
->tulip_rombuf
[idx
] != 0xFF)
3022 if (idx
== sizeof(sc
->tulip_rombuf
)) {
3024 tulip_softc_t
*root_sc
= NULL
;
3025 for (root_unit
= sc
->tulip_unit
- 1; root_unit
>= 0; root_unit
--) {
3026 root_sc
= TULIP_UNIT_TO_SOFTC(root_unit
);
3027 if (root_sc
== NULL
|| (root_sc
->tulip_features
& (TULIP_HAVE_OKROM
|TULIP_HAVE_SLAVEDROM
)) == TULIP_HAVE_OKROM
)
3031 if (root_sc
!= NULL
&& (root_sc
->tulip_features
& TULIP_HAVE_BASEROM
)
3032 && root_sc
->tulip_chipid
== sc
->tulip_chipid
3033 && root_sc
->tulip_pci_busno
== sc
->tulip_pci_busno
) {
3034 sc
->tulip_features
|= TULIP_HAVE_SLAVEDROM
;
3035 sc
->tulip_boardsw
= root_sc
->tulip_boardsw
;
3036 strlcpy(sc
->tulip_boardid
, root_sc
->tulip_boardid
,
3037 sizeof(sc
->tulip_boardid
));
3038 if (sc
->tulip_boardsw
->bd_type
== TULIP_21140_ISV
) {
3039 memcpy(sc
->tulip_rombuf
, root_sc
->tulip_rombuf
,
3040 sizeof(sc
->tulip_rombuf
));
3041 if (!tulip_srom_decode(sc
))
3044 memcpy(sc
->tulip_enaddr
, root_sc
->tulip_enaddr
,
3046 sc
->tulip_enaddr
[5] += sc
->tulip_unit
- root_sc
->tulip_unit
;
3049 * Now for a truly disgusting kludge: all 4 21040s on
3050 * the ZX314 share the same INTA line so the mapping
3051 * setup by the BIOS on the PCI bridge is worthless.
3052 * Rather than reprogramming the value in the config
3053 * register, we will handle this internally.
3055 if (root_sc
->tulip_features
& TULIP_HAVE_SHAREDINTR
) {
3056 sc
->tulip_slaves
= root_sc
->tulip_slaves
;
3057 root_sc
->tulip_slaves
= sc
;
3058 sc
->tulip_features
|= TULIP_HAVE_SLAVEDINTR
;
3066 * This is the standard DEC address ROM test.
3069 if (memcmp(&sc
->tulip_rombuf
[24], testpat
, 8) != 0)
3072 tmpbuf
[0] = sc
->tulip_rombuf
[15]; tmpbuf
[1] = sc
->tulip_rombuf
[14];
3073 tmpbuf
[2] = sc
->tulip_rombuf
[13]; tmpbuf
[3] = sc
->tulip_rombuf
[12];
3074 tmpbuf
[4] = sc
->tulip_rombuf
[11]; tmpbuf
[5] = sc
->tulip_rombuf
[10];
3075 tmpbuf
[6] = sc
->tulip_rombuf
[9]; tmpbuf
[7] = sc
->tulip_rombuf
[8];
3076 if (memcmp(&sc
->tulip_rombuf
[0], tmpbuf
, 8) != 0)
3079 memcpy(sc
->tulip_enaddr
, sc
->tulip_rombuf
, ETHER_ADDR_LEN
);
3081 cksum
= *(u_int16_t
*) &sc
->tulip_enaddr
[0];
3083 if (cksum
> 65535) cksum
-= 65535;
3084 cksum
+= *(u_int16_t
*) &sc
->tulip_enaddr
[2];
3085 if (cksum
> 65535) cksum
-= 65535;
3087 if (cksum
> 65535) cksum
-= 65535;
3088 cksum
+= *(u_int16_t
*) &sc
->tulip_enaddr
[4];
3089 if (cksum
>= 65535) cksum
-= 65535;
3091 rom_cksum
= *(u_int16_t
*) &sc
->tulip_rombuf
[6];
3093 if (cksum
!= rom_cksum
)
3098 * Check for various boards based on OUI. Did I say braindead?
3100 for (idx
= 0; tulip_vendors
[idx
].vendor_identify_nic
!= NULL
; idx
++) {
3101 if (memcmp((void *) sc
->tulip_enaddr
,
3102 tulip_vendors
[idx
].vendor_oui
, 3) == 0) {
3103 (*tulip_vendors
[idx
].vendor_identify_nic
)(sc
);
3108 sc
->tulip_features
|= TULIP_HAVE_OKROM
;
3112 #if defined(IFM_ETHER)
3115 tulip_softc_t
* const sc
)
3117 tulip_media_t media
;
3120 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
3121 if (sc
->tulip_mediums
[media
] != NULL
) {
3122 ifmedia_add(&sc
->tulip_ifmedia
, tulip_media_to_ifmedia
[media
],
3128 sc
->tulip_features
|= TULIP_HAVE_NOMEDIA
;
3129 ifmedia_add(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_NONE
, 0, 0);
3130 ifmedia_set(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_NONE
);
3131 } else if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
) {
3132 ifmedia_add(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_AUTO
, 0, 0);
3133 ifmedia_set(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_AUTO
);
3135 ifmedia_set(&sc
->tulip_ifmedia
, tulip_media_to_ifmedia
[sc
->tulip_media
]);
3136 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
3137 tulip_linkup(sc
, sc
->tulip_media
);
3142 tulip_ifmedia_change(
3143 struct ifnet
* const ifp
)
3145 tulip_softc_t
* const sc
= TULIP_IFP_TO_SOFTC(ifp
);
3147 sc
->tulip_flags
|= TULIP_NEEDRESET
;
3148 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
3149 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
3150 if (IFM_SUBTYPE(sc
->tulip_ifmedia
.ifm_media
) != IFM_AUTO
) {
3151 tulip_media_t media
;
3152 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
3153 if (sc
->tulip_mediums
[media
] != NULL
3154 && sc
->tulip_ifmedia
.ifm_media
== tulip_media_to_ifmedia
[media
]) {
3155 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
3156 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
3157 tulip_linkup(sc
, media
);
3162 sc
->tulip_flags
&= ~(TULIP_TXPROBE_ACTIVE
|TULIP_WANTRXACT
);
3169 * Media status callback
3172 tulip_ifmedia_status(
3173 struct ifnet
* const ifp
,
3174 struct ifmediareq
*req
)
3176 tulip_softc_t
*sc
= TULIP_IFP_TO_SOFTC(ifp
);
3178 #if defined(__bsdi__)
3179 if (sc
->tulip_mii
.mii_instance
!= 0) {
3180 mii_pollstat(&sc
->tulip_mii
);
3181 req
->ifm_active
= sc
->tulip_mii
.mii_media_active
;
3182 req
->ifm_status
= sc
->tulip_mii
.mii_media_status
;
3186 if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
)
3189 req
->ifm_status
= IFM_AVALID
;
3190 if (sc
->tulip_flags
& TULIP_LINKUP
)
3191 req
->ifm_status
|= IFM_ACTIVE
;
3193 req
->ifm_active
= tulip_media_to_ifmedia
[sc
->tulip_media
];
3199 tulip_softc_t
* const sc
)
3201 struct ether_multistep step
;
3202 struct ether_multi
*enm
;
3204 sc
->tulip_flags
&= ~(TULIP_WANTHASHPERFECT
|TULIP_WANTHASHONLY
|TULIP_ALLMULTI
);
3205 sc
->tulip_flags
|= TULIP_WANTSETUP
|TULIP_WANTTXSTART
;
3206 sc
->tulip_cmdmode
&= ~TULIP_CMD_RXRUN
;
3207 sc
->tulip_intrmask
&= ~TULIP_STS_RXSTOPPED
;
3208 #if defined(IFF_ALLMULTI)
3209 sc
->tulip_if
.if_flags
&= ~IFF_ALLMULTI
;
3211 sc
->tulip_if
.if_start
= tulip_ifstart
; /* so the setup packet gets queued */
3212 if (sc
->tulip_multicnt
> 14) {
3213 u_int32_t
*sp
= sc
->tulip_setupdata
;
3216 * Some early passes of the 21140 have broken implementations of
3217 * hash-perfect mode. When we get too many multicasts for perfect
3218 * filtering with these chips, we need to switch into hash-only
3219 * mode (this is better than all-multicast on network with lots
3220 * of multicast traffic).
3222 if (sc
->tulip_features
& TULIP_HAVE_BROKEN_HASH
)
3223 sc
->tulip_flags
|= TULIP_WANTHASHONLY
;
3225 sc
->tulip_flags
|= TULIP_WANTHASHPERFECT
;
3227 * If we have more than 14 multicasts, we have
3228 * go into hash perfect mode (512 bit multicast
3229 * hash and one perfect hardware).
3231 memset(sc
->tulip_setupdata
, 0, sizeof(sc
->tulip_setupdata
));
3232 ETHER_FIRST_MULTI(step
, TULIP_ETHERCOM(sc
), enm
);
3233 while (enm
!= NULL
) {
3234 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
, 6) == 0) {
3235 hash
= tulip_mchash(enm
->enm_addrlo
);
3236 #if BYTE_ORDER == BIG_ENDIAN
3237 sp
[hash
>> 4] |= bswap32(1 << (hash
& 0xF));
3239 sp
[hash
>> 4] |= 1 << (hash
& 0xF);
3242 sc
->tulip_flags
|= TULIP_ALLMULTI
;
3243 sc
->tulip_flags
&= ~(TULIP_WANTHASHONLY
|TULIP_WANTHASHPERFECT
);
3246 ETHER_NEXT_MULTI(step
, enm
);
3249 * No reason to use a hash if we are going to be
3250 * receiving every multicast.
3252 if ((sc
->tulip_flags
& TULIP_ALLMULTI
) == 0) {
3253 hash
= tulip_mchash(etherbroadcastaddr
);
3254 #if BYTE_ORDER == BIG_ENDIAN
3255 sp
[hash
>> 4] |= bswap32(1 << (hash
& 0xF));
3257 sp
[hash
>> 4] |= 1 << (hash
& 0xF);
3259 if (sc
->tulip_flags
& TULIP_WANTHASHONLY
) {
3260 hash
= tulip_mchash(sc
->tulip_enaddr
);
3261 #if BYTE_ORDER == BIG_ENDIAN
3262 sp
[hash
>> 4] |= bswap32(1 << (hash
& 0xF));
3264 sp
[hash
>> 4] |= 1 << (hash
& 0xF);
3267 #if BYTE_ORDER == BIG_ENDIAN
3268 sp
[39] = ((u_int16_t
*) sc
->tulip_enaddr
)[0] << 16;
3269 sp
[40] = ((u_int16_t
*) sc
->tulip_enaddr
)[1] << 16;
3270 sp
[41] = ((u_int16_t
*) sc
->tulip_enaddr
)[2] << 16;
3272 sp
[39] = ((u_int16_t
*) sc
->tulip_enaddr
)[0];
3273 sp
[40] = ((u_int16_t
*) sc
->tulip_enaddr
)[1];
3274 sp
[41] = ((u_int16_t
*) sc
->tulip_enaddr
)[2];
3279 if ((sc
->tulip_flags
& (TULIP_WANTHASHPERFECT
|TULIP_WANTHASHONLY
)) == 0) {
3280 u_int32_t
*sp
= sc
->tulip_setupdata
;
3282 if ((sc
->tulip_flags
& TULIP_ALLMULTI
) == 0) {
3284 * Else can get perfect filtering for 16 addresses.
3286 ETHER_FIRST_MULTI(step
, TULIP_ETHERCOM(sc
), enm
);
3287 for (; enm
!= NULL
; idx
++) {
3288 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
, 6) == 0) {
3289 #if BYTE_ORDER == BIG_ENDIAN
3290 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[0] << 16;
3291 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[1] << 16;
3292 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[2] << 16;
3294 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[0];
3295 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[1];
3296 *sp
++ = ((u_int16_t
*) enm
->enm_addrlo
)[2];
3299 sc
->tulip_flags
|= TULIP_ALLMULTI
;
3302 ETHER_NEXT_MULTI(step
, enm
);
3305 * Add the broadcast address.
3308 #if BYTE_ORDER == BIG_ENDIAN
3309 *sp
++ = 0xFFFF << 16;
3310 *sp
++ = 0xFFFF << 16;
3311 *sp
++ = 0xFFFF << 16;
3319 * Pad the rest with our hardware address
3321 for (; idx
< 16; idx
++) {
3322 #if BYTE_ORDER == BIG_ENDIAN
3323 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[0] << 16;
3324 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[1] << 16;
3325 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[2] << 16;
3327 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[0];
3328 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[1];
3329 *sp
++ = ((u_int16_t
*) sc
->tulip_enaddr
)[2];
3333 #if defined(IFF_ALLMULTI)
3334 if (sc
->tulip_flags
& TULIP_ALLMULTI
)
3335 sc
->tulip_if
.if_flags
|= IFF_ALLMULTI
;
3341 tulip_softc_t
* const sc
)
3343 tulip_ringinfo_t
*ri
;
3345 u_int32_t inreset
= (sc
->tulip_flags
& TULIP_INRESET
);
3348 * Brilliant. Simply brilliant. When switching modes/speeds
3349 * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
3350 * bits in CSR6 and then do a software reset to get the 21140
3351 * to properly reset its internal pathways to the right places.
3354 if ((sc
->tulip_flags
& TULIP_DEVICEPROBE
) == 0
3355 && sc
->tulip_boardsw
->bd_media_preset
!= NULL
)
3356 (*sc
->tulip_boardsw
->bd_media_preset
)(sc
);
3358 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
3359 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
3360 33MHz that comes to two microseconds but wait a
3361 bit longer anyways) */
3364 sc
->tulip_flags
|= TULIP_INRESET
;
3365 sc
->tulip_flags
&= ~(TULIP_NEEDRESET
|TULIP_RXBUFSLOW
);
3366 sc
->tulip_if
.if_flags
&= ~IFF_OACTIVE
;
3367 sc
->tulip_if
.if_start
= tulip_ifstart
;
3370 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3371 TULIP_CSR_WRITE(sc
, csr_txlist
, sc
->tulip_txdescmap
->dm_segs
[0].ds_addr
);
3373 TULIP_CSR_WRITE(sc
, csr_txlist
, TULIP_KVATOPHYS(sc
, &sc
->tulip_txinfo
.ri_first
[0]));
3375 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3376 TULIP_CSR_WRITE(sc
, csr_rxlist
, sc
->tulip_rxdescmap
->dm_segs
[0].ds_addr
);
3378 TULIP_CSR_WRITE(sc
, csr_rxlist
, TULIP_KVATOPHYS(sc
, &sc
->tulip_rxinfo
.ri_first
[0]));
3380 TULIP_CSR_WRITE(sc
, csr_busmode
,
3381 (1 << (TULIP_BURSTSIZE(sc
->tulip_unit
) + 8))
3382 |TULIP_BUSMODE_CACHE_ALIGN8
3383 |TULIP_BUSMODE_READMULTIPLE
3384 |(BYTE_ORDER
!= LITTLE_ENDIAN
?
3385 TULIP_BUSMODE_DESC_BIGENDIAN
: 0));
3387 sc
->tulip_txtimer
= 0;
3388 sc
->tulip_txq
.ifq_maxlen
= TULIP_TXDESCS
;
3390 * Free all the mbufs that were on the transmit ring.
3393 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3397 IF_DEQUEUE(&sc
->tulip_txq
, m
);
3400 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3401 map
= M_GETCTX(m
, bus_dmamap_t
);
3402 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
3403 tulip_free_txmap(sc
, map
);
3408 ri
= &sc
->tulip_txinfo
;
3409 ri
->ri_nextin
= ri
->ri_nextout
= ri
->ri_first
;
3410 ri
->ri_free
= ri
->ri_max
;
3411 for (di
= ri
->ri_first
; di
< ri
->ri_last
; di
++)
3413 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3414 bus_dmamap_sync(sc
->tulip_dmatag
, sc
->tulip_txdescmap
,
3415 0, sc
->tulip_txdescmap
->dm_mapsize
,
3416 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
3420 * We need to collect all the mbufs were on the
3421 * receive ring before we reinit it either to put
3422 * them back on or to know if we have to allocate
3425 ri
= &sc
->tulip_rxinfo
;
3426 ri
->ri_nextin
= ri
->ri_nextout
= ri
->ri_first
;
3427 ri
->ri_free
= ri
->ri_max
;
3428 for (di
= ri
->ri_first
; di
< ri
->ri_last
; di
++) {
3430 di
->d_length1
= 0; di
->d_addr1
= 0;
3431 di
->d_length2
= 0; di
->d_addr2
= 0;
3433 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3434 bus_dmamap_sync(sc
->tulip_dmatag
, sc
->tulip_rxdescmap
,
3435 0, sc
->tulip_rxdescmap
->dm_mapsize
,
3436 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
3439 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3443 IF_DEQUEUE(&sc
->tulip_rxq
, m
);
3446 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3447 map
= M_GETCTX(m
, bus_dmamap_t
);
3448 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
3449 tulip_free_rxmap(sc
, map
);
3455 * If tulip_reset is being called recurisvely, exit quickly knowing
3456 * that when the outer tulip_reset returns all the right stuff will
3462 sc
->tulip_intrmask
|= TULIP_STS_NORMALINTR
|TULIP_STS_RXINTR
|TULIP_STS_TXINTR
3463 |TULIP_STS_ABNRMLINTR
|TULIP_STS_SYSERROR
|TULIP_STS_TXSTOPPED
3464 |TULIP_STS_TXUNDERFLOW
|TULIP_STS_TXBABBLE
3465 |TULIP_STS_RXSTOPPED
;
3467 if ((sc
->tulip_flags
& TULIP_DEVICEPROBE
) == 0)
3468 (*sc
->tulip_boardsw
->bd_media_select
)(sc
);
3469 #if defined(TULIP_DEBUG)
3470 if ((sc
->tulip_flags
& TULIP_NEEDRESET
) == TULIP_NEEDRESET
)
3471 printf(TULIP_PRINTF_FMT
": tulip_reset: additional reset needed?!?\n",
3474 tulip_media_print(sc
);
3475 if (sc
->tulip_features
& TULIP_HAVE_DUALSENSE
)
3476 TULIP_CSR_WRITE(sc
, csr_sia_status
, TULIP_CSR_READ(sc
, csr_sia_status
));
3478 sc
->tulip_flags
&= ~(TULIP_DOINGSETUP
|TULIP_WANTSETUP
|TULIP_INRESET
3480 tulip_addr_filter(sc
);
3485 tulip_softc_t
* const sc
)
3487 if (sc
->tulip_if
.if_flags
& IFF_UP
) {
3488 if ((sc
->tulip_if
.if_flags
& IFF_RUNNING
) == 0) {
3489 /* initialize the media */
3492 sc
->tulip_if
.if_flags
|= IFF_RUNNING
;
3493 if (sc
->tulip_if
.if_flags
& IFF_PROMISC
) {
3494 sc
->tulip_flags
|= TULIP_PROMISC
;
3495 sc
->tulip_cmdmode
|= TULIP_CMD_PROMISCUOUS
;
3496 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
3498 sc
->tulip_flags
&= ~TULIP_PROMISC
;
3499 sc
->tulip_cmdmode
&= ~TULIP_CMD_PROMISCUOUS
;
3500 if (sc
->tulip_flags
& TULIP_ALLMULTI
) {
3501 sc
->tulip_cmdmode
|= TULIP_CMD_ALLMULTI
;
3503 sc
->tulip_cmdmode
&= ~TULIP_CMD_ALLMULTI
;
3506 sc
->tulip_cmdmode
|= TULIP_CMD_TXRUN
;
3507 if ((sc
->tulip_flags
& (TULIP_TXPROBE_ACTIVE
|TULIP_WANTSETUP
)) == 0) {
3509 sc
->tulip_cmdmode
|= TULIP_CMD_RXRUN
;
3510 sc
->tulip_intrmask
|= TULIP_STS_RXSTOPPED
;
3512 sc
->tulip_if
.if_flags
|= IFF_OACTIVE
;
3513 sc
->tulip_cmdmode
&= ~TULIP_CMD_RXRUN
;
3514 sc
->tulip_intrmask
&= ~TULIP_STS_RXSTOPPED
;
3516 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3517 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
3518 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == TULIP_WANTSETUP
)
3519 tulip_txput_setup(sc
);
3521 sc
->tulip_if
.if_flags
&= ~IFF_RUNNING
;
3528 tulip_softc_t
* const sc
)
3530 TULIP_PERFSTART(rxintr
)
3531 tulip_ringinfo_t
* const ri
= &sc
->tulip_rxinfo
;
3532 struct ifnet
* const ifp
= &sc
->tulip_if
;
3534 #if defined(TULIP_DEBUG)
3539 TULIP_PERFSTART(rxget
)
3540 struct ether_header eh
;
3541 tulip_desc_t
*eop
= ri
->ri_nextin
;
3542 int total_len
= 0, last_offset
= 0;
3543 struct mbuf
*ms
= NULL
, *me
= NULL
;
3545 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3550 if (fillok
&& sc
->tulip_rxq
.ifq_len
< TULIP_RXQ_TARGET
)
3553 #if defined(TULIP_DEBUG)
3554 if (cnt
== ri
->ri_max
)
3558 * If the TULIP has no descriptors, there can't be any receive
3559 * descriptors to process.
3561 if (eop
== ri
->ri_nextout
)
3565 * 90% of the packets will fit in one descriptor. So we optimize
3568 TULIP_RXDESC_POSTSYNC(sc
, eop
, sizeof(*eop
));
3569 if ((((volatile tulip_desc_t
*) eop
)->d_status
& (TULIP_DSTS_OWNER
|TULIP_DSTS_RxFIRSTDESC
|TULIP_DSTS_RxLASTDESC
)) == (TULIP_DSTS_RxFIRSTDESC
|TULIP_DSTS_RxLASTDESC
)) {
3570 IF_DEQUEUE(&sc
->tulip_rxq
, ms
);
3574 * If still owned by the TULIP, don't touch it.
3576 if (((volatile tulip_desc_t
*) eop
)->d_status
& TULIP_DSTS_OWNER
)
3580 * It is possible (though improbable unless the BIG_PACKET support
3581 * is enabled or MCLBYTES < 1518) for a received packet to cross
3582 * more than one receive descriptor.
3584 while ((((volatile tulip_desc_t
*) eop
)->d_status
& TULIP_DSTS_RxLASTDESC
) == 0) {
3585 if (++eop
== ri
->ri_last
)
3587 TULIP_RXDESC_POSTSYNC(sc
, eop
, sizeof(*eop
));
3588 if (eop
== ri
->ri_nextout
|| ((((volatile tulip_desc_t
*) eop
)->d_status
& TULIP_DSTS_OWNER
))) {
3589 #if defined(TULIP_DEBUG)
3590 sc
->tulip_dbg
.dbg_rxintrs
++;
3591 sc
->tulip_dbg
.dbg_rxpktsperintr
[cnt
]++;
3593 TULIP_PERFEND(rxget
);
3594 TULIP_PERFEND(rxintr
);
3601 * Dequeue the first buffer for the start of the packet. Hopefully
3602 * this will be the only one we need to dequeue. However, if the
3603 * packet consumed multiple descriptors, then we need to dequeue
3604 * those buffers and chain to the starting mbuf. All buffers but
3605 * the last buffer have the same length so we can set that now.
3606 * (we add to last_offset instead of multiplying since we normally
3607 * won't go into the loop and thereby saving a ourselves from
3608 * doing a multiplication by 0 in the normal case).
3610 IF_DEQUEUE(&sc
->tulip_rxq
, ms
);
3611 for (me
= ms
; total_len
> 0; total_len
--) {
3612 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3613 map
= M_GETCTX(me
, bus_dmamap_t
);
3614 TULIP_RXMAP_POSTSYNC(sc
, map
);
3615 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
3616 tulip_free_rxmap(sc
, map
);
3617 #if defined(DIAGNOSTIC)
3620 #endif /* TULIP_BUS_DMA */
3621 me
->m_len
= TULIP_RX_BUFLEN
;
3622 last_offset
+= TULIP_RX_BUFLEN
;
3623 IF_DEQUEUE(&sc
->tulip_rxq
, me
->m_next
);
3629 * Now get the size of received packet (minus the CRC).
3631 total_len
= ((eop
->d_status
>> 16) & 0x7FFF) - 4;
3632 if ((sc
->tulip_flags
& TULIP_RXIGNORE
) == 0
3633 && ((eop
->d_status
& TULIP_DSTS_ERRSUM
) == 0
3635 || (total_len
<= sc
->tulip_if
.if_mtu
+ sizeof(struct ether_header
) &&
3636 (eop
->d_status
& (TULIP_DSTS_RxBADLENGTH
|TULIP_DSTS_RxRUNT
|
3637 TULIP_DSTS_RxCOLLSEEN
|TULIP_DSTS_RxBADCRC
|
3638 TULIP_DSTS_RxOVERFLOW
)) == 0)
3641 me
->m_len
= total_len
- last_offset
;
3643 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3644 map
= M_GETCTX(me
, bus_dmamap_t
);
3645 bus_dmamap_sync(sc
->tulip_dmatag
, map
, 0, me
->m_len
,
3646 BUS_DMASYNC_POSTREAD
|BUS_DMASYNC_POSTWRITE
);
3647 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
3648 tulip_free_rxmap(sc
, map
);
3649 #if defined(DIAGNOSTIC)
3652 #endif /* TULIP_BUS_DMA */
3654 eh
= *mtod(ms
, struct ether_header
*);
3656 if (sc
->tulip_bpf
!= NULL
) {
3658 TULIP_BPF_TAP(sc
, mtod(ms
, void *), total_len
);
3660 TULIP_BPF_MTAP(sc
, ms
);
3663 sc
->tulip_flags
|= TULIP_RXACT
;
3664 if ((sc
->tulip_flags
& (TULIP_PROMISC
|TULIP_HASHONLY
))
3665 && (eh
.ether_dhost
[0] & 1) == 0
3666 && !TULIP_ADDREQUAL(eh
.ether_dhost
, sc
->tulip_enaddr
))
3671 if (eop
->d_status
& (TULIP_DSTS_RxBADLENGTH
|TULIP_DSTS_RxOVERFLOW
|TULIP_DSTS_RxWATCHDOG
)) {
3672 sc
->tulip_dot3stats
.dot3StatsInternalMacReceiveErrors
++;
3674 #if defined(TULIP_VERBOSE)
3675 const char *error
= NULL
;
3677 if (eop
->d_status
& TULIP_DSTS_RxTOOLONG
) {
3678 sc
->tulip_dot3stats
.dot3StatsFrameTooLongs
++;
3679 #if defined(TULIP_VERBOSE)
3680 error
= "frame too long";
3683 if (eop
->d_status
& TULIP_DSTS_RxBADCRC
) {
3684 if (eop
->d_status
& TULIP_DSTS_RxDRBBLBIT
) {
3685 sc
->tulip_dot3stats
.dot3StatsAlignmentErrors
++;
3686 #if defined(TULIP_VERBOSE)
3687 error
= "alignment error";
3690 sc
->tulip_dot3stats
.dot3StatsFCSErrors
++;
3691 #if defined(TULIP_VERBOSE)
3696 #if defined(TULIP_VERBOSE)
3697 if (error
!= NULL
&& (sc
->tulip_flags
& TULIP_NOMESSAGES
) == 0) {
3698 printf(TULIP_PRINTF_FMT
": receive: " TULIP_EADDR_FMT
": %s\n",
3700 TULIP_EADDR_ARGS(mtod(ms
, u_char
*) + 6),
3702 sc
->tulip_flags
|= TULIP_NOMESSAGES
;
3707 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3708 map
= M_GETCTX(me
, bus_dmamap_t
);
3709 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
3710 tulip_free_rxmap(sc
, map
);
3711 #if defined(DIAGNOSTIC)
3714 #endif /* TULIP_BUS_DMA */
3717 #if defined(TULIP_DEBUG)
3721 if (++eop
== ri
->ri_last
)
3723 ri
->ri_nextin
= eop
;
3726 * Either we are priming the TULIP with mbufs (m == NULL)
3727 * or we are about to accept an mbuf for the upper layers
3728 * so we need to allocate an mbuf to replace it. If we
3729 * can't replace it, send up it anyways. This may cause
3730 * us to drop packets in the future but that's better than
3731 * being caught in livelock.
3733 * Note that if this packet crossed multiple descriptors
3734 * we don't even try to reallocate all the mbufs here.
3735 * Instead we rely on the test of the beginning of
3736 * the loop to refill for the extra consumed mbufs.
3738 if (accept
|| ms
== NULL
) {
3740 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
3742 #if defined(TULIP_COPY_RXDATA)
3743 if (!accept
|| total_len
>= (MHLEN
- 2)) {
3745 MCLGET(m0
, M_DONTWAIT
);
3746 if ((m0
->m_flags
& M_EXT
) == 0) {
3750 #if defined(TULIP_COPY_RXDATA)
3755 #if defined(TULIP_COPY_RXDATA)
3759 #if defined(__bsdi__)
3760 eh
.ether_type
= ntohs(eh
.ether_type
);
3762 #if !defined(TULIP_COPY_RXDATA)
3763 ms
->m_pkthdr
.len
= total_len
;
3764 ms
->m_pkthdr
.rcvif
= ifp
;
3765 #if defined(__NetBSD__)
3766 (*ifp
->if_input
)(ifp
, ms
);
3768 m_adj(ms
, sizeof(struct ether_header
);
3769 ether_input(ifp
, &eh
, ms
);
3770 #endif /* __NetBSD__ */
3773 #error BIG_PACKET is incompatible with TULIP_COPY_RXDATA
3775 m0
->m_data
+= 2; /* align data after header */
3776 m_copydata(ms
, 0, total_len
, mtod(m0
, void *));
3777 m0
->m_len
= m0
->m_pkthdr
.len
= total_len
;
3778 m0
->m_pkthdr
.rcvif
= ifp
;
3779 #if defined(__NetBSD__)
3780 (*ifp
->if_input
)(ifp
, m0
);
3782 m_adj(m0
, sizeof(struct ether_header
);
3783 ether_input(ifp
, &eh
, m0
);
3784 #endif /* __NetBSD__ */
3786 #endif /* ! TULIP_COPY_RXDATA */
3792 * Couldn't allocate a new buffer. Don't bother
3793 * trying to replenish the receive queue.
3796 sc
->tulip_flags
|= TULIP_RXBUFSLOW
;
3797 #if defined(TULIP_DEBUG)
3798 sc
->tulip_dbg
.dbg_rxlowbufs
++;
3800 TULIP_PERFEND(rxget
);
3804 * Now give the buffer(s) to the TULIP and save in our
3808 tulip_desc_t
* const nextout
= ri
->ri_nextout
;
3809 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NORX)
3810 if (sc
->tulip_num_free_rxmaps
> 0) {
3811 map
= tulip_alloc_rxmap(sc
);
3814 sc
->tulip_flags
|= TULIP_RXBUFSLOW
;
3815 #if defined(TULIP_DEBUG)
3816 sc
->tulip_dbg
.dbg_rxlowbufs
++;
3821 error
= bus_dmamap_load(sc
->tulip_dmatag
, map
, mtod(ms
, void *),
3822 TULIP_RX_BUFLEN
, NULL
, BUS_DMA_NOWAIT
);
3824 printf(TULIP_PRINTF_FMT
": unable to load rx map, "
3825 "error = %d\n", TULIP_PRINTF_ARGS
, error
);
3826 panic("tulip_rx_intr"); /* XXX */
3828 nextout
->d_addr1
= map
->dm_segs
[0].ds_addr
;
3829 nextout
->d_length1
= map
->dm_segs
[0].ds_len
;
3830 if (map
->dm_nsegs
== 2) {
3831 nextout
->d_addr2
= map
->dm_segs
[1].ds_addr
;
3832 nextout
->d_length2
= map
->dm_segs
[1].ds_len
;
3834 nextout
->d_addr2
= 0;
3835 nextout
->d_length2
= 0;
3837 TULIP_RXDESC_POSTSYNC(sc
, nextout
, sizeof(*nextout
));
3838 #else /* TULIP_BUS_DMA */
3839 nextout
->d_addr1
= TULIP_KVATOPHYS(sc
, mtod(ms
, void *));
3840 nextout
->d_length1
= TULIP_RX_BUFLEN
;
3841 #endif /* TULIP_BUS_DMA */
3842 nextout
->d_status
= TULIP_DSTS_OWNER
;
3843 TULIP_RXDESC_POSTSYNC(sc
, nextout
, sizeof(u_int32_t
));
3844 if (++ri
->ri_nextout
== ri
->ri_last
)
3845 ri
->ri_nextout
= ri
->ri_first
;
3848 IF_ENQUEUE(&sc
->tulip_rxq
, ms
);
3849 } while ((ms
= me
) != NULL
);
3851 if (sc
->tulip_rxq
.ifq_len
>= TULIP_RXQ_TARGET
)
3852 sc
->tulip_flags
&= ~TULIP_RXBUFSLOW
;
3853 TULIP_PERFEND(rxget
);
3856 #if defined(TULIP_DEBUG)
3857 sc
->tulip_dbg
.dbg_rxintrs
++;
3858 sc
->tulip_dbg
.dbg_rxpktsperintr
[cnt
]++;
3860 TULIP_PERFEND(rxintr
);
3865 tulip_softc_t
* const sc
)
3867 TULIP_PERFSTART(txintr
)
3868 tulip_ringinfo_t
* const ri
= &sc
->tulip_txinfo
;
3873 while (ri
->ri_free
< ri
->ri_max
) {
3876 TULIP_TXDESC_POSTSYNC(sc
, ri
->ri_nextin
, sizeof(*ri
->ri_nextin
));
3877 if (((volatile tulip_desc_t
*) ri
->ri_nextin
)->d_status
& TULIP_DSTS_OWNER
)
3882 d_flag
= ri
->ri_nextin
->d_flag
;
3883 if (d_flag
& TULIP_DFLAG_TxLASTSEG
) {
3884 if (d_flag
& TULIP_DFLAG_TxSETUPPKT
) {
3886 * We've just finished processing a setup packet.
3887 * Mark that we finished it. If there's not
3888 * another pending, startup the TULIP receiver.
3889 * Make sure we ack the RXSTOPPED so we won't get
3890 * an abormal interrupt indication.
3892 TULIP_TXMAP_POSTSYNC(sc
, sc
->tulip_setupmap
);
3893 sc
->tulip_flags
&= ~(TULIP_DOINGSETUP
|TULIP_HASHONLY
);
3894 if (ri
->ri_nextin
->d_flag
& TULIP_DFLAG_TxINVRSFILT
)
3895 sc
->tulip_flags
|= TULIP_HASHONLY
;
3896 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == 0) {
3898 sc
->tulip_cmdmode
|= TULIP_CMD_RXRUN
;
3899 sc
->tulip_intrmask
|= TULIP_STS_RXSTOPPED
;
3900 TULIP_CSR_WRITE(sc
, csr_status
, TULIP_STS_RXSTOPPED
);
3901 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3902 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
3905 const u_int32_t d_status
= ri
->ri_nextin
->d_status
;
3906 IF_DEQUEUE(&sc
->tulip_txq
, m
);
3908 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
3909 bus_dmamap_t map
= M_GETCTX(m
, bus_dmamap_t
);
3910 TULIP_TXMAP_POSTSYNC(sc
, map
);
3911 tulip_free_txmap(sc
, map
);
3912 #endif /* TULIP_BUS_DMA */
3914 if (sc
->tulip_bpf
!= NULL
)
3915 TULIP_BPF_MTAP(sc
, m
);
3918 #if defined(TULIP_DEBUG)
3920 printf(TULIP_PRINTF_FMT
": tx_intr: failed to dequeue mbuf?!?\n", TULIP_PRINTF_ARGS
);
3923 if (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) {
3924 tulip_mediapoll_event_t event
= TULIP_MEDIAPOLL_TXPROBE_OK
;
3925 if (d_status
& (TULIP_DSTS_TxNOCARR
|TULIP_DSTS_TxEXCCOLL
)) {
3926 #if defined(TULIP_DEBUG)
3927 if (d_status
& TULIP_DSTS_TxNOCARR
)
3928 sc
->tulip_dbg
.dbg_txprobe_nocarr
++;
3929 if (d_status
& TULIP_DSTS_TxEXCCOLL
)
3930 sc
->tulip_dbg
.dbg_txprobe_exccoll
++;
3932 event
= TULIP_MEDIAPOLL_TXPROBE_FAILED
;
3934 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, event
);
3936 * Escape from the loop before media poll has reset the TULIP!
3941 if (d_status
& TULIP_DSTS_ERRSUM
) {
3942 sc
->tulip_if
.if_oerrors
++;
3943 if (d_status
& TULIP_DSTS_TxEXCCOLL
)
3944 sc
->tulip_dot3stats
.dot3StatsExcessiveCollisions
++;
3945 if (d_status
& TULIP_DSTS_TxLATECOLL
)
3946 sc
->tulip_dot3stats
.dot3StatsLateCollisions
++;
3947 if (d_status
& (TULIP_DSTS_TxNOCARR
|TULIP_DSTS_TxCARRLOSS
))
3948 sc
->tulip_dot3stats
.dot3StatsCarrierSenseErrors
++;
3949 if (d_status
& (TULIP_DSTS_TxUNDERFLOW
|TULIP_DSTS_TxBABBLE
))
3950 sc
->tulip_dot3stats
.dot3StatsInternalMacTransmitErrors
++;
3951 if (d_status
& TULIP_DSTS_TxUNDERFLOW
)
3952 sc
->tulip_dot3stats
.dot3StatsInternalTransmitUnderflows
++;
3953 if (d_status
& TULIP_DSTS_TxBABBLE
)
3954 sc
->tulip_dot3stats
.dot3StatsInternalTransmitBabbles
++;
3956 u_int32_t collisions
=
3957 (d_status
& TULIP_DSTS_TxCOLLMASK
)
3958 >> TULIP_DSTS_V_TxCOLLCNT
;
3959 sc
->tulip_if
.if_collisions
+= collisions
;
3960 if (collisions
== 1)
3961 sc
->tulip_dot3stats
.dot3StatsSingleCollisionFrames
++;
3962 else if (collisions
> 1)
3963 sc
->tulip_dot3stats
.dot3StatsMultipleCollisionFrames
++;
3964 else if (d_status
& TULIP_DSTS_TxDEFERRED
)
3965 sc
->tulip_dot3stats
.dot3StatsDeferredTransmissions
++;
3967 * SQE is only valid for 10baseT/BNC/AUI when not
3968 * running in full-duplex. In order to speed up the
3969 * test, the corresponding bit in tulip_flags needs to
3970 * set as well to get us to count SQE Test Errors.
3972 if (d_status
& TULIP_DSTS_TxNOHRTBT
& sc
->tulip_flags
)
3973 sc
->tulip_dot3stats
.dot3StatsSQETestErrors
++;
3979 if (++ri
->ri_nextin
== ri
->ri_last
)
3980 ri
->ri_nextin
= ri
->ri_first
;
3982 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0)
3983 sc
->tulip_if
.if_flags
&= ~IFF_OACTIVE
;
3986 * If nothing left to transmit, disable the timer.
3987 * Else if progress, reset the timer back to 2 ticks.
3989 if (ri
->ri_free
== ri
->ri_max
|| (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
))
3990 sc
->tulip_txtimer
= 0;
3992 sc
->tulip_txtimer
= TULIP_TXTIMER
;
3993 sc
->tulip_if
.if_opackets
+= xmits
;
3994 TULIP_PERFEND(txintr
);
3999 tulip_print_abnormal_interrupt(
4000 tulip_softc_t
* const sc
,
4003 const char * const *msgp
= tulip_status_bits
;
4006 static const char thrsh
[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
4008 csr
&= (1 << (sizeof(tulip_status_bits
)/sizeof(tulip_status_bits
[0]))) - 1;
4009 printf(TULIP_PRINTF_FMT
": abnormal interrupt:", TULIP_PRINTF_ARGS
);
4010 for (sep
= " ", mask
= 1; mask
<= csr
; mask
<<= 1, msgp
++) {
4011 if ((csr
& mask
) && *msgp
!= NULL
) {
4012 printf("%s%s", sep
, *msgp
);
4013 if (mask
== TULIP_STS_TXUNDERFLOW
&& (sc
->tulip_flags
& TULIP_NEWTXTHRESH
)) {
4014 sc
->tulip_flags
&= ~TULIP_NEWTXTHRESH
;
4015 if (sc
->tulip_cmdmode
& TULIP_CMD_STOREFWD
) {
4016 printf(" (switching to store-and-forward mode)");
4018 printf(" (raising TX threshold to %s)",
4019 &thrsh
[9 * ((sc
->tulip_cmdmode
& TULIP_CMD_THRESHOLDCTL
) >> 14)]);
4030 tulip_softc_t
* const sc
,
4033 TULIP_PERFSTART(intr
)
4035 #if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
4041 while ((csr
= TULIP_CSR_READ(sc
, csr_status
)) & sc
->tulip_intrmask
) {
4042 #if defined(__NetBSD__) && !defined(TULIP_USE_SOFTINTR)
4043 if (only_once
== 1) {
4045 rnd_add_uint32(&sc
->tulip_rndsource
, csr
);
4052 TULIP_CSR_WRITE(sc
, csr_status
, csr
);
4054 if (csr
& TULIP_STS_SYSERROR
) {
4055 sc
->tulip_last_system_error
= (csr
& TULIP_STS_ERRORMASK
) >> TULIP_STS_ERR_SHIFT
;
4056 if (sc
->tulip_flags
& TULIP_NOMESSAGES
) {
4057 sc
->tulip_flags
|= TULIP_SYSTEMERROR
;
4059 printf(TULIP_PRINTF_FMT
": system error: %s\n",
4061 tulip_system_errors
[sc
->tulip_last_system_error
]);
4063 sc
->tulip_flags
|= TULIP_NEEDRESET
;
4064 sc
->tulip_system_errors
++;
4067 if (csr
& (TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
) & sc
->tulip_intrmask
) {
4068 #if defined(TULIP_DEBUG)
4069 sc
->tulip_dbg
.dbg_link_intrs
++;
4071 if (sc
->tulip_boardsw
->bd_media_poll
!= NULL
) {
4072 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, csr
& TULIP_STS_LINKFAIL
4073 ? TULIP_MEDIAPOLL_LINKFAIL
4074 : TULIP_MEDIAPOLL_LINKPASS
);
4075 csr
&= ~TULIP_STS_ABNRMLINTR
;
4077 tulip_media_print(sc
);
4079 if (csr
& (TULIP_STS_RXINTR
|TULIP_STS_RXNOBUF
)) {
4080 u_int32_t misses
= TULIP_CSR_READ(sc
, csr_missed_frames
);
4081 if (csr
& TULIP_STS_RXNOBUF
)
4082 sc
->tulip_dot3stats
.dot3StatsMissedFrames
+= misses
& 0xFFFF;
4084 * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
4085 * on receive overflows.
4087 if ((misses
& 0x0FFE0000) && (sc
->tulip_features
& TULIP_HAVE_RXBADOVRFLW
)) {
4088 sc
->tulip_dot3stats
.dot3StatsInternalMacReceiveErrors
++;
4090 * Stop the receiver process and spin until it's stopped.
4091 * Tell rx_intr to drop the packets it dequeues.
4093 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
& ~TULIP_CMD_RXRUN
);
4094 while ((TULIP_CSR_READ(sc
, csr_status
) & TULIP_STS_RXSTOPPED
) == 0)
4096 TULIP_CSR_WRITE(sc
, csr_status
, TULIP_STS_RXSTOPPED
);
4097 sc
->tulip_flags
|= TULIP_RXIGNORE
;
4100 if (sc
->tulip_flags
& TULIP_RXIGNORE
) {
4102 * Restart the receiver.
4104 sc
->tulip_flags
&= ~TULIP_RXIGNORE
;
4105 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
4108 if (csr
& TULIP_STS_ABNRMLINTR
) {
4109 u_int32_t tmp
= csr
& sc
->tulip_intrmask
4110 & ~(TULIP_STS_NORMALINTR
|TULIP_STS_ABNRMLINTR
);
4111 if (csr
& TULIP_STS_TXUNDERFLOW
) {
4112 if ((sc
->tulip_cmdmode
& TULIP_CMD_THRESHOLDCTL
) != TULIP_CMD_THRSHLD160
) {
4113 sc
->tulip_cmdmode
+= TULIP_CMD_THRSHLD96
;
4114 sc
->tulip_flags
|= TULIP_NEWTXTHRESH
;
4115 } else if (sc
->tulip_features
& TULIP_HAVE_STOREFWD
) {
4116 sc
->tulip_cmdmode
|= TULIP_CMD_STOREFWD
;
4117 sc
->tulip_flags
|= TULIP_NEWTXTHRESH
;
4120 if (sc
->tulip_flags
& TULIP_NOMESSAGES
) {
4121 sc
->tulip_statusbits
|= tmp
;
4123 tulip_print_abnormal_interrupt(sc
, tmp
);
4124 sc
->tulip_flags
|= TULIP_NOMESSAGES
;
4126 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
4128 if (sc
->tulip_flags
& (TULIP_WANTTXSTART
|TULIP_TXPROBE_ACTIVE
|TULIP_DOINGSETUP
|TULIP_PROMISC
)) {
4130 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0)
4131 tulip_ifstart(&sc
->tulip_if
);
4134 if (sc
->tulip_flags
& TULIP_NEEDRESET
) {
4138 TULIP_PERFEND(intr
);
4141 #if defined(TULIP_USE_SOFTINTR)
4143 * This is a experimental idea to alleviate problems due to interrupt
4144 * livelock. What is interrupt livelock? It's when you spend all your
4145 * time servicing device interrupts and never drop below device ipl
4146 * to do "useful" work.
4148 * So what we do here is see if the device needs service and if so,
4149 * disable interrupts (dismiss the interrupt), place it in a list of devices
4150 * needing service, and issue a network software interrupt.
4152 * When our network software interrupt routine gets called, we simply
4153 * walk done the list of devices that we have created and deal with them
4154 * at splnet/splsoftnet.
4158 tulip_hardintr_handler(
4159 tulip_softc_t
* const sc
,
4162 if (TULIP_CSR_READ(sc
, csr_status
) & (TULIP_STS_NORMALINTR
|TULIP_STS_ABNRMLINTR
) == 0)
4166 * disable interrupts
4168 TULIP_CSR_WRITE(sc
, csr_intr
, 0);
4170 * mark it as needing a software interrupt
4172 tulip_softintr_mask
|= (1U << sc
->tulip_unit
);
4174 #if defined(__NetBSD__) && NRND > 0
4176 * This isn't all that random (the value we feed in) but it is
4177 * better than a constant probably. It isn't used in entropy
4178 * calculation anyway, just to add something to the pool.
4180 rnd_add_uint32(&sc
->tulip_rndsource
, sc
->tulip_flags
);
4188 u_int32_t softintr_mask
, mask
;
4194 * Copy mask to local copy and reset global one to 0.
4196 s
= TULIP_RAISESPL();
4197 softintr_mask
= tulip_softintr_mask
;
4198 tulip_softintr_mask
= 0;
4199 TULIP_RESTORESPL(s
);
4202 * Optimize for the single unit case.
4204 if (tulip_softintr_max_unit
== 0) {
4205 if (softintr_mask
& 1) {
4206 tulip_softc_t
* const sc
= TULIP_UNIT_TO_SOFTC(0);
4208 * Handle the "interrupt" and then reenable interrupts
4211 tulip_intr_handler(sc
, &progress
);
4212 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
4218 * Handle all "queued" interrupts in a round robin fashion.
4219 * This is done so as not to favor a particular interface.
4221 unit
= tulip_softintr_last_unit
;
4222 mask
= (1U << unit
);
4223 while (softintr_mask
!= 0) {
4224 if (tulip_softintr_max_unit
== unit
) {
4227 unit
+= 1; mask
<<= 1;
4229 if (softintr_mask
& mask
) {
4230 tulip_softc_t
* const sc
= TULIP_UNIT_TO_SOFTC(unit
);
4232 * Handle the "interrupt" and then reenable interrupts
4234 softintr_mask
^= mask
;
4235 tulip_intr_handler(sc
, &progress
);
4236 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
4241 * Save where we ending up.
4243 tulip_softintr_last_unit
= unit
;
4245 #endif /* TULIP_USE_SOFTINTR */
4247 static tulip_intrfunc_t
4251 tulip_softc_t
* sc
= arg
;
4254 for (; sc
!= NULL
; sc
= sc
->tulip_slaves
) {
4255 #if defined(TULIP_DEBUG)
4256 sc
->tulip_dbg
.dbg_intrs
++;
4258 #if defined(TULIP_USE_SOFTINTR)
4259 tulip_hardintr_handler(sc
, &progress
);
4261 tulip_intr_handler(sc
, &progress
);
4264 #if defined(TULIP_USE_SOFTINTR)
4266 schednetisr(NETISR_DE
);
4268 #if !defined(TULIP_VOID_INTRFUNC)
4273 static tulip_intrfunc_t
4277 tulip_softc_t
* sc
= (tulip_softc_t
*) arg
;
4280 #if defined(TULIP_DEBUG)
4281 sc
->tulip_dbg
.dbg_intrs
++;
4283 #if defined(TULIP_USE_SOFTINTR)
4284 tulip_hardintr_handler(sc
, &progress
);
4286 schednetisr(NETISR_DE
);
4288 tulip_intr_handler(sc
, &progress
);
4290 #if !defined(TULIP_VOID_INTRFUNC)
4295 static struct mbuf
*
4296 tulip_mbuf_compress(
4300 #if MCLBYTES >= ETHERMTU + 18 && !defined(BIG_PACKET)
4301 MGETHDR(m0
, M_DONTWAIT
, MT_DATA
);
4303 if (m
->m_pkthdr
.len
> MHLEN
) {
4304 MCLGET(m0
, M_DONTWAIT
);
4305 if ((m0
->m_flags
& M_EXT
) == 0) {
4311 m_copydata(m
, 0, m
->m_pkthdr
.len
, mtod(m0
, void *));
4312 m0
->m_pkthdr
.len
= m0
->m_len
= m
->m_pkthdr
.len
;
4316 int len
= m
->m_pkthdr
.len
;
4317 struct mbuf
**mp
= &m0
;
4320 if (mlen
== MHLEN
) {
4321 MGETHDR(*mp
, M_DONTWAIT
, MT_DATA
);
4323 MGET(*mp
, M_DONTWAIT
, MT_DATA
);
4331 MCLGET(*mp
, M_DONTWAIT
);
4332 if (((*mp
)->m_flags
& M_EXT
) == 0) {
4337 (*mp
)->m_len
= len
<= MCLBYTES
? len
: MCLBYTES
;
4339 (*mp
)->m_len
= len
<= mlen
? len
: mlen
;
4341 m_copydata(m
, m
->m_pkthdr
.len
- len
,
4342 (*mp
)->m_len
, mtod((*mp
), void *));
4343 len
-= (*mp
)->m_len
;
4344 mp
= &(*mp
)->m_next
;
4352 static struct mbuf
*
4354 tulip_softc_t
* const sc
,
4357 TULIP_PERFSTART(txput
)
4358 tulip_ringinfo_t
* const ri
= &sc
->tulip_txinfo
;
4359 tulip_desc_t
*eop
, *nextout
;
4360 int segcnt
, freedescs
;
4362 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4369 #if defined(TULIP_DEBUG)
4370 if ((sc
->tulip_cmdmode
& TULIP_CMD_TXRUN
) == 0) {
4371 printf(TULIP_PRINTF_FMT
": txput%s: tx not running\n",
4373 (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) ? "(probe)" : "");
4374 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4375 sc
->tulip_dbg
.dbg_txput_finishes
[0]++;
4381 * Now we try to fill in our transmit descriptors. This is
4382 * a bit reminiscent of going on the Ark two by two
4383 * since each descriptor for the TULIP can describe
4384 * two buffers. So we advance through packet filling
4385 * each of the two entries at a time to to fill each
4386 * descriptor. Clear the first and last segment bits
4387 * in each descriptor (actually just clear everything
4388 * but the end-of-ring or chain bits) to make sure
4389 * we don't get messed up by previously sent packets.
4391 * We may fail to put the entire packet on the ring if
4392 * there is either not enough ring entries free or if the
4393 * packet has more than MAX_TXSEG segments. In the former
4394 * case we will just wait for the ring to empty. In the
4395 * latter case we have to recopy.
4397 #if !defined(TULIP_BUS_DMA) || defined(TULIP_BUS_DMA_NOTX)
4402 eop
= nextout
= ri
->ri_nextout
;
4404 freedescs
= ri
->ri_free
;
4406 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4408 * Reclaim some DMA maps from if we are out.
4410 if (sc
->tulip_num_free_txmaps
== 0) {
4411 #if defined(TULIP_DEBUG)
4412 sc
->tulip_dbg
.dbg_no_txmaps
++;
4414 freedescs
+= tulip_tx_intr(sc
);
4416 if (sc
->tulip_num_free_txmaps
> 0) {
4417 map
= tulip_alloc_txmap(sc
);
4419 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4420 #if defined(TULIP_DEBUG)
4421 sc
->tulip_dbg
.dbg_txput_finishes
[1]++;
4425 error
= bus_dmamap_load_mbuf(sc
->tulip_dmatag
, map
, m
, BUS_DMA_NOWAIT
);
4427 if (error
== EFBIG
) {
4429 * The packet exceeds the number of transmit buffer
4430 * entries that we can use for one packet, so we have
4431 * to recopy it into one mbuf and then try again.
4433 m
= tulip_mbuf_compress(m
);
4435 #if defined(TULIP_DEBUG)
4436 sc
->tulip_dbg
.dbg_txput_finishes
[2]++;
4438 tulip_free_txmap(sc
, map
);
4441 error
= bus_dmamap_load_mbuf(sc
->tulip_dmatag
, map
, m
, BUS_DMA_NOWAIT
);
4444 printf(TULIP_PRINTF_FMT
": unable to load tx map, "
4445 "error = %d\n", TULIP_PRINTF_ARGS
, error
);
4446 #if defined(TULIP_DEBUG)
4447 sc
->tulip_dbg
.dbg_txput_finishes
[3]++;
4449 tulip_free_txmap(sc
, map
);
4453 if ((freedescs
-= (map
->dm_nsegs
+ 1) / 2) <= 0
4455 * See if there's any unclaimed space in the transmit ring.
4457 && (freedescs
+= tulip_tx_intr(sc
)) <= 0) {
4459 * There's no more room but since nothing
4460 * has been committed at this point, just
4461 * show output is active, put back the
4464 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4465 #if defined(TULIP_DEBUG)
4466 sc
->tulip_dbg
.dbg_txput_finishes
[4]++;
4468 bus_dmamap_unload(sc
->tulip_dmatag
, map
);
4469 tulip_free_txmap(sc
, map
);
4472 for (; map
->dm_nsegs
- segcnt
> 1; segcnt
+= 2) {
4474 eop
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
4475 eop
->d_status
= d_status
;
4476 eop
->d_addr1
= map
->dm_segs
[segcnt
].ds_addr
;
4477 eop
->d_length1
= map
->dm_segs
[segcnt
].ds_len
;
4478 eop
->d_addr2
= map
->dm_segs
[segcnt
+1].ds_addr
;
4479 eop
->d_length2
= map
->dm_segs
[segcnt
+1].ds_len
;
4480 d_status
= TULIP_DSTS_OWNER
;
4481 if (++nextout
== ri
->ri_last
)
4482 nextout
= ri
->ri_first
;
4484 if (segcnt
< map
->dm_nsegs
) {
4486 eop
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
4487 eop
->d_status
= d_status
;
4488 eop
->d_addr1
= map
->dm_segs
[segcnt
].ds_addr
;
4489 eop
->d_length1
= map
->dm_segs
[segcnt
].ds_len
;
4492 if (++nextout
== ri
->ri_last
)
4493 nextout
= ri
->ri_first
;
4495 TULIP_TXMAP_PRESYNC(sc
, map
);
4499 #else /* !TULIP_BUS_DMA */
4502 int len
= m0
->m_len
;
4503 void *addr
= mtod(m0
, void *);
4504 unsigned clsize
= PAGE_SIZE
- (((u_long
) addr
) & PAGE_MASK
);
4507 unsigned slen
= min(len
, clsize
);
4511 slen
= 2040, partial
= 1;
4514 if (segcnt
> TULIP_MAX_TXSEG
) {
4516 * The packet exceeds the number of transmit buffer
4517 * entries that we can use for one packet, so we have
4518 * recopy it into one mbuf and then try again.
4520 m
= tulip_mbuf_compress(m
);
4526 if (--freedescs
== 0) {
4528 * See if there's any unclaimed space in the
4531 if ((freedescs
+= tulip_tx_intr(sc
)) == 0) {
4533 * There's no more room but since nothing
4534 * has been committed at this point, just
4535 * show output is active, put back the
4538 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4539 #if defined(TULIP_DEBUG)
4540 sc
->tulip_dbg
.dbg_txput_finishes
[1]++;
4546 if (++nextout
== ri
->ri_last
)
4547 nextout
= ri
->ri_first
;
4548 eop
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
4549 eop
->d_status
= d_status
;
4550 eop
->d_addr1
= TULIP_KVATOPHYS(sc
, addr
);
4551 eop
->d_length1
= slen
;
4554 * Fill in second half of descriptor
4556 eop
->d_addr2
= TULIP_KVATOPHYS(sc
, addr
);
4557 eop
->d_length2
= slen
;
4559 d_status
= TULIP_DSTS_OWNER
;
4568 } while ((m0
= m0
->m_next
) != NULL
);
4569 #endif /* TULIP_BUS_DMA */
4572 * The descriptors have been filled in. Now get ready
4575 IF_ENQUEUE(&sc
->tulip_txq
, m
);
4579 * Make sure the next descriptor after this packet is owned
4580 * by us since it may have been set up above if we ran out
4581 * of room in the ring.
4583 nextout
->d_status
= 0;
4584 TULIP_TXDESC_PRESYNC(sc
, nextout
, sizeof(u_int32_t
));
4586 #if !defined(TULIP_BUS_DMA) || defined(TULIP_BUS_DMA_NOTX)
4588 * If we only used the first segment of the last descriptor,
4589 * make sure the second segment will not be used.
4595 #endif /* TULIP_BUS_DMA */
4598 * Mark the last and first segments, indicate we want a transmit
4599 * complete interrupt, and tell it to transmit!
4601 eop
->d_flag
|= TULIP_DFLAG_TxLASTSEG
|TULIP_DFLAG_TxWANTINTR
;
4604 * Note that ri->ri_nextout is still the start of the packet
4605 * and until we set the OWNER bit, we can still back out of
4606 * everything we have done.
4608 ri
->ri_nextout
->d_flag
|= TULIP_DFLAG_TxFIRSTSEG
;
4609 #if defined(TULIP_BUS_MAP) && !defined(TULIP_BUS_DMA_NOTX)
4610 if (eop
< ri
->ri_nextout
) {
4611 TULIP_TXDESC_PRESYNC(sc
, ri
->ri_nextout
,
4612 (void *) ri
->ri_last
- (void *) ri
->ri_nextout
);
4613 TULIP_TXDESC_PRESYNC(sc
, ri
->ri_first
,
4614 (void *) (eop
+ 1) - (void *) ri
->ri_first
);
4616 TULIP_TXDESC_PRESYNC(sc
, ri
->ri_nextout
,
4617 (void *) (eop
+ 1) - (void *) ri
->ri_nextout
);
4620 ri
->ri_nextout
->d_status
= TULIP_DSTS_OWNER
;
4621 TULIP_TXDESC_PRESYNC(sc
, ri
->ri_nextout
, sizeof(u_int32_t
));
4624 * This advances the ring for us.
4626 ri
->ri_nextout
= nextout
;
4627 ri
->ri_free
= freedescs
;
4629 TULIP_PERFEND(txput
);
4631 if (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) {
4632 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
4633 sc
->tulip_if
.if_flags
|= IFF_OACTIVE
;
4634 sc
->tulip_if
.if_start
= tulip_ifstart
;
4635 TULIP_PERFEND(txput
);
4640 * switch back to the single queueing ifstart.
4642 sc
->tulip_flags
&= ~TULIP_WANTTXSTART
;
4643 if (sc
->tulip_txtimer
== 0)
4644 sc
->tulip_txtimer
= TULIP_TXTIMER
;
4645 #if defined(TULIP_DEBUG)
4646 sc
->tulip_dbg
.dbg_txput_finishes
[5]++;
4650 * If we want a txstart, there must be not enough space in the
4651 * transmit ring. So we want to enable transmit done interrupts
4652 * so we can immediately reclaim some space. When the transmit
4653 * interrupt is posted, the interrupt handler will call tx_intr
4654 * to reclaim space and then txstart (since WANTTXSTART is set).
4655 * txstart will move the packet into the transmit ring and clear
4656 * WANTTXSTART thereby causing TXINTR to be cleared.
4659 #if defined(TULIP_DEBUG)
4660 sc
->tulip_dbg
.dbg_txput_finishes
[6]++;
4662 if (sc
->tulip_flags
& (TULIP_WANTTXSTART
|TULIP_DOINGSETUP
)) {
4663 sc
->tulip_if
.if_flags
|= IFF_OACTIVE
;
4664 sc
->tulip_if
.if_start
= tulip_ifstart
;
4665 if ((sc
->tulip_intrmask
& TULIP_STS_TXINTR
) == 0) {
4666 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
4667 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
4669 } else if ((sc
->tulip_flags
& TULIP_PROMISC
) == 0) {
4670 if (sc
->tulip_intrmask
& TULIP_STS_TXINTR
) {
4671 sc
->tulip_intrmask
&= ~TULIP_STS_TXINTR
;
4672 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
4675 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
4676 TULIP_PERFEND(txput
);
4682 tulip_softc_t
* const sc
)
4684 tulip_ringinfo_t
* const ri
= &sc
->tulip_txinfo
;
4685 tulip_desc_t
*nextout
;
4688 * We will transmit, at most, one setup packet per call to ifstart.
4691 #if defined(TULIP_DEBUG)
4692 if ((sc
->tulip_cmdmode
& TULIP_CMD_TXRUN
) == 0) {
4693 printf(TULIP_PRINTF_FMT
": txput_setup: tx not running\n",
4695 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4696 sc
->tulip_if
.if_start
= tulip_ifstart
;
4701 * Try to reclaim some free descriptors..
4703 if (ri
->ri_free
< 2)
4705 if ((sc
->tulip_flags
& TULIP_DOINGSETUP
) || ri
->ri_free
== 1) {
4706 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
4707 sc
->tulip_if
.if_start
= tulip_ifstart
;
4710 memcpy(sc
->tulip_setupbuf
, sc
->tulip_setupdata
,
4711 sizeof(sc
->tulip_setupbuf
));
4713 * Clear WANTSETUP and set DOINGSETUP. Set know that WANTSETUP is
4714 * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
4716 sc
->tulip_flags
^= TULIP_WANTSETUP
|TULIP_DOINGSETUP
;
4718 nextout
= ri
->ri_nextout
;
4719 nextout
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
4720 nextout
->d_flag
|= TULIP_DFLAG_TxFIRSTSEG
|TULIP_DFLAG_TxLASTSEG
4721 |TULIP_DFLAG_TxSETUPPKT
|TULIP_DFLAG_TxWANTINTR
;
4722 if (sc
->tulip_flags
& TULIP_WANTHASHPERFECT
)
4723 nextout
->d_flag
|= TULIP_DFLAG_TxHASHFILT
;
4724 else if (sc
->tulip_flags
& TULIP_WANTHASHONLY
)
4725 nextout
->d_flag
|= TULIP_DFLAG_TxHASHFILT
|TULIP_DFLAG_TxINVRSFILT
;
4727 nextout
->d_length2
= 0;
4728 nextout
->d_addr2
= 0;
4729 #if defined(TULIP_BUS_DMA) && !defined(TULIP_BUS_DMA_NOTX)
4730 nextout
->d_length1
= sc
->tulip_setupmap
->dm_segs
[0].ds_len
;
4731 nextout
->d_addr1
= sc
->tulip_setupmap
->dm_segs
[0].ds_addr
;
4732 if (sc
->tulip_setupmap
->dm_nsegs
== 2) {
4733 nextout
->d_length2
= sc
->tulip_setupmap
->dm_segs
[1].ds_len
;
4734 nextout
->d_addr2
= sc
->tulip_setupmap
->dm_segs
[1].ds_addr
;
4736 TULIP_TXMAP_PRESYNC(sc
, sc
->tulip_setupmap
);
4737 TULIP_TXDESC_PRESYNC(sc
, nextout
, sizeof(*nextout
));
4739 nextout
->d_length1
= sizeof(sc
->tulip_setupbuf
);
4740 nextout
->d_addr1
= TULIP_KVATOPHYS(sc
, sc
->tulip_setupbuf
);
4744 * Advance the ring for the next transmit packet.
4746 if (++ri
->ri_nextout
== ri
->ri_last
)
4747 ri
->ri_nextout
= ri
->ri_first
;
4750 * Make sure the next descriptor is owned by us since it
4751 * may have been set up above if we ran out of room in the
4754 ri
->ri_nextout
->d_status
= 0;
4755 TULIP_TXDESC_PRESYNC(sc
, ri
->ri_nextout
, sizeof(u_int32_t
));
4756 nextout
->d_status
= TULIP_DSTS_OWNER
;
4758 * Flush the ownwership of the current descriptor
4760 TULIP_TXDESC_PRESYNC(sc
, nextout
, sizeof(u_int32_t
));
4761 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
4762 if ((sc
->tulip_intrmask
& TULIP_STS_TXINTR
) == 0) {
4763 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
4764 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
4770 * This routine is entered at splnet() (splsoftnet() on NetBSD)
4771 * and thereby imposes no problems when TULIP_USE_SOFTINTR is
4775 tulip_ifioctl(struct ifnet
*ifp
, unsigned long cmd
, void *data
)
4777 TULIP_PERFSTART(ifioctl
)
4778 tulip_softc_t
* const sc
= TULIP_IFP_TO_SOFTC(ifp
);
4779 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
4780 struct ifreq
*ifr
= (struct ifreq
*) data
;
4784 #if defined(TULIP_USE_SOFTINTR)
4785 s
= TULIP_RAISESOFTSPL();
4787 s
= TULIP_RAISESPL();
4790 case SIOCINITIFADDR
: {
4791 ifp
->if_flags
|= IFF_UP
;
4793 switch(ifa
->ifa_addr
->sa_family
) {
4796 TULIP_ARP_IFINIT(sc
, ifa
);
4805 case SIOCSIFFLAGS
: {
4806 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
4808 #if !defined(IFM_ETHER)
4810 if (ifp
->if_flags
& IFF_LINK0
) flags
|= 1;
4811 if (ifp
->if_flags
& IFF_LINK1
) flags
|= 2;
4812 if (ifp
->if_flags
& IFF_LINK2
) flags
|= 4;
4814 ifp
->if_flags
&= ~(IFF_LINK0
|IFF_LINK1
|IFF_LINK2
);
4815 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
4816 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
4817 sc
->tulip_flags
&= ~(TULIP_WANTRXACT
|TULIP_LINKUP
|TULIP_NOAUTOSENSE
);
4820 tulip_media_t media
;
4821 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
4822 if (sc
->tulip_mediums
[media
] != NULL
&& --flags
== 0) {
4823 sc
->tulip_flags
|= TULIP_NOAUTOSENSE
;
4824 if (sc
->tulip_media
!= media
|| (sc
->tulip_flags
& TULIP_DIDNWAY
)) {
4825 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
4826 tulip_linkup(sc
, media
);
4832 printf(TULIP_PRINTF_FMT
": ignored invalid media request\n", TULIP_PRINTF_ARGS
);
4839 #if defined(SIOCSIFMEDIA)
4841 case SIOCGIFMEDIA
: {
4842 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->tulip_ifmedia
, cmd
);
4848 case SIOCDELMULTI
: {
4850 * Update multicast listeners
4852 if ((error
= ether_ioctl(ifp
, cmd
, data
)) == ENETRESET
) {
4853 if (ifp
->if_flags
& IFF_RUNNING
) {
4854 tulip_addr_filter(sc
); /* reset multicast filtering */
4861 #if defined(SIOCSIFMTU)
4862 #if !defined(ifr_mtu)
4863 #define ifr_mtu ifr_metric
4867 * Set the interface MTU.
4869 if (ifr
->ifr_mtu
> ETHERMTU
4871 && sc
->tulip_chipid
!= TULIP_21140
4872 && sc
->tulip_chipid
!= TULIP_21140A
4873 && sc
->tulip_chipid
!= TULIP_21041
4879 if ((error
= ifioctl_common(ifp
, cmd
, data
)) == ENETRESET
) {
4887 #endif /* SIOCSIFMTU */
4890 case SIOCGADDRROM
: {
4891 error
= copyout(sc
->tulip_rombuf
, ifr
->ifr_data
, sizeof(sc
->tulip_rombuf
));
4897 ifr
->ifr_metric
= (int) sc
->tulip_chipid
;
4902 error
= ether_ioctl(ifp
, cmd
, data
);
4907 TULIP_RESTORESPL(s
);
4908 TULIP_PERFEND(ifioctl
);
4913 * These routines gets called at device spl (from ether_output). This might
4914 * pose a problem for TULIP_USE_SOFTINTR if ether_output is called at
4915 * device spl from another driver.
4920 struct ifnet
* const ifp
)
4922 TULIP_PERFSTART(ifstart
)
4923 tulip_softc_t
* const sc
= TULIP_IFP_TO_SOFTC(ifp
);
4925 if (sc
->tulip_if
.if_flags
& IFF_RUNNING
) {
4927 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == TULIP_WANTSETUP
)
4928 tulip_txput_setup(sc
);
4930 while (sc
->tulip_if
.if_snd
.ifq_head
!= NULL
) {
4932 IF_DEQUEUE(&sc
->tulip_if
.if_snd
, m
);
4933 if ((m
= tulip_txput(sc
, m
)) != NULL
) {
4934 IF_PREPEND(&sc
->tulip_if
.if_snd
, m
);
4938 if (sc
->tulip_if
.if_snd
.ifq_head
== NULL
)
4939 sc
->tulip_if
.if_start
= tulip_ifstart_one
;
4942 TULIP_PERFEND(ifstart
);
4947 struct ifnet
* const ifp
)
4949 TULIP_PERFSTART(ifstart_one
)
4950 tulip_softc_t
* const sc
= TULIP_IFP_TO_SOFTC(ifp
);
4952 if ((sc
->tulip_if
.if_flags
& IFF_RUNNING
)
4953 && sc
->tulip_if
.if_snd
.ifq_head
!= NULL
) {
4955 IF_DEQUEUE(&sc
->tulip_if
.if_snd
, m
);
4956 if ((m
= tulip_txput(sc
, m
)) != NULL
)
4957 IF_PREPEND(&sc
->tulip_if
.if_snd
, m
);
4959 TULIP_PERFEND(ifstart_one
);
4963 * Even though this routine runs at device spl, it does not break
4964 * our use of splnet (splsoftnet under NetBSD) for the majority
4965 * of this driver (if TULIP_USE_SOFTINTR defined) since
4966 * if_watcbog is called from if_watchdog which is called from
4967 * splsoftclock which is below spl[soft]net.
4973 TULIP_PERFSTART(ifwatchdog
)
4974 tulip_softc_t
* const sc
= TULIP_IFP_TO_SOFTC(ifp
);
4976 #if defined(TULIP_DEBUG)
4977 u_int32_t rxintrs
= sc
->tulip_dbg
.dbg_rxintrs
- sc
->tulip_dbg
.dbg_last_rxintrs
;
4978 if (rxintrs
> sc
->tulip_dbg
.dbg_high_rxintrs_hz
)
4979 sc
->tulip_dbg
.dbg_high_rxintrs_hz
= rxintrs
;
4980 sc
->tulip_dbg
.dbg_last_rxintrs
= sc
->tulip_dbg
.dbg_rxintrs
;
4981 #endif /* TULIP_DEBUG */
4983 sc
->tulip_if
.if_timer
= 1;
4985 * These should be rare so do a bulk test up front so we can just skip
4988 if (sc
->tulip_flags
& (TULIP_SYSTEMERROR
|TULIP_RXBUFSLOW
|TULIP_NOMESSAGES
)) {
4990 * If the number of receive buffer is low, try to refill
4992 if (sc
->tulip_flags
& TULIP_RXBUFSLOW
)
4995 if (sc
->tulip_flags
& TULIP_SYSTEMERROR
) {
4996 printf(TULIP_PRINTF_FMT
": %d system errors: last was %s\n",
4997 TULIP_PRINTF_ARGS
, sc
->tulip_system_errors
,
4998 tulip_system_errors
[sc
->tulip_last_system_error
]);
5000 if (sc
->tulip_statusbits
) {
5001 tulip_print_abnormal_interrupt(sc
, sc
->tulip_statusbits
);
5002 sc
->tulip_statusbits
= 0;
5005 sc
->tulip_flags
&= ~(TULIP_NOMESSAGES
|TULIP_SYSTEMERROR
);
5008 if (sc
->tulip_txtimer
)
5010 if (sc
->tulip_txtimer
&& --sc
->tulip_txtimer
== 0) {
5011 printf(TULIP_PRINTF_FMT
": transmission timeout\n", TULIP_PRINTF_ARGS
);
5012 if (TULIP_DO_AUTOSENSE(sc
)) {
5013 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
5014 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
5015 sc
->tulip_flags
&= ~(TULIP_WANTRXACT
|TULIP_LINKUP
);
5021 TULIP_PERFEND(ifwatchdog
);
5022 TULIP_PERFMERGE(sc
, perf_intr_cycles
);
5023 TULIP_PERFMERGE(sc
, perf_ifstart_cycles
);
5024 TULIP_PERFMERGE(sc
, perf_ifioctl_cycles
);
5025 TULIP_PERFMERGE(sc
, perf_ifwatchdog_cycles
);
5026 TULIP_PERFMERGE(sc
, perf_timeout_cycles
);
5027 TULIP_PERFMERGE(sc
, perf_ifstart_one_cycles
);
5028 TULIP_PERFMERGE(sc
, perf_txput_cycles
);
5029 TULIP_PERFMERGE(sc
, perf_txintr_cycles
);
5030 TULIP_PERFMERGE(sc
, perf_rxintr_cycles
);
5031 TULIP_PERFMERGE(sc
, perf_rxget_cycles
);
5032 TULIP_PERFMERGE(sc
, perf_intr
);
5033 TULIP_PERFMERGE(sc
, perf_ifstart
);
5034 TULIP_PERFMERGE(sc
, perf_ifioctl
);
5035 TULIP_PERFMERGE(sc
, perf_ifwatchdog
);
5036 TULIP_PERFMERGE(sc
, perf_timeout
);
5037 TULIP_PERFMERGE(sc
, perf_ifstart_one
);
5038 TULIP_PERFMERGE(sc
, perf_txput
);
5039 TULIP_PERFMERGE(sc
, perf_txintr
);
5040 TULIP_PERFMERGE(sc
, perf_rxintr
);
5041 TULIP_PERFMERGE(sc
, perf_rxget
);
5044 #if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506)
5046 tulip_ifwatchdog_wrapper(
5049 tulip_ifwatchdog(&TULIP_UNIT_TO_SOFTC(unit
)->tulip_if
);
5051 #define tulip_ifwatchdog tulip_ifwatchdog_wrapper
5055 * All printf's are real as of now!
5060 #if !defined(IFF_NOTRAILERS)
5061 #define IFF_NOTRAILERS 0
5066 tulip_softc_t
* const sc
)
5068 struct ifnet
* const ifp
= &sc
->tulip_if
;
5070 ifp
->if_flags
= IFF_BROADCAST
|IFF_SIMPLEX
|IFF_NOTRAILERS
|IFF_MULTICAST
;
5071 ifp
->if_ioctl
= tulip_ifioctl
;
5072 ifp
->if_start
= tulip_ifstart
;
5073 ifp
->if_watchdog
= tulip_ifwatchdog
;
5075 #if (!defined(__bsdi__) || _BSDI_VERSION < 199401) && !defined(__NetBSD__)
5076 ifp
->if_output
= ether_output
;
5078 #if defined(__bsdi__) && _BSDI_VERSION < 199401
5079 ifp
->if_mtu
= ETHERMTU
;
5082 #if defined(__bsdi__) && _BSDI_VERSION >= 199510
5083 aprint_naive(": DEC Ethernet");
5084 aprint_normal(": %s%s", sc
->tulip_boardid
,
5085 tulip_chipdescs
[sc
->tulip_chipid
]);
5086 aprint_verbose(" pass %d.%d", (sc
->tulip_revinfo
& 0xF0) >> 4,
5087 sc
->tulip_revinfo
& 0x0F);
5089 sc
->tulip_pf
= aprint_normal
;
5090 aprint_normal(TULIP_PRINTF_FMT
": address " TULIP_EADDR_FMT
"\n",
5092 TULIP_EADDR_ARGS(sc
->tulip_enaddr
));
5095 #if defined(__bsdi__)
5098 TULIP_PRINTF_FMT
": %s%s pass %d.%d%s\n",
5101 tulip_chipdescs
[sc
->tulip_chipid
],
5102 (sc
->tulip_revinfo
& 0xF0) >> 4,
5103 sc
->tulip_revinfo
& 0x0F,
5104 (sc
->tulip_features
& (TULIP_HAVE_ISVSROM
|TULIP_HAVE_OKSROM
))
5105 == TULIP_HAVE_ISVSROM
? " (invalid EESPROM checksum)" : "");
5106 printf(TULIP_PRINTF_FMT
": address " TULIP_EADDR_FMT
"\n",
5108 TULIP_EADDR_ARGS(sc
->tulip_enaddr
));
5111 #if defined(__alpha__)
5113 * In case the SRM console told us about a bogus media,
5114 * we need to check to be safe.
5116 if (sc
->tulip_mediums
[sc
->tulip_media
] == NULL
)
5117 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
5120 (*sc
->tulip_boardsw
->bd_media_probe
)(sc
);
5121 #if defined(IFM_ETHER)
5122 ifmedia_init(&sc
->tulip_ifmedia
, 0,
5123 tulip_ifmedia_change
,
5124 tulip_ifmedia_status
);
5127 tulip_media_t media
;
5129 printf(TULIP_PRINTF_FMT
": media:", TULIP_PRINTF_ARGS
);
5130 for (media
= TULIP_MEDIA_UNKNOWN
, cnt
= 1; cnt
< 7 && media
< TULIP_MEDIA_MAX
; media
++) {
5131 if (sc
->tulip_mediums
[media
] != NULL
) {
5132 printf(" %d=\"%s\"", cnt
, tulip_mediums
[media
]);
5137 sc
->tulip_features
|= TULIP_HAVE_NOMEDIA
;
5144 sc
->tulip_flags
&= ~TULIP_DEVICEPROBE
;
5145 #if defined(IFM_ETHER)
5146 tulip_ifmedia_add(sc
);
5151 #if defined(__bsdi__) && _BSDI_VERSION >= 199510
5152 sc
->tulip_pf
= printf
;
5153 TULIP_ETHER_IFATTACH(sc
);
5156 #if defined(__NetBSD__) || (defined(__FreeBSD__) && BSD >= 199506)
5157 TULIP_ETHER_IFATTACH(sc
);
5159 #endif /* __bsdi__ */
5161 #if defined(__NetBSD__) && NRND > 0
5162 rnd_attach_source(&sc
->tulip_rndsource
, device_xname(&sc
->tulip_dev
),
5167 #if defined(TULIP_BUS_DMA)
5168 #if !defined(TULIP_BUS_DMA_NOTX) || !defined(TULIP_BUS_DMA_NORX)
5170 tulip_busdma_allocmem(
5171 tulip_softc_t
* const sc
,
5173 bus_dmamap_t
*map_p
,
5174 tulip_desc_t
**desc_p
)
5176 bus_dma_segment_t segs
[1];
5178 error
= bus_dmamem_alloc(sc
->tulip_dmatag
, size
, 1, PAGE_SIZE
,
5179 segs
, sizeof(segs
)/sizeof(segs
[0]),
5180 &nsegs
, BUS_DMA_NOWAIT
);
5183 error
= bus_dmamem_map(sc
->tulip_dmatag
, segs
, nsegs
, size
,
5184 (void *) &desc
, BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
);
5187 error
= bus_dmamap_create(sc
->tulip_dmatag
, size
, 1, size
, 0,
5188 BUS_DMA_NOWAIT
, &map
);
5190 error
= bus_dmamap_load(sc
->tulip_dmatag
, map
, desc
,
5191 size
, NULL
, BUS_DMA_NOWAIT
);
5193 bus_dmamap_destroy(sc
->tulip_dmatag
, map
);
5198 bus_dmamem_unmap(sc
->tulip_dmatag
, desc
, size
);
5201 bus_dmamem_free(sc
->tulip_dmatag
, segs
, nsegs
);
5211 tulip_softc_t
* const sc
)
5215 #if !defined(TULIP_BUS_DMA_NOTX)
5217 * Allocate dmamap for setup descriptor
5219 error
= bus_dmamap_create(sc
->tulip_dmatag
, sizeof(sc
->tulip_setupbuf
), 2,
5220 sizeof(sc
->tulip_setupbuf
), 0, BUS_DMA_NOWAIT
,
5221 &sc
->tulip_setupmap
);
5223 error
= bus_dmamap_load(sc
->tulip_dmatag
, sc
->tulip_setupmap
,
5224 sc
->tulip_setupbuf
, sizeof(sc
->tulip_setupbuf
),
5225 NULL
, BUS_DMA_NOWAIT
);
5227 bus_dmamap_destroy(sc
->tulip_dmatag
, sc
->tulip_setupmap
);
5230 * Allocate space and dmamap for transmit ring
5233 error
= tulip_busdma_allocmem(sc
, sizeof(tulip_desc_t
) * TULIP_TXDESCS
,
5234 &sc
->tulip_txdescmap
,
5235 &sc
->tulip_txdescs
);
5239 * Allocate dmamaps for each transmit descriptor, and place on the
5243 while (error
== 0 && sc
->tulip_num_free_txmaps
< TULIP_TXDESCS
) {
5245 if ((error
= TULIP_TXMAP_CREATE(sc
, &map
)) == 0)
5246 tulip_free_txmap(sc
, map
);
5249 while (sc
->tulip_num_free_txmaps
> 0)
5250 bus_dmamap_destroy(sc
->tulip_dmatag
, tulip_alloc_txmap(sc
));
5255 sc
->tulip_txdescs
= (tulip_desc_t
*) malloc(TULIP_TXDESCS
* sizeof(tulip_desc_t
), M_DEVBUF
, M_NOWAIT
);
5256 if (sc
->tulip_txdescs
== NULL
)
5260 #if !defined(TULIP_BUS_DMA_NORX)
5262 * Allocate space and dmamap for receive ring
5265 error
= tulip_busdma_allocmem(sc
, sizeof(tulip_desc_t
) * TULIP_RXDESCS
,
5266 &sc
->tulip_rxdescmap
,
5267 &sc
->tulip_rxdescs
);
5271 * Allocate dmamaps for each receive descriptor, and place on the
5275 while (error
== 0 && sc
->tulip_num_free_rxmaps
< TULIP_RXDESCS
) {
5277 if ((error
= TULIP_RXMAP_CREATE(sc
, &map
)) == 0)
5278 tulip_free_rxmap(sc
, map
);
5281 while (sc
->tulip_num_free_rxmaps
> 0)
5282 bus_dmamap_destroy(sc
->tulip_dmatag
, tulip_alloc_rxmap(sc
));
5287 sc
->tulip_rxdescs
= (tulip_desc_t
*) malloc(TULIP_RXDESCS
* sizeof(tulip_desc_t
), M_DEVBUF
, M_NOWAIT
);
5288 if (sc
->tulip_rxdescs
== NULL
)
5294 #endif /* TULIP_BUS_DMA */
5298 tulip_softc_t
* const sc
,
5299 tulip_csrptr_t csr_base
,
5302 sc
->tulip_csrs
.csr_busmode
= csr_base
+ 0 * csr_size
;
5303 sc
->tulip_csrs
.csr_txpoll
= csr_base
+ 1 * csr_size
;
5304 sc
->tulip_csrs
.csr_rxpoll
= csr_base
+ 2 * csr_size
;
5305 sc
->tulip_csrs
.csr_rxlist
= csr_base
+ 3 * csr_size
;
5306 sc
->tulip_csrs
.csr_txlist
= csr_base
+ 4 * csr_size
;
5307 sc
->tulip_csrs
.csr_status
= csr_base
+ 5 * csr_size
;
5308 sc
->tulip_csrs
.csr_command
= csr_base
+ 6 * csr_size
;
5309 sc
->tulip_csrs
.csr_intr
= csr_base
+ 7 * csr_size
;
5310 sc
->tulip_csrs
.csr_missed_frames
= csr_base
+ 8 * csr_size
;
5311 sc
->tulip_csrs
.csr_9
= csr_base
+ 9 * csr_size
;
5312 sc
->tulip_csrs
.csr_10
= csr_base
+ 10 * csr_size
;
5313 sc
->tulip_csrs
.csr_11
= csr_base
+ 11 * csr_size
;
5314 sc
->tulip_csrs
.csr_12
= csr_base
+ 12 * csr_size
;
5315 sc
->tulip_csrs
.csr_13
= csr_base
+ 13 * csr_size
;
5316 sc
->tulip_csrs
.csr_14
= csr_base
+ 14 * csr_size
;
5317 sc
->tulip_csrs
.csr_15
= csr_base
+ 15 * csr_size
;
5318 #if defined(TULIP_EISA)
5319 sc
->tulip_csrs
.csr_enetrom
= csr_base
+ DE425_ENETROM_OFFSET
;
5325 tulip_softc_t
* const sc
,
5326 tulip_ringinfo_t
* const ri
,
5327 tulip_desc_t
*descs
,
5330 ri
->ri_max
= ndescs
;
5331 ri
->ri_first
= descs
;
5332 ri
->ri_last
= ri
->ri_first
+ ri
->ri_max
;
5333 memset((void *) ri
->ri_first
, 0, sizeof(ri
->ri_first
[0]) * ri
->ri_max
);
5334 ri
->ri_last
[-1].d_flag
= TULIP_DFLAG_ENDRING
;
5338 * This is the PCI configuration support. Since the 21040 is available
5339 * on both EISA and PCI boards, one must be careful in how defines the
5340 * 21040 in the config file.
5343 #define PCI_CFID 0x00 /* Configuration ID */
5344 #define PCI_CFCS 0x04 /* Configurtion Command/Status */
5345 #define PCI_CFRV 0x08 /* Configuration Revision */
5346 #define PCI_CFLT 0x0c /* Configuration Latency Timer */
5347 #define PCI_CBIO 0x10 /* Configuration Base IO Address */
5348 #define PCI_CBMA 0x14 /* Configuration Base Memory Address */
5349 #define PCI_CFIT 0x3c /* Configuration Interrupt */
5350 #define PCI_CFDA 0x40 /* Configuration Driver Area */
5352 #if defined(TULIP_EISA)
5353 static const int tulip_eisa_irqs
[4] = { IRQ5
, IRQ9
, IRQ10
, IRQ11
};
5356 #if defined(__FreeBSD__)
5358 #define TULIP_PCI_ATTACH_ARGS pcici_t config_id, int unit
5359 #define TULIP_SHUTDOWN_ARGS int howto, void *arg
5361 #if defined(TULIP_DEVCONF)
5362 static void tulip_shutdown(TULIP_SHUTDOWN_ARGS
);
5366 struct kern_devconf
* const kdc
,
5369 if (kdc
->kdc_unit
< TULIP_MAX_DEVICES
) {
5370 tulip_softc_t
* const sc
= TULIP_UNIT_TO_SOFTC(kdc
->kdc_unit
);
5372 tulip_shutdown(0, sc
);
5374 (void) dev_detach(kdc
);
5384 if (PCI_VENDORID(device_id
) != DEC_VENDORID
)
5386 if (PCI_CHIPID(device_id
) == CHIPID_21040
)
5387 return "Digital 21040 Ethernet";
5388 if (PCI_CHIPID(device_id
) == CHIPID_21041
)
5389 return "Digital 21041 Ethernet";
5390 if (PCI_CHIPID(device_id
) == CHIPID_21140
) {
5391 u_int32_t revinfo
= pci_conf_read(config_id
, PCI_CFRV
) & 0xFF;
5392 if (revinfo
>= 0x20)
5393 return "Digital 21140A Fast Ethernet";
5395 return "Digital 21140 Fast Ethernet";
5397 if (PCI_CHIPID(device_id
) == CHIPID_21142
) {
5398 u_int32_t revinfo
= pci_conf_read(config_id
, PCI_CFRV
) & 0xFF;
5399 if (revinfo
>= 0x20)
5400 return "Digital 21143 Fast Ethernet";
5402 return "Digital 21142 Fast Ethernet";
5407 static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS
);
5408 static u_long tulip_pci_count
;
5410 struct pci_device dedevice
= {
5415 #if defined(TULIP_DEVCONF)
5420 DATA_SET (pcidevice_set
, dedevice
);
5421 #endif /* __FreeBSD__ */
5423 #if defined(__bsdi__)
5424 #define TULIP_PCI_ATTACH_ARGS struct device * const parent, struct device * const self, void *const aux
5425 #define TULIP_SHUTDOWN_ARGS void *arg
5434 id
= pci_inl(pa
, PCI_VENDOR_ID
);
5435 if (PCI_VENDORID(id
) != DEC_VENDORID
)
5438 id
= PCI_CHIPID(id
);
5439 if (id
!= CHIPID_21040
&& id
!= CHIPID_21041
5440 && id
!= CHIPID_21140
&& id
!= CHIPID_21142
)
5442 irq
= pci_inl(pa
, PCI_I_LINE
) & 0xFF;
5443 if (irq
== 0 || irq
>= 16) {
5444 printf("de?: invalid IRQ %d; skipping\n", irq
);
5452 struct device
*parent
,
5456 struct isa_attach_args
* const ia
= (struct isa_attach_args
*) aux
;
5460 #if _BSDI_VERSION >= 199401
5461 switch (ia
->ia_bustype
) {
5464 pa
= pci_scan(tulip_pci_match
);
5468 irq
= (1 << (pci_inl(pa
, PCI_I_LINE
) & 0xFF));
5470 /* Get the base address; assume the BIOS set it up correctly */
5471 #if defined(TULIP_IOMAPPED)
5472 ia
->ia_maddr
= NULL
;
5474 ia
->ia_iobase
= pci_inl(pa
, PCI_CBIO
) & ~7;
5475 pci_outl(pa
, PCI_CBIO
, 0xFFFFFFFF);
5476 ia
->ia_iosize
= ((~pci_inl(pa
, PCI_CBIO
)) | 7) + 1;
5477 pci_outl(pa
, PCI_CBIO
, (int) ia
->ia_iobase
);
5479 /* Disable memory space access */
5480 pci_outl(pa
, PCI_COMMAND
, pci_inl(pa
, PCI_COMMAND
) & ~2);
5482 ia
->ia_maddr
= (void *) (pci_inl(pa
, PCI_CBMA
) & ~7);
5483 pci_outl(pa
, PCI_CBMA
, 0xFFFFFFFF);
5484 ia
->ia_msize
= ((~pci_inl(pa
, PCI_CBMA
)) | 7) + 1;
5485 pci_outl(pa
, PCI_CBMA
, (int) ia
->ia_maddr
);
5489 /* Disable I/O space access */
5490 pci_outl(pa
, PCI_COMMAND
, pci_inl(pa
, PCI_COMMAND
) & ~1);
5491 #endif /* TULIP_IOMAPPED */
5493 ia
->ia_aux
= (void *) pa
;
5494 #if _BSDI_VERSION >= 199401
5497 #if defined(TULIP_EISA)
5501 if ((slot
= eisa_match(cf
, ia
)) == 0)
5503 ia
->ia_iobase
= slot
<< 12;
5504 ia
->ia_iosize
= EISA_NPORT
;
5505 eisa_slotalloc(slot
);
5506 tmp
= inb(ia
->ia_iobase
+ DE425_CFG0
);
5507 irq
= tulip_eisa_irqs
[(tmp
>> 1) & 0x03];
5509 * Until BSD/OS likes level interrupts, force
5510 * the DE425 into edge-triggered mode.
5513 outb(ia
->ia_iobase
+ DE425_CFG0
, tmp
| 1);
5515 * CBIO needs to map to the EISA slot
5516 * enable I/O access and Master
5518 outl(ia
->ia_iobase
+ DE425_CBIO
, ia
->ia_iobase
);
5519 outl(ia
->ia_iobase
+ DE425_CFCS
, 5 | inl(ia
->ia_iobase
+ DE425_CFCS
));
5523 #endif /* TULIP_EISA */
5529 /* PCI bus masters don't use host DMA channels */
5530 ia
->ia_drq
= DRQNONE
;
5532 if (ia
->ia_irq
!= IRQUNK
&& irq
!= ia
->ia_irq
) {
5533 printf("de%d: error: desired IRQ of %d does not match device's "
5534 "actual IRQ of %d,\n",
5536 ffs(ia
->ia_irq
) - 1, ffs(irq
) - 1);
5539 if (ia
->ia_irq
== IRQUNK
)
5542 ia
->ia_irq
|= IRQSHARE
;
5547 static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS
);
5549 #if defined(TULIP_EISA)
5550 static char *tulip_eisa_ids
[] = {
5556 struct cfdriver decd
= {
5557 0, "de", tulip_probe
, tulip_pci_attach
,
5558 #if _BSDI_VERSION >= 199401
5561 sizeof(tulip_softc_t
),
5562 #if defined(TULIP_EISA)
5567 #endif /* __bsdi__ */
5569 #if defined(__NetBSD__)
5570 #define TULIP_PCI_ATTACH_ARGS struct device * const parent, struct device * const self, void *const aux
5571 #define TULIP_SHUTDOWN_ARGS void *arg
5574 struct device
*parent
,
5578 struct pci_attach_args
*pa
= (struct pci_attach_args
*) aux
;
5580 /* Don't match lmc cards */
5581 if (PCI_VENDOR(pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
5582 PCI_SUBSYS_ID_REG
)) == PCI_VENDOR_LMC
)
5584 if (PCI_VENDORID(pa
->pa_id
) != DEC_VENDORID
)
5586 if (PCI_CHIPID(pa
->pa_id
) == CHIPID_21040
5587 || PCI_CHIPID(pa
->pa_id
) == CHIPID_21041
5588 || PCI_CHIPID(pa
->pa_id
) == CHIPID_21140
5589 || PCI_CHIPID(pa
->pa_id
) == CHIPID_21142
)
5595 static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS
);
5597 CFATTACH_DECL(de
, sizeof(tulip_softc_t
),
5598 tulip_pci_probe
, tulip_pci_attach
, NULL
, NULL
);
5600 #endif /* __NetBSD__ */
5604 TULIP_SHUTDOWN_ARGS
)
5606 tulip_softc_t
* const sc
= arg
;
5607 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
5608 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
5609 33MHz that comes to two microseconds but wait a
5610 bit longer anyways) */
5615 TULIP_PCI_ATTACH_ARGS
)
5617 #if defined(__FreeBSD__)
5619 #define PCI_CONF_WRITE(r, v) pci_conf_write(config_id, (r), (v))
5620 #define PCI_CONF_READ(r) pci_conf_read(config_id, (r))
5621 #define PCI_GETBUSDEVINFO(sc) ((void)((sc)->tulip_pci_busno = ((config_id.cfg1 >> 16) & 0xFF), /* XXX */ \
5622 (sc)->tulip_pci_devno = ((config_id.cfg1 >> 11) & 0x1F))) /* XXX */
5624 #if defined(__bsdi__)
5625 tulip_softc_t
* const sc
= (tulip_softc_t
*) self
;
5626 struct isa_attach_args
* const ia
= (struct isa_attach_args
*) aux
;
5627 pci_devaddr_t
*pa
= (pci_devaddr_t
*) ia
->ia_aux
;
5628 const int unit
= sc
->tulip_dev
.dv_unit
;
5629 #define PCI_CONF_WRITE(r, v) pci_outl(pa, (r), (v))
5630 #define PCI_CONF_READ(r) pci_inl(pa, (r))
5631 #define PCI_GETBUSDEVINFO(sc) ((void)((sc)->tulip_pci_busno = pa->d_bus, \
5632 (sc)->tulip_pci_devno = pa->d_agent))
5634 #if defined(__NetBSD__)
5635 tulip_softc_t
* const sc
= device_private(self
);
5636 struct pci_attach_args
* const pa
= (struct pci_attach_args
*) aux
;
5637 const int unit
= sc
->tulip_dev
.dv_unit
;
5638 #define PCI_CONF_WRITE(r, v) pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v))
5639 #define PCI_CONF_READ(r) pci_conf_read(pa->pa_pc, pa->pa_tag, (r))
5640 #define PCI_GETBUSDEVINFO(sc) do { \
5641 (sc)->tulip_pci_busno = parent; \
5642 (sc)->tulip_pci_devno = pa->pa_device; \
5644 #if defined(__alpha__)
5645 tulip_media_t media
= TULIP_MEDIA_UNKNOWN
;
5647 #endif /* __NetBSD__ */
5649 u_int32_t revinfo
, cfdainfo
, id
;
5650 #if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__)
5653 unsigned csroffset
= TULIP_PCI_CSROFFSET
;
5654 unsigned csrsize
= TULIP_PCI_CSRSIZE
;
5655 tulip_csrptr_t csr_base
;
5656 tulip_chipid_t chipid
= TULIP_CHIPID_UNKNOWN
;
5658 if (unit
>= TULIP_MAX_DEVICES
) {
5660 printf("de%d", unit
);
5662 printf(": not configured; limit of %d reached or exceeded\n",
5667 #if defined(__bsdi__)
5669 revinfo
= pci_inl(pa
, PCI_CFRV
) & 0xFF;
5670 id
= pci_inl(pa
, PCI_CFID
);
5671 cfdainfo
= pci_inl(pa
, PCI_CFDA
);
5672 #if defined(TULIP_EISA)
5674 revinfo
= inl(ia
->ia_iobase
+ DE425_CFRV
) & 0xFF;
5675 csroffset
= TULIP_EISA_CSROFFSET
;
5676 csrsize
= TULIP_EISA_CSRSIZE
;
5677 chipid
= TULIP_DE425
;
5679 #endif /* TULIP_EISA */
5681 #else /* __bsdi__ */
5682 revinfo
= PCI_CONF_READ(PCI_CFRV
) & 0xFF;
5683 id
= PCI_CONF_READ(PCI_CFID
);
5684 cfdainfo
= PCI_CONF_READ(PCI_CFDA
);
5685 #endif /* __bsdi__ */
5687 if (PCI_VENDORID(id
) == DEC_VENDORID
) {
5688 if (PCI_CHIPID(id
) == CHIPID_21040
)
5689 chipid
= TULIP_21040
;
5690 else if (PCI_CHIPID(id
) == CHIPID_21041
)
5691 chipid
= TULIP_21041
;
5692 else if (PCI_CHIPID(id
) == CHIPID_21140
)
5693 chipid
= (revinfo
>= 0x20) ? TULIP_21140A
: TULIP_21140
;
5694 else if (PCI_CHIPID(id
) == CHIPID_21142
)
5695 chipid
= (revinfo
>= 0x20) ? TULIP_21143
: TULIP_21142
;
5697 if (chipid
== TULIP_CHIPID_UNKNOWN
)
5700 if ((chipid
== TULIP_21040
|| chipid
== TULIP_DE425
) && revinfo
< 0x20) {
5702 printf("de%d", unit
);
5704 printf(": not configured; 21040 pass 2.0 required (%d.%d found)\n",
5705 revinfo
>> 4, revinfo
& 0x0f);
5707 } else if (chipid
== TULIP_21140
&& revinfo
< 0x11) {
5711 printf("de%d: not configured; 21140 pass 1.1 required (%d.%d found)\n",
5712 unit
, revinfo
>> 4, revinfo
& 0x0f);
5716 #if defined(__FreeBSD__)
5717 sc
= (tulip_softc_t
*) malloc(sizeof(*sc
), M_DEVBUF
, M_NOWAIT
);
5720 memset(sc
, 0, sizeof(*sc
)); /* Zero out the softc*/
5723 PCI_GETBUSDEVINFO(sc
);
5724 sc
->tulip_chipid
= chipid
;
5725 sc
->tulip_flags
|= TULIP_DEVICEPROBE
;
5726 if (chipid
== TULIP_21140
|| chipid
== TULIP_21140A
)
5727 sc
->tulip_features
|= TULIP_HAVE_GPR
|TULIP_HAVE_STOREFWD
;
5728 if (chipid
== TULIP_21140A
&& revinfo
<= 0x22)
5729 sc
->tulip_features
|= TULIP_HAVE_RXBADOVRFLW
;
5730 if (chipid
== TULIP_21140
)
5731 sc
->tulip_features
|= TULIP_HAVE_BROKEN_HASH
;
5732 if (chipid
!= TULIP_21040
&& chipid
!= TULIP_DE425
&& chipid
!= TULIP_21140
)
5733 sc
->tulip_features
|= TULIP_HAVE_POWERMGMT
;
5734 if (chipid
== TULIP_21041
|| chipid
== TULIP_21142
|| chipid
== TULIP_21143
) {
5735 sc
->tulip_features
|= TULIP_HAVE_DUALSENSE
;
5736 if (chipid
!= TULIP_21041
|| revinfo
>= 0x20)
5737 sc
->tulip_features
|= TULIP_HAVE_SIANWAY
;
5738 if (chipid
!= TULIP_21041
)
5739 sc
->tulip_features
|= TULIP_HAVE_SIAGP
|TULIP_HAVE_RXBADOVRFLW
|TULIP_HAVE_STOREFWD
;
5740 if (chipid
!= TULIP_21041
&& revinfo
>= 0x20)
5741 sc
->tulip_features
|= TULIP_HAVE_SIA100
;
5744 if (sc
->tulip_features
& TULIP_HAVE_POWERMGMT
5745 && (cfdainfo
& (TULIP_CFDA_SLEEP
|TULIP_CFDA_SNOOZE
))) {
5746 cfdainfo
&= ~(TULIP_CFDA_SLEEP
|TULIP_CFDA_SNOOZE
);
5747 PCI_CONF_WRITE(PCI_CFDA
, cfdainfo
);
5750 #if defined(__alpha__) && defined(__NetBSD__)
5752 * The Alpha SRM console encodes a console set media in the driver
5753 * part of the CFDA register. Note that the Multia presents a
5754 * problem in that its BNC mode is really EXTSIA. So in that case
5757 switch ((cfdainfo
>> 8) & 0xff) {
5758 case 1: media
= chipid
> TULIP_DE425
? TULIP_MEDIA_AUI
: TULIP_MEDIA_AUIBNC
; break;
5759 case 2: media
= chipid
> TULIP_DE425
? TULIP_MEDIA_BNC
: TULIP_MEDIA_UNKNOWN
; break;
5760 case 3: media
= TULIP_MEDIA_10BASET
; break;
5761 case 4: media
= TULIP_MEDIA_10BASET_FD
; break;
5762 case 5: media
= TULIP_MEDIA_100BASETX
; break;
5763 case 6: media
= TULIP_MEDIA_100BASETX_FD
; break;
5764 default: media
= TULIP_MEDIA_UNKNOWN
; break;
5768 #if defined(__NetBSD__)
5769 strlcpy(sc
->tulip_if
.if_xname
, device_xname(self
),
5770 sizeof(sc
->tulip_if
.if_xname
));
5771 sc
->tulip_if
.if_softc
= sc
;
5772 sc
->tulip_pc
= pa
->pa_pc
;
5773 #if defined(TULIP_BUS_DMA)
5774 sc
->tulip_dmatag
= pa
->pa_dmat
;
5777 sc
->tulip_unit
= unit
;
5778 sc
->tulip_name
= "de";
5780 sc
->tulip_revinfo
= revinfo
;
5781 #if defined(__FreeBSD__)
5783 sc
->tulip_if
.if_softc
= sc
;
5785 #if defined(TULIP_IOMAPPED)
5786 retval
= pci_map_port(config_id
, PCI_CBIO
, &csr_base
);
5788 retval
= pci_map_mem(config_id
, PCI_CBMA
, (vaddr_t
*) &csr_base
, &pa_csrs
);
5791 free((void *) sc
, M_DEVBUF
);
5795 #endif /* __FreeBSD__ */
5797 #if defined(__bsdi__)
5798 sc
->tulip_pf
= printf
;
5799 #if defined(TULIP_IOMAPPED)
5800 csr_base
= ia
->ia_iobase
;
5802 csr_base
= (vaddr_t
) mapphys((vaddr_t
) ia
->ia_maddr
, ia
->ia_msize
);
5804 #endif /* __bsdi__ */
5806 #if defined(__NetBSD__)
5807 callout_init(&sc
->tulip_to_ch
, 0);
5808 callout_init(&sc
->tulip_fto_ch
, 0);
5812 bus_space_tag_t iot
, memt
;
5813 bus_space_handle_t ioh
, memh
;
5814 int ioh_valid
, memh_valid
;
5816 ioh_valid
= (pci_mapreg_map(pa
, PCI_CBIO
, PCI_MAPREG_TYPE_IO
, 0,
5817 &iot
, &ioh
, NULL
, NULL
) == 0);
5818 memh_valid
= (pci_mapreg_map(pa
, PCI_CBMA
,
5819 PCI_MAPREG_TYPE_MEM
|
5820 PCI_MAPREG_MEM_TYPE_32BIT
,
5821 0, &memt
, &memh
, NULL
, NULL
) == 0);
5823 sc
->tulip_bustag
= memt
;
5824 sc
->tulip_bushandle
= memh
;
5825 } else if (ioh_valid
) {
5826 sc
->tulip_bustag
= iot
;
5827 sc
->tulip_bushandle
= ioh
;
5829 printf(": unable to map device registers\n");
5833 /* Make sure bus mastering is enabled. */
5834 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
,
5835 pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
5836 PCI_COMMAND_STATUS_REG
) |
5837 PCI_COMMAND_MASTER_ENABLE
);
5839 #endif /* __NetBSD__ */
5841 tulip_initcsrs(sc
, csr_base
+ csroffset
, csrsize
);
5843 #if defined(TULIP_BUS_DMA)
5844 if ((retval
= tulip_busdma_init(sc
)) != 0) {
5845 printf("error initing bus_dma: %d\n", retval
);
5849 sc
->tulip_txdescs
= (tulip_desc_t
*) malloc((TULIP_TXDESCS
+TULIP_RXDESCS
)*sizeof(tulip_desc_t
), M_DEVBUF
, M_WAITOK
);
5850 sc
->tulip_rxdescs
= sc
->tulip_txdescs
+ TULIP_TXDESCS
;
5853 tulip_initring(sc
, &sc
->tulip_rxinfo
, sc
->tulip_rxdescs
, TULIP_RXDESCS
);
5854 tulip_initring(sc
, &sc
->tulip_txinfo
, sc
->tulip_txdescs
, TULIP_TXDESCS
);
5857 * Make sure there won't be any interrupts or such...
5859 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
5860 DELAY(100); /* Wait 10 microseconds (actually 50 PCI cycles but at
5861 33MHz that comes to two microseconds but wait a
5862 bit longer anyways) */
5864 if ((retval
= tulip_read_macaddr(sc
)) < 0) {
5865 #if defined(__FreeBSD__)
5866 printf(TULIP_PRINTF_FMT
, TULIP_PRINTF_ARGS
);
5868 printf(": can't read ENET ROM (why=%d) (", retval
);
5869 for (idx
= 0; idx
< 32; idx
++)
5870 printf("%02x", sc
->tulip_rombuf
[idx
]);
5872 printf(TULIP_PRINTF_FMT
": %s%s pass %d.%d\n",
5874 sc
->tulip_boardid
, tulip_chipdescs
[sc
->tulip_chipid
],
5875 (sc
->tulip_revinfo
& 0xF0) >> 4, sc
->tulip_revinfo
& 0x0F);
5876 printf(TULIP_PRINTF_FMT
": address unknown\n", TULIP_PRINTF_ARGS
);
5879 tulip_intrfunc_t (*intr_rtn
)(void *) = tulip_intr_normal
;
5881 if (sc
->tulip_features
& TULIP_HAVE_SHAREDINTR
)
5882 intr_rtn
= tulip_intr_shared
;
5884 #if defined(__NetBSD__)
5886 if ((sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) == 0) {
5887 pci_intr_handle_t intrhandle
;
5888 const char *intrstr
;
5890 if (pci_intr_map(pa
, &intrhandle
)) {
5891 aprint_error_dev(&sc
->tulip_dev
, "couldn't map interrupt\n");
5894 intrstr
= pci_intr_string(pa
->pa_pc
, intrhandle
);
5895 sc
->tulip_ih
= pci_intr_establish(pa
->pa_pc
, intrhandle
, IPL_NET
,
5897 if (sc
->tulip_ih
== NULL
) {
5898 aprint_error_dev(&sc
->tulip_dev
, "couldn't establish interrupt");
5899 if (intrstr
!= NULL
)
5900 aprint_error(" at %s", intrstr
);
5904 printf("%s: interrupting at %s\n", device_xname(&sc
->tulip_dev
), intrstr
);
5906 sc
->tulip_ats
= shutdownhook_establish(tulip_shutdown
, sc
);
5907 if (sc
->tulip_ats
== NULL
)
5908 printf("%s: warning: couldn't establish shutdown hook\n",
5911 #if defined(__FreeBSD__)
5912 if ((sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) == 0) {
5913 if (!pci_map_int (config_id
, intr_rtn
, (void*) sc
, &net_imask
)) {
5914 printf(TULIP_PRINTF_FMT
": couldn't map interrupt\n",
5919 #if !defined(TULIP_DEVCONF)
5920 at_shutdown(tulip_shutdown
, sc
, SHUTDOWN_POST_SYNC
);
5923 #if defined(__bsdi__)
5924 if ((sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) == 0) {
5925 isa_establish(&sc
->tulip_id
, &sc
->tulip_dev
);
5927 sc
->tulip_ih
.ih_fun
= intr_rtn
;
5928 sc
->tulip_ih
.ih_arg
= (void *) sc
;
5929 intr_establish(ia
->ia_irq
, &sc
->tulip_ih
, DV_NET
);
5932 sc
->tulip_ats
.func
= tulip_shutdown
;
5933 sc
->tulip_ats
.arg
= (void *) sc
;
5934 atshutdown(&sc
->tulip_ats
, ATSH_ADD
);
5936 #if defined(TULIP_USE_SOFTINTR)
5937 if (sc
->tulip_unit
> tulip_softintr_max_unit
)
5938 tulip_softintr_max_unit
= sc
->tulip_unit
;
5941 s
= TULIP_RAISESPL();
5942 #if defined(__alpha__) && defined(__NetBSD__)
5943 sc
->tulip_media
= media
;
5946 #if defined(__alpha__) && defined(__NetBSD__)
5947 if (sc
->tulip_media
!= TULIP_MEDIA_UNKNOWN
)
5948 tulip_linkup(sc
, media
);
5950 TULIP_RESTORESPL(s
);