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