if_de.c revision 4322
1/*- 2 * Copyright (c) 1994 Matt Thomas (thomas@lkg.dec.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.3 1994/10/12 11:19:35 se Exp $ 25 * 26 * $Log: if_de.c,v $ 27 * Revision 1.3 1994/10/12 11:19:35 se 28 * Submitted by: Matt Thomas <thomas@lkg.dec.com> 29 * Preliminary FAST Ethernet support added (DEC21140). 30 * 31 * Revision 1.6 1994/10/11 18:20:10 thomas 32 * new pci interface 33 * new 100mb/s prelim support 34 * 35 * Revision 1.5 1994/10/01 16:10:24 thomas 36 * Modifications for FreeBSD 2.0 37 * 38 * Revision 1.4 1994/09/09 21:10:05 thomas 39 * mbuf debugging code 40 * transmit fifo owkraroudns 41 * 42 * Revision 1.3 1994/08/16 20:40:56 thomas 43 * New README files (one per driver) 44 * Minor updates to drivers (DEPCA support and add pass to attach 45 * output) 46 * 47 * Revision 1.2 1994/08/15 20:41:22 thomas 48 * Support AUI and TP. Autosense either. 49 * Revamp receive logic to use private kmem_alloc'ed 64K region. 50 * Some cleanup 51 * 52 * Revision 1.1 1994/08/12 21:01:18 thomas 53 * Initial revision 54 * 55 */ 56 57/* 58 * DEC DC21040 PCI Ethernet Controller 59 * 60 * Written by Matt Thomas 61 * BPF support code stolen directly from if_ec.c 62 * 63 * This driver supports the DEC DE435 or any other PCI 64 * board which support DC21040. 65 */ 66 67#include <de.h> 68#if NDE > 0 69 70#include <param.h> 71#include <systm.h> 72#include <mbuf.h> 73#include <protosw.h> 74#include <socket.h> 75#include <ioctl.h> 76#include <errno.h> 77#include <malloc.h> 78#include <syslog.h> 79 80#include <net/if.h> 81#include <net/if_types.h> 82#include <net/if_dl.h> 83#include <net/route.h> 84 85#include <bpfilter.h> 86#if NBPFILTER > 0 87#include <net/bpf.h> 88#include <net/bpfdesc.h> 89#endif 90 91 92#ifdef INET 93#include <netinet/in.h> 94#include <netinet/in_systm.h> 95#include <netinet/in_var.h> 96#include <netinet/ip.h> 97#include <netinet/if_ether.h> 98#endif 99 100#ifdef NS 101#include <netns/ns.h> 102#include <netns/ns_if.h> 103#endif 104 105#include <vm/vm.h> 106#include <vm/vm_kern.h> 107#include <vm/vm_param.h> 108 109 110#include <pci.h> 111#if NPCI > 0 112#include <i386/pci/pcireg.h> 113#endif 114#include <i386/isa/icu.h> 115#include <i386/pci/dc21040.h> 116 117/* 118 * This module supports the DEC DC21040 PCI Ethernet Controller. 119 */ 120 121typedef struct { 122 unsigned long addr; 123 unsigned long length; 124} tulip_addrvec_t; 125 126typedef struct { 127 tulip_desc_t *ri_first; 128 tulip_desc_t *ri_last; 129 tulip_desc_t *ri_nextin; 130 tulip_desc_t *ri_nextout; 131 int ri_max; 132 int ri_free; 133} tulip_ringinfo_t; 134 135typedef struct { 136 volatile tulip_uint32_t *csr_busmode; /* CSR0 */ 137 volatile tulip_uint32_t *csr_txpoll; /* CSR1 */ 138 volatile tulip_uint32_t *csr_rxpoll; /* CSR2 */ 139 volatile tulip_uint32_t *csr_rxlist; /* CSR3 */ 140 volatile tulip_uint32_t *csr_txlist; /* CSR4 */ 141 volatile tulip_uint32_t *csr_status; /* CSR5 */ 142 volatile tulip_uint32_t *csr_command; /* CSR6 */ 143 volatile tulip_uint32_t *csr_intr; /* CSR7 */ 144 volatile tulip_uint32_t *csr_missed_frame; /* CSR8 */ 145 volatile tulip_sint32_t *csr_enetrom; /* CSR9 */ 146 volatile tulip_uint32_t *csr_reserved; /* CSR10 */ 147 volatile tulip_uint32_t *csr_full_duplex; /* CSR11 */ 148 volatile tulip_uint32_t *csr_sia_status; /* CSR12 */ 149 volatile tulip_uint32_t *csr_sia_connectivity; /* CSR13 */ 150 volatile tulip_uint32_t *csr_sia_tx_rx; /* CSR14 */ 151 volatile tulip_uint32_t *csr_sia_general; /* CSR15 */ 152} tulip_regfile_t; 153 154/* 155 * The DC21040 has a stupid restriction in that the receive 156 * buffers must be longword aligned. But since Ethernet 157 * headers are not a multiple of longwords in size this forces 158 * the data to non-longword aligned. Since IP requires the 159 * data to be longword aligned, we can to copy it after it has 160 * been DMA'ed in our memory. 161 * 162 * Since we have to copy it anyways, we might as well as allocate 163 * dedicated receive space for the input. This allows to use a 164 * small receive buffer size and more ring entries to be able to 165 * better keep with a foold of tiny Ethernet packets. 166 * 167 * The receive space MUST ALWAYS be a multiple of the page size. 168 * And the number of receive descriptors multiplied by the size 169 * of the receive buffers must equal the recevive space. This 170 * is that we can manipulate the page tables so that even if a 171 * packet wraps around the end of the receive space, we can 172 * treat it as virtually contiguous. 173 */ 174#define TULIP_RXBUFSIZE 512 175#define TULIP_RXDESCS 128 176#define TULIP_RXSPACE (TULIP_RXBUFSIZE * TULIP_RXDESCS) 177#define TULIP_TXDESCS 128 178 179typedef struct { 180 struct arpcom tulip_ac; 181 tulip_regfile_t tulip_csrs; 182 vm_offset_t tulip_rxspace; 183 unsigned tulip_flags; 184#define TULIP_WANTSETUP 0x01 185#define TULIP_WANTHASH 0x02 186#define TULIP_DOINGSETUP 0x04 187#define TULIP_ALTPHYS 0x08 /* use AUI */ 188 unsigned char tulip_rombuf[32]; 189 tulip_uint32_t tulip_setupbuf[192/sizeof(tulip_uint32_t)]; 190 tulip_uint32_t tulip_setupdata[192/sizeof(tulip_uint32_t)]; 191 tulip_uint32_t tulip_intrmask; 192 tulip_uint32_t tulip_cmdmode; 193 tulip_uint32_t tulip_revinfo; 194#if NBPFILTER > 0 195 caddr_t tulip_bpf; /* BPF context */ 196#endif 197 struct ifqueue tulip_txq; 198 tulip_ringinfo_t tulip_rxinfo; 199 tulip_ringinfo_t tulip_txinfo; 200} tulip_softc_t; 201 202#ifndef IFF_ALTPHYS 203#define IFF_ALTPHYS IFF_LINK0 /* In case it isn't defined */ 204#endif 205typedef enum { TULIP_DC21040, TULIP_DC21140 } tulip_chipid_t; 206const char *tulip_chipdescs[] = { 207 "DC21040 [10Mb/s]", 208 "DC21140 [100Mb/s]", 209}; 210 211tulip_softc_t *tulips[NDE]; 212tulip_chipid_t tulip_chipids[NDE]; 213 214#define tulip_if tulip_ac.ac_if 215#define tulip_unit tulip_ac.ac_if.if_unit 216#define tulip_name tulip_ac.ac_if.if_name 217#define tulip_hwaddr tulip_ac.ac_enaddr 218 219#define TULIP_CRC32_POLY 0xEDB88320UL /* CRC-32 Poly -- Little Endian */ 220#define TULIP_CHECK_RXCRC 0 221#define TULIP_MAX_TXSEG 32 222 223#define TULIP_ADDREQUAL(a1, a2) \ 224 (((u_short *)a1)[0] == ((u_short *)a2)[0] \ 225 || ((u_short *)a1)[1] == ((u_short *)a2)[1] \ 226 || ((u_short *)a1)[2] == ((u_short *)a2)[2]) 227#define TULIP_ADDRBRDCST(a1) \ 228 (((u_short *)a1)[0] == 0xFFFFU \ 229 || ((u_short *)a1)[1] == 0xFFFFU \ 230 || ((u_short *)a1)[2] == 0xFFFFU) 231 232static void tulip_start(struct ifnet *ifp); 233static void tulip_addr_filter(tulip_softc_t *sc); 234 235#if __FreeBSD__ > 1 236#define TULIP_IFRESET_ARGS int unit 237#define TULIP_RESET(sc) tulip_reset((sc)->tulip_unit) 238#else 239#define TULIP_IFRESET_ARGS int unit, int uban 240#define TULIP_RESET(sc) tulip_reset((sc)->tulip_unit, 0) 241#endif 242 243static void 244tulip_reset( 245 TULIP_IFRESET_ARGS) 246{ 247 tulip_softc_t *sc = tulips[unit]; 248 tulip_ringinfo_t *ri; 249 tulip_desc_t *di; 250 vm_offset_t vmoff; 251 252 *sc->tulip_csrs.csr_busmode = TULIP_BUSMODE_SWRESET; 253 DELAY(10); /* Wait 10 microsends (actually 50 PCI cycles but at 254 33MHz that comes to two microseconds but wait a 255 bit longer anyways) */ 256 257 /* 258 * Use the 259 */ 260 *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_RESET; 261 if (sc->tulip_if.if_flags & IFF_ALTPHYS) { 262 if ((sc->tulip_flags & TULIP_ALTPHYS) == 0) 263 printf("%s%d: enabling Thinwire/AUI port\n", 264 sc->tulip_if.if_name, sc->tulip_if.if_unit); 265 *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_AUI; 266 sc->tulip_flags |= TULIP_ALTPHYS; 267 } else { 268 if (sc->tulip_flags & TULIP_ALTPHYS) 269 printf("%s%d: enabling 10baseT/UTP port\n", 270 sc->tulip_if.if_name, sc->tulip_if.if_unit); 271 *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_10BASET; 272 sc->tulip_flags &= ~TULIP_ALTPHYS; 273 } 274 *sc->tulip_csrs.csr_txlist = vtophys(&sc->tulip_txinfo.ri_first[0]); 275 *sc->tulip_csrs.csr_rxlist = vtophys(&sc->tulip_rxinfo.ri_first[0]); 276 *sc->tulip_csrs.csr_intr = 0; 277 *sc->tulip_csrs.csr_busmode = 0x4800; 278 279 sc->tulip_txq.ifq_maxlen = TULIP_TXDESCS; 280 /* 281 * Free all the mbufs that were on the transmit ring. 282 */ 283 for (;;) { 284 struct mbuf *m; 285 IF_DEQUEUE(&sc->tulip_txq, m); 286 if (m == NULL) 287 break; 288 m_freem(m); 289 } 290 291 ri = &sc->tulip_txinfo; 292 ri->ri_nextin = ri->ri_nextout = ri->ri_first; 293 ri->ri_free = ri->ri_max; 294 for (di = ri->ri_first; di < ri->ri_last; di++) 295 di->d_status = 0; 296 297 /* 298 * We need to collect all the mbufs were on the 299 * receive ring before we reinit it either to put 300 * them back on or to know if we have to allocate 301 * more. 302 */ 303 ri = &sc->tulip_rxinfo; 304 ri->ri_nextin = ri->ri_nextout = ri->ri_first; 305 ri->ri_free = ri->ri_max; 306 for (vmoff = vtophys(sc->tulip_rxspace), di = ri->ri_first; 307 di < ri->ri_last; di++, vmoff += TULIP_RXBUFSIZE) { 308 di->d_status |= TULIP_DSTS_OWNER; 309 di->d_length1 = TULIP_RXBUFSIZE; di->d_addr1 = vmoff; 310 di->d_length2 = 0; di->d_addr2 = 0; 311 } 312 313 sc->tulip_intrmask = TULIP_STS_NORMALINTR|TULIP_STS_RXINTR|TULIP_STS_TXINTR 314 |TULIP_STS_ABNRMLINTR|TULIP_STS_SYSERROR|TULIP_STS_TXSTOPPED 315 |TULIP_STS_TXBABBLE|TULIP_STS_LINKFAIL|TULIP_STS_RXSTOPPED; 316 sc->tulip_flags &= ~(TULIP_DOINGSETUP|TULIP_WANTSETUP); 317 tulip_addr_filter(sc); 318} 319 320static void 321tulip_init( 322 int unit) 323{ 324 tulip_softc_t *sc = tulips[unit]; 325 326 if (sc->tulip_if.if_flags & IFF_UP) { 327 sc->tulip_if.if_flags |= IFF_RUNNING; 328 if (sc->tulip_if.if_flags & IFF_PROMISC) { 329 sc->tulip_cmdmode |= TULIP_CMD_PROMISCUOUS; 330 } else { 331 sc->tulip_cmdmode &= ~TULIP_CMD_PROMISCUOUS; 332 if (sc->tulip_if.if_flags & IFF_ALLMULTI) { 333 sc->tulip_cmdmode |= TULIP_CMD_ALLMULTI; 334 } else { 335 sc->tulip_cmdmode &= ~TULIP_CMD_ALLMULTI; 336 } 337 } 338 sc->tulip_cmdmode |= TULIP_CMD_TXRUN; 339 if ((sc->tulip_flags & TULIP_WANTSETUP) == 0) { 340 sc->tulip_cmdmode |= TULIP_CMD_RXRUN; 341 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED; 342 } else { 343 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; 344 tulip_start(&sc->tulip_if); 345 } 346 sc->tulip_cmdmode |= TULIP_CMD_THRSHLD160; 347 *sc->tulip_csrs.csr_intr = sc->tulip_intrmask; 348 *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; 349 } else { 350 TULIP_RESET(sc); 351 sc->tulip_if.if_flags &= ~IFF_RUNNING; 352 } 353} 354 355 356#if TULIP_CHECK_RXCRC 357static unsigned 358tulip_crc32( 359 u_char *addr, 360 int len) 361{ 362 unsigned int crc = 0xFFFFFFFF; 363 static unsigned int crctbl[256]; 364 int idx; 365 static int done; 366 /* 367 * initialize the multicast address CRC table 368 */ 369 for (idx = 0; !done && idx < 256; idx++) { 370 unsigned int tmp = idx; 371 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 372 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 373 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 374 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 375 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 376 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 377 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 378 tmp = (tmp >> 1) ^ (tmp & 1 ? TULIP_CRC32_POLY : 0); /* XOR */ 379 crctbl[idx] = tmp; 380 } 381 done = 1; 382 383 while (len-- > 0) 384 crc = (crc >> 8) ^ crctbl[*addr++] ^ crctbl[crc & 0xFF]; 385 386 return crc; 387} 388#endif 389 390static void 391tulip_rx_intr( 392 tulip_softc_t *sc) 393{ 394 tulip_ringinfo_t *ri = &sc->tulip_rxinfo; 395 struct ifnet *ifp = &sc->tulip_if; 396 397 for (;;) { 398 tulip_desc_t *eop; 399 int total_len, ndescs; 400 caddr_t bufaddr = (caddr_t) sc->tulip_rxspace; 401 402 for (ndescs = 1, eop = ri->ri_nextin;; ndescs++) { 403 if (((volatile tulip_desc_t *) eop)->d_status & TULIP_DSTS_OWNER) 404 return; 405 406 if (eop->d_status & TULIP_DSTS_RxLASTDESC) 407 break; 408 if (++eop == ri->ri_last) 409 eop = ri->ri_first; 410 } 411 412 bufaddr += TULIP_RXBUFSIZE * (ri->ri_nextin - ri->ri_first); 413 total_len = ((eop->d_status >> 16) & 0x7FF) - 4; 414 415 if ((eop->d_status & TULIP_DSTS_ERRSUM) == 0) { 416 struct ether_header eh; 417 struct mbuf *m; 418 419#if TULIP_CHECK_RXCRC 420 unsigned crc = tulip_crc32(bufaddr, total_len); 421 if (~crc != *((unsigned *) &bufaddr[total_len])) { 422 printf("de0: bad rx crc: %08x [rx] != %08x\n", 423 *((unsigned *) &bufaddr[total_len]), ~crc); 424 goto next; 425 } 426#endif 427 eh = *(struct ether_header *) bufaddr; 428 eh.ether_type = ntohs(eh.ether_type); 429#if NBPFILTER > 0 430 if (sc->tulip_bpf != NULL) { 431 bpf_tap(sc->tulip_bpf, bufaddr, total_len); 432 if (eh.ether_type != ETHERTYPE_IP && eh.ether_type != ETHERTYPE_ARP) 433 goto next; 434 if ((eh.ether_dhost[0] & 1) == 0 && 435 !TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_ac.ac_enaddr)) 436 goto next; 437 } else if (!TULIP_ADDREQUAL(eh.ether_dhost, sc->tulip_ac.ac_enaddr) 438 && !TULIP_ADDRBRDCST(eh.ether_dhost)) { 439 goto next; 440 } 441#endif 442 MGETHDR(m, M_DONTWAIT, MT_DATA); 443 if (m != NULL) { 444 m->m_pkthdr.rcvif = ifp; 445 total_len -= sizeof(eh); 446 if (total_len > MHLEN) { 447 MCLGET(m, M_DONTWAIT); 448 if ((m->m_flags & M_EXT) == 0) { 449 m_freem(m); 450 ifp->if_ierrors++; 451 goto next; 452 } 453 } 454 bcopy(bufaddr + sizeof(eh), mtod(m, caddr_t), total_len); 455 m->m_len = m->m_pkthdr.len = total_len; 456 ether_input(ifp, &eh, m); 457 } else { 458 ifp->if_ierrors++; 459 } 460 } else { 461 ifp->if_ierrors++; 462 } 463next: 464 ifp->if_ipackets++; 465 while (ndescs-- > 0) { 466 ri->ri_nextin->d_status |= TULIP_DSTS_OWNER; 467 if (++ri->ri_nextin == ri->ri_last) 468 ri->ri_nextin = ri->ri_first; 469 } 470 } 471} 472 473static int 474tulip_tx_intr( 475 tulip_softc_t *sc) 476{ 477 tulip_ringinfo_t *ri = &sc->tulip_txinfo; 478 struct mbuf *m; 479 int xmits = 0; 480 481 while (ri->ri_free < ri->ri_max) { 482 if (((volatile tulip_desc_t *) ri->ri_nextin)->d_status & TULIP_DSTS_OWNER) 483 break; 484 485 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxLASTSEG) { 486 if (ri->ri_nextin->d_flag & TULIP_DFLAG_TxSETUPPKT) { 487 /* 488 * We've just finished processing a setup packet. 489 * Mark that we can finished it. If there's not 490 * another pending, startup the TULIP receiver. 491 */ 492 sc->tulip_flags &= ~TULIP_DOINGSETUP; 493 if ((sc->tulip_flags & TULIP_WANTSETUP) == 0) { 494 sc->tulip_cmdmode |= TULIP_CMD_RXRUN; 495 sc->tulip_intrmask |= TULIP_STS_RXSTOPPED; 496 *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; 497 *sc->tulip_csrs.csr_intr = sc->tulip_intrmask; 498 } 499 } else { 500 IF_DEQUEUE(&sc->tulip_txq, m); 501 m_freem(m); 502 sc->tulip_if.if_collisions += 503 (ri->ri_nextin->d_status & TULIP_DSTS_TxCOLLMASK) 504 >> TULIP_DSTS_V_TxCOLLCNT; 505 if (ri->ri_nextin->d_status & TULIP_DSTS_ERRSUM) 506 sc->tulip_if.if_oerrors++; 507 xmits++; 508 } 509 } 510 511 if (++ri->ri_nextin == ri->ri_last) 512 ri->ri_nextin = ri->ri_first; 513 ri->ri_free++; 514 sc->tulip_if.if_flags &= ~IFF_OACTIVE; 515 } 516 sc->tulip_if.if_opackets += xmits; 517 return xmits; 518} 519 520static int 521tulip_txsegment( 522 tulip_softc_t *sc, 523 struct mbuf *m, 524 tulip_addrvec_t *avp, 525 size_t maxseg) 526{ 527 int segcnt; 528 529 for (segcnt = 0; m; m = m->m_next) { 530 int len = m->m_len; 531 caddr_t addr = mtod(m, caddr_t); 532 unsigned clsize = CLBYTES - (((u_long) addr) & (CLBYTES-1)); 533 534 while (len > 0) { 535 unsigned slen = min(len, clsize); 536 if (segcnt < maxseg) { 537 avp->addr = vtophys(addr); 538 avp->length = slen; 539 } 540 len -= slen; 541 addr += slen; 542 clsize = CLBYTES; 543 avp++; 544 segcnt++; 545 } 546 } 547 if (segcnt >= maxseg) { 548 printf("%s%d: tulip_txsegment: extremely fragmented packet dropped (%d segments)\n", 549 sc->tulip_name, sc->tulip_unit, segcnt); 550 return -1; 551 } 552 avp->addr = 0; 553 avp->length = 0; 554 return segcnt; 555} 556 557static void 558tulip_start( 559 struct ifnet *ifp) 560{ 561 tulip_softc_t *sc = (tulip_softc_t *) ifp; 562 struct ifqueue *ifq = &ifp->if_snd; 563 tulip_ringinfo_t *ri = &sc->tulip_txinfo; 564 tulip_desc_t *sop, *eop; 565 struct mbuf *m; 566 tulip_addrvec_t addrvec[TULIP_MAX_TXSEG+1], *avp; 567 int segcnt; 568 tulip_uint32_t d_status; 569 570 if ((ifp->if_flags & IFF_RUNNING) == 0) 571 return; 572 573 for (;;) { 574 if (sc->tulip_flags & TULIP_WANTSETUP) { 575 if ((sc->tulip_flags & TULIP_DOINGSETUP) || ri->ri_free == 1) { 576 ifp->if_flags |= IFF_OACTIVE; 577 return; 578 } 579 bcopy(sc->tulip_setupdata, sc->tulip_setupbuf, 580 sizeof(sc->tulip_setupbuf)); 581 sc->tulip_flags &= ~TULIP_WANTSETUP; 582 sc->tulip_flags |= TULIP_DOINGSETUP; 583 ri->ri_free--; 584 ri->ri_nextout->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN; 585 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxFIRSTSEG|TULIP_DFLAG_TxLASTSEG 586 |TULIP_DFLAG_TxSETUPPKT|TULIP_DFLAG_TxWANTINTR; 587 if (sc->tulip_flags & TULIP_WANTHASH) 588 ri->ri_nextout->d_flag |= TULIP_DFLAG_TxHASHFILT; 589 ri->ri_nextout->d_length1 = sizeof(sc->tulip_setupbuf); 590 ri->ri_nextout->d_addr1 = vtophys(sc->tulip_setupbuf); 591 ri->ri_nextout->d_length2 = 0; 592 ri->ri_nextout->d_addr2 = 0; 593 ri->ri_nextout->d_status = TULIP_DSTS_OWNER; 594 *sc->tulip_csrs.csr_txpoll = 1; 595 /* 596 * Advance the ring for the next transmit packet. 597 */ 598 if (++ri->ri_nextout == ri->ri_last) 599 ri->ri_nextout = ri->ri_first; 600 } 601 602 IF_DEQUEUE(ifq, m); 603 if (m == NULL) 604 break; 605 606 /* 607 * First find out how many and which different pages 608 * the mbuf data occupies. Then check to see if we 609 * have enough descriptor space in our transmit ring 610 * to actually send it. 611 */ 612 segcnt = tulip_txsegment(sc, m, addrvec, 613 min(ri->ri_max - 1, TULIP_MAX_TXSEG)); 614 if (segcnt < 0) { 615#if 0 616 struct mbuf *m0; 617 MGETHDR(m0, M_DONTWAIT, MT_DATA); 618 if (m0 != NULL) { 619 if (m->m_pkthdr.len > MHLEN) { 620 MCLGET(m0, M_DONTWAIT); 621 if ((m0->m_flags & M_EXT) == 0) { 622 m_freem(m); 623 continue; 624 } 625 } 626 m_copydata(m, 0, mtod(m0, caddr_t), m->m_pkthdr.len); 627 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len; 628 m_freem(m); 629 IF_PREPEND(ifq, m0); 630 continue; 631 } else { 632#endif 633 m_freem(m); 634 continue; 635#if 0 636 } 637#endif 638 } 639 if (ri->ri_free - 2 <= (segcnt + 1) >> 1) 640 break; 641 642 ri->ri_free -= (segcnt + 1) >> 1; 643 /* 644 * Now we fill in our transmit descriptors. This is 645 * a bit reminiscent of going on the Ark two by two 646 * since each descriptor for the TULIP can describe 647 * two buffers. So we advance through the address 648 * vector two entries at a time to to fill each 649 * descriptor. Clear the first and last segment bits 650 * in each descriptor (actually just clear everything 651 * but the end-of-ring or chain bits) to make sure 652 * we don't get messed up by previously sent packets. 653 */ 654 sop = ri->ri_nextout; 655 d_status = 0; 656 avp = addrvec; 657 do { 658 eop = ri->ri_nextout; 659 eop->d_flag &= TULIP_DFLAG_ENDRING|TULIP_DFLAG_CHAIN; 660 eop->d_status = d_status; 661 eop->d_addr1 = avp->addr; eop->d_length1 = avp->length; avp++; 662 eop->d_addr2 = avp->addr; eop->d_length2 = avp->length; avp++; 663 d_status = TULIP_DSTS_OWNER; 664 if (++ri->ri_nextout == ri->ri_last) 665 ri->ri_nextout = ri->ri_first; 666 } while ((segcnt -= 2) > 0); 667 668 /* 669 * The descriptors have been filled in. Mark the first 670 * and last segments, indicate we want a transmit complete 671 * interrupt, give the descriptors to the TULIP, and tell 672 * it to transmit! 673 */ 674 IF_ENQUEUE(&sc->tulip_txq, m); 675 eop->d_flag |= TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR; 676 sop->d_flag |= TULIP_DFLAG_TxFIRSTSEG; 677 sop->d_status = TULIP_DSTS_OWNER; 678 679 *sc->tulip_csrs.csr_txpoll = 1; 680 } 681 if (m != NULL) { 682 ifp->if_flags |= IFF_OACTIVE; 683 IF_PREPEND(ifq, m); 684 } 685} 686 687static int 688tulip_intr( 689 tulip_softc_t *sc) 690{ 691 tulip_uint32_t csr; 692 693 while ((csr = *sc->tulip_csrs.csr_status) & (TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR)) { 694 *sc->tulip_csrs.csr_status = csr & sc->tulip_intrmask; 695 696 if (csr & TULIP_STS_SYSERROR) { 697 if ((csr & TULIP_STS_ERRORMASK) == TULIP_STS_ERR_PARITY) { 698 TULIP_RESET(sc); 699 tulip_init(sc->tulip_unit); 700 return 1; 701 } 702 } 703 if (csr & TULIP_STS_RXINTR) 704 tulip_rx_intr(sc); 705 if (sc->tulip_txinfo.ri_free < sc->tulip_txinfo.ri_max) { 706 tulip_tx_intr(sc); 707 tulip_start(&sc->tulip_if); 708 } 709 if (csr & TULIP_STS_ABNRMLINTR) { 710 printf("%s%d: abnormal interrupt: 0x%05x [0x%05x]\n", 711 sc->tulip_name, sc->tulip_unit, csr, csr & sc->tulip_intrmask); 712 *sc->tulip_csrs.csr_command = sc->tulip_cmdmode; 713 } 714 } 715 return 1; 716} 717 718/* 719 * This is the standard method of reading the DEC Address ROMS. 720 */ 721static int 722tulip_read_macaddr( 723 tulip_softc_t *sc) 724{ 725 int cksum, rom_cksum, idx; 726 tulip_sint32_t csr; 727 unsigned char tmpbuf[8]; 728 static u_char testpat[] = { 0xFF, 0, 0x55, 0xAA, 0xFF, 0, 0x55, 0xAA }; 729 730 *sc->tulip_csrs.csr_enetrom = 1; 731 for (idx = 0; idx < 32; idx++) { 732 int cnt = 0; 733 while ((csr = *sc->tulip_csrs.csr_enetrom) < 0 && cnt < 10000) 734 cnt++; 735 sc->tulip_rombuf[idx] = csr & 0xFF; 736 } 737 738 if (bcmp(&sc->tulip_rombuf[0], &sc->tulip_rombuf[16], 8) != 0) 739 return -4; 740 if (bcmp(&sc->tulip_rombuf[24], testpat, 8) != 0) 741 return -3; 742 743 tmpbuf[0] = sc->tulip_rombuf[15]; tmpbuf[1] = sc->tulip_rombuf[14]; 744 tmpbuf[2] = sc->tulip_rombuf[13]; tmpbuf[3] = sc->tulip_rombuf[12]; 745 tmpbuf[4] = sc->tulip_rombuf[11]; tmpbuf[5] = sc->tulip_rombuf[10]; 746 tmpbuf[6] = sc->tulip_rombuf[9]; tmpbuf[7] = sc->tulip_rombuf[8]; 747 if (bcmp(&sc->tulip_rombuf[0], tmpbuf, 8) != 0) 748 return -2; 749 750 bcopy(sc->tulip_rombuf, sc->tulip_hwaddr, 6); 751 752 cksum = *(u_short *) &sc->tulip_hwaddr[0]; 753 cksum *= 2; 754 if (cksum > 65535) cksum -= 65535; 755 cksum += *(u_short *) &sc->tulip_hwaddr[2]; 756 if (cksum > 65535) cksum -= 65535; 757 cksum *= 2; 758 if (cksum > 65535) cksum -= 65535; 759 cksum += *(u_short *) &sc->tulip_hwaddr[4]; 760 if (cksum >= 65535) cksum -= 65535; 761 762 rom_cksum = *(u_short *) &sc->tulip_rombuf[6]; 763 764 if (cksum != rom_cksum) 765 return -1; 766 return 0; 767} 768 769static unsigned 770tulip_mchash( 771 unsigned char *mca) 772{ 773 u_int idx, bit, data, crc = 0xFFFFFFFFUL; 774 775#ifdef __alpha 776 for (data = *(__unaligned u_long *) mca, bit = 0; bit < 48; bit++, data >>= 7771) 778 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0); 779#else 780 for (idx = 0; idx < 6; idx++) 781 for (data = *mca++, bit = 0; bit < 8; bit++, data >>= 1) 782 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0); 783#endif 784 return crc & 0x1FF; 785} 786 787static void 788tulip_addr_filter( 789 tulip_softc_t *sc) 790{ 791 tulip_uint32_t *sp = sc->tulip_setupdata; 792 struct ether_multistep step; 793 struct ether_multi *enm; 794 int i; 795 796 sc->tulip_flags &= ~TULIP_WANTHASH; 797 sc->tulip_flags |= TULIP_WANTSETUP; 798 sc->tulip_cmdmode &= ~TULIP_CMD_RXRUN; 799 sc->tulip_intrmask &= ~TULIP_STS_RXSTOPPED; 800 if (sc->tulip_ac.ac_multicnt > 14) { 801 unsigned hash; 802 /* 803 * If we have more than 14 multicasts, we have 804 * go into hash perfect mode (512 bit multicast 805 * hash and one perfect hardware). 806 */ 807 808 bzero(sc->tulip_setupdata, sizeof(sc->tulip_setupdata)); 809 hash = tulip_mchash(etherbroadcastaddr); 810 sp[hash >> 4] |= 1 << (hash & 0xF); 811 ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); 812 while (enm != NULL) { 813 hash = tulip_mchash(enm->enm_addrlo); 814 sp[hash >> 4] |= 1 << (hash & 0xF); 815 ETHER_NEXT_MULTI(step, enm); 816 } 817 sc->tulip_cmdmode |= TULIP_WANTHASH; 818 sp[40] = ((u_short *) sc->tulip_ac.ac_enaddr)[0]; 819 sp[41] = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; 820 sp[42] = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; 821 } else { 822 /* 823 * Else can get perfect filtering for 16 addresses. 824 */ 825 i = 0; 826 ETHER_FIRST_MULTI(step, &sc->tulip_ac, enm); 827 for (; enm != NULL; i++) { 828 *sp++ = ((u_short *) enm->enm_addrlo)[0]; 829 *sp++ = ((u_short *) enm->enm_addrlo)[1]; 830 *sp++ = ((u_short *) enm->enm_addrlo)[2]; 831 ETHER_NEXT_MULTI(step, enm); 832 } 833 /* 834 * If an IP address is enabled, turn on broadcast 835 */ 836 if (sc->tulip_ac.ac_ipaddr.s_addr != 0) { 837 i++; 838 *sp++ = 0xFFFF; 839 *sp++ = 0xFFFF; 840 *sp++ = 0xFFFF; 841 } 842 /* 843 * Pad the rest with our hardware address 844 */ 845 for (; i < 16; i++) { 846 *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[0]; 847 *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[1]; 848 *sp++ = ((u_short *) sc->tulip_ac.ac_enaddr)[2]; 849 } 850 } 851} 852 853static int 854tulip_ioctl( 855 struct ifnet *ifp, 856 int cmd, 857 caddr_t data) 858{ 859 tulip_softc_t *sc = tulips[ifp->if_unit]; 860 int s, error = 0; 861 862 s = splimp(); 863 864 switch (cmd) { 865 case SIOCSIFADDR: { 866 struct ifaddr *ifa = (struct ifaddr *)data; 867 868 ifp->if_flags |= IFF_UP; 869 switch(ifa->ifa_addr->sa_family) { 870#ifdef INET 871 case AF_INET: { 872 ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN(ifa)->sin_addr; 873 (*ifp->if_init)(ifp->if_unit); 874 arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); 875 break; 876 } 877#endif /* INET */ 878 879#ifdef NS 880 /* This magic copied from if_is.c; I don't use XNS, 881 * so I have no way of telling if this actually 882 * works or not. 883 */ 884 case AF_NS: { 885 struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); 886 if (ns_nullhost(*ina)) { 887 ina->x_host = *(union ns_host *)(sc->tulip_ac.ac_enaddr); 888 } else { 889 ifp->if_flags &= ~IFF_RUNNING; 890 bcopy((caddr_t)ina->x_host.c_host, 891 (caddr_t)sc->tulip_ac.ac_enaddr, 892 sizeof sc->tulip_ac.ac_enaddr); 893 } 894 895 (*ifp->if_init)(ifp->if_unit); 896 break; 897 } 898#endif /* NS */ 899 900 default: { 901 (*ifp->if_init)(ifp->if_unit); 902 break; 903 } 904 } 905 break; 906 } 907 908 case SIOCSIFFLAGS: { 909 /* 910 * Changing the connection forces a reset. 911 */ 912 if (sc->tulip_flags & TULIP_ALTPHYS) { 913 if ((ifp->if_flags & IFF_ALTPHYS) == 0) 914 TULIP_RESET(sc); 915 } else { 916 if (ifp->if_flags & IFF_ALTPHYS) 917 TULIP_RESET(sc); 918 } 919 (*ifp->if_init)(ifp->if_unit); 920 break; 921 } 922 923 case SIOCADDMULTI: 924 case SIOCDELMULTI: { 925 /* 926 * Update multicast listeners 927 */ 928 if (cmd == SIOCADDMULTI) 929 error = ether_addmulti((struct ifreq *)data, &sc->tulip_ac); 930 else 931 error = ether_delmulti((struct ifreq *)data, &sc->tulip_ac); 932 933 if (error == ENETRESET) { 934 tulip_addr_filter(sc); /* reset multicast filtering */ 935 (*ifp->if_init)(ifp->if_unit); 936 error = 0; 937 } 938 break; 939 } 940 941 default: { 942 error = EINVAL; 943 break; 944 } 945 } 946 947 splx(s); 948 return error; 949} 950 951static void 952tulip_attach( 953 tulip_softc_t *sc) 954{ 955 struct ifnet *ifp = &sc->tulip_if; 956 struct ifaddr *ifa = ifp->if_addrlist; 957 int cnt; 958 959 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; 960 961 *sc->tulip_csrs.csr_sia_connectivity = 0; 962 *sc->tulip_csrs.csr_sia_connectivity = TULIP_SIACONN_10BASET; 963 for (cnt = 0; cnt < 240000; cnt++) { 964 if ((*sc->tulip_csrs.csr_sia_status & TULIP_SIASTS_LINKFAIL) == 0) 965 break; 966 DELAY(10); 967 } 968 if (*sc->tulip_csrs.csr_sia_status & TULIP_SIASTS_LINKFAIL) { 969 ifp->if_flags |= IFF_ALTPHYS; 970 } else { 971 sc->tulip_flags |= TULIP_ALTPHYS; 972 } 973 TULIP_RESET(sc); 974 975 ifp->if_init = tulip_init; 976 ifp->if_ioctl = tulip_ioctl; 977 ifp->if_output = ether_output; 978 ifp->if_reset = tulip_reset; 979 ifp->if_start = tulip_start; 980 981 printf("%s%d: %s pass %d.%d ethernet address %s\n", 982 sc->tulip_name, sc->tulip_unit, 983 tulip_chipdescs[tulip_chipids[sc->tulip_unit]], 984 (sc->tulip_revinfo & 0xF0) >> 4, 985 sc->tulip_revinfo & 0x0F, 986 ether_sprintf(sc->tulip_hwaddr)); 987 988 if_attach(ifp); 989 990#if NBPFILTER > 0 991 bpfattach(&sc->tulip_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); 992#endif 993} 994 995static void 996tulip_initcsrs( 997 tulip_softc_t *sc, 998 volatile tulip_uint32_t *va_csrs, 999 size_t csr_size) 1000{ 1001 sc->tulip_csrs.csr_busmode = va_csrs + 0 * csr_size; 1002 sc->tulip_csrs.csr_txpoll = va_csrs + 1 * csr_size; 1003 sc->tulip_csrs.csr_rxpoll = va_csrs + 2 * csr_size; 1004 sc->tulip_csrs.csr_rxlist = va_csrs + 3 * csr_size; 1005 sc->tulip_csrs.csr_txlist = va_csrs + 4 * csr_size; 1006 sc->tulip_csrs.csr_status = va_csrs + 5 * csr_size; 1007 sc->tulip_csrs.csr_command = va_csrs + 6 * csr_size; 1008 sc->tulip_csrs.csr_intr = va_csrs + 7 * csr_size; 1009 sc->tulip_csrs.csr_missed_frame = va_csrs + 8 * csr_size; 1010 sc->tulip_csrs.csr_enetrom = va_csrs + 9 * csr_size; 1011 sc->tulip_csrs.csr_reserved = va_csrs + 10 * csr_size; 1012 sc->tulip_csrs.csr_full_duplex = va_csrs + 11 * csr_size; 1013 sc->tulip_csrs.csr_sia_status = va_csrs + 12 * csr_size; 1014 sc->tulip_csrs.csr_sia_connectivity = va_csrs + 13 * csr_size; 1015 sc->tulip_csrs.csr_sia_tx_rx = va_csrs + 14 * csr_size; 1016 sc->tulip_csrs.csr_sia_general = va_csrs + 15 * csr_size; 1017} 1018 1019static void 1020tulip_initring( 1021 tulip_softc_t *sc, 1022 tulip_ringinfo_t *ri, 1023 tulip_desc_t *descs, 1024 int ndescs) 1025{ 1026 ri->ri_max = ndescs; 1027 ri->ri_first = descs; 1028 ri->ri_last = ri->ri_first + ri->ri_max; 1029 bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max); 1030 ri->ri_last[-1].d_flag = TULIP_DFLAG_ENDRING; 1031} 1032 1033#if NPCI > 0 1034/* 1035 * This is the PCI configuration support. Since the DC21040 is available 1036 * on both EISA and PCI boards, one must be careful in how defines the 1037 * DC21040 in the config file. 1038 */ 1039static char* tulip_pci_probe (pcici_t config_id, pcidi_t device_id); 1040static void tulip_pci_attach(pcici_t config_id, int unit); 1041static u_long tulip_count; 1042 1043struct pci_driver dedevice = { 1044 tulip_pci_probe, 1045 tulip_pci_attach, 1046 &tulip_count, 1047}; 1048 1049#define PCI_CFID 0x00 /* Configuration ID */ 1050#define PCI_CFCS 0x04 /* Configurtion Command/Status */ 1051#define PCI_CFRV 0x08 /* Configuration Revision */ 1052#define PCI_CFLT 0x0c /* Configuration Latency Timer */ 1053#define PCI_CBIO 0x10 /* Configuration Base IO Address */ 1054#define PCI_CBMA 0x14 /* Configuration Base Memory Address */ 1055#define PCI_CFIT 0x3c /* Configuration Interrupt */ 1056#define PCI_CFDA 0x40 /* Configuration Driver Area */ 1057 1058#define TULIP_PCI_CSRSIZE (8 / sizeof(tulip_uint32_t)) 1059static char* 1060tulip_pci_probe( 1061 pcici_t config_id, 1062 pcidi_t device_id) 1063{ 1064 int idx; 1065 for (idx = 0; idx < NDE; idx++) { 1066 if (tulips[idx] == NULL) { 1067 if (device_id == 0x00021011ul) { 1068 tulip_chipids[idx] = TULIP_DC21040; 1069 return "digital dc21040 ethernet"; 1070 } 1071 if (device_id == 0x00091011ul) { 1072 tulip_chipids[idx] = TULIP_DC21140; 1073 return "digital dc21140 fast ethernet"; 1074 } 1075 return NULL; 1076 } 1077 } 1078 return NULL; 1079} 1080 1081static void 1082tulip_pci_attach( 1083 pcici_t config_id, 1084 int unit) 1085{ 1086 tulip_softc_t *sc; 1087 int retval, idx; 1088 vm_offset_t va_csrs, pa_csrs; 1089 tulip_desc_t *rxdescs, *txdescs; 1090 1091 sc = (tulip_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); 1092 if (sc == NULL) 1093 return; 1094 1095 rxdescs = (tulip_desc_t *) 1096 malloc(sizeof(tulip_desc_t) * TULIP_RXDESCS, M_DEVBUF, M_NOWAIT); 1097 if (rxdescs == NULL) { 1098 free((caddr_t) sc, M_DEVBUF); 1099 return; 1100 } 1101 1102 txdescs = (tulip_desc_t *) 1103 malloc(sizeof(tulip_desc_t) * TULIP_TXDESCS, M_DEVBUF, M_NOWAIT); 1104 if (txdescs == NULL) { 1105 free((caddr_t) rxdescs, M_DEVBUF); 1106 free((caddr_t) sc, M_DEVBUF); 1107 return; 1108 } 1109 1110 bzero(sc, sizeof(sc)); /* Zero out the softc*/ 1111 sc->tulip_rxspace = kmem_alloc(kernel_map, TULIP_RXSPACE + NBPG); 1112 /* 1113 * We've allocated an extra page of receive space so we can double map 1114 * the first page of the receive space into the page after the last page 1115 * of the receive space. This means that even if a receive wraps around 1116 * the end of the receive space, it will still virtually contiguous and 1117 * that greatly simplifies the recevie logic. 1118 */ 1119 pmap_enter(pmap_kernel(), sc->tulip_rxspace + TULIP_RXSPACE, 1120 vtophys(sc->tulip_rxspace), VM_PROT_READ, TRUE); 1121 1122 sc->tulip_unit = unit; 1123 sc->tulip_name = "de"; 1124 retval = pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs); 1125 if (!retval) { 1126 kmem_free(kernel_map, sc->tulip_rxspace, TULIP_RXSPACE + NBPG); 1127 free((caddr_t) txdescs, M_DEVBUF); 1128 free((caddr_t) rxdescs, M_DEVBUF); 1129 free((caddr_t) sc, M_DEVBUF); 1130 return; 1131 } 1132 tulips[unit] = sc; 1133 tulip_initcsrs(sc, (volatile tulip_uint32_t *) va_csrs, TULIP_PCI_CSRSIZE); 1134 tulip_initring(sc, &sc->tulip_rxinfo, rxdescs, TULIP_RXDESCS); 1135 tulip_initring(sc, &sc->tulip_txinfo, txdescs, TULIP_TXDESCS); 1136 sc->tulip_revinfo = pci_conf_read(config_id, PCI_CFRV); 1137 if ((retval = tulip_read_macaddr(sc)) < 0) { 1138 printf("de%d: can't read ENET ROM (why=%d) (", sc->tulip_unit, retval); 1139 for (idx = 0; idx < 32; idx++) 1140 printf("%02x", sc->tulip_rombuf[idx]); 1141 printf("\n"); 1142 printf("%s%d: %s %d.%d ethernet address %s\n", 1143 sc->tulip_name, sc->tulip_unit, 1144 tulip_chipdescs[tulip_chipids[sc->tulip_unit]], 1145 (sc->tulip_revinfo & 0xF0) >> 4, sc->tulip_revinfo & 0x0F, 1146 "unknown"); 1147 } else { 1148 pci_map_int (config_id, tulip_intr, (void*) sc, &net_imask); 1149 TULIP_RESET(sc); 1150 tulip_attach(sc); 1151 } 1152} 1153#endif /* NPCI > 0 */ 1154#endif /* NDE > 0 */ 1155