Annotation of Net2/arch/i386/isa/if_is.c, revision 1.1

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 = &top;
        !           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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.