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