Annotation of Gnu-Mach/i386/i386at/if_de6c.c, revision 1.1.1.1

1.1       root        1: #define DEBUG  1
                      2: /* 
                      3:  * Mach Operating System
                      4:  * Copyright (c) 1994,1993,1992 Carnegie Mellon University
                      5:  * All Rights Reserved.
                      6:  * 
                      7:  * Permission to use, copy, modify and distribute this software and its
                      8:  * documentation is hereby granted, provided that both the copyright
                      9:  * notice and this permission notice appear in all copies of the
                     10:  * software, derivative works or modified versions, and any portions
                     11:  * thereof, and that both notices appear in supporting documentation.
                     12:  * 
                     13:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     14:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     15:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     16:  * 
                     17:  * Carnegie Mellon requests users of this software to return to
                     18:  * 
                     19:  *  Software Distribution Coordinator  or  [email protected]
                     20:  *  School of Computer Science
                     21:  *  Carnegie Mellon University
                     22:  *  Pittsburgh PA 15213-3890
                     23:  * 
                     24:  * any improvements or extensions that they make and grant Carnegie Mellon
                     25:  * the rights to redistribute these changes.
                     26:  */
                     27: 
                     28: /* 
                     29:  * HISTORY
                     30:  * 17-Feb-94  David Golub (dbg) at Carnegie-Mellon University
                     31:  *     Fix from Bob Baron to fix transmitter problems.
                     32:  *
                     33:  * $Log: if_de6c.c,v $
                     34:  * Revision 1.1.1.1  1997/02/25 21:27:16  thomas
                     35:  * Initial source
                     36:  *
                     37:  * Revision 1.1.1.1  1996/10/30 01:39:26  thomas
                     38:  * Imported from UK22
                     39:  *
                     40:  * Revision 1.1  1994/11/08  20:47:24  baford
                     41:  * merged in CMU's MK83-MK83a diffs
                     42:  *
                     43:  * Revision 2.2  93/11/17  18:29:25  dbg
                     44:  *     Moved source into kernel/i386at/DLINK/if_de6c.c, since we
                     45:  *     can't release it but don't want to lose it.
                     46:  *     [93/11/17            dbg]
                     47:  * 
                     48:  *     Removed u_long.
                     49:  *     [93/03/25            dbg]
                     50:  * 
                     51:  *     Created.
                     52:  *     I have used if_3c501.c as a typical driver template and
                     53:  *     spliced in the appropriate particulars for the 
                     54:  *     d-link 600.
                     55:  *     [92/08/13            rvb]
                     56:  * 
                     57:  *
                     58:  *     File:   if_de6c.c
                     59:  *     Author: Robert V. Baron
                     60:  */
                     61: 
                     62: /*
                     63:  *     File:   if_3c501.c
                     64:  *     Author: Philippe Bernadat
                     65:  *     Date:   1989
                     66:  *     Copyright (c) 1989 OSF Research Institute 
                     67:  *
                     68:  *     3COM Etherlink d-link "600" Mach Ethernet drvier
                     69:  */
                     70: /*
                     71:   Copyright 1990 by Open Software Foundation,
                     72: Cambridge, MA.
                     73: 
                     74:                All Rights Reserved
                     75: 
                     76:   Permission to use, copy, modify, and distribute this software and
                     77: its documentation for any purpose and without fee is hereby granted,
                     78: provided that the above copyright notice appears in all copies and
                     79: that both the copyright notice and this permission notice appear in
                     80: supporting documentation, and that the name of OSF or Open Software
                     81: Foundation not be used in advertising or publicity pertaining to
                     82: distribution of the software without specific, written prior
                     83: permission.
                     84: 
                     85:   OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
                     86: INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
                     87: IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
                     88: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
                     89: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
                     90: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
                     91: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     92: */
                     93: 
                     94: /*
                     95:  *     I have tried to make it clear what is device specific code
                     96:  * and what code supports the general BSD ethernet interface. d-link
                     97:  * specific code is preceded by a line or two of 
                     98:  * "d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON"
                     99:  * and followed by a line or two of
                    100:  * "d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF"
                    101:  *
                    102:  *     The main routines that do device specific processing are:
                    103:  *       de6cintr      - interrupt dispatcher
                    104:  *       de6crcv       - rcv packets and switch to new buffers
                    105:  *       de6cxmt       - xmt packet and wait for xmtbusy to clear
                    106:  *       de6calive     - probe for device
                    107:  *       de6cinit      - device initialization
                    108:  *       de6cintoff    - turn it off.
                    109:  *     There are a couple of interesting macros at the head of this
                    110:  * file and some support subroutines at the end.
                    111:  *
                    112:  *     Lastly, to get decent performance on i386SX class machines, it
                    113:  * was necessary to recode the read and write d-link memory routines in
                    114:  * assembler.  The deread and dewrite routines that are used are in
                    115:  * if_de6s.s
                    116:  * 
                    117:  */
                    118: 
                    119: /* Questions:
                    120: 
                    121:        Make sure that iopl maps 378, 278 and 3bc.
                    122: 
                    123:        If you set command w/o MODE and page bit, what happens?
                    124: 
                    125:        Could I get xmt interrupts; currently I spin - this is not an issue?
                    126: 
                    127:        enable promiscuous?
                    128: 
                    129:        Can you assert TXEN and RXen simulatneously?
                    130: */
                    131: 
                    132: #include <de6c.h>
                    133: #include <par.h>
                    134: 
                    135: #ifdef MACH_KERNEL
                    136: #include       <kern/time_out.h>
                    137: #include       <device/device_types.h>
                    138: #include       <device/errno.h>
                    139: #include       <device/io_req.h>
                    140: #include       <device/if_hdr.h>
                    141: #include       <device/if_ether.h>
                    142: #include       <device/net_status.h>
                    143: #include       <device/net_io.h>
                    144: #include       <chips/busses.h>
                    145: #else  MACH_KERNEL
                    146: #include       <sys/param.h>
                    147: #include       <mach/machine/vm_param.h>
                    148: #include       <sys/systm.h>
                    149: #include       <sys/mbuf.h>
                    150: #include       <sys/buf.h>
                    151: #include       <sys/protosw.h>
                    152: #include       <sys/socket.h>
                    153: #include       <sys/vmmac.h>
                    154: #include       <sys/ioctl.h>
                    155: #include       <sys/errno.h>
                    156: #include       <sys/syslog.h>
                    157: 
                    158: #include       <net/if.h>
                    159: #include       <net/netisr.h>
                    160: #include       <net/route.h>
                    161: #include       <i386at/atbus.h>
                    162: 
                    163: #ifdef INET
                    164: #include       <netinet/in.h>
                    165: #include       <netinet/in_systm.h>
                    166: #include       <netinet/in_var.h>
                    167: #include       <netinet/ip.h>
                    168: #include       <netinet/if_ether.h>
                    169: #endif
                    170: 
                    171: #ifdef NS
                    172: #include       <netns/ns.h>
                    173: #include       <netns/ns_if.h>
                    174: #endif
                    175: #endif MACH_KERNEL
                    176: 
                    177: #include       <vm/vm_kern.h>
                    178: #include       <i386/ipl.h>
                    179: #include       <i386/pio.h>
                    180: #include       <i386at/if_de6c.h>
                    181: 
                    182: #define        SPLNET  spl6
                    183: 
                    184: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    185: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    186: #define        de6cwrite(sp, addr, buf, len) \
                    187:        de6cwriteasm(addr, buf, len, DATA(sp->port), sp->latency)
                    188: 
                    189: #define        de6cread(sp, addr, buf, len) \
                    190:        de6creadasm(addr, buf, len, DATA(sp->port), sp->latency)
                    191: 
                    192: #define DATA_OUT(sp, p, f, z) \
                    193:        de6coutb(sp, DATA(p), ((z)<<4)  | f);\
                    194:        de6coutb(sp, DATA(p), ((z)&0xf0)| f | STROBE)
                    195: 
                    196: #define STAT_IN(sp, p, in) \
                    197:        de6coutb(sp, DATA(p), STATUS); \
                    198:        in = inb(STAT(port)); \
                    199:        de6coutb(sp, DATA(p), NUL_CMD | STROBE)
                    200: 
                    201: #define        XMTidx 3
                    202: #define XMT_BSY_WAIT 10000
                    203: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    204: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    205: 
                    206: int    de6cprobe();
                    207: void   de6cattach();
                    208: int    de6cintr();
                    209: int    de6cinit();
                    210: int    de6coutput();
                    211: int    de6cioctl();
                    212: int    de6creset();
                    213: void   de6cwatch();
                    214: 
                    215: static vm_offset_t de6c_std[NDE6C] = { 0 };
                    216: static struct bus_device *de6c_info[NDE6C];
                    217: 
                    218: #ifdef MACH_KERNEL
                    219: struct bus_driver      de6cdriver = 
                    220:        {de6cprobe, 0, de6cattach, 0, de6c_std, "de", de6c_info, };
                    221: extern struct bus_device *lprinfo[];
                    222: 
                    223: #define MM io_req_t
                    224: #define        PIC     sysdep1
                    225: #define DEV    bus_device
                    226: #else  MACH_KERNEL
                    227: int    (*de6cintrs[])() = {    de6cintr, 0};
                    228: struct isa_driver      de6cdriver = 
                    229:        {de6cprobe, 0, de6cattach, "de", 0, 0, 0};
                    230: extern struct isa_dev *lprinfo[];
                    231: 
                    232: #define MM struct mbuf *
                    233: #define        PIC     dev_pic
                    234: #define DEV    isa_dev
                    235: #endif MACH_KERNEL
                    236: 
                    237: int    watchdog_id;
                    238: 
                    239: typedef struct { 
                    240: #ifdef MACH_KERNEL
                    241:        struct  ifnet   ds_if;          /* generic interface header */
                    242:        u_char  ds_addr[6];             /* Ethernet hardware address */
                    243: #else  MACH_KERNEL
                    244:        struct  arpcom  de6c_ac;
                    245: #define        ds_if   de6c_ac.ac_if
                    246: #define        ds_addr de6c_ac.ac_enaddr
                    247: #endif MACH_KERNEL
                    248:        int     flags;
                    249:         int    timer;
                    250:         u_char address[6];
                    251:        short   mode;
                    252:        int     port;
                    253:        int     latency;
                    254:        int     xmt;
                    255:        int     rcv;
                    256:        int     rcvoff;
                    257:        int     rcvspin;
                    258: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    259: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    260:        int     produce;
                    261:        int     consume;
                    262:        int     rcvlen[XMTidx];
                    263:        int     alive;
                    264: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    265: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    266:        int     (*oldvect)();
                    267:        int     oldunit;
                    268: } de6c_softc_t;
                    269: 
                    270: de6c_softc_t   de6c_softc[NDE6C];
                    271: 
                    272: int de6cactive[NDE6C];
                    273: 
                    274: /*
                    275:  *     Patch to change latency value
                    276:  */
                    277: int de6c_latency = 30; /* works on NEC Versa (pottsylvania.mach) */
                    278: 
                    279: #ifdef DEBUG
                    280: int de6crcv0, de6crcv1, de6crcv2, de6crcv3;
                    281: int de6cdo_rcvintr = 0, de6cdo_watch = 0;
                    282: int de6cdo_xmt = 0;
                    283: #define D(X) X
                    284: #else  /* DEBUG */
                    285: #define D(X)
                    286: #endif /* DEBUG */
                    287: 
                    288: /*
                    289:  * de6cprobe:
                    290:  *     We are not directly probed.  The lprattach will call de6cattach.
                    291:  *     But what we have is plausible for a probe.
                    292:  */
                    293: de6cprobe(port, dev)
                    294: struct DEV             *dev;
                    295: {
                    296: #ifdef MACH_KERNEL
                    297:        int             unit = dev->unit;
                    298: #else  MACH_KERNEL
                    299:        int             unit = dev->dev_unit;
                    300: #endif MACH_KERNEL
                    301: 
                    302:        if ((unit < 0) || (unit >= NDE6C)) {
                    303:                return(0);
                    304:        }
                    305:        return(1);
                    306: }
                    307: 
                    308: /*
                    309:  * de6cattach:
                    310:  *
                    311:  *     Called from lprattach
                    312:  *
                    313:  */
                    314: void de6cattach(dev)
                    315: #ifdef MACH_KERNEL
                    316: struct bus_device      *dev;
                    317: #else  MACH_KERNEL
                    318: struct isa_dev         *dev;
                    319: #endif MACH_KERNEL
                    320: {
                    321:        de6c_softc_t    *sp;
                    322:        struct  ifnet   *ifp;
                    323: #ifdef MACH_KERNEL
                    324:        int             unit = dev->unit;
                    325:        int             port = (int)dev->address;
                    326: #else  MACH_KERNEL
                    327:        int             unit = dev->dev_unit;
                    328:        int             port = (int)dev->dev_addr;
                    329: #endif MACH_KERNEL
                    330: 
                    331:        sp = &de6c_softc[unit];
                    332:        sp->port = port;
                    333:        sp->timer = -1;
                    334:        sp->flags = 0;
                    335:        sp->mode = 0;
                    336: 
                    337:        ifp = &(sp->ds_if);
                    338:        ifp->if_unit = unit;
                    339:        ifp->if_mtu = ETHERMTU;
                    340:        ifp->if_flags = IFF_BROADCAST;
                    341: 
                    342: #ifdef MACH_KERNEL
                    343:        ifp->if_header_size = sizeof(struct ether_header);
                    344:        ifp->if_header_format = HDR_ETHERNET;
                    345:        ifp->if_address_size = 6;
                    346:        ifp->if_address = (char *)&sp->address[0];
                    347:        if_init_queues(ifp);
                    348: #else  MACH_KERNEL
                    349:        ifp->if_name = "de";
                    350:        ifp->if_init = de6cinit;
                    351:        ifp->if_output = de6coutput;
                    352:        ifp->if_ioctl = de6cioctl;
                    353:        ifp->if_reset = de6creset;
                    354:        ifp->if_next = NULL;
                    355:        if_attach(ifp);
                    356: #endif MACH_KERNEL
                    357: 
                    358:        sp->alive = de6calive(sp);
                    359: }
                    360: 
                    361: de6calive(sp)
                    362: de6c_softc_t   *sp;
                    363: {
                    364:        int             port = sp->port;
                    365:        int             unit = sp->ds_if.if_unit;
                    366:        struct DEV      *dev = lprinfo[unit];
                    367:        int             i;
                    368: 
                    369: #ifdef MACH_KERNEL
                    370: #else  /* MACH_KERNEL */
                    371:        extern int tcp_recvspace;               /* empircal messure */
                    372: #endif /* MACH_KERNEL */
                    373: 
                    374: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    375: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    376:        de6coutb(sp, CMD(port), SLT_NIC);
                    377:        DATA_OUT(sp, port, COMMAND, RESET);
                    378:        DATA_OUT(sp, port, COMMAND, STOP_RESET);
                    379:        sp->latency = 101;
                    380:        if (!de6cgetid(sp, sp->ds_addr)) {
                    381:                de6coutb(sp, CMD(port), SLT_PRN);
                    382:                return 0;
                    383:        }
                    384: 
                    385: #ifdef MACH_KERNEL
                    386: #else  /* MACH_KERNEL */
                    387:        tcp_recvspace = 0x300;          /* empircal messure */
                    388: #endif /* MACH_KERNEL */
                    389: 
                    390: #ifdef de6cwrite
                    391:        sp->latency = de6c_latency;
                    392: #else  /* de6cwrite */
                    393:        sp->latency = 0;
                    394: #endif /* de6cwrite */
                    395: 
                    396:        for (i = 0; i++ < 10;) {
                    397:                if (de6cmemcheck(sp))
                    398:                        break;
                    399:                sp->latency += 10;
                    400:        }
                    401: 
                    402:        de6cgetid(sp, sp->ds_addr);
                    403:        de6cgetid(sp, sp->address);
                    404:        de6csetid(sp, sp->address);
                    405:        de6coutb(sp, CMD(port), SLT_PRN);
                    406: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    407: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    408: 
                    409: #ifdef MACH_KERNEL
                    410: #if     NPAR > 0
                    411:        printf("\n");
                    412: #endif /* NPAR > 0 */
                    413:        printf("  de%d:  at lpr%d, port = %x, spl = %d, pic = %d. ",
                    414:                unit, unit, dev->address, dev->sysdep, dev->sysdep1);
                    415: 
                    416:        printf("ethernet id [%x:%x:%x:%x:%x:%x]",
                    417:                sp->address[0],sp->address[1],sp->address[2], 
                    418:                sp->address[3],sp->address[4],sp->address[5]);
                    419: 
                    420:        if (sp->latency > 1) {
                    421:                printf("\n");
                    422:                printf("  LATENCY = %d", sp->latency);
                    423:                printf("  LATENCY = %d", sp->latency);
                    424:                printf("  LATENCY = %d", sp->latency);
                    425:                printf("  LATENCY = %d", sp->latency);
                    426:        }
                    427: #else  MACH_KERNEL
                    428:        printf("de%d:  port = %x, spl = %d, pic = %d. ",
                    429:                unit, dev->dev_addr, dev->dev_spl, dev->dev_pic);
                    430: 
                    431:        printf("ethernet id [%x:%x:%x:%x:%x:%x]\n",
                    432:                sp->address[0],sp->address[1],sp->address[2], 
                    433:                sp->address[3],sp->address[4],sp->address[5]);
                    434: 
                    435:        if (sp->latency > 1) {
                    436:                printf("de%d:", unit);
                    437:                printf("  LATENCY = %d", sp->latency);
                    438:                printf("  LATENCY = %d", sp->latency);
                    439:                printf("  LATENCY = %d", sp->latency);
                    440:                printf("  LATENCY = %d", sp->latency);
                    441:                printf("\n");
                    442:        }
                    443: #endif MACH_KERNEL
                    444: 
                    445:        return 1;
                    446: }
                    447: 
                    448: /*
                    449:  * de6cwatch():
                    450:  *
                    451:  */
                    452: void de6cwatch(b_ptr)
                    453: short *b_ptr;
                    454: {
                    455: #ifdef DEBUG_MORE
                    456:        int unit = *b_ptr;
                    457:        de6c_softc_t *sp = &de6c_softc[unit];
                    458: 
                    459:        if(!de6cdo_watch) return;
                    460:        de6cintr(unit);
                    461:        if (sp->ds_if.if_flags & IFF_RUNNING)
                    462:                timeout(de6cwatch, b_ptr, de6cdo_watch);
                    463: #endif /* DEBUG_MORE */
                    464: }
                    465: 
                    466: #ifdef MACH_KERNEL
                    467: void de6cstart(int);   /* forward */
                    468: 
                    469: de6coutput(dev, ior)
                    470:        dev_t           dev;
                    471:        io_req_t        ior;
                    472: {
                    473:        register int    unit = minor(dev);
                    474: 
                    475:        if (unit < 0 || unit >= NDE6C ||
                    476:                de6c_softc[unit].port == 0)
                    477:            return (ENXIO);
                    478: 
                    479:        return (net_write(&de6c_softc[unit].ds_if, de6cstart, ior));
                    480: }
                    481: 
                    482: io_return_t
                    483: de6csetinput(
                    484:        dev_t           dev,
                    485:        mach_port_t     receive_port,
                    486:        int             priority,
                    487:        filter_t        filter[],
                    488:        natural_t       filter_count)
                    489: {
                    490:        register int unit = minor(dev);
                    491: 
                    492:        if (unit < 0 || unit >= NDE6C ||
                    493:                de6c_softc[unit].port == 0)
                    494:            return ENXIO;
                    495: 
                    496:        return net_set_filter(&de6c_softc[unit].ds_if,
                    497:                        receive_port, priority,
                    498:                        filter, filter_count);
                    499: }
                    500: 
                    501: #else  MACH_KERNEL
                    502: /*
                    503:  * de6coutput:
                    504:  *
                    505:  *     This routine is called by the "if" layer to output a packet to
                    506:  *     the network.  This code resolves the local ethernet address, and
                    507:  *     puts it into the mbuf if there is room.  If not, then a new mbuf
                    508:  *     is allocated with the header information and precedes the data
                    509:  *     to be transmitted.
                    510:  *
                    511:  * input:      ifnet structure pointer, an mbuf with data, and address
                    512:  *             to be resolved
                    513:  * output:     mbuf is updated to hold enet address, or a new mbuf
                    514:  *             with the address is added
                    515:  *
                    516:  */
                    517: de6coutput(ifp, m0, dst)
                    518: struct ifnet   *ifp;
                    519: struct mbuf    *m0;
                    520: struct sockaddr *dst;
                    521: {
                    522:        register de6c_softc_t           *sp = &de6c_softc[ifp->if_unit];
                    523:        int                             type, opri, error;
                    524:        u_char                          edst[6];
                    525:        struct in_addr                  idst;
                    526:        register struct mbuf            *m = m0;
                    527:        register struct ether_header    *eh;
                    528:        register int                     off;
                    529:        int                             usetrailers;
                    530: 
                    531:        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
                    532:                de6cintoff(ifp->if_unit);
                    533:                error = ENETDOWN;
                    534:                goto bad;
                    535:        }
                    536:        switch (dst->sa_family) {
                    537: 
                    538: #ifdef INET
                    539:        case AF_INET:
                    540:                idst = ((struct sockaddr_in *)dst)->sin_addr;
                    541:                if (!arpresolve(&sp->de6c_ac, m, &idst, edst, &usetrailers)){
                    542:                        return (0);     /* if not yet resolved */
                    543:                }
                    544:                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
                    545: 
                    546:                if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
                    547:                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
                    548:                        type = ETHERTYPE_TRAIL + (off>>9);
                    549:                        m->m_off -= 2 * sizeof (u_short);
                    550:                        m->m_len += 2 * sizeof (u_short);
                    551:                        *mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP);
                    552:                        *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
                    553:                        goto gottrailertype;
                    554:                }
                    555:                type = ETHERTYPE_IP;
                    556:                off = 0;
                    557:                goto gottype;
                    558: #endif
                    559: #ifdef NS
                    560:        case AF_NS:
                    561:                type = ETHERTYPE_NS;
                    562:                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
                    563:                (caddr_t)edst, sizeof (edst));
                    564:                off = 0;
                    565:                goto gottype;
                    566: #endif
                    567: 
                    568:        case AF_UNSPEC:
                    569:                eh = (struct ether_header *)dst->sa_data;
                    570:                bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
                    571:                type = eh->ether_type;
                    572:                goto gottype;
                    573: 
                    574:        default:
                    575:                printf("de6c%d: can't handle af%d\n", ifp->if_unit,
                    576:                        dst->sa_family);
                    577:                error = EAFNOSUPPORT;
                    578:                goto bad;
                    579:        }
                    580: 
                    581: gottrailertype:
                    582:        /*
                    583:         * Packet to be sent as trailer: move first packet
                    584:         * (control information) to end of chain.
                    585:         */
                    586:        while (m->m_next)
                    587:                m = m->m_next;
                    588:        m->m_next = m0;
                    589:        m = m0->m_next;
                    590:        m0->m_next = 0;
                    591:        m0 = m;
                    592: 
                    593: gottype:
                    594:        /*
                    595:         * Add local net header.  If no space in first mbuf,
                    596:         * allocate another.
                    597:         */
                    598:        if (m->m_off > MMAXOFF ||
                    599:            MMINOFF + sizeof (struct ether_header) > m->m_off) {
                    600:                m = m_get(M_DONTWAIT, MT_HEADER);
                    601:                if (m == 0) {
                    602:                        error = ENOBUFS;
                    603:                        goto bad;
                    604:                }
                    605:                m->m_next = m0;
                    606:                m->m_off = MMINOFF;
                    607:                m->m_len = sizeof (struct ether_header);
                    608:        } else {
                    609:                m->m_off -= sizeof (struct ether_header);
                    610:                m->m_len += sizeof (struct ether_header);
                    611:        }
                    612:        eh = mtod(m, struct ether_header *);
                    613:        eh->ether_type = htons((u_short)type);
                    614:        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
                    615:        bcopy((caddr_t)sp->address,(caddr_t)eh->ether_shost, sizeof(edst));
                    616:        /*
                    617:         * Queue message on interface, and start output if interface
                    618:         * not yet active.
                    619:         */
                    620:        opri = SPLNET();
                    621:        if (IF_QFULL(&ifp->if_snd)) {
                    622:                IF_DROP(&ifp->if_snd);
                    623:                splx(opri);
                    624:                m_freem(m);
                    625:                return (ENOBUFS);
                    626:        }
                    627:        IF_ENQUEUE(&ifp->if_snd, m);
                    628:        de6cstart(ifp->if_unit);
                    629:        splx(opri);
                    630:        return (0);
                    631: 
                    632: bad:
                    633:        m_freem(m0);
                    634:        return (error);
                    635: }
                    636: #endif MACH_KERNEL
                    637: 
                    638: /*
                    639:  * de6creset:
                    640:  *
                    641:  *     This routine is in part an entry point for the "if" code.  Since most 
                    642:  *     of the actual initialization has already (we hope already) been done
                    643:  *     by calling de6cattach().
                    644:  *
                    645:  * input       : unit number or board number to reset
                    646:  * output      : board is reset
                    647:  *
                    648:  */
                    649: de6creset(unit)
                    650: int    unit;
                    651: {
                    652:        de6c_softc[unit].ds_if.if_flags &= ~IFF_RUNNING;
                    653:        return(de6cinit(unit));
                    654: }
                    655: 
                    656: 
                    657: 
                    658: /*
                    659:  * de6cinit:
                    660:  *
                    661:  *     Another routine that interfaces the "if" layer to this driver.  
                    662:  *     Simply resets the structures that are used by "upper layers".  
                    663:  *
                    664:  * input       : board number
                    665:  * output      : structures (if structs) and board are reset
                    666:  *
                    667:  */    
                    668: de6cinit(unit)
                    669: int    unit;
                    670: {
                    671:        de6c_softc_t    *sp = &de6c_softc[unit];
                    672:        struct  ifnet   *ifp = &(sp->ds_if);
                    673:        int             port = sp->port;
                    674:        int             pic = lprinfo[unit]->PIC;
                    675:        spl_t           oldpri;
                    676: 
                    677: #ifdef MACH_KERNEL
                    678: #else  MACH_KERNEL
                    679:        if (ifp->if_addrlist == (struct ifaddr *)0) {
                    680:                return;
                    681:        }
                    682: #endif MACH_KERNEL
                    683:        oldpri = SPLNET();
                    684: 
                    685:        if (ivect[pic] != de6cintr) {
                    686:                sp->oldvect = ivect[pic];
                    687:                              ivect[pic] = de6cintr;
                    688:                sp->oldunit = iunit[pic];
                    689:                              iunit[pic] = unit;
                    690:        }
                    691: 
                    692: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    693: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    694:        sp->consume = 0;
                    695:        sp->produce = 0;
                    696:        de6coutb(sp, CMD(port), SLT_NIC);
                    697:        DATA_OUT(sp, port, COMMAND, RESET);
                    698:        DATA_OUT(sp, port, COMMAND, STOP_RESET);
                    699:        de6coutb(sp, CMD(port), IRQEN);
                    700:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                    701:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|RXEN);
                    702:        de6coutb(sp, CMD(port), SLT_PRN);
                    703: #if    0
                    704:        if (sp->mode & IFF_PROMISC) {
                    705:                /* handle promiscuous case */;
                    706:        }
                    707: #endif 0
                    708: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    709: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                    710:        sp->ds_if.if_flags |= IFF_RUNNING;
                    711:        sp->flags |= DSF_RUNNING;
                    712:        sp->timer = 5;
                    713:        timeout(de6cwatch, &(ifp->if_unit), 3);
                    714:        de6cstart(unit);
                    715:        splx(oldpri);
                    716: }
                    717: 
                    718: #ifdef MACH_KERNEL
                    719: /*ARGSUSED*/
                    720: de6copen(dev, flag)
                    721:        dev_t   dev;
                    722:        int     flag;
                    723: {
                    724:        register int    unit = minor(dev);
                    725: 
                    726:        if (unit < 0 || unit >= NDE6C ||
                    727:                de6c_softc[unit].port == 0)
                    728:            return (ENXIO);
                    729: 
                    730:        de6c_softc[unit].ds_if.if_flags |= IFF_UP;
                    731:        de6cinit(unit);
                    732:        return(0);
                    733: }
                    734: #endif MACH_KERNEL
                    735: 
                    736: /*
                    737:  * de6cstart:
                    738:  *
                    739:  *     This is yet another interface routine that simply tries to output a
                    740:  *     in an mbuf after a reset.
                    741:  *
                    742:  * input       : board number
                    743:  * output      : stuff sent to board if any there
                    744:  *
                    745:  */
                    746: 
                    747: /* NOTE: called at SPLNET */
                    748: void de6cstart(
                    749:        int     unit)
                    750: {
                    751:        struct  ifnet   *ifp = &(de6c_softc[unit].ds_if);
                    752:        MM              m;
                    753: 
                    754:        for(;;) {
                    755:                IF_DEQUEUE(&ifp->if_snd, m);
                    756:                if (m != (MM) 0)
                    757:                        de6cxmt(unit, m);
                    758:                else
                    759:                        return;
                    760:        }
                    761: }
                    762: 
                    763: #ifdef MACH_KERNEL
                    764: /*ARGSUSED*/
                    765: io_return_t
                    766: de6cgetstat(
                    767:        dev_t           dev,
                    768:        int             flavor,
                    769:        dev_status_t    status,         /* pointer to OUT array */
                    770:        natural_t       *count)         /* out */
                    771: {
                    772:        register int    unit = minor(dev);
                    773:        register de6c_softc_t *sp;
                    774: 
                    775:        if (unit < 0 || unit >= NDE6C ||
                    776:                de6c_softc[unit].port == 0)
                    777:            return (ENXIO);
                    778: 
                    779:        sp = &de6c_softc[unit];
                    780:        if (! sp->alive)
                    781:                if (! (sp->alive = de6calive(sp)))
                    782:                        return ENXIO;
                    783: 
                    784:        return (net_getstat(&de6c_softc[unit].ds_if,
                    785:                            flavor,
                    786:                            status,
                    787:                            count));
                    788: }
                    789: 
                    790: io_return_t
                    791: de6csetstat(
                    792:        dev_t           dev,
                    793:        int             flavor,
                    794:        dev_status_t    status,
                    795:        natural_t       count)
                    796: {
                    797:        register int    unit = minor(dev);
                    798:        register de6c_softc_t *sp;
                    799: 
                    800:        if (unit < 0 || unit >= NDE6C ||
                    801:                de6c_softc[unit].port == 0)
                    802:            return (ENXIO);
                    803: 
                    804:        sp = &de6c_softc[unit];
                    805:        if (! sp->alive)
                    806:                if (! (sp->alive = de6calive(sp)))
                    807:                        return ENXIO;
                    808: 
                    809: 
                    810:        switch (flavor) {
                    811:            case NET_STATUS:
                    812:            {
                    813:                /*
                    814:                 * All we can change are flags, and not many of those.
                    815:                 */
                    816:                register struct net_status *ns = (struct net_status *)status;
                    817:                int     mode = 0;
                    818: 
                    819:                if (count < NET_STATUS_COUNT)
                    820:                    return (D_INVALID_SIZE);
                    821: 
                    822:                if (ns->flags & IFF_ALLMULTI)
                    823:                    mode |= MOD_ENAL;
                    824:                if (ns->flags & IFF_PROMISC)
                    825:                    mode |= MOD_PROM;
                    826: 
                    827:                /*
                    828:                 * Force a compilete reset if the receive mode changes
                    829:                 * so that these take effect immediately.
                    830:                 */
                    831:                if (sp->mode != mode) {
                    832:                    sp->mode = mode;
                    833:                    if (sp->flags & DSF_RUNNING) {
                    834:                        sp->flags &= ~(DSF_LOCK | DSF_RUNNING);
                    835:                        de6cinit(unit);
                    836:                    }
                    837:                }
                    838:                break;
                    839:            }
                    840:            case NET_ADDRESS:
                    841:            {
                    842:                register union ether_cvt {
                    843:                    char        addr[6];
                    844:                    int         lwd[2];
                    845:                } *ec = (union ether_cvt *)status;
                    846: 
                    847:                if (count < sizeof(*ec)/sizeof(int))
                    848:                    return (D_INVALID_SIZE);
                    849: 
                    850:                ec->lwd[0] = ntohl(ec->lwd[0]);
                    851:                ec->lwd[1] = ntohl(ec->lwd[1]);
                    852:                de6csetid(sp->port, ec->addr);
                    853:                break;
                    854:            }
                    855: 
                    856:            default:
                    857:                return (D_INVALID_OPERATION);
                    858:        }
                    859:        return (D_SUCCESS);
                    860: }
                    861: #else  MACH_KERNEL
                    862: 
                    863: /*
                    864:  * de6cioctl:
                    865:  *
                    866:  *     This routine processes an ioctl request from the "if" layer
                    867:  *     above.
                    868:  *
                    869:  * input       : pointer the appropriate "if" struct, command, and data
                    870:  * output      : based on command appropriate action is taken on the
                    871:  *               de6c board(s) or related structures
                    872:  * return      : error is returned containing exit conditions
                    873:  *
                    874:  */
                    875: de6cioctl(ifp, cmd, data)
                    876: struct ifnet   *ifp;
                    877: int    cmd;
                    878: caddr_t        data;
                    879: {
                    880:        register struct ifaddr          *ifa = (struct ifaddr *)data;
                    881:        register de6c_softc_t           *sp = &de6c_softc[ifp->if_unit];
                    882:        int                             opri, error;
                    883:        short                           mode = 0;
                    884: 
                    885:        if (! sp->alive)
                    886:                if (! (sp->alive = de6calive(sp)))
                    887:                        return ENXIO;
                    888: 
                    889:        opri = SPLNET();
                    890:        error = 0;
                    891:        switch (cmd) {
                    892:                case SIOCSIFADDR:
                    893:                        ifp->if_flags |= IFF_UP;
                    894:                        de6cinit(ifp->if_unit);
                    895:                        switch (ifa->ifa_addr.sa_family) {
                    896: #ifdef INET
                    897:                                case AF_INET:
                    898:                                        ((struct arpcom *)ifp)->ac_ipaddr =
                    899:                                                IA_SIN(ifa)->sin_addr;
                    900:                                        arpwhohas((struct arpcom *)ifp, 
                    901:                                                  &IA_SIN(ifa)->sin_addr);
                    902:                                        break;
                    903: #endif
                    904: #ifdef NS
                    905:                                case AF_NS:
                    906:                                        {
                    907:                                        register struct ns_addr *ina = 
                    908:                                        &(IA_SNS(ifa)->sns_addr);
                    909:                                        if (ns_nullhost(*ina))
                    910:                                                ina->x_host = 
                    911:                                                *(union ns_host *)(ds->ds_addr);
                    912:                                        else
                    913:                                                de6cseteh(ina->x_host.c_host,
                    914:                                                de6c_softc[ifp->if_unit].port);
                    915:                                        break;
                    916:                                        }
                    917: #endif
                    918:                        }
                    919:                        break;
                    920:                case SIOCSIFFLAGS:
                    921:                        if (ifp->if_flags & IFF_ALLMULTI)
                    922:                                mode |= MOD_ENAL;
                    923:                        if (ifp->if_flags & IFF_PROMISC)
                    924:                                mode |= MOD_PROM;
                    925:                        /*
                    926:                         * force a complete reset if the receive multicast/
                    927:                         * promiscuous mode changes so that these take 
                    928:                         * effect immediately.
                    929:                         *
                    930:                         */
                    931:                        if (sp->mode != mode) {
                    932:                                sp->mode = mode;
                    933:                                if (sp->flags & DSF_RUNNING) {
                    934:                                        sp->flags &=
                    935:                                                ~(DSF_LOCK|DSF_RUNNING);
                    936:                                        de6cinit(ifp->if_unit);
                    937:                                }
                    938:                        }
                    939:                        if ((ifp->if_flags & IFF_UP) == 0 &&
                    940:                            sp->flags & DSF_RUNNING) {
                    941:                                sp->timer = -1;
                    942:                                de6cintoff(ifp->if_unit);
                    943:                        } else 
                    944:                        if (ifp->if_flags & IFF_UP &&
                    945:                            (sp->flags & DSF_RUNNING) == 0)
                    946:                                de6cinit(ifp->if_unit);
                    947:                        break;
                    948:        default:
                    949:                error = EINVAL;
                    950:        }
                    951:        splx(opri);
                    952:        return (error);
                    953: }
                    954: #endif MACH_KERNEL
                    955: 
                    956: /*
                    957:  * de6cintr:
                    958:  *
                    959:  *     This function is the interrupt handler for the de6c ethernet
                    960:  *     board.  This routine will be called whenever either a packet
                    961:  *     is received, or a packet has successfully been transfered and
                    962:  *     the unit is ready to transmit another packet.
                    963:  *
                    964:  * input       : board number that interrupted
                    965:  * output      : either a packet is received, or a packet is transfered
                    966:  *
                    967:  */
                    968: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    969: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                    970: #ifdef DEBUG_MORE
                    971: de6crcvintr(unit)
                    972: int unit;
                    973: {
                    974:        if(!de6cdo_rcvintr)
                    975:                return;
                    976:        de6cintr(unit);
                    977: }
                    978: #endif /* DEBUG_MORE */
                    979: 
                    980: de6cintr(unit)
                    981: int unit;
                    982: {
                    983:        register de6c_softc_t   *sp = &de6c_softc[unit];
                    984:        int                     port = sp->port;
                    985:        int                     in;
                    986: 
                    987:        if (de6cactive[unit] || !(sp->flags & DSF_RUNNING))
                    988:                return;
                    989:        de6cactive[unit]++;
                    990:        de6coutb(sp, CMD(port), SLT_NIC);
                    991:        STAT_IN(sp, port, in);
                    992: 
                    993:        if ((in & (GOOD|TXBUSY)) == (GOOD|TXBUSY)) {
                    994:                /* on L40's means that we are disconnected */
                    995:                printf("de6intr%d: Card was disconnected; turning off network.\n", unit);
                    996:                de6cintoff(unit);
                    997:                de6cactive[unit]--;
                    998:                return;
                    999:        }
                   1000: 
                   1001:        if (in & GOOD)
                   1002:                de6crcv(unit, in);
                   1003:        else
                   1004: /*rvb:tmp              printf("intr: %x\n", in)*/;
                   1005: 
                   1006: 
                   1007:        de6coutb(sp, CMD(port), SLT_PRN);
                   1008:        de6cactive[unit]--;
                   1009: }
                   1010: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1011: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1012: 
                   1013: /*
                   1014:  * de6crcv:
                   1015:  *
                   1016:  *     This routine is called by the interrupt handler to initiate a
                   1017:  *     packet transfer from the board to the "if" layer above this
                   1018:  *     driver.  This routine checks if a buffer has been successfully
                   1019:  *     received by the de6c.  If so, the routine de6cread is called
                   1020:  *     to do the actual transfer of the board data (including the
                   1021:  *     ethernet header) into a packet (consisting of an mbuf chain).
                   1022:  *
                   1023:  * input       : number of the board to check
                   1024:  * output      : if a packet is available, it is "sent up"
                   1025:  *
                   1026:  */
                   1027: de6crcv(unit, in)
                   1028: int    unit, in;
                   1029: {
                   1030:        register de6c_softc_t   *sp = &de6c_softc[unit];
                   1031:        register struct ifnet   *ifp = &sp->ds_if;
                   1032:        int                     port = sp->port;
                   1033:        int                     bo;
                   1034:        int                     collision = 0;
                   1035:        int                     spins = 0;
                   1036:        u_short                 len;
                   1037:        struct ether_header     header;
                   1038:        int                     tlen;
                   1039:        register struct ifqueue *inq;
                   1040:        int                     opri;
                   1041:        struct  ether_header    eh;
                   1042: #ifdef MACH_KERNEL
                   1043:        ipc_kmsg_t              new_kmsg;
                   1044:        struct ether_header     *ehp;
                   1045:        struct packet_header    *pkt;
                   1046: #else  MACH_KERNEL
                   1047:        struct  mbuf            *m, *tm;
                   1048: #endif MACH_KERNEL
                   1049: 
                   1050:        sp->rcv++;
                   1051: 
                   1052: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1053: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1054:        D(de6crcv0++);
                   1055: #define MT (sp->consume == sp->produce)
                   1056:        while (in & GOOD || !MT) {
                   1057:                spins++;
                   1058:                D(de6crcv1++);
                   1059:                if (in & GOOD) {
                   1060:                        sp->rcvlen[sp->produce] = de6clen(sp);
                   1061:                        if ( ((sp->produce + 1) % XMTidx) != sp->consume) {
                   1062:                                if (++sp->produce == XMTidx)
                   1063:                                        sp->produce = 0;
                   1064:                                DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                   1065:                                DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|RXEN);
                   1066:                        } else collision = 1;
                   1067:                }
                   1068:                len = sp->rcvlen[sp->consume];
                   1069:                bo = sp->consume*BFRSIZ;
                   1070:                if (len < 60) {
                   1071:                        printf("de%d: len(%d) < 60\n", unit, len);
                   1072:                        goto out;
                   1073:                        return;
                   1074:                }
                   1075:                de6cread(sp, bo, &eh, sizeof(struct ether_header));
                   1076:                bo += sizeof(struct ether_header);
                   1077:                len -= 18;
                   1078: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1079: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1080: 
                   1081: #ifdef MACH_KERNEL
                   1082:                new_kmsg = net_kmsg_get();
                   1083:                if (new_kmsg == IKM_NULL) {
                   1084:                    /*
                   1085:                     * Drop the packet.
                   1086:                     */
                   1087:                    sp->ds_if.if_rcvdrops++;
                   1088:                    goto out;
                   1089:                    return;
                   1090:                }
                   1091: 
                   1092:                ehp = (struct ether_header *)
                   1093:                        (&net_kmsg(new_kmsg)->header[0]);
                   1094:                pkt = (struct packet_header *)
                   1095:                        (&net_kmsg(new_kmsg)->packet[0]);
                   1096: 
                   1097:                /*
                   1098:                 * Get header.
                   1099:                 */
                   1100:                *ehp = eh;
                   1101: 
                   1102:                /*
                   1103:                 * Get body
                   1104:                 */
                   1105: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1106:                de6cread(sp, bo, (char *)(pkt + 1), len);
                   1107: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1108:                pkt->type = ehp->ether_type;
                   1109:                pkt->length = len + sizeof(struct packet_header);
                   1110: 
                   1111:                /*
                   1112:                 * Hand the packet to the network module.
                   1113:                 */
                   1114:                net_packet(ifp, new_kmsg, pkt->length,
                   1115:                           ethernet_priority(new_kmsg));
                   1116: 
                   1117: #else  MACH_KERNEL
                   1118:                eh.ether_type = htons(eh.ether_type);
                   1119:                m =(struct mbuf *)0;
                   1120:                while ( len ) {
                   1121:                        if (m == (struct mbuf *)0) {
                   1122:                                m = m_get(M_DONTWAIT, MT_DATA);
                   1123:                                if (m == (struct mbuf *)0) {
                   1124:                                        printf("de6crcv: Lost frame\n");
                   1125:                                        goto out;
                   1126:                                        return;
                   1127:                                }
                   1128:                                tm = m;
                   1129:                                tm->m_off = MMINOFF;
                   1130:                /*
                   1131:                 * first mbuf in the packet must contain a pointer to the
                   1132:                 * ifnet structure.  other mbufs that follow and make up
                   1133:                 * the packet do not need this pointer in the mbuf.
                   1134:                 *
                   1135:                 */
                   1136:                                *(mtod(tm, struct ifnet **)) = ifp;
                   1137:                                tm->m_len = sizeof(struct ifnet **);
                   1138:                        }
                   1139:                        else {
                   1140:                                tm->m_next = m_get(M_DONTWAIT, MT_DATA);
                   1141:                                tm = tm->m_next;
                   1142:                                tm->m_off = MMINOFF;
                   1143:                                tm->m_len = 0;
                   1144:                                if (tm == (struct mbuf *)0) {
                   1145:                                        m_freem(m);
                   1146:                                        printf("de6crcv: No mbufs, lost frame\n");
                   1147:                                        goto out;
                   1148:                                        return;
                   1149:                                }
                   1150:                        }
                   1151:                        tlen = MIN( MLEN - tm->m_len, len );
                   1152:                        tm->m_next = (struct mbuf *)0;
                   1153: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1154:                        de6cread(sp, bo, mtod(tm, char *)+tm->m_len, tlen);
                   1155:                        bo += tlen;
                   1156: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1157:                        tm->m_len += tlen;
                   1158:                        len -= tlen;
                   1159:                }
                   1160: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1161: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1162:                STAT_IN(sp, port, in);
                   1163:                if (in & GOOD) {                /* got another */
                   1164:                        D(de6crcv2++);
                   1165:                        sp->rcvlen[sp->produce] = de6clen(sp);
                   1166:                        if ( ((sp->produce + 1) % XMTidx) != sp->consume) {
                   1167:                                if (++sp->produce == XMTidx)
                   1168:                                        sp->produce = 0;
                   1169:                                DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                   1170:                                DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|RXEN);
                   1171:                        } else collision = 1;
                   1172:                }
                   1173: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1174: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1175: 
                   1176:                /*
                   1177:                 * received packet is now in a chain of mbuf's.  next step is
                   1178:                 * to pass the packet upwards.
                   1179:                 *
                   1180:                 */
                   1181:                switch (eh.ether_type) {
                   1182: 
                   1183: #ifdef INET
                   1184:                        case ETHERTYPE_IP:
                   1185:                                schednetisr(NETISR_IP);
                   1186:                                inq = &ipintrq;
                   1187:                                break;
                   1188:                        case ETHERTYPE_ARP:
                   1189:                                arpinput(&sp->de6c_ac, m);
                   1190:                                goto out;
                   1191:                                return;
                   1192: #endif
                   1193: #ifdef NS
                   1194:                        case ETHERTYPE_NS:
                   1195:                                schednetisr(NETISR_NS);
                   1196:                                inq = &nsintrq;
                   1197:                                break;
                   1198: #endif
                   1199:                        default:
                   1200:                                m_freem(m);
                   1201:                                goto out;
                   1202:                                return;
                   1203:                }
                   1204:                opri = SPLNET();
                   1205:                if (IF_QFULL(inq)) {
                   1206:                        IF_DROP(inq);
                   1207:                        splx(opri);
                   1208:                        m_freem(m);
                   1209:                        goto out;
                   1210:                        return;
                   1211:                }
                   1212:                IF_ENQUEUE(inq, m);
                   1213:                splx(opri);
                   1214: #endif MACH_KERNEL
                   1215: out:
                   1216: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1217: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1218:                STAT_IN(sp, port, in);
                   1219:                if (in & GOOD) {                /* got another */
                   1220:                        D(de6crcv3++);
                   1221:                }
                   1222: /*2*/  /* implies wrap and pause */
                   1223:                if (collision) {
                   1224:                        collision = 0;
                   1225:                        D(printf("*C* "));
                   1226:                        sp->rcvoff++;
                   1227:                        if (++sp->produce == XMTidx)
                   1228:                                sp->produce = 0;
                   1229:                        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                   1230:                        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|RXEN);
                   1231:                }
                   1232: /*2*/  /* implies wrap and pause */
                   1233:                if (++sp->consume == XMTidx)
                   1234:                        sp->consume = 0;
                   1235:                if (spins > 10) {
                   1236:                        spins = 0;
                   1237:                        D(printf("*R* "));
                   1238:                        sp->rcvspin++;
                   1239:                        /* how should we recover here ??? */;
                   1240:                        /* return does not work */;
                   1241:                        /* de6cinit(unit) gets ugly if we are called from
                   1242:                           de6cxmt */;
                   1243:                }
                   1244: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1245: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1246:        }
                   1247: }
                   1248: 
                   1249: 
                   1250: /*
                   1251:  * de6cxmt:
                   1252:  *
                   1253:  *     This routine fills in the appropriate registers and memory
                   1254:  *     locations on the d-link "600" board and starts the board off on
                   1255:  *     the transmit.
                   1256:  *
                   1257:  * input       : board number of interest, and a pointer to the mbuf
                   1258:  * output      : board memory and registers are set for xfer and attention
                   1259:  *
                   1260:  */
                   1261: /* NOTE: called at SPLNET */
                   1262: /*
                   1263:  * This implies that rcv interrupts will be blocked.
                   1264:  */
                   1265: #define        max(a,b)        (((a) > (b)) ? (a) : (b))
                   1266: 
                   1267: char de6mt[ETHERMIN];
                   1268: de6cxmt(unit, m)
                   1269: int    unit;
                   1270: MM     m;
                   1271: {
                   1272: #ifdef MACH_KERNEL
                   1273: #else  MACH_KERNEL
                   1274:        register struct mbuf    *tm_p;
                   1275: #endif MACH_KERNEL
                   1276:        int                     i;
                   1277:        int                     in;
                   1278:        int                     bo, boo;
                   1279:        de6c_softc_t            *sp = &de6c_softc[unit];
                   1280:        int                     port = sp->port;
                   1281:        u_short                 count = 0;
                   1282:        u_short                 bytes_in_msg;
                   1283:        static int              m_length();
                   1284: 
                   1285: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1286: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1287:        if (de6cactive[unit] >= 2)              /* a funny loop caused by */
                   1288:                return;                         /* a flood of arps */
                   1289:        if (de6cactive[unit]++ == 0)
                   1290:                de6coutb(sp, CMD(port), SLT_NIC);
                   1291:        STAT_IN(sp, port, in);
                   1292: 
                   1293:        D(if (de6cdo_xmt) printf("xmt: stat[-] = %x\n", in));
                   1294:        if (in & GOOD) {
                   1295:                de6crcv(unit, in);
                   1296:        }
                   1297:        sp->xmt++;
                   1298: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1299: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1300: 
                   1301: #ifdef MACH_KERNEL
                   1302:        count = m->io_count;
                   1303:        bytes_in_msg = max(count, ETHERMIN + sizeof(struct ether_header));
                   1304: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1305:        boo = bo = XMTidx*BFRSIZ+(BFRSIZ-bytes_in_msg);
                   1306:        de6cwrite(sp, bo, m->io_data, count);
                   1307: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1308:        bo += count;
                   1309:        iodone(m);
                   1310: #else  MACH_KERNEL
                   1311:        bytes_in_msg = max(m_length(m), ETHERMIN + sizeof(struct ether_header));
                   1312: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1313:        boo = bo = XMTidx*BFRSIZ+(BFRSIZ-bytes_in_msg);
                   1314: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1315: 
                   1316:        for (tm_p = m; tm_p != (struct mbuf *)0; tm_p = tm_p->m_next) {
                   1317:                if (count + tm_p->m_len > ETHERMTU + sizeof(struct ether_header))
                   1318:                        break;
                   1319:                if (tm_p->m_len == 0)
                   1320:                        continue;
                   1321: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1322:                de6cwrite(sp, bo, mtod(tm_p, caddr_t), tm_p->m_len);
                   1323:                bo += tm_p->m_len;
                   1324: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1325:                count += tm_p->m_len;
                   1326:        }
                   1327:        m_freem(m);
                   1328: #endif MACH_KERNEL
                   1329: 
                   1330: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1331: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1332:        if (bytes_in_msg - count > 0)
                   1333:                de6cwrite(sp, bo, de6mt, bytes_in_msg - count);
                   1334: 
                   1335:        DATA_OUT(sp, port, TX_ADR,  boo       & 0xff);
                   1336:        DATA_OUT(sp, port, TX_ADR, (boo >> 8) & 0xff);
                   1337:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                   1338:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|TXEN);
                   1339: 
                   1340:        for (i = 0; i < XMT_BSY_WAIT; i++) {
                   1341:                STAT_IN(sp, port, in);
                   1342:                D(if (de6cdo_xmt) printf("xmt: stat[%d] = %x\n", i, in));
                   1343:                if (in & GOOD) {
                   1344:                        /*
                   1345:                         * this does indeed happen
                   1346:                         * printf("!#");
                   1347:                         */
                   1348:                        de6crcv(unit, in);
                   1349:                }
                   1350:                if (!(in & TXBUSY)) {
                   1351:                        goto out;
                   1352:                        return;
                   1353:                }
                   1354:        }
                   1355:        printf("dexmt: stat[??] = %x\n", i, in);
                   1356: out:
                   1357:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4));
                   1358:        DATA_OUT(sp, port, COMMAND, RX_BP|(sp->produce<<4)|RXEN);
                   1359: 
                   1360:        if (--de6cactive[unit] == 0)
                   1361:                de6coutb(sp, CMD(port), SLT_PRN);
                   1362: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1363: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1364: }
                   1365: 
                   1366: /*
                   1367:  * de6cintoff:
                   1368:  *
                   1369:  *     This function turns interrupts off for the de6c board indicated.
                   1370:  *
                   1371:  */
                   1372: de6cintoff(unit)
                   1373: int unit;
                   1374: {
                   1375:        de6c_softc_t    *sp = &de6c_softc[unit];
                   1376:        int             port = sp->port;
                   1377:        int             pic = lprinfo[unit]->PIC;
                   1378: 
                   1379:        printf("de%d: Turning off d-link \"600\"\n", unit);
                   1380:        sp->ds_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
                   1381:        sp->flags &= ~(DSF_LOCK | DSF_RUNNING);
                   1382: 
                   1383: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1384: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1385:        de6coutb(sp, CMD(port), SLT_NIC);
                   1386:        DATA_OUT(sp, port, COMMAND, RESET);
                   1387:        DATA_OUT(sp, port, COMMAND, STOP_RESET);
                   1388:        de6coutb(sp, CMD(port), SLT_PRN);
                   1389: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1390: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1391: 
                   1392:        outb(CMD(sp->port), 0x07);
                   1393:        ivect[pic] = sp->oldvect;
                   1394:        iunit[pic] = sp->oldunit;
                   1395: }
                   1396: 
                   1397: #ifdef MACH_KERNEL
                   1398: #else  MACH_KERNEL
                   1399: /*
                   1400:  * The length of an mbuf chain
                   1401:  */
                   1402: static
                   1403: m_length(m)
                   1404:        register struct mbuf *m;
                   1405: {
                   1406:        register int len = 0;
                   1407:        
                   1408:        while (m) {
                   1409:                len += m->m_len;
                   1410:                m = m->m_next;
                   1411:        }
                   1412:        return len;
                   1413: }
                   1414: #endif MACH_KERNEL
                   1415: 
                   1416: 
                   1417: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1418: /* d-link 600 ON; d-link 600 ON; d-link 600 ON; d-link 600 ON */
                   1419: de6cgetid(sp, buf)
                   1420: de6c_softc_t *sp;
                   1421: u_char *buf;
                   1422: {
                   1423:        de6cread(sp, EADDR, buf, 6);
                   1424:        if ((buf[0] != 0x00) || (buf[1] != 0xde) || (buf[2] != 0x15))
                   1425:                return 0;
                   1426:        buf[0] = 0x80;
                   1427:        buf[1] = 0x00;
                   1428:        buf[2] = 0xc8;
                   1429:        /* for this model d-link we assert 0x70 as the high mfr's nibble. */
                   1430:        buf[3] = 0x70 | (buf[3] & 0xf);
                   1431:        return 1;
                   1432: }
                   1433: 
                   1434: de6csetid(sp, buf)
                   1435: de6c_softc_t *sp;
                   1436: char *buf;
                   1437: {
                   1438:        de6cwrite(sp, EADDR, buf, 6);
                   1439: }
                   1440: 
                   1441: /*
                   1442:  * get length of packet just rcv'd.
                   1443:  * includes ether header and crc
                   1444:  */
                   1445: de6clen(sp)
                   1446: de6c_softc_t *sp;
                   1447: {
                   1448:        int     port = sp->port;
                   1449:        int     in;
                   1450:        int     i;
                   1451: 
                   1452:        de6coutb(sp, DATA(port), RX_LEN);
                   1453:        in = inb(STAT(port));
                   1454:        de6coutb(sp, DATA(port), RX_LEN|STROBE);
                   1455:        i = ((in>>4) | (inb(STAT(port)) & 0xf0));
                   1456: 
                   1457:        de6coutb(sp, DATA(port), RX_LEN);
                   1458:        in = inb(STAT(port));
                   1459:        de6coutb(sp, DATA(port), RX_LEN|STROBE);
                   1460:        i |= ((in>>4) | (inb(STAT(port)) & 0xf0)) << 8;
                   1461: 
                   1462:        return i;
                   1463: }
                   1464: 
                   1465: #if    0
                   1466: de6cread(sp, address, buf, len)
                   1467: de6c_softc_t *sp;
                   1468: unsigned char *buf;
                   1469: {
                   1470:        int     port = sp->port;
                   1471:        u_char  in;
                   1472: 
                   1473:        DATA_OUT(sp, port, RW_ADR,  address       & 0xff);
                   1474:        DATA_OUT(sp, port, RW_ADR, (address >> 8) & 0xff);
                   1475: 
                   1476:        while (len--) {
                   1477:                de6coutb(sp, DATA(port), READ);
                   1478:                in = inb(STAT(port));
                   1479:                de6coutb(sp, DATA(port), READ|STROBE);
                   1480:                *buf++ = ((in>>4) | (inb(STAT(port)) & 0xf0));
                   1481:        }
                   1482: }
                   1483: 
                   1484: de6cwrite(sp, address, buf, len)
                   1485: de6c_softc_t *sp;
                   1486: unsigned char *buf;
                   1487: {
                   1488:        int     port = sp->port;
                   1489:        int     out;
                   1490: 
                   1491:        DATA_OUT(sp, port, RW_ADR,  address       & 0xff);
                   1492:        DATA_OUT(sp, port, RW_ADR, (address >> 8) & 0xff);
                   1493: 
                   1494:        while (len--) {
                   1495:                out = *buf++;
                   1496:                DATA_OUT(sp, port, WRITE, out);
                   1497: 
                   1498:        }
                   1499: }
                   1500: #endif 0
                   1501: 
                   1502: #ifndef        de6cread
                   1503: de6cread(sp, address, buf, len)
                   1504: de6c_softc_t *sp;
                   1505: unsigned char *buf;
                   1506: {
                   1507:        int                     port = sp->port;
                   1508:        register volatile int   i;
                   1509:        unsigned char           in;
                   1510: 
                   1511:        outb(port, ((address)<<4)  | RW_ADR);
                   1512:        i = sp->latency; while (i-- > 0);
                   1513:        outb(port, ((address)&0xf0)| RW_ADR | 0x8);
                   1514:        i = sp->latency; while (i-- > 0);
                   1515: 
                   1516:        outb(port, ((address>>8)<<4)  | RW_ADR);
                   1517:        i = sp->latency; while (i-- > 0);
                   1518:        outb(port, ((address>>8)&0xf0)| RW_ADR | 0x8);
                   1519:        i = sp->latency; while (i-- > 0);
                   1520: 
                   1521:        while (len--) {
                   1522:                outb(port, READ);
                   1523:                i = sp->latency; while (i-- > 0);
                   1524:                in = inb(STAT(port));
                   1525:                outb(port, READ|0x08);
                   1526:                i = sp->latency; while (i-- > 0);
                   1527:                *buf++ = ((in>>4) | (inb(STAT(port)) & 0xf0));
                   1528:        }
                   1529: }
                   1530: #endif /* de6cread */
                   1531: 
                   1532: #ifndef        de6cwrite
                   1533: de6cwrite(sp, address, buf, len)
                   1534: de6c_softc_t *sp;
                   1535: unsigned char *buf;
                   1536: {
                   1537:        int                     port = sp->port;
                   1538:        register volatile int   i;
                   1539:        unsigned char           out;
                   1540: 
                   1541:        outb(port, ((address)<<4)  | RW_ADR);
                   1542:        i = sp->latency; while (i-- > 0);
                   1543:        outb(port, ((address)&0xf0)| RW_ADR | 0x8);
                   1544:        i = sp->latency; while (i-- > 0);
                   1545: 
                   1546:        outb(port, ((address>>8)<<4)  | RW_ADR);
                   1547:        i = sp->latency; while (i-- > 0);
                   1548:        outb(port, ((address>>8)&0xf0)| RW_ADR | 0x8);
                   1549:        i = sp->latency; while (i-- > 0);
                   1550: 
                   1551:        while (len--) {
                   1552:                out = *buf++;
                   1553:                outb(port, ((out)<<4)  | WRITE);
                   1554:                i = sp->latency; while (i-- > 0);
                   1555:                outb(port, ((out)&0xf0)| WRITE | 0x8);
                   1556:                i = sp->latency; while (i-- > 0);
                   1557:        }
                   1558: }
                   1559: #endif /* de6cwrite */
                   1560: 
                   1561: de6coutb(sp, p, v)
                   1562: de6c_softc_t *sp;
                   1563: {
                   1564: register volatile int i = sp->latency; 
                   1565: 
                   1566:        outb(p, v);
                   1567:        while (i-- > 0);
                   1568: }
                   1569: 
                   1570: de6cmemcheck(sp)
                   1571: de6c_softc_t *sp;
                   1572: {
                   1573:        int i;
                   1574:        int off = 0;
                   1575:        int ret = 1;
                   1576: #ifdef MACH_KERNEL
                   1577:        unsigned short *memchk;
                   1578:        unsigned short *chkmem;
                   1579:        if (kmem_alloc(kernel_map, (vm_offset_t *)&memchk, BFRS * BFRSIZ) !=
                   1580:            KERN_SUCCESS ||
                   1581:            kmem_alloc(kernel_map, (vm_offset_t *)&chkmem, BFRS * BFRSIZ) !=
                   1582:            KERN_SUCCESS) {
                   1583:                printf("de6c: memory allocation failure!!\n");
                   1584:                return 0;
                   1585:        }
                   1586: #else  /* MACH_KERNEL */
                   1587:        unsigned short *memchk = (unsigned short *) kmem_alloc(kernel_map, BFRS * BFRSIZ);
                   1588:        unsigned short *chkmem = (unsigned short *) kmem_alloc(kernel_map, BFRS * BFRSIZ);
                   1589:        if ( ! ((int) memchk) || ! ((int) chkmem)) {
                   1590:                printf("de6c: memory allocation failure!!\n");
                   1591:                return 0;
                   1592:        }
                   1593: #endif /* MACH_KERNEL */
                   1594: 
                   1595:        for (i = 0; i < BFRS * BFRSIZ/sizeof (short); i++)
                   1596:                memchk[i] = i;
                   1597:        bzero(chkmem, BFRS * BFRSIZ);
                   1598: 
                   1599: 
                   1600:        for (off = 0; off < BFRS * BFRSIZ; off += BFRSIZ/2) {
                   1601:                de6cwrite(sp, off, memchk+(off/sizeof (short)), BFRSIZ/2);
                   1602:                de6cread (sp, off, chkmem+(off/sizeof (short)), BFRSIZ/2);
                   1603:        }
                   1604: 
                   1605:        for (i = 0; i < BFRS * (BFRSIZ/sizeof (short)); i++)
                   1606:                if (memchk[i] != chkmem[i]) {
                   1607:                        printf("de: tilt:seq [%x:%d] %x != %x\n",
                   1608:                                i, i, memchk[i], chkmem[i]);
                   1609:                        ret = 0;
                   1610:                        break;
                   1611:                }
                   1612: 
                   1613:        kmem_free(kernel_map, (vm_offset_t) memchk, BFRS * BFRSIZ);
                   1614:        kmem_free(kernel_map, (vm_offset_t) chkmem, BFRS * BFRSIZ);
                   1615: 
                   1616:        return ret;
                   1617: }
                   1618: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1619: /* d-link 600 OFF; d-link 600 OFF; d-link 600 OFF; d-link 600 OFF */
                   1620: 
                   1621: #ifdef DEBUG
                   1622: #define STATIC
                   1623: STATIC int print_pkt(), print_bdy();
                   1624: STATIC int print_e_hdr(), print_ip_hdr(), print_ip();
                   1625: STATIC int print_ipa(), print_arp(), print_e(), print_chars();
                   1626: 
                   1627: STATIC
                   1628: print_pkt(p, len)
                   1629: unsigned char *p;
                   1630: {
                   1631:        int j, k;
                   1632:        int type;
                   1633: 
                   1634:        if (len < 18)
                   1635:                printf("print_pkt: too small %d\n", len);
                   1636: 
                   1637:        type = print_e_hdr(p);
                   1638: 
                   1639:        switch (type) {
                   1640:        case 0x806:
                   1641:                print_arp(p+14);
                   1642:                break;
                   1643:        case 0x800:
                   1644:                print_ip(p+14, len - 18);
                   1645:                break;
                   1646:        default:
                   1647:                for (j = 14; j < len; j +=20) {
                   1648:                    for (k = 0; k < 20; k++)
                   1649:                        printf("%2x ", p[j+k]);
                   1650:                    printf("\n");
                   1651:                }
                   1652:        }
                   1653: }
                   1654: 
                   1655: STATIC
                   1656: print_bdy(p, len, type)
                   1657: unsigned char *p;
                   1658: {
                   1659:        int j, k;
                   1660: 
                   1661:        if (len < 18)
                   1662:                printf("print_pkt: too small %d|n", len);
                   1663: 
                   1664:        switch (type) {
                   1665:        case 0x806:
                   1666:                print_arp(p);
                   1667:                break;
                   1668:        case 0x800:
                   1669:                print_ip(p, len);
                   1670:                break;
                   1671:        default:
                   1672:                for (j = 0; j < len; j +=20) {
                   1673:                    for (k = 0; k < 20; k++)
                   1674:                        printf("%2x ", p[j+k]);
                   1675:                    printf("\n");
                   1676:                }
                   1677:        }
                   1678: }
                   1679: 
                   1680: STATIC
                   1681: print_e_hdr(p)
                   1682: unsigned char *p;
                   1683: {
                   1684:        int type = ntohs(((unsigned short *)p)[6]);
                   1685: 
                   1686:        printf("S=%x:%x:%x:%x:%x:%x, ", p[6], p[7], p[8], p[9], p[10], p[11]);
                   1687:        printf("D=%x:%x:%x:%x:%x:%x, ", p[0], p[1], p[2], p[3], p[4], p[5]);
                   1688:        printf("T=%x\n", type);
                   1689: 
                   1690:        return type;
                   1691: }
                   1692: 
                   1693: STATIC
                   1694: print_ip_hdr(u)
                   1695: u_char *u;
                   1696: {
                   1697: 
                   1698:        int l = ntohs(*(u_short *)(u+2));
                   1699:        
                   1700:        print_ipa(u+12);
                   1701:        printf(" -> ");
                   1702:        print_ipa(u+12+4);
                   1703:        printf(" L%d(0x%x)\n", l, l);
                   1704: }
                   1705: 
                   1706: STATIC
                   1707: print_ip(p, len)
                   1708: unsigned char *p;
                   1709: {
                   1710:        int j,k;
                   1711: 
                   1712:        print_ip_hdr(p);
                   1713:        for (k =0; k < 12; k++)
                   1714:                printf("%2x ", p[k]);
                   1715:        print_ipa(p+12);
                   1716:        printf(" ");
                   1717:        print_ipa(p+12+4);
                   1718:        printf("\n");
                   1719:        for (j = 20; j < len; j +=16) {
                   1720:            for (k = 0; k < 16; k++)
                   1721:                printf("%2x ", p[j+k]);
                   1722:            print_chars(&p[j], 16);
                   1723:            printf("\n");
                   1724:        }
                   1725: }
                   1726: 
                   1727: STATIC
                   1728: print_ipa(u)
                   1729: u_char *u;
                   1730: {
                   1731:        printf("%d.%d.%d.%d", u[0], u[1], u[2], u[3]);
                   1732: }
                   1733: 
                   1734: STATIC
                   1735: print_arp(p)
                   1736: #ifdef MACH_KERNEL
                   1737: {}
                   1738: #else  MACH_KERNEL
                   1739: struct arphdr *p;
                   1740: {
                   1741:        u_char *u = (u_char *)(p+1);
                   1742: 
                   1743:        printf("op = %x, pro = %x, hln = %x, pln = %x\n",
                   1744:                ntohs(p->ar_op), ntohs(p->ar_pro), p->ar_hln, p->ar_pln);
                   1745: 
                   1746:        print_e(u);
                   1747:        print_ipa(u+p->ar_hln);
                   1748:        printf("        seeks\n");
                   1749: 
                   1750:        print_e(u+p->ar_hln+p->ar_pln);
                   1751:        print_ipa(u+p->ar_hln+p->ar_pln+p->ar_hln);
                   1752:        printf("\n");
                   1753: 
                   1754: }
                   1755: #endif MACH_KERNEL
                   1756: 
                   1757: STATIC
                   1758: print_e(u)
                   1759: u_char *u;
                   1760: {
                   1761:        printf("%x:%x:%x:%x:%x:%x ", u[0], u[1], u[2], u[3], u[4], u[5]);
                   1762: }
                   1763: 
                   1764: STATIC
                   1765: print_chars(u, len)
                   1766: u_char *u;
                   1767: {
                   1768:        int c;
                   1769: 
                   1770:        printf("|>");
                   1771:        while (len--) {
                   1772:                c = *u++;
                   1773:                if (c < 0x7f && c > 0x1f)
                   1774:                        printf("%c", c);
                   1775:                else 
                   1776:                        printf(" ");
                   1777:                }
                   1778:        printf("<|");
                   1779: }
                   1780: #endif DEBUG

unix.superglobalmegacorp.com

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