if_de.c revision 16357
1/*- 2 * Copyright (c) 1994, 1995, 1996 Matt Thomas (matt@3am-software.com) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. The name of the author may not be used to endorse or promote products 11 * derived from this software withough specific prior written permission 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 * $Id: if_de.c,v 1.47 1996/05/21 19:05:31 wollman Exp $ 25 * 26 */ 27 28/* 29 * DEC DC21040 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 DC21040, DC21041, or DC21140 (mostly). 36 */ 37 38#include <sys/param.h> 39#include <sys/systm.h> 40#include <sys/mbuf.h> 41#include <sys/protosw.h> 42#include <sys/socket.h> 43#include <sys/ioctl.h> 44#include <sys/errno.h> 45#include <sys/malloc.h> 46#include <sys/kernel.h> 47#include <sys/proc.h> /* only for declaration of wakeup() used by vm.h */ 48#if defined(__FreeBSD__) 49#include <sys/devconf.h> 50#include <machine/clock.h> 51#elif defined(__bsdi__) || defined(__NetBSD__) 52#include <sys/device.h> 53#endif 54 55#include <net/if.h> 56#include <net/if_types.h> 57#include <net/if_dl.h> 58#include <net/route.h> 59 60#include "bpfilter.h" 61#if NBPFILTER > 0 62#include <net/bpf.h> 63#include <net/bpfdesc.h> 64#endif 65 66#ifdef INET 67#include <netinet/in.h> 68#include <netinet/in_systm.h> 69#include <netinet/in_var.h> 70#include <netinet/ip.h> 71#include <netinet/if_ether.h> 72#endif 73 74#ifdef NS 75#include <netns/ns.h> 76#include <netns/ns_if.h> 77#endif 78 79#include <vm/vm.h> 80#include <vm/vm_param.h> 81#include <vm/vm_kern.h> 82 83#if defined(__FreeBSD__) 84#include <vm/pmap.h> 85#include <pci.h> 86#if NPCI > 0 87#include <pci/pcivar.h> 88#include <pci/dc21040.h> 89#endif 90#endif /* __FreeBSD__ */ 91 92#if defined(__bsdi__) 93#include <i386/pci/pci.h> 94#include <i386/pci/ic/dc21040.h> 95#include <i386/isa/isa.h> 96#include <i386/isa/icu.h> 97#include <i386/isa/dma.h> 98#include <i386/isa/isavar.h> 99#if _BSDI_VERSION < 199510 100#include <eisa.h> 101#else 102#define NEISA 0 103#endif 104#if NEISA > 0 && _BSDI_VERSION >= 199401 105#include <i386/eisa/eisa.h> 106#define TULIP_EISA 107#endif 108#endif /* __bsdi__ */ 109 110#if defined(__NetBSD__) 111#include <machine/bus.h> 112#if defined(__alpha__) 113#include <machine/intr.h> 114#endif 115#include <dev/pci/pcireg.h> 116#include <dev/pci/pcivar.h> 117#include <dev/ic/dc21040reg.h> 118#endif /* __NetBSD__ */ 119 120/* 121 * Intel CPUs should use I/O mapped access. 122 */ 123#if defined(__i386__) || defined(TULIP_EISA) 124#define TULIP_IOMAPPED 125#endif 126 127#if 0 128/* 129 * This turns on all sort of debugging stuff and make the 130 * driver much larger. 131 */ 132#define TULIP_DEBUG 133#endif 134 135/* 136 * This module supports 137 * the DEC DC21040 PCI Ethernet Controller. 138 * the DEC DC21041 PCI Ethernet Controller. 139 * the DEC DC21140 PCI Fast Ethernet Controller. 140 */ 141 142#ifdef TULIP_IOMAPPED 143#define TULIP_EISA_CSRSIZE 16 144#define TULIP_EISA_CSROFFSET 0 145#define TULIP_PCI_CSRSIZE 8 146#define TULIP_PCI_CSROFFSET 0 147 148#if defined(__NetBSD__) 149typedef bus_io_size_t tulip_csrptr_t; 150 151#define TULIP_CSR_READ(sc, csr) \ 152 bus_io_read_4((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr) 153#define TULIP_CSR_WRITE(sc, csr, val) \ 154 bus_io_write_4((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr, (val)) 155 156#define TULIP_CSR_READBYTE(sc, csr) \ 157 bus_io_read_1((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr) 158#define TULIP_CSR_WRITEBYTE(sc, csr, val) \ 159 bus_io_write_1((sc)->tulip_bc, (sc)->tulip_ioh, (sc)->tulip_csrs.csr, (val)) 160#else 161typedef tulip_uint16_t tulip_csrptr_t; 162 163#define TULIP_CSR_READ(sc, csr) (inl((sc)->tulip_csrs.csr)) 164#define TULIP_CSR_WRITE(sc, csr, val) outl((sc)->tulip_csrs.csr, val) 165 166#define TULIP_CSR_READBYTE(sc, csr) (inb((sc)->tulip_csrs.csr)) 167#define TULIP_CSR_WRITEBYTE(sc, csr, val) outb((sc)->tulip_csrs.csr, val) 168#endif /* __NetBSD__ */ 169 170#else /* TULIP_IOMAPPED */ 171 172#define TULIP_PCI_CSRSIZE 8 173#define TULIP_PCI_CSROFFSET 0 174 175#if defined(__NetBSD__) 176typedef bus_mem_size_t tulip_csrptr_t; 177 178#define TULIP_CSR_READ(sc, csr) \ 179 bus_mem_read_4((sc)->tulip_bc, (sc)->tulip_memh, (sc)->tulip_csrs.csr) 180#define TULIP_CSR_WRITE(sc, csr, val) \ 181 bus_mem_write_4((sc)->tulip_bc, (sc)->tulip_memh, (sc)->tulip_csrs.csr, \ 182 (val)) 183#else 184typedef volatile tulip_uint32_t *tulip_csrptr_t; 185 186/* 187 * macros to read and write CSRs. Note that the "0 +" in 188 * READ_CSR is to prevent the macro from being an lvalue 189 * and WRITE_CSR shouldn't be assigned from. 190 */ 191#define TULIP_CSR_READ(sc, csr) (0 + *(sc)->tulip_csrs.csr) 192#define TULIP_CSR_WRITE(sc, csr, val) ((void)(*(sc)->tulip_csrs.csr = (val))) 193#endif /* __NetBSD__ */ 194 195#endif /* TULIP_IOMAPPED */ 196 197/* 198 * This structure contains "pointers" for the registers on 199 * the various 21x4x chips. CSR0 through CSR8 are common 200 * to all chips. After that, it gets messy... 201 */ 202typedef struct { 203 tulip_csrptr_t csr_busmode; /* CSR0 */ 204 tulip_csrptr_t csr_txpoll; /* CSR1 */ 205 tulip_csrptr_t csr_rxpoll; /* CSR2 */ 206 tulip_csrptr_t csr_rxlist; /* CSR3 */ 207 tulip_csrptr_t csr_txlist; /* CSR4 */ 208 tulip_csrptr_t csr_status; /* CSR5 */ 209 tulip_csrptr_t csr_command; /* CSR6 */ 210 tulip_csrptr_t csr_intr; /* CSR7 */ 211 tulip_csrptr_t csr_missed_frames; /* CSR8 */ 212 213 /* DC21040 specific registers */ 214 215 tulip_csrptr_t csr_enetrom; /* CSR9 */ 216 tulip_csrptr_t csr_reserved; /* CSR10 */ 217 tulip_csrptr_t csr_full_duplex; /* CSR11 */ 218 219 /* DC21040/DC21041 common registers */ 220 221 tulip_csrptr_t csr_sia_status; /* CSR12 */ 222 tulip_csrptr_t csr_sia_connectivity; /* CSR13 */ 223 tulip_csrptr_t csr_sia_tx_rx; /* CSR14 */ 224 tulip_csrptr_t csr_sia_general; /* CSR15 */ 225 226 /* DC21140/DC21041 common registers */ 227 228 tulip_csrptr_t csr_srom_mii; /* CSR9 */ 229 tulip_csrptr_t csr_gp_timer; /* CSR11 */ 230 231 /* DC21140 specific registers */ 232 233 tulip_csrptr_t csr_gp; /* CSR12 */ 234 tulip_csrptr_t csr_watchdog; /* CSR15 */ 235 236 /* DC21041 specific registers */ 237 238 tulip_csrptr_t csr_bootrom; /* CSR10 */ 239} tulip_regfile_t; 240 241/* 242 * While 21x4x allows chaining of its descriptors, this driver 243 * doesn't take advantage of it. We keep the descriptors in a 244 * traditional FIFO ring. 245 */ 246typedef struct { 247 tulip_desc_t *ri_first; /* first entry in ring */ 248 tulip_desc_t *ri_last; /* one after last entry */ 249 tulip_desc_t *ri_nextin; /* next to processed by host */ 250 tulip_desc_t *ri_nextout; /* next to processed by adapter */ 251 int ri_max; 252 int ri_free; 253} tulip_ringinfo_t; 254 255/* 256 * The DC21040 has a stupid restriction in that the receive 257 * buffers must be longword aligned. But since Ethernet 258 * headers are not a multiple of longwords in size this forces 259 * the data to non-longword aligned. Since IP requires the 260 * data to be longword aligned, we need to copy it after it has 261 * been DMA'ed in our memory. 262 * 263 * Since we have to copy it anyways, we might as well as allocate 264 * dedicated receive space for the input. This allows to use a 265 * small receive buffer size and more ring entries to be able to 266 * better keep with a flood of tiny Ethernet packets. 267 * 268 * The receive space MUST ALWAYS be a multiple of the page size. 269 * And the number of receive descriptors multiplied by the size 270 * of the receive buffers must equal the recevive space. This 271 * is so that we can manipulate the page tables so that even if a 272 * packet wraps around the end of the receive space, we can 273 * treat it as virtually contiguous. 274 * 275 * The above used to be true (the stupid restriction is still true) 276 * but we gone to directly DMA'ing into MBUFs (unless it's on an 277 * architecture which can't handle unaligned accesses) because with 278 * 100Mb/s cards the copying is just too much of a hit. 279 */ 280#if defined(__alpha__) 281#define TULIP_COPY_RXDATA 1 282#endif 283 284#define TULIP_RXDESCS 48 285#define TULIP_TXDESCS 128 286#define TULIP_RXQ_TARGET 32 287#if TULIP_RXQ_TARGET >= TULIP_RXDESCS 288#error TULIP_RXQ_TARGET must be less than TULIP_RXDESCS 289#endif 290#define TULIP_RX_BUFLEN ((MCLBYTES < 2048 ? MCLBYTES : 2048) - 16) 291 292/* 293 * Forward reference to make C happy. 294 */ 295typedef struct _tulip_softc_t tulip_softc_t; 296 297/* 298 * Some boards need to treated specially. The following enumeration 299 * identifies the cards with quirks (or those we just want to single 300 * out for special merit or scorn). 301 */ 302typedef enum { 303 TULIP_DC21040_GENERIC, /* Generic DC21040 (works with most any board) */ 304 TULIP_DC21040_ZX314_MASTER, /* ZNYX ZX314 Master 21040 (it has the interrupt line) */ 305 TULIP_DC21040_ZX314_SLAVE, /* ZNYX ZX314 Slave 21040 (its interrupt is tied to the master's */ 306 TULIP_DC21140_DEC_EB, /* Digital Semicondutor 21140 Evaluation Board */ 307 TULIP_DC21140_DEC_DE500, /* Digital DE500-?? 10/100 */ 308 TULIP_DC21140_SMC_9332, /* SMC 9332 */ 309 TULIP_DC21140_COGENT_EM100, /* Cogent EM100 100 only */ 310 TULIP_DC21140_ZNYX_ZX34X, /* ZNYX ZX342 10/100 */ 311 TULIP_DC21041_GENERIC, /* Generic DC21041 card */ 312 TULIP_DC21041_DEC_DE450 /* Digital DE450 */ 313} tulip_board_t; 314 315/* 316 * This data structure is used to abstract out the quirks. 317 * media_probe = tries to determine the media type. 318 * media_select = enables the current media (or autosenses) 319 * media_preset = 21140, etal requires bit to set before the 320 * the software reset; hence pre-set. Should be 321 * pre-reset but that's ugly. 322 * mii_probe = probe for PHY devices connected via the MII interface 323 * on 21140, etal. 324 */ 325 326typedef struct { 327 tulip_board_t bd_type; 328 const char *bd_description; 329 int (*bd_media_probe)(tulip_softc_t *sc); 330 void (*bd_media_select)(tulip_softc_t *sc); 331 void (*bd_media_preset)(tulip_softc_t *sc); 332 void (*bd_mii_probe)(tulip_softc_t *sc); 333} tulip_boardsw_t; 334 335/* 336 * The next few declarations are for MII/PHY based board. 337 * 338 * The first enumeration identifies a superset of various datums 339 * that can be obtained from various PHY chips. Not all PHYs will 340 * support all datums. 341 * The modedata structure indicates what register contains 342 * a datum, what mask is applied the register contents, and what the 343 * result should be. 344 * The attr structure records information about a supported PHY. 345 * The phy structure records information about a PHY instance. 346 */ 347 348typedef enum { 349 PHY_MODE_10T, 350 PHY_MODE_100TX, 351 PHY_MODE_100T4, 352 PHY_MODE_FULLDUPLEX, 353 PHY_MODE_MAX 354} phy_mode_t; 355 356typedef struct { 357 unsigned short pm_regno; 358 unsigned short pm_mask; 359 unsigned short pm_value; 360} phy_modedata_t; 361 362typedef struct { 363 const char *attr_name; 364 unsigned attr_id; 365 unsigned short attr_flags; 366#define PHY_NEED_HARD_RESET 0x0001 367#define PHY_DUAL_CYCLE_TA 0x0002 368 phy_modedata_t attr_modes[PHY_MODE_MAX]; 369} phy_attr_t; 370 371typedef struct _tulip_phy_t { 372 const struct _tulip_phy_t *phy_next; 373 const phy_attr_t *phy_attr; 374 unsigned phy_devaddr; 375 unsigned phy_status; 376} tulip_phy_t; 377 378/* 379 * The various controllers support. Technically the DE425 is just 380 * a 21040 on EISA. But since it remarkable difference from normal 381 * 21040s, we give it its own chip id. 382 */ 383 384typedef enum { 385 TULIP_DC21040, TULIP_DE425, 386 TULIP_DC21041, 387 TULIP_DC21140, TULIP_DC21140A, TULIP_DC21142, 388 TULIP_CHIPID_UNKNOWN 389} tulip_chipid_t; 390 391/* 392 * Various probe states used when trying to autosense the media. 393 * While we could try to autosense on the 21040, it a pain and so 394 * until someone complain we won't. However, the 21041 and MII 395 * 2114x do support autosense. 396 */ 397 398typedef enum { 399 TULIP_PROBE_INACTIVE, TULIP_PROBE_10BASET, TULIP_PROBE_AUI, 400 TULIP_PROBE_BNC, TULIP_PROBE_PHYRESET, TULIP_PROBE_PHYAUTONEG, 401 TULIP_PROBE_MEDIATEST, TULIP_PROBE_FAILED 402} tulip_probe_state_t; 403 404/* 405 * Various physical media types supported. 406 * BNCAUI is BNC or AUI since on the 21040 you can't really tell 407 * which is in use. 408 */ 409typedef enum { 410 TULIP_MEDIA_UNKNOWN, 411 TULIP_MEDIA_10BASET, 412 TULIP_MEDIA_BNC, 413 TULIP_MEDIA_AUI, 414 TULIP_MEDIA_BNCAUI, 415 TULIP_MEDIA_10BASET_FD, 416 TULIP_MEDIA_100BASETX, 417 TULIP_MEDIA_100BASETX_FD, 418 TULIP_MEDIA_100BASET4 419} tulip_media_t; 420 421typedef struct { 422 /* 423 * Transmit Statistics 424 */ 425 tulip_uint32_t dot3StatsSingleCollisionFrames; 426 tulip_uint32_t dot3StatsMultipleCollisionFrames; 427 tulip_uint32_t dot3StatsSQETestErrors; 428 tulip_uint32_t dot3StatsDeferredTransmissions; 429 tulip_uint32_t dot3StatsLateCollisions; 430 tulip_uint32_t dot3StatsExcessiveCollisions; 431 tulip_uint32_t dot3StatsInternalMacTransmitErrors; 432 tulip_uint32_t dot3StatsCarrierSenseErrors; 433 /* 434 * Receive Statistics 435 */ 436 tulip_uint32_t dot3StatsMissedFrames; /* not in rfc1650! */ 437 tulip_uint32_t dot3StatsAlignmentErrors; 438 tulip_uint32_t dot3StatsFCSErrors; 439 tulip_uint32_t dot3StatsFrameTooLongs; 440 tulip_uint32_t dot3StatsInternalMacReceiveErrors; 441} tulip_dot3_stats_t; 442 443/* 444 * Now to important stuff. This is softc structure (where does softc 445 * come from??? No idea) for the tulip device. 446 * 447 */ 448struct _tulip_softc_t { 449#if defined(__bsdi__) 450 struct device tulip_dev; /* base device */ 451 struct isadev tulip_id; /* ISA device */ 452 struct intrhand tulip_ih; /* intrrupt vectoring */ 453 struct atshutdown tulip_ats; /* shutdown hook */ 454#if _BSDI_VERSION < 199401 455 caddr_t tulip_bpf; /* for BPF */ 456#else 457 prf_t tulip_pf; /* printf function */ 458#endif 459#endif 460#if defined(__NetBSD__) 461 struct device tulip_dev; /* base device */ 462 void *tulip_ih; /* intrrupt vectoring */ 463 void *tulip_ats; /* shutdown hook */ 464 bus_chipset_tag_t tulip_bc; 465 pci_chipset_tag_t tulip_pc; 466#ifdef TULIP_IOMAPPED 467 bus_io_handle_t tulip_ioh; /* I/O region handle */ 468#else 469 bus_io_handle_t tulip_memh; /* memory region handle */ 470#endif 471#endif 472 struct arpcom tulip_ac; 473 tulip_regfile_t tulip_csrs; 474 unsigned tulip_flags; 475#define TULIP_WANTSETUP 0x00000001 476#define TULIP_WANTHASH 0x00000002 477#define TULIP_DOINGSETUP 0x00000004 478#define TULIP_ALTPHYS 0x00000008 479#define TULIP_PRINTMEDIA 0x00000010 480#define TULIP_TXPROBE_ACTIVE 0x00000020 481#define TULIP_TXPROBE_OK 0x00000040 482#define TULIP_WANTRXACT 0x00000080 483#define TULIP_RXACT 0x00000100 484#define TULIP_INRESET 0x00000200 485#define TULIP_NEEDRESET 0x00000400 486#define TULIP_SQETEST 0x00000800 487#define TULIP_ROMOK 0x00001000 488#define TULIP_SLAVEDROM 0x00002000 489#define TULIP_SLAVEDINTR 0x00004000 490#define TULIP_LINKSUSPECT 0x00008000 491#define TULIP_LINKUP 0x00010000 492#define TULIP_RXBUFSLOW 0x00020000 493#define TULIP_NOMESSAGES 0x00040000 494#define TULIP_SYSTEMERROR 0x00080000 495#define TULIP_DEVICEPROBE 0x00100000 496#define TULIP_FAKEGPTIMEOUT 0x00200000 497 unsigned char tulip_rombuf[128]; 498 tulip_uint32_t tulip_setupbuf[192/sizeof(tulip_uint32_t)]; 499 tulip_uint32_t tulip_setupdata[192/sizeof(tulip_uint32_t)]; 500 tulip_uint32_t tulip_intrmask; 501 tulip_uint32_t tulip_cmdmode; 502 tulip_uint32_t tulip_revinfo; 503 tulip_uint32_t tulip_gpticks; 504 tulip_uint32_t tulip_gpunits; 505 tulip_uint32_t tulip_last_system_error : 3; 506 tulip_uint32_t tulip_txtimer : 2; 507 tulip_uint32_t tulip_system_errors; 508 tulip_uint32_t tulip_statusbits; 509 tulip_uint32_t tulip_abilities; 510 /* tulip_uint32_t tulip_bus; XXX */ 511 tulip_media_t tulip_media; 512 tulip_probe_state_t tulip_probe_state; 513 tulip_chipid_t tulip_chipid; 514 const char *tulip_boardid; 515 char tulip_boardidbuf[16]; 516 const tulip_boardsw_t *tulip_boardsw; 517 tulip_softc_t *tulip_slaves; 518 tulip_phy_t *tulip_phys; 519#ifdef TULIP_DEBUG 520 struct { 521 tulip_uint32_t dbg_intrs; 522 tulip_uint32_t dbg_msdelay; 523 tulip_uint32_t dbg_gpticks; 524 enum { 525 TULIP_GPTMR_10MB, 526 TULIP_GPTMR_10MB_MII, 527 TULIP_GPTMR_100MB_MII 528 } dbg_gprate; 529 tulip_uint32_t dbg_gpintrs; 530 tulip_uint32_t dbg_gpintrs_hz; 531 tulip_uint32_t dbg_link_downed; 532 tulip_uint32_t dbg_link_suspected; 533 u_int16_t dbg_phyregs[32][4]; 534 tulip_uint32_t dbg_rxlowbufs; 535 tulip_uint32_t dbg_rxintrs; 536 tulip_uint32_t dbg_last_rxintrs; 537 tulip_uint32_t dbg_high_rxintrs_hz; 538 tulip_uint32_t dbg_rxpktsperintr[TULIP_RXDESCS]; 539 } tulip_dbg; 540#endif 541 struct ifqueue tulip_txq; 542 struct ifqueue tulip_rxq; 543 tulip_dot3_stats_t tulip_dot3stats; 544 tulip_ringinfo_t tulip_rxinfo; 545 tulip_ringinfo_t tulip_txinfo; 546 tulip_desc_t tulip_rxdescs[TULIP_RXDESCS]; 547 tulip_desc_t tulip_txdescs[TULIP_TXDESCS]; 548}; 549 550static const char * const tulip_chipdescs[] = { 551 "DC21040 [10Mb/s]", 552#if defined(TULIP_EISA) 553 "DE425 [10Mb/s]", 554#else 555 NULL, 556#endif 557 "DC21041 [10Mb/s]", 558 "DC21140 [10-100Mb/s]", 559 "DC21140A [10-100Mb/s]", 560 "DC21142 [10-100Mb/s]", 561}; 562 563static const char * const tulip_mediums[] = { 564 "unknown", /* TULIP_MEDIA_UNKNOWN */ 565 "10baseT", /* TULIP_MEDIA_10BASET */ 566 "BNC", /* TULIP_MEDIA_BNC */ 567 "AUI", /* TULIP_MEDIA_AUI */ 568 "BNC/AUI", /* TULIP_MEDIA_BNCAUI */ 569 "Full Duplex 10baseT", /* TULIP_MEDIA_10BASET_FD */ 570 "100baseTX", /* TULIP_MEDIA_100BASET */ 571 "Full Duplex 100baseTX", /* TULIP_MEDIA_100BASET_FD */ 572 "100baseT4", /* TULIP_MEDIA_100BASET4 */ 573}; 574 575static const tulip_media_t tulip_phy_statuses[] = { 576 TULIP_MEDIA_10BASET, TULIP_MEDIA_10BASET_FD, 577 TULIP_MEDIA_100BASETX, TULIP_MEDIA_100BASETX_FD, 578 TULIP_MEDIA_100BASET4 579}; 580 581static const char * const tulip_system_errors[] = { 582 "parity error", 583 "master abort", 584 "target abort", 585 "reserved #3", 586 "reserved #4", 587 "reserved #5", 588 "reserved #6", 589 "reserved #7", 590}; 591 592static const char * const tulip_status_bits[] = { 593 NULL, 594 "transmit process stopped", 595 NULL, 596 "transmit jabber timeout", 597 598 NULL, 599 "transmit underflow", 600 NULL, 601 "receive underflow", 602 603 "receive process stopped", 604 "receive watchdog timeout", 605 NULL, 606 NULL, 607 608 "link failure", 609 NULL, 610 NULL, 611}; 612 613#ifndef IFF_ALTPHYS 614#define IFF_ALTPHYS IFF_LINK2 /* In case it isn't defined */ 615#endif 616 617#ifndef IFF_FULLDUPLEX 618#define IFF_FULLDUPLEX IFF_LINK1 619#endif 620 621#ifndef IFF_NOAUTONEG 622#if IFF_ALTPHYS == IFF_LINK2 623#define IFF_NOAUTONEG IFF_LINK0 624#else 625#define IFF_NOAUTONEG IFF_LINK2 626#endif 627#endif 628 629#if (IFF_ALTPHYS&IFF_FULLDUPLEX&IFF_NOAUTONEG) != 0 630#error IFF_ALTPHYS, IFF_FULLDUPLEX, IFF_NOAUTONEG overlap 631#endif 632 633 634#if defined(__FreeBSD__) 635typedef void ifnet_ret_t; 636typedef int ioctl_cmd_t; 637#define TULIP_COUNTINCR 4 638tulip_softc_t **tulips; 639int tulip_count; 640#if BSD >= 199506 641#define TULIP_IFP_TO_SOFTC(ifp) ((tulip_softc_t *)((ifp)->if_softc)) 642#if NBPFILTER > 0 643#define TULIP_BPF_MTAP(sc, m) bpf_mtap(&(sc)->tulip_if, m) 644#define TULIP_BPF_TAP(sc, p, l) bpf_tap(&(sc)->tulip_if, p, l) 645#define TULIP_BPF_ATTACH(sc) bpfattach(&(sc)->tulip_if, DLT_EN10MB, sizeof(struct ether_header)) 646#endif 647#define tulip_intrfunc_t void 648#define TULIP_VOID_INTRFUNC 649#define IFF_NOTRAILERS 0 650#define CLBYTES PAGE_SIZE 651#if 0 652#define TULIP_KVATOPHYS(sc, va) kvtop(va) 653#endif 654#define TULIP_EADDR_FMT "%6D" 655#define TULIP_EADDR_ARGS(addr) addr, ":" 656#else 657extern int bootverbose; 658#define TULIP_IFP_TO_SOFTC(ifp) (TULIP_UNIT_TO_SOFTC((ifp)->if_unit)) 659#endif 660#define TULIP_UNIT_TO_SOFTC(unit) (tulips[unit]) 661#define TULIP_BURSTSIZE(unit) pci_max_burst_len 662#define loudprintf if (bootverbose) printf 663#endif 664 665#if defined(__bsdi__) 666typedef int ifnet_ret_t; 667typedef int ioctl_cmd_t; 668extern struct cfdriver decd; 669#define TULIP_UNIT_TO_SOFTC(unit) ((tulip_softc_t *) decd.cd_devs[unit]) 670#define TULIP_IFP_TO_SOFTC(ifp) (TULIP_UNIT_TO_SOFTC((ifp)->if_unit)) 671#if _BSDI_VERSION >= 199510 672#if 0 673#define TULIP_BURSTSIZE(unit) log2_burst_size 674#endif 675#define loudprintf aprint_verbose 676#define printf (*sc->tulip_pf) 677#elif _BSDI_VERSION <= 199401 678#define DRQNONE 0 679#define loudprintf printf 680static void 681arp_ifinit( 682 struct arpcom *ac, 683 struct ifaddr *ifa) 684{ 685 ac->ac_ipaddr = IA_SIN(ifa)->sin_addr; 686 arpwhohas(ac, &ac->ac_ipaddr); 687} 688#endif 689#endif /* __bsdi__ */ 690 691#if defined(__NetBSD__) 692typedef void ifnet_ret_t; 693typedef u_long ioctl_cmd_t; 694extern struct cfattach de_ca; 695extern struct cfdriver de_cd; 696#define TULIP_UNIT_TO_SOFTC(unit) ((tulip_softc_t *) de_cd.cd_devs[unit]) 697#define TULIP_IFP_TO_SOFTC(ifp) ((tulip_softc_t *)((ifp)->if_softc)) 698#define tulip_xname tulip_ac.ac_if.if_xname 699#define tulip_unit tulip_dev.dv_unit 700#define loudprintf printf 701#define TULIP_PRINTF_FMT "%s" 702#define TULIP_PRINTF_ARGS sc->tulip_xname 703#if defined(__alpha__) 704/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ 705#define TULIP_KVATOPHYS(va) (vtophys(va) | 0x40000000) 706#endif 707#endif /* __NetBSD__ */ 708 709#ifndef TULIP_PRINTF_FMT 710#define TULIP_PRINTF_FMT "%s%d" 711#endif 712#ifndef TULIP_PRINTF_ARGS 713#define TULIP_PRINTF_ARGS sc->tulip_name, sc->tulip_unit 714#endif 715 716#ifndef TULIP_BURSTSIZE 717#define TULIP_BURSTSIZE(unit) 3 718#endif 719 720#define tulip_if tulip_ac.ac_if 721#ifndef tulip_unit 722#define tulip_unit tulip_ac.ac_if.if_unit 723#endif 724#define tulip_name tulip_ac.ac_if.if_name 725#define tulip_hwaddr tulip_ac.ac_enaddr 726 727#if !defined(tulip_bpf) && (!defined(__bsdi__) || _BSDI_VERSION >= 199401) 728#define tulip_bpf tulip_ac.ac_if.if_bpf 729#endif 730 731#if !defined(tulip_intrfunc_t) 732#define tulip_intrfunc_t int 733#endif 734 735#if !defined(TULIP_KVATOPHYS) 736#define TULIP_KVATOPHYS(sc, va) vtophys(va) 737#endif 738 739/* 740 * While I think FreeBSD's 2.2 change to the bpf is a nice simplification, 741 * it does add yet more conditional code to this driver. Sigh. 742 */ 743#if !defined(TULIP_BPF_MTAP) && NBPFILTER > 0 744#define TULIP_BPF_MTAP(sc, m) bpf_mtap((sc)->tulip_bpf, m) 745#define TULIP_BPF_TAP(sc, p, l) bpf_tap((sc)->tulip_bpf, p, l) 746#define TULIP_BPF_ATTACH(sc) bpfattach(&(sc)->tulip_bpf, &(sc)->tulip_if, DLT_EN10MB, sizeof(struct ether_header)) 747#endif 748 749/* 750 * However, this change to FreeBSD I am much less enamored with. 751 */ 752#if !defined(TULIP_EADDR_FMT) 753#define TULIP_EADDR_FMT "%s" 754#define TULIP_EADDR_ARGS(addr) ether_sprintf(addr) 755#endif 756 757#define TULIP_CRC32_POLY 0xEDB88320UL /* CRC-32 Poly -- Little Endian */ 758#define TULIP_MAX_TXSEG 30 759 760#define TULIP_ADDREQUAL(a1, a2) \ 761 (((u_int16_t *)a1)[0] == ((u_int16_t *)a2)[0] \ 762 && ((u_int16_t *)a1)[1] == ((u_int16_t *)a2)[1] \ 763 && ((u_int16_t *)a1)[2] == ((u_int16_t *)a2)[2]) 764#define TULIP_ADDRBRDCST(a1) \ 765 (((u_int16_t *)a1)[0] == 0xFFFFU \ 766 && ((u_int16_t *)a1)[1] == 0xFFFFU \ 767 && ((u_int16_t *)a1)[2] == 0xFFFFU) 768 769static tulip_intrfunc_t tulip_intr(void *arg); 770static void tulip_reset(tulip_softc_t * const sc); 771static ifnet_ret_t tulip_ifstart(struct ifnet *ifp); 772static void tulip_rx_intr(tulip_softc_t * const sc); 773static void tulip_addr_filter(tulip_softc_t * const sc); 774static unsigned tulip_mii_readreg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno); 775static void tulip_mii_writereg(tulip_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data); 776 777static int 778tulip_dc21040_media_probe( 779 tulip_softc_t * const sc) 780{ 781 int cnt; 782 783 TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0); 784 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET); 785 for (cnt = 0; cnt < 2400; cnt++) { 786 if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) == 0) 787 break; 788 DELAY(1000); 789 } 790 sc->tulip_if.if_baudrate = 10000000; 791 return (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) != 0; 792} 793 794static void 795tulip_dc21040_media_select( 796 tulip_softc_t * const sc) 797{ 798 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160 799 |TULIP_CMD_BACKOFFCTR; 800 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 801 sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP; 802 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 803 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI); 804 sc->tulip_media = TULIP_MEDIA_BNCAUI; 805 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 806 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 807 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 808 } else { 809 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) { 810 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 811 sc->tulip_media = TULIP_MEDIA_10BASET_FD; 812 sc->tulip_flags &= ~TULIP_SQETEST; 813 } else { 814 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 815 sc->tulip_media = TULIP_MEDIA_10BASET; 816 } 817 if (sc->tulip_flags & TULIP_ALTPHYS) 818 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 819 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET); 820 } 821} 822 823static int 824tulip_dc21040_10baset_only_media_probe( 825 tulip_softc_t * const sc) 826{ 827 TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0); 828 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET); 829 sc->tulip_if.if_baudrate = 10000000; 830 return 0; 831} 832 833static void 834tulip_dc21040_10baset_only_media_select( 835 tulip_softc_t * const sc) 836{ 837 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160 838 |TULIP_CMD_BACKOFFCTR; 839 sc->tulip_flags |= TULIP_LINKUP; 840 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 841 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_10BASET); 842 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) { 843 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 844 sc->tulip_media = TULIP_MEDIA_10BASET_FD; 845 sc->tulip_flags &= ~TULIP_SQETEST; 846 } else { 847 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 848 sc->tulip_media = TULIP_MEDIA_10BASET; 849 sc->tulip_flags |= TULIP_SQETEST; 850 } 851 if (sc->tulip_flags & TULIP_ALTPHYS) 852 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 853 sc->tulip_flags &= ~TULIP_ALTPHYS; 854} 855 856static int 857tulip_dc21040_auibnc_only_media_probe( 858 tulip_softc_t * const sc) 859{ 860 TULIP_CSR_WRITE(sc, csr_sia_connectivity, 0); 861 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI); 862 sc->tulip_if.if_baudrate = 10000000; 863 sc->tulip_flags |= TULIP_SQETEST|TULIP_LINKUP; 864 return 0; 865} 866 867static void 868tulip_dc21040_auibnc_only_media_select( 869 tulip_softc_t * const sc) 870{ 871 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_THRSHLD160 872 |TULIP_CMD_BACKOFFCTR; 873 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 874 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_AUI); 875 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) 876 sc->tulip_if.if_flags &= ~IFF_FULLDUPLEX; 877 sc->tulip_media = TULIP_MEDIA_BNCAUI; 878 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 879 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 880 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 881 sc->tulip_flags &= ~TULIP_ALTPHYS; 882} 883 884static const tulip_boardsw_t tulip_dc21040_boardsw = { 885 TULIP_DC21040_GENERIC, 886 "", 887 tulip_dc21040_media_probe, 888 tulip_dc21040_media_select, 889 NULL, 890 NULL 891}; 892 893static const tulip_boardsw_t tulip_dc21040_10baset_only_boardsw = { 894 TULIP_DC21040_GENERIC, 895 "", 896 tulip_dc21040_10baset_only_media_probe, 897 tulip_dc21040_10baset_only_media_select, 898 NULL, 899 NULL 900}; 901 902static const tulip_boardsw_t tulip_dc21040_auibnc_only_boardsw = { 903 TULIP_DC21040_GENERIC, 904 "", 905 tulip_dc21040_auibnc_only_media_probe, 906 tulip_dc21040_auibnc_only_media_select, 907 NULL, 908 NULL 909}; 910 911static const tulip_boardsw_t tulip_dc21040_zx314_master_boardsw = { 912 TULIP_DC21040_ZX314_MASTER, 913 "ZNYX ZX314 ", 914 tulip_dc21040_10baset_only_media_probe, 915 tulip_dc21040_10baset_only_media_select 916}; 917 918static const tulip_boardsw_t tulip_dc21040_zx314_slave_boardsw = { 919 TULIP_DC21040_ZX314_SLAVE, 920 "ZNYX ZX314 ", 921 tulip_dc21040_10baset_only_media_probe, 922 tulip_dc21040_10baset_only_media_select 923}; 924 925static const phy_attr_t tulip_phy_attrlist[] = { 926 { "NS DP83840", 0x20005c00, 0, /* 08-00-17 */ 927 { 928 { 0x19, 0x40, 0x40 }, /* 10TX */ 929 { 0x19, 0x40, 0x00 }, /* 100TX */ 930 } 931 }, 932 { "Seeq 80C240", 0x0281F400, 0, /* 00-A0-7D */ 933 { 934 { 0x12, 0x10, 0x00 }, /* 10T */ 935 { }, /* 100TX */ 936 { 0x12, 0x10, 0x10 }, /* 100T4 */ 937 { 0x12, 0x08, 0x08 }, /* FULL_DUPLEX */ 938 } 939 }, 940 { NULL } 941}; 942 943static void 944tulip_dc21140_mii_probe( 945 tulip_softc_t * const sc) 946{ 947 unsigned devaddr; 948 949 for (devaddr = 31; devaddr > 0; devaddr--) { 950 unsigned status = tulip_mii_readreg(sc, devaddr, PHYREG_STATUS); 951 unsigned media; 952 unsigned id; 953 const phy_attr_t *attr; 954 tulip_phy_t *phy; 955 const char *sep; 956 if (status == 0 || status == 0xFFFF || status < PHYSTS_10BASET) 957 continue; 958 if ((status & PHYSTS_EXTENDED_REGS) == 0) { 959 loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (no extended register set)\n", 960 TULIP_PRINTF_ARGS, devaddr); 961 continue; 962 } 963 id = (tulip_mii_readreg(sc, devaddr, PHYREG_IDLOW) << 16) | 964 tulip_mii_readreg(sc, devaddr, PHYREG_IDHIGH); 965 for (attr = tulip_phy_attrlist; attr->attr_name != NULL; attr++) { 966 if ((id & ~0x0F) == attr->attr_id) 967 break; 968 } 969 if (attr->attr_name == NULL) { 970 loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (unrecogized id 0x%08x)\n", 971 TULIP_PRINTF_ARGS, devaddr, id & ~0x0F); 972 continue; 973 } 974 975 MALLOC(phy, tulip_phy_t *, sizeof(tulip_phy_t), M_DEVBUF, M_NOWAIT); 976 if (phy == NULL) { 977 loudprintf(TULIP_PRINTF_FMT "(phy%d): skipping (memory allocation failed)\n", 978 TULIP_PRINTF_ARGS, devaddr); 979 continue; 980 } 981 phy->phy_attr = attr; 982 phy->phy_devaddr = devaddr; 983 phy->phy_status = status; 984 phy->phy_next = sc->tulip_phys; 985 sc->tulip_phys = phy; 986 987 loudprintf(TULIP_PRINTF_FMT "(phy%d): model = %s%s\n", 988 TULIP_PRINTF_ARGS, 989 phy->phy_devaddr, phy->phy_attr->attr_name, 990 (phy->phy_status & PHYSTS_CAN_AUTONEG) 991 ? " (supports media autonegotiation)" 992 : ""); 993 loudprintf(TULIP_PRINTF_FMT "(phy%d): media = ", 994 TULIP_PRINTF_ARGS, phy->phy_devaddr); 995 for (media = 11, sep = ""; media < 16; media++) { 996 if (status & (1 << media)) { 997 loudprintf("%s%s", sep, tulip_mediums[tulip_phy_statuses[media-11]]); 998 sep = ", "; 999 } 1000 } 1001 loudprintf("\n"); 1002 } 1003} 1004 1005/* 1006 * The general purpose timer of the 21140/21140a/21142 is kind 1007 * of strange. It can run on one of 3 speeds depending on the mode 1008 * of the chip. 1009 * 1010 * 10Mb/s port 204.8 microseconds (also speed of DC21041 timer) 1011 * 100Mb/s MII 81.92 microseconds 1012 * 10Mb/s MII 819.2 microseconds 1013 * 1014 * So we use a tick of a 819.2 microseconds and bias the number of ticks 1015 * required based on the mode in which we are running. 2560/3125 = .8192 1016 * so we use the reciprocal to scale the ms delay to 21140 ticks. 1017 */ 1018static void 1019tulip_dc21140_gp_timer_set( 1020 tulip_softc_t * const sc, 1021 unsigned msdelay) 1022{ 1023 tulip_uint32_t cmdmode = TULIP_CSR_READ(sc, csr_command); 1024#ifdef TULIP_DEBUG 1025 sc->tulip_dbg.dbg_msdelay = msdelay; 1026#endif 1027 if ((cmdmode & TULIP_CMD_PORTSELECT) == 0) { 1028 msdelay *= 4; 1029#ifdef TULIP_DEBUG 1030 sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_10MB_MII; 1031#endif 1032 } else if ((cmdmode & TULIP_CMD_TXTHRSHLDCTL) == 0) { 1033 msdelay *= 10; 1034#ifdef TULIP_DEBUG 1035 sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_100MB_MII; 1036 } else { 1037 sc->tulip_dbg.dbg_gprate = TULIP_GPTMR_10MB; 1038#endif 1039 } 1040#if 0 1041 if (sc->tulip_chipid == TULIP_DC21140A) 1042 msdelay *= 10; 1043#endif 1044 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_GPTIMEOUT); 1045 TULIP_CSR_WRITE(sc, csr_gp_timer, (msdelay * 313 + 128) / 256); 1046 if (sc->tulip_flags & TULIP_DEVICEPROBE) { 1047 sc->tulip_flags |= TULIP_FAKEGPTIMEOUT; 1048 } else { 1049 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); 1050 sc->tulip_flags &= ~TULIP_FAKEGPTIMEOUT; 1051 } 1052#ifdef TULIP_DEBUG 1053 sc->tulip_dbg.dbg_gpticks = (msdelay * 313 + 128) / 256; 1054#endif 1055} 1056 1057static int 1058tulip_dc21140_map_abilities( 1059 tulip_softc_t * const sc, 1060 const tulip_phy_t * const phy, 1061 unsigned abilities) 1062{ 1063 sc->tulip_abilities = abilities; 1064 if (abilities & PHYSTS_100BASETX_FD) { 1065 sc->tulip_media = TULIP_MEDIA_100BASETX_FD; 1066 } else if (abilities & PHYSTS_100BASETX) { 1067 sc->tulip_media = TULIP_MEDIA_100BASETX; 1068 } else if (abilities & PHYSTS_100BASET4) { 1069 sc->tulip_media = TULIP_MEDIA_100BASET4; 1070 } else if (abilities & PHYSTS_10BASET_FD) { 1071 sc->tulip_media = TULIP_MEDIA_10BASET_FD; 1072 } else if (abilities & PHYSTS_10BASET) { 1073 sc->tulip_media = TULIP_MEDIA_10BASET; 1074 } else { 1075 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 1076 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST; 1077 return 1; 1078 } 1079 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1080 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE; 1081 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_NEEDRESET; 1082 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1083 return 0; 1084} 1085 1086static void 1087tulip_dc21140_autonegotiate( 1088 tulip_softc_t * const sc, 1089 const tulip_phy_t * const phy) 1090{ 1091 tulip_uint32_t data; 1092 1093 if (sc->tulip_flags & TULIP_INRESET) { 1094 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1095 } 1096 if (sc->tulip_if.if_flags & IFF_NOAUTONEG) { 1097 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST; 1098 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL); 1099 if (data & PHYCTL_AUTONEG_ENABLE) { 1100 data &= ~PHYCTL_AUTONEG_ENABLE; 1101 tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data); 1102 } 1103 return; 1104 } 1105 1106 again: 1107 switch (sc->tulip_probe_state) { 1108 case TULIP_PROBE_INACTIVE: { 1109 sc->tulip_flags |= TULIP_TXPROBE_ACTIVE; 1110 tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, PHYCTL_RESET); 1111 sc->tulip_gpticks = 10; 1112 sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_NORMALINTR; 1113 sc->tulip_probe_state = TULIP_PROBE_PHYRESET; 1114 goto again; 1115 } 1116 case TULIP_PROBE_PHYRESET: { 1117 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL); 1118 if (data & PHYCTL_RESET) { 1119 if (--sc->tulip_gpticks > 0) { 1120 tulip_dc21140_gp_timer_set(sc, 100); 1121 return; 1122 } 1123 printf(TULIP_PRINTF_FMT "(phy%d): error: reset of PHY never completed!\n", 1124 TULIP_PRINTF_ARGS, phy->phy_devaddr); 1125 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE; 1126 sc->tulip_probe_state = TULIP_PROBE_FAILED; 1127 sc->tulip_if.if_flags &= ~(IFF_UP|IFF_RUNNING); 1128 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1129 return; 1130 } 1131 if ((phy->phy_status & PHYSTS_CAN_AUTONEG) == 0 1132 && (sc->tulip_if.if_flags & IFF_NOAUTONEG)) { 1133#ifdef TULIP_DEBUG 1134 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation disabled\n", 1135 TULIP_PRINTF_ARGS, phy->phy_devaddr); 1136#endif 1137 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST; 1138 return; 1139 } 1140 if (tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ADVERTISEMENT) != ((phy->phy_status >> 6) | 0x01)) 1141 tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ADVERTISEMENT, (phy->phy_status >> 6) | 0x01); 1142 tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data|PHYCTL_AUTONEG_RESTART|PHYCTL_AUTONEG_ENABLE); 1143 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL); 1144#ifdef TULIP_DEBUG 1145 if ((data & PHYCTL_AUTONEG_ENABLE) == 0) 1146 loudprintf(TULIP_PRINTF_FMT "(phy%d): oops: enable autonegotiation failed: 0x%04x\n", 1147 TULIP_PRINTF_ARGS, phy->phy_devaddr, data); 1148 else 1149 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation restarted: 0x%04x\n", 1150 TULIP_PRINTF_ARGS, phy->phy_devaddr, data); 1151#endif 1152 sc->tulip_probe_state = TULIP_PROBE_PHYAUTONEG; 1153 sc->tulip_gpticks = 60; 1154 goto again; 1155 } 1156 case TULIP_PROBE_PHYAUTONEG: { 1157 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS); 1158 if ((data & PHYSTS_AUTONEG_DONE) == 0) { 1159 if (--sc->tulip_gpticks > 0) { 1160 tulip_dc21140_gp_timer_set(sc, 100); 1161 return; 1162 } 1163#ifdef TULIP_DEBUG 1164 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation timeout: sts=0x%04x, ctl=0x%04x\n", 1165 TULIP_PRINTF_ARGS, phy->phy_devaddr, data, 1166 tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL)); 1167#endif 1168 sc->tulip_probe_state = TULIP_PROBE_MEDIATEST; 1169 return; 1170 } 1171 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ABILITIES); 1172#ifdef TULIP_DEBUG 1173 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation complete: 0x%04x\n", 1174 TULIP_PRINTF_ARGS, phy->phy_devaddr, data); 1175#endif 1176 data = (data << 6) & phy->phy_status; 1177 tulip_dc21140_map_abilities(sc, phy, data); 1178 return; 1179 } 1180 } 1181#ifdef TULIP_DEBUG 1182 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation failure: state = %d\n", 1183 TULIP_PRINTF_ARGS, phy->phy_devaddr, sc->tulip_probe_state); 1184#endif 1185} 1186 1187static tulip_media_t 1188tulip_dc21140_phy_readspecific( 1189 tulip_softc_t * const sc, 1190 const tulip_phy_t * const phy) 1191{ 1192 const phy_attr_t * const attr = phy->phy_attr; 1193 unsigned data; 1194 unsigned idx = 0; 1195 static const tulip_media_t table[] = { 1196 TULIP_MEDIA_UNKNOWN, 1197 TULIP_MEDIA_10BASET, 1198 TULIP_MEDIA_100BASETX, 1199 TULIP_MEDIA_100BASET4, 1200 TULIP_MEDIA_UNKNOWN, 1201 TULIP_MEDIA_10BASET_FD, 1202 TULIP_MEDIA_100BASETX_FD, 1203 TULIP_MEDIA_UNKNOWN 1204 }; 1205 1206 /* 1207 * Don't read phy specific registers if link is not up. 1208 */ 1209 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS); 1210 if ((data & PHYSTS_LINK_UP) == 0) 1211 return TULIP_MEDIA_UNKNOWN; 1212 1213 if (attr->attr_modes[PHY_MODE_100TX].pm_regno) { 1214 const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100TX]; 1215 data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno); 1216 if ((data & pm->pm_mask) == pm->pm_value) 1217 idx = 2; 1218 } 1219 if (idx == 0 && attr->attr_modes[PHY_MODE_100T4].pm_regno) { 1220 const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_100T4]; 1221 data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno); 1222 if ((data & pm->pm_mask) == pm->pm_value) 1223 idx = 3; 1224 } 1225 if (idx == 0 && attr->attr_modes[PHY_MODE_10T].pm_regno) { 1226 const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_10T]; 1227 data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno); 1228 if ((data & pm->pm_mask) == pm->pm_value) 1229 idx = 1; 1230 } 1231 if (idx != 0 && attr->attr_modes[PHY_MODE_FULLDUPLEX].pm_regno) { 1232 const phy_modedata_t * const pm = &attr->attr_modes[PHY_MODE_FULLDUPLEX]; 1233 data = tulip_mii_readreg(sc, phy->phy_devaddr, pm->pm_regno); 1234 idx += ((data & pm->pm_mask) == pm->pm_value ? 4 : 0); 1235 } 1236 return table[idx]; 1237} 1238 1239static void 1240tulip_dc21140_mii_link_monitor( 1241 tulip_softc_t * const sc, 1242 const tulip_phy_t * const phy) 1243{ 1244 tulip_uint32_t data; 1245 1246 tulip_dc21140_gp_timer_set(sc, 425); 1247 /* 1248 * Have we seen some packets? If so, the link must be good. 1249 */ 1250 if ((sc->tulip_flags & (TULIP_RXACT|TULIP_LINKSUSPECT|TULIP_LINKUP)) == (TULIP_RXACT|TULIP_LINKUP)) { 1251 sc->tulip_flags &= ~TULIP_RXACT; 1252 return; 1253 } 1254 1255 /* 1256 * Read the PHY status register. 1257 */ 1258 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_STATUS); 1259 if ((sc->tulip_if.if_flags & IFF_NOAUTONEG) == 0 && (data & PHYSTS_AUTONEG_DONE)) { 1260 /* 1261 * If autonegotiation hasn't been disabled and the PHY has complete 1262 * autonegotiation, see the if the remote systems abilities have changed. 1263 * If so, upgrade or downgrade as appropriate. 1264 */ 1265 unsigned abilities = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_AUTONEG_ABILITIES); 1266 abilities = (abilities << 6) & phy->phy_status; 1267 if (abilities != sc->tulip_abilities) { 1268 sc->tulip_flags |= TULIP_PRINTMEDIA; 1269#ifdef TULIP_DEBUG 1270 loudprintf(TULIP_PRINTF_FMT "(phy%d): autonegotiation changed: 0x%04x -> 0x%04x\n", 1271 TULIP_PRINTF_ARGS, phy->phy_devaddr, 1272 sc->tulip_abilities, abilities); 1273#endif 1274 tulip_dc21140_map_abilities(sc, phy, abilities); 1275 return; 1276 } 1277 } 1278 /* 1279 * The link is now up. If was down, say its back up. 1280 */ 1281 if ((data & (PHYSTS_LINK_UP|PHYSTS_REMOTE_FAULT)) == PHYSTS_LINK_UP) { 1282 if ((sc->tulip_if.if_flags & IFF_NOAUTONEG) == 0) { 1283 tulip_media_t media = tulip_dc21140_phy_readspecific(sc, phy); 1284 if (media != sc->tulip_media && media != TULIP_MEDIA_UNKNOWN) { 1285 sc->tulip_media = media; 1286 sc->tulip_flags |= TULIP_PRINTMEDIA; 1287 } 1288 } 1289 sc->tulip_gpticks = 0; 1290 if (sc->tulip_flags & TULIP_PRINTMEDIA) { 1291 printf(TULIP_PRINTF_FMT ": %senabling %s port\n", 1292 TULIP_PRINTF_ARGS, 1293 (sc->tulip_flags & TULIP_LINKUP) ? "" : "link up: ", 1294 tulip_mediums[sc->tulip_media]); 1295 } else if ((sc->tulip_flags & TULIP_LINKUP) == 0) { 1296 printf(TULIP_PRINTF_FMT ": link up\n", TULIP_PRINTF_ARGS); 1297 } 1298 sc->tulip_flags &= ~(TULIP_PRINTMEDIA|TULIP_LINKSUSPECT|TULIP_RXACT); 1299 sc->tulip_flags |= TULIP_LINKUP; 1300 return; 1301 } 1302 /* 1303 * The link may be down. Mark it as suspect. If suspect for 12 ticks, 1304 * mark it down. If autonegotiation is not disabled, restart the media 1305 * probe to see if the media has changed. 1306 */ 1307 if ((sc->tulip_flags & TULIP_LINKSUSPECT) == 0) { 1308 sc->tulip_flags |= TULIP_LINKSUSPECT; 1309 sc->tulip_flags &= ~TULIP_LINKUP; 1310 sc->tulip_gpticks = 12; 1311#ifdef TULIP_DEBUG 1312 sc->tulip_dbg.dbg_link_suspected++; 1313#endif 1314 return; 1315 } 1316 if (--sc->tulip_gpticks > 0) 1317 return; 1318 if (sc->tulip_flags & TULIP_LINKSUSPECT) { 1319 printf(TULIP_PRINTF_FMT ": link down: cable problem?\n", TULIP_PRINTF_ARGS); 1320 sc->tulip_flags &= ~TULIP_LINKSUSPECT; 1321#ifdef TULIP_DEBUG 1322 sc->tulip_dbg.dbg_link_downed++; 1323#endif 1324 } 1325 if (sc->tulip_if.if_flags & IFF_NOAUTONEG) 1326 return; 1327 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 1328 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1329 tulip_dc21140_autonegotiate(sc, phy); 1330} 1331 1332static void 1333tulip_dc21140_nomii_media_preset( 1334 tulip_softc_t * const sc) 1335{ 1336 sc->tulip_flags &= ~TULIP_SQETEST; 1337 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1338 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT 1339 |TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER; 1340 sc->tulip_if.if_baudrate = 100000000; 1341 } else { 1342 sc->tulip_cmdmode &= ~(TULIP_CMD_PORTSELECT 1343 |TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER); 1344 sc->tulip_if.if_baudrate = 10000000; 1345 if ((sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX) == 0) 1346 sc->tulip_flags |= TULIP_SQETEST; 1347 } 1348 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 1349} 1350 1351static void 1352tulip_dc21140_mii_media_preset( 1353 tulip_softc_t * const sc) 1354{ 1355 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT; 1356 sc->tulip_flags &= ~TULIP_SQETEST; 1357 if (sc->tulip_media != TULIP_MEDIA_UNKNOWN) { 1358 switch (sc->tulip_media) { 1359 case TULIP_MEDIA_10BASET: { 1360 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 1361 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL; 1362 sc->tulip_if.if_baudrate = 10000000; 1363 sc->tulip_flags |= TULIP_SQETEST; 1364 break; 1365 } 1366 case TULIP_MEDIA_10BASET_FD: { 1367 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL; 1368 sc->tulip_if.if_baudrate = 10000000; 1369 break; 1370 } 1371 case TULIP_MEDIA_100BASET4: 1372 case TULIP_MEDIA_100BASETX: { 1373 sc->tulip_cmdmode &= ~(TULIP_CMD_FULLDUPLEX|TULIP_CMD_TXTHRSHLDCTL); 1374 sc->tulip_if.if_baudrate = 100000000; 1375 break; 1376 } 1377 case TULIP_MEDIA_100BASETX_FD: { 1378 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 1379 sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL; 1380 sc->tulip_if.if_baudrate = 100000000; 1381 break; 1382 } 1383 } 1384 } 1385 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 1386} 1387 1388static void 1389tulip_dc21140_nomii_100only_media_preset( 1390 tulip_softc_t * const sc) 1391{ 1392 sc->tulip_cmdmode |= TULIP_CMD_PORTSELECT 1393 |TULIP_CMD_PCSFUNCTION|TULIP_CMD_SCRAMBLER; 1394 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 1395} 1396 1397 1398static int 1399tulip_dc21140_evalboard_media_probe( 1400 tulip_softc_t * const sc) 1401{ 1402 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS); 1403 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT); 1404 TULIP_CSR_WRITE(sc, csr_command, 1405 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT | 1406 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE); 1407 TULIP_CSR_WRITE(sc, csr_command, 1408 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL); 1409 DELAY(1000000); 1410 return (TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_EB_OK100) != 0; 1411} 1412 1413static void 1414tulip_dc21140_evalboard_media_select( 1415 tulip_softc_t * const sc) 1416{ 1417 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE 1418 |TULIP_CMD_BACKOFFCTR; 1419 sc->tulip_flags |= TULIP_LINKUP; 1420 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_PINS); 1421 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EB_INIT); 1422 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1423 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 1424 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1425 sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL; 1426 sc->tulip_media = TULIP_MEDIA_100BASETX; 1427 sc->tulip_flags &= ~TULIP_SQETEST; 1428 } else { 1429 if (sc->tulip_flags & TULIP_ALTPHYS) 1430 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1431 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL; 1432 sc->tulip_media = TULIP_MEDIA_10BASET; 1433 sc->tulip_flags |= TULIP_SQETEST; 1434 } 1435#ifdef BIG_PACKET 1436 if (sc->tulip_if.if_mtu > ETHERMTU) { 1437 TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE); 1438 } 1439#endif 1440} 1441 1442static const tulip_boardsw_t tulip_dc21140_eb_boardsw = { 1443 TULIP_DC21140_DEC_EB, 1444 "", 1445 tulip_dc21140_evalboard_media_probe, 1446 tulip_dc21140_evalboard_media_select, 1447 tulip_dc21140_nomii_media_preset, 1448}; 1449 1450static int 1451tulip_dc21140_smc9332_media_probe( 1452 tulip_softc_t * const sc) 1453{ 1454 int idx; 1455 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS); 1456 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT); 1457 TULIP_CSR_WRITE(sc, csr_command, 1458 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT | 1459 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE); 1460 TULIP_CSR_WRITE(sc, csr_command, 1461 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL); 1462 DELAY(200000); 1463 for (idx = 1000; idx > 0; idx--) { 1464 tulip_uint32_t csr = TULIP_CSR_READ(sc, csr_gp); 1465 if ((csr & (TULIP_GP_SMC_9332_OK100|TULIP_GP_SMC_9332_OK10)) == TULIP_GP_SMC_9332_OK100) 1466 return 1; 1467 if ((csr & (TULIP_GP_SMC_9332_OK100|TULIP_GP_SMC_9332_OK10)) == TULIP_GP_SMC_9332_OK10) 1468 return 0; 1469 DELAY(1000); 1470 } 1471 return 0; 1472} 1473 1474static void 1475tulip_dc21140_smc9332_media_select( 1476 tulip_softc_t * const sc) 1477{ 1478 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE 1479 |TULIP_CMD_BACKOFFCTR; 1480 sc->tulip_flags |= TULIP_LINKUP; 1481 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_PINS); 1482 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_SMC_9332_INIT); 1483 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1484 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 1485 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1486 sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL; 1487 sc->tulip_media = TULIP_MEDIA_100BASETX; 1488 sc->tulip_flags &= ~TULIP_SQETEST; 1489 } else { 1490 if (sc->tulip_flags & TULIP_ALTPHYS) 1491 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1492 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL; 1493 sc->tulip_media = TULIP_MEDIA_10BASET; 1494 sc->tulip_flags |= TULIP_SQETEST; 1495 } 1496#ifdef BIG_PACKET 1497 if (sc->tulip_if.if_mtu > ETHERMTU) { 1498 TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE); 1499 } 1500#endif 1501} 1502 1503static const tulip_boardsw_t tulip_dc21140_smc9332_boardsw = { 1504 TULIP_DC21140_SMC_9332, 1505 "SMC 9332 ", 1506 tulip_dc21140_smc9332_media_probe, 1507 tulip_dc21140_smc9332_media_select, 1508 tulip_dc21140_nomii_media_preset, 1509}; 1510 1511static int 1512tulip_dc21140_cogent_em100_media_probe( 1513 tulip_softc_t * const sc) 1514{ 1515 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS); 1516 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT); 1517 TULIP_CSR_WRITE(sc, csr_command, 1518 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT | 1519 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE); 1520 TULIP_CSR_WRITE(sc, csr_command, 1521 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL); 1522 return 1; 1523} 1524 1525static void 1526tulip_dc21140_cogent_em100_media_select( 1527 tulip_softc_t * const sc) 1528{ 1529 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE 1530 |TULIP_CMD_BACKOFFCTR; 1531 sc->tulip_flags |= TULIP_LINKUP; 1532 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_PINS); 1533 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_EM100_INIT); 1534 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 1535 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1536 sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL; 1537 sc->tulip_media = TULIP_MEDIA_100BASETX; 1538#ifdef BIG_PACKET 1539 if (sc->tulip_if.if_mtu > ETHERMTU) { 1540 TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE); 1541 } 1542#endif 1543} 1544 1545static const tulip_boardsw_t tulip_dc21140_cogent_em100_boardsw = { 1546 TULIP_DC21140_COGENT_EM100, 1547 "Cogent EM100 ", 1548 tulip_dc21140_cogent_em100_media_probe, 1549 tulip_dc21140_cogent_em100_media_select, 1550 tulip_dc21140_nomii_100only_media_preset 1551}; 1552 1553 1554static int 1555tulip_dc21140_znyx_zx34x_media_probe( 1556 tulip_softc_t * const sc) 1557{ 1558 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS); 1559 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT); 1560 TULIP_CSR_WRITE(sc, csr_command, 1561 TULIP_CSR_READ(sc, csr_command) | TULIP_CMD_PORTSELECT | 1562 TULIP_CMD_PCSFUNCTION | TULIP_CMD_SCRAMBLER | TULIP_CMD_MUSTBEONE); 1563 TULIP_CSR_WRITE(sc, csr_command, 1564 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL); 1565 DELAY(1000000); 1566 1567 return (TULIP_CSR_READ(sc, csr_gp) & TULIP_GP_ZX34X_OK10); 1568} 1569 1570static void 1571tulip_dc21140_znyx_zx34x_media_select( 1572 tulip_softc_t * const sc) 1573{ 1574 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE 1575 |TULIP_CMD_BACKOFFCTR; 1576 sc->tulip_flags |= TULIP_LINKUP; 1577 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_PINS); 1578 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_ZX34X_INIT); 1579 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1580 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 1581 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1582 sc->tulip_cmdmode &= ~TULIP_CMD_TXTHRSHLDCTL; 1583 sc->tulip_media = TULIP_MEDIA_100BASETX; 1584 } else { 1585 if (sc->tulip_flags & TULIP_ALTPHYS) 1586 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1587 sc->tulip_cmdmode |= TULIP_CMD_TXTHRSHLDCTL; 1588 sc->tulip_media = TULIP_MEDIA_10BASET; 1589 } 1590#ifdef BIG_PACKET 1591 if (sc->tulip_if.if_mtu > ETHERMTU) { 1592 TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE); 1593 } 1594#endif 1595} 1596 1597static const tulip_boardsw_t tulip_dc21140_znyx_zx34x_boardsw = { 1598 TULIP_DC21140_ZNYX_ZX34X, 1599 "ZNYX ZX34X ", 1600 tulip_dc21140_znyx_zx34x_media_probe, 1601 tulip_dc21140_znyx_zx34x_media_select, 1602 tulip_dc21140_nomii_media_preset, 1603}; 1604 1605static const struct { 1606 unsigned short value_gp; 1607 unsigned short value_phyctl; 1608} tulip_dc21140_de500_csrvalues[] = { 1609 { TULIP_GP_DE500_HALFDUPLEX, 0 }, /* TULIP_MEDIA_UNKNOWN */ 1610 { TULIP_GP_DE500_HALFDUPLEX, 0 }, /* TULIP_MEDIA_10BASET */ 1611 { /* n/a */ }, /* TULIP_MEDIA_BNC */ 1612 { /* n/a */ }, /* TULIP_MEDIA_AUI */ 1613 { /* n/a */ }, /* TULIP_MEDIA_BNCAUI */ 1614 { 0, PHYCTL_FULL_DUPLEX }, /* TULIP_MEDIA_10BASET_FD */ 1615 { TULIP_GP_DE500_HALFDUPLEX| /* TULIP_MEDIA_100BASET */ 1616 TULIP_GP_DE500_FORCE_100, PHYCTL_SELECT_100MB }, 1617 { TULIP_GP_DE500_FORCE_100, /* TULIP_MEDIA_100BASET_FD */ 1618 PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX }, 1619 { TULIP_GP_DE500_HALFDUPLEX| /* TULIP_MEDIA_100BASET4 */ 1620 TULIP_GP_DE500_FORCE_100, PHYCTL_SELECT_100MB }, 1621}; 1622 1623static void 1624tulip_dc21140_de500_media_select( 1625 tulip_softc_t * const sc) 1626{ 1627 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1628 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) { 1629 sc->tulip_media = TULIP_MEDIA_100BASETX_FD; 1630 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 1631 } else { 1632 sc->tulip_media = TULIP_MEDIA_100BASETX; 1633 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 1634 } 1635 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 1636 sc->tulip_flags |= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1637 } else { 1638 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) { 1639 sc->tulip_media = TULIP_MEDIA_10BASET_FD; 1640 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 1641 } else { 1642 sc->tulip_media = TULIP_MEDIA_10BASET; 1643 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 1644 } 1645 if (sc->tulip_flags & TULIP_ALTPHYS) 1646 sc->tulip_flags ^= TULIP_PRINTMEDIA|TULIP_ALTPHYS; 1647 } 1648} 1649 1650static int 1651tulip_dc21140_de500xa_media_probe( 1652 tulip_softc_t * const sc) 1653{ 1654 int idx; 1655 1656 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS); 1657 DELAY(500); 1658 TULIP_CSR_WRITE(sc, csr_gp, 1659 TULIP_GP_DE500_HALFDUPLEX|TULIP_GP_DE500_FORCE_100); 1660 DELAY(1000); 1661 TULIP_CSR_WRITE(sc, csr_command, 1662 TULIP_CSR_READ(sc, csr_command) 1663 |TULIP_CMD_PORTSELECT|TULIP_CMD_PCSFUNCTION 1664 |TULIP_CMD_SCRAMBLER|TULIP_CMD_MUSTBEONE); 1665 TULIP_CSR_WRITE(sc, csr_command, 1666 TULIP_CSR_READ(sc, csr_command) & ~TULIP_CMD_TXTHRSHLDCTL); 1667 for (idx = 2400; idx > 0; idx--) { 1668 tulip_uint32_t data; 1669 DELAY(1000); 1670 data = ~TULIP_CSR_READ(sc, csr_gp); 1671 if ((data & (TULIP_GP_DE500_LINK_PASS|TULIP_GP_DE500_SYM_LINK)) == (TULIP_GP_DE500_SYM_LINK|TULIP_GP_DE500_LINK_PASS)) 1672 return 1; 1673 } 1674 return 0; 1675} 1676 1677static void 1678tulip_dc21140_de500xa_media_select( 1679 tulip_softc_t * const sc) 1680{ 1681 sc->tulip_cmdmode |= TULIP_CMD_STOREFWD|TULIP_CMD_MUSTBEONE 1682 |TULIP_CMD_BACKOFFCTR; 1683 sc->tulip_flags |= TULIP_LINKUP; 1684 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS); 1685 tulip_dc21140_de500_media_select(sc); 1686 TULIP_CSR_WRITE(sc, csr_gp, tulip_dc21140_de500_csrvalues[sc->tulip_media].value_gp); 1687#ifdef BIG_PACKET 1688 if (sc->tulip_if.if_mtu > ETHERMTU) { 1689 TULIP_CSR_WRITE(sc, csr_watchdog, TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE); 1690 } 1691#endif 1692} 1693 1694static const tulip_boardsw_t tulip_dc21140_de500xa_boardsw = { 1695 TULIP_DC21140_DEC_DE500, "Digital DE500-XA ", 1696 tulip_dc21140_de500xa_media_probe, 1697 tulip_dc21140_de500xa_media_select, 1698 tulip_dc21140_nomii_media_preset, 1699}; 1700 1701static int 1702tulip_dc21140_de500aa_media_probe( 1703 tulip_softc_t * const sc) 1704{ 1705 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PINS); 1706 TULIP_CSR_WRITE(sc, csr_gp, TULIP_GP_DE500_PHY_RESET); 1707 DELAY(1000); 1708 TULIP_CSR_WRITE(sc, csr_gp, 0); 1709 1710 TULIP_CSR_WRITE(sc, csr_command, TULIP_CMD_PORTSELECT); 1711 return 0; 1712} 1713 1714static void 1715tulip_dc21140_de500aa_media_select( 1716 tulip_softc_t * const sc) 1717{ 1718 const tulip_phy_t *phy = sc->tulip_phys; 1719 tulip_uint32_t data; 1720 1721 if (phy == NULL) 1722 return; 1723 1724 /* 1725 * Defer autosensing until out of device probe (will be 1726 * triggered by ifwatchdog or ifioctl). 1727 */ 1728 1729 if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) { 1730 tulip_media_t old_media; 1731 if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST) 1732 tulip_dc21140_autonegotiate(sc, phy); 1733 if (sc->tulip_probe_state != TULIP_PROBE_MEDIATEST) 1734 return; 1735 old_media = sc->tulip_media; 1736 if (sc->tulip_if.if_flags & IFF_NOAUTONEG) { 1737 tulip_dc21140_de500_media_select(sc); 1738 } else { 1739 sc->tulip_media = tulip_dc21140_phy_readspecific(sc, phy); 1740 if (sc->tulip_media == TULIP_MEDIA_UNKNOWN) { 1741 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1742 tulip_dc21140_autonegotiate(sc, phy); 1743 return; 1744 } 1745 sc->tulip_flags |= TULIP_PRINTMEDIA; 1746 } 1747 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1748 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE; 1749 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1750 if (sc->tulip_flags & TULIP_INRESET) 1751 goto in_reset; 1752 if (sc->tulip_media != old_media) 1753 sc->tulip_flags |= TULIP_NEEDRESET; 1754 return; 1755 } 1756 if ((sc->tulip_flags & TULIP_INRESET) == 0) { 1757 tulip_dc21140_mii_link_monitor(sc, phy); 1758 return; 1759 } 1760 in_reset: 1761 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1762 sc->tulip_flags |= TULIP_ALTPHYS; 1763 } else { 1764 sc->tulip_flags &= ~TULIP_ALTPHYS; 1765 } 1766 sc->tulip_gpticks = 8; 1767 sc->tulip_intrmask |= TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_NORMALINTR; 1768 tulip_dc21140_gp_timer_set(sc, 425); 1769 data = tulip_mii_readreg(sc, phy->phy_devaddr, PHYREG_CONTROL); 1770 if ((data & PHYCTL_AUTONEG_ENABLE) == 0) { 1771 data &= ~(PHYCTL_SELECT_100MB|PHYCTL_FULL_DUPLEX); 1772 data |= tulip_dc21140_de500_csrvalues[sc->tulip_media].value_phyctl; 1773 tulip_mii_writereg(sc, phy->phy_devaddr, PHYREG_CONTROL, data); 1774 } 1775} 1776 1777static const tulip_boardsw_t tulip_dc21140_de500aa_boardsw = { 1778 TULIP_DC21140_DEC_DE500, "Digital DE500-AA ", 1779 tulip_dc21140_de500aa_media_probe, 1780 tulip_dc21140_de500aa_media_select, 1781 tulip_dc21140_mii_media_preset, 1782 tulip_dc21140_mii_probe, 1783}; 1784 1785static int 1786tulip_dc21041_media_probe( 1787 tulip_softc_t * const sc) 1788{ 1789 sc->tulip_if.if_baudrate = 10000000; 1790 return 0; 1791} 1792 1793#ifdef BIG_PACKET 1794#define TULIP_DC21041_SIAGEN_WATCHDOG (sc->tulip_if.if_mtu > ETHERMTU ? TULIP_WATCHDOG_RXDISABLE|TULIP_WATCHDOG_TXDISABLE : 0) 1795#else 1796#define TULIP_DC21041_SIAGEN_WATCHDOG 0 1797#endif 1798 1799static void 1800tulip_dc21041_media_select( 1801 tulip_softc_t * const sc) 1802{ 1803 sc->tulip_cmdmode |= TULIP_CMD_CAPTREFFCT|TULIP_CMD_ENHCAPTEFFCT 1804 |TULIP_CMD_THRSHLD160|TULIP_CMD_BACKOFFCTR; 1805 sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_GPTIMEOUT|TULIP_STS_TXINTR 1806 |TULIP_STS_ABNRMLINTR|TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL; 1807 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 1808 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) { 1809 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 1810 sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE); 1811 sc->tulip_flags |= TULIP_ALTPHYS|TULIP_WANTRXACT; 1812 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1813 } 1814 } else { 1815 if (sc->tulip_flags & TULIP_ALTPHYS) { 1816 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 1817 sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE|TULIP_ALTPHYS); 1818 sc->tulip_flags |= TULIP_WANTRXACT; 1819 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1820 } 1821 } 1822 1823 if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_LINKFAIL) { 1824 if (sc->tulip_media == TULIP_MEDIA_10BASET) { 1825 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 1826 } else if (sc->tulip_media == TULIP_MEDIA_BNC) { 1827 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1828 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1829 DELAY(50); 1830 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC); 1831 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_BNC); 1832 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG); 1833 DELAY(50); 1834 return; 1835 } else if (sc->tulip_media == TULIP_MEDIA_AUI) { 1836 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1837 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1838 DELAY(50); 1839 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI); 1840 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_AUI); 1841 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG); 1842 DELAY(50); 1843 return; 1844 } 1845 1846 switch (sc->tulip_probe_state) { 1847 case TULIP_PROBE_INACTIVE: { 1848 sc->tulip_if.if_flags |= IFF_OACTIVE; 1849 sc->tulip_gpticks = 200; 1850 sc->tulip_probe_state = TULIP_PROBE_10BASET; 1851 sc->tulip_flags |= TULIP_TXPROBE_ACTIVE; 1852 sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_LINKUP); 1853 sc->tulip_cmdmode |= TULIP_CMD_TXRUN; 1854 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode & ~TULIP_CMD_RXRUN); 1855 1856 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1857 DELAY(50); 1858 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_10BASET); 1859 if (sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX) 1860 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_10BASET_FD); 1861 else 1862 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_10BASET); 1863 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_10BASET|TULIP_DC21041_SIAGEN_WATCHDOG); 1864 DELAY(50); 1865 TULIP_CSR_WRITE(sc, csr_gp_timer, 12000000 / 204800); /* 120 ms */ 1866 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_GPTIMEOUT); 1867 tulip_ifstart(&sc->tulip_if); 1868 break; 1869 } 1870 case TULIP_PROBE_10BASET: { 1871 if (--sc->tulip_gpticks > 0) { 1872 if ((TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_OTHERRXACTIVITY) == 0) { 1873 TULIP_CSR_WRITE(sc, csr_gp_timer, 12000000 / 204800); /* 120 ms */ 1874 /* TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); */ 1875 break; 1876 } 1877 } 1878 sc->tulip_gpticks = 4; 1879 if (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_OTHERRXACTIVITY) { 1880 sc->tulip_probe_state = TULIP_PROBE_BNC; 1881 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1882 DELAY(50); 1883 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC); 1884 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_BNC); 1885 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG); 1886 TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_SIASTS_OTHERRXACTIVITY); 1887 DELAY(50); 1888 TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */ 1889 } else { 1890 sc->tulip_probe_state = TULIP_PROBE_AUI; 1891 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1892 DELAY(50); 1893 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI); 1894 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_AUI); 1895 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG); 1896 DELAY(50); 1897 TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */ 1898 } 1899 break; 1900 } 1901 case TULIP_PROBE_BNC: 1902 case TULIP_PROBE_AUI: { 1903 if (sc->tulip_flags & TULIP_TXPROBE_OK) { 1904 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 1905 sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE); 1906 sc->tulip_flags |= TULIP_LINKUP; 1907 TULIP_CSR_WRITE(sc, csr_gp_timer, 0); /* disable */ 1908 if (sc->tulip_probe_state == TULIP_PROBE_AUI) { 1909 if (sc->tulip_media != TULIP_MEDIA_AUI) { 1910 sc->tulip_media = TULIP_MEDIA_AUI; 1911 sc->tulip_flags |= TULIP_PRINTMEDIA; 1912 } 1913 } else if (sc->tulip_probe_state == TULIP_PROBE_BNC) { 1914 if (sc->tulip_media != TULIP_MEDIA_BNC) { 1915 sc->tulip_media = TULIP_MEDIA_BNC; 1916 sc->tulip_flags |= TULIP_PRINTMEDIA; 1917 } 1918 } 1919 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 1920 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 1921 break; 1922 } 1923 if ((sc->tulip_flags & TULIP_WANTRXACT) == 0 1924 || (TULIP_CSR_READ(sc, csr_sia_status) & TULIP_SIASTS_RXACTIVITY)) { 1925 if ((sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) { 1926 struct mbuf *m; 1927 /* 1928 * Before we are sure this is the right media we need 1929 * to send a small packet to make sure there's carrier. 1930 * Strangely, BNC and AUI will 'see" receive data if 1931 * either is connected so the transmit is the only way 1932 * to verify the connectivity. 1933 */ 1934 MGETHDR(m, M_DONTWAIT, MT_DATA); 1935 if (m == NULL) { 1936 TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */ 1937 break; 1938 } 1939 /* 1940 * Construct a LLC TEST message which will point to ourselves. 1941 */ 1942 bcopy(sc->tulip_hwaddr, mtod(m, struct ether_header *)->ether_dhost, 6); 1943 bcopy(sc->tulip_hwaddr, mtod(m, struct ether_header *)->ether_shost, 6); 1944 mtod(m, struct ether_header *)->ether_type = htons(3); 1945 mtod(m, unsigned char *)[14] = 0; 1946 mtod(m, unsigned char *)[15] = 0; 1947 mtod(m, unsigned char *)[16] = 0xE3; /* LLC Class1 TEST (no poll) */ 1948 m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3; 1949 /* 1950 * send it! 1951 */ 1952 sc->tulip_flags &= ~TULIP_TXPROBE_OK; 1953 IF_PREPEND(&sc->tulip_if.if_snd, m); 1954 tulip_ifstart(&sc->tulip_if); 1955 break; 1956 } 1957 sc->tulip_flags &= ~TULIP_TXPROBE_ACTIVE; 1958 } 1959 /* 1960 * Take 2 passes through before deciding to not 1961 * wait for receive activity. Then take another 1962 * two passes before spitting out a warning. 1963 */ 1964 if (sc->tulip_gpticks > 0 && --sc->tulip_gpticks == 0) { 1965 if (sc->tulip_flags & TULIP_WANTRXACT) { 1966 sc->tulip_flags &= ~TULIP_WANTRXACT; 1967 sc->tulip_gpticks = 4; 1968 } else { 1969 printf(TULIP_PRINTF_FMT ": autosense failed: cable problem?\n", 1970 TULIP_PRINTF_ARGS); 1971 } 1972 } 1973 /* 1974 * Since this media failed to probe, try the other one. 1975 */ 1976 if (sc->tulip_probe_state == TULIP_PROBE_AUI) { 1977 sc->tulip_probe_state = TULIP_PROBE_BNC; 1978 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1979 DELAY(50); 1980 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_BNC); 1981 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_BNC); 1982 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_BNC|TULIP_DC21041_SIAGEN_WATCHDOG); 1983 DELAY(50); 1984 TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */ 1985 } else { 1986 sc->tulip_probe_state = TULIP_PROBE_AUI; 1987 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 1988 DELAY(50); 1989 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_AUI); 1990 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_AUI); 1991 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_AUI|TULIP_DC21041_SIAGEN_WATCHDOG); 1992 DELAY(50); 1993 TULIP_CSR_WRITE(sc, csr_gp_timer, 100000000 / 204800); /* 100 ms */ 1994 } 1995 break; 1996 } 1997 } 1998 } else { 1999 /* 2000 * If the link has passed LinkPass, 10baseT is the 2001 * proper media to use. 2002 */ 2003 if (sc->tulip_if.if_flags & IFF_FULLDUPLEX) { 2004 if (sc->tulip_media != TULIP_MEDIA_10BASET_FD) { 2005 sc->tulip_media = TULIP_MEDIA_10BASET_FD; 2006 sc->tulip_flags |= TULIP_PRINTMEDIA; 2007 sc->tulip_cmdmode |= TULIP_CMD_FULLDUPLEX; 2008 } 2009 } else { 2010 if (sc->tulip_media != TULIP_MEDIA_10BASET) { 2011 sc->tulip_media = TULIP_MEDIA_10BASET; 2012 sc->tulip_flags |= TULIP_PRINTMEDIA; 2013 sc->tulip_cmdmode &= ~TULIP_CMD_FULLDUPLEX; 2014 } 2015 } 2016 if (sc->tulip_media != TULIP_MEDIA_10BASET 2017 || (sc->tulip_flags & TULIP_INRESET)) { 2018 sc->tulip_media = TULIP_MEDIA_10BASET; 2019 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_SIACONN_RESET); 2020 DELAY(50); 2021 TULIP_CSR_WRITE(sc, csr_sia_connectivity, TULIP_DC21041_SIACONN_10BASET); 2022 if (sc->tulip_cmdmode & TULIP_CMD_FULLDUPLEX) 2023 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_10BASET_FD); 2024 else 2025 TULIP_CSR_WRITE(sc, csr_sia_tx_rx, TULIP_DC21041_SIATXRX_10BASET); 2026 TULIP_CSR_WRITE(sc, csr_sia_general, TULIP_DC21041_SIAGEN_10BASET|TULIP_DC21041_SIAGEN_WATCHDOG); 2027 DELAY(50); 2028 } 2029 TULIP_CSR_WRITE(sc, csr_gp_timer, 0); /* disable */ 2030 sc->tulip_gpticks = 1; 2031 sc->tulip_probe_state = TULIP_PROBE_10BASET; 2032 sc->tulip_intrmask &= ~TULIP_STS_GPTIMEOUT; 2033 sc->tulip_flags |= TULIP_LINKUP; 2034 sc->tulip_flags &= ~(TULIP_TXPROBE_OK|TULIP_TXPROBE_ACTIVE); 2035 sc->tulip_if.if_flags &= ~IFF_OACTIVE; 2036 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 2037 } 2038 if (sc->tulip_flags & TULIP_DEVICEPROBE) { 2039 sc->tulip_flags |= TULIP_FAKEGPTIMEOUT; 2040 } else { 2041 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); 2042 sc->tulip_flags &= ~TULIP_FAKEGPTIMEOUT; 2043 } 2044} 2045 2046static const tulip_boardsw_t tulip_dc21041_boardsw = { 2047 TULIP_DC21041_GENERIC, 2048 "", 2049 tulip_dc21041_media_probe, 2050 tulip_dc21041_media_select 2051}; 2052 2053static void 2054tulip_reset( 2055 tulip_softc_t * const sc) 2056{ 2057 tulip_ringinfo_t *ri; 2058 tulip_desc_t *di; 2059 2060 /* 2061 * Brilliant. Simply brilliant. When switching modes/speeds 2062 * on a DC2114*, you need to set the appriopriate MII/PCS/SCL/PS 2063 * bits in CSR6 and then do a software reset to get the DC21140 2064 * to properly reset its internal pathways to the right places. 2065 * Grrrr. 2066 */ 2067 if (sc->tulip_boardsw->bd_media_preset != NULL) 2068 (*sc->tulip_boardsw->bd_media_preset)(sc); 2069 2070 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); 2071 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 2072 33MHz that comes to two microseconds but wait a 2073 bit longer anyways) */ 2074 2075 sc->tulip_flags |= TULIP_INRESET; 2076 sc->tulip_flags &= ~(TULIP_NEEDRESET|TULIP_RXBUFSLOW); 2077 sc->tulip_intrmask = 0; 2078 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); 2079 2080 TULIP_CSR_WRITE(sc, csr_txlist, TULIP_KVATOPHYS(sc, &sc->tulip_txinfo.ri_first[0])); 2081 TULIP_CSR_WRITE(sc, csr_rxlist, TULIP_KVATOPHYS(sc, &sc->tulip_rxinfo.ri_first[0])); 2082 TULIP_CSR_WRITE(sc, csr_busmode, 2083 (1 << (TULIP_BURSTSIZE(sc->tulip_unit) + 8)) 2084 |TULIP_BUSMODE_CACHE_ALIGN8 2085 |(BYTE_ORDER != LITTLE_ENDIAN ? TULIP_BUSMODE_BIGENDIAN : 0)); 2086 2087 sc->tulip_gpticks = 0; 2088 sc->tulip_txtimer = 0; 2089 sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS; 2090 sc->tulip_if.if_flags &= ~IFF_OACTIVE; 2091 /* 2092 * Free all the mbufs that were on the transmit ring. 2093 */ 2094 for (;;) { 2095 struct mbuf *m; 2096 IF_DEQUEUE(&sc->tulip_txq, m); 2097 if (m == NULL) 2098 break; 2099 m_freem(m); 2100 } 2101 2102 ri = &sc->tulip_txinfo; 2103 ri->ri_nextin = ri->ri_nextout = ri->ri_first; 2104 ri->ri_free = ri->ri_max; 2105 for (di = ri->ri_first; di < ri->ri_last; di++) 2106 di->d_status = 0; 2107 2108 /* 2109 * We need to collect all the mbufs were on the 2110 * receive ring before we reinit it either to put 2111 * them back on or to know if we have to allocate 2112 * more. 2113 */ 2114 ri = &sc->tulip_rxinfo; 2115 ri->ri_nextin = ri->ri_nextout = ri->ri_first; 2116 ri->ri_free = ri->ri_max; 2117 for (di = ri->ri_first; di < ri->ri_last; di++) { 2118 di->d_status = 0; 2119 di->d_length1 = 0; di->d_addr1 = 0; 2120 di->d_length2 = 0; di->d_addr2 = 0; 2121 } 2122 for (;;) { 2123 struct mbuf *m; 2124 IF_DEQUEUE(&sc->tulip_rxq, m); 2125 if (m == NULL) 2126 break; 2127 m_freem(m); 2128 } 2129 2130 (*sc->tulip_boardsw->bd_media_select)(sc); 2131#ifdef TULIP_DEBUG 2132 if ((sc->tulip_flags & (TULIP_DEVICEPROBE|TULIP_NEEDRESET)) == TULIP_NEEDRESET) 2133 printf(TULIP_PRINTF_FMT ": tulip_reset: additional reset needed?!?\n", 2134 TULIP_PRINTF_ARGS); 2135#endif 2136 if ((sc->tulip_flags & (TULIP_LINKUP|TULIP_PRINTMEDIA)) == (TULIP_LINKUP|TULIP_PRINTMEDIA)) { 2137 printf(TULIP_PRINTF_FMT ": enabling %s port\n", 2138 TULIP_PRINTF_ARGS, 2139 tulip_mediums[sc->tulip_media]); 2140 sc->tulip_flags &= ~TULIP_PRINTMEDIA; 2141 } 2142 if (sc->tulip_chipid == TULIP_DC21041) 2143 TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status)); 2144 2145 sc->tulip_intrmask |= TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR 2146 |TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED 2147 |TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL|TULIP_STS_RXSTOPPED; 2148 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP|TULIP_INRESET 2149 |TULIP_RXACT); 2150 tulip_addr_filter(sc); 2151} 2152 2153static void 2154tulip_init( 2155 tulip_softc_t * const sc) 2156{ 2157 if (sc->tulip_if.if_flags & IFF_UP) { 2158 sc->tulip_if.if_flags |= IFF_RUNNING; 2159 if (sc->tulip_if.if_flags & IFF_PROMISC) { 2160 sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS; 2161 } else { 2162 sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS; 2163 if (sc->tulip_if.if_flags & IFF_ALLMULTI) { 2164 sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI; 2165 } else { 2166 sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI; 2167 } 2168 } 2169 sc->tulip_cmdmode |= TULIP_CMD_TXRUN; 2170 if ((sc->tulip_flags & TULIP_WANTSETUP) == 0) { 2171 tulip_rx_intr(sc); 2172 sc->tulip_cmdmode |= TULIP_CMD_RXRUN; 2173 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED; 2174 } else { 2175 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; 2176 tulip_ifstart(&sc->tulip_if); 2177 } 2178 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); 2179 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 2180 } else { 2181 tulip_reset(sc); 2182 sc->tulip_if.if_flags &= ~IFF_RUNNING; 2183 } 2184} 2185 2186static void 2187tulip_rx_intr( 2188 tulip_softc_t * const sc) 2189{ 2190 tulip_ringinfo_t * const ri = &sc->tulip_rxinfo; 2191 struct ifnet * const ifp = &sc->tulip_if; 2192 int fillok = 1; 2193#ifdef TULIP_DEBUG 2194 int cnt = 0; 2195#endif 2196 2197 for (;;) { 2198 struct ether_header eh; 2199 tulip_desc_t *eop = ri->ri_nextin; 2200 int total_len = 0, last_offset = 0; 2201 struct mbuf *ms = NULL, *me = NULL; 2202 int accept = 0; 2203 2204 if (fillok && sc->tulip_rxq.ifq_len < TULIP_RXQ_TARGET) 2205 goto queue_mbuf; 2206 2207#ifdef TULIP_DEBUG 2208 if (cnt == ri->ri_max) { 2209 sc->tulip_dbg.dbg_rxintrs++; 2210 sc->tulip_dbg.dbg_rxpktsperintr[cnt]++; 2211 return; 2212 } 2213#endif 2214 2215 if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER) { 2216#ifdef TULIP_DEBUG 2217 sc->tulip_dbg.dbg_rxintrs++; 2218 sc->tulip_dbg.dbg_rxpktsperintr[cnt]++; 2219#endif 2220 return; 2221 } 2222 /* 2223 * It is possible (though improbable unless the BIG_PACKET support 2224 * is enabled or MCLBYTES < 1518) for a received packet to cross 2225 * more than one receive descriptor. 2226 */ 2227 while ((((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_RxLASTDESC) == 0) { 2228 if (++eop == ri->ri_last) 2229 eop = ri->ri_first; 2230 if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER) { 2231#ifdef TULIP_DEBUG 2232 sc->tulip_dbg.dbg_rxintrs++; 2233 sc->tulip_dbg.dbg_rxpktsperintr[cnt]++; 2234#endif 2235 return; 2236 } 2237 total_len++; 2238 } 2239 2240 /* 2241 * Dequeue the first buffer for the start of the packet. Hopefully this 2242 * will be the only one we need to dequeue. However, if the packet consumed 2243 * multiple descriptors, then we need to dequeue those buffers and chain to 2244 * the starting mbuf. All buffers but the last buffer have the same length 2245 * so we can set that now. (we add to last_offset instead of multiplying 2246 * since we normally won't go into the loop and thereby saving a ourselves 2247 * from doing a multiplication by 0 in the normal case). 2248 */ 2249 IF_DEQUEUE(&sc->tulip_rxq, ms); 2250 for (me = ms; total_len > 0; total_len--) { 2251 me->m_len = TULIP_RX_BUFLEN; 2252 last_offset += TULIP_RX_BUFLEN; 2253 IF_DEQUEUE(&sc->tulip_rxq, me->m_next); 2254 me = me->m_next; 2255 } 2256 2257 /* 2258 * Now get the size of received packet (minus the CRC). 2259 */ 2260 total_len = ((eop->d_status >> 16) & 0x7FFF) - 4; 2261 if ((eop->d_status & TULIP_DSTS_ERRSUM) == 0 2262#ifdef BIG_PACKET 2263 || (total_len <= sc->tulip_if.if_mtu + sizeof(struct ether_header) && 2264 (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxRUNT| 2265 TULIP_DSTS_RxCOLLSEEN|TULIP_DSTS_RxBADCRC| 2266 TULIP_DSTS_RxOVERFLOW)) == 0) 2267#endif 2268 ) { 2269 me->m_len = total_len - last_offset; 2270 eh = *mtod(ms, struct ether_header *); 2271#if NBPFILTER > 0 2272 if (sc->tulip_bpf != NULL) 2273 if (me == ms) 2274 TULIP_BPF_TAP(sc, mtod(ms, caddr_t), total_len); 2275 else 2276 TULIP_BPF_MTAP(sc, ms); 2277#endif 2278 if ((sc->tulip_if.if_flags & IFF_PROMISC) 2279 && (eh.ether_dhost[0] & 1) == 0 2280 && !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_ac.ac_enaddr)) 2281 goto next; 2282 accept = 1; 2283 sc->tulip_flags |= TULIP_RXACT; 2284 total_len -= sizeof(struct ether_header); 2285 } else { 2286 ifp->if_ierrors++; 2287 if (eop->d_status & (TULIP_DSTS_RxBADLENGTH|TULIP_DSTS_RxOVERFLOW|TULIP_DSTS_RxWATCHDOG)) { 2288 sc->tulip_dot3stats.dot3StatsInternalMacReceiveErrors++; 2289 } else { 2290 const char *error = NULL; 2291 if (eop->d_status & TULIP_DSTS_RxTOOLONG) { 2292 sc->tulip_dot3stats.dot3StatsFrameTooLongs++; 2293 error = "frame too long"; 2294 } 2295 if (eop->d_status & TULIP_DSTS_RxBADCRC) { 2296 if (eop->d_status & TULIP_DSTS_RxDRBBLBIT) { 2297 sc->tulip_dot3stats.dot3StatsAlignmentErrors++; 2298 error = "alignment error"; 2299 } else { 2300 sc->tulip_dot3stats.dot3StatsFCSErrors++; 2301 error = "bad crc"; 2302 } 2303 } 2304 if (error != NULL && (sc->tulip_flags & TULIP_NOMESSAGES) == 0) { 2305 printf(TULIP_PRINTF_FMT ": receive: " TULIP_EADDR_FMT ": %s\n", 2306 TULIP_PRINTF_ARGS, 2307 TULIP_EADDR_ARGS(mtod(ms, u_char *) + 6), 2308 error); 2309 sc->tulip_flags |= TULIP_NOMESSAGES; 2310 } 2311 } 2312 } 2313 next: 2314#ifdef TULIP_DEBUG 2315 cnt++; 2316#endif 2317 ifp->if_ipackets++; 2318 if (++eop == ri->ri_last) 2319 eop = ri->ri_first; 2320 ri->ri_nextin = eop; 2321 queue_mbuf: 2322 /* 2323 * Either we are priming the TULIP with mbufs (m == NULL) 2324 * or we are about to accept an mbuf for the upper layers 2325 * so we need to allocate an mbuf to replace it. If we 2326 * can't replace it, send up it anyways. This may cause 2327 * us to drop packets in the future but that's better than 2328 * being caught in livelock. 2329 * 2330 * Note that if this packet crossed multiple descriptors 2331 * we don't even try to reallocate all the mbufs here. 2332 * Instead we rely on the test of the beginning of 2333 * the loop to refill for the extra consumed mbufs. 2334 */ 2335 if (accept || ms == NULL) { 2336 struct mbuf *m0; 2337 MGETHDR(m0, M_DONTWAIT, MT_DATA); 2338 if (m0 != NULL) { 2339#if defined(TULIP_COPY_RXDATA) 2340 if (!accept || total_len >= MHLEN) { 2341#endif 2342 MCLGET(m0, M_DONTWAIT); 2343 if ((m0->m_flags & M_EXT) == 0) { 2344 m_freem(m0); 2345 m0 = NULL; 2346 } 2347#if defined(TULIP_COPY_RXDATA) 2348 } 2349#endif 2350 } 2351 if (accept) { 2352#if defined(__bsdi__) 2353 eh.ether_type = ntohs(eh.ether_type); 2354#endif 2355#if !defined(TULIP_COPY_RXDATA) 2356 ms->m_data += sizeof(struct ether_header); 2357 ms->m_len -= sizeof(struct ether_header); 2358 ms->m_pkthdr.len = total_len; 2359 ms->m_pkthdr.rcvif = ifp; 2360 ether_input(ifp, &eh, ms); 2361#else 2362#ifdef BIG_PACKET 2363#error BIG_PACKET is incompatible with TULIP_COPY_RXDATA 2364#endif 2365 if (ms == me) 2366 bcopy(mtod(ms, caddr_t) + sizeof(struct ether_header), 2367 mtod(m0, caddr_t), total_len); 2368 else 2369 m_copydata(ms, 0, total_len, mtod(m0, caddr_t)); 2370 m0->m_len = m0->m_pkthdr.len = total_len; 2371 m0->m_pkthdr.rcvif = ifp; 2372 ether_input(ifp, &eh, m0); 2373 m0 = ms; 2374#endif 2375 } 2376 ms = m0; 2377 } 2378 if (ms == NULL) { 2379 /* 2380 * Couldn't allocate a new buffer. Don't bother 2381 * trying to replenish the receive queue. 2382 */ 2383 fillok = 0; 2384 sc->tulip_flags |= TULIP_RXBUFSLOW; 2385#ifdef TULIP_DEBUG 2386 sc->tulip_dbg.dbg_rxlowbufs++; 2387#endif 2388 continue; 2389 } 2390 /* 2391 * Now give the buffer(s) to the TULIP and save in our 2392 * receive queue. 2393 */ 2394 do { 2395 ri->ri_nextout->d_length1 = TULIP_RX_BUFLEN; 2396 ri->ri_nextout->d_addr1 = TULIP_KVATOPHYS(sc, mtod(ms, caddr_t)); 2397 ri->ri_nextout->d_status = TULIP_DSTS_OWNER; 2398 if (++ri->ri_nextout == ri->ri_last) 2399 ri->ri_nextout = ri->ri_first; 2400 me = ms->m_next; 2401 ms->m_next = NULL; 2402 IF_ENQUEUE(&sc->tulip_rxq, ms); 2403 } while ((ms = me) != NULL); 2404 2405 if (sc->tulip_rxq.ifq_len == TULIP_RXQ_TARGET) 2406 sc->tulip_flags &= ~TULIP_RXBUFSLOW; 2407 } 2408} 2409 2410static int 2411tulip_tx_intr( 2412 tulip_softc_t * const sc) 2413{ 2414 tulip_ringinfo_t * const ri = &sc->tulip_txinfo; 2415 struct mbuf *m; 2416 int xmits = 0; 2417 2418 while (ri->ri_free < ri->ri_max) { 2419 if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER) 2420 break; 2421 2422 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxLASTSEG) { 2423 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxSETUPPKT) { 2424 /* 2425 * We've just finished processing a setup packet. 2426 * Mark that we can finished it. If there's not 2427 * another pending, startup the TULIP receiver. 2428 * Make sure we ack the RXSTOPPED so we won't get 2429 * an abormal interrupt indication. 2430 */ 2431 sc->tulip_flags &= ~TULIP_DOINGSETUP; 2432 if ((sc->tulip_flags & TULIP_WANTSETUP) == 0 2433 && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) { 2434 tulip_rx_intr(sc); 2435 sc->tulip_cmdmode |= TULIP_CMD_RXRUN; 2436 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED; 2437 TULIP_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED); 2438 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 2439 TULIP_CSR_WRITE(sc, csr_intr, sc->tulip_intrmask); 2440 } 2441 } else { 2442 tulip_desc_t * eop = ri->ri_nextin; 2443 IF_DEQUEUE(&sc->tulip_txq, m); 2444 m_freem(m); 2445 xmits++; 2446 if (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) { 2447 if ((eop->d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxEXCCOLL)) == 0) 2448 sc->tulip_flags |= TULIP_TXPROBE_OK; 2449 (*sc->tulip_boardsw->bd_media_select)(sc); 2450 if (sc->tulip_chipid == TULIP_DC21041) 2451 TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status)); 2452 } else { 2453 if (eop->d_status & TULIP_DSTS_ERRSUM) { 2454 sc->tulip_if.if_oerrors++; 2455 if (eop->d_status & TULIP_DSTS_TxEXCCOLL) 2456 sc->tulip_dot3stats.dot3StatsExcessiveCollisions++; 2457 if (eop->d_status & TULIP_DSTS_TxLATECOLL) 2458 sc->tulip_dot3stats.dot3StatsLateCollisions++; 2459 if (eop->d_status & (TULIP_DSTS_TxNOCARR|TULIP_DSTS_TxCARRLOSS)) 2460 sc->tulip_dot3stats.dot3StatsCarrierSenseErrors++; 2461 if (eop->d_status & (TULIP_DSTS_TxUNDERFLOW|TULIP_DSTS_TxBABBLE)) 2462 sc->tulip_dot3stats.dot3StatsInternalMacTransmitErrors++; 2463 } else { 2464 tulip_uint32_t collisions = 2465 (eop->d_status & TULIP_DSTS_TxCOLLMASK) 2466 >> TULIP_DSTS_V_TxCOLLCNT; 2467 sc->tulip_if.if_collisions += collisions; 2468 if (collisions == 1) 2469 sc->tulip_dot3stats.dot3StatsSingleCollisionFrames++; 2470 else if (collisions > 1) 2471 sc->tulip_dot3stats.dot3StatsMultipleCollisionFrames++; 2472 else if (eop->d_status & TULIP_DSTS_TxDEFERRED) 2473 sc->tulip_dot3stats.dot3StatsDeferredTransmissions++; 2474 /* 2475 * SQE is only valid for 10baseT/BNC/AUI when not 2476 * running in full-duplex. In order to speed up the 2477 * test, the corresponding bit in tulip_flags needs to 2478 * set as well to get us to count SQE Test Errors. 2479 */ 2480 if (eop->d_status & TULIP_DSTS_TxNOHRTBT & sc->tulip_flags) 2481 sc->tulip_dot3stats.dot3StatsSQETestErrors++; 2482 } 2483 } 2484 } 2485 } 2486 2487 if (++ri->ri_nextin == ri->ri_last) 2488 ri->ri_nextin = ri->ri_first; 2489 ri->ri_free++; 2490 sc->tulip_if.if_flags &= ~IFF_OACTIVE; 2491 } 2492 /* 2493 * If nothing left to transmit, disable the timer. 2494 * Else if progress, reset the timer back to 2 ticks. 2495 */ 2496 if (ri->ri_free == ri->ri_max) 2497 sc->tulip_txtimer = 0; 2498 else if (xmits > 0) 2499 sc->tulip_txtimer = 2; 2500 sc->tulip_if.if_opackets += xmits; 2501 return xmits; 2502} 2503 2504static ifnet_ret_t 2505tulip_ifstart( 2506 struct ifnet * const ifp) 2507{ 2508 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); 2509 struct ifqueue * const ifq = &ifp->if_snd; 2510 tulip_ringinfo_t * const ri = &sc->tulip_txinfo; 2511 struct mbuf *m, *m0, *next_m0; 2512 2513 if ((ifp->if_flags & IFF_RUNNING) == 0 2514 && (sc->tulip_flags & TULIP_TXPROBE_ACTIVE) == 0) 2515 return; 2516 2517 for (;;) { 2518 tulip_desc_t *eop, *nextout; 2519 int segcnt, free, recopy; 2520 tulip_uint32_t d_status; 2521 2522 if (sc->tulip_flags & TULIP_WANTSETUP) { 2523 if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) { 2524 ifp->if_flags |= IFF_OACTIVE; 2525 return; 2526 } 2527 bcopy(sc->tulip_setupdata, sc->tulip_setupbuf, 2528 sizeof(sc->tulip_setupbuf)); 2529 sc->tulip_flags &= ~TULIP_WANTSETUP; 2530 sc->tulip_flags |= TULIP_DOINGSETUP; 2531 ri->ri_free--; 2532 ri->ri_nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN; 2533 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG 2534 |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR; 2535 if (sc->tulip_flags & TULIP_WANTHASH) 2536 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxHASHFILT; 2537 ri->ri_nextout->d_length1 = sizeof(sc->tulip_setupbuf); 2538 ri->ri_nextout->d_addr1 = TULIP_KVATOPHYS(sc, sc->tulip_setupbuf); 2539 ri->ri_nextout->d_length2 = 0; 2540 ri->ri_nextout->d_addr2 = 0; 2541 ri->ri_nextout->d_status = TULIP_DSTS_OWNER; 2542 TULIP_CSR_WRITE(sc, csr_txpoll, 1); 2543 /* 2544 * Advance the ring for the next transmit packet. 2545 */ 2546 if (++ri->ri_nextout == ri->ri_last) 2547 ri->ri_nextout = ri->ri_first; 2548 /* 2549 * Make sure the next descriptor is owned by us since it 2550 * may have been set up above if we ran out of room in the 2551 * ring. 2552 */ 2553 ri->ri_nextout->d_status = 0; 2554 } 2555 2556 IF_DEQUEUE(ifq, m); 2557 if (m == NULL) 2558 break; 2559 2560 /* 2561 * Now we try to fill in our transmit descriptors. This is 2562 * a bit reminiscent of going on the Ark two by two 2563 * since each descriptor for the TULIP can describe 2564 * two buffers. So we advance through packet filling 2565 * each of the two entries at a time to to fill each 2566 * descriptor. Clear the first and last segment bits 2567 * in each descriptor (actually just clear everything 2568 * but the end-of-ring or chain bits) to make sure 2569 * we don't get messed up by previously sent packets. 2570 * 2571 * We may fail to put the entire packet on the ring if 2572 * there is either not enough ring entries free or if the 2573 * packet has more than MAX_TXSEG segments. In the former 2574 * case we will just wait for the ring to empty. In the 2575 * latter case we have to recopy. 2576 */ 2577 d_status = 0; 2578 recopy = 0; 2579 eop = nextout = ri->ri_nextout; 2580 m0 = m; 2581 segcnt = 0; 2582 free = ri->ri_free; 2583 do { 2584 int len = m0->m_len; 2585 caddr_t addr = mtod(m0, caddr_t); 2586 unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1)); 2587 2588 next_m0 = m0->m_next; 2589 while (len > 0) { 2590 unsigned slen = min(len, clsize); 2591#ifdef BIG_PACKET 2592 int partial = 0; 2593 if (slen >= 2048) 2594 slen = 2040, partial = 1; 2595#endif 2596 segcnt++; 2597 if (segcnt > TULIP_MAX_TXSEG) { 2598 recopy = 1; 2599 next_m0 = NULL; /* to break out of outside loop */ 2600 break; 2601 } 2602 if (segcnt & 1) { 2603 if (--free == 0) { 2604 /* 2605 * There's no more room but since nothing 2606 * has been committed at this point, just 2607 * show output is active, put back the 2608 * mbuf and return. 2609 */ 2610 ifp->if_flags |= IFF_OACTIVE; 2611 IF_PREPEND(ifq, m); 2612 return; 2613 } 2614 eop = nextout; 2615 if (++nextout == ri->ri_last) 2616 nextout = ri->ri_first; 2617 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN; 2618 eop->d_status = d_status; 2619 eop->d_addr1 = TULIP_KVATOPHYS(sc, addr); 2620 eop->d_length1 = slen; 2621 } else { 2622 /* 2623 * Fill in second half of descriptor 2624 */ 2625 eop->d_addr2 = TULIP_KVATOPHYS(sc, addr); 2626 eop->d_length2 = slen; 2627 } 2628 d_status = TULIP_DSTS_OWNER; 2629 len -= slen; 2630 addr += slen; 2631#ifdef BIG_PACKET 2632 if (partial) 2633 continue; 2634#endif 2635 clsize = CLBYTES; 2636 } 2637 } while ((m0 = next_m0) != NULL); 2638 2639 /* 2640 * The packet exceeds the number of transmit buffer 2641 * entries that we can use for one packet, so we have 2642 * recopy it into one mbuf and then try again. 2643 */ 2644 if (recopy) { 2645 MGETHDR(m0, M_DONTWAIT, MT_DATA); 2646 if (m0 != NULL) { 2647 if (m->m_pkthdr.len > MHLEN) { 2648 MCLGET(m0, M_DONTWAIT); 2649 if ((m0->m_flags & M_EXT) == 0) { 2650 m_freem(m); 2651 m_freem(m0); 2652 continue; 2653 } 2654 } 2655 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t)); 2656 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len; 2657 IF_PREPEND(ifq, m0); 2658 } 2659 m_freem(m); 2660 continue; 2661 } 2662 2663 /* 2664 * The descriptors have been filled in. Now get ready 2665 * to transmit. 2666 */ 2667#if NBPFILTER > 0 2668 if (sc->tulip_bpf != NULL) 2669 TULIP_BPF_MTAP(sc, m); 2670#endif 2671 IF_ENQUEUE(&sc->tulip_txq, m); 2672 2673 /* 2674 * Make sure the next descriptor after this packet is owned 2675 * by us since it may have been set up above if we ran out 2676 * of room in the ring. 2677 */ 2678 nextout->d_status = 0; 2679 2680 /* 2681 * If we only used the first segment of the last descriptor, 2682 * make sure the second segment will not be used. 2683 */ 2684 if (segcnt & 1) { 2685 eop->d_addr2 = 0; 2686 eop->d_length2 = 0; 2687 } 2688 2689 /* 2690 * Mark the last and first segments, indicate we want a transmit 2691 * complete interrupt, give the descriptors to the TULIP, and tell 2692 * it to transmit! 2693 */ 2694 eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR; 2695 2696 /* 2697 * Note that ri->ri_nextout is still the start of the packet 2698 * and until we set the OWNER bit, we can still back out of 2699 * everything we have done. 2700 */ 2701 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG; 2702 ri->ri_nextout->d_status = TULIP_DSTS_OWNER; 2703 2704 /* 2705 * This advances the ring for us. 2706 */ 2707 ri->ri_nextout = nextout; 2708 ri->ri_free = free; 2709 2710 TULIP_CSR_WRITE(sc, csr_txpoll, 1); 2711 2712 if (sc->tulip_txtimer == 0) 2713 sc->tulip_txtimer = 2; 2714 } 2715 if (m != NULL) { 2716 ifp->if_flags |= IFF_OACTIVE; 2717 IF_PREPEND(ifq, m); 2718 } 2719} 2720 2721static void 2722tulip_print_abnormal_interrupt( 2723 tulip_softc_t * const sc, 2724 tulip_uint32_t csr) 2725{ 2726 const char * const *msgp = tulip_status_bits; 2727 const char *sep; 2728 2729 csr &= (1 << (sizeof(tulip_status_bits)/sizeof(tulip_status_bits[0]))) - 1; 2730 printf(TULIP_PRINTF_FMT ": abnormal interrupt:", TULIP_PRINTF_ARGS); 2731 for (sep = " "; csr != 0; csr >>= 1, msgp++) { 2732 if ((csr & 1) && *msgp != NULL) { 2733 printf("%s%s", sep, *msgp); 2734 sep = ", "; 2735 } 2736 } 2737 printf("\n"); 2738} 2739 2740static tulip_intrfunc_t 2741tulip_intr( 2742 void *arg) 2743{ 2744 tulip_softc_t * sc = (tulip_softc_t *) arg; 2745 tulip_uint32_t csr; 2746#if !defined(TULIP_VOID_INTRFUNC) 2747 int progress = 0; 2748#endif 2749 2750 do { 2751#if defined(TULIP_DEBUG) 2752 sc->tulip_dbg.dbg_intrs++; 2753#endif 2754 while ((csr = TULIP_CSR_READ(sc, csr_status)) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) { 2755#if !defined(TULIP_VOID_INTRFUNC) 2756 progress = 1; 2757#endif 2758 TULIP_CSR_WRITE(sc, csr_status, csr); 2759 2760 if (csr & TULIP_STS_SYSERROR) { 2761 sc->tulip_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT; 2762 if (sc->tulip_flags & TULIP_NOMESSAGES) { 2763 sc->tulip_flags |= TULIP_SYSTEMERROR; 2764 } else { 2765 printf(TULIP_PRINTF_FMT ": system error: %s\n", 2766 TULIP_PRINTF_ARGS, 2767 tulip_system_errors[sc->tulip_last_system_error]); 2768 } 2769 sc->tulip_flags |= TULIP_NEEDRESET; 2770 sc->tulip_system_errors++; 2771 break; 2772 } 2773 if (csr & (TULIP_STS_GPTIMEOUT|TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) { 2774#if defined(TULIP_DEBUG) 2775 sc->tulip_dbg.dbg_gpintrs++; 2776#endif 2777 if (sc->tulip_chipid == TULIP_DC21041) { 2778 (*sc->tulip_boardsw->bd_media_select)(sc); 2779 if (csr & (TULIP_STS_LINKPASS|TULIP_STS_LINKFAIL)) 2780 csr &= ~TULIP_STS_ABNRMLINTR; 2781 TULIP_CSR_WRITE(sc, csr_sia_status, TULIP_CSR_READ(sc, csr_sia_status)); 2782 } else if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) { 2783 (*sc->tulip_boardsw->bd_media_select)(sc); 2784 csr &= ~(TULIP_STS_ABNRMLINTR|TULIP_STS_GPTIMEOUT); 2785 } 2786 if ((sc->tulip_flags & (TULIP_LINKUP|TULIP_PRINTMEDIA)) == (TULIP_LINKUP|TULIP_PRINTMEDIA)) { 2787 printf(TULIP_PRINTF_FMT ": enabling %s port\n", 2788 TULIP_PRINTF_ARGS, 2789 tulip_mediums[sc->tulip_media]); 2790 sc->tulip_flags &= ~TULIP_PRINTMEDIA; 2791 } 2792 } 2793 if (csr & TULIP_STS_ABNRMLINTR) { 2794 tulip_uint32_t tmp = csr & sc->tulip_intrmask 2795 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR); 2796 if (sc->tulip_flags & TULIP_NOMESSAGES) { 2797 sc->tulip_statusbits |= tmp; 2798 } else { 2799 tulip_print_abnormal_interrupt(sc, tmp); 2800 sc->tulip_flags |= TULIP_NOMESSAGES; 2801 } 2802 TULIP_CSR_WRITE(sc, csr_command, sc->tulip_cmdmode); 2803 } 2804 if (csr & (TULIP_STS_RXINTR|TULIP_STS_RXNOBUF)) { 2805 tulip_rx_intr(sc); 2806 if (csr & TULIP_STS_RXNOBUF) 2807 sc->tulip_dot3stats.dot3StatsMissedFrames += 2808 TULIP_CSR_READ(sc, csr_missed_frames) & 0xFFFF; 2809 } 2810 if (sc->tulip_txinfo.ri_free < sc->tulip_txinfo.ri_max) { 2811 tulip_tx_intr(sc); 2812 tulip_ifstart(&sc->tulip_if); 2813 } 2814 } 2815 if (sc->tulip_flags & TULIP_NEEDRESET) { 2816 tulip_reset(sc); 2817 tulip_init(sc); 2818 } 2819 } while ((sc = sc->tulip_slaves) != NULL); 2820#if !defined(TULIP_VOID_INTRFUNC) 2821 return progress; 2822#endif 2823} 2824 2825/* 2826 * 2827 */ 2828 2829static void 2830tulip_delay_300ns( 2831 tulip_softc_t * const sc) 2832{ 2833 int idx; 2834 for (idx = (300 / 33) + 1; idx > 0; idx--) 2835 TULIP_CSR_READ(sc, csr_busmode); 2836} 2837 2838#define EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0) 2839 2840static void 2841tulip_idle_srom( 2842 tulip_softc_t * const sc) 2843{ 2844 unsigned bit, csr; 2845 2846 csr = SROMSEL ; EMIT; 2847 csr = SROMSEL | SROMRD; EMIT; 2848 csr ^= SROMCS; EMIT; 2849 csr ^= SROMCLKON; EMIT; 2850 2851 /* 2852 * Write 25 cycles of 0 which will force the SROM to be idle. 2853 */ 2854 for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) { 2855 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */ 2856 csr ^= SROMCLKON; EMIT; /* clock high; data valid */ 2857 } 2858 csr ^= SROMCLKOFF; EMIT; 2859 csr ^= SROMCS; EMIT; 2860 csr = 0; EMIT; 2861} 2862 2863 2864static void 2865tulip_read_srom( 2866 tulip_softc_t * const sc) 2867{ 2868 int idx; 2869 const unsigned bitwidth = SROM_BITWIDTH; 2870 const unsigned cmdmask = (SROMCMD_RD << bitwidth); 2871 const unsigned msb = 1 << (bitwidth + 3 - 1); 2872 unsigned lastidx = (1 << bitwidth) - 1; 2873 2874 tulip_idle_srom(sc); 2875 2876 for (idx = 0; idx <= lastidx; idx++) { 2877 unsigned lastbit, data, bits, bit, csr; 2878 csr = SROMSEL ; EMIT; 2879 csr = SROMSEL | SROMRD; EMIT; 2880 csr ^= SROMCSON; EMIT; 2881 csr ^= SROMCLKON; EMIT; 2882 2883 lastbit = 0; 2884 for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1) { 2885 const unsigned thisbit = bits & msb; 2886 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */ 2887 if (thisbit != lastbit) { 2888 csr ^= SROMDOUT; EMIT; /* clock low; invert data */ 2889 } else { 2890 EMIT; 2891 } 2892 csr ^= SROMCLKON; EMIT; /* clock high; data valid */ 2893 lastbit = thisbit; 2894 } 2895 csr ^= SROMCLKOFF; EMIT; 2896 2897 for (data = 0, bits = 0; bits < 16; bits++) { 2898 data <<= 1; 2899 csr ^= SROMCLKON; EMIT; /* clock high; data valid */ 2900 data |= TULIP_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0; 2901 csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */ 2902 } 2903 sc->tulip_rombuf[idx*2] = data & 0xFF; 2904 sc->tulip_rombuf[idx*2+1] = data >> 8; 2905 csr = SROMSEL | SROMRD; EMIT; 2906 csr = 0; EMIT; 2907 } 2908 tulip_idle_srom(sc); 2909} 2910 2911#define MII_EMIT do { TULIP_CSR_WRITE(sc, csr_srom_mii, csr); tulip_delay_300ns(sc); } while (0) 2912 2913static void 2914tulip_mii_sendbits( 2915 tulip_softc_t * const sc, 2916 unsigned data, 2917 unsigned bits) 2918{ 2919 unsigned msb = 1 << (bits - 1); 2920 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); 2921 unsigned lastbit = (csr & MII_DOUT) ? msb : 0; 2922 2923 csr |= MII_WR; MII_EMIT; /* clock low; assert write */ 2924 2925 for (; bits > 0; bits--, data <<= 1) { 2926 const unsigned thisbit = data & msb; 2927 if (thisbit != lastbit) { 2928 csr ^= MII_DOUT; MII_EMIT; /* clock low; invert data */ 2929 } 2930 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ 2931 lastbit = thisbit; 2932 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */ 2933 } 2934} 2935 2936static void 2937tulip_mii_turnaround( 2938 tulip_softc_t * const sc, 2939 unsigned cmd) 2940{ 2941 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); 2942 2943 if (cmd == MII_WRCMD) { 2944 csr |= MII_DOUT; MII_EMIT; /* clock low; change data */ 2945 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ 2946 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */ 2947 csr ^= MII_DOUT; MII_EMIT; /* clock low; change data */ 2948 } else { 2949 csr |= MII_RD; MII_EMIT; /* clock low; switch to read */ 2950 } 2951 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ 2952 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */ 2953} 2954 2955static unsigned 2956tulip_mii_readbits( 2957 tulip_softc_t * const sc) 2958{ 2959 unsigned data; 2960 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); 2961 int idx; 2962 2963 for (idx = 0, data = 0; idx < 16; idx++) { 2964 data <<= 1; /* this is NOOP on the first pass through */ 2965 csr ^= MII_CLKON; MII_EMIT; /* clock high; data valid */ 2966 if (TULIP_CSR_READ(sc, csr_srom_mii) & MII_DIN) 2967 data |= 1; 2968 csr ^= MII_CLKOFF; MII_EMIT; /* clock low; data not valid */ 2969 } 2970 csr ^= MII_RD; MII_EMIT; /* clock low; turn off read */ 2971 2972 return data; 2973} 2974 2975static unsigned 2976tulip_mii_readreg( 2977 tulip_softc_t * const sc, 2978 unsigned devaddr, 2979 unsigned regno) 2980{ 2981 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); 2982 unsigned data; 2983 2984 csr &= ~(MII_RD|MII_CLK); MII_EMIT; 2985 tulip_mii_sendbits(sc, MII_PREAMBLE, 32); 2986 tulip_mii_sendbits(sc, MII_RDCMD, 8); 2987 tulip_mii_sendbits(sc, devaddr, 5); 2988 tulip_mii_sendbits(sc, regno, 5); 2989 tulip_mii_turnaround(sc, MII_RDCMD); 2990 2991 data = tulip_mii_readbits(sc); 2992#ifdef TULIP_DEBUG 2993 sc->tulip_dbg.dbg_phyregs[regno][0] = data; 2994 sc->tulip_dbg.dbg_phyregs[regno][1]++; 2995#endif 2996 return data; 2997} 2998 2999static void 3000tulip_mii_writereg( 3001 tulip_softc_t * const sc, 3002 unsigned devaddr, 3003 unsigned regno, 3004 unsigned data) 3005{ 3006 unsigned csr = TULIP_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK); 3007 csr &= ~(MII_RD|MII_CLK); MII_EMIT; 3008 tulip_mii_sendbits(sc, MII_PREAMBLE, 32); 3009 tulip_mii_sendbits(sc, MII_WRCMD, 8); 3010 tulip_mii_sendbits(sc, devaddr, 5); 3011 tulip_mii_sendbits(sc, regno, 5); 3012 tulip_mii_turnaround(sc, MII_WRCMD); 3013 tulip_mii_sendbits(sc, data, 16); 3014#ifdef TULIP_DEBUG 3015 sc->tulip_dbg.dbg_phyregs[regno][2] = data; 3016 sc->tulip_dbg.dbg_phyregs[regno][3]++; 3017#endif 3018} 3019 3020#define tulip_mchash(mca) (tulip_crc32(mca, 6) & 0x1FF) 3021#define tulip_srom_crcok(databuf) ( \ 3022 ((tulip_crc32(databuf, 126) & 0xFFFF) ^ 0xFFFF)== \ 3023 ((databuf)[126] | ((databuf)[127] << 8))) 3024 3025static unsigned 3026tulip_crc32( 3027 const unsigned char *databuf, 3028 size_t datalen) 3029{ 3030 u_int idx, bit, data, crc = 0xFFFFFFFFUL; 3031 3032 for (idx = 0; idx < datalen; idx++) 3033 for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) 3034 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0); 3035 return crc; 3036} 3037 3038static void 3039tulip_identify_smc_nic( 3040 tulip_softc_t *sc) 3041{ 3042 tulip_uint32_t id1, id2, ei; 3043 int auibnc = 0, utp = 0; 3044 char *cp; 3045 3046 if (sc->tulip_chipid == TULIP_DC21041) 3047 return; 3048 if (sc->tulip_chipid == TULIP_DC21140) { 3049 sc->tulip_boardsw = &tulip_dc21140_smc9332_boardsw; 3050 return; 3051 } 3052 id1 = sc->tulip_rombuf[0x60] | (sc->tulip_rombuf[0x61] << 8); 3053 id2 = sc->tulip_rombuf[0x62] | (sc->tulip_rombuf[0x63] << 8); 3054 ei = sc->tulip_rombuf[0x66] | (sc->tulip_rombuf[0x67] << 8); 3055 3056 strcpy(sc->tulip_boardidbuf, "SMC 8432"); 3057 cp = &sc->tulip_boardidbuf[8]; 3058 if ((id1 & 1) == 0) 3059 *cp++ = 'B', auibnc = 1; 3060 if ((id1 & 0xFF) > 0x32) 3061 *cp++ = 'T', utp = 1; 3062 if ((id1 & 0x4000) == 0) 3063 *cp++ = 'A', auibnc = 1; 3064 if (id2 == 0x15) { 3065 sc->tulip_boardidbuf[7] = '4'; 3066 *cp++ = '-'; 3067 *cp++ = 'C'; 3068 *cp++ = 'H'; 3069 *cp++ = (ei ? '2' : '1'); 3070 } 3071 *cp++ = ' '; 3072 *cp = '\0'; 3073 if (utp && !auibnc) 3074 sc->tulip_boardsw = &tulip_dc21040_10baset_only_boardsw; 3075 else if (!utp && auibnc) 3076 sc->tulip_boardsw = &tulip_dc21040_auibnc_only_boardsw; 3077} 3078 3079/* 3080 * This deals with the vagaries of the address roms and the 3081 * brain-deadness that various vendors commit in using them. 3082 */ 3083static int 3084tulip_read_macaddr( 3085 tulip_softc_t *sc) 3086{ 3087 int cksum, rom_cksum, idx; 3088 tulip_uint32_t csr; 3089 unsigned char tmpbuf[8]; 3090 static const u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA }; 3091 3092 if (sc->tulip_chipid == TULIP_DC21040) { 3093 TULIP_CSR_WRITE(sc, csr_enetrom, 1); 3094 for (idx = 0; idx < sizeof(sc->tulip_rombuf); idx++) { 3095 int cnt = 0; 3096 while (((csr = TULIP_CSR_READ(sc, csr_enetrom)) & 0x80000000L) && cnt < 10000) 3097 cnt++; 3098 sc->tulip_rombuf[idx] = csr & 0xFF; 3099 } 3100 sc->tulip_boardsw = &tulip_dc21040_boardsw; 3101#if defined(TULIP_EISA) 3102 } else if (sc->tulip_chipid == TULIP_DE425) { 3103 int cnt; 3104 for (idx = 0, cnt = 0; idx < sizeof(testpat) && cnt < 32; cnt++) { 3105 tmpbuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom); 3106 if (tmpbuf[idx] == testpat[idx]) 3107 ++idx; 3108 else 3109 idx = 0; 3110 } 3111 for (idx = 0; idx < 32; idx++) 3112 sc->tulip_rombuf[idx] = TULIP_CSR_READBYTE(sc, csr_enetrom); 3113 sc->tulip_boardsw = &tulip_dc21040_boardsw; 3114#endif /* TULIP_EISA */ 3115 } else { 3116 int new_srom_fmt = 0; 3117 /* 3118 * Thankfully all DC21041's act the same. 3119 * Assume all DC21140 board are compatible with the 3120 * DEC 10/100 evaluation board. Not really valid but 3121 * it's the best we can do until every one switches to 3122 * the new SROM format. 3123 */ 3124 if (sc->tulip_chipid == TULIP_DC21041) 3125 sc->tulip_boardsw = &tulip_dc21041_boardsw; 3126 else 3127 sc->tulip_boardsw = &tulip_dc21140_eb_boardsw; 3128 tulip_read_srom(sc); 3129 if (tulip_srom_crcok(sc->tulip_rombuf)) { 3130 /* 3131 * SROM CRC is valid therefore it must be in the 3132 * new format. 3133 */ 3134 new_srom_fmt = 1; 3135 } else if (sc->tulip_rombuf[126] == 0xff && sc->tulip_rombuf[127] == 0xFF) { 3136 /* 3137 * No checksum is present. See if the SROM id checks out; 3138 * the first 18 bytes should be 0 followed by a 1 followed 3139 * by the number of adapters (which we don't deal with yet). 3140 */ 3141 for (idx = 0; idx < 18; idx++) { 3142 if (sc->tulip_rombuf[idx] != 0) 3143 break; 3144 } 3145 if (idx == 18 && sc->tulip_rombuf[18] == 1 && sc->tulip_rombuf[19] != 0) 3146 new_srom_fmt = 2; 3147 } 3148 if (new_srom_fmt) { 3149 int copy_name = 0; 3150 /* 3151 * New SROM format. Copy out the Ethernet address. 3152 * If it contains a DE500-XA string, then it must be 3153 * a DE500-XA. 3154 */ 3155 bcopy(sc->tulip_rombuf + 20, sc->tulip_hwaddr, 6); 3156 if (bcmp(sc->tulip_rombuf + 29, "DE500-XA", 8) == 0) { 3157 sc->tulip_boardsw = &tulip_dc21140_de500xa_boardsw; 3158 copy_name = 1; 3159 } else if (bcmp(sc->tulip_rombuf + 29, "DE500-AA", 8) == 0) { 3160 sc->tulip_boardsw = &tulip_dc21140_de500aa_boardsw; 3161 copy_name = 1; 3162 } else if (bcmp(sc->tulip_rombuf + 29, "DE450", 5) == 0) { 3163 copy_name = 1; 3164 } 3165 if (copy_name) { 3166 bcopy(sc->tulip_rombuf + 29, sc->tulip_boardidbuf, 8); 3167 sc->tulip_boardidbuf[8] = ' '; 3168 sc->tulip_boardid = sc->tulip_boardidbuf; 3169 } 3170 if (sc->tulip_boardsw == NULL) 3171 return -6; 3172 goto check_oui; 3173 } 3174 } 3175 3176 3177 if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) { 3178 /* 3179 * Some folks don't use the standard ethernet rom format 3180 * but instead just put the address in the first 6 bytes 3181 * of the rom and let the rest be all 0xffs. (Can we say 3182 * ZNYX???) (well sometimes they put in a checksum so we'll 3183 * start at 8). 3184 */ 3185 for (idx = 8; idx < 32; idx++) { 3186 if (sc->tulip_rombuf[idx] != 0xFF) 3187 return -4; 3188 } 3189 /* 3190 * Make sure the address is not multicast or locally assigned 3191 * that the OUI is not 00-00-00. 3192 */ 3193 if ((sc->tulip_rombuf[0] & 3) != 0) 3194 return -4; 3195 if (sc->tulip_rombuf[0] == 0 && sc->tulip_rombuf[1] == 0 3196 && sc->tulip_rombuf[2] == 0) 3197 return -4; 3198 bcopy(sc->tulip_rombuf, sc->tulip_hwaddr, 6); 3199 sc->tulip_flags |= TULIP_ROMOK; 3200 goto check_oui; 3201 } else { 3202 /* 3203 * A number of makers of multiport boards (ZNYX and Cogent) 3204 * only put on one address ROM on their DC21040 boards. So 3205 * if the ROM is all zeros and this is a DC21040, look at the 3206 * previous configured boards (as long as they are on the same 3207 * PCI bus and the bus number is non-zero) until we find the 3208 * master board with address ROM. We then use its address ROM 3209 * as the base for this board. (we add our relative board 3210 * to the last byte of its address). 3211 */ 3212 if (sc->tulip_chipid == TULIP_DC21040 /* && sc->tulip_bus != 0 XXX */) { 3213 for (idx = 0; idx < 32; idx++) { 3214 if (sc->tulip_rombuf[idx] != 0) 3215 break; 3216 } 3217 if (idx == 32) { 3218 int root_unit; 3219 tulip_softc_t *root_sc = NULL; 3220 for (root_unit = sc->tulip_unit - 1; root_unit >= 0; root_unit--) { 3221 root_sc = TULIP_UNIT_TO_SOFTC(root_unit); 3222 if (root_sc == NULL || (root_sc->tulip_flags & (TULIP_ROMOK|TULIP_SLAVEDROM)) == TULIP_ROMOK) 3223 break; 3224 root_sc = NULL; 3225 } 3226 if (root_sc != NULL 3227 /* && root_sc->tulip_bus == sc->tulip_bus XXX */) { 3228 bcopy(root_sc->tulip_hwaddr, sc->tulip_hwaddr, 6); 3229 sc->tulip_hwaddr[5] += sc->tulip_unit - root_sc->tulip_unit; 3230 sc->tulip_flags |= TULIP_SLAVEDROM; 3231 if (root_sc->tulip_boardsw->bd_type == TULIP_DC21040_ZX314_MASTER) { 3232 sc->tulip_boardsw = &tulip_dc21040_zx314_slave_boardsw; 3233 /* 3234 * Now for a truly disgusting kludge: all 4 DC21040s on 3235 * the ZX314 share the same INTA line so the mapping 3236 * setup by the BIOS on the PCI bridge is worthless. 3237 * Rather than reprogramming the value in the config 3238 * register, we will handle this internally. 3239 */ 3240 sc->tulip_slaves = root_sc->tulip_slaves; 3241 root_sc->tulip_slaves = sc; 3242 sc->tulip_flags |= TULIP_SLAVEDINTR; 3243 } 3244 return 0; 3245 } 3246 } 3247 } 3248 } 3249 3250 /* 3251 * This is the standard DEC address ROM test. 3252 */ 3253 3254 if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0) 3255 return -3; 3256 3257 tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14]; 3258 tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12]; 3259 tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10]; 3260 tmpbuf[6] = sc->tulip_rombuf[9]; tmpbuf[7] = sc->tulip_rombuf[8]; 3261 if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0) 3262 return -2; 3263 3264 bcopy(sc->tulip_rombuf, sc->tulip_hwaddr, 6); 3265 3266 cksum = *(u_int16_t *) &sc->tulip_hwaddr[0]; 3267 cksum *= 2; 3268 if (cksum > 65535) cksum -= 65535; 3269 cksum += *(u_int16_t *) &sc->tulip_hwaddr[2]; 3270 if (cksum > 65535) cksum -= 65535; 3271 cksum *= 2; 3272 if (cksum > 65535) cksum -= 65535; 3273 cksum += *(u_int16_t *) &sc->tulip_hwaddr[4]; 3274 if (cksum >= 65535) cksum -= 65535; 3275 3276 rom_cksum = *(u_int16_t *) &sc->tulip_rombuf[6]; 3277 3278 if (cksum != rom_cksum) 3279 return -1; 3280 3281 check_oui: 3282 /* 3283 * Check for various boards based on OUI. Did I say braindead? 3284 */ 3285 if (sc->tulip_hwaddr[0] == TULIP_OUI_COGENT_0 3286 && sc->tulip_hwaddr[1] == TULIP_OUI_COGENT_1 3287 && sc->tulip_hwaddr[2] == TULIP_OUI_COGENT_2) { 3288 if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) { 3289 if (sc->tulip_rombuf[32] == TULIP_COGENT_EM100_ID) 3290 sc->tulip_boardsw = &tulip_dc21140_cogent_em100_boardsw; 3291 } 3292 } else if (sc->tulip_hwaddr[0] == TULIP_OUI_ZNYX_0 3293 && sc->tulip_hwaddr[1] == TULIP_OUI_ZNYX_1 3294 && sc->tulip_hwaddr[2] == TULIP_OUI_ZNYX_2) { 3295 if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) { 3296 /* this at least works for the zx342 from Znyx */ 3297 sc->tulip_boardsw = &tulip_dc21140_znyx_zx34x_boardsw; 3298 } else if (sc->tulip_chipid == TULIP_DC21040 3299 && (sc->tulip_hwaddr[3] & ~3) == 0xF0 3300 && (sc->tulip_hwaddr[5] & 3) == 0) { 3301 sc->tulip_boardsw = &tulip_dc21040_zx314_master_boardsw; 3302 } 3303 } else if (sc->tulip_hwaddr[0] == TULIP_OUI_SMC_0 3304 && sc->tulip_hwaddr[1] == TULIP_OUI_SMC_1 3305 && sc->tulip_hwaddr[2] == TULIP_OUI_SMC_2) { 3306 tulip_identify_smc_nic(sc); 3307 } 3308 3309 if (sc->tulip_boardidbuf[0] != '\0') 3310 sc->tulip_boardid = sc->tulip_boardidbuf; 3311 else 3312 sc->tulip_boardid = sc->tulip_boardsw->bd_description; 3313 sc->tulip_flags |= TULIP_ROMOK; 3314 return 0; 3315} 3316 3317static void 3318tulip_addr_filter( 3319 tulip_softc_t * const sc) 3320{ 3321 tulip_uint32_t *sp = sc->tulip_setupdata; 3322 struct ether_multistep step; 3323 struct ether_multi *enm; 3324 int i = 0; 3325 3326 sc->tulip_flags &= ~TULIP_WANTHASH; 3327 sc->tulip_flags |= TULIP_WANTSETUP; 3328 sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; 3329 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; 3330 if (sc->tulip_ac.ac_multicnt > 14) { 3331 unsigned hash; 3332 /* 3333 * If we have more than 14 multicasts, we have 3334 * go into hash perfect mode (512 bit multicast 3335 * hash and one perfect hardware). 3336 */ 3337 3338 bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata)); 3339 hash = tulip_mchash(etherbroadcastaddr); 3340 sp[hash >> 4] |= 1 << (hash & 0xF); 3341 ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); 3342 while (enm != NULL) { 3343 hash = tulip_mchash(enm->enm_addrlo); 3344 sp[hash >> 4] |= 1 << (hash & 0xF); 3345 ETHER_NEXT_MULTI(step, enm); 3346 } 3347 sc->tulip_flags |= TULIP_WANTHASH; 3348 sp[39] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0]; 3349 sp[40] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1]; 3350 sp[41] = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2]; 3351 } else { 3352 /* 3353 * Else can get perfect filtering for 16 addresses. 3354 */ 3355 ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); 3356 for (; enm != NULL; i++) { 3357 *sp++ = ((u_int16_t *) enm->enm_addrlo)[0]; 3358 *sp++ = ((u_int16_t *) enm->enm_addrlo)[1]; 3359 *sp++ = ((u_int16_t *) enm->enm_addrlo)[2]; 3360 ETHER_NEXT_MULTI(step, enm); 3361 } 3362 /* 3363 * Add the broadcast address. 3364 */ 3365 i++; 3366 *sp++ = 0xFFFF; 3367 *sp++ = 0xFFFF; 3368 *sp++ = 0xFFFF; 3369 /* 3370 * Pad the rest with our hardware address 3371 */ 3372 for (; i < 16; i++) { 3373 *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[0]; 3374 *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[1]; 3375 *sp++ = ((u_int16_t *) sc->tulip_ac.ac_enaddr)[2]; 3376 } 3377 } 3378} 3379 3380static int 3381tulip_ifioctl( 3382 struct ifnet * const ifp, 3383 ioctl_cmd_t cmd, 3384 caddr_t data) 3385{ 3386 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); 3387 struct ifaddr *ifa = (struct ifaddr *)data; 3388 struct ifreq *ifr = (struct ifreq *) data; 3389 int s, error = 0; 3390 3391 s = splimp(); 3392 3393 switch (cmd) { 3394 case SIOCSIFADDR: { 3395 ifp->if_flags |= IFF_UP; 3396 switch(ifa->ifa_addr->sa_family) { 3397#ifdef INET 3398 case AF_INET: { 3399 tulip_init(sc); 3400 arp_ifinit(&sc->tulip_ac, ifa); 3401 break; 3402 } 3403#endif /* INET */ 3404 3405#ifdef NS 3406 /* 3407 * This magic copied from if_is.c; I don't use XNS, 3408 * so I have no way of telling if this actually 3409 * works or not. 3410 */ 3411 case AF_NS: { 3412 struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 3413 if (ns_nullhost(*ina)) { 3414 ina->x_host = *(union ns_host *)(sc->tulip_ac.ac_enaddr); 3415 } else { 3416 ifp->if_flags &= ~IFF_RUNNING; 3417 bcopy((caddr_t)ina->x_host.c_host, 3418 (caddr_t)sc->tulip_ac.ac_enaddr, 3419 sizeof sc->tulip_ac.ac_enaddr); 3420 } 3421 tulip_init(sc); 3422 break; 3423 } 3424#endif /* NS */ 3425 3426 default: { 3427 tulip_init(sc); 3428 break; 3429 } 3430 } 3431 break; 3432 } 3433 case SIOCGIFADDR: { 3434 bcopy((caddr_t) sc->tulip_ac.ac_enaddr, 3435 (caddr_t) ((struct sockaddr *)&ifr->ifr_data)->sa_data, 3436 6); 3437 break; 3438 } 3439 3440 case SIOCSIFFLAGS: { 3441 /* 3442 * Changing the connection forces a reset. 3443 */ 3444 if (sc->tulip_flags & TULIP_ALTPHYS) { 3445 if ((ifp->if_flags & IFF_ALTPHYS) == 0) { 3446 sc->tulip_flags |= TULIP_NEEDRESET; 3447 } 3448 } else { 3449 if (ifp->if_flags & IFF_ALTPHYS) { 3450 sc->tulip_flags |= TULIP_NEEDRESET; 3451 } 3452 } 3453 if (sc->tulip_flags & TULIP_NEEDRESET) { 3454 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 3455 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 3456 sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TXPROBE_OK|TULIP_WANTRXACT); 3457 tulip_reset(sc); 3458 } 3459 tulip_init(sc); 3460 break; 3461 } 3462 3463 case SIOCADDMULTI: 3464 case SIOCDELMULTI: { 3465 /* 3466 * Update multicast listeners 3467 */ 3468 if (cmd == SIOCADDMULTI) 3469 error = ether_addmulti(ifr, &sc->tulip_ac); 3470 else 3471 error = ether_delmulti(ifr, &sc->tulip_ac); 3472 3473 if (error == ENETRESET) { 3474 tulip_addr_filter(sc); /* reset multicast filtering */ 3475 tulip_init(sc); 3476 error = 0; 3477 } 3478 break; 3479 } 3480#if defined(SIOCSIFMTU) 3481#if !defined(ifr_mtu) 3482#define ifr_mtu ifr_metric 3483#endif 3484 case SIOCSIFMTU: 3485 /* 3486 * Set the interface MTU. 3487 */ 3488 if (ifr->ifr_mtu > ETHERMTU 3489#ifdef BIG_PACKET 3490 && sc->tulip_chipid != TULIP_DC21140 3491 && sc->tulip_chipid != TULIP_DC21140A 3492 && sc->tulip_chipid != TULIP_DC21041 3493#endif 3494 ) { 3495 error = EINVAL; 3496 break; 3497 } 3498 ifp->if_mtu = ifr->ifr_mtu; 3499#ifdef BIG_PACKET 3500 tulip_reset(sc); 3501 tulip_init(sc); 3502#endif 3503 break; 3504#endif /* SIOCSIFMTU */ 3505 3506 default: { 3507 error = EINVAL; 3508 break; 3509 } 3510 } 3511 3512 splx(s); 3513 return error; 3514} 3515 3516static void 3517tulip_ifwatchdog( 3518 struct ifnet *ifp) 3519{ 3520 tulip_softc_t * const sc = TULIP_IFP_TO_SOFTC(ifp); 3521 3522#if defined(TULIP_DEBUG) 3523 tulip_uint32_t rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs; 3524 if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz) 3525 sc->tulip_dbg.dbg_high_rxintrs_hz = rxintrs; 3526 sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs; 3527 sc->tulip_dbg.dbg_gpintrs_hz = sc->tulip_dbg.dbg_gpintrs; 3528 sc->tulip_dbg.dbg_gpintrs = 0; 3529#endif /* TULIP_DEBUG */ 3530 3531 sc->tulip_if.if_timer = 1; 3532 /* 3533 * These should be rare so do a bulk test up front so we can just skip 3534 * them if needed. 3535 */ 3536 if (sc->tulip_flags & (TULIP_SYSTEMERROR|TULIP_RXBUFSLOW|TULIP_FAKEGPTIMEOUT|TULIP_NOMESSAGES)) { 3537 /* 3538 * This for those devices that need to autosense. Interrupts are not 3539 * allowed during device probe so we fake one here to start the 3540 * autosense. Do this before the others since it can effect their 3541 * state. 3542 */ 3543 if (sc->tulip_flags & TULIP_FAKEGPTIMEOUT) 3544 (*sc->tulip_boardsw->bd_media_select)(sc); 3545 3546 /* 3547 * If the number of receive buffer is low, try to refill 3548 */ 3549 if (sc->tulip_flags & TULIP_RXBUFSLOW) 3550 tulip_rx_intr(sc); 3551 3552 if (sc->tulip_flags & TULIP_SYSTEMERROR) { 3553 printf(TULIP_PRINTF_FMT ": %d system errors: last was %s\n", 3554 TULIP_PRINTF_ARGS, sc->tulip_system_errors, 3555 tulip_system_errors[sc->tulip_last_system_error]); 3556 } 3557 if (sc->tulip_statusbits) { 3558 tulip_print_abnormal_interrupt(sc, sc->tulip_statusbits); 3559 sc->tulip_statusbits = 0; 3560 } 3561 3562 sc->tulip_flags &= ~(TULIP_NOMESSAGES|TULIP_SYSTEMERROR); 3563 } 3564 3565 if (sc->tulip_txtimer && --sc->tulip_txtimer == 0) { 3566 printf(TULIP_PRINTF_FMT ": transmission timeout\n", TULIP_PRINTF_ARGS); 3567 sc->tulip_media = TULIP_MEDIA_UNKNOWN; 3568 sc->tulip_probe_state = TULIP_PROBE_INACTIVE; 3569 sc->tulip_flags &= ~(TULIP_TXPROBE_ACTIVE|TULIP_TXPROBE_OK|TULIP_WANTRXACT|TULIP_LINKUP|TULIP_LINKSUSPECT); 3570 tulip_reset(sc); 3571 tulip_init(sc); 3572 } 3573} 3574#if defined(__bsdi__) || (defined(__FreeBSD__) && BSD < 199506) 3575static ifnet_ret_t 3576tulip_ifwatchdog_wrapper( 3577 int unit) 3578{ 3579 tulip_ifwatchdog(&TULIP_UNIT_TO_SOFTC(unit)->tulip_if); 3580} 3581#define tulip_ifwatchdog tulip_ifwatchdog_wrapper 3582#endif 3583 3584/* 3585 * All printf's are real as of now! 3586 */ 3587#ifdef printf 3588#undef printf 3589#endif 3590#if !defined(IFF_NOTRAILERS) 3591#define IFF_NOTRAILERS 0 3592#endif 3593 3594static void 3595tulip_attach( 3596 tulip_softc_t * const sc) 3597{ 3598 struct ifnet * const ifp = &sc->tulip_if; 3599 3600 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST; 3601 ifp->if_ioctl = tulip_ifioctl; 3602 ifp->if_start = tulip_ifstart; 3603 ifp->if_watchdog = tulip_ifwatchdog; 3604 ifp->if_timer = 1; 3605#if !defined(__bsdi__) || _BSDI_VERSION < 199401 3606 ifp->if_output = ether_output; 3607#endif 3608#if defined(__bsdi__) && _BSDI_VERSION < 199401 3609 ifp->if_mtu = ETHERMTU; 3610#endif 3611 3612#if defined(__bsdi__) && _BSDI_VERSION >= 199510 3613 aprint_naive(": DEC Ethernet"); 3614 aprint_normal(": %s%s", sc->tulip_boardid, 3615 tulip_chipdescs[sc->tulip_chipid]); 3616 aprint_verbose(" pass %d.%d", (sc->tulip_revinfo & 0xF0) >> 4, 3617 sc->tulip_revinfo & 0x0F); 3618 printf("\n"); 3619 sc->tulip_pf = aprint_normal; 3620 aprint_normal(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n", 3621 TULIP_PRINTF_ARGS, 3622 TULIP_EADDR_ARGS(sc->tulip_hwaddr)); 3623#else 3624 printf( 3625#if defined(__bsdi__) 3626 "\n" 3627#endif 3628 TULIP_PRINTF_FMT ": %s%s pass %d.%d\n", 3629 TULIP_PRINTF_ARGS, 3630 sc->tulip_boardid, 3631 tulip_chipdescs[sc->tulip_chipid], 3632 (sc->tulip_revinfo & 0xF0) >> 4, 3633 sc->tulip_revinfo & 0x0F); 3634 printf(TULIP_PRINTF_FMT ": address " TULIP_EADDR_FMT "\n", 3635 TULIP_PRINTF_ARGS, 3636 TULIP_EADDR_ARGS(sc->tulip_hwaddr)); 3637#endif 3638 3639 3640 if (sc->tulip_boardsw->bd_mii_probe != NULL) 3641 (*sc->tulip_boardsw->bd_mii_probe)(sc); 3642 3643 if ((*sc->tulip_boardsw->bd_media_probe)(sc)) { 3644 ifp->if_flags |= IFF_ALTPHYS; 3645 } else { 3646 sc->tulip_flags |= TULIP_ALTPHYS; 3647 } 3648 3649 sc->tulip_flags |= TULIP_DEVICEPROBE; 3650 tulip_reset(sc); 3651 sc->tulip_flags &= ~TULIP_DEVICEPROBE; 3652 3653#if defined(__bsdi__) && _BSDI_VERSION >= 199510 3654 sc->tulip_pf = printf; 3655 ether_attach(ifp); 3656#else 3657 if_attach(ifp); 3658#if defined(__NetBSD__) || (defined(__FreeBSD__) && BSD >= 199506) 3659 ether_ifattach(ifp); 3660#endif 3661#endif /* __bsdi__ */ 3662 3663#if NBPFILTER > 0 3664 TULIP_BPF_ATTACH(sc); 3665#endif 3666} 3667 3668static void 3669tulip_initcsrs( 3670 tulip_softc_t * const sc, 3671 tulip_csrptr_t csr_base, 3672 size_t csr_size) 3673{ 3674 sc->tulip_csrs.csr_busmode = csr_base + 0 * csr_size; 3675 sc->tulip_csrs.csr_txpoll = csr_base + 1 * csr_size; 3676 sc->tulip_csrs.csr_rxpoll = csr_base + 2 * csr_size; 3677 sc->tulip_csrs.csr_rxlist = csr_base + 3 * csr_size; 3678 sc->tulip_csrs.csr_txlist = csr_base + 4 * csr_size; 3679 sc->tulip_csrs.csr_status = csr_base + 5 * csr_size; 3680 sc->tulip_csrs.csr_command = csr_base + 6 * csr_size; 3681 sc->tulip_csrs.csr_intr = csr_base + 7 * csr_size; 3682 sc->tulip_csrs.csr_missed_frames = csr_base + 8 * csr_size; 3683 if (sc->tulip_chipid == TULIP_DC21040) { 3684 sc->tulip_csrs.csr_enetrom = csr_base + 9 * csr_size; 3685 sc->tulip_csrs.csr_reserved = csr_base + 10 * csr_size; 3686 sc->tulip_csrs.csr_full_duplex = csr_base + 11 * csr_size; 3687 sc->tulip_csrs.csr_sia_status = csr_base + 12 * csr_size; 3688 sc->tulip_csrs.csr_sia_connectivity = csr_base + 13 * csr_size; 3689 sc->tulip_csrs.csr_sia_tx_rx = csr_base + 14 * csr_size; 3690 sc->tulip_csrs.csr_sia_general = csr_base + 15 * csr_size; 3691#if defined(TULIP_EISA) 3692 } else if (sc->tulip_chipid == TULIP_DE425) { 3693 sc->tulip_csrs.csr_enetrom = csr_base + DE425_ENETROM_OFFSET; 3694 sc->tulip_csrs.csr_reserved = csr_base + 10 * csr_size; 3695 sc->tulip_csrs.csr_full_duplex = csr_base + 11 * csr_size; 3696 sc->tulip_csrs.csr_sia_status = csr_base + 12 * csr_size; 3697 sc->tulip_csrs.csr_sia_connectivity = csr_base + 13 * csr_size; 3698 sc->tulip_csrs.csr_sia_tx_rx = csr_base + 14 * csr_size; 3699 sc->tulip_csrs.csr_sia_general = csr_base + 15 * csr_size; 3700#endif /* TULIP_EISA */ 3701 } else if (sc->tulip_chipid == TULIP_DC21140 || sc->tulip_chipid == TULIP_DC21140A) { 3702 sc->tulip_csrs.csr_srom_mii = csr_base + 9 * csr_size; 3703 sc->tulip_csrs.csr_gp_timer = csr_base + 11 * csr_size; 3704 sc->tulip_csrs.csr_gp = csr_base + 12 * csr_size; 3705 sc->tulip_csrs.csr_watchdog = csr_base + 15 * csr_size; 3706 } else if (sc->tulip_chipid == TULIP_DC21041) { 3707 sc->tulip_csrs.csr_srom_mii = csr_base + 9 * csr_size; 3708 sc->tulip_csrs.csr_bootrom = csr_base + 10 * csr_size; 3709 sc->tulip_csrs.csr_gp_timer = csr_base + 11 * csr_size; 3710 sc->tulip_csrs.csr_sia_status = csr_base + 12 * csr_size; 3711 sc->tulip_csrs.csr_sia_connectivity = csr_base + 13 * csr_size; 3712 sc->tulip_csrs.csr_sia_tx_rx = csr_base + 14 * csr_size; 3713 sc->tulip_csrs.csr_sia_general = csr_base + 15 * csr_size; 3714 } 3715} 3716 3717static void 3718tulip_initring( 3719 tulip_softc_t * const sc, 3720 tulip_ringinfo_t * const ri, 3721 tulip_desc_t *descs, 3722 int ndescs) 3723{ 3724 ri->ri_max = ndescs; 3725 ri->ri_first = descs; 3726 ri->ri_last = ri->ri_first + ri->ri_max; 3727 bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max); 3728 ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING; 3729} 3730 3731/* 3732 * This is the PCI configuration support. Since the DC21040 is available 3733 * on both EISA and PCI boards, one must be careful in how defines the 3734 * DC21040 in the config file. 3735 */ 3736 3737#define PCI_CFID 0x00 /* Configuration ID */ 3738#define PCI_CFCS 0x04 /* Configurtion Command/Status */ 3739#define PCI_CFRV 0x08 /* Configuration Revision */ 3740#define PCI_CFLT 0x0c /* Configuration Latency Timer */ 3741#define PCI_CBIO 0x10 /* Configuration Base IO Address */ 3742#define PCI_CBMA 0x14 /* Configuration Base Memory Address */ 3743#define PCI_CFIT 0x3c /* Configuration Interrupt */ 3744#define PCI_CFDA 0x40 /* Configuration Driver Area */ 3745 3746#if defined(TULIP_EISA) 3747static const int tulip_eisa_irqs[4] = { IRQ5, IRQ9, IRQ10, IRQ11 }; 3748#endif 3749 3750#if defined(__FreeBSD__) 3751 3752#define TULIP_PCI_ATTACH_ARGS pcici_t config_id, int unit 3753 3754static int 3755tulip_pci_shutdown( 3756 struct kern_devconf * const kdc, 3757 int force) 3758{ 3759 if (kdc->kdc_unit < tulip_count) { 3760 tulip_softc_t * const sc = TULIP_UNIT_TO_SOFTC(kdc->kdc_unit); 3761 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); 3762 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 3763 33MHz that comes to two microseconds but wait a 3764 bit longer anyways) */ 3765 } 3766 (void) dev_detach(kdc); 3767 return 0; 3768} 3769 3770static char* 3771tulip_pci_probe( 3772 pcici_t config_id, 3773 pcidi_t device_id) 3774{ 3775 if (PCI_VENDORID(device_id) != DEC_VENDORID) 3776 return NULL; 3777 if (PCI_CHIPID(device_id) == DC21040_CHIPID) 3778 return "Digital DC21040 Ethernet"; 3779 if (PCI_CHIPID(device_id) == DC21041_CHIPID) 3780 return "Digital DC21041 Ethernet"; 3781 if (PCI_CHIPID(device_id) == DC21140_CHIPID) { 3782 tulip_uint32_t revinfo = pci_conf_read(config_id, PCI_CFRV) & 0xFF; 3783 if (revinfo >= 0x20) 3784 return "Digital DC21140A Fast Ethernet"; 3785 else 3786 return "Digital DC21140 Fast Ethernet"; 3787 3788 } 3789 return NULL; 3790} 3791 3792static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS); 3793static u_long tulip_pci_count; 3794 3795struct pci_device dedevice = { 3796 "de", 3797 tulip_pci_probe, 3798 tulip_pci_attach, 3799 &tulip_pci_count, 3800 tulip_pci_shutdown, 3801}; 3802 3803DATA_SET (pcidevice_set, dedevice); 3804#endif /* __FreeBSD__ */ 3805 3806#if defined(__bsdi__) 3807#define TULIP_PCI_ATTACH_ARGS struct device * const parent, struct device * const self, void * const aux 3808 3809static void 3810tulip_shutdown( 3811 void *arg) 3812{ 3813 tulip_softc_t * const sc = (tulip_softc_t *) arg; 3814 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); 3815 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 3816 33MHz that comes to two microseconds but wait a 3817 bit longer anyways) */ 3818} 3819 3820static int 3821tulip_pci_match( 3822 pci_devaddr_t *pa) 3823{ 3824 int irq; 3825 unsigned id; 3826 3827 id = pci_inl(pa, PCI_VENDOR_ID); 3828 if (PCI_VENDORID(id) != DEC_VENDORID) 3829 return 0; 3830 id = PCI_CHIPID(id); 3831 if (id != DC21040_CHIPID && id != DC21041_CHIPID && id != DC21140_CHIPID) 3832 return 0; 3833 irq = pci_inl(pa, PCI_I_LINE) & 0xFF; 3834 if (irq == 0 || irq >= 16) { 3835 printf("de?: invalid IRQ %d; skipping\n", irq); 3836 return 0; 3837 } 3838 return 1; 3839} 3840 3841static int 3842tulip_probe( 3843 struct device *parent, 3844 struct cfdata *cf, 3845 void *aux) 3846{ 3847 struct isa_attach_args * const ia = (struct isa_attach_args *) aux; 3848 unsigned irq, slot; 3849 pci_devaddr_t *pa; 3850 3851#if _BSDI_VERSION >= 199401 3852 switch (ia->ia_bustype) { 3853 case BUS_PCI: 3854#endif 3855 pa = pci_scan(tulip_pci_match); 3856 if (pa == NULL) 3857 return 0; 3858 3859 irq = (1 << (pci_inl(pa, PCI_I_LINE) & 0xFF)); 3860 3861 /* Get the base address; assume the BIOS set it up correctly */ 3862#if defined(TULIP_IOMAPPED) 3863 ia->ia_maddr = NULL; 3864 ia->ia_msize = 0; 3865 ia->ia_iobase = pci_inl(pa, PCI_CBIO) & ~7; 3866 pci_outl(pa, PCI_CBIO, 0xFFFFFFFF); 3867 ia->ia_iosize = ((~pci_inl(pa, PCI_CBIO)) | 7) + 1; 3868 pci_outl(pa, PCI_CBIO, (int) ia->ia_iobase); 3869 3870 /* Disable memory space access */ 3871 pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~2); 3872#else 3873 ia->ia_maddr = (caddr_t) (pci_inl(pa, PCI_CBMA) & ~7); 3874 pci_outl(pa, PCI_CBMA, 0xFFFFFFFF); 3875 ia->ia_msize = ((~pci_inl(pa, PCI_CBMA)) | 7) + 1; 3876 pci_outl(pa, PCI_CBMA, (int) ia->ia_maddr); 3877 ia->ia_iobase = 0; 3878 ia->ia_iosize = 0; 3879 3880 /* Disable I/O space access */ 3881 pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~1); 3882#endif /* TULIP_IOMAPPED */ 3883 3884 ia->ia_aux = (void *) pa; 3885#if _BSDI_VERSION >= 199401 3886 break; 3887 3888#if defined(TULIP_EISA) 3889 case BUS_EISA: { 3890 unsigned tmp; 3891 3892 if ((slot = eisa_match(cf, ia)) == 0) 3893 return 0; 3894 ia->ia_iobase = slot << 12; 3895 ia->ia_iosize = EISA_NPORT; 3896 eisa_slotalloc(slot); 3897 tmp = inb(ia->ia_iobase + DE425_CFG0); 3898 irq = tulip_eisa_irqs[(tmp >> 1) & 0x03]; 3899 /* 3900 * Until BSD/OS likes level interrupts, force 3901 * the DE425 into edge-triggered mode. 3902 */ 3903 if ((tmp & 1) == 0) 3904 outb(ia->ia_iobase + DE425_CFG0, tmp | 1); 3905 /* 3906 * CBIO needs to map to the EISA slot 3907 * enable I/O access and Master 3908 */ 3909 outl(ia->ia_iobase + DE425_CBIO, ia->ia_iobase); 3910 outl(ia->ia_iobase + DE425_CFCS, 5 | inl(ia->ia_iobase + DE425_CFCS)); 3911 ia->ia_aux = NULL; 3912 break; 3913 } 3914#endif /* TULIP_EISA */ 3915 default: 3916 return 0; 3917 } 3918#endif 3919 3920 /* PCI bus masters don't use host DMA channels */ 3921 ia->ia_drq = DRQNONE; 3922 3923 if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) { 3924 printf("de%d: error: desired IRQ of %d does not match device's " 3925 "actual IRQ of %d,\n", 3926 cf->cf_unit, 3927 ffs(ia->ia_irq) - 1, ffs(irq) - 1); 3928 return 0; 3929 } 3930 if (ia->ia_irq == IRQUNK) 3931 ia->ia_irq = irq; 3932#ifdef IRQSHARE 3933 ia->ia_irq |= IRQSHARE; 3934#endif 3935 return 1; 3936} 3937 3938static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS); 3939 3940#if defined(TULIP_EISA) 3941static char *tulip_eisa_ids[] = { 3942 "DEC4250", 3943 NULL 3944}; 3945#endif 3946 3947struct cfdriver decd = { 3948 0, "de", tulip_probe, tulip_pci_attach, 3949#if _BSDI_VERSION >= 199401 3950 DV_IFNET, 3951#endif 3952 sizeof(tulip_softc_t), 3953#if defined(TULIP_EISA) 3954 tulip_eisa_ids 3955#endif 3956}; 3957 3958#endif /* __bsdi__ */ 3959 3960#if defined(__NetBSD__) 3961#define TULIP_PCI_ATTACH_ARGS struct device * const parent, struct device * const self, void * const aux 3962 3963static void 3964tulip_pci_shutdown( 3965 void *arg) 3966{ 3967 tulip_softc_t * const sc = (tulip_softc_t *) arg; 3968 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); 3969 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 3970 33MHz that comes to two microseconds but wait a 3971 bit longer anyways) */ 3972} 3973 3974static int 3975tulip_pci_probe( 3976 struct device *parent, 3977 void *match, 3978 void *aux) 3979{ 3980 struct pci_attach_args *pa = (struct pci_attach_args *) aux; 3981 3982 if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID) 3983 return 0; 3984 if (PCI_CHIPID(pa->pa_id) == DC21040_CHIPID 3985 || PCI_CHIPID(pa->pa_id) == DC21041_CHIPID 3986 || PCI_CHIPID(pa->pa_id) == DC21140_CHIPID) 3987 return 1; 3988 3989 return 0; 3990} 3991 3992static void tulip_pci_attach(TULIP_PCI_ATTACH_ARGS); 3993 3994struct cfattach de_ca = { 3995 sizeof(tulip_softc_t), tulip_pci_probe, tulip_pci_attach 3996}; 3997 3998struct cfdriver de_cd = { 3999 0, "de", DV_IFNET 4000}; 4001 4002#endif /* __NetBSD__ */ 4003 4004static void 4005tulip_pci_attach( 4006 TULIP_PCI_ATTACH_ARGS) 4007{ 4008#if defined(__FreeBSD__) 4009 tulip_softc_t *sc; 4010#define PCI_CONF_WRITE(r, v) pci_conf_write(config_id, (r), (v)) 4011#define PCI_CONF_READ(r) pci_conf_read(config_id, (r)) 4012#endif 4013#if defined(__bsdi__) 4014 tulip_softc_t * const sc = (tulip_softc_t *) self; 4015 struct isa_attach_args * const ia = (struct isa_attach_args *) aux; 4016 pci_devaddr_t *pa = (pci_devaddr_t *) ia->ia_aux; 4017 const int unit = sc->tulip_dev.dv_unit; 4018#define PCI_CONF_WRITE(r, v) pci_outl(pa, (r), (v)) 4019#define PCI_CONF_READ(r) pci_inl(pa, (r)) 4020#endif 4021#if defined(__NetBSD__) 4022 tulip_softc_t * const sc = (tulip_softc_t *) self; 4023 struct pci_attach_args * const pa = (struct pci_attach_args *) aux; 4024 const int unit = sc->tulip_dev.dv_unit; 4025#if defined(TULIP_IOMAPPED) 4026 bus_io_addr_t iobase; 4027 bus_io_size_t iosize; 4028#else 4029 bus_mem_addr_t membase; 4030 bus_mem_size_t memsize; 4031#endif 4032#define PCI_CONF_WRITE(r, v) pci_conf_write(pa->pa_pc, pa->pa_tag, (r), (v)) 4033#define PCI_CONF_READ(r) pci_conf_read(pa->pa_pc, pa->pa_tag, (r)) 4034#endif /* __NetBSD__ */ 4035 int retval, idx; 4036 tulip_uint32_t revinfo, cfdainfo, id; 4037#if !defined(TULIP_IOMAPPED) && defined(__FreeBSD__) 4038 vm_offset_t pa_csrs; 4039#endif 4040 unsigned csroffset = TULIP_PCI_CSROFFSET; 4041 unsigned csrsize = TULIP_PCI_CSRSIZE; 4042 tulip_csrptr_t csr_base; 4043 tulip_chipid_t chipid = TULIP_CHIPID_UNKNOWN; 4044 4045#if defined(__FreeBSD__) 4046 if (unit >= tulip_count) { 4047 tulip_softc_t **new_tulips = 4048 (tulip_softc_t **) malloc((tulip_count + TULIP_COUNTINCR) * sizeof(tulip_softc_t *), M_DEVBUF, M_WAITOK); 4049 if (new_tulips == NULL) { 4050 printf("de%d: not configured; can't allocate memory\n", unit); 4051 return; 4052 } 4053 if (tulips != NULL) { 4054 bcopy(tulips, new_tulips, tulip_count * sizeof(tulips[0])); 4055 free(tulips, M_DEVBUF); 4056 } 4057 bzero(&new_tulips[tulip_count], TULIP_COUNTINCR * sizeof(new_tulips[0])); 4058 tulip_count += TULIP_COUNTINCR; 4059 tulips = new_tulips; 4060 } 4061#endif 4062 4063#if defined(__bsdi__) 4064 if (pa != NULL) { 4065 revinfo = pci_inl(pa, PCI_CFRV) & 0xFF; 4066 id = pci_inl(pa, PCI_CFID); 4067 cfdainfo = pci_inl(pa, PCI_CFDA); 4068#if defined(TULIP_EISA) 4069 } else { 4070 revinfo = inl(ia->ia_iobase + DE425_CFRV) & 0xFF; 4071 csroffset = TULIP_EISA_CSROFFSET; 4072 csrsize = TULIP_EISA_CSRSIZE; 4073 chipid = TULIP_DE425; 4074 cfdainfo = 0; 4075#endif 4076 } 4077#else /* __bsdi__ */ 4078 revinfo = PCI_CONF_READ(PCI_CFRV) & 0xFF; 4079 id = PCI_CONF_READ(PCI_CFID); 4080 cfdainfo = PCI_CONF_READ(PCI_CFDA); 4081#endif 4082 4083 if (PCI_VENDORID(id) == DEC_VENDORID) { 4084 if (PCI_CHIPID(id) == DC21040_CHIPID) chipid = TULIP_DC21040; 4085 else if (PCI_CHIPID(id) == DC21140_CHIPID) { 4086 chipid = (revinfo >= 0x20) ? TULIP_DC21140A : TULIP_DC21140; 4087 } 4088 else if (PCI_CHIPID(id) == DC21041_CHIPID) chipid = TULIP_DC21041; 4089 } 4090 if (chipid == TULIP_CHIPID_UNKNOWN) 4091 return; 4092 4093 if ((chipid == TULIP_DC21040 || chipid == TULIP_DE425) && revinfo < 0x20) { 4094#ifdef __FreeBSD__ 4095 printf("de%d", unit); 4096#endif 4097 printf(": not configured; DC21040 pass 2.0 required (%d.%d found)\n", 4098 revinfo >> 4, revinfo & 0x0f); 4099 return; 4100 } else if (chipid == TULIP_DC21140 && revinfo < 0x11) { 4101#ifndef __FreeBSD__ 4102 printf("\n"); 4103#endif 4104 printf("de%d: not configured; DC21140 pass 1.1 required (%d.%d found)\n", 4105 unit, revinfo >> 4, revinfo & 0x0f); 4106 return; 4107 } 4108 4109 if ((chipid == TULIP_DC21041 || chipid == TULIP_DC21140A) 4110 && (cfdainfo & (TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE))) { 4111 cfdainfo &= ~(TULIP_CFDA_SLEEP|TULIP_CFDA_SNOOZE); 4112 PCI_CONF_WRITE(PCI_CFDA, cfdainfo); 4113 printf("de%d: waking device from sleep/snooze mode\n", unit); 4114 DELAY(11*1000); 4115 } 4116 4117 4118#if defined(__FreeBSD__) 4119 sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); 4120 if (sc == NULL) 4121 return; 4122 bzero(sc, sizeof(*sc)); /* Zero out the softc*/ 4123#endif 4124 4125 sc->tulip_chipid = chipid; 4126#if defined(__NetBSD__) 4127 bcopy(self->dv_xname, sc->tulip_if.if_xname, IFNAMSIZ); 4128 sc->tulip_if.if_softc = sc; 4129 sc->tulip_bc = pa->pa_bc; 4130 sc->tulip_pc = pa->pa_pc; 4131#else 4132 sc->tulip_unit = unit; 4133 sc->tulip_name = "de"; 4134#endif 4135 sc->tulip_revinfo = revinfo; 4136#if defined(__FreeBSD__) 4137#if BSD >= 199506 4138 sc->tulip_if.if_softc = sc; 4139#endif 4140#if defined(TULIP_IOMAPPED) 4141 retval = pci_map_port(config_id, PCI_CBIO, &csr_base); 4142#else 4143 retval = pci_map_mem(config_id, PCI_CBMA, (vm_offset_t *) &csr_base, &pa_csrs); 4144#endif 4145 if (!retval) { 4146 free((caddr_t) sc, M_DEVBUF); 4147 return; 4148 } 4149 tulips[unit] = sc; 4150#endif /* __FreeBSD__ */ 4151 4152#if defined(__bsdi__) 4153#if defined(TULIP_IOMAPPED) 4154 csr_base = ia->ia_iobase; 4155#else 4156 csr_base = (vm_offset_t) mapphys((vm_offset_t) ia->ia_maddr, ia->ia_msize); 4157#endif 4158#endif /* __bsdi__ */ 4159 4160#if defined(__NetBSD__) 4161 csr_base = 0; 4162#if defined(TULIP_IOMAPPED) 4163 if (pci_io_find(pa->pa_pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize) 4164 || bus_io_map(pa->pa_bc, iobase, iosize, &sc->tulip_ioh)) 4165 return; 4166#else 4167 if (pci_mem_find(pa->pa_pc, pa->pa_tag, PCI_CBMA, &membase, &memsize, NULL) 4168 || bus_mem_map(pa->pa_bc, membase, memsize, 0, &sc->tulip_memh)) 4169 return; 4170#endif 4171#endif /* __NetBSD__ */ 4172 4173 tulip_initcsrs(sc, csr_base + csroffset, csrsize); 4174 tulip_initring(sc, &sc->tulip_rxinfo, sc->tulip_rxdescs, TULIP_RXDESCS); 4175 tulip_initring(sc, &sc->tulip_txinfo, sc->tulip_txdescs, TULIP_TXDESCS); 4176 if ((retval = tulip_read_macaddr(sc)) < 0) { 4177#ifdef __FreeBSD__ 4178 printf(TULIP_PRINTF_FMT, TULIP_PRINTF_ARGS); 4179#endif 4180 printf(": can't read ENET ROM (why=%d) (", retval); 4181 for (idx = 0; idx < 32; idx++) 4182 printf("%02x", sc->tulip_rombuf[idx]); 4183 printf("\n"); 4184 printf(TULIP_PRINTF_FMT ": %s%s pass %d.%d\n", 4185 TULIP_PRINTF_ARGS, 4186 (sc->tulip_boardid != NULL ? sc->tulip_boardid : ""), 4187 tulip_chipdescs[sc->tulip_chipid], 4188 (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F); 4189 printf(TULIP_PRINTF_FMT ": address unknown\n", TULIP_PRINTF_ARGS); 4190 } else { 4191 int s; 4192 /* 4193 * Make sure there won't be any interrupts or such... 4194 */ 4195 TULIP_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); 4196 DELAY(10); /* Wait 10 microseconds (actually 50 PCI cycles but at 4197 33MHz that comes to two microseconds but wait a 4198 bit longer anyways) */ 4199#if defined(__NetBSD__) 4200 if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) { 4201 pci_intr_handle_t intrhandle; 4202 const char *intrstr; 4203 4204 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, 4205 pa->pa_intrline, &intrhandle)) { 4206 printf(": couldn't map interrupt\n"); 4207 return; 4208 } 4209 intrstr = pci_intr_string(pa->pa_pc, intrhandle); 4210 sc->tulip_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET, 4211 tulip_intr, sc); 4212 if (sc->tulip_ih == NULL) 4213 printf(": couldn't establish interrupt"); 4214 if (intrstr != NULL) 4215 printf(" at %s", intrstr); 4216 printf("\n"); 4217 if (sc->tulip_ih == NULL) 4218 return; 4219 } 4220 sc->tulip_ats = shutdownhook_establish(tulip_pci_shutdown, sc); 4221 if (sc->tulip_ats == NULL) 4222 printf("\n%s: warning: couldn't establish shutdown hook\n", 4223 sc->tulip_xname); 4224#endif 4225#if defined(__FreeBSD__) 4226 if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) { 4227 if (!pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask)) { 4228 printf(TULIP_PRINTF_FMT ": couldn't map interrupt\n", 4229 TULIP_PRINTF_ARGS); 4230 return; 4231 } 4232 } 4233#endif 4234#if defined(__bsdi__) 4235 if ((sc->tulip_flags & TULIP_SLAVEDINTR) == 0) { 4236 isa_establish(&sc->tulip_id, &sc->tulip_dev); 4237 4238 sc->tulip_ih.ih_fun = tulip_intr; 4239 sc->tulip_ih.ih_arg = (void *)sc; 4240 intr_establish(ia->ia_irq, &sc->tulip_ih, DV_NET); 4241 } 4242 4243 sc->tulip_ats.func = tulip_shutdown; 4244 sc->tulip_ats.arg = (void *) sc; 4245 atshutdown(&sc->tulip_ats, ATSH_ADD); 4246#endif 4247 s = splimp(); 4248 tulip_reset(sc); 4249 tulip_attach(sc); 4250 splx(s); 4251 } 4252} 4253 4254