Annotation of Gnu-Mach/i386/i386at/if_ns8390.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /* NOTE:
        !            27:  *     There are three outstanding bug/features in this implementation.
        !            28:  * They may even be hardware misfeatures.  The conditions are registered
        !            29:  * by counters maintained by the software.
        !            30:  *     1: over_write is a condition that means that the board wants to store
        !            31:  * packets, but there is no room.  So new packets are lost.  What seems to
        !            32:  * be happening is that we get an over_write condition, but there are no
        !            33:  * or just a few packets in the board's ram.  Also it seems that we get
        !            34:  * several over_writes in a row.
        !            35:  *     2: Since there is only one transmit buffer, we need a lock to indicate
        !            36:  * whether it is in use.  We clear this lock when we get a transmit interrupt.
        !            37:  * Sometimes we go to transmit and although there is no transmit in progress,
        !            38:  * the lock is set.  (In this case, we just ignore the lock.)  It would look
        !            39:  * like we can miss transmit interrupts?
        !            40:  *     3: We tried to clean up the unnecessary switches to bank 0.  
        !            41:  * Unfortunately, when you do an ifconfig "down", the system tend to lock up
        !            42:  * a few seconds later (this was when DSF_RUNNING) was not being set before.
        !            43:  * But even with DSF_RUNNING, on an EISA bus machine we ALWAYS lock up after
        !            44:  * a few seconds. 
        !            45:  */
        !            46: 
        !            47: /*
        !            48:  * Western Digital 8003E Mach Ethernet driver (for intel 80386)
        !            49:  * Copyright (c) 1990 by Open Software Foundation (OSF).
        !            50:  */
        !            51: 
        !            52: /*
        !            53:   Copyright 1990 by Open Software Foundation,
        !            54: Cambridge, MA.
        !            55: 
        !            56:                All Rights Reserved
        !            57: 
        !            58:   Permission to use, copy, modify, and distribute this software and
        !            59: its documentation for any purpose and without fee is hereby granted,
        !            60: provided that the above copyright notice appears in all copies and
        !            61: that both the copyright notice and this permission notice appear in
        !            62: supporting documentation, and that the name of OSF or Open Software
        !            63: Foundation not be used in advertising or publicity pertaining to
        !            64: distribution of the software without specific, written prior
        !            65: permission.
        !            66: 
        !            67:   OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
        !            68: <INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
        !            69: IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
        !            70: CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
        !            71: LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
        !            72: NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
        !            73: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            74: */
        !            75: 
        !            76: #define IF_CNTRS       MACH
        !            77: 
        !            78: #include       <ns8390.h>
        !            79: #if NNS8390 > 0
        !            80: 
        !            81: #include       <mach_ttd.h>
        !            82: #include       <kern/time_out.h>
        !            83: #include       <device/device_types.h>
        !            84: #include       <device/errno.h>
        !            85: #include       <device/io_req.h>
        !            86: #include       <device/if_hdr.h>
        !            87: #include       <device/if_ether.h>
        !            88: #include       <device/net_status.h>
        !            89: #include       <device/net_io.h>
        !            90: #include       "vm_param.h"
        !            91: #include       <i386/ipl.h>
        !            92: #include       <chips/busses.h>
        !            93: #include       <i386at/ds8390.h>
        !            94: #include       <i386at/if_wd8003.h>
        !            95: #include       <i386at/if_3c503.h>
        !            96: 
        !            97: #if    MACH_TTD
        !            98: #include <ttd/ttd_stub.h>
        !            99: #endif /* MACH_TTD */
        !           100: 
        !           101: 
        !           102: #define        SPLNET  spl6
        !           103: 
        !           104: int wd_debug = 0;
        !           105:   
        !           106: int    ns8390probe();
        !           107: void   ns8390attach();
        !           108: int    ns8390intr();
        !           109: int    ns8390init();
        !           110: int    ns8390output();
        !           111: int    ns8390ioctl();
        !           112: int    ns8390reset();
        !           113: int     ns8390rcv();
        !           114: int    ns8390watch();
        !           115: int     ns8390get_CURR();
        !           116: int     ns8390over_write();
        !           117: 
        !           118: struct bus_device      *ns8390info[NNS8390];   /* ???? */
        !           119: 
        !           120: static vm_offset_t ns8390_std[NNS8390] = { 0 };
        !           121: static struct bus_device *ns8390_info[NNS8390];
        !           122: struct bus_driver      ns8390driver =
        !           123:        {ns8390probe, 0, ns8390attach, 0, ns8390_std, "ns8390", ns8390_info, 0, 0, 0};
        !           124: 
        !           125: int    watchdog_id;
        !           126: 
        !           127: char *wd8003_card = "wd";
        !           128: char *elii_card = "el";
        !           129: /*               2e0, 2a0, 280,  250,   350,   330,   310, 300*/
        !           130: int elii_irq[8] = {5,   2,   2,     5,     5, 0x711, 0x711,  5};
        !           131: int elii_bnc[8] = {1,   0,   1,     1,     0, 0x711, 0x711,  0};
        !           132: /*int elii_bnc[8] = {0, 1,   1,     1,     1,     1,     0,  1}; */
        !           133: 
        !           134: typedef struct {
        !           135: #ifdef MACH_KERNEL
        !           136:        struct  ifnet   ds_if;          /* generic interface header */
        !           137:        u_char  ds_addr[6];             /* Ethernet hardware address */
        !           138: #else  MACH_KERNEL
        !           139:        struct  arpcom  ns8390_ac;
        !           140: #define        ds_if   ns8390_ac.ac_if
        !           141: #define        ds_addr ns8390_ac.ac_enaddr
        !           142: #endif MACH_KERNEL
        !           143:        int     flags;
        !           144:        int     timer;
        !           145:        int     interrupt;
        !           146:        char    *nic;
        !           147:        u_char   address[ETHER_ADDR_SIZE];
        !           148:        short   mode;
        !           149:        int     tbusy;
        !           150:        char    *sram;          /* beginning of the shared memory RAM buffer */
        !           151:        int     read_nxtpkt_ptr;/* pointer to next packet available */
        !           152:        int     pstart;         /* page start hold */
        !           153:        int     pstop;          /* page stop hold */
        !           154:        int     tpsr;           /* transmit page start hold */
        !           155:        int     fifo_depth;     /* NIC fifo threshold */
        !           156:        char    *card;
        !           157:        int     board_id;
        !           158: }
        !           159: ns8390_softc_t;
        !           160: 
        !           161: ns8390_softc_t ns8390_softc[NNS8390];
        !           162: 
        !           163: struct ns8390_cntrs {
        !           164: u_int  ovw,
        !           165:        jabber,
        !           166:        crc,
        !           167:        frame,
        !           168:        miss,
        !           169:        fifo,
        !           170:        rcv;
        !           171: u_int  xmt,
        !           172:        xmti,
        !           173:        busy,
        !           174:        heart;
        !           175: } ns8390_cntrs[NNS8390];
        !           176: 
        !           177: #if    MACH_TTD        
        !           178: boolean_t ttd_poll_loop;
        !           179: 
        !           180: int ns8390poll_receive();
        !           181: int ns8390transmit_ttd();
        !           182: #endif /* MACH_TTD */
        !           183: 
        !           184: #ifdef IF_CNTRS
        !           185: int ns_narp = 1, ns_arp = 0;
        !           186: int ns_ein[32], ns_eout[32]; 
        !           187: int ns_lin[128/8], ns_lout[128/8]; 
        !           188: static
        !           189: log_2(no)
        !           190: unsigned long no;
        !           191: {
        !           192:        return ({ unsigned long _temp__;
        !           193:                asm("bsr %1, %0; jne 0f; xorl %0, %0; 0:" :
        !           194:                    "=r" (_temp__) : "a" (no));
        !           195:                _temp__;});
        !           196: }
        !           197: #endif IF_CNTRS
        !           198: 
        !           199: /* Interrupts mask bits */
        !           200: int  imr_hold = DSIM_PRXE|DSIM_PTXE|DSIM_RXEE|DSIM_TXEE|DSIM_OVWE|DSIM_CNTE; 
        !           201: 
        !           202: /*
        !           203:  * ns8390probe:
        !           204:  *
        !           205:  *     This function "probes" or checks for the wd8003 board on the bus to see
        !           206:  *     if it is there.  As far as I can tell, the best break between this
        !           207:  *     routine and the attach code is to simply determine whether the board
        !           208:  *      is configured in properly. Currently my approach to this is to test the
        !           209:  *      base I/O special offset for the Western Digital unique byte sequence
        !           210:  *      identifier.  If the bytes match we assume board is there.
        !           211:  *     The config code expects to see a successful return from the probe
        !           212:  *     routine before attach will be called.
        !           213:  *
        !           214:  * input       : address device is mapped to, and unit # being checked
        !           215:  * output      : a '1' is returned if the board exists, and a 0 otherwise
        !           216:  *
        !           217:  */
        !           218: 
        !           219: ns8390probe(port, dev)
        !           220: struct bus_device      *dev;
        !           221: {
        !           222:        caddr_t         hdwbase = (caddr_t)dev->address;
        !           223:        int             unit = dev->unit;
        !           224:        ns8390_softc_t  *sp = &ns8390_softc[unit];
        !           225:        int             tmp;
        !           226:        int             vendor_id;
        !           227: 
        !           228:        if ((unit < 0) || (unit > NNS8390)) {
        !           229:                printf("ns8390 ethernet unit %d out of range\n", unit);
        !           230:                return(0);
        !           231:        }
        !           232:        if (((u_char) inb(hdwbase+IFWD_LAR_0) == (u_char) WD_NODE_ADDR_0) &&
        !           233:            ((u_char) inb(hdwbase+IFWD_LAR_1) == (u_char) WD_NODE_ADDR_1) &&
        !           234:            ((u_char) inb(hdwbase+IFWD_LAR_2) == (u_char) WD_NODE_ADDR_2)) {
        !           235:                        ns8390info[unit] = dev;
        !           236:                        sp->card = wd8003_card;
        !           237:                        dev->name = wd8003_card;
        !           238:                        sp->nic = hdwbase + OFF_8390;
        !           239:                                /* enable mem access to board */
        !           240:                        sp->board_id = wd80xxget_board_id(dev);
        !           241: 
        !           242:                        *(sp->address)      = inb(hdwbase+IFWD_LAR_0);
        !           243:                        *(sp->address + 1)  = inb(hdwbase+IFWD_LAR_1);
        !           244:                        *(sp->address + 2)  = inb(hdwbase+IFWD_LAR_2);
        !           245:                        *(sp->address + 3)  = inb(hdwbase+IFWD_LAR_3);
        !           246:                        *(sp->address + 4)  = inb(hdwbase+IFWD_LAR_4);
        !           247:                        *(sp->address + 5)  = inb(hdwbase+IFWD_LAR_5);
        !           248:                        return (1);
        !           249:                }  /* checks the address of the board to verify that it is a WD */
        !           250:        
        !           251:        /* try to avoid any NE2000 pretending to be an el II */
        !           252:        if (inb(hdwbase + 0x408) == 0xff) 
        !           253:                return 0;
        !           254: 
        !           255:        /* check vendor id */
        !           256:        tmp = inb(hdwbase + CTLR);
        !           257: 
        !           258:        outb(hdwbase + CTLR, CTLR_RST|CTLR_THIN); /* Reset it... */
        !           259:        outb(hdwbase + CTLR, CTLR_THIN);
        !           260:        /* 
        !           261:         * Map the station addr PROM into the lower I/O ports. We now
        !           262:         * check for both the old and new 3Com prefix 
        !           263:         */
        !           264:        outb(hdwbase + CTLR, CTLR_STA_ADDR|CTLR_THIN);
        !           265:        vendor_id = inb(hdwbase)*0x10000 + inb(hdwbase + 1)*0x100 + 
        !           266:                inb(hdwbase + 2);
        !           267:        /* Restore the register we frobbed. */
        !           268:        outb(hdwbase + CTLR, tmp);
        !           269:        if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) 
        !           270:                return 0;
        !           271: 
        !           272:        if ((tmp = inb(hdwbase+BCFR))) {
        !           273:                switch(tmp) {
        !           274:                case (1<<7):    sp->board_id = 7; break;        /*irq5 xvcr*/
        !           275: #ifdef not_currently_possible
        !           276:                case (1<<6):    sp->board_id = 6; break;
        !           277:                case (1<<5):    sp->board_id = 5; break;
        !           278: #endif not_currently_possible
        !           279:                case (1<<4):    sp->board_id = 4; break;
        !           280:                case (1<<3):    sp->board_id = 3; break;
        !           281:                case (1<<2):    sp->board_id = 2; break;        /*irq2 bnc*/
        !           282:                case (1<<1):    sp->board_id = 1; break;        /*irq2 xvcr*/
        !           283:                case (1<<0):    sp->board_id = 0; break;        /*irq5 bnc*/
        !           284:                default:        return 0;
        !           285:                }
        !           286:                switch (inb(hdwbase+PCFR)) {
        !           287:                case (1<<7):    dev->phys_address = 0xDC000; break;
        !           288:                case (1<<6):    dev->phys_address = 0xD8000; break;
        !           289: #ifdef not_currently_possible
        !           290:                case (1<<5):    dev->phys_address = 0xCC000; break;
        !           291:                case (1<<4):    dev->phys_address = 0xC8000; break;
        !           292: #endif not_currently_possible
        !           293:                default:
        !           294:                        printf("EtherLink II with NO memory configured\n");
        !           295:                        return 0;
        !           296:                }
        !           297:                ns8390info[unit] = dev;
        !           298:                dev->sysdep1 = elii_irq[sp->board_id];
        !           299:                if (dev->sysdep1 == 2)
        !           300:                        dev->sysdep1 = 9;
        !           301:                sp->card = elii_card;
        !           302:                dev->name = elii_card;
        !           303:                sp->nic = hdwbase;
        !           304:                return 1;
        !           305:         }
        !           306: 
        !           307:        return(0);
        !           308: }
        !           309: 
        !           310: /*
        !           311:  * ns8390attach:
        !           312:  *
        !           313:  *     This function attaches a ns8390 board to the "system".  The rest of
        !           314:  *     runtime structures are initialized here (this routine is called after
        !           315:  *     a successful probe of the board).  Once the ethernet address is read
        !           316:  *     and stored, the board's ifnet structure is attached and readied.
        !           317:  *
        !           318:  * input       : bus_device structure setup in autoconfig
        !           319:  * output      : board structs and ifnet is setup
        !           320:  *
        !           321:  */
        !           322: 
        !           323: void ns8390attach(dev)
        !           324: struct bus_device      *dev;
        !           325: {
        !           326:        ns8390_softc_t  *sp;
        !           327:        struct  ifnet   *ifp;
        !           328:        u_char          unit;
        !           329:        int             temp;
        !           330: 
        !           331:        take_dev_irq(dev);
        !           332:        unit = (u_char)dev->unit;
        !           333:        sp = &ns8390_softc[unit];
        !           334:        printf(", port = %x, spl = %d, pic = %d. ",
        !           335:                dev->address, dev->sysdep, dev->sysdep1);
        !           336: 
        !           337:        if (sp->card == elii_card) {
        !           338:                if (elii_bnc[sp->board_id])
        !           339:                        printf("cheapernet ");
        !           340:                else
        !           341:                        printf("ethernet ");
        !           342:        } else
        !           343:                printf("ethernet ");
        !           344: 
        !           345:        (volatile char *)sp->sram =
        !           346:            (volatile char *) phystokv(dev->phys_address);
        !           347:        dev->address = (vm_offset_t) phystokv(dev->address);
        !           348:        sp->timer = -1;
        !           349:        sp->flags = 0;
        !           350:        sp->mode  = 0;
        !           351: 
        !           352:        if (!ns8390hwrst(unit)) {
        !           353:                printf("%s%d: attach(): reset failed.\n",
        !           354:                        sp->card, unit);
        !           355:                return;
        !           356:        }
        !           357:                /* N.B. sp->address is not determined till
        !           358:                 * hwrst time. */
        !           359:        *(sp->ds_addr)      = *(sp->address);
        !           360:        *(sp->ds_addr + 1)  = *(sp->address + 1);
        !           361:        *(sp->ds_addr + 2)  = *(sp->address + 2);
        !           362:        *(sp->ds_addr + 3)  = *(sp->address + 3);
        !           363:        *(sp->ds_addr + 4)  = *(sp->address + 4);
        !           364:        *(sp->ds_addr + 5)  = *(sp->address + 5);
        !           365: 
        !           366:        printf("id [%x:%x:%x:%x:%x:%x]",
        !           367:                sp->address[0],sp->address[1],sp->address[2],
        !           368:                sp->address[3],sp->address[4],sp->address[5]);
        !           369:        ifp = &(sp->ds_if);
        !           370:        ifp->if_unit = unit;
        !           371:        ifp->if_mtu = ETHERMTU;
        !           372:        ifp->if_flags = IFF_BROADCAST;
        !           373: #ifdef MACH_KERNEL
        !           374:        ifp->if_header_size = sizeof(struct ether_header);
        !           375:        ifp->if_header_format = HDR_ETHERNET;
        !           376:        ifp->if_address_size = 6;
        !           377:        ifp->if_address = (char *)&sp->address[0];
        !           378:        if_init_queues(ifp);
        !           379: #else  MACH_KERNEL
        !           380:        ifp->if_name = sp->card;
        !           381:        ifp->if_init = ns8390init;
        !           382:        ifp->if_output = ns8390output;
        !           383:        ifp->if_ioctl = ns8390ioctl;
        !           384:        ifp->if_reset = ns8390reset;
        !           385:        ifp->if_next = NULL;
        !           386:        if_attach(ifp);
        !           387: #ifdef notdef
        !           388:        watchdog_id = timeout(ns8390watch, &(ifp->if_unit), 20*HZ);
        !           389: #endif
        !           390: #endif MACH_KERNEL
        !           391: 
        !           392: #ifdef MACH_KERNEL
        !           393: #if    MACH_TTD
        !           394:        if (!ttd_get_packet) {
        !           395:                ttd_device_unit = unit;
        !           396:                ttd_get_packet = ns8390poll_receive;
        !           397:                ttd_send_packet = ns8390transmit_ttd;
        !           398:                ttd_host_ether_id.array[0] = *(sp->address);
        !           399:                ttd_host_ether_id.array[1] = *(sp->address + 1);
        !           400:                ttd_host_ether_id.array[2] = *(sp->address + 2);
        !           401:                ttd_host_ether_id.array[3] = *(sp->address + 3);
        !           402:                ttd_host_ether_id.array[4] = *(sp->address + 4);
        !           403:                ttd_host_ether_id.array[5] = *(sp->address + 5);
        !           404:        }
        !           405: #endif /* MACH_TTD */
        !           406: #endif /* MACH_KERNEL */
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * ns8390watch():
        !           411:  *
        !           412:  */
        !           413: 
        !           414: int
        !           415: ns8390watch(b_ptr)
        !           416: caddr_t        b_ptr;
        !           417: {
        !           418:        int     x,
        !           419:                y,
        !           420:                opri,
        !           421:                unit;
        !           422:        int     temp_cr;
        !           423:        caddr_t nic;
        !           424: 
        !           425:        unit = *b_ptr;
        !           426: #ifdef MACH_KERNEL
        !           427:        timeout(ns8390watch,b_ptr,20*HZ);
        !           428: #else  MACH_KERNEL
        !           429:        watchdog_id = timeout(ns8390watch,b_ptr,20*HZ);
        !           430: #endif MACH_KERNEL
        !           431:        nic = ns8390_softc[unit].nic;
        !           432:        temp_cr = inb(nic+ds_cmd);
        !           433:        outb(nic + ds_cmd, (temp_cr & 0x3f) | DSCM_PG0);
        !           434:        printf("<<< ISR=%x CURR=%x rdnxt=%x BNDY=%x>>> ",
        !           435:                inb(nic + ds0_isr),
        !           436:                ns8390get_CURR(unit), ns8390_softc[unit].read_nxtpkt_ptr,
        !           437:                inb(nic+ds0_bndy));
        !           438:        outb(nic+ds_cmd,temp_cr);
        !           439: }
        !           440: 
        !           441: #ifdef MACH_KERNEL
        !           442: int ns8390start();     /* forward */
        !           443: 
        !           444: /*ARGSUSED*/
        !           445: wd8003open(dev, flag)
        !           446:        dev_t   dev;
        !           447:        int     flag;
        !           448: {
        !           449:        register int    unit = minor(dev);
        !           450: 
        !           451:        if (ns8390_softc[unit].card != wd8003_card)
        !           452:                return (ENXIO);
        !           453:        if (unit < 0 || unit >= NNS8390 ||
        !           454:                ns8390_softc[unit].nic == 0)
        !           455:            return (ENXIO);
        !           456: 
        !           457:        ns8390_softc[unit].ds_if.if_flags |= IFF_UP;
        !           458:        ns8390init(unit);
        !           459:        return(0);
        !           460: }
        !           461: 
        !           462: eliiopen(dev, flag)
        !           463:        dev_t   dev;
        !           464:        int     flag;
        !           465: {
        !           466:        register int    unit = minor(dev);
        !           467: 
        !           468:        if (ns8390_softc[unit].card != elii_card)
        !           469:                return (ENXIO);
        !           470:        if (unit < 0 || unit >= NNS8390 ||
        !           471:                ns8390_softc[unit].nic == 0)
        !           472:            return (ENXIO);
        !           473: 
        !           474:        ns8390_softc[unit].ds_if.if_flags |= IFF_UP;
        !           475:        ns8390init(unit);
        !           476:        return(0);
        !           477: }
        !           478: 
        !           479: ns8390output(dev, ior)
        !           480:        dev_t           dev;
        !           481:        io_req_t        ior;
        !           482: {
        !           483:        register int    unit = minor(dev);
        !           484: 
        !           485:        if (unit < 0 || unit >= NNS8390 ||
        !           486:                ns8390_softc[unit].nic == 0)
        !           487:            return (ENXIO);
        !           488:        return (net_write(&ns8390_softc[unit].ds_if, ns8390start, ior));
        !           489: }
        !           490: 
        !           491: ns8390setinput(dev, receive_port, priority, filter, filter_count)
        !           492:        dev_t           dev;
        !           493:        mach_port_t     receive_port;
        !           494:        int             priority;
        !           495:        filter_t        filter[];
        !           496:        unsigned int    filter_count;
        !           497: {
        !           498:        register int unit = minor(dev);
        !           499: 
        !           500:        if (unit < 0 || unit >= NNS8390 ||
        !           501:                ns8390_softc[unit].nic == 0)
        !           502:            return (ENXIO);
        !           503: 
        !           504:        return (net_set_filter(&ns8390_softc[unit].ds_if,
        !           505:                        receive_port, priority,
        !           506:                        filter, filter_count));
        !           507: }
        !           508: 
        !           509: #else  MACH_KERNEL
        !           510: /*
        !           511:  * ns8390output:
        !           512:  *
        !           513:  *     This routine is called by the "if" layer to output a packet to
        !           514:  *     the network.  This code resolves the local ethernet address, and
        !           515:  *     puts it into the mbuf if there is room.  If not, then a new mbuf
        !           516:  *     is allocated with the header information and precedes the data
        !           517:  *     to be transmitted.  The routine ns8390xmt() which actually
        !           518:  *      transmits the data expects the ethernet header to precede the
        !           519:  *      data in the mbuf.
        !           520:  *
        !           521:  * input:      ifnet structure pointer, an mbuf with data, and address
        !           522:  *             to be resolved
        !           523:  * output:     mbuf is updated to hold enet address, or a new mbuf
        !           524:  *             with the address is added
        !           525:  *
        !           526:  */
        !           527: 
        !           528: ns8390output(ifp, m0, dst)
        !           529: struct ifnet   *ifp;
        !           530: struct mbuf    *m0;
        !           531: struct sockaddr *dst;
        !           532: {
        !           533:        register ns8390_softc_t         *is = &ns8390_softc[ifp->if_unit];
        !           534:        u_char                          edst[6];
        !           535:        struct in_addr                  idst;
        !           536:        register struct mbuf            *m = m0;
        !           537:        register struct ether_header    *eh;
        !           538:        register int                    off;
        !           539:        int                             usetrailers;
        !           540:        int                             type, error;
        !           541:        spl_t                           opri;
        !           542: 
        !           543:        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
        !           544:                printf("%s%d output(): Turning off board %d\n",
        !           545:                        is->card, ifp->if_unit);
        !           546:                ns8390intoff(ifp->if_unit);
        !           547:                error = ENETDOWN;
        !           548:                goto bad;
        !           549:        }
        !           550:        switch (dst->sa_family) {
        !           551: #ifdef INET
        !           552:        case AF_INET:
        !           553:                idst = ((struct sockaddr_in *)dst)->sin_addr;
        !           554:                if (!arpresolve(&is->ns8390_ac, m, &idst, edst, &usetrailers)){
        !           555:                        return (0);     /* if not yet resolved */
        !           556:                }
        !           557:                off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
        !           558:                if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
        !           559:                    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
        !           560:                        type = ETHERTYPE_TRAIL + (off>>9);
        !           561:                        m->m_off -= 2 * sizeof (u_short);
        !           562:                        m->m_len += 2 * sizeof (u_short);
        !           563:                        *mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP);
        !           564:                        *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
        !           565:                        goto gottrailertype;
        !           566:                }
        !           567:                type = ETHERTYPE_IP;
        !           568:                off = 0;
        !           569:                goto gottype;
        !           570: #endif
        !           571: #ifdef NS
        !           572:        case AF_NS:
        !           573:                type = ETHERTYPE_NS;
        !           574:                bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
        !           575:                      (caddr_t)edst,
        !           576:                      sizeof (edst));
        !           577:                off = 0;
        !           578:                goto gottype;
        !           579: #endif
        !           580:        case AF_UNSPEC:
        !           581:                eh = (struct ether_header *)dst->sa_data;
        !           582:                bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, sizeof (edst));
        !           583:                type = eh->ether_type;
        !           584:                goto gottype;
        !           585:        default:
        !           586:                printf("%s%d output(): can't handle af%d\n",
        !           587:                        is->card, ifp->if_unit,
        !           588:                        dst->sa_family);
        !           589:                error = EAFNOSUPPORT;
        !           590:                goto bad;
        !           591:        }
        !           592: gottrailertype:
        !           593:        /*
        !           594:         * Packet to be sent as trailer: move first packet
        !           595:         * (control information) to end of chain.
        !           596:         */
        !           597:        while (m->m_next)
        !           598:                m = m->m_next;
        !           599:        m->m_next = m0;
        !           600:        m = m0->m_next;
        !           601:        m0->m_next = 0;
        !           602:        m0 = m;
        !           603: gottype:
        !           604:        /*
        !           605:         * Add local net header.  If no space in first mbuf,
        !           606:         * allocate another.
        !           607:         */
        !           608:        if (m->m_off > MMAXOFF ||
        !           609:            MMINOFF + sizeof (struct ether_header) > m->m_off) {
        !           610:                m = m_get(M_DONTWAIT, MT_HEADER);
        !           611:                if (m == 0) {
        !           612:                        error = ENOBUFS;
        !           613:                        goto bad;
        !           614:                }
        !           615:                m->m_next = m0;
        !           616:                m->m_off = MMINOFF;
        !           617:                m->m_len = sizeof (struct ether_header);
        !           618:        } else {
        !           619:                m->m_off -= sizeof (struct ether_header);
        !           620:                m->m_len += sizeof (struct ether_header);
        !           621:        }
        !           622:        eh = mtod(m, struct ether_header *);
        !           623:        eh->ether_type = htons((u_short)type);
        !           624:        bcopy((caddr_t)edst, (caddr_t)eh->ether_dhost, sizeof (edst));
        !           625:        bcopy((caddr_t)is->address,
        !           626:              (caddr_t)eh->ether_shost,
        !           627:              sizeof(edst));
        !           628:        /*
        !           629:         * Queue message on interface, and start output if interface
        !           630:         * not yet active.
        !           631:         */
        !           632:        opri = SPLNET();
        !           633:        if (IF_QFULL(&ifp->if_snd)) {
        !           634:                IF_DROP(&ifp->if_snd);
        !           635:                splx(opri);
        !           636:                m_freem(m);
        !           637:                return (ENOBUFS);
        !           638:        }
        !           639:        IF_ENQUEUE(&ifp->if_snd, m);
        !           640:        /*
        !           641:         * Some action needs to be added here for checking whether the
        !           642:         * board is already transmitting.  If it is, we don't want to
        !           643:         * start it up (ie call ns8390start()).  We will attempt to send
        !           644:         * packets that are queued up after an interrupt occurs.  Some
        !           645:         * flag checking action has to happen here and/or in the start
        !           646:         * routine.  This note is here to remind me that some thought
        !           647:         * is needed and there is a potential problem here.
        !           648:         *
        !           649:         */
        !           650:        ns8390start(ifp->if_unit);
        !           651:        splx(opri);
        !           652:        return (0);
        !           653: bad:
        !           654:        m_freem(m0);
        !           655:        return (error);
        !           656: }
        !           657: #endif MACH_KERNEL
        !           658: 
        !           659: /*
        !           660:  * ns8390reset:
        !           661:  *
        !           662:  *     This routine is in part an entry point for the "if" code.  Since most
        !           663:  *     of the actual initialization has already (we hope already) been done
        !           664:  *     by calling ns8390attach().
        !           665:  *
        !           666:  * input       : unit number or board number to reset
        !           667:  * output      : board is reset
        !           668:  *
        !           669:  */
        !           670: 
        !           671: int
        !           672: ns8390reset(unit)
        !           673: int    unit;
        !           674: {
        !           675: 
        !           676:        ns8390_softc[unit].ds_if.if_flags &= ~IFF_RUNNING;
        !           677:        return(ns8390init(unit));
        !           678: }
        !           679: 
        !           680: /*
        !           681:  * ns8390init:
        !           682:  *
        !           683:  *     Another routine that interfaces the "if" layer to this driver.
        !           684:  *     Simply resets the structures that are used by "upper layers".
        !           685:  *     As well as calling ns8390hwrst that does reset the ns8390 board.
        !           686:  *
        !           687:  * input       : board number
        !           688:  * output      : structures (if structs) and board are reset
        !           689:  *
        !           690:  */
        !           691: 
        !           692: int
        !           693: ns8390init(unit)
        !           694: int    unit;
        !           695: {
        !           696:        struct  ifnet   *ifp;
        !           697:        int             stat;
        !           698:        spl_t           oldpri;
        !           699: 
        !           700:        ifp = &(ns8390_softc[unit].ds_if);
        !           701: #ifdef MACH_KERNEL
        !           702: #else  MACH_KERNEL
        !           703:        if (ifp->if_addrlist == (struct ifaddr *)0) {
        !           704:                return;
        !           705:        }
        !           706: #endif MACH_KERNEL
        !           707:        oldpri = SPLNET();
        !           708:        if ((stat = ns8390hwrst(unit)) == TRUE) {
        !           709:                ns8390_softc[unit].ds_if.if_flags |= IFF_RUNNING;
        !           710:                ns8390_softc[unit].flags |= DSF_RUNNING;
        !           711:                ns8390_softc[unit].tbusy = 0;
        !           712:                ns8390start(unit);
        !           713:        } else
        !           714:                printf("%s%d init(): trouble resetting board %d\n",
        !           715:                        ns8390_softc[unit].card, unit);
        !           716:        ns8390_softc[unit].timer = 5;
        !           717:        splx(oldpri);
        !           718:        return(stat);
        !           719: }
        !           720: 
        !           721: /*
        !           722:  * ns8390start:
        !           723:  *
        !           724:  *     This is yet another interface routine that simply tries to output a
        !           725:  *     in an mbuf after a reset.
        !           726:  *
        !           727:  * input       : board number
        !           728:  * output      : stuff sent to board if any there
        !           729:  *
        !           730:  */
        !           731: 
        !           732: ns8390start(unit)
        !           733: int    unit;
        !           734: {
        !           735:        register ns8390_softc_t *is = &ns8390_softc[unit];
        !           736:        struct  ifnet           *ifp;
        !           737: #ifdef MACH_KERNEL
        !           738:        io_req_t        m;
        !           739: #else  MACH_KERNEL
        !           740:        struct  mbuf    *m;
        !           741: #endif MACH_KERNEL
        !           742: 
        !           743:        if (is->tbusy) {
        !           744:                caddr_t nic = ns8390_softc[unit].nic;
        !           745:                if (!(inb(nic+ds_cmd) & DSCM_TRANS)) {
        !           746:                        is->tbusy = 0;
        !           747:                        ns8390_cntrs[unit].busy++;
        !           748:                } else
        !           749:                        return;
        !           750:        }
        !           751: 
        !           752:        ifp = &(ns8390_softc[unit].ds_if);
        !           753: 
        !           754:        IF_DEQUEUE(&ifp->if_snd, m);
        !           755: #ifdef MACH_KERNEL
        !           756:        if (m != 0)
        !           757: #else  MACH_KERNEL
        !           758:        if (m != (struct mbuf *)0)
        !           759: #endif MACH_KERNEL
        !           760:        {
        !           761:                is->tbusy++;
        !           762:                ns8390_cntrs[unit].xmt++;
        !           763:                ns8390xmt(unit, m);
        !           764:        }
        !           765: }
        !           766: 
        !           767: #ifdef MACH_KERNEL
        !           768: /*ARGSUSED*/
        !           769: ns8390getstat(dev, flavor, status, count)
        !           770:        dev_t           dev;
        !           771:        int             flavor;
        !           772:        dev_status_t    status;         /* pointer to OUT array */
        !           773:        unsigned int    *count;         /* out */
        !           774: {
        !           775:        register int    unit = minor(dev);
        !           776: 
        !           777:        if (unit < 0 || unit >= NNS8390 ||
        !           778:                ns8390_softc[unit].nic == 0)
        !           779:            return (ENXIO);
        !           780: 
        !           781:        return (net_getstat(&ns8390_softc[unit].ds_if,
        !           782:                            flavor,
        !           783:                            status,
        !           784:                            count));
        !           785: }
        !           786: ns8390setstat(dev, flavor, status, count)
        !           787:        dev_t           dev;
        !           788:        int             flavor;
        !           789:        dev_status_t    status;
        !           790:        unsigned int    count;
        !           791: {
        !           792:        register int    unit = minor(dev);
        !           793:        register ns8390_softc_t *sp;
        !           794: 
        !           795:        if (unit < 0 || unit >= NNS8390 ||
        !           796:                ns8390_softc[unit].nic == 0)
        !           797:            return (ENXIO);
        !           798: 
        !           799:        sp = &ns8390_softc[unit];
        !           800: 
        !           801:        switch (flavor) {
        !           802:            case NET_STATUS:
        !           803:            {
        !           804:                /*
        !           805:                 * All we can change are flags, and not many of those.
        !           806:                 */
        !           807:                register struct net_status *ns = (struct net_status *)status;
        !           808:                int     mode = 0;
        !           809: 
        !           810:                if (count < NET_STATUS_COUNT)
        !           811:                    return (D_INVALID_SIZE);
        !           812: 
        !           813:                if (ns->flags & IFF_ALLMULTI)
        !           814:                    mode |= MOD_ENAL;
        !           815:                if (ns->flags & IFF_PROMISC)
        !           816:                    mode |= MOD_PROM;
        !           817: 
        !           818:                /*
        !           819:                 * Force a complete reset if the receive mode changes
        !           820:                 * so that these take effect immediately.
        !           821:                 */
        !           822:                if (sp->mode != mode) {
        !           823:                    sp->mode = mode;
        !           824:                    if (sp->flags & DSF_RUNNING) {
        !           825:                        sp->flags &= ~(DSF_LOCK | DSF_RUNNING);
        !           826:                        ns8390init(unit);
        !           827:                    }
        !           828:                }
        !           829:                break;
        !           830:            }
        !           831: 
        !           832:            default:
        !           833:                return (D_INVALID_OPERATION);
        !           834:        }
        !           835:        return (D_SUCCESS);
        !           836: }
        !           837: #else  MACH_KERNEL
        !           838: /*
        !           839:  * ns8390ioctl:
        !           840:  *
        !           841:  *     This routine processes an ioctl request from the "if" layer
        !           842:  *     above.
        !           843:  *
        !           844:  * input       : pointer the appropriate "if" struct, command, and data
        !           845:  * output      : based on command appropriate action is taken on the
        !           846:  *               ns8390 board(s) or related structures
        !           847:  * return      : error is returned containing exit conditions
        !           848:  *
        !           849:  */
        !           850: 
        !           851: int
        !           852: ns8390ioctl(ifp, cmd, data)
        !           853: struct ifnet   *ifp;
        !           854: int    cmd;
        !           855: caddr_t        data;
        !           856: {
        !           857:        register struct ifaddr  *ifa = (struct ifaddr *)data;
        !           858:        register ns8390_softc_t *is;
        !           859:        int                     error;
        !           860:        spl_t                   opri;
        !           861:        short                    mode = 0;
        !           862: 
        !           863:        is = &ns8390_softc[ifp->if_unit];
        !           864:        opri = SPLNET();
        !           865:        error = 0;
        !           866:        switch (cmd) {
        !           867:        case SIOCSIFADDR:
        !           868:                ifp->if_flags |= IFF_UP;
        !           869:                ns8390init(ifp->if_unit);
        !           870:                switch (ifa->ifa_addr.sa_family) {
        !           871: #ifdef INET
        !           872:                case AF_INET:
        !           873:                        ((struct arpcom *)ifp)->ac_ipaddr =
        !           874:                            IA_SIN(ifa)->sin_addr;
        !           875:                        arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
        !           876:                        break;
        !           877: #endif
        !           878: #ifdef NS
        !           879:                case AF_NS:
        !           880:                        {
        !           881:                                register struct ns_addr *ina =
        !           882:                                    &(IA_SNS(ifa)->sns_addr);
        !           883:                                if (ns_nullhost(*ina))
        !           884:                                        ina->x_host =
        !           885:                                            *(union ns_host *)(ds->ds_addr);
        !           886:                                else
        !           887: ????
        !           888:                                        ns8390seteh(ina->x_host.c_host,
        !           889:                                                    ns8390_softc[ifp->if_unit].base);
        !           890:                                break;
        !           891:                        }
        !           892: #endif
        !           893:                }
        !           894:                break;
        !           895:        case SIOCSIFFLAGS:
        !           896:                if (ifp->if_flags & IFF_ALLMULTI)
        !           897:                        mode |= MOD_ENAL;
        !           898:                if (ifp->if_flags & IFF_PROMISC)
        !           899:                        mode |= MOD_PROM;
        !           900:                /*
        !           901:                 * force a complete reset if the receive multicast/
        !           902:                 * promiscuous mode changes so that these take
        !           903:                 * effect immediately.
        !           904:                 *
        !           905:                 */
        !           906:                if (is->mode != mode) {
        !           907:                        is->mode = mode;
        !           908:                        if (is->flags & DSF_RUNNING) {
        !           909:                                is->flags &=
        !           910:                                    ~(DSF_LOCK|DSF_RUNNING);
        !           911:                                ns8390init(ifp->if_unit);
        !           912:                        }
        !           913:                }
        !           914:                if ((ifp->if_flags & IFF_UP) == 0 &&
        !           915:                    is->flags & DSF_RUNNING) {
        !           916:                        printf("%s%d ioctl(): turning off board %d\n",
        !           917:                                is->card, ifp->if_unit);
        !           918:                        is->flags &= ~(DSF_LOCK | DSF_RUNNING);
        !           919:                        is->timer = -1;
        !           920:                        ns8390intoff(ifp->if_unit);
        !           921:                        ns8390over_write(ifp->if_unit);
        !           922:                } else
        !           923:                    if (ifp->if_flags & IFF_UP &&
        !           924:                    (is->flags & DSF_RUNNING) == 0)
        !           925:                        ns8390init(ifp->if_unit);
        !           926:                break;
        !           927: #ifdef IF_CNTRS
        !           928:        case SIOCCIFCNTRS:
        !           929:                if (!suser()) {
        !           930:                        error = EPERM;
        !           931:                        break;
        !           932:                }
        !           933:                bzero((caddr_t)ns_ein, sizeof (ns_ein));
        !           934:                bzero((caddr_t)ns_eout, sizeof (ns_eout));
        !           935:                bzero((caddr_t)ns_lin, sizeof (ns_lin));
        !           936:                bzero((caddr_t)ns_lout, sizeof (ns_lout));
        !           937:                bzero((caddr_t)&ns_arp, sizeof (int));
        !           938:                bzero((caddr_t)&ns8390_cntrs, sizeof (ns8390_cntrs));
        !           939:                break;
        !           940: #endif IF_CNTRS
        !           941:        default:
        !           942:                error = EINVAL;
        !           943:        }
        !           944:        splx(opri);
        !           945:        return (error);
        !           946: }
        !           947: #endif MACH_KERNEL
        !           948: 
        !           949: /*
        !           950:  * ns8390hwrst:
        !           951:  *
        !           952:  *     This routine resets the ns8390 board that corresponds to the
        !           953:  *     board number passed in.
        !           954:  *
        !           955:  * input       : board number to do a hardware reset
        !           956:  * output      : board is reset
        !           957:  *
        !           958:  */
        !           959: 
        !           960: int
        !           961: ns8390hwrst(unit)
        !           962: int unit;
        !           963: {
        !           964:        caddr_t nic = ns8390_softc[unit].nic;
        !           965:        int     count;
        !           966:        u_char  stat;
        !           967:        spl_t   spl = SPLNET();
        !           968: 
        !           969:        if (ns8390_softc[unit].card == wd8003_card && 
        !           970:            config_wd8003(unit) == FALSE) {
        !           971:                printf("%s%d hwrst(): config_wd8003 failed.\n",
        !           972:                        ns8390_softc[unit].card, unit);
        !           973:                splx(spl);
        !           974:                return(FALSE);
        !           975:        }
        !           976:        if (ns8390_softc[unit].card == elii_card && 
        !           977:            config_3c503(unit) == FALSE) {
        !           978:                printf("%s%d hwrst(): config_3c503 failed.\n",
        !           979:                        ns8390_softc[unit].card, unit);
        !           980:                splx(spl);
        !           981:                return(FALSE);
        !           982:        }
        !           983:        if (config_nic(unit) == FALSE) {
        !           984:                printf("%s%d hwrst(): config_nic failed.\n",
        !           985:                        ns8390_softc[unit].card, unit);
        !           986:                splx(spl);
        !           987:                return(FALSE);
        !           988:        }
        !           989:        splx(spl);
        !           990:        return(TRUE);
        !           991: }
        !           992: 
        !           993: /*
        !           994:  * ns8390intr:
        !           995:  *
        !           996:  *     This function is the interrupt handler for the ns8390 ethernet
        !           997:  *     board.  This routine will be called whenever either a packet
        !           998:  *     is received, or a packet has successfully been transfered and
        !           999:  *     the unit is ready to transmit another packet.
        !          1000:  *
        !          1001:  * input       : board number that interrupted
        !          1002:  * output      : either a packet is received, or a packet is transfered
        !          1003:  *
        !          1004:  */
        !          1005: int
        !          1006: ns8390intr(unit)
        !          1007: {
        !          1008:        int     opri, i;
        !          1009:        int     isr_status;
        !          1010:        int     temp_cr;
        !          1011:        caddr_t nic = ns8390_softc[unit].nic;
        !          1012: 
        !          1013:        temp_cr = inb(nic+ds_cmd);
        !          1014:        outb(nic+ds_cmd, (temp_cr & 0x3f) | DSCM_PG0);
        !          1015:        outb(nic+ds0_imr, 0);                   /* stop board interrupts */
        !          1016:        outb(nic+ds_cmd, temp_cr);
        !          1017:        while (isr_status = inb(nic+ds0_isr)) {
        !          1018:                outb(nic+ds0_isr, isr_status);          /* clear interrupt status */
        !          1019: 
        !          1020:                if ((isr_status & (DSIS_ROVRN|DSIS_RXE)) == DSIS_RXE) {
        !          1021:                        int rsr = inb(nic+ds0_rsr);
        !          1022:                        if (rsr & DSRS_DFR) ns8390_cntrs[unit].jabber++;
        !          1023:                        if (rsr & ~(DSRS_DFR|DSRS_PHY|DSRS_FAE|DSRS_CRC|DSIS_RX))
        !          1024:                                printf("%s%d intr(): isr = %x, RSR = %x\n",
        !          1025:                                        ns8390_softc[unit].card, unit,
        !          1026:                                        isr_status, rsr);
        !          1027:                } else if (isr_status & DSIS_ROVRN) {
        !          1028:                        ns8390_cntrs[unit].ovw++;
        !          1029:                        ns8390over_write(unit);
        !          1030:                }
        !          1031:                if (isr_status & DSIS_RX) {     /* DFR & PRX is possible */
        !          1032:                        ns8390rcv(unit);
        !          1033: 
        !          1034: #if    MACH_TTD
        !          1035:                        if (kttd_active)
        !          1036:                                ttd_poll_loop = FALSE;
        !          1037: #endif /* MACH_TTD */
        !          1038:                }
        !          1039: 
        !          1040:                if (isr_status & DSIS_TXE) {
        !          1041:                        int tsr = inb(nic+ds0_tsr);
        !          1042:                        tsr &= ~0x2;            /* unadvertised special */
        !          1043: #if    MACH_TTD
        !          1044:                        if (!kttd_active)
        !          1045: #endif /* MACH_TTD */
        !          1046:                        {
        !          1047:                                if (tsr == (DSTS_CDH|DSTS_ABT))
        !          1048:                                        ns8390_cntrs[unit].heart++;
        !          1049:                                else
        !          1050:                                        printf("%s%d intr(): isr = %x, TSR = %x\n",
        !          1051:                                               ns8390_softc[unit].card, unit,
        !          1052:                                               isr_status, tsr);
        !          1053:                                ns8390_softc[unit].tbusy = 0;
        !          1054:                                ns8390start(unit);
        !          1055:                        }
        !          1056:                } else if (isr_status & DSIS_TX) {
        !          1057: #if    MACH_TTD
        !          1058:                        if (!kttd_active)
        !          1059: #endif /* MACH_TTD */
        !          1060:                        {
        !          1061:                                ns8390_cntrs[unit].xmti++;
        !          1062:                                ns8390_softc[unit].tbusy = 0;
        !          1063:                                ns8390start(unit);
        !          1064:                        }
        !          1065:                }
        !          1066: 
        !          1067:                if (isr_status & DSIS_CTRS) {
        !          1068:                        int c0 = inb(nic+ds0_cntr0);
        !          1069:                        int c1 = inb(nic+ds0_cntr1);
        !          1070:                        int c2 = inb(nic+ds0_cntr2);
        !          1071:                        ns8390_cntrs[unit].frame += c0;
        !          1072:                        ns8390_cntrs[unit].crc += c1;
        !          1073:                        ns8390_cntrs[unit].miss += c2;
        !          1074: #ifdef COUNTERS
        !          1075:                        printf("%s%d intr(): isr = %x, FRAME %x, CRC %x, MISS %x\n",
        !          1076:                                ns8390_softc[unit].card, unit,
        !          1077:                                isr_status, c0, c1, c2);
        !          1078:                        printf("%s%d intr(): TOTAL   , FRAME %x, CRC %x, MISS %x\n",
        !          1079:                                ns8390_softc[unit].card, unit,
        !          1080:                                ns8390_cntrs[unit].frame,
        !          1081:                                ns8390_cntrs[unit].crc,
        !          1082:                                ns8390_cntrs[unit].miss);
        !          1083: #endif COUNTERS
        !          1084:                        outb(nic+ds0_isr, isr_status);  /* clear interrupt status again */
        !          1085:                }
        !          1086:        }
        !          1087:        temp_cr=inb(nic+ds_cmd);
        !          1088:        outb(nic+ds_cmd, (temp_cr & 0x3f) | DSCM_PG0);
        !          1089:        outb(nic+ds0_imr, imr_hold);
        !          1090:        outb(nic+ds_cmd, temp_cr);
        !          1091:        return(0);
        !          1092: }
        !          1093: 
        !          1094: /*
        !          1095:  *  Called if on board buffer has been completely filled by ns8390intr.  It stops
        !          1096:  *  the board, reads in all the buffers that are currently in the buffer, and
        !          1097:  *  then restart board.
        !          1098:  */
        !          1099: ns8390over_write(unit)
        !          1100: int unit;
        !          1101: {
        !          1102:        caddr_t nic = ns8390_softc[unit].nic;
        !          1103:        int     no;
        !          1104:        int     count = 0;
        !          1105: 
        !          1106:        outb(nic+ds_cmd, DSCM_NODMA|DSCM_STOP|DSCM_PG0);        /* clear the receive buffer */
        !          1107:        outb(nic+ds0_rbcr0, 0);
        !          1108:        outb(nic+ds0_rbcr1, 0);  
        !          1109:        while ((!(inb (nic + ds0_isr) & DSIS_RESET)) && (count < 10000))
        !          1110:                count++;
        !          1111:        if (count == 10000) {
        !          1112:                printf("%s%d: over_write(): would not reset.\n",
        !          1113:                        ns8390_softc[unit].card, unit);
        !          1114:        }
        !          1115:        no = ns8390rcv(unit);
        !          1116: #ifdef OVWBUG
        !          1117:        printf("%s%d over_write(): ns8390 OVW ... %d.\n",
        !          1118:                ns8390_softc[unit].card, unit, no);
        !          1119: #endif OVWBUG
        !          1120:        outb(nic+ds0_tcr, DSTC_LB0);    /* External loopback mode */
        !          1121:        outb(nic+ds_cmd, DSCM_NODMA|DSCM_START|DSCM_PG0);
        !          1122:        outb(nic+ds0_tcr, 0);
        !          1123:        return;
        !          1124: }
        !          1125: 
        !          1126: /*
        !          1127:  * ns8390rcv:
        !          1128:  *
        !          1129:  *     This routine is called by the interrupt handler to initiate a
        !          1130:  *     packet transfer from the board to the "if" layer above this
        !          1131:  *     driver.  This routine checks if a buffer has been successfully
        !          1132:  *     received by the ns8390.  If so, it does the actual transfer of the
        !          1133:  *      board data (including the ethernet header) into a packet (consisting
        !          1134:  *      of an mbuf chain) and enqueues it to a higher level.
        !          1135:  *      Then check again whether there are any packets in the receive ring,
        !          1136:  *      if so, read the next packet, until there are no more.
        !          1137:  *
        !          1138:  * input       : number of the board to check
        !          1139:  * output      : if a packet is available, it is "sent up"
        !          1140:  */
        !          1141: ns8390rcv(unit)
        !          1142: int unit;
        !          1143: {
        !          1144:        register ns8390_softc_t *is = &ns8390_softc[unit];
        !          1145:        register struct ifnet   *ifp = &is->ds_if;
        !          1146:        caddr_t                 nic = is->nic;
        !          1147:        int                     packets = 0;
        !          1148:        struct ether_header     eh;
        !          1149:        u_short                 mlen, len, bytes_in_mbuf, bytes;
        !          1150:        u_short                 remaining;
        !          1151:        int                     temp_cr;
        !          1152:        u_char                  *mb_p;
        !          1153:        int                     board_id = is->board_id;
        !          1154:        vm_offset_t             hdwbase = ns8390info[unit]->address;
        !          1155:        spl_t                   s;
        !          1156: 
        !          1157:        /* calculation of pkt size */
        !          1158:        int nic_overcount;         /* NIC says 1 or 2 more than we need */
        !          1159:        int pkt_size;              /* calculated size of received data */
        !          1160:        int wrap_size;             /* size of data before wrapping it */
        !          1161:        int header_nxtpkt_ptr;     /* NIC's next pkt ptr in rcv header */
        !          1162:        int low_byte_count;        /* low byte count of read from rcv header */
        !          1163:        int high_byte_count;       /* calculated high byte count */
        !          1164: 
        !          1165: 
        !          1166:        volatile char *sram_nxtpkt_ptr;   /* mem location of next packet */
        !          1167:        volatile char *sram_getdata_ptr;  /* next location to be read */
        !          1168: #ifdef MACH_KERNEL
        !          1169:        ipc_kmsg_t      new_kmsg;
        !          1170:        struct ether_header *ehp;
        !          1171:        struct packet_header *pkt;
        !          1172: #else  MACH_KERNEL
        !          1173:        struct mbuf *m, *tm;              /* initial allocation of mem; temp */
        !          1174: #endif MACH_KERNEL
        !          1175: 
        !          1176: 
        !          1177: #if    MACH_TTD
        !          1178:        if (((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) &&
        !          1179:            !kttd_active) {
        !          1180: #else
        !          1181:        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
        !          1182: #endif /* MACH_TTD */
        !          1183:                temp_cr = inb(nic+ds_cmd); /* get current CR value */
        !          1184:                outb(nic+ds_cmd,((temp_cr & 0x3F)|DSCM_PG0|DSCM_STOP));
        !          1185:                outb(nic+ds0_imr, 0);      /* Interrupt Mask Register  */
        !          1186:                outb(nic+ds_cmd, temp_cr);
        !          1187:                return -1;
        !          1188:        }
        !          1189: 
        !          1190:        while(is->read_nxtpkt_ptr != ns8390get_CURR(unit))   {
        !          1191: 
        !          1192:                /* while there is a packet to read from the buffer */
        !          1193: 
        !          1194:                if ((is->read_nxtpkt_ptr < is->pstart) ||
        !          1195:                    (is->read_nxtpkt_ptr >= is->pstop)) {
        !          1196:                        ns8390hwrst(unit);
        !          1197:                        return -1;
        !          1198:                }    /* if next packet pointer is out of receive ring bounds */
        !          1199: 
        !          1200: #if    MACH_TTD
        !          1201:                if (!kttd_active)
        !          1202: #endif /* MACH_TTD */
        !          1203:                {
        !          1204:                        packets++;
        !          1205:                        ns8390_cntrs[unit].rcv++;
        !          1206:                }
        !          1207: 
        !          1208:                sram_nxtpkt_ptr = (char *) (is->sram + (is->read_nxtpkt_ptr << 8));
        !          1209: 
        !          1210:                /* get packet size and location of next packet */
        !          1211:                header_nxtpkt_ptr = *(sram_nxtpkt_ptr + 1);
        !          1212:                header_nxtpkt_ptr &= 0xFF;
        !          1213:                low_byte_count = *(sram_nxtpkt_ptr + 2);
        !          1214:                low_byte_count &= 0xFF;
        !          1215: 
        !          1216:                if ((low_byte_count + NIC_HEADER_SIZE) > NIC_PAGE_SIZE)
        !          1217:                        nic_overcount = 2;
        !          1218:                else
        !          1219:                        nic_overcount = 1;
        !          1220:                if (header_nxtpkt_ptr > is->read_nxtpkt_ptr) {
        !          1221:                        wrap_size = 0;
        !          1222:                        high_byte_count = header_nxtpkt_ptr - is->read_nxtpkt_ptr -
        !          1223:                            nic_overcount;
        !          1224:                } else {
        !          1225:                        wrap_size = (int) (is->pstop - is->read_nxtpkt_ptr - nic_overcount);
        !          1226:                        high_byte_count = is->pstop - is->read_nxtpkt_ptr +
        !          1227:                            header_nxtpkt_ptr - is->pstart - nic_overcount;
        !          1228:                }
        !          1229:                pkt_size = (high_byte_count << 8) | (low_byte_count & 0xFF);
        !          1230:                /* does not seem to include NIC_HEADER_SIZE */
        !          1231:                if (!pkt_size) {
        !          1232:                        printf("%s%d rcv(): zero length.\n",
        !          1233:                                ns8390_softc[unit].card, unit);
        !          1234:                        goto next_pkt;
        !          1235:                }
        !          1236:                len = pkt_size;
        !          1237: 
        !          1238:                sram_getdata_ptr = sram_nxtpkt_ptr + NIC_HEADER_SIZE;
        !          1239:                if (board_id & IFWD_SLOT_16BIT) {
        !          1240: #if    MACH_TTD
        !          1241:                        if (!kttd_active)
        !          1242: #endif /* MACH_TTD */
        !          1243:                        { s = splhi(); }
        !          1244: 
        !          1245:                        en_16bit_access(hdwbase, board_id);
        !          1246:                        bcopy16 (sram_getdata_ptr,
        !          1247:                                 &eh,
        !          1248:                                 sizeof(struct ether_header));
        !          1249:                        dis_16bit_access (hdwbase, board_id);
        !          1250: #if    MACH_TTD
        !          1251:                        if (!kttd_active)
        !          1252: #endif /* MACH_TTD */
        !          1253:                        { splx(s); }
        !          1254: 
        !          1255:                } else {
        !          1256:                        bcopy16 (sram_getdata_ptr,
        !          1257:                                 &eh,
        !          1258:                                 sizeof(struct ether_header));
        !          1259:                }                   
        !          1260:                sram_getdata_ptr += sizeof(struct ether_header);
        !          1261:                len -= (sizeof(struct ether_header) + 4);       /* crc size */
        !          1262: #ifdef MACH_KERNEL
        !          1263: #if    MACH_TTD
        !          1264:                if (kttd_active) {
        !          1265:                        new_kmsg = (ipc_kmsg_t)ttd_request_msg;
        !          1266:                }else
        !          1267: #endif /* MACH_TTD */
        !          1268:                {
        !          1269:                        new_kmsg = net_kmsg_get();
        !          1270:                        if (new_kmsg == IKM_NULL) {
        !          1271:                                /*
        !          1272:                                 * Drop the packet.
        !          1273:                                 */
        !          1274:                                is->ds_if.if_rcvdrops++;    
        !          1275:                                /*
        !          1276:                                 * not only do we want to return, we need to drop
        !          1277:                                 * the packet on the floor to clear the interrupt.
        !          1278:                                 */
        !          1279:                                ns8390lost_frame(unit);
        !          1280:                                return;/* packets;*/
        !          1281:                        }
        !          1282:                }
        !          1283: 
        !          1284: #if    DEBUG_TTD
        !          1285:                dump_ether_header("ns8390wire",&eh);
        !          1286: #endif /* DEBUG_TTD */
        !          1287: 
        !          1288:                ehp = (struct ether_header *) (&net_kmsg(new_kmsg)->header[0]);
        !          1289:                pkt = (struct packet_header *) (&net_kmsg(new_kmsg)->packet[0]);
        !          1290: 
        !          1291: #if    DEBUG_TTD
        !          1292:                printf("!ehp = 0x%x, pkt = 0x%x!",ehp, pkt);
        !          1293: #endif /* DEBUG_TTD */
        !          1294: 
        !          1295:                *ehp = eh;
        !          1296:                if (len >
        !          1297:                    (wrap_size = (is->sram + (is->pstop << 8) - sram_getdata_ptr))) {
        !          1298:                        /* if needs to wrap */
        !          1299:                        if (board_id & IFWD_SLOT_16BIT) {
        !          1300: #if    MACH_TTD
        !          1301:                                if (!kttd_active)
        !          1302: #endif /* MACH_TTD */
        !          1303:                                { s = splhi(); }
        !          1304: 
        !          1305:                                en_16bit_access(hdwbase, board_id);
        !          1306:                                bcopy16 (sram_getdata_ptr, (char *) (pkt + 1),
        !          1307:                                         wrap_size);
        !          1308:                                dis_16bit_access (hdwbase, board_id);
        !          1309: #if    MACH_TTD
        !          1310:                                if (!kttd_active)
        !          1311: #endif /* MACH_TTD */
        !          1312:                                { splx(s); }
        !          1313:                        } else {
        !          1314:                                bcopy (sram_getdata_ptr, (char *) (pkt + 1),
        !          1315:                                       wrap_size);
        !          1316:                        }
        !          1317:                        sram_getdata_ptr = (volatile char *)
        !          1318:                            (is->sram + (is->pstart << 8));
        !          1319:                } else {   /* normal getting data from buffer */
        !          1320:                        wrap_size = 0;
        !          1321:                }
        !          1322:                if (board_id & IFWD_SLOT_16BIT) {
        !          1323: #if    MACH_TTD
        !          1324:                        if (!kttd_active)
        !          1325: #endif /* MACH_TTD */
        !          1326:                        { s = splhi(); }
        !          1327:                        en_16bit_access(hdwbase, board_id);
        !          1328:                        bcopy16 (sram_getdata_ptr,
        !          1329:                                 (char *) (pkt + 1) + wrap_size,
        !          1330:                                 len - wrap_size);
        !          1331:                        dis_16bit_access (hdwbase, board_id);
        !          1332: #if    MACH_TTD
        !          1333:                        if (!kttd_active)
        !          1334: #endif /* MACH_TTD */
        !          1335:                        { splx(s); }
        !          1336:                } else {
        !          1337:                        bcopy (sram_getdata_ptr,
        !          1338:                               (char *) (pkt + 1) + wrap_size,
        !          1339:                               len - wrap_size);
        !          1340:                }
        !          1341: 
        !          1342:                pkt->type = ehp->ether_type;
        !          1343:                pkt->length = len + sizeof(struct packet_header);
        !          1344: 
        !          1345: #if    MACH_TTD
        !          1346:                /*
        !          1347:                 * Don't want to call net_packet if we are polling
        !          1348:                 * for a packet.
        !          1349:                 */
        !          1350:                if (!kttd_active)
        !          1351: #endif /* MACH_TTD */
        !          1352:                {
        !          1353:                        /*
        !          1354:                         * Hand the packet to the network module.
        !          1355:                         */
        !          1356:                        net_packet(ifp, new_kmsg, pkt->length,
        !          1357:                                   ethernet_priority(new_kmsg));
        !          1358:                }
        !          1359: 
        !          1360: #else  MACH_KERNEL
        !          1361: #define NEW
        !          1362: #ifdef NEW
        !          1363:                m = (struct mbuf *) 0;
        !          1364:                eh.ether_type = ntohs(eh.ether_type);
        !          1365:                MGET(m, M_DONTWAIT, MT_DATA);
        !          1366:                if (m == (struct mbuf *) 0) {
        !          1367:                        printf("%s%d rcv(): Lost frame\n",
        !          1368:                                ns8390_softc[unit].card, unit);
        !          1369:                        ns8390lost_frame(unit); /* update NIC pointers and registers */
        !          1370:                        return packets;
        !          1371:                }
        !          1372:                m->m_next = (struct mbuf *) 0;
        !          1373:                tm = m;
        !          1374:                m->m_len = MLEN;
        !          1375:                if (len > 2 * MLEN - sizeof (struct ifnet **)) {
        !          1376:                        MCLGET(m);
        !          1377:                }
        !          1378:                *(mtod(tm, struct ifnet **)) = ifp;
        !          1379:                mlen = sizeof (struct ifnet **);
        !          1380:                bytes_in_mbuf = m->m_len - sizeof(struct ifnet **);
        !          1381:                mb_p = mtod(tm, u_char *) + sizeof (struct ifnet **);
        !          1382:                bytes = min(bytes_in_mbuf, len);
        !          1383:                remaining =  (int) (is->sram + (is->pstop << 8) -
        !          1384:                                    sram_getdata_ptr);
        !          1385:                bytes = min(bytes, remaining);
        !          1386:                do {
        !          1387:                        if (board_id & IFWD_SLOT_16BIT) {
        !          1388:                                s = splhi();
        !          1389:                                en_16bit_access(hdwbase, board_id);
        !          1390:                                bcopy16 (sram_getdata_ptr, mb_p, bytes);
        !          1391:                                dis_16bit_access (hdwbase, board_id);
        !          1392:                                splx(s);
        !          1393:                        } else {
        !          1394:                                bcopy16 (sram_getdata_ptr, mb_p, bytes);
        !          1395:                        }
        !          1396:                        
        !          1397:                        mlen += bytes;
        !          1398: 
        !          1399:                        if (!(bytes_in_mbuf -= bytes)) {
        !          1400:                                MGET(tm->m_next, M_DONTWAIT, MT_DATA);
        !          1401:                                tm = tm->m_next;
        !          1402:                                if (tm == (struct mbuf *)0) {
        !          1403:                                        printf("%s%d rcv(): No mbufs, lost frame\n",
        !          1404:                                                ns8390_softc[unit].card, unit);
        !          1405:                                        m_freem(m);              /* free the mbuf chain */
        !          1406:                                        ns8390lost_frame(unit);  /* update NIC pointers and registers */
        !          1407:                                        return;
        !          1408:                                }
        !          1409:                                mlen = 0;
        !          1410:                                tm->m_len = MLEN;
        !          1411:                                bytes_in_mbuf = MLEN;
        !          1412:                                mb_p = mtod(tm, u_char *);
        !          1413:                        } else
        !          1414:                                mb_p += bytes;
        !          1415: 
        !          1416:                        if (!(len  -= bytes)) {
        !          1417:                                tm->m_len = mlen;
        !          1418:                                break;
        !          1419:                        } else if (bytes == remaining) {
        !          1420:                                sram_getdata_ptr = (volatile char *) (is->sram +
        !          1421:                                    (is->pstart << 8));
        !          1422:                                bytes = len;
        !          1423:                                remaining = ETHERMTU;
        !          1424:                        } else {
        !          1425:                                sram_getdata_ptr += bytes;
        !          1426:                                remaining -= bytes;
        !          1427:                        }
        !          1428: 
        !          1429:                        bytes = min(bytes_in_mbuf, len);
        !          1430:                        bytes = min(bytes, remaining);
        !          1431:                } while(1);
        !          1432: #else  NEW
        !          1433:                m = (struct mbuf *) 0;
        !          1434:                eh.ether_type = ntohs(eh.ether_type);
        !          1435: 
        !          1436:                while ( len ) {
        !          1437:                        if (m == (struct mbuf *) 0) {
        !          1438:                                m = m_get(M_DONTWAIT, MT_DATA);
        !          1439:                                if (m == (struct mbuf *) 0) {
        !          1440:                                        printf("%s%d rcv(): Lost frame\n",
        !          1441:                                        ns8390_softc[unit].card, unit);
        !          1442:                                        ns8390lost_frame(unit); /* update NIC pointers and registers */
        !          1443:                                        return packets;
        !          1444:                                }
        !          1445:                                tm = m;
        !          1446:                                tm->m_off = MMINOFF;
        !          1447: 
        !          1448: 
        !          1449:                                /*
        !          1450:                                 * first mbuf in the packet must contain a pointer to the
        !          1451:                                 * ifnet structure.  other mbufs that follow and make up
        !          1452:                                 * the packet do not need this pointer in the mbuf.
        !          1453:                                 *
        !          1454:                                 */
        !          1455: 
        !          1456:                                *(mtod(tm, struct ifnet **)) = ifp;
        !          1457:                                tm->m_len = sizeof(struct ifnet **);
        !          1458: 
        !          1459:                        /* end of first buffer of packet */
        !          1460:                        } else {
        !          1461:                                tm->m_next = m_get(M_DONTWAIT, MT_DATA);
        !          1462:                                tm = tm->m_next;
        !          1463:                                if (tm == (struct mbuf *) 0) {
        !          1464:                                        printf("%s%d rcv(): No mbufs, lost frame\n",
        !          1465:                                                ns8390_softc[unit].card, unit);
        !          1466:                                        m_freem(m);              /* free the mbuf chain */
        !          1467:                                        ns8390lost_frame(unit);  /* update NIC pointers and registers */
        !          1468:                                        return packets;
        !          1469:                                }
        !          1470:                                tm->m_off = MMINOFF;
        !          1471:                                tm->m_len = 0;
        !          1472:                        }
        !          1473: 
        !          1474:                        tlen = MIN( MLEN - tm->m_len, len);
        !          1475:                        /* size of mbuf so you know how much you can copy from board */
        !          1476:                        tm->m_next = (struct mbuf *) 0;
        !          1477:                        if (sram_getdata_ptr + tlen >=
        !          1478:                            (volatile char *) (is->sram + (is->pstop << 8))) {
        !          1479:                                /* if needs to wrap */
        !          1480:                                wrap_size = (int) (is->sram + (is->pstop << 8) -
        !          1481:                                    sram_getdata_ptr);
        !          1482:                                if (board_id & IFWD_SLOT_16BIT) {
        !          1483:                                        s = splhi();
        !          1484:                                        en_16bit_access(hdwbase, board_id);
        !          1485:                                        bcopy16 (sram_getdata_ptr,
        !          1486:                                                 mtod(tm, char*) + tm->m_len,
        !          1487:                                                 wrap_size);
        !          1488:                                        dis_16bit_access (hdwbase, board_id);
        !          1489:                                        splx(s);
        !          1490:                                } else {
        !          1491:                                        bcopy16 (sram_getdata_ptr,
        !          1492:                                                 mtod(tm, char*) + tm->m_len,
        !          1493:                                                 wrap_size);
        !          1494:                                }
        !          1495:                                tm->m_len += wrap_size;
        !          1496:                                len -= wrap_size;
        !          1497: 
        !          1498:                                sram_getdata_ptr = (volatile char *) (is->sram +
        !          1499:                                    (is->pstart << 8));
        !          1500:                        } else {   /* normal getting data from buffer */
        !          1501:                                if (board_id & IFWD_SLOT_16BIT) {
        !          1502:                                        s = splhi();
        !          1503:                                        en_16bit_access(hdwbase, board_id);
        !          1504:                                        bcopy16 (sram_getdata_ptr,
        !          1505:                                                 mtod(tm, char*) + tm->m_len,
        !          1506:                                                 tlen);
        !          1507:                                        dis_16bit_access (hdwbase, board_id);
        !          1508:                                        splx(s);
        !          1509:                                } else {
        !          1510:                                        bcopy16 (sram_getdata_ptr,
        !          1511:                                                 mtod(tm, char*) + tm->m_len,
        !          1512:                                                 tlen);
        !          1513:                                }
        !          1514:                                sram_getdata_ptr += tlen;
        !          1515:                                tm->m_len += tlen;
        !          1516:                                len -= tlen;
        !          1517: 
        !          1518:                              }
        !          1519:                }
        !          1520: 
        !          1521: #endif NEW
        !          1522:                if (!ns8390send_packet_up(m, &eh, is))
        !          1523:                        m_freem(m);
        !          1524: #ifdef IF_CNTRS
        !          1525:                ns_ein[log_2(pkt_size)]++;
        !          1526:                if (pkt_size < 128) ns_lin[(pkt_size)>>3]++;
        !          1527: 
        !          1528:                if (eh.ether_type == ETHERTYPE_ARP) {
        !          1529:                        ns_arp++;
        !          1530:                        if (ns_narp) {
        !          1531:                                ns_ein[log_2(pkt_size)]--;
        !          1532:                                if (pkt_size < 128) ns_lin[(pkt_size)>>3]--;
        !          1533:                        }
        !          1534:                }
        !          1535: #endif IF_CNTRS
        !          1536: #endif MACH_KERNEL
        !          1537: 
        !          1538: next_pkt:
        !          1539:                is->read_nxtpkt_ptr = *(sram_nxtpkt_ptr + 1);
        !          1540:                is->read_nxtpkt_ptr &= 0xFF;
        !          1541: 
        !          1542: #if    MACH_TTD
        !          1543:                if (!kttd_active)
        !          1544: #endif /* MACH_TTD */
        !          1545:                {
        !          1546:                        temp_cr = inb(nic+ds_cmd);
        !          1547:                        outb(nic+ds_cmd, (temp_cr & 0x3f) | DSCM_PG0);
        !          1548:                }
        !          1549: 
        !          1550:                if (is->read_nxtpkt_ptr == ns8390get_CURR(unit))
        !          1551:                        if (is->read_nxtpkt_ptr == is->pstart)
        !          1552:                                outb(nic+ds0_bndy, is->pstop - 1);
        !          1553:                        else
        !          1554:                                outb(nic+ds0_bndy, is->read_nxtpkt_ptr - 1);
        !          1555:                else
        !          1556:                        outb(nic+ds0_bndy, is->read_nxtpkt_ptr);
        !          1557: 
        !          1558: #if    MACH_TTD
        !          1559:                if (!kttd_active)
        !          1560: #endif /* MACH_TTD */
        !          1561:                { outb(nic+ds_cmd, temp_cr); }
        !          1562: 
        !          1563: #if    MACH_TTD
        !          1564:                /*
        !          1565:                 * Hand the packet back to the TTD server, if active.
        !          1566:                 */
        !          1567:                if (kttd_active && pkt_size)
        !          1568:                        return 1;
        !          1569: #endif /* MACH_TTD */
        !          1570: 
        !          1571: 
        !          1572:        }
        !          1573:        return packets;
        !          1574: 
        !          1575: }
        !          1576: 
        !          1577: #ifdef MACH_KERNEL
        !          1578: #if    MACH_TTD
        !          1579: /*
        !          1580:  * Polling routines for the TTD debugger.
        !          1581:  */
        !          1582: int ns8390poll_receive(unit)
        !          1583:        int     unit;
        !          1584: {
        !          1585:        int s;
        !          1586:        int orig_cr;
        !          1587:        int orig_imr;
        !          1588:        int isr_status;
        !          1589:        int pkts;
        !          1590:        
        !          1591:        ttd_poll_loop = TRUE;
        !          1592: 
        !          1593:        
        !          1594:        /*
        !          1595:         * Should already in at splhigh.  Is this necessary? XXX
        !          1596:         */
        !          1597:        s = splhigh();
        !          1598: 
        !          1599: #if    0
        !          1600:        if (kttd_debug)
        !          1601:                printf("ns8390poll_receive: beginning polling loop\n");
        !          1602: #endif /* DEBUG_TTD */
        !          1603: 
        !          1604:        /*
        !          1605:         * Loop until packet arrives.
        !          1606:         */
        !          1607:        while(ttd_poll_loop) {
        !          1608: 
        !          1609:                /*
        !          1610:                 * Call intr routine
        !          1611:                 */
        !          1612: 
        !          1613:                ns8390intr(unit);
        !          1614:        }
        !          1615: 
        !          1616: #if    0
        !          1617:        if (kttd_debug)
        !          1618:                printf("ns8390poll_receive: got packet exiting loop\n");
        !          1619: #endif /* DEBUG_TTD */
        !          1620: 
        !          1621:        splx(s);
        !          1622: }
        !          1623: 
        !          1624: int ns8390transmit_ttd(unit, packet, len)
        !          1625:        int unit;
        !          1626:        char * packet;
        !          1627:        int len;
        !          1628: {
        !          1629:        ns8390_softc_t  *is = &ns8390_softc[unit];
        !          1630:        caddr_t         nic = is->nic;
        !          1631:        u_short         count = 0;      /* amount of data already copied */
        !          1632:        volatile char   *sram_write_pkt;
        !          1633:        int             board_id = is->board_id;
        !          1634:        caddr_t         hdwbase = ns8390info[unit]->address;
        !          1635:        int             s;
        !          1636:        int             orig_cr;
        !          1637:        int             orig_imr;
        !          1638:        int             isr_status;
        !          1639:        boolean_t       loop = TRUE;
        !          1640: 
        !          1641: #if    0
        !          1642:        dump_ipudpbootp("Beg of xmit",packet);
        !          1643: #endif
        !          1644: 
        !          1645:        s = splhigh();
        !          1646: 
        !          1647:        /* begining of physical address of transmition buffer */
        !          1648: 
        !          1649:        sram_write_pkt = is->sram + is->tpsr * 0x100; 
        !          1650: 
        !          1651:        count = len;
        !          1652:        if (board_id & IFWD_SLOT_16BIT) {
        !          1653:                en_16bit_access(hdwbase, board_id);
        !          1654:                bcopy16 (packet, sram_write_pkt,  count);
        !          1655:                dis_16bit_access (hdwbase, board_id);
        !          1656:        } else {
        !          1657:                bcopy (packet, sram_write_pkt,  count);
        !          1658:        }
        !          1659: 
        !          1660:        while (count < ETHERMIN+sizeof(struct ether_header)) {
        !          1661:                *(sram_write_pkt + count) = 0;
        !          1662:                count++;
        !          1663:        }
        !          1664:        outb(nic+ds_cmd, DSCM_NODMA|DSCM_START|DSCM_PG0);               /* select page 0 */
        !          1665:        outb(nic+ds0_tpsr, is->tpsr);           /* xmt page start at 0 of RAM */
        !          1666:        outb(nic+ds0_tbcr1, count >> 8);                /* upper byte of count */
        !          1667:        outb(nic+ds0_tbcr0, count & 0xFF);              /* lower byte of count */
        !          1668:        outb(nic+ds_cmd, DSCM_TRANS|DSCM_NODMA|DSCM_START);             /* start transmission */
        !          1669: 
        !          1670:        ns8390intr(unit);
        !          1671: 
        !          1672:        splx(s);
        !          1673: }
        !          1674: #endif /* MACH_TTD */
        !          1675: #endif /* MACH_KERNEL */
        !          1676: 
        !          1677: #ifdef MACH_KERNEL
        !          1678: #else  MACH_KERNEL
        !          1679: /*
        !          1680:  * Send a packet composed of an mbuf chain to the higher levels
        !          1681:  *
        !          1682:  */
        !          1683: ns8390send_packet_up(m, eh, is)
        !          1684: struct mbuf *m;
        !          1685: struct ether_header *eh;
        !          1686: ns8390_softc_t *is;
        !          1687: {
        !          1688:        register struct ifqueue *inq;
        !          1689:        spl_t                   opri;
        !          1690: 
        !          1691:        switch (eh->ether_type) {
        !          1692: #ifdef INET
        !          1693:        case ETHERTYPE_IP:
        !          1694:                schednetisr(NETISR_IP);
        !          1695:                inq = &ipintrq;
        !          1696:                break;
        !          1697:        case ETHERTYPE_ARP:
        !          1698:                arpinput(&is->ns8390_ac, m);
        !          1699:                return(TRUE);
        !          1700: #endif
        !          1701: #ifdef NS
        !          1702:        case ETHERTYPE_NS:
        !          1703:                schednetisr(NETISR_NS);
        !          1704:                inq = &nsintrq;
        !          1705:                break;
        !          1706: #endif
        !          1707:        default:
        !          1708:                return(FALSE);
        !          1709:        }
        !          1710:        opri = SPLNET();
        !          1711:        if (IF_QFULL(inq)) {
        !          1712:                IF_DROP(inq);
        !          1713:                splx(opri);
        !          1714:                return(FALSE);
        !          1715:        }
        !          1716:        IF_ENQUEUE(inq, m);
        !          1717:        splx(opri);
        !          1718:        return(TRUE);
        !          1719: }
        !          1720: #endif MACH_KERNEL
        !          1721: 
        !          1722: /*
        !          1723:  *  ns8390lost_frame:
        !          1724:  *  this routine called by ns8390read after memory for mbufs could not be
        !          1725:  *  allocated.  It sets the boundary pointers and registers to the next
        !          1726:  *  packet location.
        !          1727:  */
        !          1728: 
        !          1729: ns8390lost_frame(unit)
        !          1730: int unit;
        !          1731: {
        !          1732:        ns8390_softc_t *is = &ns8390_softc[unit];
        !          1733:        caddr_t        nic = is->nic;
        !          1734:        volatile char  *sram_nxtpkt_ptr;
        !          1735:        int            temp_cr;
        !          1736: 
        !          1737: 
        !          1738: 
        !          1739:        sram_nxtpkt_ptr = (volatile char *) (is->sram +
        !          1740:            (is->read_nxtpkt_ptr << 8));
        !          1741: 
        !          1742:        is->read_nxtpkt_ptr = *(sram_nxtpkt_ptr + 1);
        !          1743:        is->read_nxtpkt_ptr &= 0xFF;
        !          1744: 
        !          1745:        temp_cr = inb(nic+ds_cmd);
        !          1746:        outb(nic+ds_cmd, (temp_cr & 0x3f) | DSCM_PG0);
        !          1747: 
        !          1748:        /* update boundary register */
        !          1749:        if (is->read_nxtpkt_ptr == ns8390get_CURR(unit))
        !          1750:                if (is->read_nxtpkt_ptr == is->pstart)
        !          1751:                        outb(nic+ds0_bndy, is->pstop - 1);
        !          1752:                else
        !          1753:                        outb(nic+ds0_bndy, is->read_nxtpkt_ptr - 1);
        !          1754:        else
        !          1755:                outb(nic+ds0_bndy, is->read_nxtpkt_ptr);
        !          1756: 
        !          1757:        outb(nic+ds_cmd, temp_cr);
        !          1758: 
        !          1759:        return;
        !          1760: }
        !          1761: 
        !          1762: /*
        !          1763:  * ns8390get_CURR():
        !          1764:  *
        !          1765:  * Returns the value of the register CURR, which points to the next
        !          1766:  * available space for NIC to receive from network unto receive ring.
        !          1767:  *
        !          1768:  */
        !          1769: 
        !          1770: int
        !          1771: ns8390get_CURR(unit)
        !          1772: int unit;
        !          1773: {
        !          1774:        caddr_t nic = ns8390_softc[unit].nic;
        !          1775:        int     temp_cr;
        !          1776:        int     ret_val;
        !          1777:        spl_t   s;
        !          1778:   
        !          1779:        s = SPLNET();
        !          1780: 
        !          1781:        temp_cr = inb(nic+ds_cmd);                  /* get current CR value */
        !          1782:        outb(nic+ds_cmd, ((temp_cr & 0x3F) | DSCM_PG1)); /* select page 1 registers */
        !          1783:        ret_val = inb(nic+ds1_curr);                /* read CURR value */
        !          1784:        outb(nic+ds_cmd, temp_cr);
        !          1785:        splx(s);
        !          1786:        return (ret_val & 0xFF);
        !          1787: }
        !          1788: 
        !          1789: /*
        !          1790:  * ns8390xmt:
        !          1791:  *
        !          1792:  *     This routine fills in the appropriate registers and memory
        !          1793:  *     locations on the ns8390 board and starts the board off on
        !          1794:  *     the transmit.
        !          1795:  *
        !          1796:  * input       : board number of interest, and a pointer to the mbuf
        !          1797:  * output      : board memory and registers are set for xfer and attention
        !          1798:  *
        !          1799:  */
        !          1800: 
        !          1801: ns8390xmt(unit, m)
        !          1802: int    unit;
        !          1803: #ifdef MACH_KERNEL
        !          1804: io_req_t       m;
        !          1805: #else  MACH_KERNEL
        !          1806: struct mbuf    *m;
        !          1807: #endif MACH_KERNEL
        !          1808: {
        !          1809:        ns8390_softc_t          *is = &ns8390_softc[unit];
        !          1810:        caddr_t                 nic = is->nic;
        !          1811:        struct ether_header     *eh;
        !          1812:        int                     i;
        !          1813:        int                     opri;
        !          1814:        u_short                 count = 0;      /* amount of data already copied */
        !          1815:        volatile char           *sram_write_pkt;
        !          1816:        int                     board_id = is->board_id;
        !          1817:        vm_offset_t             hdwbase = ns8390info[unit]->address;
        !          1818:        spl_t     s;
        !          1819: 
        !          1820: #ifdef MACH_KERNEL
        !          1821: #else  MACH_KERNEL
        !          1822:        register struct mbuf    *tm_p;
        !          1823: #endif MACH_KERNEL
        !          1824:        /* begining of physical address of transmition buffer */
        !          1825: 
        !          1826:        sram_write_pkt = is->sram + is->tpsr * 0x100; 
        !          1827: 
        !          1828: #ifdef MACH_KERNEL
        !          1829:        count = m->io_count;
        !          1830:        if (board_id & IFWD_SLOT_16BIT) {
        !          1831:                s = splhi();
        !          1832:                en_16bit_access(hdwbase, board_id);
        !          1833:                bcopy16 (m->io_data, sram_write_pkt,  count);
        !          1834:                dis_16bit_access (hdwbase, board_id);
        !          1835:                splx(s);
        !          1836:        } else {
        !          1837:                bcopy (m->io_data, sram_write_pkt,  count);
        !          1838:        }
        !          1839: #else  MACH_KERNEL
        !          1840:        for(tm_p = m; tm_p != (struct mbuf *)0; tm_p = tm_p->m_next)  {
        !          1841:                if (count + tm_p->m_len > ETHERMTU + sizeof (struct ether_header))
        !          1842:                        break;
        !          1843:                if (tm_p->m_len == 0)
        !          1844:                        continue;
        !          1845:                if (board_id & IFWD_SLOT_16BIT) {
        !          1846:                        s = splhi();
        !          1847:                        en_16bit_access(hdwbase, board_id);
        !          1848:                        bcopy16 (mtod(tm_p, caddr_t),
        !          1849:                                 sram_write_pkt + count,
        !          1850:                                 tm_p->m_len);
        !          1851:                        dis_16bit_access (hdwbase, board_id);
        !          1852:                        splx(s);
        !          1853:                } else {
        !          1854:                        bcopy16 (mtod(tm_p, caddr_t),
        !          1855:                                 sram_write_pkt + count,
        !          1856:                                 tm_p->m_len);
        !          1857:                }
        !          1858:                count += tm_p->m_len;
        !          1859:        }
        !          1860: #ifdef IF_CNTRS
        !          1861:        ns_eout[log_2(count+4/*crc*/)]++;
        !          1862:        if (count < 128)  ns_lout[(count+4/*crc*/)>>3]++;
        !          1863: #endif IF_CNTRS
        !          1864: #endif MACH_KERNEL
        !          1865:        while (count < ETHERMIN+sizeof(struct ether_header)) {
        !          1866:                *(sram_write_pkt + count) = 0;
        !          1867:                count++;
        !          1868:        }
        !          1869: 
        !          1870:        /* select page 0 */
        !          1871:        outb(nic+ds_cmd, DSCM_NODMA|DSCM_START|DSCM_PG0);
        !          1872:        outb(nic+ds0_tpsr, is->tpsr);   /* xmt page start at 0 of RAM */
        !          1873:        outb(nic+ds0_tbcr1, count >> 8);        /* upper byte of count */
        !          1874:        outb(nic+ds0_tbcr0, count & 0xFF);      /* lower byte of count */
        !          1875:        /* start transmission */
        !          1876:        outb(nic+ds_cmd, DSCM_TRANS|DSCM_NODMA|DSCM_START);     
        !          1877: 
        !          1878: #ifdef MACH_KERNEL
        !          1879:        iodone(m);
        !          1880:        m=0;
        !          1881: #else  MACH_KERNEL
        !          1882:        /* If this is a broadcast packet, loop it back to rcv.  */
        !          1883:        eh = mtod( m, struct ether_header *);
        !          1884:        for (i=0; ((i < 6) && (eh->ether_dhost[i] == 0xff)); i++)  ;
        !          1885:        if (i == 6) {
        !          1886:                if (!ns8390send_packet_up(m, eh, is))
        !          1887:                        m_freem(m);
        !          1888:        } else
        !          1889:                m_freem(m);
        !          1890: #endif MACH_KERNEL
        !          1891:        return;
        !          1892: }
        !          1893: 
        !          1894: config_nic(unit)
        !          1895: int unit;
        !          1896: {
        !          1897:        ns8390_softc_t *is = &ns8390_softc[unit];
        !          1898:        caddr_t   nic = is->nic;
        !          1899:        int       i;
        !          1900:        int       temp;
        !          1901:        int       count = 0;
        !          1902:        spl_t     s;
        !          1903: 
        !          1904:        /* soft reset and page 0 */
        !          1905:        outb (nic+ds_cmd, DSCM_PG0|DSCM_NODMA|DSCM_STOP);             
        !          1906: 
        !          1907:        while ((!(inb (nic + ds0_isr) & DSIS_RESET)) && (count < 10000))
        !          1908:                count++;
        !          1909:        if (count == 10000) {
        !          1910:                printf("%s%d: config_nic(): would not reset.\n",
        !          1911:                        ns8390_softc[unit].card, unit);
        !          1912:        }
        !          1913: 
        !          1914:        /* fifo depth | not loopback */
        !          1915:        temp = ((is->fifo_depth & 0x0c) << 3) | DSDC_BMS;    
        !          1916: 
        !          1917:        /* word xfer select (16 bit cards ) */
        !          1918:        if (is->board_id & IFWD_SLOT_16BIT)
        !          1919:                temp |= DSDC_WTS;                       
        !          1920: 
        !          1921:        outb (nic+ds0_dcr, temp);
        !          1922:        outb (nic+ds0_tcr, 0);
        !          1923:        outb (nic+ds0_rcr, DSRC_MON);   /* receive configuration register */
        !          1924:        /* recieve ring starts 2k into RAM */
        !          1925:        outb (nic+ds0_pstart, is->pstart);      
        !          1926:        /* stop at last RAM buffer rcv location */
        !          1927:        outb (nic+ds0_pstop, is->pstop);        
        !          1928: 
        !          1929:        /* boundary pointer for page 0 */
        !          1930:        outb (nic+ds0_bndy, is->pstart);        
        !          1931:        s = SPLNET();
        !          1932: 
        !          1933:        /* maintain rst | sel page 1 */
        !          1934:        outb (nic+ds_cmd, DSCM_PG1|DSCM_NODMA|DSCM_STOP);       
        !          1935: 
        !          1936:        /* internal next packet pointer */
        !          1937:        is->read_nxtpkt_ptr = is->pstart + 1;   
        !          1938: 
        !          1939:        outb (nic+ds1_curr, is->read_nxtpkt_ptr);       /* Current page register */
        !          1940:        for(i=0; i<ETHER_ADDR_SIZE; i++)
        !          1941:                outb (nic+ds1_par0+i, is->address[i]);
        !          1942:        for(i=0; i<8; i++)
        !          1943:                outb (nic+ds1_mar0+i, 0);
        !          1944: 
        !          1945:        outb (nic+ds_cmd, DSCM_PG0|DSCM_STOP|DSCM_NODMA);
        !          1946:        splx(s);
        !          1947:        outb (nic+ds0_isr, 0xff);               /* clear all interrupt status bits */
        !          1948:        outb (nic+ds0_imr, imr_hold);   /* Enable interrupts */
        !          1949:        outb (nic+ds0_rbcr0, 0);        /* clear remote byte count */
        !          1950:        outb (nic+ds0_rbcr1, 0);
        !          1951: 
        !          1952:        /* start NIC | select page 0 */
        !          1953:        outb (nic+ds_cmd, DSCM_PG0|DSCM_START|DSCM_NODMA); 
        !          1954: 
        !          1955:        outb (nic+ds0_rcr, DSRC_AB);            /* receive configuration register */
        !          1956: 
        !          1957:        return TRUE;
        !          1958: }
        !          1959: 
        !          1960: /*
        !          1961:  * config_ns8390:
        !          1962:  *
        !          1963:  *     This routine does a standard config of a wd8003 family board, with
        !          1964:  *      the proper modifications to different boards within this family.
        !          1965:  *
        !          1966:  */
        !          1967: config_wd8003(unit)
        !          1968: int    unit;
        !          1969: {
        !          1970:        ns8390_softc_t *is = &ns8390_softc[unit];
        !          1971:        vm_offset_t   hdwbase = ns8390info[unit]->address;
        !          1972:        int       i;
        !          1973:        int       RAMsize;
        !          1974:        volatile char  *RAMbase;
        !          1975:        int       addr_temp;
        !          1976: 
        !          1977:        is->tpsr = 0;                   /* transmit page start hold */
        !          1978:        is->pstart = 0x06;              /* receive page start hold */
        !          1979:        is->read_nxtpkt_ptr = is->pstart + 1; /* internal next packet pointer */
        !          1980:        is->fifo_depth = 0x08;          /* NIC fifo threshold */
        !          1981:        switch (is->board_id & IFWD_RAM_SIZE_MASK) {
        !          1982:              case IFWD_RAM_SIZE_8K:  
        !          1983:                RAMsize =  0x2000;      break;
        !          1984:              case IFWD_RAM_SIZE_16K: 
        !          1985:                RAMsize =  0x4000;      break;
        !          1986:              case IFWD_RAM_SIZE_32K: 
        !          1987:                RAMsize =  0x8000;      break;
        !          1988:              case IFWD_RAM_SIZE_64K: 
        !          1989:                RAMsize = 0x10000;      break;
        !          1990:              default:           
        !          1991:                RAMsize =  0x2000;      break;
        !          1992:        }
        !          1993:        is->pstop = (((int)RAMsize >> 8) & 0x0ff);      /* rcv page stop hold */
        !          1994:        RAMbase = (volatile char *)ns8390info[unit]->phys_address;
        !          1995:        addr_temp = ((int)(RAMbase) >> 13) & 0x3f; /* convert to be written to MSR */
        !          1996:        outb(hdwbase+IFWD_MSR, addr_temp | IFWD_MENB); /* initialize MSR */
        !          1997:        /* enable 16 bit access from lan controller */
        !          1998:        if (is->board_id & IFWD_SLOT_16BIT) {
        !          1999:                if (is->board_id & IFWD_INTERFACE_CHIP) {
        !          2000:                        outb(hdwbase+IFWD_REG_5,
        !          2001:                             (inb(hdwbase + IFWD_REG_5) & IFWD_REG5_MEM_MASK) |
        !          2002:                             IFWD_LAN16ENB);
        !          2003:                } else {
        !          2004:                        outb(hdwbase+IFWD_REG_5, (IFWD_LAN16ENB | IFWD_LA19));
        !          2005:                }
        !          2006:        }
        !          2007:        /*
        !          2008:          outb(hdwbase+LAAR, LAN16ENB | LA19| MEM16ENB | SOFTINT);
        !          2009:          */
        !          2010:        
        !          2011:        return TRUE;
        !          2012: }
        !          2013: 
        !          2014: /*
        !          2015:  * config_ns8390:
        !          2016:  *
        !          2017:  *     This routine does a standard config of a 3 com etherlink II board.
        !          2018:  *
        !          2019:  */
        !          2020: int
        !          2021: config_3c503(unit)
        !          2022: int    unit;
        !          2023: {
        !          2024:        ns8390_softc_t  *is = &ns8390_softc[unit];
        !          2025:        struct bus_device       *dev = ns8390info[unit];
        !          2026:        vm_offset_t             hdwbase = dev->address;
        !          2027:        int             RAMsize = dev->am;
        !          2028:        int             i;
        !          2029: 
        !          2030:        is->tpsr =   0x20;              /* transmit page start hold */
        !          2031:        is->sram = (char *)phystokv(dev->phys_address) - is->tpsr * 0x100;
        !          2032:                                        /* When NIC says page 20, this means go to
        !          2033:                                           the beginning of the sram range */
        !          2034:        is->pstart = 0x26;              /* receive page start hold */
        !          2035:        is->read_nxtpkt_ptr = is->pstart + 1; /* internal next packet pointer */
        !          2036:        is->fifo_depth = 0x08;          /* NIC fifo threshold */
        !          2037:        is->pstop = is->tpsr + ((RAMsize >> 8) & 0x0ff);      /* rcv page stop hold */
        !          2038: 
        !          2039:        outb(hdwbase+CTLR, CTLR_RST|CTLR_THIN);
        !          2040:        outb(hdwbase+CTLR, CTLR_THIN);
        !          2041:        outb(hdwbase+CTLR, CTLR_STA_ADDR|CTLR_THIN);
        !          2042:        for (i = 0; i < 6; i++)
        !          2043:                is->address[i] = inb(hdwbase+i);
        !          2044:        outb(hdwbase+CTLR, elii_bnc[is->board_id]?CTLR_THIN:CTLR_THICK);
        !          2045:        outb(hdwbase+PSTR, is->pstart);
        !          2046:        outb(hdwbase+PSPR, is->pstop);
        !          2047:        outb(hdwbase+IDCFR, IDCFR_IRQ2 << (elii_irq[is->board_id] - 2));
        !          2048:        outb(hdwbase+GACFR, GACFR_TCM|GACFR_8K);
        !          2049:        /* BCFR & PCRFR ro */
        !          2050:        /* STREG ro & dma */
        !          2051:        outb(hdwbase+DQTR, 0);
        !          2052:        outb(hdwbase+DAMSB, 0);
        !          2053:        outb(hdwbase+DALSB, 0);
        !          2054:        outb(hdwbase+VPTR2, 0);
        !          2055:        outb(hdwbase+VPTR1, 0);
        !          2056:        outb(hdwbase+VPTR0, 0);
        !          2057:        outb(hdwbase+RFMSB, 0);
        !          2058:        outb(hdwbase+RFLSB, 0);
        !          2059:        return TRUE;
        !          2060: }
        !          2061: 
        !          2062: /*
        !          2063:  * ns8390intoff:
        !          2064:  *
        !          2065:  *     This function turns interrupts off for the ns8390 board indicated.
        !          2066:  *
        !          2067:  */
        !          2068: void
        !          2069: ns8390intoff(unit)
        !          2070: int unit;
        !          2071: {
        !          2072:        caddr_t nic = ns8390_softc[unit].nic;
        !          2073:        int temp_cr = inb(nic+ds_cmd);  /* get current CR value */
        !          2074: 
        !          2075:        outb(nic+ds_cmd,((temp_cr & 0x3F)|DSCM_PG0|DSCM_STOP));
        !          2076:        outb(nic+ds0_imr, 0);                   /* Interrupt Mask Register  */
        !          2077:        outb(nic+ds_cmd, temp_cr|DSCM_STOP);
        !          2078: 
        !          2079: }
        !          2080: 
        !          2081: 
        !          2082: /*
        !          2083:  *   wd80xxget_board_id:
        !          2084:  *
        !          2085:  *   determine which board is being used.
        !          2086:  *   Currently supports:
        !          2087:  *    wd8003E (tested)
        !          2088:  *    wd8003EBT
        !          2089:  *    wd8003EP (tested)
        !          2090:  *    wd8013EP (tested)
        !          2091:  *
        !          2092:  */
        !          2093: wd80xxget_board_id(dev)
        !          2094: struct bus_device      *dev;
        !          2095: {
        !          2096:        vm_offset_t    hdwbase = dev->address;
        !          2097:        long           unit = dev->unit;
        !          2098:        long           board_id = 0;
        !          2099:        int            reg_temp;
        !          2100:        int            rev_num;                 /* revision number */
        !          2101:        int            ram_flag;
        !          2102:        int            intr_temp;
        !          2103:        int            i;
        !          2104:        boolean_t      register_aliasing;
        !          2105: 
        !          2106:        rev_num = (inb(hdwbase + IFWD_BOARD_ID) & IFWD_BOARD_REV_MASK) >> 1;
        !          2107:        printf("%s%d: ", ns8390_softc[unit].card, unit);
        !          2108:        
        !          2109:        if (rev_num == 0) {
        !          2110:                printf("rev 0x00\n");
        !          2111:                /* It must be 8000 board */
        !          2112:                return 0;
        !          2113:        }
        !          2114:        
        !          2115:        /* Check if register aliasing is true, that is reading from register
        !          2116:           offsets 0-7 will return the contents of register offsets 8-f */
        !          2117:        
        !          2118:        register_aliasing = TRUE;
        !          2119:        for (i = 1; i < 5; i++) {
        !          2120:                if (inb(hdwbase + IFWD_REG_0 + i) !=
        !          2121:                    inb(hdwbase + IFWD_LAR_0 + i))
        !          2122:                    register_aliasing = FALSE;
        !          2123:        }
        !          2124:        if (inb(hdwbase + IFWD_REG_7) != inb(hdwbase + IFWD_CHKSUM))
        !          2125:            register_aliasing = FALSE;
        !          2126:        
        !          2127:        
        !          2128:        if (register_aliasing == FALSE) {
        !          2129:                /* Check if board has interface chip */
        !          2130:                
        !          2131:                reg_temp = inb(hdwbase + IFWD_REG_7);   /* save old */
        !          2132:                outb(hdwbase + IFWD_REG_7, 0x35);       /* write value */
        !          2133:                inb(hdwbase + IFWD_REG_0);              /* dummy read */
        !          2134:                if ((inb(hdwbase + IFWD_REG_7) & 0xff) == 0x35) {
        !          2135:                        outb(hdwbase + IFWD_REG_7, 0x3a);/* Try another value*/
        !          2136:                        inb(hdwbase + IFWD_REG_0);      /* dummy read */
        !          2137:                        if ((inb(hdwbase + IFWD_REG_7) & 0xff) == 0x3a) {
        !          2138:                                board_id |= IFWD_INTERFACE_CHIP;
        !          2139:                                outb(hdwbase + IFWD_REG_7, reg_temp);
        !          2140:                                /* restore old value */
        !          2141:                        }
        !          2142:                }
        !          2143:                
        !          2144:                /* Check if board is 16 bit by testing if bit zero in
        !          2145:                   register 1 is unchangeable by software. If so then
        !          2146:                   card has 16 bit capability */
        !          2147:                reg_temp = inb(hdwbase + IFWD_REG_1);
        !          2148:                outb(hdwbase + IFWD_REG_1, reg_temp ^ IFWD_16BIT);
        !          2149:                inb(hdwbase + IFWD_REG_0);                   /* dummy read */
        !          2150:                if ((inb(hdwbase + IFWD_REG_1) & IFWD_16BIT) ==
        !          2151:                    (reg_temp & IFWD_16BIT)) {        /* Is bit unchanged */
        !          2152:                        board_id |= IFWD_BOARD_16BIT; /* Yes == 16 bit */
        !          2153:                        reg_temp &= 0xfe;             /* For 16 bit board
        !          2154:                                                         always reset bit 0 */
        !          2155:                }
        !          2156:                outb(hdwbase + IFWD_REG_1, reg_temp);    /* write value back */
        !          2157:                
        !          2158:                /* Test if 16 bit card is in 16 bit slot by reading bit zero in
        !          2159:                   register 1. */
        !          2160:                if (board_id & IFWD_BOARD_16BIT) {
        !          2161:                        if (inb(hdwbase + IFWD_REG_1) & IFWD_16BIT) {
        !          2162:                                board_id |= IFWD_SLOT_16BIT;
        !          2163:                        }
        !          2164:                }
        !          2165:        }
        !          2166:        
        !          2167:        /* Get media type */
        !          2168:        
        !          2169:        if (inb(hdwbase + IFWD_BOARD_ID) & IFWD_MEDIA_TYPE) {
        !          2170:                board_id |= IFWD_ETHERNET_MEDIA;
        !          2171:        } else if (rev_num == 1) {
        !          2172:                board_id |= IFWD_STARLAN_MEDIA;
        !          2173:        } else {
        !          2174:                board_id |= IFWD_TWISTED_PAIR_MEDIA;
        !          2175:        }
        !          2176: 
        !          2177:        if (rev_num == 2) {
        !          2178:                if (inb(hdwbase + IFWD_BOARD_ID) & IFWD_SOFT_CONFIG) {
        !          2179:                        if ((board_id & IFWD_STATIC_ID_MASK) == WD8003EB ||
        !          2180:                            (board_id & IFWD_STATIC_ID_MASK) == WD8003W) {
        !          2181:                                board_id |= IFWD_ALTERNATE_IRQ_BIT;
        !          2182:                        }
        !          2183:                }
        !          2184:                /* Check for memory size */
        !          2185:                
        !          2186:                ram_flag = inb(hdwbase + IFWD_BOARD_ID) & IFWD_MEMSIZE;
        !          2187:            
        !          2188:                switch (board_id & IFWD_STATIC_ID_MASK) {
        !          2189:                      case WD8003E: /* same as WD8003EBT */
        !          2190:                      case WD8003S: /* same as WD8003SH */
        !          2191:                      case WD8003WT:
        !          2192:                      case WD8003W:
        !          2193:                      case WD8003EB: /* same as WD8003EP */
        !          2194:                        if (ram_flag)
        !          2195:                            board_id |= IFWD_RAM_SIZE_32K;
        !          2196:                        else
        !          2197:                            board_id |= IFWD_RAM_SIZE_8K;
        !          2198:                        break;
        !          2199:                      case WD8003ETA:
        !          2200:                      case WD8003STA:
        !          2201:                      case WD8003EA:
        !          2202:                      case WD8003SHA:
        !          2203:                      case WD8003WA:
        !          2204:                        board_id |= IFWD_RAM_SIZE_16K;
        !          2205:                        break;
        !          2206:                      case WD8013EBT:
        !          2207:                        if (board_id & IFWD_SLOT_16BIT) {
        !          2208:                                if (ram_flag)
        !          2209:                                    board_id |= IFWD_RAM_SIZE_64K;
        !          2210:                                else
        !          2211:                                    board_id |= IFWD_RAM_SIZE_16K;
        !          2212:                        } else {
        !          2213:                                if (ram_flag)
        !          2214:                                    board_id |= IFWD_RAM_SIZE_32K;
        !          2215:                                else
        !          2216:                                    board_id |= IFWD_RAM_SIZE_8K;
        !          2217:                        }
        !          2218:                        break;
        !          2219:                      default:
        !          2220:                        board_id |= IFWD_RAM_SIZE_UNKNOWN;
        !          2221:                        break;
        !          2222:                }
        !          2223:        } else if (rev_num >= 3) {
        !          2224:                board_id &= (long) ~IFWD_MEDIA_MASK;   /* remove media info */
        !          2225:                board_id |= IFWD_INTERFACE_584_CHIP;
        !          2226:                board_id |= wd80xxget_eeprom_info(hdwbase, board_id);
        !          2227:        } else {
        !          2228:                /* Check for memory size */
        !          2229:                if (board_id & IFWD_BOARD_16BIT) {
        !          2230:                        if (board_id & IFWD_SLOT_16BIT)
        !          2231:                            board_id |= IFWD_RAM_SIZE_16K;
        !          2232:                        else
        !          2233:                            board_id |= IFWD_RAM_SIZE_8K;
        !          2234:                } else if (board_id & IFWD_MICROCHANNEL)
        !          2235:                    board_id |= IFWD_RAM_SIZE_16K;
        !          2236:                else if (board_id & IFWD_INTERFACE_CHIP) {
        !          2237:                        if (inb(hdwbase + IFWD_REG_1) & IFWD_MEMSIZE)
        !          2238:                            board_id |= IFWD_RAM_SIZE_32K;
        !          2239:                        else
        !          2240:                            board_id |= IFWD_RAM_SIZE_8K;
        !          2241:                } else
        !          2242:                    board_id |= IFWD_RAM_SIZE_UNKNOWN;
        !          2243:                
        !          2244:                /* No support for 690 chip yet. It should be checked here */
        !          2245:        }
        !          2246:        
        !          2247:        switch (board_id & IFWD_STATIC_ID_MASK) {
        !          2248:              case WD8003E: printf("WD8003E or WD8003EBT"); break;
        !          2249:              case WD8003S: printf("WD8003S or WD8003SH"); break;
        !          2250:              case WD8003WT: printf("WD8003WT"); break;
        !          2251:              case WD8003W: printf("WD8003W"); break;
        !          2252:              case WD8003EB:
        !          2253:                if (board_id & IFWD_INTERFACE_584_CHIP)
        !          2254:                    printf("WD8003EP");
        !          2255:                else
        !          2256:                    printf("WD8003EB");
        !          2257:                break;
        !          2258:              case WD8003EW: printf("WD8003EW"); break;
        !          2259:              case WD8003ETA: printf("WD8003ETA"); break;
        !          2260:              case WD8003STA: printf("WD8003STA"); break;
        !          2261:              case WD8003EA: printf("WD8003EA"); break;
        !          2262:              case WD8003SHA: printf("WD8003SHA"); break;
        !          2263:              case WD8003WA: printf("WD8003WA"); break;
        !          2264:              case WD8013EBT: printf("WD8013EBT"); break;
        !          2265:              case WD8013EB:
        !          2266:                if (board_id & IFWD_INTERFACE_584_CHIP)
        !          2267:                    printf("WD8013EP");
        !          2268:                else
        !          2269:                    printf("WD8013EB");
        !          2270:                break;
        !          2271:              case WD8013W: printf("WD8013W"); break;
        !          2272:              case WD8013EW: printf("WD8013EW"); break;
        !          2273:              default: printf("unknown"); break;
        !          2274:        }
        !          2275:        printf(" rev 0x%02x", rev_num);
        !          2276:        switch(board_id & IFWD_RAM_SIZE_RES_7) {
        !          2277:              case IFWD_RAM_SIZE_UNKNOWN:
        !          2278:                break;
        !          2279:              case IFWD_RAM_SIZE_8K:
        !          2280:                printf(" 8 kB ram");
        !          2281:                break;
        !          2282:              case IFWD_RAM_SIZE_16K:
        !          2283:                printf(" 16 kB ram");
        !          2284:                break;
        !          2285:              case IFWD_RAM_SIZE_32K:
        !          2286:                printf(" 32 kB ram");
        !          2287:                break;
        !          2288:              case IFWD_RAM_SIZE_64K:
        !          2289:                printf(" 64 kB ram");
        !          2290:                break;
        !          2291:              default:
        !          2292:                printf("wd: Internal error ram size value invalid %d\n",
        !          2293:                       (board_id & IFWD_RAM_SIZE_RES_7)>>16);
        !          2294:        }
        !          2295:        
        !          2296:        if (board_id & IFWD_BOARD_16BIT) {
        !          2297:                if (board_id & IFWD_SLOT_16BIT) {
        !          2298:                        printf(", in 16 bit slot");
        !          2299:                } else {
        !          2300:                        printf(", 16 bit board in 8 bit slot");
        !          2301:                }
        !          2302:        }
        !          2303:        if (board_id & IFWD_INTERFACE_CHIP) {
        !          2304:                if (board_id & IFWD_INTERFACE_584_CHIP) {
        !          2305:                        printf(", 584 chip");
        !          2306:                } else {
        !          2307:                        printf(", 583 chip");
        !          2308:                }
        !          2309:        }
        !          2310:        if ((board_id & IFWD_INTERFACE_CHIP) == IFWD_INTERFACE_CHIP) {
        !          2311:                /* program the WD83C583 EEPROM registers */
        !          2312:                int irr_temp, icr_temp;
        !          2313:                
        !          2314:                icr_temp = inb(hdwbase + IFWD_ICR);
        !          2315:                irr_temp = inb(hdwbase + IFWD_IRR);
        !          2316:                
        !          2317:                irr_temp &= ~(IFWD_IR0 | IFWD_IR1);
        !          2318:                irr_temp |= IFWD_IEN;
        !          2319:                
        !          2320:                icr_temp &= IFWD_WTS;
        !          2321:                
        !          2322:                if (!(board_id & IFWD_INTERFACE_584_CHIP)) {
        !          2323:                        icr_temp |= IFWD_DMAE | IFWD_IOPE;
        !          2324:                        if (ram_flag)
        !          2325:                            icr_temp |= IFWD_MSZ;
        !          2326:                }
        !          2327:                
        !          2328:                if (board_id & IFWD_INTERFACE_584_CHIP) {
        !          2329:                        switch(ns8390info[unit]->sysdep1) {
        !          2330:                              case 10:
        !          2331:                                icr_temp |= IFWD_DMAE;
        !          2332:                                break;
        !          2333:                              case 2:
        !          2334:                              case 9: /* Same as 2 */
        !          2335:                                break;
        !          2336:                              case 11:
        !          2337:                                icr_temp |= IFWD_DMAE;
        !          2338:                                /*FALLTHROUGH*/
        !          2339:                              case 3:
        !          2340:                                irr_temp |= IFWD_IR0;
        !          2341:                                break;
        !          2342:                              case 15:
        !          2343:                                icr_temp |= IFWD_DMAE;
        !          2344:                                /*FALLTHROUGH*/
        !          2345:                              case 5:
        !          2346:                                irr_temp |= IFWD_IR1;
        !          2347:                                break;
        !          2348:                              case 4:
        !          2349:                                icr_temp |= IFWD_DMAE;
        !          2350:                                /*FALLTHROUGH*/
        !          2351:                              case 7:
        !          2352:                                irr_temp |= IFWD_IR0 | IFWD_IR1;
        !          2353:                                break;
        !          2354:                              default:
        !          2355:                                printf("%s%d: wd80xx_get_board_id(): Could not set Interrupt Request Register according to pic(%d).\n",
        !          2356:                                       ns8390_softc[unit].card, unit,
        !          2357:                                       ns8390info[unit]->sysdep1);
        !          2358:                                break;
        !          2359:                        }
        !          2360:                } else {
        !          2361:                        switch(ns8390info[unit]->sysdep1) {
        !          2362:                                /* attempt to set interrupt according to assigned pic */
        !          2363:                              case 2:
        !          2364:                              case 9: /* Same as 2 */
        !          2365:                                break;
        !          2366:                              case 3:
        !          2367:                                irr_temp |= IFWD_IR0;
        !          2368:                                break;
        !          2369:                              case 4:
        !          2370:                                irr_temp |= IFWD_IR1;
        !          2371:                                break;
        !          2372:                              case 5:
        !          2373:                                irr_temp |= IFWD_IR1 | IFWD_AINT;
        !          2374:                                break;
        !          2375:                              case 7: 
        !          2376:                                irr_temp |= IFWD_IR0 | IFWD_IR1;
        !          2377:                                break;
        !          2378:                              default: 
        !          2379:                                printf("%s%d: wd80xx_get_board_id(): Could not set Interrupt Request Register according to pic(%d).\n",
        !          2380:                                       ns8390_softc[unit].card, unit,
        !          2381:                                       ns8390info[unit]->sysdep1);
        !          2382:                        }
        !          2383:                }
        !          2384:                outb(hdwbase + IFWD_IRR, irr_temp);
        !          2385:                outb(hdwbase + IFWD_ICR, icr_temp);
        !          2386:        }
        !          2387:        printf("\n");
        !          2388:        return (board_id);
        !          2389: }
        !          2390: 
        !          2391: wd80xxget_eeprom_info(hdwbase, board_id)
        !          2392:      caddr_t   hdwbase;
        !          2393:      long      board_id;
        !          2394: {
        !          2395:   unsigned long new_bits = 0;
        !          2396:   int          reg_temp;
        !          2397:   
        !          2398:   outb(hdwbase + IFWD_REG_1,
        !          2399:        ((inb(hdwbase + IFWD_REG_1) & IFWD_ICR_MASK) | IFWD_OTHER_BIT));
        !          2400:   outb(hdwbase + IFWD_REG_3,
        !          2401:        ((inb(hdwbase + IFWD_REG_3) & IFWD_EAR_MASK) | IFWD_ENGR_PAGE));
        !          2402:   outb(hdwbase + IFWD_REG_1,
        !          2403:        ((inb(hdwbase + IFWD_REG_1) & IFWD_ICR_MASK) |
        !          2404:        (IFWD_RLA | IFWD_OTHER_BIT)));
        !          2405:   while (inb(hdwbase + IFWD_REG_1) & IFWD_RECALL_DONE_MASK)
        !          2406:       ;
        !          2407:   
        !          2408:   reg_temp = inb(hdwbase + IFWD_EEPROM_1);
        !          2409:   switch (reg_temp & IFWD_EEPROM_BUS_TYPE_MASK) {
        !          2410:        case IFWD_EEPROM_BUS_TYPE_AT:
        !          2411:          if (wd_debug & 1) printf("wd: AT bus, ");
        !          2412:          break;
        !          2413:        case IFWD_EEPROM_BUS_TYPE_MCA:
        !          2414:          if (wd_debug & 1) printf("wd: MICROCHANNEL, ");
        !          2415:          new_bits |= IFWD_MICROCHANNEL;
        !          2416:          break;
        !          2417:        default:
        !          2418:          break;
        !          2419:   }
        !          2420:   switch (reg_temp & IFWD_EEPROM_BUS_SIZE_MASK) {
        !          2421:        case IFWD_EEPROM_BUS_SIZE_8BIT:
        !          2422:          if (wd_debug & 1) printf("8 bit bus size, ");
        !          2423:          break;
        !          2424:        case IFWD_EEPROM_BUS_SIZE_16BIT:
        !          2425:          if (wd_debug & 1) printf("16 bit bus size ");
        !          2426:          new_bits |= IFWD_BOARD_16BIT;
        !          2427:          if (inb(hdwbase + IFWD_REG_1) & IFWD_16BIT) {
        !          2428:                  new_bits |= IFWD_SLOT_16BIT;
        !          2429:                  if (wd_debug & 1)
        !          2430:                      printf("in 16 bit slot, ");
        !          2431:          } else {
        !          2432:                  if (wd_debug & 1)
        !          2433:                      printf("in 8 bit slot (why?), ");
        !          2434:          }
        !          2435:          break;
        !          2436:        default:
        !          2437:          if (wd_debug & 1) printf("bus size other than 8 or 16 bit, ");
        !          2438:          break;
        !          2439:   }
        !          2440:   reg_temp = inb(hdwbase + IFWD_EEPROM_0);
        !          2441:   switch (reg_temp & IFWD_EEPROM_MEDIA_MASK) {
        !          2442:        case IFWD_STARLAN_TYPE:
        !          2443:          if (wd_debug & 1) printf("Starlan media, ");
        !          2444:          new_bits |= IFWD_STARLAN_MEDIA;
        !          2445:          break;
        !          2446:        case IFWD_TP_TYPE:
        !          2447:          if (wd_debug & 1) printf("Twisted pair media, ");
        !          2448:          new_bits |= IFWD_TWISTED_PAIR_MEDIA;
        !          2449:          break;
        !          2450:        case IFWD_EW_TYPE:
        !          2451:          if (wd_debug & 1) printf("Ethernet and twisted pair media, ");
        !          2452:          new_bits |= IFWD_EW_MEDIA;
        !          2453:          break;
        !          2454:        case IFWD_ETHERNET_TYPE: /*FALLTHROUGH*/
        !          2455:        default:
        !          2456:          if (wd_debug & 1) printf("ethernet media, ");
        !          2457:          new_bits |= IFWD_ETHERNET_MEDIA;
        !          2458:          break;
        !          2459:   }
        !          2460:   switch (reg_temp & IFWD_EEPROM_IRQ_MASK) {
        !          2461:        case IFWD_ALTERNATE_IRQ_1:
        !          2462:          if (wd_debug & 1) printf("Alternate irq 1\n");
        !          2463:          new_bits |= IFWD_ALTERNATE_IRQ_BIT;
        !          2464:          break;
        !          2465:        default:
        !          2466:          if (wd_debug & 1) printf("\n");
        !          2467:          break;
        !          2468:   }
        !          2469:   switch (reg_temp & IFWD_EEPROM_RAM_SIZE_MASK) {
        !          2470:        case IFWD_EEPROM_RAM_SIZE_8K:
        !          2471:          new_bits |= IFWD_RAM_SIZE_8K;
        !          2472:          break;
        !          2473:        case IFWD_EEPROM_RAM_SIZE_16K:
        !          2474:          if ((new_bits & IFWD_BOARD_16BIT) && (new_bits & IFWD_SLOT_16BIT))
        !          2475:              new_bits |= IFWD_RAM_SIZE_16K;
        !          2476:          else
        !          2477:              new_bits |= IFWD_RAM_SIZE_8K;
        !          2478:          break;
        !          2479:        case IFWD_EEPROM_RAM_SIZE_32K:
        !          2480:          new_bits |= IFWD_RAM_SIZE_32K;
        !          2481:          break;
        !          2482:        case IFWD_EEPROM_RAM_SIZE_64K:
        !          2483:          if ((new_bits & IFWD_BOARD_16BIT) && (new_bits & IFWD_SLOT_16BIT))
        !          2484:              new_bits |= IFWD_RAM_SIZE_64K;
        !          2485:          else
        !          2486:              new_bits |= IFWD_RAM_SIZE_32K;
        !          2487:          break;
        !          2488:        default:
        !          2489:          new_bits |= IFWD_RAM_SIZE_UNKNOWN;
        !          2490:          break;
        !          2491:   }
        !          2492:   outb(hdwbase + IFWD_REG_1,
        !          2493:        ((inb(hdwbase + IFWD_REG_1) & IFWD_ICR_MASK) | IFWD_OTHER_BIT));
        !          2494:   outb(hdwbase + IFWD_REG_3,
        !          2495:        ((inb(hdwbase + IFWD_REG_3) & IFWD_EAR_MASK) | IFWD_EA6));
        !          2496:   outb(hdwbase + IFWD_REG_1,
        !          2497:        ((inb(hdwbase + IFWD_REG_1) & IFWD_ICR_MASK) | IFWD_RLA));
        !          2498:   return (new_bits);
        !          2499: }
        !          2500: 
        !          2501: wdpr(unit)
        !          2502: {
        !          2503:        caddr_t nic = ns8390_softc[unit].nic;
        !          2504:        spl_t   s;
        !          2505:        int     temp_cr;
        !          2506: 
        !          2507:        s = SPLNET();
        !          2508:        temp_cr = inb(nic+ds_cmd);      /* get current CR value */
        !          2509: 
        !          2510:        printf("CR %x, BNDRY %x, TSR %x, NCR %x, FIFO %x, ISR %x, RSR %x\n",
        !          2511:                inb(nic+0x0), inb(nic+0x3), inb(nic+0x4), inb(nic+0x5),
        !          2512:                inb(nic+0x6), inb(nic+0x7), inb(nic+0xc));
        !          2513:        printf("CLD %x:%x, CRD %x:%x, FR %x, CRC %x, Miss %x\n",
        !          2514:                inb(nic+0x1), inb(nic+0x2),
        !          2515:                inb(nic+0x8), inb(nic+0x9),
        !          2516:                inb(nic+0xd), inb(nic+0xe), inb(nic+0xf));
        !          2517: 
        !          2518:        
        !          2519:        outb(nic, (temp_cr&0x3f)|DSCM_PG1);             /* page 1 CR value */
        !          2520:        printf("PHYS %x:%x:%x:%x:%x CUR %x\n",
        !          2521:                inb(nic+0x1), inb(nic+0x2), inb(nic+0x3),
        !          2522:                inb(nic+0x4), inb(nic+0x5), inb(nic+0x6),
        !          2523:                inb(nic+0x7));
        !          2524:        printf("MAR %x:%x:%x:%x:%x:%x:%x:%x\n",
        !          2525:                inb(nic+0x8), inb(nic+0x9), inb(nic+0xa), inb(nic+0xb),
        !          2526:                inb(nic+0xc), inb(nic+0xd), inb(nic+0xe), inb(nic+0xf));
        !          2527:        outb(nic, temp_cr);                     /* restore current CR value */
        !          2528:        splx(s);
        !          2529: }
        !          2530: 
        !          2531: 
        !          2532: /*
        !          2533:   This sets bit 7 (0 justified) of register offset 0x05. It will enable
        !          2534:   the host to access shared RAM 16 bits at a time. It will also maintain
        !          2535:   the LAN16BIT bit high in addition, this routine maintains address bit 19
        !          2536:   (previous cards assumed this bit high...we must do it manually)
        !          2537:   
        !          2538:   note 1: this is a write only register
        !          2539:   note 2: this routine should be called only after interrupts are disabled
        !          2540:     and they should remain disabled until after the routine 'dis_16bit_access'
        !          2541:     is called
        !          2542: */
        !          2543: 
        !          2544: en_16bit_access (hdwbase, board_id)
        !          2545:        caddr_t hdwbase;
        !          2546:        long    board_id;
        !          2547: {
        !          2548:        if (board_id & IFWD_INTERFACE_CHIP)
        !          2549:            outb(hdwbase+IFWD_REG_5,
        !          2550:                 (inb(hdwbase+IFWD_REG_5) & IFWD_REG5_MEM_MASK)
        !          2551:                 | IFWD_MEM16ENB | IFWD_LAN16ENB);
        !          2552:         else
        !          2553:             outb(hdwbase+IFWD_REG_5, (IFWD_MEM16ENB | IFWD_LAN16ENB |
        !          2554:                                      IFWD_LA19));
        !          2555: }
        !          2556: 
        !          2557: /*
        !          2558:   This resets bit 7 (0 justified) of register offset 0x05. It will disable
        !          2559:   the host from accessing shared RAM 16 bits at a time. It will maintain the
        !          2560:   LAN16BIT bit high in addition, this routine maintains address bit 19
        !          2561:   (previous cards assumed this bit high...we must do it manually)
        !          2562: 
        !          2563:   note: this is a write only register
        !          2564: */
        !          2565: 
        !          2566: dis_16bit_access (hdwbase, board_id)
        !          2567:        caddr_t hdwbase;
        !          2568:        long board_id;
        !          2569: {
        !          2570:        if (board_id & IFWD_INTERFACE_CHIP)
        !          2571:            outb(hdwbase+IFWD_REG_5,
        !          2572:                 ((inb(hdwbase+IFWD_REG_5) & IFWD_REG5_MEM_MASK) |
        !          2573:                  IFWD_LAN16ENB));
        !          2574:        else
        !          2575:            outb(hdwbase+IFWD_REG_5, (IFWD_LAN16ENB | IFWD_LA19));
        !          2576: }
        !          2577: 
        !          2578: #endif

unix.superglobalmegacorp.com

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