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