Annotation of Net2/arch/vax/if/if_dp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1990 Regents of the University of California.
                      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. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)if_dp.c     7.9 (Berkeley) 6/27/91
                     34:  */
                     35: 
                     36: #include "dp.h"
                     37: #if NDP > 0
                     38: 
                     39: /*
                     40:  * DPV-11 device driver, X.25 version
                     41:  *
                     42:  * Derived from dmc-11 driver:
                     43:  *
                     44:  *     Bill Nesheim
                     45:  *     Cornell University
                     46:  *
                     47:  *     Lou Salkind
                     48:  *     New York University
                     49:  */
                     50: 
                     51: /* #define DEBUG       /* for base table dump on fatal error */
                     52: 
                     53: #include "../include/pte.h"
                     54: 
                     55: #include "sys/param.h"
                     56: #include "sys/systm.h"
                     57: #include "sys/mbuf.h"
                     58: #include "sys/buf.h"
                     59: #include "sys/ioctl.h"         /* must precede tty.h */
                     60: #include "sys/protosw.h"
                     61: #include "sys/socket.h"
                     62: #include "sys/socketvar.h"
                     63: #include "sys/syslog.h"
                     64: #include "sys/vmmac.h"
                     65: #include "sys/errno.h"
                     66: #include "sys/time.h"
                     67: #include "sys/kernel.h"
                     68: 
                     69: #include "net/if.h"
                     70: #include "net/if_types.h"
                     71: #include "net/netisr.h"
                     72: #include "net/route.h"
                     73: 
                     74: #include "../include/cpu.h"
                     75: #include "../include/mtpr.h"
                     76: 
                     77: #define        dzdevice dpdevice
                     78: #include "../uba/pdma.h"
                     79: #include "../uba/ubavar.h"
                     80: 
                     81: #include "netccitt/x25.h"
                     82: #include "netccitt/pk.h"
                     83: #include "netccitt/pk_var.h"
                     84: 
                     85: #include "if_dpreg.h"
                     86: 
                     87: /*
                     88:  * Driver information for auto-configuration stuff.
                     89:  */
                     90: int    dpprobe(), dpattach(), dpinit(), dpioctl(), dprint(), dpxint();
                     91: int    dpoutput(), dpreset(), dptimeout(), dpstart(), dptestoutput();
                     92: int    x25_ifoutput(), x25_rtrequest();
                     93: 
                     94: struct uba_device *dpinfo[NDP];
                     95: 
                     96: u_short        dpstd[] = { 0 };
                     97: struct uba_driver dpdriver =
                     98:        { dpprobe, 0, dpattach, 0, dpstd, "dp", dpinfo };
                     99: 
                    100: /*
                    101:  * Pdma structures for fast interrupts.
                    102:  */
                    103: struct pdma dppdma[2*NDP];
                    104: 
                    105: /*
                    106:  * DP software status per interface.
                    107:  *
                    108:  * Each interface is referenced by a network interface structure,
                    109:  * dp_if, which the routing code uses to locate the interface.
                    110:  * This structure contains the output queue for the interface, its address, ...
                    111:  */
                    112: struct dp_softc {
                    113:        struct  ifnet dp_if;            /* network-visible interface */
                    114:        int     dp_ipl;
                    115:        struct  dpdevice *dp_addr;      /* dpcsr address */
                    116:        short   dp_iused;               /* input buffers given to DP */
                    117:        short   dp_flags;               /* flags */
                    118: #define DPF_RUNNING    0x01            /* device initialized */
                    119: #define DPF_ONLINE     0x02            /* device running (had a RDYO) */
                    120: #define DPF_RESTART    0x04            /* software restart in progress */
                    121: #define DPF_FLUSH      0x08            /* had a ROVR, flush ipkt when done */
                    122: #define DPF_X25UP      0x10            /* XXX -- someday we'll do PPP also */
                    123:        short   dp_ostate;              /* restarting, etc. */
                    124:        short   dp_istate;              /* not sure this is necessary */
                    125: #define DPS_IDLE       0
                    126: #define DPS_RESTART    1
                    127: #define DPS_ACTIVE     2
                    128: #define DPS_XEM                3               /* transmitting CRC, etc. */
                    129:        short   dp_olen;                /* length of last packet sent */
                    130:        short   dp_ilen;                /* length of last packet recvd */
                    131:        char    dp_obuf[DP_MTU+8];
                    132:        char    dp_ibuf[DP_MTU+8];
                    133: } dp_softc[NDP];
                    134: 
                    135: /*
                    136:  * Debug info
                    137:  */
                    138: struct dpstat {
                    139:        long    start;
                    140:        long    nohdr;
                    141:        long    init;
                    142:        long    rint;
                    143:        long    xint;
                    144:        long    reset;
                    145:        long    ioctl;
                    146:        long    down;
                    147:        long    mchange;
                    148:        long    timeout;
                    149:        long    rsm;
                    150:        long    rem;
                    151:        long    remchr;
                    152:        long    rga;
                    153:        long    xem;
                    154:        long    rovr;
                    155: } dpstat;
                    156: 
                    157: short dp_ilb = 0;
                    158: short dp_log = 0;
                    159: 
                    160: #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
                    161: int dp_sizes[] = {
                    162:        sizeof(dp_softc[0]), sizeof(struct ifnet),
                    163:        _offsetof(struct dp_softc, dp_obuf[0]),
                    164:        _offsetof(struct dp_softc, dp_ibuf[0]),
                    165:        };
                    166: 
                    167: dpprobe(reg, ui)
                    168:        caddr_t reg;
                    169:        struct  uba_device *ui;
                    170: {
                    171:        register int br, cvec;
                    172:        register struct dpdevice *addr = (struct dpdevice *)reg;
                    173:        register int unit = ui->ui_unit;
                    174: 
                    175: #ifdef lint
                    176:        br = 0; cvec = br; br = cvec;
                    177:        dprint(0); dpxint(0);
                    178: #endif
                    179:        (void) spl6();
                    180:        addr->dpclr = DP_CLR;
                    181:        addr->dpclr = DP_XIE|DP_XE;
                    182:        DELAY(100000);
                    183:        dp_softc[unit].dp_ipl = br = qbgetpri();
                    184:        dp_softc[unit].dp_addr = addr;
                    185:        addr->dpclr = 0;
                    186:        if (cvec && cvec != 0x200){
                    187:                cvec -= 4;
                    188:        }
                    189:        return (1);
                    190: }
                    191: 
                    192: /*
                    193:  * Interface exists: make available by filling in network interface
                    194:  * record.  System will initialize the interface when it is ready
                    195:  * to accept packets.
                    196:  */
                    197: dpattach(ui)
                    198:        register struct uba_device *ui;
                    199: {
                    200:        register struct dp_softc *dp = &dp_softc[ui->ui_unit];
                    201: 
                    202:        dp->dp_if.if_unit = ui->ui_unit;
                    203:        dp->dp_if.if_name = "dp";
                    204:        dp->dp_if.if_mtu = DP_MTU;
                    205:        dp->dp_if.if_init = dpinit;
                    206:        dp->dp_if.if_output = x25_ifoutput;
                    207:        dp->dp_if.if_type = IFT_X25;
                    208:        dp->dp_if.if_hdrlen = 5;
                    209:        dp->dp_if.if_addrlen = 8;
                    210:        dp->dp_if.if_start = dpstart;
                    211:        dp->dp_if.if_ioctl = dpioctl;
                    212:        dp->dp_if.if_reset = dpreset;
                    213:        dp->dp_if.if_watchdog = dptimeout;
                    214:        dp->dp_if.if_flags = 0;
                    215:        if_attach(&dp->dp_if);
                    216: }
                    217: 
                    218: /*
                    219:  * Reset of interface after UNIBUS reset.
                    220:  * If interface is on specified UBA, reset its state.
                    221:  */
                    222: dpreset(unit, uban)
                    223:        int unit, uban;
                    224: {
                    225:        register struct uba_device *ui;
                    226:        register struct dp_softc *dp = &dp_softc[unit];
                    227:        register struct dpdevice *addr;
                    228: 
                    229:        dpstat.reset++;
                    230:        if (unit >= NDP || (ui = dpinfo[unit]) == 0 || ui->ui_alive == 0 ||
                    231:            ui->ui_ubanum != uban)
                    232:                return;
                    233:        dpdown(unit);
                    234:        dpinit(unit);
                    235:        printf(" dp%d", unit);
                    236: }
                    237: 
                    238: /*
                    239:  * Initialization of interface.
                    240:  */
                    241: dpinit(unit)
                    242:        int unit;
                    243: {
                    244:        register struct dp_softc *dp = &dp_softc[unit];
                    245:        register struct dpdevice *addr;
                    246:        register struct ifaddr *ifa;
                    247:        register struct pdma *pdp = &dppdma[unit*2];
                    248:        int base, s;
                    249: 
                    250:        dpstat.init++;
                    251:        /*
                    252:         * Check to see that an address has been set.
                    253:         */
                    254:        for (ifa = dp->dp_if.if_addrlist; ifa; ifa = ifa->ifa_next)
                    255:                if (ifa->ifa_addr->sa_family != AF_LINK)
                    256:                        break;
                    257:        if (ifa == (struct ifaddr *) 0)
                    258:                return;
                    259: 
                    260:        addr = dp->dp_addr;
                    261:        s = splimp();
                    262:        dp->dp_iused = 0;
                    263:        dp->dp_istate = dp->dp_ostate = DPS_IDLE;
                    264:        dp->dp_if.if_flags |= IFF_RUNNING;
                    265:        dp->dp_if.if_flags &= ~IFF_OACTIVE;
                    266: 
                    267:        pdp->p_addr = addr;
                    268:        pdp->p_fcn = dpxint;
                    269:        pdp->p_mem = pdp->p_end = dp->dp_obuf;
                    270:        pdp++;
                    271:        pdp->p_addr = addr;
                    272:        pdp->p_fcn = dprint;
                    273:        /* force initial interrupt to come to dprint */
                    274:        pdp->p_mem = pdp->p_end = dp->dp_ibuf + DP_MTU + 8;
                    275: 
                    276:        addr->dpclr = DP_CLR;
                    277:        DELAY(5000);
                    278:        /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
                    279:                            CRC = CCIIT, initially all ones, 2nd addr = 0 */
                    280:        addr->dpsar = DP_SSLM | DP_IDLE;
                    281:        addr->dpclr = DP_XE | dp_ilb;
                    282:        addr->dptdsr = DP_XSM;
                    283:        /* enable receiver, receive interrupt, DTR, RTS */
                    284:        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
                    285:        dpstart(&dp->dp_if);
                    286:        splx(s);
                    287: }
                    288: 
                    289: /*
                    290:  * Start output on interface.  Get another datagram
                    291:  * to send from the interface queue and map it to
                    292:  * the interface before starting output.
                    293:  *
                    294:  */
                    295: dpstart(ifp)
                    296:        struct ifnet *ifp;
                    297: {
                    298:        int s, unit = ifp->if_unit, error = 0, len;
                    299:        register struct dp_softc *dp = &dp_softc[unit];
                    300:        register struct dpdevice *addr = dp->dp_addr;
                    301:        register struct mbuf *m;
                    302:        register char *cp;
                    303:        char *cplim;
                    304: 
                    305:        /*
                    306:         * If already doing output, go away and depend on transmit
                    307:         * complete or error.
                    308:         */
                    309:        dpstat.start++;
                    310:        if ((dp->dp_if.if_flags & IFF_OACTIVE) ||
                    311:            (dp->dp_if.if_flags & IFF_RUNNING) == 0)
                    312:                goto out;
                    313:        IF_DEQUEUE(&dp->dp_if.if_snd, m);
                    314:        if (m == 0)
                    315:                goto out;
                    316:        dp->dp_if.if_collisions++;
                    317:        if (m->m_flags & M_PKTHDR)
                    318:                len = m->m_pkthdr.len;
                    319:        else {
                    320:                struct mbuf *m0 = m;
                    321:                for (len = 0; m; m = m->m_next)
                    322:                        len += m->m_len;
                    323:                m = m0;
                    324:                dpstat.nohdr++;
                    325:        }
                    326:        if (len < 2)
                    327:                goto out;
                    328:        if (len > DP_MTU) {
                    329:                error = EINVAL;
                    330:                goto out;
                    331:        }
                    332:        dppdma[2*unit].p_mem = cp = dp->dp_obuf;
                    333:        while (m) {
                    334:                struct mbuf *n;
                    335:                bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);
                    336:                cp += m->m_len;
                    337:                MFREE(m, n); m = n;
                    338:        }
                    339:        dppdma[2*unit].p_end = cp - 1;
                    340:        dp->dp_if.if_flags |= IFF_OACTIVE;
                    341:        dp->dp_ostate = DPS_ACTIVE;
                    342:        dp->dp_if.if_collisions--;
                    343:        dp->dp_olen = len;
                    344:        if (dp_log) {
                    345:                register u_char *p = (u_char *)dp->dp_obuf;
                    346:                log(LOG_DEBUG, "dpoutput(%d):%x %x %x %x %x\n",
                    347:                        len, p[0], p[1], p[2], p[3], p[4]);
                    348:        }
                    349:        addr->dpsar = DP_SSLM | DP_IDLE;
                    350:        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
                    351:        addr->dpclr = DP_XIE | DP_XE | dp_ilb;
                    352:        addr->dptdsr = DP_XSM;
                    353: out:
                    354:        return (error);
                    355: }
                    356: /*
                    357:  * Receive done or error interrupt
                    358:  */
                    359: dprint(unit, pdma, addr)
                    360: register struct pdma *pdma;
                    361: register struct dpdevice *addr;
                    362: {
                    363:        register struct dp_softc *dp = &dp_softc[unit];
                    364:        short rdsr = addr->dprdsr, rcsr = pdma->p_arg;
                    365: 
                    366:        dpstat.rint++;
                    367:        splx(dp->dp_ipl);
                    368:        if (rdsr & DP_RGA) {
                    369:                /* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),
                    370:                            CRC = CCIIT, initially all ones, 2nd addr = 0 */
                    371:                addr->dpsar = DP_SSLM | DP_IDLE;
                    372:                addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
                    373:                dpstat.rga++;
                    374:                return;
                    375:        }
                    376:        if (rdsr & DP_RSM) { /* Received Start of Message */
                    377:                dpstat.rsm++;
                    378:                pdma->p_mem = dp->dp_ibuf;
                    379:                if (rcsr & DP_RDR) {
                    380:                    dp->dp_ibuf[0] = rdsr & DP_RBUF;
                    381:                    pdma->p_mem++;
                    382:                }
                    383:                dp->dp_flags &= ~DPF_FLUSH;
                    384:                return;
                    385:        }
                    386:        if (rdsr & DP_REM) { /* Received End of Message */
                    387:                dpstat.rem++;
                    388:                if (rcsr & DP_RDR) {
                    389:                    *(pdma->p_mem++) = rdsr;
                    390:                    dpstat.remchr++;
                    391:                }
                    392:                dp->dp_ilen = pdma->p_mem - dp->dp_ibuf;
                    393:                if (rdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {
                    394:                        dp->dp_if.if_ierrors++;
                    395:                } else
                    396:                        dpinput(&dp->dp_if, dp->dp_ilen, dp->dp_ibuf);
                    397:                pdma->p_mem = pdma->p_end;
                    398:                dp->dp_flags &= ~ DPF_FLUSH;
                    399:                return;
                    400:        }
                    401:        if (rdsr & DP_ROVR) {
                    402:                dpstat.rovr++;
                    403:                dp->dp_flags |= DPF_FLUSH;
                    404:                return;
                    405:        }
                    406:        if (rcsr & DP_MSC) {
                    407:                dpstat.mchange++;
                    408:                if (0 == (rcsr & DP_DSR)) {
                    409:                        log(LOG_DEBUG, "dp%d: lost modem\n", unit);
                    410:                        /*dpdown(unit);*/
                    411:                }
                    412:                return;
                    413:        }
                    414:        dp->dp_flags |= DPF_FLUSH;
                    415:        if (pdma->p_mem != pdma->p_end)
                    416:                log(LOG_DEBUG, "dp%d: unexplained receiver interrupt\n", unit);
                    417: }
                    418: /*
                    419:  * Transmit complete or error interrupt
                    420:  */
                    421: dpxint(unit, pdma, addr)
                    422: register struct pdma *pdma;
                    423: register struct dpdevice *addr;
                    424: {
                    425:        register struct dp_softc *dp = &dp_softc[unit];
                    426:        int s;
                    427: 
                    428:        splx(dp->dp_ipl);
                    429:        dpstat.xint++;
                    430:        if (addr->dptdsr & DP_XERR) {
                    431:                log(LOG_DEBUG, "if_dp%d: data late\n", unit);
                    432:        restart:
                    433:                pdma->p_mem = dp->dp_obuf;
                    434:                addr->dptdsr = DP_XSM;
                    435:                dp->dp_if.if_oerrors++;
                    436:                return;
                    437:        }
                    438:        switch (dp->dp_ostate) {
                    439: 
                    440:        case DPS_ACTIVE:
                    441:                if (pdma->p_mem != pdma->p_end) {
                    442:                        log(LOG_DEBUG, "if_dp%d: misc error in dpxint\n", unit);
                    443:                        goto restart;
                    444:                }
                    445:                addr->dpsar = DP_IDLE|DP_SSLM;
                    446:                addr->dpclr = DP_XE | DP_XIE | dp_ilb;
                    447:                addr->dptdsr = DP_XEM | (0xff & pdma->p_mem[0]);
                    448:                addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;
                    449:                dp->dp_ostate = DPS_XEM;
                    450:                break;
                    451: 
                    452:        case DPS_XEM:
                    453:                dpstat.xem++;
                    454:                dp->dp_if.if_opackets++;
                    455:                dp->dp_ostate = DPS_IDLE;
                    456:                dp->dp_if.if_flags &= ~IFF_OACTIVE;
                    457:                if (dp->dp_if.if_snd.ifq_len)
                    458:                        dpstart(&dp->dp_if);
                    459:                else {
                    460:                        addr->dpsar = DP_IDLE|DP_SSLM;
                    461:                        addr->dpclr = DP_XE | dp_ilb;
                    462:                        addr->dptdsr = DP_XSM;
                    463:                        addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR|DP_RTS;
                    464:                }
                    465:                break;
                    466: 
                    467:        default:
                    468:                log(LOG_DEBUG, "if_dp%d: impossible state in dpxint\n");
                    469:        }
                    470: }
                    471: /*
                    472:  * Routine to copy from device buffer into mbufs.
                    473:  *
                    474:  * Warning: This makes the fairly safe assumption that
                    475:  * mbufs have even lengths.
                    476:  */
                    477: struct mbuf *
                    478: dpget(rxbuf, totlen, off, ifp)
                    479:        caddr_t rxbuf;
                    480:        int totlen, off;
                    481:        struct ifnet *ifp;
                    482: {
                    483:        register caddr_t cp;
                    484:        register struct mbuf *m;
                    485:        struct mbuf *top = 0, **mp = &top;
                    486:        int len;
                    487:        caddr_t packet_end;
                    488: 
                    489:        cp = rxbuf;
                    490:        packet_end = cp + totlen;
                    491:        if (off) {
                    492:                off += 2 * sizeof(u_short);
                    493:                totlen -= 2 *sizeof(u_short);
                    494:                cp = rxbuf + off;
                    495:        }
                    496: 
                    497:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    498:        if (m == 0)
                    499:                return (0);
                    500:        m->m_pkthdr.rcvif = ifp;
                    501:        m->m_pkthdr.len = totlen;
                    502:        m->m_len = MHLEN;
                    503: 
                    504:        while (totlen > 0) {
                    505:                if (top) {
                    506:                        MGET(m, M_DONTWAIT, MT_DATA);
                    507:                        if (m == 0) {
                    508:                                m_freem(top);
                    509:                                return (0);
                    510:                        }
                    511:                        m->m_len = MLEN;
                    512:                }
                    513:                len = min(totlen, (packet_end - cp));
                    514:                if (len >= MINCLSIZE) {
                    515:                        MCLGET(m, M_DONTWAIT);
                    516:                        if (m->m_flags & M_EXT)
                    517:                                m->m_len = len = min(len, MCLBYTES);
                    518:                        else
                    519:                                len = m->m_len;
                    520:                } else {
                    521:                        /*
                    522:                         * Place initial small packet/header at end of mbuf.
                    523:                         */
                    524:                        if (len < m->m_len) {
                    525:                                if (top == 0 && len + max_linkhdr <= m->m_len)
                    526:                                        m->m_data += max_linkhdr;
                    527:                                m->m_len = len;
                    528:                        } else
                    529:                                len = m->m_len;
                    530:                }
                    531:                bcopy(cp, mtod(m, caddr_t), (u_int)len);
                    532:                *mp = m;
                    533:                mp = &m->m_next;
                    534:                totlen -= len;
                    535:                cp += len;
                    536:                if (cp == packet_end)
                    537:                        cp = rxbuf;
                    538:        }
                    539:        return (top);
                    540: }
                    541: 
                    542: dpinput(ifp, len, buffer)
                    543: register struct ifnet *ifp;
                    544: caddr_t buffer;
                    545: {
                    546:        register struct ifqueue *inq;
                    547:        register struct mbuf *m;
                    548:        extern struct ifqueue hdintrq, ipintrq;
                    549:        int isr;
                    550: 
                    551:        ifp->if_ipackets++;
                    552:        if (dp_log) {
                    553:                register u_char *p = (u_char *)buffer;
                    554:                log(LOG_DEBUG, "dpinput(%d):%x %x %x %x %x\n",
                    555:                        len, p[0], p[1], p[2], p[3], p[4]);
                    556:        }
                    557:        
                    558:     {
                    559:        register struct ifaddr *ifa = ifp->if_addrlist;
                    560:        register u_char *cp = (u_char *)buffer;
                    561: 
                    562:        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
                    563:                if (ifa->ifa_addr->sa_family != AF_LINK)
                    564:                        break;
                    565:        if (cp[0] == 0xff && cp[1] == 0x3) {
                    566:                /* This is a UI HDLC Packet, so we'll assume PPP
                    567:                   protocol.  for now, IP only. */
                    568:                buffer += 4;
                    569:                len -= 4;
                    570:                inq = &ipintrq;
                    571:                isr = NETISR_IP;
                    572:        } else {
                    573:                inq = &hdintrq;
                    574:                isr = NETISR_CCITT;
                    575:        }
                    576:     }
                    577:        if (len <= 0)
                    578:                return;
                    579: 
                    580:        m = dpget(buffer, len , 0, ifp);
                    581:        if (m == 0)
                    582:                return;
                    583: 
                    584:        if(IF_QFULL(inq)) {
                    585:                IF_DROP(inq);
                    586:                m_freem(m);
                    587:        } else {
                    588:                IF_ENQUEUE(inq, m);
                    589:                schednetisr(isr);
                    590:        }
                    591: }
                    592: 
                    593: /*
                    594:  * Process an ioctl request.
                    595:  */
                    596: dpioctl(ifp, cmd, data)
                    597:        register struct ifnet *ifp;
                    598:        int cmd;
                    599:        caddr_t data;
                    600: {
                    601:        register struct ifaddr *ifa = (struct ifaddr *)data;
                    602:        int s = splimp(), error = 0;
                    603:        struct dp_softc *dp = &dp_softc[ifp->if_unit];
                    604: 
                    605:        dpstat.ioctl++;
                    606:        switch (cmd) {
                    607:        case SIOCSIFCONF_X25:
                    608:                ifp->if_flags |= IFF_UP;
                    609:                error = hd_ctlinput(PRC_IFUP, ifa->ifa_addr);
                    610:                if (error == 0)
                    611:                        dpinit(ifp->if_unit);
                    612:                break;
                    613: 
                    614:        case SIOCSIFADDR:
                    615:                ifa->ifa_rtrequest = x25_rtrequest;
                    616:                break;
                    617: 
                    618:        case SIOCSIFFLAGS:
                    619:                if ((ifp->if_flags & IFF_UP) == 0 &&
                    620:                    (ifp->if_flags & IFF_RUNNING))
                    621:                        dpdown(ifp->if_unit);
                    622:                else if (ifp->if_flags & IFF_UP &&
                    623:                    (ifp->if_flags & IFF_RUNNING) == 0)
                    624:                        dpinit(ifp->if_unit);
                    625:                break;
                    626: 
                    627: 
                    628:        default:
                    629:                error = EINVAL;
                    630:        }
                    631:        splx(s);
                    632:        return (error);
                    633: }
                    634: /*
                    635:  * Reset a device and mark down.
                    636:  * Flush output queue and drop queue limit.
                    637:  */
                    638: dpdown(unit)
                    639: int unit;
                    640: {
                    641: 
                    642:        register struct dp_softc *dp = &dp_softc[unit];
                    643:        register struct dpdevice *addr = dp->dp_addr;
                    644: 
                    645:        dpstat.down++;
                    646:        if_qflush(&dp->dp_if.if_snd);
                    647:        dp->dp_flags = 0;
                    648:        dp->dp_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                    649: 
                    650:        addr->dpclr = DP_CLR;
                    651:        DELAY(1000);
                    652:        addr->dpsar = 0;
                    653:        addr->dprcsr = 0;
                    654: }
                    655: 
                    656: /*
                    657:  * Watchdog timeout to see that transmitted packets don't
                    658:  * lose interrupts.  The device has to be online (the first
                    659:  * transmission may block until the other side comes up).
                    660:  */
                    661: dptimeout(unit)
                    662:        int unit;
                    663: {
                    664:        register struct dp_softc *dp;
                    665: 
                    666:        /* currently not armed */
                    667:        dpstat.timeout++;
                    668:        dp = &dp_softc[unit];
                    669:        if (dp->dp_if.if_flags & IFF_OACTIVE) {
                    670:                dpstart(&dp->dp_if);
                    671:        }
                    672: }
                    673: /*
                    674:  * For debugging loopback activity.
                    675:  */
                    676: static char pppheader[4] = { -1, 3, 0, 0x21 };
                    677: int dp_louts;
                    678: 
                    679: dptestoutput(ifp, m, dst, rt)
                    680: register struct ifnet *ifp;
                    681: register struct mbuf *m;
                    682: struct sockaddr *dst;
                    683: struct rtentry *rt;
                    684: {
                    685:        /*
                    686:         * Queue message on interface, and start output if interface
                    687:         * not yet active.
                    688:         */
                    689:        int s = splimp(), error = 0;
                    690:        dp_louts++;
                    691:        M_PREPEND(m, sizeof pppheader, M_DONTWAIT);
                    692:        if (m == 0) {
                    693:                splx(s);
                    694:                return ENOBUFS;
                    695:        }
                    696:        bcopy(pppheader, mtod(m, caddr_t), sizeof pppheader);
                    697:        if (IF_QFULL(&ifp->if_snd)) {
                    698:                IF_DROP(&ifp->if_snd);
                    699:            /* printf("%s%d: HDLC says OK to send but queue full, may hang\n",
                    700:                        ifp->if_name, ifp->if_unit);*/
                    701:                m_freem(m);
                    702:                error = ENOBUFS;
                    703:        } else {
                    704:                IF_ENQUEUE(&ifp->if_snd, m);
                    705:                if ((ifp->if_flags & IFF_OACTIVE) == 0)
                    706:                        (*ifp->if_start)(ifp);
                    707:        }
                    708:        splx(s);
                    709:        return (error);
                    710: }
                    711: 
                    712: #endif

unix.superglobalmegacorp.com

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