|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1990, 1991 William F. Jolitz. ! 3: * Copyright (c) 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * Redistribution and use in source and binary forms, with or without ! 7: * modification, are permitted provided that the following conditions ! 8: * are met: ! 9: * 1. Redistributions of source code must retain the above copyright ! 10: * notice, this list of conditions and the following disclaimer. ! 11: * 2. Redistributions in binary form must reproduce the above copyright ! 12: * notice, this list of conditions and the following disclaimer in the ! 13: * documentation and/or other materials provided with the distribution. ! 14: * 3. All advertising materials mentioning features or use of this software ! 15: * must display the following acknowledgement: ! 16: * This product includes software developed by the University of ! 17: * California, Berkeley and its contributors. ! 18: * 4. Neither the name of the University nor the names of its contributors ! 19: * may be used to endorse or promote products derived from this software ! 20: * without specific prior written permission. ! 21: * ! 22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 32: * SUCH DAMAGE. ! 33: * ! 34: * @(#)if_ne.c 7.4 (Berkeley) 5/21/91 ! 35: */ ! 36: ! 37: /* ! 38: * Isolink 4110-2 Ethernet driver ! 39: */ ! 40: ! 41: #include "is.h" ! 42: #if NIS > 0 ! 43: ! 44: #include "param.h" ! 45: #include "systm.h" ! 46: #include "mbuf.h" ! 47: #include "buf.h" ! 48: #include "protosw.h" ! 49: #include "socket.h" ! 50: #include "ioctl.h" ! 51: #include "errno.h" ! 52: #include "syslog.h" ! 53: ! 54: #include "net/if.h" ! 55: #include "net/netisr.h" ! 56: #include "net/route.h" ! 57: ! 58: #ifdef INET ! 59: #include "netinet/in.h" ! 60: #include "netinet/in_systm.h" ! 61: #include "netinet/in_var.h" ! 62: #include "netinet/ip.h" ! 63: #include "netinet/if_ether.h" ! 64: #endif ! 65: ! 66: #ifdef NS ! 67: #include "netns/ns.h" ! 68: #include "netns/ns_if.h" ! 69: #endif ! 70: ! 71: #include "i386/isa/isa_device.h" ! 72: #include "i386/isa/if_isreg.h" ! 73: #include "i386/isa/icu.h" ! 74: ! 75: #include "vm/vm.h" ! 76: ! 77: /* Function prototypes */ ! 78: int isprobe(), isattach(); ! 79: int isioctl(),isinit(),isstart(); ! 80: ! 81: struct isa_driver isdriver = { ! 82: isprobe, isattach, "is", ! 83: }; ! 84: ! 85: ! 86: struct mbuf *isget(); ! 87: ! 88: #define ETHER_MIN_LEN 64 ! 89: ! 90: /* ! 91: * Ethernet software status per interface. ! 92: * ! 93: * Each interface is referenced by a network interface structure, ! 94: * ns_if, which the routing code uses to locate the interface. ! 95: * This structure contains the output queue for the interface, its address, ... ! 96: */ ! 97: struct is_softc { ! 98: struct arpcom ns_ac; /* Ethernet common part */ ! 99: #define ns_if ns_ac.ac_if /* network-visible interface */ ! 100: #define ns_addr ns_ac.ac_enaddr /* hardware Ethernet address */ ! 101: int last_rd; ! 102: int last_td; ! 103: int no_td; ! 104: } is_softc[NIS] ; ! 105: ! 106: struct init_block init_block; ! 107: struct mds *td, *rd; ! 108: unsigned char *rbuf,*tbuf; ! 109: ! 110: int isc; ! 111: ! 112: iswrcsr(port,val) ! 113: u_short port; ! 114: u_short val; ! 115: { ! 116: outw(isc+RAP,port); ! 117: outw(isc+RDP,val); ! 118: } ! 119: ! 120: u_short isrdcsr(port) ! 121: u_short port; ! 122: { ! 123: outw(isc+RAP,port); ! 124: return(inw(isc+RDP)); ! 125: } ! 126: ! 127: isprobe(dvp) ! 128: struct isa_device *dvp; ! 129: { ! 130: int val,i,s; ! 131: register struct is_softc *ns = &is_softc[0]; ! 132: ! 133: isc = dvp->id_iobase; ! 134: s = splimp(); ! 135: ! 136: /* Stop the lance chip, put it known state */ ! 137: iswrcsr(0,STOP); ! 138: DELAY(100); ! 139: ! 140: /* is there a lance? */ ! 141: iswrcsr(3, 0xffff); ! 142: if (isrdcsr(3) != 7) { ! 143: isc = 0; ! 144: return (0); ! 145: } ! 146: iswrcsr(3, 0); ! 147: ! 148: /* Extract board address */ ! 149: for(i=0; i < 6; i++) ns->ns_addr[i] = inb(isc+(i*2)); ! 150: ! 151: splx(s); ! 152: return (1); ! 153: } ! 154: ! 155: ! 156: ! 157: /* ! 158: * Reset of interface. ! 159: */ ! 160: isreset(unit, uban) ! 161: int unit, uban; ! 162: { ! 163: if (unit >= NIS) ! 164: return; ! 165: printf("is%d: reset\n", unit); ! 166: isinit(unit); ! 167: } ! 168: ! 169: /* ! 170: * Interface exists: make available by filling in network interface ! 171: * record. System will initialize the interface when it is ready ! 172: * to accept packets. We get the ethernet address here. ! 173: */ ! 174: isattach(dvp) ! 175: struct isa_device *dvp; ! 176: { ! 177: int unit = dvp->id_unit; ! 178: register struct is_softc *is = &is_softc[unit]; ! 179: register struct ifnet *ifp = &is->ns_if; ! 180: ! 181: /* Set up DMA */ ! 182: isa_dmacascade(dvp->id_drq); ! 183: ! 184: ifp->if_unit = unit; ! 185: ifp->if_name = isdriver.name ; ! 186: ifp->if_mtu = ETHERMTU; ! 187: printf (" ethernet address %s", ether_sprintf(is->ns_addr)) ; ! 188: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS; ! 189: ifp->if_init = isinit; ! 190: ifp->if_output = ether_output; ! 191: ifp->if_start = isstart; ! 192: ifp->if_ioctl = isioctl; ! 193: ifp->if_reset = isreset; ! 194: ifp->if_watchdog = 0; ! 195: if_attach(ifp); ! 196: } ! 197: ! 198: ! 199: /* Lance initialisation block set up */ ! 200: init_mem() ! 201: { ! 202: int i; ! 203: u_long temp; ! 204: ! 205: /* Allocate memory */ ! 206: /* Temporary hack, will use kmem_alloc in future */ ! 207: #define MAXMEM ((NRBUF+NTBUF)*(BUFSIZE) + (NRBUF+NTBUF)*sizeof(struct mds) + 8) ! 208: static u_char lance_mem[MAXMEM]; ! 209: ! 210: ! 211: /* Align message descriptors on quad word boundary ! 212: (this is essential) */ ! 213: ! 214: temp = (u_long) &lance_mem; ! 215: temp = (temp+8) - (temp%8); ! 216: rd = (struct mds *) temp; ! 217: td = (struct mds *) (temp + (NRBUF*sizeof(struct mds))); ! 218: temp += (NRBUF+NTBUF) * sizeof(struct mds); ! 219: ! 220: init_block.mode = 0; ! 221: ! 222: /* Get ethernet address */ ! 223: for (i=0; i<6; i++) ! 224: init_block.padr[i] = inb(isc+(i*2)); ! 225: ! 226: /* Clear multicast address for now */ ! 227: for (i=0; i<8; i++) ! 228: init_block.ladrf[i] = 0; ! 229: ! 230: init_block.rdra = kvtop(rd); ! 231: init_block.rlen = ((kvtop(rd) >> 16) & 0xff) | (RLEN<<13); ! 232: init_block.tdra = kvtop(td); ! 233: init_block.tlen = ((kvtop(td) >> 16) & 0xff) | (TLEN<<13); ! 234: ! 235: /* Set up receive ring descriptors */ ! 236: rbuf = (unsigned char *)temp; ! 237: for (i=0; i<NRBUF; i++) { ! 238: (rd+i)->addr = kvtop(temp); ! 239: (rd+i)->flags= ((kvtop(temp) >> 16) & 0xff) | OWN; ! 240: (rd+i)->bcnt = -BUFSIZE; ! 241: (rd+i)->mcnt = 0; ! 242: temp += BUFSIZE; ! 243: } ! 244: ! 245: /* Set up transmit ring descriptors */ ! 246: tbuf = (unsigned char *)temp; ! 247: #ifdef ISDEBUG ! 248: printf("rd = %x,td = %x, rbuf = %x, tbuf = %x,td+1=%x\n",rd,td,rbuf,tbuf,td+1); ! 249: #endif ! 250: for (i=0; i<NTBUF; i++) { ! 251: (td+i)->addr = kvtop(temp); ! 252: (td+i)->flags= ((kvtop(temp) >> 16) & 0xff); ! 253: (td+i)->bcnt = 0; ! 254: (td+i)->mcnt = 0; ! 255: temp += BUFSIZE; ! 256: } ! 257: ! 258: } ! 259: ! 260: /* ! 261: * Initialization of interface; set up initialization block ! 262: * and transmit/receive descriptor rings. ! 263: */ ! 264: isinit(unit) ! 265: int unit; ! 266: { ! 267: register struct is_softc *ns = &is_softc[unit]; ! 268: struct ifnet *ifp = &ns->ns_if; ! 269: int s; ! 270: register i; ! 271: ! 272: if (ifp->if_addrlist == (struct ifaddr *)0) return; ! 273: ! 274: ns->last_rd = ns->last_td = ns->no_td = 0; ! 275: s = splimp(); ! 276: ! 277: /* Set up lance's memory area */ ! 278: init_mem(); ! 279: ! 280: /* Stop Lance to get access to other registers */ ! 281: iswrcsr(0,STOP); ! 282: ! 283: /* I wish I knew what this was */ ! 284: iswrcsr(3,0); ! 285: ! 286: /* Give lance the physical address of its memory area */ ! 287: iswrcsr(1,kvtop(&init_block)); ! 288: iswrcsr(2,(kvtop(&init_block) >> 16) & 0xff); ! 289: ! 290: /* OK, let's try and initialise the Lance */ ! 291: iswrcsr(0,INIT); ! 292: ! 293: /* Wait for initialisation to finish */ ! 294: for(i=0; i<1000; i++){ ! 295: if (isrdcsr(0)&IDON) ! 296: break; ! 297: } ! 298: if (isrdcsr(0)&IDON) { ! 299: /* Start lance */ ! 300: iswrcsr(0,STRT|IDON|INEA); ! 301: ns->ns_if.if_flags |= IFF_RUNNING; ! 302: isstart(ifp); ! 303: } ! 304: else ! 305: printf("Isolink card failed to initialise\n"); ! 306: ! 307: splx(s); ! 308: } ! 309: ! 310: /* ! 311: * Setup output on interface. ! 312: * Get another datagram to send off of the interface queue, ! 313: * and map it to the interface before starting the output. ! 314: * called only at splimp or interrupt level. ! 315: */ ! 316: isstart(ifp) ! 317: struct ifnet *ifp; ! 318: { ! 319: register struct is_softc *ns = &is_softc[ifp->if_unit]; ! 320: struct mbuf *m0, *m; ! 321: unsigned char *buffer; ! 322: u_short len; ! 323: int i; ! 324: struct mds *cdm; ! 325: ! 326: ! 327: if ((ns->ns_if.if_flags & IFF_RUNNING) == 0) ! 328: return; ! 329: ! 330: do { ! 331: cdm = (td + ns->last_td); ! 332: if (cdm->flags&OWN) ! 333: return; ! 334: ! 335: IF_DEQUEUE(&ns->ns_if.if_snd, m); ! 336: ! 337: if (m == 0) ! 338: return; ! 339: ! 340: /* ! 341: * Copy the mbuf chain into the transmit buffer ! 342: */ ! 343: ! 344: buffer = tbuf+(BUFSIZE*ns->last_td); ! 345: len=0; ! 346: for (m0=m; m != 0; m=m->m_next) { ! 347: bcopy(mtod(m,caddr_t),buffer,m->m_len); ! 348: buffer += m->m_len; ! 349: len += m->m_len; ! 350: } ! 351: ! 352: m_freem(m0); ! 353: len = MAX(len,ETHER_MIN_LEN); ! 354: ! 355: /* ! 356: * Init transmit registers, and set transmit start flag. ! 357: */ ! 358: ! 359: cdm->flags |= (OWN|STP|ENP); ! 360: cdm->bcnt = -len; ! 361: cdm->mcnt = 0; ! 362: #ifdef ISDEBUG ! 363: xmit_print(ns->last_td); ! 364: #endif ! 365: ! 366: iswrcsr(0,TDMD|INEA); ! 367: if (++ns->last_td >= NTBUF) ! 368: ns->last_td=0; ! 369: }while(++ns->no_td < NTBUF); ! 370: ns->no_td = NTBUF; ! 371: ns->ns_if.if_flags |= IFF_OACTIVE; ! 372: #ifdef ISDEBUG ! 373: printf("no_td = %x, last_td = %x\n",ns->no_td, ns->last_td); ! 374: #endif ! 375: return(0); ! 376: } ! 377: ! 378: ! 379: /* ! 380: * Controller interrupt. ! 381: */ ! 382: isintr(unit) ! 383: { ! 384: register struct is_softc *ns = &is_softc[unit]; ! 385: u_short isr; ! 386: ! 387: while((isr=isrdcsr(0))&INTR) { ! 388: if (isr&ERR) { ! 389: if (isr&BABL) ! 390: printf("BABL\n"); ! 391: if (isr&CERR) ! 392: printf("CERR\n"); ! 393: if (isr&MISS) ! 394: printf("MISS\n"); ! 395: if (isr&MERR) ! 396: printf("MERR\n"); ! 397: iswrcsr(0,BABL|CERR|MISS|MERR|INEA); ! 398: } ! 399: if (!(isr&TXON)) { ! 400: isreset(unit); ! 401: return(1); ! 402: } ! 403: if (!(isr&RXON)) { ! 404: isreset(unit); ! 405: return(1); ! 406: } ! 407: if (isr&RINT) { ! 408: isrint(unit); ! 409: } ! 410: if (isr&TINT) { ! 411: iswrcsr(0,TINT|INEA); ! 412: istint(unit); ! 413: } ! 414: } ! 415: } ! 416: ! 417: istint(unit) ! 418: int unit; ! 419: { ! 420: struct is_softc *is = &is_softc[unit]; ! 421: register struct ifnet *ifp = &is->ns_if; ! 422: int i,loopcount=0; ! 423: struct mds *cdm; ! 424: ! 425: do { ! 426: if ((i=is->last_td - is->no_td) < 0) ! 427: i+=NTBUF; ! 428: cdm = (td+i); ! 429: #ifdef ISDEBUG ! 430: printf("Trans cdm = %x\n",cdm); ! 431: #endif ! 432: if (cdm->flags&OWN) { ! 433: if (loopcount) ! 434: break; ! 435: return; ! 436: } ! 437: loopcount++; ! 438: is->ns_if.if_flags &= ~IFF_OACTIVE; ! 439: }while(--is->no_td > 0); ! 440: isstart(ifp); ! 441: ! 442: } ! 443: ! 444: #define NEXTRDS \ ! 445: if (++rmd == NRBUF) rmd=0, cdm=rd; else ++cdm ! 446: ! 447: isrint(unit) ! 448: int unit; ! 449: { ! 450: register struct is_softc *is=&is_softc[unit]; ! 451: register int rmd = is->last_rd; ! 452: struct mds *cdm = (rd + rmd); ! 453: ! 454: /* Out of sync with hardware, should never happen */ ! 455: ! 456: if (cdm->flags & OWN) { ! 457: printf("is0 error: out of sync\n"); ! 458: iswrcsr(0,RINT|INEA); ! 459: return; ! 460: } ! 461: ! 462: /* Process all buffers with valid data */ ! 463: while (!(cdm->flags&OWN)) { ! 464: /* Clear interrupt to avoid race condition */ ! 465: iswrcsr(0,RINT|INEA); ! 466: if (cdm->flags&ERR) { ! 467: if (cdm->flags&FRAM) ! 468: printf("FRAM\n"); ! 469: if (cdm->flags&OFLO) ! 470: printf("OFLO\n"); ! 471: if (cdm->flags&CRC) ! 472: printf("CRC\n"); ! 473: if (cdm->flags&RBUFF) ! 474: printf("RBUFF\n"); ! 475: }else ! 476: if (cdm->flags&(STP|ENP) != (STP|ENP)) { ! 477: do { ! 478: iswrcsr(0,RINT|INEA); ! 479: cdm->mcnt = 0; ! 480: cdm->flags |= OWN; ! 481: NEXTRDS; ! 482: }while (!(cdm->flags&(OWN|ERR|STP|ENP))); ! 483: is->last_rd = rmd; ! 484: printf("Chained buffer\n"); ! 485: if ((cdm->flags & (OWN|ERR|STP|ENP)) != ENP) { ! 486: isreset(unit); ! 487: return; ! 488: } ! 489: }else ! 490: { ! 491: #ifdef ISDEBUG ! 492: recv_print(is->last_rd); ! 493: #endif ! 494: isread(is,rbuf+(BUFSIZE*rmd),cdm->mcnt); ! 495: } ! 496: ! 497: cdm->flags |= OWN; ! 498: cdm->mcnt = 0; ! 499: NEXTRDS; ! 500: #ifdef ISDEBUG ! 501: printf("is->last_rd = %x, cdm = %x\n",is->last_rd,cdm); ! 502: #endif ! 503: } /* while */ ! 504: is->last_rd = rmd; ! 505: } /* isrint */ ! 506: ! 507: /* ! 508: * Pass a packet to the higher levels. ! 509: * We deal with the trailer protocol here. ! 510: */ ! 511: isread(ns, buf, len) ! 512: register struct is_softc *ns; ! 513: char *buf; ! 514: int len; ! 515: { ! 516: register struct ether_header *eh; ! 517: struct mbuf *m; ! 518: int off, resid; ! 519: register struct ifqueue *inq; ! 520: ! 521: /* ! 522: * Deal with trailer protocol: if type is trailer type ! 523: * get true type from first 16-bit word past data. ! 524: * Remember that type was trailer by setting off. ! 525: */ ! 526: eh = (struct ether_header *)buf; ! 527: eh->ether_type = ntohs((u_short)eh->ether_type); ! 528: len = len - sizeof(struct ether_header) - 4; ! 529: #define nedataaddr(eh, off, type) ((type)(((caddr_t)((eh)+1)+(off)))) ! 530: if (eh->ether_type >= ETHERTYPE_TRAIL && ! 531: eh->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) { ! 532: off = (eh->ether_type - ETHERTYPE_TRAIL) * 512; ! 533: if (off >= ETHERMTU) return; /* sanity */ ! 534: eh->ether_type = ntohs(*nedataaddr(eh, off, u_short *)); ! 535: resid = ntohs(*(nedataaddr(eh, off+2, u_short *))); ! 536: if (off + resid > len) return; /* sanity */ ! 537: len = off + resid; ! 538: } else off = 0; ! 539: ! 540: if (len == 0) return; ! 541: ! 542: /* ! 543: * Pull packet off interface. Off is nonzero if packet ! 544: * has trailing header; neget will then force this header ! 545: * information to be at the front, but we still have to drop ! 546: * the type and length which are at the front of any trailer data. ! 547: */ ! 548: m = isget(buf, len, off, &ns->ns_if); ! 549: if (m == 0) return; ! 550: ! 551: ether_input(&ns->ns_if, eh, m); ! 552: } ! 553: ! 554: /* ! 555: * Supporting routines ! 556: */ ! 557: ! 558: /* ! 559: * Pull read data off a interface. ! 560: * Len is length of data, with local net header stripped. ! 561: * Off is non-zero if a trailer protocol was used, and ! 562: * gives the offset of the trailer information. ! 563: * We copy the trailer information and then all the normal ! 564: * data into mbufs. When full cluster sized units are present ! 565: * we copy into clusters. ! 566: */ ! 567: struct mbuf * ! 568: isget(buf, totlen, off0, ifp) ! 569: caddr_t buf; ! 570: int totlen, off0; ! 571: struct ifnet *ifp; ! 572: { ! 573: struct mbuf *top, **mp, *m, *p; ! 574: int off = off0, len; ! 575: register caddr_t cp = buf; ! 576: char *epkt; ! 577: ! 578: buf += sizeof(struct ether_header); ! 579: cp = buf; ! 580: epkt = cp + totlen; ! 581: ! 582: ! 583: if (off) { ! 584: cp += off + 2 * sizeof(u_short); ! 585: totlen -= 2 * sizeof(u_short); ! 586: } ! 587: ! 588: MGETHDR(m, M_DONTWAIT, MT_DATA); ! 589: if (m == 0) ! 590: return (0); ! 591: m->m_pkthdr.rcvif = ifp; ! 592: m->m_pkthdr.len = totlen; ! 593: m->m_len = MHLEN; ! 594: ! 595: top = 0; ! 596: mp = ⊤ ! 597: while (totlen > 0) { ! 598: if (top) { ! 599: MGET(m, M_DONTWAIT, MT_DATA); ! 600: if (m == 0) { ! 601: m_freem(top); ! 602: return (0); ! 603: } ! 604: m->m_len = MLEN; ! 605: } ! 606: len = min(totlen, epkt - cp); ! 607: if (len >= MINCLSIZE) { ! 608: MCLGET(m, M_DONTWAIT); ! 609: if (m->m_flags & M_EXT) ! 610: m->m_len = len = min(len, MCLBYTES); ! 611: else ! 612: len = m->m_len; ! 613: } else { ! 614: /* ! 615: * Place initial small packet/header at end of mbuf. ! 616: */ ! 617: if (len < m->m_len) { ! 618: if (top == 0 && len + max_linkhdr <= m->m_len) ! 619: m->m_data += max_linkhdr; ! 620: m->m_len = len; ! 621: } else ! 622: len = m->m_len; ! 623: } ! 624: bcopy(cp, mtod(m, caddr_t), (unsigned)len); ! 625: cp += len; ! 626: *mp = m; ! 627: mp = &m->m_next; ! 628: totlen -= len; ! 629: if (cp == epkt) ! 630: cp = buf; ! 631: } ! 632: return (top); ! 633: } ! 634: ! 635: /* ! 636: * Process an ioctl request. ! 637: */ ! 638: isioctl(ifp, cmd, data) ! 639: register struct ifnet *ifp; ! 640: int cmd; ! 641: caddr_t data; ! 642: { ! 643: register struct ifaddr *ifa = (struct ifaddr *)data; ! 644: struct is_softc *ns = &is_softc[ifp->if_unit]; ! 645: struct ifreq *ifr = (struct ifreq *)data; ! 646: int s = splimp(), error = 0; ! 647: ! 648: ! 649: switch (cmd) { ! 650: ! 651: case SIOCSIFADDR: ! 652: ifp->if_flags |= IFF_UP; ! 653: ! 654: switch (ifa->ifa_addr->sa_family) { ! 655: #ifdef INET ! 656: case AF_INET: ! 657: isinit(ifp->if_unit); /* before arpwhohas */ ! 658: ((struct arpcom *)ifp)->ac_ipaddr = ! 659: IA_SIN(ifa)->sin_addr; ! 660: arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr); ! 661: break; ! 662: #endif ! 663: #ifdef NS ! 664: case AF_NS: ! 665: { ! 666: register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr); ! 667: ! 668: if (ns_nullhost(*ina)) ! 669: ina->x_host = *(union ns_host *)(ns->ns_addr); ! 670: else { ! 671: /* ! 672: * The manual says we can't change the address ! 673: * while the receiver is armed, ! 674: * so reset everything ! 675: */ ! 676: ifp->if_flags &= ~IFF_RUNNING; ! 677: bcopy((caddr_t)ina->x_host.c_host, ! 678: (caddr_t)ns->ns_addr, sizeof(ns->ns_addr)); ! 679: } ! 680: isinit(ifp->if_unit); /* does ne_setaddr() */ ! 681: break; ! 682: } ! 683: #endif ! 684: default: ! 685: isinit(ifp->if_unit); ! 686: break; ! 687: } ! 688: break; ! 689: ! 690: case SIOCSIFFLAGS: ! 691: if ((ifp->if_flags & IFF_UP) == 0 && ! 692: ifp->if_flags & IFF_RUNNING) { ! 693: ifp->if_flags &= ~IFF_RUNNING; ! 694: iswrcsr(0,STOP); ! 695: } else if (ifp->if_flags & IFF_UP && ! 696: (ifp->if_flags & IFF_RUNNING) == 0) ! 697: isinit(ifp->if_unit); ! 698: break; ! 699: ! 700: #ifdef notdef ! 701: case SIOCGHWADDR: ! 702: bcopy((caddr_t)ns->ns_addr, (caddr_t) &ifr->ifr_data, ! 703: sizeof(ns->ns_addr)); ! 704: break; ! 705: #endif ! 706: ! 707: default: ! 708: error = EINVAL; ! 709: } ! 710: splx(s); ! 711: return (error); ! 712: } ! 713: ! 714: recv_print(no) ! 715: int no; ! 716: { ! 717: struct mds *rmd; ! 718: int len,i; ! 719: ! 720: rmd = (rd+no); ! 721: len = rmd->mcnt; ! 722: printf("Receive buffer %d, len = %d\n",no,len); ! 723: printf("Status %x\n",isrdcsr(0)); ! 724: for (i=0; i<len; i++) ! 725: printf("%x ",*(rbuf+(BUFSIZE*no)+i)); ! 726: printf("\n"); ! 727: } ! 728: ! 729: xmit_print(no) ! 730: int no; ! 731: { ! 732: struct mds *rmd; ! 733: int i; ! 734: u_short len; ! 735: ! 736: rmd = (td+no); ! 737: len = -(rmd->bcnt); ! 738: printf("Transmit buffer %d, len = %d\n",no,len); ! 739: printf("Status %x\n",isrdcsr(0)); ! 740: printf("addr %x, flags %x, bcnt %x, mcnt %x\n", ! 741: rmd->addr,rmd->flags,rmd->bcnt,rmd->mcnt); ! 742: for (i=0; i<len; i++) ! 743: printf("%x ",*(tbuf+(BUFSIZE*no)+i)); ! 744: printf("\n"); ! 745: } ! 746: ! 747: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.