1 /* $NetBSD: if_de.c,v 1.86 1999/06/01 19:17:59 thorpej Exp $ */
3 * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. The name of the author may not be used to endorse or promote products
12 * derived from this software without specific prior written permission
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * Id: if_de.c,v 1.94 1997/07/03 16:55:07 thomas Exp
29 * DEC 21040 PCI Ethernet Controller
31 * Written by Matt Thomas
32 * BPF support code stolen directly from if_ec.c
34 * This driver supports the DEC DE435 or any other PCI
35 * board which support 21040, 21041, or 21140 (mostly).
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD: head/sys/dev/de/if_de.c 271849 2014-09-19 03:51:26Z glebius $");
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/endian.h>
45 #include <sys/socket.h>
46 #include <sys/sockio.h>
47 #include <sys/malloc.h>
48 #include <sys/kernel.h>
49 #include <sys/eventhandler.h>
52 #include <sys/interrupt.h>
57 #include <net/if_media.h>
58 #include <net/if_dl.h>
59 #include <net/ifq_var.h>
63 #include <netinet/in.h>
64 #include <netinet/if_ether.h>
69 #include <net/if_var.h>
71 #include <bus/pci/pcivar.h>
72 #include <bus/pci/pcireg.h>
73 #include <dev/netif/de/dc21040reg.h>
76 * Intel CPUs should use I/O mapped access.
78 #if defined(__x86_64__)
79 #define TULIP_IOMAPPED
90 static tulip_softc_t
*tulips
[TULIP_MAX_DEVICES
];
93 * This module supports
94 * the DEC 21040 PCI Ethernet Controller.
95 * the DEC 21041 PCI Ethernet Controller.
96 * the DEC 21140 PCI Fast Ethernet Controller.
98 static void tulip_mii_autonegotiate(tulip_softc_t
*, u_int
);
99 static void tulip_intr_shared(void *);
100 static void tulip_intr_normal(void *);
101 static void tulip_init(tulip_softc_t
*);
102 static void tulip_reset(tulip_softc_t
*);
103 static void tulip_ifstart(struct ifnet
*, struct ifaltq_subque
*);
104 static struct mbuf
*tulip_txput(tulip_softc_t
*, struct mbuf
*);
105 static void tulip_txput_setup(tulip_softc_t
*);
106 static void tulip_rx_intr(tulip_softc_t
*);
107 static void tulip_addr_filter(tulip_softc_t
*);
108 static u_int
tulip_mii_readreg(tulip_softc_t
*, u_int
, u_int
);
109 static void tulip_mii_writereg(tulip_softc_t
*, u_int
, u_int
, u_int
);
110 static int tulip_mii_map_abilities(tulip_softc_t
* const sc
, unsigned abilities
);
111 static tulip_media_t
tulip_mii_phy_readspecific(tulip_softc_t
*);
112 static int tulip_srom_decode(tulip_softc_t
*);
113 static int tulip_ifmedia_change(struct ifnet
*);
114 static void tulip_ifmedia_status(struct ifnet
*, struct ifmediareq
*);
115 static struct mbuf
*tulip_dequeue_mbuf(tulip_ringinfo_t
*ri
, tulip_descinfo_t
*di
,
117 static void tulip_dma_map_addr(void *, bus_dma_segment_t
*, int, int);
118 static void tulip_dma_map_rxbuf(void *, bus_dma_segment_t
*, int,
120 static void tulip_ifinit(void *);
123 tulip_dma_map_addr(void *arg
, bus_dma_segment_t
*segs
, int nseg
, int error
)
131 *paddr
= segs
->ds_addr
;
135 tulip_dma_map_rxbuf(void *arg
, bus_dma_segment_t
*segs
, int nseg
,
136 bus_size_t mapsize
, int error
)
144 KASSERT(nseg
== 1, ("too many DMA segments"));
145 KASSERT(segs
[0].ds_len
>= TULIP_RX_BUFLEN
, ("receive buffer too small"));
147 desc
->d_addr1
= segs
[0].ds_addr
& 0xffffffff;
148 desc
->d_length1
= TULIP_RX_BUFLEN
;
150 /* These should already always be zero. */
157 tulip_dequeue_mbuf(tulip_ringinfo_t
*ri
, tulip_descinfo_t
*di
, int sync
)
167 TULIP_RXMAP_POSTSYNC(ri
, di
);
170 TULIP_TXMAP_POSTSYNC(ri
, di
);
173 panic("bad sync flag: %d", sync
);
175 bus_dmamap_unload(ri
->ri_data_tag
, *di
->di_map
);
182 tulip_timeout_callback(void *arg
)
184 tulip_softc_t
*sc
= arg
;
186 lwkt_serialize_enter(sc
->arpcom
.ac_if
.if_serializer
);
187 sc
->tulip_flags
&= ~TULIP_TIMEOUTPENDING
;
188 sc
->tulip_probe_timeout
-= 1000 / TULIP_HZ
;
189 (sc
->tulip_boardsw
->bd_media_poll
)(sc
, TULIP_MEDIAPOLL_TIMER
);
190 lwkt_serialize_exit(sc
->arpcom
.ac_if
.if_serializer
);
194 tulip_timeout(tulip_softc_t
*sc
)
196 if (sc
->tulip_flags
& TULIP_TIMEOUTPENDING
)
198 sc
->tulip_flags
|= TULIP_TIMEOUTPENDING
;
199 callout_reset(&sc
->tulip_callout
, (hz
+ TULIP_HZ
/ 2) / TULIP_HZ
,
200 tulip_timeout_callback
, sc
);
204 tulip_txprobe(tulip_softc_t
*sc
)
209 * Before we are sure this is the right media we need
210 * to send a small packet to make sure there's carrier.
211 * Strangely, BNC and AUI will "see" receive data if
212 * either is connected so the transmit is the only way
213 * to verify the connectivity.
215 MGETHDR(m
, M_NOWAIT
, MT_DATA
);
219 * Construct a LLC TEST message which will point to ourselves.
221 bcopy(sc
->arpcom
.ac_enaddr
, mtod(m
, struct ether_header
*)->ether_dhost
,
223 bcopy(sc
->arpcom
.ac_enaddr
, mtod(m
, struct ether_header
*)->ether_shost
,
225 mtod(m
, struct ether_header
*)->ether_type
= htons(3);
226 mtod(m
, unsigned char *)[14] = 0;
227 mtod(m
, unsigned char *)[15] = 0;
228 mtod(m
, unsigned char *)[16] = 0xE3; /* LLC Class1 TEST (no poll) */
229 m
->m_len
= m
->m_pkthdr
.len
= sizeof(struct ether_header
) + 3;
233 sc
->tulip_cmdmode
|= TULIP_CMD_TXRUN
;
234 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
235 sc
->tulip_flags
|= TULIP_TXPROBE_ACTIVE
;
236 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
237 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
238 if ((m
= tulip_txput(sc
, m
)) != NULL
)
240 sc
->tulip_probe
.probe_txprobes
++;
245 tulip_media_set(tulip_softc_t
*sc
, tulip_media_t media
)
247 const tulip_media_info_t
*mi
= sc
->tulip_mediums
[media
];
253 * If we are switching media, make sure we don't think there's
254 * any stale RX activity
256 sc
->tulip_flags
&= ~TULIP_RXACT
;
257 if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
258 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, TULIP_SIACONN_RESET
);
259 TULIP_CSR_WRITE(sc
, csr_sia_tx_rx
, mi
->mi_sia_tx_rx
);
260 if (sc
->tulip_features
& TULIP_HAVE_SIAGP
) {
261 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_gp_control
|mi
->mi_sia_general
);
263 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_gp_data
|mi
->mi_sia_general
);
265 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_sia_general
);
267 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, mi
->mi_sia_connectivity
);
268 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
) {
269 #define TULIP_GPR_CMDBITS (TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER|TULIP_CMD_TXTHRSHLDCTL)
271 * If the cmdmode bits don't match the currently operating mode,
272 * set the cmdmode appropriately and reset the chip.
274 if (((mi
->mi_cmdmode
^ TULIP_CSR_READ(sc
, csr_command
)) & TULIP_GPR_CMDBITS
) != 0) {
275 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
276 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
279 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_PINSET
|sc
->tulip_gpinit
);
281 TULIP_CSR_WRITE(sc
, csr_gp
, (u_int8_t
) mi
->mi_gpdata
);
282 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
284 * If the cmdmode bits don't match the currently operating mode,
285 * set the cmdmode appropriately and reset the chip.
287 if (((mi
->mi_cmdmode
^ TULIP_CSR_READ(sc
, csr_command
)) & TULIP_GPR_CMDBITS
) != 0) {
288 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
289 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
292 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_gpcontrol
);
293 TULIP_CSR_WRITE(sc
, csr_sia_general
, mi
->mi_gpdata
);
294 } else if (mi
->mi_type
== TULIP_MEDIAINFO_MII
295 && sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
) {
297 if (sc
->tulip_features
& TULIP_HAVE_SIAGP
) {
299 dp
= &sc
->tulip_rombuf
[mi
->mi_reset_offset
];
300 for (idx
= 0; idx
< mi
->mi_reset_length
; idx
++, dp
+= 2) {
302 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp
[0] + 256 * dp
[1]) << 16);
304 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
305 dp
= &sc
->tulip_rombuf
[mi
->mi_gpr_offset
];
306 for (idx
= 0; idx
< mi
->mi_gpr_length
; idx
++, dp
+= 2) {
308 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp
[0] + 256 * dp
[1]) << 16);
311 for (idx
= 0; idx
< mi
->mi_reset_length
; idx
++) {
313 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_reset_offset
+ idx
]);
315 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
316 for (idx
= 0; idx
< mi
->mi_gpr_length
; idx
++) {
318 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_gpr_offset
+ idx
]);
321 if (sc
->tulip_flags
& TULIP_TRYNWAY
) {
322 tulip_mii_autonegotiate(sc
, sc
->tulip_phyaddr
);
323 } else if ((sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
324 u_int32_t data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_CONTROL
);
325 data
&= ~(PHYCTL_SELECT_100MB
|PHYCTL_FULL_DUPLEX
|PHYCTL_AUTONEG_ENABLE
);
326 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
327 if (TULIP_IS_MEDIA_FD(media
))
328 data
|= PHYCTL_FULL_DUPLEX
;
329 if (TULIP_IS_MEDIA_100MB(media
))
330 data
|= PHYCTL_SELECT_100MB
;
331 tulip_mii_writereg(sc
, sc
->tulip_phyaddr
, PHYREG_CONTROL
, data
);
337 tulip_linkup(tulip_softc_t
*sc
, tulip_media_t media
)
339 if ((sc
->tulip_flags
& TULIP_LINKUP
) == 0)
340 sc
->tulip_flags
|= TULIP_PRINTLINKUP
;
341 sc
->tulip_flags
|= TULIP_LINKUP
;
342 ifq_clr_oactive(&sc
->arpcom
.ac_if
.if_snd
);
343 #if 0 /* XXX how does with work with ifmedia? */
344 if ((sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
345 if (sc
->arpcom
.ac_if
.if_flags
& IFF_FULLDUPLEX
) {
346 if (TULIP_CAN_MEDIA_FD(media
)
347 && sc
->tulip_mediums
[TULIP_FD_MEDIA_OF(media
)] != NULL
)
348 media
= TULIP_FD_MEDIA_OF(media
);
350 if (TULIP_IS_MEDIA_FD(media
)
351 && sc
->tulip_mediums
[TULIP_HD_MEDIA_OF(media
)] != NULL
)
352 media
= TULIP_HD_MEDIA_OF(media
);
356 if (sc
->tulip_media
!= media
) {
357 sc
->tulip_media
= media
;
358 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
359 if (TULIP_IS_MEDIA_FD(sc
->tulip_media
)) {
360 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
361 } else if (sc
->tulip_chipid
!= TULIP_21041
|| (sc
->tulip_flags
& TULIP_DIDNWAY
) == 0) {
362 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
366 * We could set probe_timeout to 0 but setting to 3000 puts this
367 * in one central place and the only matters is tulip_link is
368 * followed by a tulip_timeout. Therefore setting it should not
369 * result in aberrant behavour.
371 sc
->tulip_probe_timeout
= 3000;
372 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
373 sc
->tulip_flags
&= ~(TULIP_TXPROBE_ACTIVE
|TULIP_TRYNWAY
);
374 if (sc
->tulip_flags
& TULIP_INRESET
) {
375 tulip_media_set(sc
, sc
->tulip_media
);
376 } else if (sc
->tulip_probe_media
!= sc
->tulip_media
) {
378 * No reason to change media if we have the right media.
386 tulip_media_print(tulip_softc_t
*sc
)
388 if ((sc
->tulip_flags
& TULIP_LINKUP
) == 0)
390 if (sc
->tulip_flags
& TULIP_PRINTMEDIA
) {
391 if_printf(&sc
->arpcom
.ac_if
, "enabling %s port\n",
392 tulip_mediums
[sc
->tulip_media
]);
393 sc
->tulip_flags
&= ~(TULIP_PRINTMEDIA
|TULIP_PRINTLINKUP
);
394 } else if (sc
->tulip_flags
& TULIP_PRINTLINKUP
) {
395 if_printf(&sc
->arpcom
.ac_if
, "link up\n");
396 sc
->tulip_flags
&= ~TULIP_PRINTLINKUP
;
400 static tulip_link_status_t
401 tulip_media_link_monitor(tulip_softc_t
*sc
)
403 const tulip_media_info_t
*mi
= sc
->tulip_mediums
[sc
->tulip_media
];
404 tulip_link_status_t linkup
= TULIP_LINK_DOWN
;
407 #if defined(DIAGNOSTIC)
408 panic("tulip_media_link_monitor: %s: botch at line %d\n",
409 tulip_mediums
[sc
->tulip_media
],__LINE__
);
411 return TULIP_LINK_UNKNOWN
;
416 * Have we seen some packets? If so, the link must be good.
418 if ((sc
->tulip_flags
& (TULIP_RXACT
|TULIP_LINKUP
)) == (TULIP_RXACT
|TULIP_LINKUP
)) {
419 sc
->tulip_flags
&= ~TULIP_RXACT
;
420 sc
->tulip_probe_timeout
= 3000;
421 return TULIP_LINK_UP
;
424 sc
->tulip_flags
&= ~TULIP_RXACT
;
425 if (mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
428 * Read the PHY status register.
430 status
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
);
431 if (status
& PHYSTS_AUTONEG_DONE
) {
433 * If the PHY has completed autonegotiation, see the if the
434 * remote systems abilities have changed. If so, upgrade or
435 * downgrade as appropriate.
437 u_int32_t abilities
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_AUTONEG_ABILITIES
);
438 abilities
= (abilities
<< 6) & status
;
439 if (abilities
!= sc
->tulip_abilities
) {
440 if (tulip_mii_map_abilities(sc
, abilities
)) {
441 tulip_linkup(sc
, sc
->tulip_probe_media
);
442 return TULIP_LINK_UP
;
445 * if we had selected media because of autonegotiation,
446 * we need to probe for the new media.
448 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
449 if (sc
->tulip_flags
& TULIP_DIDNWAY
)
450 return TULIP_LINK_DOWN
;
454 * The link is now up. If was down, say its back up.
456 if ((status
& (PHYSTS_LINK_UP
|PHYSTS_REMOTE_FAULT
)) == PHYSTS_LINK_UP
)
457 linkup
= TULIP_LINK_UP
;
458 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
) {
460 * No activity sensor? Assume all's well.
462 if (mi
->mi_actmask
== 0)
463 return TULIP_LINK_UNKNOWN
;
465 * Does the activity data match?
467 if ((TULIP_CSR_READ(sc
, csr_gp
) & mi
->mi_actmask
) == mi
->mi_actdata
)
468 linkup
= TULIP_LINK_UP
;
469 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
471 * Assume non TP ok for now.
473 if (!TULIP_IS_MEDIA_TP(sc
->tulip_media
))
474 return TULIP_LINK_UNKNOWN
;
475 if ((TULIP_CSR_READ(sc
, csr_sia_status
) & TULIP_SIASTS_LINKFAIL
) == 0)
476 linkup
= TULIP_LINK_UP
;
477 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
478 return TULIP_LINK_UNKNOWN
;
481 * We will wait for 3 seconds until the link goes into suspect mode.
483 if (sc
->tulip_flags
& TULIP_LINKUP
) {
484 if (linkup
== TULIP_LINK_UP
)
485 sc
->tulip_probe_timeout
= 3000;
486 if (sc
->tulip_probe_timeout
> 0)
487 return TULIP_LINK_UP
;
489 sc
->tulip_flags
&= ~TULIP_LINKUP
;
490 if_printf(&sc
->arpcom
.ac_if
, "link down: cable problem?\n");
492 return TULIP_LINK_DOWN
;
496 tulip_media_poll(tulip_softc_t
*sc
, tulip_mediapoll_event_t event
)
498 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
499 && event
== TULIP_MEDIAPOLL_TIMER
) {
500 switch (tulip_media_link_monitor(sc
)) {
501 case TULIP_LINK_DOWN
: {
503 * Link Monitor failed. Probe for new media.
505 event
= TULIP_MEDIAPOLL_LINKFAIL
;
508 case TULIP_LINK_UP
: {
515 case TULIP_LINK_UNKNOWN
: {
517 * We can't tell so don't bother.
524 if (event
== TULIP_MEDIAPOLL_LINKFAIL
) {
525 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
) {
526 if (TULIP_DO_AUTOSENSE(sc
)) {
527 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
528 if (sc
->arpcom
.ac_if
.if_flags
& IFF_UP
)
529 tulip_reset(sc
); /* restart probe */
535 if (event
== TULIP_MEDIAPOLL_START
) {
536 ifq_set_oactive(&sc
->arpcom
.ac_if
.if_snd
);
537 if (sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
)
539 sc
->tulip_probe_mediamask
= 0;
540 sc
->tulip_probe_passes
= 0;
542 * If the SROM contained an explicit media to use, use it.
544 sc
->tulip_cmdmode
&= ~(TULIP_CMD_RXRUN
|TULIP_CMD_FULLDUPLEX
);
545 sc
->tulip_flags
|= TULIP_TRYNWAY
|TULIP_PROBE1STPASS
;
546 sc
->tulip_flags
&= ~(TULIP_DIDNWAY
|TULIP_PRINTMEDIA
|TULIP_PRINTLINKUP
);
548 * connidx is defaulted to a media_unknown type.
550 sc
->tulip_probe_media
= tulip_srom_conninfo
[sc
->tulip_connidx
].sc_media
;
551 if (sc
->tulip_probe_media
!= TULIP_MEDIA_UNKNOWN
) {
552 tulip_linkup(sc
, sc
->tulip_probe_media
);
557 if (sc
->tulip_features
& TULIP_HAVE_GPR
) {
558 sc
->tulip_probe_state
= TULIP_PROBE_GPRTEST
;
559 sc
->tulip_probe_timeout
= 2000;
561 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
;
562 sc
->tulip_probe_timeout
= 0;
563 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
568 * Ignore txprobe failures or spurious callbacks.
570 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
571 && sc
->tulip_probe_state
!= TULIP_PROBE_MEDIATEST
) {
572 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
577 * If we really transmitted a packet, then that's the media we'll use.
579 if (event
== TULIP_MEDIAPOLL_TXPROBE_OK
|| event
== TULIP_MEDIAPOLL_LINKPASS
) {
580 if (event
== TULIP_MEDIAPOLL_LINKPASS
) {
581 /* XXX Check media status just to be sure */
582 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
584 tulip_linkup(sc
, sc
->tulip_probe_media
);
589 if (sc
->tulip_probe_state
== TULIP_PROBE_GPRTEST
) {
591 * Brute force. We cycle through each of the media types
592 * and try to transmit a packet.
594 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
595 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
;
596 sc
->tulip_probe_timeout
= 0;
601 if (sc
->tulip_probe_state
!= TULIP_PROBE_MEDIATEST
602 && (sc
->tulip_features
& TULIP_HAVE_MII
)) {
603 tulip_media_t old_media
= sc
->tulip_probe_media
;
604 tulip_mii_autonegotiate(sc
, sc
->tulip_phyaddr
);
605 switch (sc
->tulip_probe_state
) {
606 case TULIP_PROBE_FAILED
:
607 case TULIP_PROBE_MEDIATEST
: {
609 * Try the next media.
611 sc
->tulip_probe_mediamask
|= sc
->tulip_mediums
[sc
->tulip_probe_media
]->mi_mediamask
;
612 sc
->tulip_probe_timeout
= 0;
614 if (sc
->tulip_probe_state
== TULIP_PROBE_FAILED
)
616 if (sc
->tulip_probe_media
!= tulip_mii_phy_readspecific(sc
))
618 sc
->tulip_probe_timeout
= TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
) ? 2500 : 300;
622 case TULIP_PROBE_PHYAUTONEG
: {
625 case TULIP_PROBE_INACTIVE
: {
627 * Only probe if we autonegotiated a media that hasn't failed.
629 sc
->tulip_probe_timeout
= 0;
630 if (sc
->tulip_probe_mediamask
& TULIP_BIT(sc
->tulip_probe_media
)) {
631 sc
->tulip_probe_media
= old_media
;
634 tulip_linkup(sc
, sc
->tulip_probe_media
);
639 #if defined(DIAGNOSTIC)
640 panic("tulip_media_poll: botch at line %d", __LINE__
);
647 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
) {
648 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
653 * switch to another media if we tried this one enough.
655 if (/* event == TULIP_MEDIAPOLL_TXPROBE_FAILED || */ sc
->tulip_probe_timeout
<= 0) {
657 * Find the next media type to check for. Full Duplex
658 * types are not allowed.
661 sc
->tulip_probe_media
-= 1;
662 if (sc
->tulip_probe_media
== TULIP_MEDIA_UNKNOWN
) {
663 if (++sc
->tulip_probe_passes
== 3) {
664 if_printf(&sc
->arpcom
.ac_if
,
665 "autosense failed: cable problem?\n");
666 if ((sc
->arpcom
.ac_if
.if_flags
& IFF_UP
) == 0) {
667 sc
->arpcom
.ac_if
.if_flags
&= ~IFF_RUNNING
;
668 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
672 sc
->tulip_flags
^= TULIP_TRYNWAY
; /* XXX */
673 sc
->tulip_probe_mediamask
= 0;
674 sc
->tulip_probe_media
= TULIP_MEDIA_MAX
- 1;
676 } while (sc
->tulip_mediums
[sc
->tulip_probe_media
] == NULL
677 || (sc
->tulip_probe_mediamask
& TULIP_BIT(sc
->tulip_probe_media
))
678 || TULIP_IS_MEDIA_FD(sc
->tulip_probe_media
));
680 sc
->tulip_probe_timeout
= TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
) ? 2500 : 1000;
681 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
682 sc
->tulip_probe
.probe_txprobes
= 0;
684 tulip_media_set(sc
, sc
->tulip_probe_media
);
685 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
690 * If this is hanging off a phy, we know are doing NWAY and we have
691 * forced the phy to a specific speed. Wait for link up before
692 * before sending a packet.
694 switch (sc
->tulip_mediums
[sc
->tulip_probe_media
]->mi_type
) {
695 case TULIP_MEDIAINFO_MII
: {
696 if (sc
->tulip_probe_media
!= tulip_mii_phy_readspecific(sc
))
700 case TULIP_MEDIAINFO_SIA
: {
701 if (TULIP_IS_MEDIA_TP(sc
->tulip_probe_media
)) {
702 if (TULIP_CSR_READ(sc
, csr_sia_status
) & TULIP_SIASTS_LINKFAIL
)
704 tulip_linkup(sc
, sc
->tulip_probe_media
);
706 if (sc
->tulip_features
& TULIP_HAVE_MII
)
713 case TULIP_MEDIAINFO_RESET
:
714 case TULIP_MEDIAINFO_SYM
:
715 case TULIP_MEDIAINFO_NONE
:
716 case TULIP_MEDIAINFO_GPR
: {
721 * Try to send a packet.
727 tulip_media_select(tulip_softc_t
*sc
)
729 if (sc
->tulip_features
& TULIP_HAVE_GPR
) {
730 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_PINSET
|sc
->tulip_gpinit
);
732 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_gpdata
);
735 * If this board has no media, just return
737 if (sc
->tulip_features
& TULIP_HAVE_NOMEDIA
)
740 if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
) {
741 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
742 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, TULIP_MEDIAPOLL_START
);
744 tulip_media_set(sc
, sc
->tulip_media
);
749 tulip_21040_mediainfo_init(tulip_softc_t
*sc
, tulip_media_t media
)
751 sc
->tulip_cmdmode
|= TULIP_CMD_CAPTREFFCT
|TULIP_CMD_THRSHLD160
752 |TULIP_CMD_BACKOFFCTR
;
753 sc
->arpcom
.ac_if
.if_baudrate
= 10000000;
755 if (media
== TULIP_MEDIA_10BASET
|| media
== TULIP_MEDIA_UNKNOWN
) {
756 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[0], 21040, 10BASET
);
757 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[1], 21040, 10BASET_FD
);
758 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
761 if (media
== TULIP_MEDIA_AUIBNC
|| media
== TULIP_MEDIA_UNKNOWN
) {
762 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[2], 21040, AUIBNC
);
765 if (media
== TULIP_MEDIA_UNKNOWN
) {
766 TULIP_MEDIAINFO_SIA_INIT(sc
, &sc
->tulip_mediainfo
[3], 21040, EXTSIA
);
771 tulip_21040_media_probe(tulip_softc_t
*sc
)
773 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_UNKNOWN
);
777 tulip_21040_10baset_only_media_probe(tulip_softc_t
*sc
)
779 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_10BASET
);
780 tulip_media_set(sc
, TULIP_MEDIA_10BASET
);
781 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
785 tulip_21040_10baset_only_media_select(tulip_softc_t
*sc
)
787 sc
->tulip_flags
|= TULIP_LINKUP
;
788 if (sc
->tulip_media
== TULIP_MEDIA_10BASET_FD
) {
789 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
790 sc
->tulip_flags
&= ~TULIP_SQETEST
;
792 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
793 sc
->tulip_flags
|= TULIP_SQETEST
;
795 tulip_media_set(sc
, sc
->tulip_media
);
799 tulip_21040_auibnc_only_media_probe(tulip_softc_t
*sc
)
801 tulip_21040_mediainfo_init(sc
, TULIP_MEDIA_AUIBNC
);
802 sc
->tulip_flags
|= TULIP_SQETEST
|TULIP_LINKUP
;
803 tulip_media_set(sc
, TULIP_MEDIA_AUIBNC
);
804 sc
->tulip_media
= TULIP_MEDIA_AUIBNC
;
808 tulip_21040_auibnc_only_media_select(tulip_softc_t
*sc
)
810 tulip_media_set(sc
, TULIP_MEDIA_AUIBNC
);
811 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
814 static const tulip_boardsw_t tulip_21040_boardsw
= {
816 tulip_21040_media_probe
,
821 static const tulip_boardsw_t tulip_21040_10baset_only_boardsw
= {
823 tulip_21040_10baset_only_media_probe
,
824 tulip_21040_10baset_only_media_select
,
828 static const tulip_boardsw_t tulip_21040_auibnc_only_boardsw
= {
830 tulip_21040_auibnc_only_media_probe
,
831 tulip_21040_auibnc_only_media_select
,
836 tulip_21041_mediainfo_init(tulip_softc_t
*sc
)
838 tulip_media_info_t
*mi
= sc
->tulip_mediainfo
;
841 if (sc
->tulip_revinfo
>= 0x20) {
842 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041P2
, 10BASET
);
843 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041P2
, 10BASET_FD
);
844 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041P2
, AUI
);
845 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041P2
, BNC
);
849 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[0], 21041, 10BASET
);
850 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[1], 21041, 10BASET_FD
);
851 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[2], 21041, AUI
);
852 TULIP_MEDIAINFO_SIA_INIT(sc
, &mi
[3], 21041, BNC
);
856 tulip_21041_media_probe(tulip_softc_t
*sc
)
858 sc
->arpcom
.ac_if
.if_baudrate
= 10000000;
859 sc
->tulip_cmdmode
|= TULIP_CMD_CAPTREFFCT
|TULIP_CMD_ENHCAPTEFFCT
860 |TULIP_CMD_THRSHLD160
|TULIP_CMD_BACKOFFCTR
;
861 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
862 tulip_21041_mediainfo_init(sc
);
866 tulip_21041_media_poll(tulip_softc_t
*sc
, tulip_mediapoll_event_t event
)
870 if (event
== TULIP_MEDIAPOLL_LINKFAIL
) {
871 if (sc
->tulip_probe_state
!= TULIP_PROBE_INACTIVE
872 || !TULIP_DO_AUTOSENSE(sc
))
874 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
875 tulip_reset(sc
); /* start probe */
880 * If we've been been asked to start a poll or link change interrupt
881 * restart the probe (and reset the tulip to a known state).
883 if (event
== TULIP_MEDIAPOLL_START
) {
884 ifq_set_oactive(&sc
->arpcom
.ac_if
.if_snd
);
885 sc
->tulip_cmdmode
&= ~(TULIP_CMD_FULLDUPLEX
|TULIP_CMD_RXRUN
);
887 if (sc
->tulip_revinfo
>= 0x20) {
888 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
;
889 sc
->tulip_flags
|= TULIP_DIDNWAY
;
892 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
893 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
894 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
895 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_10BASET_TIMEOUT
;
896 tulip_media_set(sc
, TULIP_MEDIA_10BASET
);
901 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
)
904 if (event
== TULIP_MEDIAPOLL_TXPROBE_OK
) {
905 tulip_linkup(sc
, sc
->tulip_probe_media
);
909 sia_status
= TULIP_CSR_READ(sc
, csr_sia_status
);
910 TULIP_CSR_WRITE(sc
, csr_sia_status
, sia_status
);
911 if ((sia_status
& TULIP_SIASTS_LINKFAIL
) == 0) {
912 if (sc
->tulip_revinfo
>= 0x20) {
913 if (sia_status
& (PHYSTS_10BASET_FD
<< (16 - 6)))
914 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET_FD
;
917 * If the link has passed LinkPass, 10baseT is the
918 * proper media to use.
920 tulip_linkup(sc
, sc
->tulip_probe_media
);
925 * wait for up to 2.4 seconds for the link to reach pass state.
926 * Only then start scanning the other media for activity.
927 * choose media with receive activity over those without.
929 if (sc
->tulip_probe_media
== TULIP_MEDIA_10BASET
) {
930 if (event
!= TULIP_MEDIAPOLL_TIMER
)
932 if (sc
->tulip_probe_timeout
> 0
933 && (sia_status
& TULIP_SIASTS_OTHERRXACTIVITY
) == 0) {
937 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
938 sc
->tulip_flags
|= TULIP_WANTRXACT
;
939 if (sia_status
& TULIP_SIASTS_OTHERRXACTIVITY
) {
940 sc
->tulip_probe_media
= TULIP_MEDIA_BNC
;
942 sc
->tulip_probe_media
= TULIP_MEDIA_AUI
;
944 tulip_media_set(sc
, sc
->tulip_probe_media
);
950 * If we failed, clear the txprobe active flag.
952 if (event
== TULIP_MEDIAPOLL_TXPROBE_FAILED
)
953 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
956 if (event
== TULIP_MEDIAPOLL_TIMER
) {
958 * If we've received something, then that's our link!
960 if (sc
->tulip_flags
& TULIP_RXACT
) {
961 tulip_linkup(sc
, sc
->tulip_probe_media
);
965 * if no txprobe active
967 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0
968 && ((sc
->tulip_flags
& TULIP_WANTRXACT
) == 0
969 || (sia_status
& TULIP_SIASTS_RXACTIVITY
))) {
970 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
976 * Take 2 passes through before deciding to not
977 * wait for receive activity. Then take another
978 * two passes before spitting out a warning.
980 if (sc
->tulip_probe_timeout
<= 0) {
981 if (sc
->tulip_flags
& TULIP_WANTRXACT
) {
982 sc
->tulip_flags
&= ~TULIP_WANTRXACT
;
983 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
985 if_printf(&sc
->arpcom
.ac_if
,
986 "autosense failed: cable problem?\n");
987 if ((sc
->arpcom
.ac_if
.if_flags
& IFF_UP
) == 0) {
988 sc
->arpcom
.ac_if
.if_flags
&= ~IFF_RUNNING
;
989 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
997 * Since this media failed to probe, try the other one.
999 sc
->tulip_probe_timeout
= TULIP_21041_PROBE_AUIBNC_TIMEOUT
;
1000 if (sc
->tulip_probe_media
== TULIP_MEDIA_AUI
) {
1001 sc
->tulip_probe_media
= TULIP_MEDIA_BNC
;
1003 sc
->tulip_probe_media
= TULIP_MEDIA_AUI
;
1005 tulip_media_set(sc
, sc
->tulip_probe_media
);
1006 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
1010 static const tulip_boardsw_t tulip_21041_boardsw
= {
1011 TULIP_21041_GENERIC
,
1012 tulip_21041_media_probe
,
1014 tulip_21041_media_poll
1017 static const tulip_phy_attr_t tulip_mii_phy_attrlist
[] = {
1018 { 0x20005c00, 0, /* 08-00-17 */
1020 { 0x19, 0x0040, 0x0040 }, /* 10TX */
1021 { 0x19, 0x0040, 0x0000 }, /* 100TX */
1024 { 0x0281F400, 0, /* 00-A0-7D */
1026 { 0x12, 0x0010, 0x0000 }, /* 10T */
1028 { 0x12, 0x0010, 0x0010 }, /* 100T4 */
1029 { 0x12, 0x0008, 0x0008 }, /* FULL_DUPLEX */
1033 { 0x0015F420, 0, /* 00-A0-7D */
1035 { 0x12, 0x0010, 0x0000 }, /* 10T */
1037 { 0x12, 0x0010, 0x0010 }, /* 100T4 */
1038 { 0x12, 0x0008, 0x0008 }, /* FULL_DUPLEX */
1042 { 0x0281F400, 0, /* 00-A0-BE */
1044 { 0x11, 0x8000, 0x0000 }, /* 10T */
1045 { 0x11, 0x8000, 0x8000 }, /* 100TX */
1047 { 0x11, 0x4000, 0x4000 }, /* FULL_DUPLEX */
1053 static tulip_media_t
1054 tulip_mii_phy_readspecific(tulip_softc_t
*sc
)
1056 const tulip_phy_attr_t
*attr
;
1060 static const tulip_media_t table
[] = {
1061 TULIP_MEDIA_UNKNOWN
,
1062 TULIP_MEDIA_10BASET
,
1063 TULIP_MEDIA_100BASETX
,
1064 TULIP_MEDIA_100BASET4
,
1065 TULIP_MEDIA_UNKNOWN
,
1066 TULIP_MEDIA_10BASET_FD
,
1067 TULIP_MEDIA_100BASETX_FD
,
1072 * Don't read phy specific registers if link is not up.
1074 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_STATUS
);
1075 if ((data
& (PHYSTS_LINK_UP
|PHYSTS_EXTENDED_REGS
)) != (PHYSTS_LINK_UP
|PHYSTS_EXTENDED_REGS
))
1076 return TULIP_MEDIA_UNKNOWN
;
1078 id
= (tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_IDLOW
) << 16) |
1079 tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, PHYREG_IDHIGH
);
1080 for (attr
= tulip_mii_phy_attrlist
;; attr
++) {
1081 if (attr
->attr_id
== 0)
1082 return TULIP_MEDIA_UNKNOWN
;
1083 if ((id
& ~0x0F) == attr
->attr_id
)
1087 if (attr
->attr_modes
[PHY_MODE_100TX
].pm_regno
) {
1088 const tulip_phy_modedata_t
*pm
= &attr
->attr_modes
[PHY_MODE_100TX
];
1089 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1090 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1093 if (idx
== 0 && attr
->attr_modes
[PHY_MODE_100T4
].pm_regno
) {
1094 const tulip_phy_modedata_t
*pm
= &attr
->attr_modes
[PHY_MODE_100T4
];
1095 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1096 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1099 if (idx
== 0 && attr
->attr_modes
[PHY_MODE_10T
].pm_regno
) {
1100 const tulip_phy_modedata_t
*pm
= &attr
->attr_modes
[PHY_MODE_10T
];
1101 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1102 if ((data
& pm
->pm_mask
) == pm
->pm_value
)
1105 if (idx
!= 0 && attr
->attr_modes
[PHY_MODE_FULLDUPLEX
].pm_regno
) {
1106 const tulip_phy_modedata_t
*pm
= &attr
->attr_modes
[PHY_MODE_FULLDUPLEX
];
1107 data
= tulip_mii_readreg(sc
, sc
->tulip_phyaddr
, pm
->pm_regno
);
1108 idx
+= ((data
& pm
->pm_mask
) == pm
->pm_value
? 4 : 0);
1114 tulip_mii_get_phyaddr(tulip_softc_t
*sc
, u_int offset
)
1118 for (phyaddr
= 1; phyaddr
< 32; phyaddr
++) {
1119 u_int status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1120 if (status
== 0 || status
== 0xFFFF || status
< PHYSTS_10BASET
)
1127 u_int status
= tulip_mii_readreg(sc
, 0, PHYREG_STATUS
);
1128 if (status
== 0 || status
== 0xFFFF || status
< PHYSTS_10BASET
)
1129 return TULIP_MII_NOPHY
;
1132 return TULIP_MII_NOPHY
;
1136 tulip_mii_map_abilities(tulip_softc_t
*sc
, u_int abilities
)
1138 sc
->tulip_abilities
= abilities
;
1139 if (abilities
& PHYSTS_100BASETX_FD
) {
1140 sc
->tulip_probe_media
= TULIP_MEDIA_100BASETX_FD
;
1141 } else if (abilities
& PHYSTS_100BASET4
) {
1142 sc
->tulip_probe_media
= TULIP_MEDIA_100BASET4
;
1143 } else if (abilities
& PHYSTS_100BASETX
) {
1144 sc
->tulip_probe_media
= TULIP_MEDIA_100BASETX
;
1145 } else if (abilities
& PHYSTS_10BASET_FD
) {
1146 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET_FD
;
1147 } else if (abilities
& PHYSTS_10BASET
) {
1148 sc
->tulip_probe_media
= TULIP_MEDIA_10BASET
;
1150 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1153 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
1158 tulip_mii_autonegotiate(tulip_softc_t
*sc
, u_int phyaddr
)
1160 switch (sc
->tulip_probe_state
) {
1161 case TULIP_PROBE_MEDIATEST
:
1162 case TULIP_PROBE_INACTIVE
: {
1163 sc
->tulip_flags
|= TULIP_DIDNWAY
;
1164 tulip_mii_writereg(sc
, phyaddr
, PHYREG_CONTROL
, PHYCTL_RESET
);
1165 sc
->tulip_probe_timeout
= 3000;
1166 sc
->tulip_intrmask
|= TULIP_STS_ABNRMLINTR
|TULIP_STS_NORMALINTR
;
1167 sc
->tulip_probe_state
= TULIP_PROBE_PHYRESET
;
1170 case TULIP_PROBE_PHYRESET
: {
1172 uint32_t data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_CONTROL
);
1173 if (data
& PHYCTL_RESET
) {
1174 if (sc
->tulip_probe_timeout
> 0) {
1178 if_printf(&sc
->arpcom
.ac_if
,
1179 "(phy%d): error: reset of PHY never completed!\n", phyaddr
);
1180 sc
->tulip_flags
&= ~TULIP_TXPROBE_ACTIVE
;
1181 sc
->tulip_probe_state
= TULIP_PROBE_FAILED
;
1182 sc
->arpcom
.ac_if
.if_flags
&= ~(IFF_UP
|IFF_RUNNING
);
1185 status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1186 if ((status
& PHYSTS_CAN_AUTONEG
) == 0) {
1187 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1188 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1191 if (tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ADVERTISEMENT
) != ((status
>> 6) | 0x01))
1192 tulip_mii_writereg(sc
, phyaddr
, PHYREG_AUTONEG_ADVERTISEMENT
, (status
>> 6) | 0x01);
1193 tulip_mii_writereg(sc
, phyaddr
, PHYREG_CONTROL
, data
|PHYCTL_AUTONEG_RESTART
|PHYCTL_AUTONEG_ENABLE
);
1194 data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_CONTROL
);
1195 sc
->tulip_probe_state
= TULIP_PROBE_PHYAUTONEG
;
1196 sc
->tulip_probe_timeout
= 3000;
1199 case TULIP_PROBE_PHYAUTONEG
: {
1200 u_int32_t status
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_STATUS
);
1202 if ((status
& PHYSTS_AUTONEG_DONE
) == 0) {
1203 if (sc
->tulip_probe_timeout
> 0) {
1207 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1208 sc
->tulip_probe_state
= TULIP_PROBE_MEDIATEST
;
1211 data
= tulip_mii_readreg(sc
, phyaddr
, PHYREG_AUTONEG_ABILITIES
);
1212 data
= (data
<< 6) & status
;
1213 if (!tulip_mii_map_abilities(sc
, data
))
1214 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
1218 #if defined(DIAGNOSTIC)
1219 panic("tulip_media_poll: botch at line %d", __LINE__
);
1227 tulip_2114x_media_preset(tulip_softc_t
*sc
)
1229 const tulip_media_info_t
*mi
= NULL
;
1230 tulip_media_t media
;
1232 if (sc
->tulip_probe_state
== TULIP_PROBE_INACTIVE
)
1233 media
= sc
->tulip_media
;
1235 media
= sc
->tulip_probe_media
;
1237 sc
->tulip_cmdmode
&= ~TULIP_CMD_PORTSELECT
;
1238 sc
->tulip_flags
&= ~TULIP_SQETEST
;
1239 if (media
!= TULIP_MEDIA_UNKNOWN
&& media
!= TULIP_MEDIA_MAX
) {
1240 mi
= sc
->tulip_mediums
[media
];
1241 if (mi
->mi_type
== TULIP_MEDIAINFO_MII
) {
1242 sc
->tulip_cmdmode
|= TULIP_CMD_PORTSELECT
;
1243 } else if (mi
->mi_type
== TULIP_MEDIAINFO_GPR
1244 || mi
->mi_type
== TULIP_MEDIAINFO_SYM
) {
1245 sc
->tulip_cmdmode
&= ~TULIP_GPR_CMDBITS
;
1246 sc
->tulip_cmdmode
|= mi
->mi_cmdmode
;
1247 } else if (mi
->mi_type
== TULIP_MEDIAINFO_SIA
) {
1248 TULIP_CSR_WRITE(sc
, csr_sia_connectivity
, TULIP_SIACONN_RESET
);
1252 case TULIP_MEDIA_BNC
:
1253 case TULIP_MEDIA_AUI
:
1254 case TULIP_MEDIA_10BASET
: {
1255 sc
->tulip_cmdmode
&= ~TULIP_CMD_FULLDUPLEX
;
1256 sc
->tulip_cmdmode
|= TULIP_CMD_TXTHRSHLDCTL
;
1257 sc
->arpcom
.ac_if
.if_baudrate
= 10000000;
1258 sc
->tulip_flags
|= TULIP_SQETEST
;
1261 case TULIP_MEDIA_10BASET_FD
: {
1262 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
|TULIP_CMD_TXTHRSHLDCTL
;
1263 sc
->arpcom
.ac_if
.if_baudrate
= 10000000;
1266 case TULIP_MEDIA_100BASEFX
:
1267 case TULIP_MEDIA_100BASET4
:
1268 case TULIP_MEDIA_100BASETX
: {
1269 sc
->tulip_cmdmode
&= ~(TULIP_CMD_FULLDUPLEX
|TULIP_CMD_TXTHRSHLDCTL
);
1270 sc
->tulip_cmdmode
|= TULIP_CMD_PORTSELECT
;
1271 sc
->arpcom
.ac_if
.if_baudrate
= 100000000;
1274 case TULIP_MEDIA_100BASEFX_FD
:
1275 case TULIP_MEDIA_100BASETX_FD
: {
1276 sc
->tulip_cmdmode
|= TULIP_CMD_FULLDUPLEX
|TULIP_CMD_PORTSELECT
;
1277 sc
->tulip_cmdmode
&= ~TULIP_CMD_TXTHRSHLDCTL
;
1278 sc
->arpcom
.ac_if
.if_baudrate
= 100000000;
1285 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
1289 ********************************************************************
1290 * Start of 21140/21140A support which does not use the MII interface
1294 tulip_null_media_poll(tulip_softc_t
*sc
, tulip_mediapoll_event_t event
)
1296 #if defined(DIAGNOSTIC)
1297 if_printf(&sc
->arpcom
.ac_if
, "botch(media_poll) at line %d\n", __LINE__
);
1302 tulip_21140_mediainit(tulip_softc_t
*sc
, tulip_media_info_t
*mip
,
1303 tulip_media_t media
, u_int gpdata
, u_int cmdmode
)
1305 sc
->tulip_mediums
[media
] = mip
;
1306 mip
->mi_type
= TULIP_MEDIAINFO_GPR
;
1307 mip
->mi_cmdmode
= cmdmode
;
1308 mip
->mi_gpdata
= gpdata
;
1312 tulip_21140_evalboard_media_probe(tulip_softc_t
*sc
)
1314 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1316 sc
->tulip_gpinit
= TULIP_GP_EB_PINS
;
1317 sc
->tulip_gpdata
= TULIP_GP_EB_INIT
;
1318 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_PINS
);
1319 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_INIT
);
1320 TULIP_CSR_WRITE(sc
, csr_command
,
1321 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1322 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1323 TULIP_CSR_WRITE(sc
, csr_command
,
1324 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1326 if ((TULIP_CSR_READ(sc
, csr_gp
) & TULIP_GP_EB_OK100
) != 0) {
1327 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
1329 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1331 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1333 TULIP_CMD_TXTHRSHLDCTL
);
1334 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1336 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1337 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1339 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1340 |TULIP_CMD_SCRAMBLER
);
1341 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1343 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1344 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1347 static const tulip_boardsw_t tulip_21140_eb_boardsw
= {
1349 tulip_21140_evalboard_media_probe
,
1351 tulip_null_media_poll
,
1352 tulip_2114x_media_preset
,
1356 tulip_21140_accton_media_probe(tulip_softc_t
*sc
)
1358 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1361 sc
->tulip_gpinit
= TULIP_GP_EB_PINS
;
1362 sc
->tulip_gpdata
= TULIP_GP_EB_INIT
;
1363 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_PINS
);
1364 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EB_INIT
);
1365 TULIP_CSR_WRITE(sc
, csr_command
,
1366 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1367 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1368 TULIP_CSR_WRITE(sc
, csr_command
,
1369 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1371 gpdata
= TULIP_CSR_READ(sc
, csr_gp
);
1372 if ((gpdata
& TULIP_GP_EN1207_UTP_INIT
) == 0) {
1373 sc
->tulip_media
= TULIP_MEDIA_10BASET
;
1375 if ((gpdata
& TULIP_GP_EN1207_BNC_INIT
) == 0) {
1376 sc
->tulip_media
= TULIP_MEDIA_BNC
;
1378 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1381 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_BNC
,
1382 TULIP_GP_EN1207_BNC_INIT
,
1383 TULIP_CMD_TXTHRSHLDCTL
);
1384 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1385 TULIP_GP_EN1207_UTP_INIT
,
1386 TULIP_CMD_TXTHRSHLDCTL
);
1387 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1388 TULIP_GP_EN1207_UTP_INIT
,
1389 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1390 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1391 TULIP_GP_EN1207_100_INIT
,
1392 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1393 |TULIP_CMD_SCRAMBLER
);
1394 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1395 TULIP_GP_EN1207_100_INIT
,
1396 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1397 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1400 static const tulip_boardsw_t tulip_21140_accton_boardsw
= {
1402 tulip_21140_accton_media_probe
,
1404 tulip_null_media_poll
,
1405 tulip_2114x_media_preset
,
1409 tulip_21140_smc9332_media_probe(tulip_softc_t
*sc
)
1411 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1414 TULIP_CSR_WRITE(sc
, csr_command
, TULIP_CMD_PORTSELECT
|TULIP_CMD_MUSTBEONE
);
1415 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
1416 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
1417 33MHz that comes to two microseconds but wait a
1418 bit longer anyways) */
1419 TULIP_CSR_WRITE(sc
, csr_command
, TULIP_CMD_PORTSELECT
|
1420 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1421 sc
->tulip_gpinit
= TULIP_GP_SMC_9332_PINS
;
1422 sc
->tulip_gpdata
= TULIP_GP_SMC_9332_INIT
;
1423 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_SMC_9332_PINS
|TULIP_GP_PINSET
);
1424 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_SMC_9332_INIT
);
1426 for (idx
= 1000; idx
> 0; idx
--) {
1427 u_int32_t csr
= TULIP_CSR_READ(sc
, csr_gp
);
1428 if ((csr
& (TULIP_GP_SMC_9332_OK10
|TULIP_GP_SMC_9332_OK100
)) == (TULIP_GP_SMC_9332_OK10
|TULIP_GP_SMC_9332_OK100
)) {
1431 } else if ((csr
& TULIP_GP_SMC_9332_OK10
) == 0) {
1438 sc
->tulip_media
= cnt
> 100 ? TULIP_MEDIA_100BASETX
: TULIP_MEDIA_10BASET
;
1439 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1440 TULIP_GP_SMC_9332_INIT
,
1441 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1442 |TULIP_CMD_SCRAMBLER
);
1443 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1444 TULIP_GP_SMC_9332_INIT
,
1445 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1446 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1447 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1448 TULIP_GP_SMC_9332_INIT
,
1449 TULIP_CMD_TXTHRSHLDCTL
);
1450 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1451 TULIP_GP_SMC_9332_INIT
,
1452 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1455 static const tulip_boardsw_t tulip_21140_smc9332_boardsw
= {
1456 TULIP_21140_SMC_9332
,
1457 tulip_21140_smc9332_media_probe
,
1459 tulip_null_media_poll
,
1460 tulip_2114x_media_preset
,
1464 tulip_21140_cogent_em100_media_probe(tulip_softc_t
*sc
)
1466 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1469 sc
->tulip_gpinit
= TULIP_GP_EM100_PINS
;
1470 sc
->tulip_gpdata
= TULIP_GP_EM100_INIT
;
1471 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EM100_PINS
);
1472 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_EM100_INIT
);
1474 cmdmode
= TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
|TULIP_CMD_MUSTBEONE
;
1475 cmdmode
&= ~(TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_SCRAMBLER
);
1476 if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100FX_ID
) {
1477 TULIP_CSR_WRITE(sc
, csr_command
, cmdmode
);
1478 sc
->tulip_media
= TULIP_MEDIA_100BASEFX
;
1480 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASEFX
,
1481 TULIP_GP_EM100_INIT
,
1482 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
);
1483 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASEFX_FD
,
1484 TULIP_GP_EM100_INIT
,
1485 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1486 |TULIP_CMD_FULLDUPLEX
);
1488 TULIP_CSR_WRITE(sc
, csr_command
, cmdmode
|TULIP_CMD_SCRAMBLER
);
1489 sc
->tulip_media
= TULIP_MEDIA_100BASETX
;
1490 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1491 TULIP_GP_EM100_INIT
,
1492 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1493 |TULIP_CMD_SCRAMBLER
);
1494 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1495 TULIP_GP_EM100_INIT
,
1496 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1497 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1501 static const tulip_boardsw_t tulip_21140_cogent_em100_boardsw
= {
1502 TULIP_21140_COGENT_EM100
,
1503 tulip_21140_cogent_em100_media_probe
,
1505 tulip_null_media_poll
,
1506 tulip_2114x_media_preset
1510 tulip_21140_znyx_zx34x_media_probe(tulip_softc_t
*sc
)
1512 tulip_media_info_t
*mip
= sc
->tulip_mediainfo
;
1513 int cnt10
= 0, cnt100
= 0, idx
;
1515 sc
->tulip_gpinit
= TULIP_GP_ZX34X_PINS
;
1516 sc
->tulip_gpdata
= TULIP_GP_ZX34X_INIT
;
1517 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ZX34X_PINS
);
1518 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ZX34X_INIT
);
1519 TULIP_CSR_WRITE(sc
, csr_command
,
1520 TULIP_CSR_READ(sc
, csr_command
) | TULIP_CMD_PORTSELECT
|
1521 TULIP_CMD_PCSFUNCTION
| TULIP_CMD_SCRAMBLER
| TULIP_CMD_MUSTBEONE
);
1522 TULIP_CSR_WRITE(sc
, csr_command
,
1523 TULIP_CSR_READ(sc
, csr_command
) & ~TULIP_CMD_TXTHRSHLDCTL
);
1526 for (idx
= 1000; idx
> 0; idx
--) {
1527 uint32_t csr
= TULIP_CSR_READ(sc
, csr_gp
);
1528 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
)) {
1531 } else if ((csr
& TULIP_GP_ZX34X_LNKFAIL
) == 0) {
1540 sc
->tulip_media
= cnt100
> 100 ? TULIP_MEDIA_100BASETX
: TULIP_MEDIA_10BASET
;
1541 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET
,
1542 TULIP_GP_ZX34X_INIT
,
1543 TULIP_CMD_TXTHRSHLDCTL
);
1544 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_10BASET_FD
,
1545 TULIP_GP_ZX34X_INIT
,
1546 TULIP_CMD_TXTHRSHLDCTL
|TULIP_CMD_FULLDUPLEX
);
1547 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX
,
1548 TULIP_GP_ZX34X_INIT
,
1549 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1550 |TULIP_CMD_SCRAMBLER
);
1551 tulip_21140_mediainit(sc
, mip
++, TULIP_MEDIA_100BASETX_FD
,
1552 TULIP_GP_ZX34X_INIT
,
1553 TULIP_CMD_PORTSELECT
|TULIP_CMD_PCSFUNCTION
1554 |TULIP_CMD_SCRAMBLER
|TULIP_CMD_FULLDUPLEX
);
1557 static const tulip_boardsw_t tulip_21140_znyx_zx34x_boardsw
= {
1558 TULIP_21140_ZNYX_ZX34X
,
1559 tulip_21140_znyx_zx34x_media_probe
,
1561 tulip_null_media_poll
,
1562 tulip_2114x_media_preset
,
1566 tulip_2114x_media_probe(tulip_softc_t
*sc
)
1568 sc
->tulip_cmdmode
|= TULIP_CMD_MUSTBEONE
| TULIP_CMD_BACKOFFCTR
|
1569 TULIP_CMD_THRSHLD72
;
1572 static const tulip_boardsw_t tulip_2114x_isv_boardsw
= {
1574 tulip_2114x_media_probe
,
1577 tulip_2114x_media_preset
,
1581 * ******** END of chip-specific handlers. ***********
1585 * Code the read the SROM and MII bit streams (I2C)
1588 TULIP_CSR_WRITE(sc, csr_srom_mii, csr); \
1593 tulip_srom_idle(tulip_softc_t
*sc
)
1597 csr
= SROMSEL
; EMIT
;
1598 csr
= SROMSEL
| SROMRD
; EMIT
;
1599 csr
^= SROMCS
; EMIT
;
1600 csr
^= SROMCLKON
; EMIT
;
1603 * Write 25 cycles of 0 which will force the SROM to be idle.
1605 for (bit
= 3 + SROM_BITWIDTH
+ 16; bit
> 0; bit
--) {
1606 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
1607 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
1609 csr
^= SROMCLKOFF
; EMIT
;
1610 csr
^= SROMCS
; EMIT
;
1615 tulip_srom_read(tulip_softc_t
*sc
)
1617 const u_int bitwidth
= SROM_BITWIDTH
;
1618 const u_int cmdmask
= (SROMCMD_RD
<< bitwidth
);
1619 const u_int msb
= 1 << (bitwidth
+ 3 - 1);
1620 u_int idx
, lastidx
= (1 << bitwidth
) - 1;
1622 tulip_srom_idle(sc
);
1624 for (idx
= 0; idx
<= lastidx
; idx
++) {
1625 u_int lastbit
, data
, bits
, bit
, csr
;
1626 csr
= SROMSEL
; EMIT
;
1627 csr
= SROMSEL
| SROMRD
; EMIT
;
1628 csr
^= SROMCSON
; EMIT
;
1629 csr
^= SROMCLKON
; EMIT
;
1632 for (bits
= idx
|cmdmask
, bit
= bitwidth
+ 3; bit
> 0; bit
--, bits
<<= 1) {
1633 u_int thisbit
= bits
& msb
;
1634 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
1635 if (thisbit
!= lastbit
) {
1636 csr
^= SROMDOUT
; EMIT
; /* clock low; invert data */
1640 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
1643 csr
^= SROMCLKOFF
; EMIT
;
1645 for (data
= 0, bits
= 0; bits
< 16; bits
++) {
1647 csr
^= SROMCLKON
; EMIT
; /* clock high; data valid */
1648 data
|= TULIP_CSR_READ(sc
, csr_srom_mii
) & SROMDIN
? 1 : 0;
1649 csr
^= SROMCLKOFF
; EMIT
; /* clock low; data not valid */
1651 sc
->tulip_rombuf
[idx
*2] = data
& 0xFF;
1652 sc
->tulip_rombuf
[idx
*2+1] = data
>> 8;
1653 csr
= SROMSEL
| SROMRD
; EMIT
;
1656 tulip_srom_idle(sc
);
1659 #define MII_EMIT do { \
1660 TULIP_CSR_WRITE(sc, csr_srom_mii, csr); \
1665 tulip_mii_writebits(tulip_softc_t
*sc
, u_int data
, u_int bits
)
1667 u_int csr
, msb
, lastbit
;
1669 msb
= 1 << (bits
- 1);
1670 csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
1671 lastbit
= (csr
& MII_DOUT
) ? msb
: 0;
1672 csr
|= MII_WR
; MII_EMIT
; /* clock low; assert write */
1674 for (; bits
> 0; bits
--, data
<<= 1) {
1675 const unsigned thisbit
= data
& msb
;
1676 if (thisbit
!= lastbit
) {
1677 csr
^= MII_DOUT
; MII_EMIT
; /* clock low; invert data */
1679 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
1681 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
1686 tulip_mii_turnaround(tulip_softc_t
*sc
, u_int cmd
)
1690 csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
1692 if (cmd
== MII_WRCMD
) {
1693 csr
|= MII_DOUT
; MII_EMIT
; /* clock low; change data */
1694 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
1695 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
1696 csr
^= MII_DOUT
; MII_EMIT
; /* clock low; change data */
1698 csr
|= MII_RD
; MII_EMIT
; /* clock low; switch to read */
1700 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
1701 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
1705 tulip_mii_readbits(tulip_softc_t
*sc
)
1707 u_int csr
, data
, idx
;
1709 csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
1711 for (idx
= 0, data
= 0; idx
< 16; idx
++) {
1712 data
<<= 1; /* this is NOOP on the first pass through */
1713 csr
^= MII_CLKON
; MII_EMIT
; /* clock high; data valid */
1714 if (TULIP_CSR_READ(sc
, csr_srom_mii
) & MII_DIN
)
1716 csr
^= MII_CLKOFF
; MII_EMIT
; /* clock low; data not valid */
1718 csr
^= MII_RD
; MII_EMIT
; /* clock low; turn off read */
1724 tulip_mii_readreg(tulip_softc_t
*sc
, u_int devaddr
, u_int regno
)
1729 csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
1730 csr
&= ~(MII_RD
|MII_CLK
); MII_EMIT
;
1731 tulip_mii_writebits(sc
, MII_PREAMBLE
, 32);
1732 tulip_mii_writebits(sc
, MII_RDCMD
, 8);
1733 tulip_mii_writebits(sc
, devaddr
, 5);
1734 tulip_mii_writebits(sc
, regno
, 5);
1735 tulip_mii_turnaround(sc
, MII_RDCMD
);
1737 data
= tulip_mii_readbits(sc
);
1742 tulip_mii_writereg(tulip_softc_t
*sc
, u_int devaddr
, u_int regno
, u_int data
)
1746 csr
= TULIP_CSR_READ(sc
, csr_srom_mii
) & (MII_RD
|MII_DOUT
|MII_CLK
);
1747 csr
&= ~(MII_RD
|MII_CLK
); MII_EMIT
;
1748 tulip_mii_writebits(sc
, MII_PREAMBLE
, 32);
1749 tulip_mii_writebits(sc
, MII_WRCMD
, 8);
1750 tulip_mii_writebits(sc
, devaddr
, 5);
1751 tulip_mii_writebits(sc
, regno
, 5);
1752 tulip_mii_turnaround(sc
, MII_WRCMD
);
1753 tulip_mii_writebits(sc
, data
, 16);
1756 #define tulip_mchash(mca) (ether_crc32_le(mca, 6) & 0x1FF)
1757 #define tulip_srom_crcok(databuf) ( \
1758 ((ether_crc32_le(databuf, 126) & 0xFFFFU) ^ 0xFFFFU) == \
1759 ((databuf)[126] | ((databuf)[127] << 8)))
1762 tulip_identify_dec_nic(tulip_softc_t
*sc
)
1764 strcpy(sc
->tulip_boardid
, "DEC ");
1766 if (sc
->tulip_chipid
<= TULIP_21040
)
1768 if (bcmp(sc
->tulip_rombuf
+ 29, "DE500", 5) == 0
1769 || bcmp(sc
->tulip_rombuf
+ 29, "DE450", 5) == 0) {
1770 bcopy(sc
->tulip_rombuf
+ 29, &sc
->tulip_boardid
[D0
], 8);
1771 sc
->tulip_boardid
[D0
+8] = ' ';
1777 tulip_identify_znyx_nic(tulip_softc_t
* const sc
)
1780 strcpy(sc
->tulip_boardid
, "ZNYX ZX3XX ");
1781 if (sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
) {
1783 sc
->tulip_boardid
[8] = '4';
1784 znyx_ptr
= sc
->tulip_rombuf
[124] + 256 * sc
->tulip_rombuf
[125];
1785 if (znyx_ptr
< 26 || znyx_ptr
> 116) {
1786 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
1789 /* ZX344 = 0010 .. 0013FF
1791 if (sc
->tulip_rombuf
[znyx_ptr
] == 0x4A
1792 && sc
->tulip_rombuf
[znyx_ptr
+ 1] == 0x52
1793 && sc
->tulip_rombuf
[znyx_ptr
+ 2] == 0x01) {
1794 id
= sc
->tulip_rombuf
[znyx_ptr
+ 5] + 256 * sc
->tulip_rombuf
[znyx_ptr
+ 4];
1795 if ((id
>> 8) == (TULIP_ZNYX_ID_ZX342
>> 8)) {
1796 sc
->tulip_boardid
[9] = '2';
1797 if (id
== TULIP_ZNYX_ID_ZX342B
) {
1798 sc
->tulip_boardid
[10] = 'B';
1799 sc
->tulip_boardid
[11] = ' ';
1801 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
1802 } else if (id
== TULIP_ZNYX_ID_ZX344
) {
1803 sc
->tulip_boardid
[10] = '4';
1804 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
1805 } else if (id
== TULIP_ZNYX_ID_ZX345
) {
1806 sc
->tulip_boardid
[9] = (sc
->tulip_rombuf
[19] > 1) ? '8' : '5';
1807 } else if (id
== TULIP_ZNYX_ID_ZX346
) {
1808 sc
->tulip_boardid
[9] = '6';
1809 } else if (id
== TULIP_ZNYX_ID_ZX351
) {
1810 sc
->tulip_boardid
[8] = '5';
1811 sc
->tulip_boardid
[9] = '1';
1816 * Assume it's a ZX342...
1818 sc
->tulip_boardsw
= &tulip_21140_znyx_zx34x_boardsw
;
1822 sc
->tulip_boardid
[8] = '1';
1823 if (sc
->tulip_chipid
== TULIP_21041
) {
1824 sc
->tulip_boardid
[10] = '1';
1827 if (sc
->tulip_rombuf
[32] == 0x4A && sc
->tulip_rombuf
[33] == 0x52) {
1828 id
= sc
->tulip_rombuf
[37] + 256 * sc
->tulip_rombuf
[36];
1829 if (id
== TULIP_ZNYX_ID_ZX312T
) {
1830 sc
->tulip_boardid
[9] = '2';
1831 sc
->tulip_boardid
[10] = 'T';
1832 sc
->tulip_boardid
[11] = ' ';
1833 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
1834 } else if (id
== TULIP_ZNYX_ID_ZX314_INTA
) {
1835 sc
->tulip_boardid
[9] = '4';
1836 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
1837 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
1838 } else if (id
== TULIP_ZNYX_ID_ZX314
) {
1839 sc
->tulip_boardid
[9] = '4';
1840 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
1841 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
1842 } else if (id
== TULIP_ZNYX_ID_ZX315_INTA
) {
1843 sc
->tulip_boardid
[9] = '5';
1844 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
1845 } else if (id
== TULIP_ZNYX_ID_ZX315
) {
1846 sc
->tulip_boardid
[9] = '5';
1847 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
1853 if ((sc
->arpcom
.ac_enaddr
[3] & ~3) == 0xF0 && (sc
->arpcom
.ac_enaddr
[5] & 2) == 0) {
1854 sc
->tulip_boardid
[9] = '4';
1855 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
1856 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
1857 } else if ((sc
->arpcom
.ac_enaddr
[3] & ~3) == 0xF4 && (sc
->arpcom
.ac_enaddr
[5] & 1) == 0) {
1858 sc
->tulip_boardid
[9] = '5';
1859 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
1860 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
1861 } else if ((sc
->arpcom
.ac_enaddr
[3] & ~3) == 0xEC) {
1862 sc
->tulip_boardid
[9] = '2';
1863 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
1869 tulip_identify_smc_nic(tulip_softc_t
* const sc
)
1871 uint32_t id1
, id2
, ei
;
1872 int auibnc
= 0, utp
= 0;
1875 strcpy(sc
->tulip_boardid
, "SMC ");
1876 if (sc
->tulip_chipid
== TULIP_21041
)
1878 if (sc
->tulip_chipid
!= TULIP_21040
) {
1879 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
) {
1880 strcpy(&sc
->tulip_boardid
[4], "9332DST ");
1881 sc
->tulip_boardsw
= &tulip_21140_smc9332_boardsw
;
1882 } else if (sc
->tulip_features
& (TULIP_HAVE_BASEROM
|TULIP_HAVE_SLAVEDROM
)) {
1883 strcpy(&sc
->tulip_boardid
[4], "9334BDT ");
1885 strcpy(&sc
->tulip_boardid
[4], "9332BDT ");
1889 id1
= sc
->tulip_rombuf
[0x60] | (sc
->tulip_rombuf
[0x61] << 8);
1890 id2
= sc
->tulip_rombuf
[0x62] | (sc
->tulip_rombuf
[0x63] << 8);
1891 ei
= sc
->tulip_rombuf
[0x66] | (sc
->tulip_rombuf
[0x67] << 8);
1893 strcpy(&sc
->tulip_boardid
[4], "8432");
1894 cp
= &sc
->tulip_boardid
[8];
1896 *cp
++ = 'B', auibnc
= 1;
1897 if ((id1
& 0xFF) > 0x32)
1898 *cp
++ = 'T', utp
= 1;
1899 if ((id1
& 0x4000) == 0)
1900 *cp
++ = 'A', auibnc
= 1;
1902 sc
->tulip_boardid
[7] = '4';
1906 *cp
++ = (ei
? '2' : '1');
1911 sc
->tulip_boardsw
= &tulip_21040_10baset_only_boardsw
;
1912 else if (!utp
&& auibnc
)
1913 sc
->tulip_boardsw
= &tulip_21040_auibnc_only_boardsw
;
1917 tulip_identify_cogent_nic(tulip_softc_t
* const sc
)
1919 strcpy(sc
->tulip_boardid
, "Cogent ");
1920 if (sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
) {
1921 if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100TX_ID
) {
1922 strcat(sc
->tulip_boardid
, "EM100TX ");
1923 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
1924 #if defined(TULIP_COGENT_EM110TX_ID)
1925 } else if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM110TX_ID
) {
1926 strcat(sc
->tulip_boardid
, "EM110TX ");
1927 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
1929 } else if (sc
->tulip_rombuf
[32] == TULIP_COGENT_EM100FX_ID
) {
1930 strcat(sc
->tulip_boardid
, "EM100FX ");
1931 sc
->tulip_boardsw
= &tulip_21140_cogent_em100_boardsw
;
1934 * Magic number (0x24001109U) is the SubVendor (0x2400) and
1935 * SubDevId (0x1109) for the ANA6944TX (EM440TX).
1937 if (*(uint32_t *) sc
->tulip_rombuf
== 0x24001109U
1938 && (sc
->tulip_features
& TULIP_HAVE_BASEROM
)) {
1940 * Cogent (Adaptec) is still mapping all INTs to INTA of
1941 * first 21140. Dumb! Dumb!
1943 strcat(sc
->tulip_boardid
, "EM440TX ");
1944 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
;
1946 } else if (sc
->tulip_chipid
== TULIP_21040
) {
1947 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
|TULIP_HAVE_BASEROM
;
1952 tulip_identify_accton_nic(tulip_softc_t
* const sc
)
1954 strcpy(sc
->tulip_boardid
, "ACCTON ");
1955 switch (sc
->tulip_chipid
) {
1957 strcat(sc
->tulip_boardid
, "EN1207 ");
1958 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
)
1959 sc
->tulip_boardsw
= &tulip_21140_accton_boardsw
;
1962 strcat(sc
->tulip_boardid
, "EN1207TX ");
1963 if (sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
)
1964 sc
->tulip_boardsw
= &tulip_21140_eb_boardsw
;
1967 strcat(sc
->tulip_boardid
, "EN1203 ");
1968 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
1971 strcat(sc
->tulip_boardid
, "EN1203 ");
1972 sc
->tulip_boardsw
= &tulip_21041_boardsw
;
1975 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
1981 tulip_identify_asante_nic(tulip_softc_t
* const sc
)
1983 strcpy(sc
->tulip_boardid
, "Asante ");
1984 if ((sc
->tulip_chipid
== TULIP_21140
|| sc
->tulip_chipid
== TULIP_21140A
)
1985 && sc
->tulip_boardsw
!= &tulip_2114x_isv_boardsw
) {
1986 tulip_media_info_t
*mi
= sc
->tulip_mediainfo
;
1989 * The Asante Fast Ethernet doesn't always ship with a valid
1990 * new format SROM. So if isn't in the new format, we cheat
1991 * set it up as if we had.
1994 sc
->tulip_gpinit
= TULIP_GP_ASANTE_PINS
;
1995 sc
->tulip_gpdata
= 0;
1997 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ASANTE_PINS
|TULIP_GP_PINSET
);
1998 TULIP_CSR_WRITE(sc
, csr_gp
, TULIP_GP_ASANTE_PHYRESET
);
2000 TULIP_CSR_WRITE(sc
, csr_gp
, 0);
2002 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2003 mi
->mi_gpr_length
= 0;
2004 mi
->mi_gpr_offset
= 0;
2005 mi
->mi_reset_length
= 0;
2006 mi
->mi_reset_offset
= 0;
2008 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2009 for (idx
= 20; idx
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx
--) {
2011 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, 0);
2013 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
) {
2014 if_printf(&sc
->arpcom
.ac_if
, "can't find phy 0\n");
2018 sc
->tulip_features
|= TULIP_HAVE_MII
;
2019 mi
->mi_capabilities
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
|PHYSTS_100BASETX
|PHYSTS_100BASETX_FD
;
2020 mi
->mi_advertisement
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
|PHYSTS_100BASETX
|PHYSTS_100BASETX_FD
;
2021 mi
->mi_full_duplex
= PHYSTS_10BASET_FD
|PHYSTS_100BASETX_FD
;
2022 mi
->mi_tx_threshold
= PHYSTS_10BASET
|PHYSTS_10BASET_FD
;
2023 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2024 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2025 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2026 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2027 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2028 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2029 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2031 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2036 tulip_identify_compex_nic(tulip_softc_t
*sc
)
2038 strcpy(sc
->tulip_boardid
, "COMPEX ");
2039 if (sc
->tulip_chipid
== TULIP_21140A
) {
2041 tulip_softc_t
*root_sc
= NULL
;
2043 strcat(sc
->tulip_boardid
, "400TX/PCI ");
2045 * All 4 chips on these boards share an interrupt. This code
2046 * copied from tulip_read_macaddr.
2048 sc
->tulip_features
|= TULIP_HAVE_SHAREDINTR
;
2049 for (root_unit
= sc
->tulip_unit
- 1; root_unit
>= 0; root_unit
--) {
2050 root_sc
= tulips
[root_unit
];
2052 || !(root_sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
))
2057 && root_sc
->tulip_chipid
== sc
->tulip_chipid
2058 && root_sc
->tulip_pci_busno
== sc
->tulip_pci_busno
) {
2059 sc
->tulip_features
|= TULIP_HAVE_SLAVEDINTR
;
2060 sc
->tulip_slaves
= root_sc
->tulip_slaves
;
2061 root_sc
->tulip_slaves
= sc
;
2062 } else if(sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) {
2063 if_printf(&sc
->arpcom
.ac_if
, "can't find master device for interrupts");
2066 strcat(sc
->tulip_boardid
, "unknown ");
2068 /* sc->tulip_boardsw = &tulip_21140_eb_boardsw; */
2073 tulip_srom_decode(tulip_softc_t
*sc
)
2075 u_int idx1
, idx2
, idx3
;
2077 const tulip_srom_header_t
*shp
= (const tulip_srom_header_t
*) &sc
->tulip_rombuf
[0];
2078 const tulip_srom_adapter_info_t
*saip
= (const tulip_srom_adapter_info_t
*) (shp
+ 1);
2079 tulip_srom_media_t srom_media
;
2080 tulip_media_info_t
*mi
= sc
->tulip_mediainfo
;
2082 uint32_t leaf_offset
, blocks
, data
;
2084 for (idx1
= 0; idx1
< shp
->sh_adapter_count
; idx1
++, saip
++) {
2085 if (shp
->sh_adapter_count
== 1)
2087 if (saip
->sai_device
== sc
->tulip_pci_devno
)
2091 * Didn't find the right media block for this card.
2093 if (idx1
== shp
->sh_adapter_count
)
2097 * Save the hardware address.
2099 bcopy(shp
->sh_ieee802_address
, sc
->arpcom
.ac_enaddr
, ETHER_ADDR_LEN
);
2101 * If this is a multiple port card, add the adapter index to the last
2102 * byte of the hardware address. (if it isn't multiport, adding 0
2105 sc
->arpcom
.ac_enaddr
[5] += idx1
;
2107 leaf_offset
= saip
->sai_leaf_offset_lowbyte
2108 + saip
->sai_leaf_offset_highbyte
* 256;
2109 dp
= sc
->tulip_rombuf
+ leaf_offset
;
2111 sc
->tulip_conntype
= (tulip_srom_connection_t
) (dp
[0] + dp
[1] * 256); dp
+= 2;
2113 for (idx2
= 0;; idx2
++) {
2114 if (tulip_srom_conninfo
[idx2
].sc_type
== sc
->tulip_conntype
2115 || tulip_srom_conninfo
[idx2
].sc_type
== TULIP_SROM_CONNTYPE_NOT_USED
)
2118 sc
->tulip_connidx
= idx2
;
2120 if (sc
->tulip_chipid
== TULIP_21041
) {
2122 for (idx2
= 0; idx2
< blocks
; idx2
++) {
2123 tulip_media_t media
;
2125 srom_media
= (tulip_srom_media_t
) (data
& 0x3F);
2126 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2127 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2130 media
= tulip_srom_mediums
[idx3
].sm_type
;
2131 if (media
!= TULIP_MEDIA_UNKNOWN
) {
2132 if (data
& TULIP_SROM_21041_EXTENDED
) {
2133 mi
->mi_type
= TULIP_MEDIAINFO_SIA
;
2134 sc
->tulip_mediums
[media
] = mi
;
2135 mi
->mi_sia_connectivity
= dp
[0] + dp
[1] * 256;
2136 mi
->mi_sia_tx_rx
= dp
[2] + dp
[3] * 256;
2137 mi
->mi_sia_general
= dp
[4] + dp
[5] * 256;
2141 case TULIP_MEDIA_BNC
: {
2142 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, BNC
);
2146 case TULIP_MEDIA_AUI
: {
2147 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, AUI
);
2151 case TULIP_MEDIA_10BASET
: {
2152 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET
);
2156 case TULIP_MEDIA_10BASET_FD
: {
2157 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET_FD
);
2167 if (data
& TULIP_SROM_21041_EXTENDED
)
2172 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, BNC
); mi
++;
2173 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, AUI
); mi
++;
2174 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET
); mi
++;
2175 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21041, 10BASET_FD
); mi
++;
2179 unsigned length
, type
;
2180 tulip_media_t gp_media
= TULIP_MEDIA_UNKNOWN
;
2181 if (sc
->tulip_features
& TULIP_HAVE_GPR
)
2182 sc
->tulip_gpinit
= *dp
++;
2184 for (idx2
= 0; idx2
< blocks
; idx2
++) {
2186 if ((*dp
& 0x80) == 0) {
2190 length
= (*dp
++ & 0x7f) - 1;
2191 type
= *dp
++ & 0x3f;
2194 switch (type
& 0x3f) {
2195 case 0: { /* 21140[A] GPR block */
2196 tulip_media_t media
;
2197 srom_media
= (tulip_srom_media_t
)(dp
[0] & 0x3f);
2198 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2199 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2202 media
= tulip_srom_mediums
[idx3
].sm_type
;
2203 if (media
== TULIP_MEDIA_UNKNOWN
)
2205 mi
->mi_type
= TULIP_MEDIAINFO_GPR
;
2206 sc
->tulip_mediums
[media
] = mi
;
2207 mi
->mi_gpdata
= dp
[1];
2208 if (media
> gp_media
&& !TULIP_IS_MEDIA_FD(media
)) {
2209 sc
->tulip_gpdata
= mi
->mi_gpdata
;
2212 data
= dp
[2] + dp
[3] * 256;
2213 mi
->mi_cmdmode
= TULIP_SROM_2114X_CMDBITS(data
);
2214 if (data
& TULIP_SROM_2114X_NOINDICATOR
) {
2218 mi
->mi_default
= (data
& TULIP_SROM_2114X_DEFAULT
) != 0;
2220 mi
->mi_actmask
= TULIP_SROM_2114X_BITPOS(data
);
2221 mi
->mi_actdata
= (data
& TULIP_SROM_2114X_POLARITY
) ? 0 : mi
->mi_actmask
;
2226 case 1: { /* 21140[A] MII block */
2227 const u_int phyno
= *dp
++;
2228 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2229 mi
->mi_gpr_length
= *dp
++;
2230 mi
->mi_gpr_offset
= dp
- sc
->tulip_rombuf
;
2231 dp
+= mi
->mi_gpr_length
;
2232 mi
->mi_reset_length
= *dp
++;
2233 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2234 dp
+= mi
->mi_reset_length
;
2237 * Before we probe for a PHY, use the GPR information
2238 * to select it. If we don't, it may be inaccessible.
2240 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_gpinit
|TULIP_GP_PINSET
);
2241 for (idx3
= 0; idx3
< mi
->mi_reset_length
; idx3
++) {
2243 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_reset_offset
+ idx3
]);
2245 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
2246 for (idx3
= 0; idx3
< mi
->mi_gpr_length
; idx3
++) {
2248 TULIP_CSR_WRITE(sc
, csr_gp
, sc
->tulip_rombuf
[mi
->mi_gpr_offset
+ idx3
]);
2252 * At least write something!
2254 if (mi
->mi_reset_length
== 0 && mi
->mi_gpr_length
== 0)
2255 TULIP_CSR_WRITE(sc
, csr_gp
, 0);
2257 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2258 for (idx3
= 20; idx3
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx3
--) {
2260 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, phyno
);
2262 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
)
2264 sc
->tulip_features
|= TULIP_HAVE_MII
;
2265 mi
->mi_capabilities
= dp
[0] + dp
[1] * 256; dp
+= 2;
2266 mi
->mi_advertisement
= dp
[0] + dp
[1] * 256; dp
+= 2;
2267 mi
->mi_full_duplex
= dp
[0] + dp
[1] * 256; dp
+= 2;
2268 mi
->mi_tx_threshold
= dp
[0] + dp
[1] * 256; dp
+= 2;
2269 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2270 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2271 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2272 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2273 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2274 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2275 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2279 case 2: { /* 2114[23] SIA block */
2280 tulip_media_t media
;
2281 srom_media
= (tulip_srom_media_t
)(dp
[0] & 0x3f);
2282 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2283 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2286 media
= tulip_srom_mediums
[idx3
].sm_type
;
2287 if (media
== TULIP_MEDIA_UNKNOWN
)
2289 mi
->mi_type
= TULIP_MEDIAINFO_SIA
;
2290 sc
->tulip_mediums
[media
] = mi
;
2292 mi
->mi_sia_connectivity
= dp
[1] + dp
[2] * 256;
2293 mi
->mi_sia_tx_rx
= dp
[3] + dp
[4] * 256;
2294 mi
->mi_sia_general
= dp
[5] + dp
[6] * 256;
2298 case TULIP_MEDIA_BNC
: {
2299 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, BNC
);
2302 case TULIP_MEDIA_AUI
: {
2303 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, AUI
);
2306 case TULIP_MEDIA_10BASET
: {
2307 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, 10BASET
);
2308 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2311 case TULIP_MEDIA_10BASET_FD
: {
2312 TULIP_MEDIAINFO_SIA_INIT(sc
, mi
, 21142, 10BASET_FD
);
2313 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2321 mi
->mi_sia_gp_control
= (dp
[1] + dp
[2] * 256) << 16;
2322 mi
->mi_sia_gp_data
= (dp
[3] + dp
[4] * 256) << 16;
2327 case 3: { /* 2114[23] MII PHY block */
2328 const u_int phyno
= *dp
++;
2330 mi
->mi_type
= TULIP_MEDIAINFO_MII
;
2331 mi
->mi_gpr_length
= *dp
++;
2332 mi
->mi_gpr_offset
= dp
- sc
->tulip_rombuf
;
2333 dp
+= 2 * mi
->mi_gpr_length
;
2334 mi
->mi_reset_length
= *dp
++;
2335 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2336 dp
+= 2 * mi
->mi_reset_length
;
2338 dp0
= &sc
->tulip_rombuf
[mi
->mi_reset_offset
];
2339 for (idx3
= 0; idx3
< mi
->mi_reset_length
; idx3
++, dp0
+= 2) {
2341 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp0
[0] + 256 * dp0
[1]) << 16);
2343 sc
->tulip_phyaddr
= mi
->mi_phyaddr
;
2344 dp0
= &sc
->tulip_rombuf
[mi
->mi_gpr_offset
];
2345 for (idx3
= 0; idx3
< mi
->mi_gpr_length
; idx3
++, dp0
+= 2) {
2347 TULIP_CSR_WRITE(sc
, csr_sia_general
, (dp0
[0] + 256 * dp0
[1]) << 16);
2350 if (mi
->mi_reset_length
== 0 && mi
->mi_gpr_length
== 0)
2351 TULIP_CSR_WRITE(sc
, csr_sia_general
, 0);
2353 mi
->mi_phyaddr
= TULIP_MII_NOPHY
;
2354 for (idx3
= 20; idx3
> 0 && mi
->mi_phyaddr
== TULIP_MII_NOPHY
; idx3
--) {
2356 mi
->mi_phyaddr
= tulip_mii_get_phyaddr(sc
, phyno
);
2358 if (mi
->mi_phyaddr
== TULIP_MII_NOPHY
)
2360 sc
->tulip_features
|= TULIP_HAVE_MII
;
2361 mi
->mi_capabilities
= dp
[0] + dp
[1] * 256; dp
+= 2;
2362 mi
->mi_advertisement
= dp
[0] + dp
[1] * 256; dp
+= 2;
2363 mi
->mi_full_duplex
= dp
[0] + dp
[1] * 256; dp
+= 2;
2364 mi
->mi_tx_threshold
= dp
[0] + dp
[1] * 256; dp
+= 2;
2365 mi
->mi_mii_interrupt
= dp
[0] + dp
[1] * 256; dp
+= 2;
2366 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX_FD
);
2367 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASETX
);
2368 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 100BASET4
);
2369 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET_FD
);
2370 TULIP_MEDIAINFO_ADD_CAPABILITY(sc
, mi
, 10BASET
);
2371 mi
->mi_phyid
= (tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDLOW
) << 16) |
2372 tulip_mii_readreg(sc
, mi
->mi_phyaddr
, PHYREG_IDHIGH
);
2376 case 4: { /* 21143 SYM block */
2377 tulip_media_t media
;
2378 srom_media
= (tulip_srom_media_t
) dp
[0];
2379 for (idx3
= 0; tulip_srom_mediums
[idx3
].sm_type
!= TULIP_MEDIA_UNKNOWN
; idx3
++) {
2380 if (tulip_srom_mediums
[idx3
].sm_srom_type
== srom_media
)
2383 media
= tulip_srom_mediums
[idx3
].sm_type
;
2384 if (media
== TULIP_MEDIA_UNKNOWN
)
2386 mi
->mi_type
= TULIP_MEDIAINFO_SYM
;
2387 sc
->tulip_mediums
[media
] = mi
;
2388 mi
->mi_gpcontrol
= (dp
[1] + dp
[2] * 256) << 16;
2389 mi
->mi_gpdata
= (dp
[3] + dp
[4] * 256) << 16;
2390 data
= dp
[5] + dp
[6] * 256;
2391 mi
->mi_cmdmode
= TULIP_SROM_2114X_CMDBITS(data
);
2392 if (data
& TULIP_SROM_2114X_NOINDICATOR
) {
2395 mi
->mi_default
= (data
& TULIP_SROM_2114X_DEFAULT
) != 0;
2396 mi
->mi_actmask
= TULIP_SROM_2114X_BITPOS(data
);
2397 mi
->mi_actdata
= (data
& TULIP_SROM_2114X_POLARITY
) ? 0 : mi
->mi_actmask
;
2399 if (TULIP_IS_MEDIA_TP(media
))
2400 sc
->tulip_intrmask
|= TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
;
2405 case 5: { /* 21143 Reset block */
2406 mi
->mi_type
= TULIP_MEDIAINFO_RESET
;
2407 mi
->mi_reset_length
= *dp
++;
2408 mi
->mi_reset_offset
= dp
- sc
->tulip_rombuf
;
2409 dp
+= 2 * mi
->mi_reset_length
;
2420 return mi
- sc
->tulip_mediainfo
;
2423 static const struct {
2424 void (*vendor_identify_nic
)(tulip_softc_t
* const sc
);
2425 unsigned char vendor_oui
[3];
2426 } tulip_vendors
[] = {
2427 { tulip_identify_dec_nic
, { 0x08, 0x00, 0x2B } },
2428 { tulip_identify_dec_nic
, { 0x00, 0x00, 0xF8 } },
2429 { tulip_identify_smc_nic
, { 0x00, 0x00, 0xC0 } },
2430 { tulip_identify_smc_nic
, { 0x00, 0xE0, 0x29 } },
2431 { tulip_identify_znyx_nic
, { 0x00, 0xC0, 0x95 } },
2432 { tulip_identify_cogent_nic
, { 0x00, 0x00, 0x92 } },
2433 { tulip_identify_asante_nic
, { 0x00, 0x00, 0x94 } },
2434 { tulip_identify_cogent_nic
, { 0x00, 0x00, 0xD1 } },
2435 { tulip_identify_accton_nic
, { 0x00, 0x00, 0xE8 } },
2436 { tulip_identify_compex_nic
, { 0x00, 0x80, 0x48 } },
2441 * This deals with the vagaries of the address roms and the
2442 * brain-deadness that various vendors commit in using them.
2445 tulip_read_macaddr(tulip_softc_t
*sc
)
2447 u_int cksum
, rom_cksum
, idx
;
2449 unsigned char tmpbuf
[8];
2450 static const u_char testpat
[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA };
2452 sc
->tulip_connidx
= TULIP_SROM_LASTCONNIDX
;
2454 if (sc
->tulip_chipid
== TULIP_21040
) {
2455 TULIP_CSR_WRITE(sc
, csr_enetrom
, 1);
2456 for (idx
= 0; idx
< sizeof(sc
->tulip_rombuf
); idx
++) {
2458 while (((csr
= TULIP_CSR_READ(sc
, csr_enetrom
)) & 0x80000000L
) && cnt
< 10000)
2460 sc
->tulip_rombuf
[idx
] = csr
& 0xFF;
2462 sc
->tulip_boardsw
= &tulip_21040_boardsw
;
2464 if (sc
->tulip_chipid
== TULIP_21041
) {
2466 * Thankfully all 21041's act the same.
2468 sc
->tulip_boardsw
= &tulip_21041_boardsw
;
2471 * Assume all 21140 board are compatible with the
2472 * DEC 10/100 evaluation board. Not really valid but
2473 * it's the best we can do until every one switches to
2474 * the new SROM format.
2477 sc
->tulip_boardsw
= &tulip_21140_eb_boardsw
;
2479 tulip_srom_read(sc
);
2480 if (tulip_srom_crcok(sc
->tulip_rombuf
)) {
2482 * SROM CRC is valid therefore it must be in the
2485 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
|TULIP_HAVE_OKSROM
;
2486 } else if (sc
->tulip_rombuf
[126] == 0xff && sc
->tulip_rombuf
[127] == 0xFF) {
2488 * No checksum is present. See if the SROM id checks out;
2489 * the first 18 bytes should be 0 followed by a 1 followed
2490 * by the number of adapters (which we don't deal with yet).
2492 for (idx
= 0; idx
< 18; idx
++) {
2493 if (sc
->tulip_rombuf
[idx
] != 0)
2496 if (idx
== 18 && sc
->tulip_rombuf
[18] == 1 && sc
->tulip_rombuf
[19] != 0)
2497 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
;
2498 } else if (sc
->tulip_chipid
>= TULIP_21142
) {
2499 sc
->tulip_features
|= TULIP_HAVE_ISVSROM
;
2500 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2502 if ((sc
->tulip_features
& TULIP_HAVE_ISVSROM
) && tulip_srom_decode(sc
)) {
2503 if (sc
->tulip_chipid
!= TULIP_21041
)
2504 sc
->tulip_boardsw
= &tulip_2114x_isv_boardsw
;
2507 * If the SROM specifies more than one adapter, tag this as a
2510 if (sc
->tulip_rombuf
[19] > 1)
2511 sc
->tulip_features
|= TULIP_HAVE_BASEROM
;
2512 if (sc
->tulip_boardsw
== NULL
)
2519 if (bcmp(&sc
->tulip_rombuf
[0], &sc
->tulip_rombuf
[16], 8) != 0) {
2521 * Some folks don't use the standard ethernet rom format
2522 * but instead just put the address in the first 6 bytes
2523 * of the rom and let the rest be all 0xffs. (Can we say
2524 * ZNYX?) (well sometimes they put in a checksum so we'll
2527 for (idx
= 8; idx
< 32; idx
++) {
2528 if (sc
->tulip_rombuf
[idx
] != 0xFF)
2532 * Make sure the address is not multicast or locally assigned
2533 * that the OUI is not 00-00-00.
2535 if ((sc
->tulip_rombuf
[0] & 3) != 0)
2537 if (sc
->tulip_rombuf
[0] == 0 && sc
->tulip_rombuf
[1] == 0
2538 && sc
->tulip_rombuf
[2] == 0)
2540 bcopy(sc
->tulip_rombuf
, sc
->arpcom
.ac_enaddr
, ETHER_ADDR_LEN
);
2541 sc
->tulip_features
|= TULIP_HAVE_OKROM
;
2545 * A number of makers of multiport boards (ZNYX and Cogent)
2546 * only put on one address ROM on their 21040 boards. So
2547 * if the ROM is all zeros (or all 0xFFs), look at the
2548 * previous configured boards (as long as they are on the same
2549 * PCI bus and the bus number is non-zero) until we find the
2550 * master board with address ROM. We then use its address ROM
2551 * as the base for this board. (we add our relative board
2552 * to the last byte of its address).
2554 for (idx
= 0; idx
< sizeof(sc
->tulip_rombuf
); idx
++) {
2555 if (sc
->tulip_rombuf
[idx
] != 0 && sc
->tulip_rombuf
[idx
] != 0xFF)
2558 if (idx
== sizeof(sc
->tulip_rombuf
)) {
2560 tulip_softc_t
*root_sc
= NULL
;
2561 for (root_unit
= sc
->tulip_unit
- 1; root_unit
>= 0; root_unit
--) {
2562 root_sc
= tulips
[root_unit
];
2563 if (root_sc
== NULL
|| (root_sc
->tulip_features
& (TULIP_HAVE_OKROM
|TULIP_HAVE_SLAVEDROM
)) == TULIP_HAVE_OKROM
)
2567 if (root_sc
!= NULL
&& (root_sc
->tulip_features
& TULIP_HAVE_BASEROM
)
2568 && root_sc
->tulip_chipid
== sc
->tulip_chipid
2569 && root_sc
->tulip_pci_busno
== sc
->tulip_pci_busno
) {
2570 sc
->tulip_features
|= TULIP_HAVE_SLAVEDROM
;
2571 sc
->tulip_boardsw
= root_sc
->tulip_boardsw
;
2572 strcpy(sc
->tulip_boardid
, root_sc
->tulip_boardid
);
2573 if (sc
->tulip_boardsw
->bd_type
== TULIP_21140_ISV
) {
2574 bcopy(root_sc
->tulip_rombuf
, sc
->tulip_rombuf
,
2575 sizeof(sc
->tulip_rombuf
));
2576 if (!tulip_srom_decode(sc
))
2579 bcopy(root_sc
->arpcom
.ac_enaddr
, sc
->arpcom
.ac_enaddr
,
2581 sc
->arpcom
.ac_enaddr
[5] += sc
->tulip_unit
- root_sc
->tulip_unit
;
2584 * Now for a truly disgusting kludge: all 4 21040s on
2585 * the ZX314 share the same INTA line so the mapping
2586 * setup by the BIOS on the PCI bridge is worthless.
2587 * Rather than reprogramming the value in the config
2588 * register, we will handle this internally.
2590 if (root_sc
->tulip_features
& TULIP_HAVE_SHAREDINTR
) {
2591 sc
->tulip_slaves
= root_sc
->tulip_slaves
;
2592 root_sc
->tulip_slaves
= sc
;
2593 sc
->tulip_features
|= TULIP_HAVE_SLAVEDINTR
;
2601 * This is the standard DEC address ROM test.
2604 if (bcmp(&sc
->tulip_rombuf
[24], testpat
, 8) != 0)
2607 tmpbuf
[0] = sc
->tulip_rombuf
[15]; tmpbuf
[1] = sc
->tulip_rombuf
[14];
2608 tmpbuf
[2] = sc
->tulip_rombuf
[13]; tmpbuf
[3] = sc
->tulip_rombuf
[12];
2609 tmpbuf
[4] = sc
->tulip_rombuf
[11]; tmpbuf
[5] = sc
->tulip_rombuf
[10];
2610 tmpbuf
[6] = sc
->tulip_rombuf
[9]; tmpbuf
[7] = sc
->tulip_rombuf
[8];
2611 if (bcmp(&sc
->tulip_rombuf
[0], tmpbuf
, 8) != 0)
2614 bcopy(sc
->tulip_rombuf
, sc
->arpcom
.ac_enaddr
, ETHER_ADDR_LEN
);
2616 cksum
= *(u_int16_t
*) &sc
->arpcom
.ac_enaddr
[0];
2618 if (cksum
> 65535) cksum
-= 65535;
2619 cksum
+= *(u_int16_t
*) &sc
->arpcom
.ac_enaddr
[2];
2620 if (cksum
> 65535) cksum
-= 65535;
2622 if (cksum
> 65535) cksum
-= 65535;
2623 cksum
+= *(u_int16_t
*) &sc
->arpcom
.ac_enaddr
[4];
2624 if (cksum
>= 65535) cksum
-= 65535;
2626 rom_cksum
= *(u_int16_t
*) &sc
->tulip_rombuf
[6];
2628 if (cksum
!= rom_cksum
)
2633 * Check for various boards based on OUI. Did I say braindead?
2635 for (idx
= 0; tulip_vendors
[idx
].vendor_identify_nic
!= NULL
; idx
++) {
2636 if (bcmp(sc
->arpcom
.ac_enaddr
, tulip_vendors
[idx
].vendor_oui
, 3) == 0) {
2637 (*tulip_vendors
[idx
].vendor_identify_nic
)(sc
);
2642 sc
->tulip_features
|= TULIP_HAVE_OKROM
;
2647 tulip_ifmedia_add(tulip_softc_t
* const sc
)
2649 tulip_media_t media
;
2652 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
2653 if (sc
->tulip_mediums
[media
] != NULL
) {
2654 ifmedia_add(&sc
->tulip_ifmedia
, tulip_media_to_ifmedia
[media
],
2660 sc
->tulip_features
|= TULIP_HAVE_NOMEDIA
;
2661 ifmedia_add(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_NONE
, 0, 0);
2662 ifmedia_set(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_NONE
);
2663 } else if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
) {
2664 ifmedia_add(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_AUTO
, 0, 0);
2665 ifmedia_set(&sc
->tulip_ifmedia
, IFM_ETHER
| IFM_AUTO
);
2667 ifmedia_set(&sc
->tulip_ifmedia
, tulip_media_to_ifmedia
[sc
->tulip_media
]);
2668 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
2669 tulip_linkup(sc
, sc
->tulip_media
);
2674 tulip_ifmedia_change(struct ifnet
*ifp
)
2676 tulip_softc_t
*sc
= (tulip_softc_t
*)ifp
->if_softc
;
2678 sc
->tulip_flags
|= TULIP_NEEDRESET
;
2679 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
2680 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
2681 if (IFM_SUBTYPE(sc
->tulip_ifmedia
.ifm_media
) != IFM_AUTO
) {
2682 tulip_media_t media
;
2683 for (media
= TULIP_MEDIA_UNKNOWN
; media
< TULIP_MEDIA_MAX
; media
++) {
2684 if (sc
->tulip_mediums
[media
] != NULL
2685 && sc
->tulip_ifmedia
.ifm_media
== tulip_media_to_ifmedia
[media
]) {
2686 sc
->tulip_flags
|= TULIP_PRINTMEDIA
;
2687 sc
->tulip_flags
&= ~TULIP_DIDNWAY
;
2688 tulip_linkup(sc
, media
);
2693 sc
->tulip_flags
&= ~(TULIP_TXPROBE_ACTIVE
|TULIP_WANTRXACT
);
2700 * Media status callback
2703 tulip_ifmedia_status(struct ifnet
*ifp
, struct ifmediareq
*req
)
2705 tulip_softc_t
*sc
= (tulip_softc_t
*)ifp
->if_softc
;
2707 if (sc
->tulip_media
== TULIP_MEDIA_UNKNOWN
)
2710 req
->ifm_status
= IFM_AVALID
;
2711 if (sc
->tulip_flags
& TULIP_LINKUP
)
2712 req
->ifm_status
|= IFM_ACTIVE
;
2714 req
->ifm_active
= tulip_media_to_ifmedia
[sc
->tulip_media
];
2718 tulip_addr_filter(tulip_softc_t
*sc
)
2720 struct ifmultiaddr
*ifma
;
2725 sc
->tulip_flags
&= ~(TULIP_WANTHASHPERFECT
|TULIP_WANTHASHONLY
|TULIP_ALLMULTI
);
2726 sc
->tulip_flags
|= TULIP_WANTSETUP
|TULIP_WANTTXSTART
;
2727 sc
->tulip_cmdmode
&= ~TULIP_CMD_RXRUN
;
2728 sc
->tulip_intrmask
&= ~TULIP_STS_RXSTOPPED
;
2729 #if defined(IFF_ALLMULTI)
2730 if (sc
->arpcom
.ac_if
.if_flags
& IFF_ALLMULTI
)
2731 sc
->tulip_flags
|= TULIP_ALLMULTI
;
2735 ifp
= &sc
->arpcom
.ac_if
;
2736 TAILQ_FOREACH(ifma
, &ifp
->if_multiaddrs
, ifma_link
) {
2737 if (ifma
->ifma_addr
->sa_family
== AF_LINK
)
2741 if (multicnt
> 14) {
2742 uint32_t *sp
= sc
->tulip_setupdata
;
2745 * Some early passes of the 21140 have broken implementations of
2746 * hash-perfect mode. When we get too many multicasts for perfect
2747 * filtering with these chips, we need to switch into hash-only
2748 * mode (this is better than all-multicast on network with lots
2749 * of multicast traffic).
2751 if (sc
->tulip_features
& TULIP_HAVE_BROKEN_HASH
)
2752 sc
->tulip_flags
|= TULIP_WANTHASHONLY
;
2754 sc
->tulip_flags
|= TULIP_WANTHASHPERFECT
;
2756 * If we have more than 14 multicasts, we have
2757 * go into hash perfect mode (512 bit multicast
2758 * hash and one perfect hardware).
2760 bzero(sc
->tulip_setupdata
, sizeof(sc
->tulip_setupdata
));
2762 TAILQ_FOREACH(ifma
, &ifp
->if_multiaddrs
, ifma_link
) {
2763 if (ifma
->ifma_addr
->sa_family
!= AF_LINK
)
2766 hash
= tulip_mchash(LLADDR((struct sockaddr_dl
*)ifma
->ifma_addr
));
2767 sp
[hash
>> 4] |= htole32(1 << (hash
& 0xF));
2770 * No reason to use a hash if we are going to be
2771 * receiving every multicast.
2773 if ((sc
->tulip_flags
& TULIP_ALLMULTI
) == 0) {
2774 hash
= tulip_mchash(ifp
->if_broadcastaddr
);
2775 sp
[hash
>> 4] |= htole32(1 << (hash
& 0xF));
2776 if (sc
->tulip_flags
& TULIP_WANTHASHONLY
) {
2777 hash
= tulip_mchash(sc
->arpcom
.ac_enaddr
);
2778 sp
[hash
>> 4] |= htole32(1 << (hash
& 0xF));
2780 sp
[39] = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[0]);
2781 sp
[40] = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[1]);
2782 sp
[41] = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[2]);
2786 if ((sc
->tulip_flags
& (TULIP_WANTHASHPERFECT
|TULIP_WANTHASHONLY
)) == 0) {
2787 uint32_t *sp
= sc
->tulip_setupdata
;
2789 if ((sc
->tulip_flags
& TULIP_ALLMULTI
) == 0) {
2791 * Else can get perfect filtering for 16 addresses.
2793 TAILQ_FOREACH(ifma
, &ifp
->if_multiaddrs
, ifma_link
) {
2794 if (ifma
->ifma_addr
->sa_family
!= AF_LINK
)
2796 addrp
= LLADDR((struct sockaddr_dl
*)ifma
->ifma_addr
);
2797 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)addrp
)[0]);
2798 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)addrp
)[1]);
2799 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)addrp
)[2]);
2803 * Add the broadcast address.
2806 *sp
++ = TULIP_SP_MAC(0xFFFF);
2807 *sp
++ = TULIP_SP_MAC(0xFFFF);
2808 *sp
++ = TULIP_SP_MAC(0xFFFF);
2811 * Pad the rest with our hardware address
2813 for (; idx
< 16; idx
++) {
2814 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[0]);
2815 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[1]);
2816 *sp
++ = TULIP_SP_MAC(((u_int16_t
*)sc
->arpcom
.ac_enaddr
)[2]);
2819 #if defined(IFF_ALLMULTI)
2820 if (sc
->tulip_flags
& TULIP_ALLMULTI
)
2821 sc
->arpcom
.ac_if
.if_flags
|= IFF_ALLMULTI
;
2826 tulip_reset(tulip_softc_t
*sc
)
2828 tulip_ringinfo_t
*ri
;
2829 tulip_descinfo_t
*di
;
2831 uint32_t inreset
= (sc
->tulip_flags
& TULIP_INRESET
);
2834 * Brilliant. Simply brilliant. When switching modes/speeds
2835 * on a 2114*, you need to set the appriopriate MII/PCS/SCL/PS
2836 * bits in CSR6 and then do a software reset to get the 21140
2837 * to properly reset its internal pathways to the right places.
2840 if ((sc
->tulip_flags
& TULIP_DEVICEPROBE
) == 0
2841 && sc
->tulip_boardsw
->bd_media_preset
!= NULL
)
2842 (*sc
->tulip_boardsw
->bd_media_preset
)(sc
);
2844 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
2845 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
2846 33MHz that comes to two microseconds but wait a
2847 bit longer anyways) */
2850 sc
->tulip_flags
|= TULIP_INRESET
;
2851 sc
->tulip_flags
&= ~(TULIP_NEEDRESET
|TULIP_RXBUFSLOW
);
2852 ifq_clr_oactive(&sc
->arpcom
.ac_if
.if_snd
);
2855 TULIP_CSR_WRITE(sc
, csr_txlist
, sc
->tulip_txinfo
.ri_dma_addr
& 0xffffffff);
2856 TULIP_CSR_WRITE(sc
, csr_rxlist
, sc
->tulip_rxinfo
.ri_dma_addr
& 0xffffffff);
2857 TULIP_CSR_WRITE(sc
, csr_busmode
,
2858 (1 << (3 /*pci_max_burst_len*/ + 8))
2859 |TULIP_BUSMODE_CACHE_ALIGN8
2860 |TULIP_BUSMODE_READMULTIPLE
2861 |(BYTE_ORDER
!= LITTLE_ENDIAN
?
2862 TULIP_BUSMODE_DESC_BIGENDIAN
: 0));
2864 sc
->tulip_txtimer
= 0;
2865 sc
->tulip_txq
.ifq_maxlen
= TULIP_TXDESCS
;
2867 * Free all the mbufs that were on the transmit ring.
2869 ri
= &sc
->tulip_txinfo
;
2870 for (di
= ri
->ri_first
; di
< ri
->ri_last
; di
++) {
2871 m
= tulip_dequeue_mbuf(ri
, di
, SYNC_NONE
);
2874 di
->di_desc
->d_status
= 0;
2877 ri
->ri_nextin
= ri
->ri_nextout
= ri
->ri_first
;
2878 ri
->ri_free
= ri
->ri_max
;
2879 TULIP_TXDESC_PRESYNC(ri
);
2882 * We need to collect all the mbufs that were on the
2883 * receive ring before we reinit it either to put
2884 * them back on or to know if we have to allocate
2887 ri
= &sc
->tulip_rxinfo
;
2888 ri
->ri_nextin
= ri
->ri_nextout
= ri
->ri_first
;
2889 ri
->ri_free
= ri
->ri_max
;
2890 for (di
= ri
->ri_first
; di
< ri
->ri_last
; di
++) {
2891 di
->di_desc
->d_status
= 0;
2892 di
->di_desc
->d_length1
= 0; di
->di_desc
->d_addr1
= 0;
2893 di
->di_desc
->d_length2
= 0; di
->di_desc
->d_addr2
= 0;
2895 TULIP_RXDESC_PRESYNC(ri
);
2896 for (di
= ri
->ri_first
; di
< ri
->ri_last
; di
++) {
2897 m
= tulip_dequeue_mbuf(ri
, di
, SYNC_NONE
);
2903 * If tulip_reset is being called recursively, exit quickly knowing
2904 * that when the outer tulip_reset returns all the right stuff will
2910 sc
->tulip_intrmask
|= TULIP_STS_NORMALINTR
|TULIP_STS_RXINTR
|TULIP_STS_TXINTR
2911 |TULIP_STS_ABNRMLINTR
|TULIP_STS_SYSERROR
|TULIP_STS_TXSTOPPED
2912 |TULIP_STS_TXUNDERFLOW
|TULIP_STS_TXBABBLE
2913 |TULIP_STS_RXSTOPPED
;
2915 if ((sc
->tulip_flags
& TULIP_DEVICEPROBE
) == 0)
2916 (*sc
->tulip_boardsw
->bd_media_select
)(sc
);
2917 tulip_media_print(sc
);
2918 if (sc
->tulip_features
& TULIP_HAVE_DUALSENSE
)
2919 TULIP_CSR_WRITE(sc
, csr_sia_status
, TULIP_CSR_READ(sc
, csr_sia_status
));
2921 sc
->tulip_flags
&= ~(TULIP_DOINGSETUP
|TULIP_WANTSETUP
|TULIP_INRESET
2923 tulip_addr_filter(sc
);
2927 tulip_init(tulip_softc_t
* const sc
)
2929 if (sc
->arpcom
.ac_if
.if_flags
& IFF_UP
) {
2930 if ((sc
->arpcom
.ac_if
.if_flags
& IFF_RUNNING
) == 0) {
2931 /* initialize the media */
2934 sc
->arpcom
.ac_if
.if_flags
|= IFF_RUNNING
;
2935 if (sc
->arpcom
.ac_if
.if_flags
& IFF_PROMISC
) {
2936 sc
->tulip_flags
|= TULIP_PROMISC
;
2937 sc
->tulip_cmdmode
|= TULIP_CMD_PROMISCUOUS
;
2938 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
2940 sc
->tulip_flags
&= ~TULIP_PROMISC
;
2941 sc
->tulip_cmdmode
&= ~TULIP_CMD_PROMISCUOUS
;
2942 if (sc
->tulip_flags
& TULIP_ALLMULTI
) {
2943 sc
->tulip_cmdmode
|= TULIP_CMD_ALLMULTI
;
2945 sc
->tulip_cmdmode
&= ~TULIP_CMD_ALLMULTI
;
2948 sc
->tulip_cmdmode
|= TULIP_CMD_TXRUN
;
2949 if ((sc
->tulip_flags
& (TULIP_TXPROBE_ACTIVE
|TULIP_WANTSETUP
)) == 0) {
2951 sc
->tulip_cmdmode
|= TULIP_CMD_RXRUN
;
2952 sc
->tulip_intrmask
|= TULIP_STS_RXSTOPPED
;
2954 ifq_set_oactive(&sc
->arpcom
.ac_if
.if_snd
);
2955 sc
->tulip_cmdmode
&= ~TULIP_CMD_RXRUN
;
2956 sc
->tulip_intrmask
&= ~TULIP_STS_RXSTOPPED
;
2958 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
2959 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
2960 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == TULIP_WANTSETUP
)
2961 tulip_txput_setup(sc
);
2963 sc
->arpcom
.ac_if
.if_flags
&= ~IFF_RUNNING
;
2968 #define DESC_STATUS(di) (((volatile tulip_desc_t *)((di)->di_desc))->d_status)
2969 #define DESC_FLAG(di) ((di)->di_desc->d_flag)
2972 tulip_rx_intr(tulip_softc_t
*sc
)
2974 tulip_ringinfo_t
*ri
= &sc
->tulip_rxinfo
;
2975 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
2979 tulip_descinfo_t
*eop
= ri
->ri_nextin
, *dip
;
2980 int total_len
= 0, last_offset
= 0;
2981 struct mbuf
*ms
= NULL
, *me
= NULL
;
2985 if (fillok
&& (ri
->ri_max
- ri
->ri_free
) < TULIP_RXQ_TARGET
)
2989 * If the TULIP has no descriptors, there can't be any receive
2990 * descriptors to process.
2992 if (eop
== ri
->ri_nextout
)
2996 * 90% of the packets will fit in one descriptor. So we optimize
2999 TULIP_RXDESC_POSTSYNC(ri
);
3000 if ((DESC_STATUS(eop
) & (TULIP_DSTS_OWNER
|TULIP_DSTS_RxFIRSTDESC
|TULIP_DSTS_RxLASTDESC
)) == (TULIP_DSTS_RxFIRSTDESC
|TULIP_DSTS_RxLASTDESC
)) {
3001 ms
= tulip_dequeue_mbuf(ri
, eop
, SYNC_RX
);
3006 * If still owned by the TULIP, don't touch it.
3008 if (DESC_STATUS(eop
) & TULIP_DSTS_OWNER
)
3012 * It is possible (though improbable unless MCLBYTES < 1518) for
3013 * a received packet to cross more than one receive descriptor.
3014 * We first loop through the descriptor ring making sure we have
3015 * received a complete packet. If not, we bail until the next
3019 while ((DESC_STATUS(eop
) & TULIP_DSTS_RxLASTDESC
) == 0) {
3020 if (++eop
== ri
->ri_last
)
3022 TULIP_RXDESC_POSTSYNC(ri
);
3023 if (eop
== ri
->ri_nextout
|| (DESC_STATUS(eop
) & TULIP_DSTS_OWNER
)) {
3030 * Dequeue the first buffer for the start of the packet. Hopefully
3031 * this will be the only one we need to dequeue. However, if the
3032 * packet consumed multiple descriptors, then we need to dequeue
3033 * those buffers and chain to the starting mbuf. All buffers but
3034 * the last buffer have the same length so we can set that now.
3035 * (we add to last_offset instead of multiplying since we normally
3036 * won't go into the loop and thereby saving ourselves from
3037 * doing a multiplication by 0 in the normal case).
3039 ms
= tulip_dequeue_mbuf(ri
, dip
, SYNC_RX
);
3041 for (me
= ms
; total_len
> 0; total_len
--) {
3042 me
->m_len
= TULIP_RX_BUFLEN
;
3043 last_offset
+= TULIP_RX_BUFLEN
;
3044 if (++dip
== ri
->ri_last
)
3046 me
->m_next
= tulip_dequeue_mbuf(ri
, dip
, SYNC_RX
);
3050 KASSERT(dip
== eop
, ("mismatched descinfo structs"));
3054 * Now get the size of received packet (minus the CRC).
3056 total_len
= ((DESC_STATUS(eop
) >> 16) & 0x7FFF) - ETHER_CRC_LEN
;
3057 if ((sc
->tulip_flags
& TULIP_RXIGNORE
) == 0
3058 && ((DESC_STATUS(eop
) & TULIP_DSTS_ERRSUM
) == 0)) {
3059 me
->m_len
= total_len
- last_offset
;
3060 sc
->tulip_flags
|= TULIP_RXACT
;
3063 IFNET_STAT_INC(ifp
, ierrors
, 1);
3064 if (DESC_STATUS(eop
) & (TULIP_DSTS_RxBADLENGTH
|TULIP_DSTS_RxOVERFLOW
|TULIP_DSTS_RxWATCHDOG
)) {
3065 sc
->tulip_dot3stats
.dot3StatsInternalMacReceiveErrors
++;
3067 if (DESC_STATUS(eop
) & TULIP_DSTS_RxTOOLONG
) {
3068 sc
->tulip_dot3stats
.dot3StatsFrameTooLongs
++;
3070 if (DESC_STATUS(eop
) & TULIP_DSTS_RxBADCRC
) {
3071 if (DESC_STATUS(eop
) & TULIP_DSTS_RxDRBBLBIT
) {
3072 sc
->tulip_dot3stats
.dot3StatsAlignmentErrors
++;
3074 sc
->tulip_dot3stats
.dot3StatsFCSErrors
++;
3079 IFNET_STAT_INC(ifp
, ipackets
, 1);
3080 if (++eop
== ri
->ri_last
)
3082 ri
->ri_nextin
= eop
;
3085 * We have received a good packet that needs to be passed up the
3091 KASSERT(ms
!= NULL
, ("no packet to accept"));
3093 * Update the header for the mbuf referencing this receive
3094 * buffer and pass it up the stack. Allocate a new mbuf cluster
3095 * to replace the one we just passed up the stack.
3097 * Note that if this packet crossed multiple descriptors
3098 * we don't even try to reallocate all the mbufs here.
3099 * Instead we rely on the test at the beginning of
3100 * the loop to refill for the extra consumed mbufs.
3102 ms
->m_pkthdr
.len
= total_len
;
3103 ms
->m_pkthdr
.rcvif
= ifp
;
3105 ifp
->if_input(ifp
, m0
, NULL
, -1);
3106 ms
= m_getcl(M_NOWAIT
, MT_DATA
, M_PKTHDR
);
3107 } else if (ms
== NULL
) {
3109 * If we are priming the TULIP with mbufs, then allocate
3110 * a new cluster for the next descriptor.
3112 ms
= m_getcl(M_NOWAIT
, MT_DATA
, M_PKTHDR
);
3116 * Couldn't allocate a new buffer. Don't bother
3117 * trying to replenish the receive queue.
3120 sc
->tulip_flags
|= TULIP_RXBUFSLOW
;
3124 * Now give the buffer(s) to the TULIP and save in our
3128 tulip_descinfo_t
* const nextout
= ri
->ri_nextout
;
3131 KASSERT(ms
->m_data
== ms
->m_ext
.ext_buf
,
3132 ("rx mbuf data doesn't point to cluster"));
3133 ms
->m_len
= ms
->m_pkthdr
.len
= TULIP_RX_BUFLEN
;
3134 error
= bus_dmamap_load_mbuf(ri
->ri_data_tag
, *nextout
->di_map
, ms
,
3135 tulip_dma_map_rxbuf
, nextout
->di_desc
, BUS_DMA_NOWAIT
);
3137 device_printf(sc
->tulip_dev
,
3138 "unable to load rx map, error = %d\n", error
);
3139 panic("tulip_rx_intr"); /* XXX */
3141 nextout
->di_desc
->d_status
= TULIP_DSTS_OWNER
;
3142 KASSERT(nextout
->di_mbuf
== NULL
, ("clobbering earlier rx mbuf"));
3143 nextout
->di_mbuf
= ms
;
3144 TULIP_RXDESC_POSTSYNC(ri
);
3145 if (++ri
->ri_nextout
== ri
->ri_last
)
3146 ri
->ri_nextout
= ri
->ri_first
;
3150 } while ((ms
= me
) != NULL
);
3152 if ((ri
->ri_max
- ri
->ri_free
) >= TULIP_RXQ_TARGET
)
3153 sc
->tulip_flags
&= ~TULIP_RXBUFSLOW
;
3158 tulip_tx_intr(tulip_softc_t
*sc
)
3160 tulip_ringinfo_t
*ri
= &sc
->tulip_txinfo
;
3165 while (ri
->ri_free
< ri
->ri_max
) {
3168 TULIP_TXDESC_POSTSYNC(ri
);
3169 if (DESC_STATUS(ri
->ri_nextin
) & TULIP_DSTS_OWNER
)
3174 d_flag
= DESC_FLAG(ri
->ri_nextin
);
3175 if (d_flag
& TULIP_DFLAG_TxLASTSEG
) {
3176 if (d_flag
& TULIP_DFLAG_TxSETUPPKT
) {
3178 * We've just finished processing a setup packet.
3179 * Mark that we finished it. If there's not
3180 * another pending, startup the TULIP receiver.
3181 * Make sure we ack the RXSTOPPED so we won't get
3182 * an abormal interrupt indication.
3184 bus_dmamap_sync(sc
->tulip_setup_tag
, sc
->tulip_setup_map
,
3185 BUS_DMASYNC_POSTWRITE
);
3186 sc
->tulip_flags
&= ~(TULIP_DOINGSETUP
|TULIP_HASHONLY
);
3187 if (DESC_FLAG(ri
->ri_nextin
) & TULIP_DFLAG_TxINVRSFILT
)
3188 sc
->tulip_flags
|= TULIP_HASHONLY
;
3189 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == 0) {
3191 sc
->tulip_cmdmode
|= TULIP_CMD_RXRUN
;
3192 sc
->tulip_intrmask
|= TULIP_STS_RXSTOPPED
;
3193 TULIP_CSR_WRITE(sc
, csr_status
, TULIP_STS_RXSTOPPED
);
3194 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3195 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
3198 const uint32_t d_status
= DESC_STATUS(ri
->ri_nextin
);
3199 m
= tulip_dequeue_mbuf(ri
, ri
->ri_nextin
, SYNC_TX
);
3203 if (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) {
3204 tulip_mediapoll_event_t event
= TULIP_MEDIAPOLL_TXPROBE_OK
;
3205 if (d_status
& (TULIP_DSTS_TxNOCARR
|TULIP_DSTS_TxEXCCOLL
)) {
3206 event
= TULIP_MEDIAPOLL_TXPROBE_FAILED
;
3208 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, event
);
3210 * Escape from the loop before media poll has reset the TULIP!
3215 if (d_status
& TULIP_DSTS_ERRSUM
) {
3216 IFNET_STAT_INC(&sc
->arpcom
.ac_if
, oerrors
, 1);
3217 if (d_status
& TULIP_DSTS_TxEXCCOLL
)
3218 sc
->tulip_dot3stats
.dot3StatsExcessiveCollisions
++;
3219 if (d_status
& TULIP_DSTS_TxLATECOLL
)
3220 sc
->tulip_dot3stats
.dot3StatsLateCollisions
++;
3221 if (d_status
& (TULIP_DSTS_TxNOCARR
|TULIP_DSTS_TxCARRLOSS
))
3222 sc
->tulip_dot3stats
.dot3StatsCarrierSenseErrors
++;
3223 if (d_status
& (TULIP_DSTS_TxUNDERFLOW
|TULIP_DSTS_TxBABBLE
))
3224 sc
->tulip_dot3stats
.dot3StatsInternalMacTransmitErrors
++;
3225 if (d_status
& TULIP_DSTS_TxUNDERFLOW
)
3226 sc
->tulip_dot3stats
.dot3StatsInternalTransmitUnderflows
++;
3227 if (d_status
& TULIP_DSTS_TxBABBLE
)
3228 sc
->tulip_dot3stats
.dot3StatsInternalTransmitBabbles
++;
3230 u_int32_t collisions
=
3231 (d_status
& TULIP_DSTS_TxCOLLMASK
)
3232 >> TULIP_DSTS_V_TxCOLLCNT
;
3233 IFNET_STAT_INC(&sc
->arpcom
.ac_if
, collisions
, collisions
);
3234 if (collisions
== 1)
3235 sc
->tulip_dot3stats
.dot3StatsSingleCollisionFrames
++;
3236 else if (collisions
> 1)
3237 sc
->tulip_dot3stats
.dot3StatsMultipleCollisionFrames
++;
3238 else if (d_status
& TULIP_DSTS_TxDEFERRED
)
3239 sc
->tulip_dot3stats
.dot3StatsDeferredTransmissions
++;
3241 * SQE is only valid for 10baseT/BNC/AUI when not
3242 * running in full-duplex. In order to speed up the
3243 * test, the corresponding bit in tulip_flags needs to
3244 * set as well to get us to count SQE Test Errors.
3246 if (d_status
& TULIP_DSTS_TxNOHRTBT
& sc
->tulip_flags
)
3247 sc
->tulip_dot3stats
.dot3StatsSQETestErrors
++;
3253 if (++ri
->ri_nextin
== ri
->ri_last
)
3254 ri
->ri_nextin
= ri
->ri_first
;
3256 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0)
3257 ifq_clr_oactive(&sc
->arpcom
.ac_if
.if_snd
);
3260 * If nothing left to transmit, disable the timer.
3261 * Else if progress, reset the timer back to 2 ticks.
3263 if (ri
->ri_free
== ri
->ri_max
|| (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
))
3264 sc
->tulip_txtimer
= 0;
3266 sc
->tulip_txtimer
= TULIP_TXTIMER
;
3267 IFNET_STAT_INC(&sc
->arpcom
.ac_if
, opackets
, xmits
);
3272 tulip_print_abnormal_interrupt(tulip_softc_t
*sc
, uint32_t csr
)
3274 const char * const *msgp
= tulip_status_bits
;
3277 const char thrsh
[] = "72|128\0\0\0" "96|256\0\0\0" "128|512\0\0" "160|1024";
3279 csr
&= (1 << (NELEM(tulip_status_bits
))) - 1;
3280 if_printf(&sc
->arpcom
.ac_if
, "abnormal interrupt:");
3281 for (sep
= " ", mask
= 1; mask
<= csr
; mask
<<= 1, msgp
++) {
3282 if ((csr
& mask
) && *msgp
!= NULL
) {
3283 kprintf("%s%s", sep
, *msgp
);
3284 if (mask
== TULIP_STS_TXUNDERFLOW
&& (sc
->tulip_flags
& TULIP_NEWTXTHRESH
)) {
3285 sc
->tulip_flags
&= ~TULIP_NEWTXTHRESH
;
3286 if (sc
->tulip_cmdmode
& TULIP_CMD_STOREFWD
) {
3287 kprintf(" (switching to store-and-forward mode)");
3289 kprintf(" (raising TX threshold to %s)",
3290 &thrsh
[9 * ((sc
->tulip_cmdmode
& TULIP_CMD_THRESHOLDCTL
) >> 14)]);
3300 tulip_intr_handler(tulip_softc_t
*sc
)
3304 while ((csr
= TULIP_CSR_READ(sc
, csr_status
)) & sc
->tulip_intrmask
) {
3305 TULIP_CSR_WRITE(sc
, csr_status
, csr
);
3307 if (csr
& TULIP_STS_SYSERROR
) {
3308 sc
->tulip_last_system_error
= (csr
& TULIP_STS_ERRORMASK
) >> TULIP_STS_ERR_SHIFT
;
3309 if (sc
->tulip_flags
& TULIP_NOMESSAGES
) {
3310 sc
->tulip_flags
|= TULIP_SYSTEMERROR
;
3312 if_printf(&sc
->arpcom
.ac_if
, "system error: %s\n",
3313 tulip_system_errors
[sc
->tulip_last_system_error
]);
3315 sc
->tulip_flags
|= TULIP_NEEDRESET
;
3316 sc
->tulip_system_errors
++;
3319 if (csr
& (TULIP_STS_LINKPASS
|TULIP_STS_LINKFAIL
) & sc
->tulip_intrmask
) {
3320 if (sc
->tulip_boardsw
->bd_media_poll
!= NULL
) {
3321 (*sc
->tulip_boardsw
->bd_media_poll
)(sc
, csr
& TULIP_STS_LINKFAIL
3322 ? TULIP_MEDIAPOLL_LINKFAIL
3323 : TULIP_MEDIAPOLL_LINKPASS
);
3324 csr
&= ~TULIP_STS_ABNRMLINTR
;
3326 tulip_media_print(sc
);
3328 if (csr
& (TULIP_STS_RXINTR
|TULIP_STS_RXNOBUF
)) {
3329 u_int32_t misses
= TULIP_CSR_READ(sc
, csr_missed_frames
);
3330 if (csr
& TULIP_STS_RXNOBUF
)
3331 sc
->tulip_dot3stats
.dot3StatsMissedFrames
+= misses
& 0xFFFF;
3333 * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
3334 * on receive overflows.
3336 if ((misses
& 0x0FFE0000) && (sc
->tulip_features
& TULIP_HAVE_RXBADOVRFLW
)) {
3337 sc
->tulip_dot3stats
.dot3StatsInternalMacReceiveErrors
++;
3339 * Stop the receiver process and spin until it's stopped.
3340 * Tell rx_intr to drop the packets it dequeues.
3342 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
& ~TULIP_CMD_RXRUN
);
3343 while ((TULIP_CSR_READ(sc
, csr_status
) & TULIP_STS_RXSTOPPED
) == 0)
3345 TULIP_CSR_WRITE(sc
, csr_status
, TULIP_STS_RXSTOPPED
);
3346 sc
->tulip_flags
|= TULIP_RXIGNORE
;
3349 if (sc
->tulip_flags
& TULIP_RXIGNORE
) {
3351 * Restart the receiver.
3353 sc
->tulip_flags
&= ~TULIP_RXIGNORE
;
3354 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
3357 if (csr
& TULIP_STS_ABNRMLINTR
) {
3358 u_int32_t tmp
= csr
& sc
->tulip_intrmask
3359 & ~(TULIP_STS_NORMALINTR
|TULIP_STS_ABNRMLINTR
);
3360 if (csr
& TULIP_STS_TXUNDERFLOW
) {
3361 if ((sc
->tulip_cmdmode
& TULIP_CMD_THRESHOLDCTL
) != TULIP_CMD_THRSHLD160
) {
3362 sc
->tulip_cmdmode
+= TULIP_CMD_THRSHLD96
;
3363 sc
->tulip_flags
|= TULIP_NEWTXTHRESH
;
3364 } else if (sc
->tulip_features
& TULIP_HAVE_STOREFWD
) {
3365 sc
->tulip_cmdmode
|= TULIP_CMD_STOREFWD
;
3366 sc
->tulip_flags
|= TULIP_NEWTXTHRESH
;
3369 if (sc
->tulip_flags
& TULIP_NOMESSAGES
) {
3370 sc
->tulip_statusbits
|= tmp
;
3372 tulip_print_abnormal_interrupt(sc
, tmp
);
3373 sc
->tulip_flags
|= TULIP_NOMESSAGES
;
3375 TULIP_CSR_WRITE(sc
, csr_command
, sc
->tulip_cmdmode
);
3377 if (sc
->tulip_flags
& (TULIP_WANTTXSTART
|TULIP_TXPROBE_ACTIVE
|TULIP_DOINGSETUP
|TULIP_PROMISC
)) {
3379 if ((sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) == 0)
3380 if_devstart(&sc
->arpcom
.ac_if
);
3383 if (sc
->tulip_flags
& TULIP_NEEDRESET
) {
3390 tulip_intr_shared(void *arg
)
3394 for (sc
= arg
; sc
!= NULL
; sc
= sc
->tulip_slaves
)
3395 tulip_intr_handler(sc
);
3399 tulip_intr_normal(void *arg
)
3401 tulip_softc_t
*sc
= (tulip_softc_t
*)arg
;
3403 tulip_intr_handler(sc
);
3406 static struct mbuf
*
3407 tulip_txput(tulip_softc_t
*sc
, struct mbuf
*m
)
3409 tulip_ringinfo_t
* const ri
= &sc
->tulip_txinfo
;
3410 tulip_descinfo_t
*eop
, *nextout
;
3413 bus_dma_segment_t segs
[TULIP_MAX_TXSEG
];
3419 * Now we try to fill in our transmit descriptors. This is
3420 * a bit reminiscent of going on the Ark two by two
3421 * since each descriptor for the TULIP can describe
3422 * two buffers. So we advance through packet filling
3423 * each of the two entries at a time to to fill each
3424 * descriptor. Clear the first and last segment bits
3425 * in each descriptor (actually just clear everything
3426 * but the end-of-ring or chain bits) to make sure
3427 * we don't get messed up by previously sent packets.
3429 * We may fail to put the entire packet on the ring if
3430 * there is either not enough ring entries free or if the
3431 * packet has more than MAX_TXSEG segments. In the former
3432 * case we will just wait for the ring to empty. In the
3433 * latter case we have to recopy.
3437 eop
= nextout
= ri
->ri_nextout
;
3442 * Reclaim some tx descriptors if we are out since we need at least one
3443 * free descriptor so that we have a dma_map to load the mbuf.
3446 free
+= tulip_tx_intr(sc
);
3449 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
3452 error
= bus_dmamap_load_mbuf_segment(ri
->ri_data_tag
, *eop
->di_map
, m
, segs
,
3453 1, &nsegs
, BUS_DMA_NOWAIT
);
3455 if (error
== EFBIG
) {
3457 * The packet exceeds the number of transmit buffer
3458 * entries that we can use for one packet, so we have
3459 * to recopy it into one mbuf and then try again. If
3460 * we can't recopy it, try again later.
3462 m0
= m_defrag(m
, M_NOWAIT
);
3464 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
3468 error
= bus_dmamap_load_mbuf_segment(ri
->ri_data_tag
, *eop
->di_map
,
3469 m
, segs
, 1, &nsegs
, BUS_DMA_NOWAIT
);
3472 device_printf(sc
->tulip_dev
,
3473 "unable to load tx map, error = %d\n", error
);
3478 * Each descriptor allows for up to 2 fragments since we don't use
3479 * the descriptor chaining mode in this driver.
3481 if ((free
-= (nsegs
+ 1) / 2) <= 0
3483 * See if there's any unclaimed space in the transmit ring.
3485 && (free
+= tulip_tx_intr(sc
)) <= 0) {
3487 * There's no more room but since nothing
3488 * has been committed at this point, just
3489 * show output is active, put back the
3492 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
3493 bus_dmamap_unload(ri
->ri_data_tag
, *eop
->di_map
);
3496 for (; nsegs
- segcnt
> 1; segcnt
+= 2) {
3498 eop
->di_desc
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
3499 eop
->di_desc
->d_status
= d_status
;
3500 eop
->di_desc
->d_addr1
= segs
[segcnt
].ds_addr
& 0xffffffff;
3501 eop
->di_desc
->d_length1
= segs
[segcnt
].ds_len
;
3502 eop
->di_desc
->d_addr2
= segs
[segcnt
+1].ds_addr
& 0xffffffff;
3503 eop
->di_desc
->d_length2
= segs
[segcnt
+1].ds_len
;
3504 d_status
= TULIP_DSTS_OWNER
;
3505 if (++nextout
== ri
->ri_last
)
3506 nextout
= ri
->ri_first
;
3508 if (segcnt
< nsegs
) {
3510 eop
->di_desc
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
3511 eop
->di_desc
->d_status
= d_status
;
3512 eop
->di_desc
->d_addr1
= segs
[segcnt
].ds_addr
& 0xffffffff;
3513 eop
->di_desc
->d_length1
= segs
[segcnt
].ds_len
;
3514 eop
->di_desc
->d_addr2
= 0;
3515 eop
->di_desc
->d_length2
= 0;
3516 if (++nextout
== ri
->ri_last
)
3517 nextout
= ri
->ri_first
;
3521 * tulip_tx_intr() harvests the mbuf from the last descriptor in the
3522 * frame. We just used the dmamap in the first descriptor for the
3523 * load operation however. Thus, to let the tulip_dequeue_mbuf() call
3524 * in tulip_tx_intr() unload the correct dmamap, we swap the dmamap
3525 * pointers in the two descriptors if this is a multiple-descriptor
3528 if (eop
!= ri
->ri_nextout
) {
3530 eop
->di_map
= ri
->ri_nextout
->di_map
;
3531 ri
->ri_nextout
->di_map
= map
;
3535 * bounce a copy to the bpf listener, if any.
3537 if (!(sc
->tulip_flags
& TULIP_DEVICEPROBE
))
3538 BPF_MTAP(&sc
->arpcom
.ac_if
, m
);
3541 * The descriptors have been filled in. Now get ready
3544 KASSERT(eop
->di_mbuf
== NULL
, ("clobbering earlier tx mbuf"));
3546 TULIP_TXMAP_PRESYNC(ri
, ri
->ri_nextout
);
3550 * Make sure the next descriptor after this packet is owned
3551 * by us since it may have been set up above if we ran out
3552 * of room in the ring.
3554 DESC_STATUS(nextout
) = 0;
3555 TULIP_TXDESC_PRESYNC(ri
);
3558 * Mark the last and first segments, indicate we want a transmit
3559 * complete interrupt, and tell it to transmit!
3561 DESC_FLAG(eop
) |= TULIP_DFLAG_TxLASTSEG
|TULIP_DFLAG_TxWANTINTR
;
3564 * Note that ri->ri_nextout is still the start of the packet
3565 * and until we set the OWNER bit, we can still back out of
3566 * everything we have done.
3568 DESC_FLAG(ri
->ri_nextout
) |= TULIP_DFLAG_TxFIRSTSEG
;
3569 TULIP_TXDESC_PRESYNC(ri
);
3570 DESC_STATUS(ri
->ri_nextout
) = TULIP_DSTS_OWNER
;
3571 TULIP_TXDESC_PRESYNC(ri
);
3574 * This advances the ring for us.
3576 ri
->ri_nextout
= nextout
;
3579 if (sc
->tulip_flags
& TULIP_TXPROBE_ACTIVE
) {
3580 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
3581 ifq_set_oactive(&sc
->arpcom
.ac_if
.if_snd
);
3586 * switch back to the single queueing ifstart.
3588 sc
->tulip_flags
&= ~TULIP_WANTTXSTART
;
3589 if (sc
->tulip_txtimer
== 0)
3590 sc
->tulip_txtimer
= TULIP_TXTIMER
;
3593 * If we want a txstart, there must be not enough space in the
3594 * transmit ring. So we want to enable transmit done interrupts
3595 * so we can immediately reclaim some space. When the transmit
3596 * interrupt is posted, the interrupt handler will call tx_intr
3597 * to reclaim space and then txstart (since WANTTXSTART is set).
3598 * txstart will move the packet into the transmit ring and clear
3599 * WANTTXSTART thereby causing TXINTR to be cleared.
3602 if (sc
->tulip_flags
& (TULIP_WANTTXSTART
|TULIP_DOINGSETUP
)) {
3603 ifq_set_oactive(&sc
->arpcom
.ac_if
.if_snd
);
3604 if ((sc
->tulip_intrmask
& TULIP_STS_TXINTR
) == 0) {
3605 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
3606 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3608 } else if ((sc
->tulip_flags
& TULIP_PROMISC
) == 0) {
3609 if (sc
->tulip_intrmask
& TULIP_STS_TXINTR
) {
3610 sc
->tulip_intrmask
&= ~TULIP_STS_TXINTR
;
3611 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3614 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
3619 tulip_txput_setup(tulip_softc_t
*sc
)
3621 tulip_ringinfo_t
*ri
= &sc
->tulip_txinfo
;
3622 tulip_desc_t
*nextout
;
3625 * We will transmit, at most, one setup packet per call to ifstart.
3629 * Try to reclaim some free descriptors..
3631 if (ri
->ri_free
< 2)
3633 if ((sc
->tulip_flags
& TULIP_DOINGSETUP
) || ri
->ri_free
== 1) {
3634 sc
->tulip_flags
|= TULIP_WANTTXSTART
;
3637 bcopy(sc
->tulip_setupdata
, sc
->tulip_setupbuf
,
3638 sizeof(sc
->tulip_setupdata
));
3640 * Clear WANTSETUP and set DOINGSETUP. Since we know that WANTSETUP is
3641 * set and DOINGSETUP is clear doing an XOR of the two will DTRT.
3643 sc
->tulip_flags
^= TULIP_WANTSETUP
|TULIP_DOINGSETUP
;
3645 nextout
= ri
->ri_nextout
->di_desc
;
3646 nextout
->d_flag
&= TULIP_DFLAG_ENDRING
|TULIP_DFLAG_CHAIN
;
3647 nextout
->d_flag
|= TULIP_DFLAG_TxFIRSTSEG
|TULIP_DFLAG_TxLASTSEG
3648 |TULIP_DFLAG_TxSETUPPKT
|TULIP_DFLAG_TxWANTINTR
;
3649 if (sc
->tulip_flags
& TULIP_WANTHASHPERFECT
)
3650 nextout
->d_flag
|= TULIP_DFLAG_TxHASHFILT
;
3651 else if (sc
->tulip_flags
& TULIP_WANTHASHONLY
)
3652 nextout
->d_flag
|= TULIP_DFLAG_TxHASHFILT
|TULIP_DFLAG_TxINVRSFILT
;
3654 nextout
->d_length2
= 0;
3655 nextout
->d_addr2
= 0;
3656 nextout
->d_length1
= sizeof(sc
->tulip_setupdata
);
3657 nextout
->d_addr1
= sc
->tulip_setup_dma_addr
& 0xffffffff;
3658 bus_dmamap_sync(sc
->tulip_setup_tag
, sc
->tulip_setup_map
,
3659 BUS_DMASYNC_PREREAD
|BUS_DMASYNC_PREWRITE
);
3660 TULIP_TXDESC_PRESYNC(ri
);
3663 * Advance the ring for the next transmit packet.
3665 if (++ri
->ri_nextout
== ri
->ri_last
)
3666 ri
->ri_nextout
= ri
->ri_first
;
3669 * Make sure the next descriptor is owned by us since it
3670 * may have been set up above if we ran out of room in the
3673 DESC_STATUS(ri
->ri_nextout
) = 0;
3674 TULIP_TXDESC_PRESYNC(ri
);
3675 nextout
->d_status
= TULIP_DSTS_OWNER
;
3677 * Flush the ownwership of the current descriptor
3679 TULIP_TXDESC_PRESYNC(ri
);
3680 TULIP_CSR_WRITE(sc
, csr_txpoll
, 1);
3681 if ((sc
->tulip_intrmask
& TULIP_STS_TXINTR
) == 0) {
3682 sc
->tulip_intrmask
|= TULIP_STS_TXINTR
;
3683 TULIP_CSR_WRITE(sc
, csr_intr
, sc
->tulip_intrmask
);
3688 tulip_ifioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
, struct ucred
* cr
)
3690 tulip_softc_t
*sc
= (tulip_softc_t
*)ifp
->if_softc
;
3691 struct ifreq
*ifr
= (struct ifreq
*)data
;
3696 bcopy((caddr_t
) sc
->arpcom
.ac_enaddr
,
3697 (caddr_t
) ((struct sockaddr
*)&ifr
->ifr_data
)->sa_data
,
3702 case SIOCSIFFLAGS
: {
3703 tulip_addr_filter(sc
); /* reinit multicast filter */
3709 case SIOCGIFMEDIA
: {
3710 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->tulip_ifmedia
, cmd
);
3715 case SIOCDELMULTI
: {
3717 * Update multicast listeners
3719 tulip_addr_filter(sc
); /* reset multicast filtering */
3727 * Set the interface MTU.
3729 if (ifr
->ifr_mtu
> ETHERMTU
3734 ifp
->if_mtu
= ifr
->ifr_mtu
;
3738 case SIOCGADDRROM
: {
3739 error
= copyout(sc
->tulip_rombuf
, ifr
->ifr_data
, sizeof(sc
->tulip_rombuf
));
3745 ifr
->ifr_metric
= (int) sc
->tulip_chipid
;
3750 error
= ether_ioctl(ifp
, cmd
, data
);
3758 tulip_ifinit(void *xsc
)
3760 tulip_softc_t
*sc
= xsc
;
3762 tulip_addr_filter(sc
); /* reinit multicast filter */
3767 tulip_ifstart(struct ifnet
*ifp
, struct ifaltq_subque
*ifsq
)
3769 tulip_softc_t
*sc
= (tulip_softc_t
*)ifp
->if_softc
;
3771 ASSERT_ALTQ_SQ_DEFAULT(ifp
, ifsq
);
3772 if (sc
->arpcom
.ac_if
.if_flags
& IFF_RUNNING
) {
3774 if ((sc
->tulip_flags
& (TULIP_WANTSETUP
|TULIP_TXPROBE_ACTIVE
)) == TULIP_WANTSETUP
)
3775 tulip_txput_setup(sc
);
3777 while (!ifq_is_empty(&sc
->arpcom
.ac_if
.if_snd
)) {
3780 m
= ifq_dequeue(&sc
->arpcom
.ac_if
.if_snd
);
3784 if ((m
= tulip_txput(sc
, m
)) != NULL
) {
3785 ifq_prepend(&sc
->arpcom
.ac_if
.if_snd
, m
);
3793 tulip_ifwatchdog(struct ifnet
*ifp
)
3795 tulip_softc_t
* const sc
= (tulip_softc_t
*)ifp
->if_softc
;
3797 sc
->arpcom
.ac_if
.if_timer
= 1;
3799 * These should be rare so do a bulk test up front so we can just skip
3802 if (sc
->tulip_flags
& (TULIP_SYSTEMERROR
|TULIP_RXBUFSLOW
|TULIP_NOMESSAGES
)) {
3804 * If the number of receive buffer is low, try to refill
3806 if (sc
->tulip_flags
& TULIP_RXBUFSLOW
)
3809 if (sc
->tulip_flags
& TULIP_SYSTEMERROR
) {
3810 if_printf(ifp
, "%d system errors: last was %s\n",
3811 sc
->tulip_system_errors
,
3812 tulip_system_errors
[sc
->tulip_last_system_error
]);
3814 if (sc
->tulip_statusbits
) {
3815 tulip_print_abnormal_interrupt(sc
, sc
->tulip_statusbits
);
3816 sc
->tulip_statusbits
= 0;
3819 sc
->tulip_flags
&= ~(TULIP_NOMESSAGES
|TULIP_SYSTEMERROR
);
3822 if (sc
->tulip_txtimer
)
3824 if (sc
->tulip_txtimer
&& --sc
->tulip_txtimer
== 0) {
3825 if_printf(ifp
, "transmission timeout\n");
3826 if (TULIP_DO_AUTOSENSE(sc
)) {
3827 sc
->tulip_media
= TULIP_MEDIA_UNKNOWN
;
3828 sc
->tulip_probe_state
= TULIP_PROBE_INACTIVE
;
3829 sc
->tulip_flags
&= ~(TULIP_WANTRXACT
|TULIP_LINKUP
);
3837 tulip_attach(tulip_softc_t
*sc
)
3839 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
3841 ifp
->if_flags
= IFF_BROADCAST
|IFF_SIMPLEX
|IFF_MULTICAST
;
3842 ifp
->if_init
= tulip_ifinit
;
3843 ifp
->if_ioctl
= tulip_ifioctl
;
3844 ifp
->if_start
= tulip_ifstart
;
3845 ifp
->if_watchdog
= tulip_ifwatchdog
;
3848 if_printf(ifp
, "%s%s pass %d.%d%s\n",
3850 tulip_chipdescs
[sc
->tulip_chipid
],
3851 (sc
->tulip_revinfo
& 0xF0) >> 4,
3852 sc
->tulip_revinfo
& 0x0F,
3853 (sc
->tulip_features
& (TULIP_HAVE_ISVSROM
|TULIP_HAVE_OKSROM
))
3854 == TULIP_HAVE_ISVSROM
? " (invalid EESPROM checksum)" : "");
3856 (*sc
->tulip_boardsw
->bd_media_probe
)(sc
);
3857 ifmedia_init(&sc
->tulip_ifmedia
, 0,
3858 tulip_ifmedia_change
,
3859 tulip_ifmedia_status
);
3860 sc
->tulip_flags
&= ~TULIP_DEVICEPROBE
;
3861 tulip_ifmedia_add(sc
);
3863 ifq_set_maxlen(&ifp
->if_snd
, ifqmaxlen
);
3864 ether_ifattach(&sc
->arpcom
.ac_if
, sc
->arpcom
.ac_enaddr
, NULL
);
3869 /* Release memory for a single descriptor ring. */
3871 tulip_busdma_freering(tulip_ringinfo_t
*ri
)
3875 /* Release the DMA maps and tag for data buffers. */
3876 if (ri
->ri_data_maps
!= NULL
) {
3877 for (i
= 0; i
< ri
->ri_max
; i
++) {
3878 if (ri
->ri_data_maps
[i
] != NULL
) {
3879 bus_dmamap_destroy(ri
->ri_data_tag
, ri
->ri_data_maps
[i
]);
3880 ri
->ri_data_maps
[i
] = NULL
;
3883 kfree(ri
->ri_data_maps
, M_DEVBUF
);
3884 ri
->ri_data_maps
= NULL
;
3886 if (ri
->ri_data_tag
!= NULL
) {
3887 bus_dma_tag_destroy(ri
->ri_data_tag
);
3888 ri
->ri_data_tag
= NULL
;
3891 /* Release the DMA memory and tag for the ring descriptors. */
3892 if (ri
->ri_dma_addr
!= 0) {
3893 bus_dmamap_unload(ri
->ri_ring_tag
, ri
->ri_ring_map
);
3894 ri
->ri_dma_addr
= 0;
3896 if (ri
->ri_descs
!= NULL
) {
3897 bus_dmamem_free(ri
->ri_ring_tag
, ri
->ri_descs
, ri
->ri_ring_map
);
3898 ri
->ri_descs
= NULL
;
3900 if (ri
->ri_ring_tag
!= NULL
) {
3901 bus_dma_tag_destroy(ri
->ri_ring_tag
);
3902 ri
->ri_ring_tag
= NULL
;
3906 /* Allocate memory for a single descriptor ring. */
3908 tulip_busdma_allocring(device_t dev
, tulip_softc_t
*sc
, size_t count
,
3909 bus_size_t align
, int nsegs
, tulip_ringinfo_t
*ri
, const char *name
)
3914 /* First, setup a tag. */
3916 size
= count
* sizeof(tulip_desc_t
);
3917 error
= bus_dma_tag_create(bus_get_dma_tag(dev
),
3918 32, 0, BUS_SPACE_MAXADDR_32BIT
,
3919 BUS_SPACE_MAXADDR
, size
, 1, size
, 0, &ri
->ri_ring_tag
);
3921 device_printf(dev
, "failed to allocate %s descriptor ring dma tag\n",
3926 /* Next, allocate memory for the descriptors. */
3927 error
= bus_dmamem_alloc(ri
->ri_ring_tag
, (void **)&ri
->ri_descs
,
3928 BUS_DMA_NOWAIT
| BUS_DMA_ZERO
, &ri
->ri_ring_map
);
3930 device_printf(dev
, "failed to allocate memory for %s descriptor ring\n",
3935 /* Map the descriptors. */
3936 error
= bus_dmamap_load(ri
->ri_ring_tag
, ri
->ri_ring_map
, ri
->ri_descs
,
3937 size
, tulip_dma_map_addr
, &ri
->ri_dma_addr
, BUS_DMA_NOWAIT
);
3939 device_printf(dev
, "failed to get dma address for %s descriptor ring\n",
3944 /* Allocate a tag for the data buffers. */
3945 error
= bus_dma_tag_create(bus_get_dma_tag(dev
), align
, 0,
3946 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
,
3947 MCLBYTES
* nsegs
, nsegs
, MCLBYTES
, 0, &ri
->ri_data_tag
);
3949 device_printf(dev
, "failed to allocate %s buffer dma tag\n", name
);
3953 /* Allocate maps for the data buffers. */
3954 ri
->ri_data_maps
= kmalloc(sizeof(bus_dmamap_t
) * count
, M_DEVBUF
,
3956 for (i
= 0; i
< count
; i
++) {
3957 error
= bus_dmamap_create(ri
->ri_data_tag
, 0, &ri
->ri_data_maps
[i
]);
3959 device_printf(dev
, "failed to create map for %s buffer %d\n",
3968 /* Release busdma maps, tags, and memory. */
3970 tulip_busdma_cleanup(tulip_softc_t
*sc
)
3973 /* Release resources for the setup descriptor. */
3974 if (sc
->tulip_setup_dma_addr
!= 0) {
3975 bus_dmamap_unload(sc
->tulip_setup_tag
, sc
->tulip_setup_map
);
3976 sc
->tulip_setup_dma_addr
= 0;
3978 if (sc
->tulip_setupbuf
!= NULL
) {
3979 bus_dmamem_free(sc
->tulip_setup_tag
, sc
->tulip_setupbuf
,
3980 sc
->tulip_setup_map
);
3981 sc
->tulip_setupbuf
= NULL
;
3983 if (sc
->tulip_setup_tag
!= NULL
) {
3984 bus_dma_tag_destroy(sc
->tulip_setup_tag
);
3985 sc
->tulip_setup_tag
= NULL
;
3988 /* Release the transmit ring. */
3989 tulip_busdma_freering(&sc
->tulip_txinfo
);
3991 /* Release the receive ring. */
3992 tulip_busdma_freering(&sc
->tulip_rxinfo
);
3996 tulip_busdma_init(device_t dev
, tulip_softc_t
*sc
)
4001 * Allocate space and dmamap for transmit ring.
4003 error
= tulip_busdma_allocring(dev
, sc
, TULIP_TXDESCS
, 1, TULIP_MAX_TXSEG
,
4004 &sc
->tulip_txinfo
, "transmit");
4009 * Allocate space and dmamap for receive ring. We tell bus_dma that
4010 * we can map MCLBYTES so that it will accept a full MCLBYTES cluster,
4011 * but we will only map the first TULIP_RX_BUFLEN bytes. This is not
4012 * a waste in practice though as an ethernet frame can easily fit
4013 * in TULIP_RX_BUFLEN bytes.
4015 error
= tulip_busdma_allocring(dev
, sc
, TULIP_RXDESCS
, 4, 1,
4016 &sc
->tulip_rxinfo
, "receive");
4021 * Allocate a DMA tag, memory, and map for setup descriptor
4023 error
= bus_dma_tag_create(bus_get_dma_tag(dev
), 32, 0,
4024 BUS_SPACE_MAXADDR_32BIT
, BUS_SPACE_MAXADDR
,
4025 sizeof(sc
->tulip_setupdata
), 1, sizeof(sc
->tulip_setupdata
), 0,
4026 &sc
->tulip_setup_tag
);
4028 device_printf(dev
, "failed to allocate setup descriptor dma tag\n");
4031 error
= bus_dmamem_alloc(sc
->tulip_setup_tag
, (void **)&sc
->tulip_setupbuf
,
4032 BUS_DMA_NOWAIT
| BUS_DMA_ZERO
, &sc
->tulip_setup_map
);
4034 device_printf(dev
, "failed to allocate memory for setup descriptor\n");
4037 error
= bus_dmamap_load(sc
->tulip_setup_tag
, sc
->tulip_setup_map
,
4038 sc
->tulip_setupbuf
, sizeof(sc
->tulip_setupdata
),
4039 tulip_dma_map_addr
, &sc
->tulip_setup_dma_addr
, BUS_DMA_NOWAIT
);
4041 device_printf(dev
, "failed to get dma address for setup descriptor\n");
4049 tulip_initcsrs(tulip_softc_t
*sc
, tulip_csrptr_t csr_base
, size_t csr_size
)
4051 sc
->tulip_csrs
.csr_busmode
= csr_base
+ 0 * csr_size
;
4052 sc
->tulip_csrs
.csr_txpoll
= csr_base
+ 1 * csr_size
;
4053 sc
->tulip_csrs
.csr_rxpoll
= csr_base
+ 2 * csr_size
;
4054 sc
->tulip_csrs
.csr_rxlist
= csr_base
+ 3 * csr_size
;
4055 sc
->tulip_csrs
.csr_txlist
= csr_base
+ 4 * csr_size
;
4056 sc
->tulip_csrs
.csr_status
= csr_base
+ 5 * csr_size
;
4057 sc
->tulip_csrs
.csr_command
= csr_base
+ 6 * csr_size
;
4058 sc
->tulip_csrs
.csr_intr
= csr_base
+ 7 * csr_size
;
4059 sc
->tulip_csrs
.csr_missed_frames
= csr_base
+ 8 * csr_size
;
4060 sc
->tulip_csrs
.csr_9
= csr_base
+ 9 * csr_size
;
4061 sc
->tulip_csrs
.csr_10
= csr_base
+ 10 * csr_size
;
4062 sc
->tulip_csrs
.csr_11
= csr_base
+ 11 * csr_size
;
4063 sc
->tulip_csrs
.csr_12
= csr_base
+ 12 * csr_size
;
4064 sc
->tulip_csrs
.csr_13
= csr_base
+ 13 * csr_size
;
4065 sc
->tulip_csrs
.csr_14
= csr_base
+ 14 * csr_size
;
4066 sc
->tulip_csrs
.csr_15
= csr_base
+ 15 * csr_size
;
4070 tulip_initring(tulip_ringinfo_t
*ri
, int ndescs
)
4074 ri
->ri_descinfo
= kmalloc(sizeof(tulip_descinfo_t
) * ndescs
, M_DEVBUF
,
4076 for (i
= 0; i
< ndescs
; i
++) {
4077 ri
->ri_descinfo
[i
].di_desc
= &ri
->ri_descs
[i
];
4078 ri
->ri_descinfo
[i
].di_map
= &ri
->ri_data_maps
[i
];
4080 ri
->ri_first
= ri
->ri_descinfo
;
4081 ri
->ri_max
= ndescs
;
4082 ri
->ri_last
= ri
->ri_first
+ ri
->ri_max
;
4083 bzero(ri
->ri_descs
, sizeof(tulip_desc_t
) * ri
->ri_max
);
4084 DESC_FLAG(&ri
->ri_last
[-1]) = TULIP_DFLAG_ENDRING
;
4089 * This is the PCI configuration support.
4092 #define PCI_CBIO PCIR_BAR(0) /* Configuration Base IO Address */
4093 #define PCI_CBMA PCIR_BAR(1) /* Configuration Base Memory Address */
4094 #define PCI_CFDA 0x40 /* Configuration Driver Area */
4097 tulip_pci_probe(device_t dev
)
4099 const char *name
= NULL
;
4101 if (pci_get_vendor(dev
) != DEC_VENDORID
)
4105 * Some LanMedia WAN cards use the Tulip chip, but they have
4106 * their own driver, and we should not recognize them
4108 if (pci_get_subvendor(dev
) == 0x1376)
4111 switch (pci_get_device(dev
)) {
4113 name
= "Digital 21040 Ethernet";
4116 name
= "Digital 21041 Ethernet";
4119 if (pci_get_revid(dev
) >= 0x20)
4120 name
= "Digital 21140A Fast Ethernet";
4122 name
= "Digital 21140 Fast Ethernet";
4125 if (pci_get_revid(dev
) >= 0x20)
4126 name
= "Digital 21143 Fast Ethernet";
4128 name
= "Digital 21142 Fast Ethernet";
4132 device_set_desc(dev
, name
);
4139 tulip_shutdown(device_t dev
)
4141 tulip_softc_t
*sc
= device_get_softc(dev
);
4143 lwkt_serialize_enter(sc
->arpcom
.ac_if
.if_serializer
);
4144 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
4145 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at
4146 33MHz that comes to two microseconds but wait a
4147 bit longer anyways) */
4148 lwkt_serialize_exit(sc
->arpcom
.ac_if
.if_serializer
);
4153 tulip_pci_attach(device_t dev
)
4157 uint32_t revinfo
, cfdainfo
;
4158 u_int csroffset
= TULIP_PCI_CSROFFSET
;
4159 u_int csrsize
= TULIP_PCI_CSRSIZE
;
4160 tulip_csrptr_t csr_base
;
4161 tulip_chipid_t chipid
= TULIP_CHIPID_UNKNOWN
;
4162 struct resource
*res
;
4165 unit
= device_get_unit(dev
);
4167 if (unit
>= TULIP_MAX_DEVICES
) {
4168 device_printf(dev
, "not configured; limit of %d reached or exceeded\n",
4173 revinfo
= pci_get_revid(dev
);
4174 cfdainfo
= pci_read_config(dev
, PCI_CFDA
, 4);
4176 /* turn busmaster on in case BIOS doesn't set it */
4177 pci_enable_busmaster(dev
);
4179 if (pci_get_vendor(dev
) == DEC_VENDORID
) {
4180 if (pci_get_device(dev
) == CHIPID_21040
)
4181 chipid
= TULIP_21040
;
4182 else if (pci_get_device(dev
) == CHIPID_21041
)
4183 chipid
= TULIP_21041
;
4184 else if (pci_get_device(dev
) == CHIPID_21140
)
4185 chipid
= (revinfo
>= 0x20) ? TULIP_21140A
: TULIP_21140
;
4186 else if (pci_get_device(dev
) == CHIPID_21142
)
4187 chipid
= (revinfo
>= 0x20) ? TULIP_21143
: TULIP_21142
;
4189 if (chipid
== TULIP_CHIPID_UNKNOWN
)
4192 if (chipid
== TULIP_21040
&& revinfo
< 0x20) {
4194 "not configured; 21040 pass 2.0 required (%d.%d found)\n",
4195 revinfo
>> 4, revinfo
& 0x0f);
4197 } else if (chipid
== TULIP_21140
&& revinfo
< 0x11) {
4199 "not configured; 21140 pass 1.1 required (%d.%d found)\n",
4200 revinfo
>> 4, revinfo
& 0x0f);
4204 sc
= device_get_softc(dev
);
4205 sc
->tulip_dev
= dev
;
4206 sc
->tulip_pci_busno
= pci_get_bus(dev
);
4207 sc
->tulip_pci_devno
= pci_get_slot(dev
);
4208 sc
->tulip_chipid
= chipid
;
4209 sc
->tulip_flags
|= TULIP_DEVICEPROBE
;
4210 if (chipid
== TULIP_21140
|| chipid
== TULIP_21140A
)
4211 sc
->tulip_features
|= TULIP_HAVE_GPR
|TULIP_HAVE_STOREFWD
;
4212 if (chipid
== TULIP_21140A
&& revinfo
<= 0x22)
4213 sc
->tulip_features
|= TULIP_HAVE_RXBADOVRFLW
;
4214 if (chipid
== TULIP_21140
)
4215 sc
->tulip_features
|= TULIP_HAVE_BROKEN_HASH
;
4216 if (chipid
!= TULIP_21040
&& chipid
!= TULIP_21140
)
4217 sc
->tulip_features
|= TULIP_HAVE_POWERMGMT
;
4218 if (chipid
== TULIP_21041
|| chipid
== TULIP_21142
|| chipid
== TULIP_21143
) {
4219 sc
->tulip_features
|= TULIP_HAVE_DUALSENSE
;
4220 if (chipid
!= TULIP_21041
|| revinfo
>= 0x20)
4221 sc
->tulip_features
|= TULIP_HAVE_SIANWAY
;
4222 if (chipid
!= TULIP_21041
)
4223 sc
->tulip_features
|= TULIP_HAVE_SIAGP
|TULIP_HAVE_RXBADOVRFLW
|TULIP_HAVE_STOREFWD
;
4224 if (chipid
!= TULIP_21041
&& revinfo
>= 0x20)
4225 sc
->tulip_features
|= TULIP_HAVE_SIA100
;
4228 if (sc
->tulip_features
& TULIP_HAVE_POWERMGMT
4229 && (cfdainfo
& (TULIP_CFDA_SLEEP
|TULIP_CFDA_SNOOZE
))) {
4230 cfdainfo
&= ~(TULIP_CFDA_SLEEP
|TULIP_CFDA_SNOOZE
);
4231 pci_write_config(dev
, PCI_CFDA
, cfdainfo
, 4);
4234 if_initname(&sc
->arpcom
.ac_if
, device_get_name(dev
), unit
);
4235 sc
->tulip_unit
= unit
;
4236 sc
->tulip_revinfo
= revinfo
;
4237 sc
->arpcom
.ac_if
.if_softc
= sc
;
4238 #if defined(TULIP_IOMAPPED)
4240 res
= bus_alloc_resource_any(dev
, SYS_RES_IOPORT
, &rid
, RF_ACTIVE
);
4243 res
= bus_alloc_resource_any(dev
, SYS_RES_MEMORY
, &rid
, RF_ACTIVE
);
4247 sc
->tulip_csrs_bst
= rman_get_bustag(res
);
4248 sc
->tulip_csrs_bsh
= rman_get_bushandle(res
);
4251 callout_init(&sc
->tulip_callout
);
4254 tulip_initcsrs(sc
, csr_base
+ csroffset
, csrsize
);
4256 if ((retval
= tulip_busdma_init(dev
, sc
)) != 0) {
4257 device_printf(dev
, "error initing bus_dma: %d\n", retval
);
4258 tulip_busdma_cleanup(sc
);
4262 retval
= tulip_initring(&sc
->tulip_rxinfo
, TULIP_RXDESCS
);
4264 retval
= tulip_initring(&sc
->tulip_txinfo
, TULIP_TXDESCS
);
4266 tulip_busdma_cleanup(sc
);
4271 * Make sure there won't be any interrupts or such...
4273 TULIP_CSR_WRITE(sc
, csr_busmode
, TULIP_BUSMODE_SWRESET
);
4274 DELAY(100); /* Wait 10 microseconds (actually 50 PCI cycles but at
4275 33MHz that comes to two microseconds but wait a
4276 bit longer anyways) */
4278 if ((retval
= tulip_read_macaddr(sc
)) < 0) {
4279 device_printf(dev
, "can't read ENET ROM (why=%d) (", retval
);
4280 for (idx
= 0; idx
< 32; idx
++)
4281 kprintf("%02x", sc
->tulip_rombuf
[idx
]);
4283 device_printf(dev
, "%s%s pass %d.%d\n",
4284 sc
->tulip_boardid
, tulip_chipdescs
[sc
->tulip_chipid
],
4285 (sc
->tulip_revinfo
& 0xF0) >> 4, sc
->tulip_revinfo
& 0x0F);
4286 device_printf(dev
, "address unknown\n");
4288 void (*intr_rtn
)(void *) = tulip_intr_normal
;
4290 if (sc
->tulip_features
& TULIP_HAVE_SHAREDINTR
)
4291 intr_rtn
= tulip_intr_shared
;
4295 /* Setup interrupt last. */
4296 if ((sc
->tulip_features
& TULIP_HAVE_SLAVEDINTR
) == 0) {
4300 res
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
4301 RF_SHAREABLE
| RF_ACTIVE
);
4302 if (res
== NULL
|| bus_setup_intr(dev
, res
, INTR_MPSAFE
,
4304 sc
->arpcom
.ac_if
.if_serializer
)) {
4305 device_printf(dev
, "couldn't map interrupt\n");
4306 ifmedia_removeall(&sc
->tulip_ifmedia
);
4307 ether_ifdetach(&sc
->arpcom
.ac_if
);
4308 tulip_busdma_cleanup(sc
);
4312 ifq_set_cpuid(&sc
->arpcom
.ac_if
.if_snd
, rman_get_cpuid(res
));
4318 static device_method_t tulip_pci_methods
[] = {
4319 /* Device interface */
4320 DEVMETHOD(device_probe
, tulip_pci_probe
),
4321 DEVMETHOD(device_attach
, tulip_pci_attach
),
4322 DEVMETHOD(device_shutdown
, tulip_shutdown
),
4325 static driver_t tulip_pci_driver
= {
4328 sizeof(tulip_softc_t
),
4330 static devclass_t tulip_devclass
;
4332 DECLARE_DUMMY_MODULE(if_de
);
4333 DRIVER_MODULE(if_de
, pci
, tulip_pci_driver
, tulip_devclass
, NULL
, NULL
);