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