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