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