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