Annotation of researchv9/sys/boot/stand/if_ie.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)if_ie.c 1.1 86/02/03 Copyr 1985 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: /* 
                     10:  * Parameters controlling TIMEBOMB action: times out if chip hangs.
                     11:  *
                     12:  */
                     13: #define        TIMEBOMB        1000000         /* One million times around is all... */
                     14: #define        TIMEOUT         -1              /* if (function()) return (TIMEOUT); */
                     15: #define        OK              0               /* Traditional OK value */
                     16: 
                     17: 
                     18: /*
                     19:  * Sun Intel Ethernet Controller interface
                     20:  */
                     21: #include "saio.h"
                     22: #include "param.h"
                     23: #include "../h/socket.h"
                     24: #include "../sunif/if_iereg.h"
                     25: #include "../sunif/if_mie.h"
                     26: #include "../sunif/if_obie.h"
                     27: #include "../mon/idprom.h"
                     28: #include "../mon/cpu.map.h"
                     29: 
                     30: int    iexmit(), iepoll(), iereset();
                     31: 
                     32: unsigned long iestd[] = { 0x88000, 0x8C000 };
                     33: #define NSTD 2
                     34: 
                     35: struct saif ieif = {
                     36:        iexmit,
                     37:        iepoll,
                     38:        iereset,
                     39: };
                     40: 
                     41: #define        IEVVSIZ         1024            /* # of pages in page map */
                     42: #define IEPHYMEMSIZ    (16*1024)
                     43: #define IEVIRMEMSIZ    (16*1024)
                     44: #define IEPAGSIZ       1024
                     45: #define        IERBUFSIZ       1600
                     46: #define        IEXBUFSIZ       1600
                     47: 
                     48: #ifdef SUN2
                     49: #define        IEDMABASE       0x000000        /* Can access all of memory */
                     50: #endif SUN2
                     51: #ifdef SUN3
                     52: #define        IEDMABASE       0x0F000000      /* Can access top 16MB of memory */
                     53: #endif SUN3
                     54: 
                     55: /* Location in virtual memory of the SCP (System Configuration Pointer) */
                     56: #define SCP_LOC (char *)(IEDMABASE+IESCPADDR)
                     57: 
                     58: /* controller types */
                     59: #define IE_MB  1       /* Multibus */
                     60: #define        IE_OB   2       /* onboard */
                     61: 
                     62: struct ie_softc {
                     63:        /*
                     64:         * This first item does two things.  First, it reserves space for
                     65:         * all the various protocols that need to put their locals somewhere
                     66:         * (it was decided that HERE is convenient!).  Second, it fills
                     67:         * out the structure to align es_scp to the wierd-in address
                     68:         * that Intel (thanks guys) fetches it from.
                     69:         */
                     70:        char    es_fill[PROTOSCRATCH-sizeof(struct iescp)]; /* Align */
                     71:        struct  iescp   es_scp;         /* System config pointer (used once) */
                     72:        struct  ieiscp  es_iscp;        /* Intermediate sys config ptr (once) */
                     73:        struct  iescb   es_scb;         /* Sys Control Block, the real mama */
                     74:        struct  ierbd   es_rbd;
                     75:        struct  ierbd   es_rbd2;        /* Hack for 82586 ucode bugs */
                     76:        struct  ierfd   es_rfd;
                     77:        struct  ietfd   es_tfd;
                     78:        struct  ietbd   es_tbd;
                     79:        struct  mie_device *es_mie;
                     80:        struct  obie_device *es_obie;
                     81:        short   es_type;
                     82:        struct  ieiaddr es_iaddr;       /* Cmd to set up our Ethernet addr */
                     83:        struct  ieconf  es_ic;          /* Cmd to configure the chip */
                     84:        char    es_rbuf[IERBUFSIZ];
                     85:        char    es_xbuf[IEXBUFSIZ];     /* buffer accessible by chip */
                     86:        char    es_rbuf2[10];           /* Hack for 82586 ucode bugs */
                     87: };
                     88: 
                     89: /*
                     90:  * This initializes the onboard Ethernet control reg to:
                     91:  *     Reset is active
                     92:  *     Loopback is NOT active
                     93:  *     Channel Attn is not active
                     94:  *     Interrupt enable is not active.
                     95:  * Loopback is deactivated due to a bug in the Intel serial interface
                     96:  * chip.  This chip powers-up in a locked up state if Loopback is active.
                     97:  * It "unlocks" itself if you release Loopback; then it's OK to reassert it.
                     98:  */
                     99: struct obie_device obie_reset = {0, 1, 0, 0, 0, 0, 0};
                    100: 
                    101: ieoff_t to_ieoff();
                    102: ieaddr_t to_ieaddr();
                    103: 
                    104: #ifdef DEBUG
                    105: ieint_t from_ieint();
                    106: #endif DEBUG
                    107: 
                    108: struct devinfo ieinfo = {
                    109:        sizeof (struct mie_device),
                    110:        sizeof(struct ie_softc),
                    111:        0,
                    112:        NSTD,
                    113:        iestd,
                    114:        MAP_MBMEM,
                    115:        0,                              /* transfer size handled by ND */
                    116: };
                    117: 
                    118: int xxprobe(), xxboot(), ieopen(), ieclose(), etherstrategy(), nullsys();
                    119: 
                    120: struct boottab iedriver = {
                    121:        "ie",   xxprobe,        xxboot, ieopen,         ieclose,
                    122:        etherstrategy,  "ie: Sun/Intel Ethernet",       &ieinfo,
                    123: };
                    124: 
                    125: /*
                    126:  * Open Intel Ethernet nd connection, return -1 for errors.
                    127:  */
                    128: ieopen(sip)
                    129:        struct saioreq *sip;
                    130: {
                    131:        register int result;
                    132: 
                    133:        sip->si_sif = &ieif;
                    134:        if ( ieinit(sip) || (result = etheropen(sip)) < 0 ) {
                    135:                ieclose(sip);           /* Make sure we kill chip */
                    136:                return (-1);
                    137:        }
                    138:        return (result);
                    139: }
                    140: 
                    141: /*
                    142:  * Set up memory maps and Ethernet chip.
                    143:  * Returns 1 for error, 0 for ok.
                    144:  */
                    145: int
                    146: ieinit(sip)
                    147:        struct saioreq *sip;
                    148: {
                    149:        register struct ie_softc *es;
                    150:        int paddr;
                    151:        int i;
                    152:        struct idprom id;
                    153:        
                    154:        if (idprom(IDFORM_1, &id) == IDFORM_1 &&
                    155:            id.id_machine != IDM_SUN2_MULTI &&
                    156:            (sip->si_ctlr == 0 || sip->si_ctlr == iestd[0])) {
                    157:                /* onboard Ethernet */
                    158:                register struct obie_device *obie;
                    159: 
                    160:                es = (struct ie_softc *)sip->si_dmaaddr;
                    161:                bzero((char *)es, sizeof *es);
                    162:                es->es_type = IE_OB;
                    163:                es->es_obie = obie = (struct obie_device *)
                    164:                        devalloc(MAP_OBIO, VIOPG_ETHER << BYTES_PG_SHIFT,
                    165:                                sizeof(*obie));
                    166:        } else {
                    167:                register struct mie_device *mie;
                    168:                struct miepg *pg;
                    169:                short *ap;
                    170: 
                    171:                mie = (struct mie_device *) sip->si_devaddr;
                    172:                mie->mie_peack = 1;
                    173:                mie->mie_noloop = 0;
                    174:                mie->mie_ie = 0;
                    175:                mie->mie_pie = 0;
                    176:                paddr = mie->mie_mbmhi << 16;
                    177:                ap = (short *)mie->mie_pgmap;
                    178:                for (i=0; i<IEVVSIZ; i++)       /* note: sets p2mem -> 0 */
                    179:                        *ap++ = 0;
                    180:                for (i=0; i<IEPHYMEMSIZ/IEPAGSIZ; i++) {
                    181:                        mie->mie_pgmap[0].mp_pfnum = i;
                    182:                }
                    183:                pg = &mie->mie_pgmap[0];
                    184:                for (i=0; i<IEVIRMEMSIZ/IEPAGSIZ; i++) {
                    185:                        pg->mp_swab = 1;
                    186:                        pg->mp_pfnum = i;
                    187:                        pg++;
                    188:                }
                    189:                /* last page for chip init */
                    190:                mie->mie_pgmap[IEVVSIZ-1].mp_pfnum = (PROTOSCRATCH/IEPAGSIZ)-1;
                    191:                es = (struct ie_softc *) 
                    192:                        devalloc(MAP_MBMEM, paddr, sizeof(struct ie_softc));
                    193:                bzero((char *)es, sizeof *es);
                    194:                es->es_type = IE_MB;
                    195:                es->es_mie = mie;
                    196:        }
                    197:        /* FIXME, release multibus resources ifdef. */
                    198:        sip->si_devdata = (caddr_t)es;
                    199:        return iereset(es, sip);
                    200: }
                    201: 
                    202: /*
                    203:  * Basic 82586 initialization
                    204:  * Returns 1 for error, 0 for ok.
                    205:  */
                    206: int
                    207: iereset(es, sip)
                    208:        register struct ie_softc *es;
                    209:        struct saioreq *sip;
                    210: {
                    211:        struct ieiscp *iscp = &es->es_iscp;
                    212:        struct iescb *scb = &es->es_scb;
                    213:        struct ieiaddr *iad = &es->es_iaddr;
                    214:        struct ieconf *ic = &es->es_ic;
                    215:        int j;
                    216:        int savepmap;
                    217:        register struct mie_device *mie = es->es_mie;
                    218:        register struct obie_device *obie = es->es_obie;
                    219: 
                    220:        for (j = 0; j < 10; j++) {
                    221:                /* Set up the control blocks for initializing the chip */
                    222:                bzero((caddr_t)&es->es_scp, sizeof (struct iescp));
                    223:                es->es_scp.ie_iscp = to_ieaddr(es, (caddr_t)iscp);
                    224:                bzero((caddr_t)iscp, sizeof (struct ieiscp));
                    225:                iscp->ie_busy = 1;
                    226:                iscp->ie_scb = to_ieoff(es, (caddr_t)scb);
                    227:                iscp->ie_cbbase = to_ieaddr(es, (caddr_t)es);
                    228:                bzero((caddr_t)scb, sizeof (struct iescb));
                    229:                if (es->es_type == IE_OB) {
                    230:                        /*
                    231:                         * The 82586 has bugs that require us to be in 
                    232:                         * loopback mode while we initialize it, to avoid
                    233:                         * transitions on CRS (carrier sense).
                    234:                         * 
                    235:                         * However, the Intel serial interface chip used
                    236:                         * on Carrera also has bugs: if it powers-up in
                    237:                         * loopback, you have to release loopback at least
                    238:                         * once to make it behave -- it powers up with
                    239:                         * CRS and CDT permanently active, which rapes the 586.
                    240:                         *
                    241:                         * How do you spell "broken"?  I-N-T-E-L...
                    242:                         */
                    243:                        *obie = obie_reset;     /* Reset chip & interface */
                    244:                        DELAY(20);
                    245:                        obie->obie_noloop = 0;  /* Put it in loopback now */
                    246:                        DELAY(20);
                    247:                        obie->obie_noreset = 1; /* Release Reset on 82586 */
                    248:                        DELAY(200);
                    249:                        /*
                    250:                         * Now set up to let the Ethernet chip read the SCP.
                    251:                         * Intel wired in the address of the SCP.  It happens
                    252:                         * to be 0xFFFFF6.
                    253:                         */
                    254:                        savepmap = getpgmap(SCP_LOC);
                    255:                        setpgmap(SCP_LOC, getpgmap((char *)&es->es_scp));
                    256:                } else {
                    257:                        mie->mie_reset = 1;
                    258:                        DELAY(20);
                    259:                        mie->mie_reset = 0;
                    260:                        DELAY(200);
                    261:                }
                    262: 
                    263:                /*
                    264:                 * We are set up.  Give the chip a zap, then wait up to
                    265:                 * 1 sec, or until chip comes ready.
                    266:                 */
                    267:                ieca(es);
                    268:                CDELAY(iscp->ie_busy != 1, 1000);
                    269: 
                    270:                /* Whether or not it worked, we have to clean up. */
                    271:                if (es->es_type == IE_OB) {
                    272:                        /* If it didn't init, reset chip again. */
                    273:                        if (iscp->ie_busy == 1)
                    274:                                obie->obie_noreset = 0;
                    275:                        setpgmap(SCP_LOC, savepmap);
                    276:                }
                    277:                if (iscp->ie_busy == 1)
                    278:                        continue;       /* Continue loop until we get it */
                    279: 
                    280:                /*
                    281:                 * Now try to run a few simple commands before we say "OK".
                    282:                 */
                    283:                bzero((caddr_t)iad, sizeof (struct ieiaddr));
                    284:                iad->ieia_cb.ie_cmd = IE_IADDR;
                    285:                myetheraddr((struct ether_addr *)iad->ieia_addr);
                    286:                if (iesimple(es, &iad->ieia_cb)) {
                    287:                        printf("ie: hang while setting Ethernet address.\n");
                    288:                        continue;
                    289:                }
                    290: 
                    291:                iedefaultconf(ic);
                    292:                if (iesimple(es, &ic->ieconf_cb)) {
                    293:                        printf("ie: hang while setting chip config.\n");
                    294:                        continue;
                    295:                }
                    296: 
                    297:                /*
                    298:                 * Take the Ethernet interface chip out of loopback mode, i.e.
                    299:                 * put us on the wire.  We can't do this before having
                    300:                 * initialized the Ethernet chip because the chip does random
                    301:                 * things if its 'wire' is active between the time it's reset
                    302:                 * and the first CA.  Also, the IA-setup and configure commands
                    303:                 * will hang under some conditions unless the interface is
                    304:                 * very quiet and still.
                    305:                 */
                    306:                if (es->es_type == IE_OB)
                    307:                        obie->obie_noloop = 1;
                    308:                if (es->es_type == IE_MB)
                    309:                        mie->mie_noloop = 1; 
                    310:                if (ierustart(es)) {
                    311:                        printf("ie: hang while starting receiver.\n");
                    312:                        continue;
                    313:                }
                    314:                        
                    315:                return 0;               /* It all worked! */
                    316:        }
                    317: 
                    318:        /* We tried a bunch of times, no luck. */
                    319:        printf("ie: cannot initialize\n");
                    320:        return 1;
                    321: }
                    322: 
                    323: /*
                    324:  * Initialize and start the Receive Unit
                    325:  */
                    326: int
                    327: ierustart(es)
                    328:        register struct ie_softc *es;
                    329: {
                    330:        register struct ierbd *rbd = &es->es_rbd;
                    331:        struct ierbd *rbd2 = &es->es_rbd2;
                    332:        register struct ierfd *rfd = &es->es_rfd;
                    333:        register struct iescb *scb = &es->es_scb;
                    334:        int timebomb = TIMEBOMB;
                    335: 
                    336:        /*
                    337:         * Stop the RU, since we're sharing buffers with it.
                    338:         * Then wait until it has really stopped.
                    339:         */
                    340:        while (scb->ie_rus == IERUS_READY) {
                    341:                while (scb->ie_cmd != 0)        /* XXX */
                    342:                        if (timebomb-- <= 0) return TIMEOUT;
                    343:                scb->ie_cmd = IECMD_RU_ABORT;
                    344:                ieca(es);
                    345:        }
                    346: 
                    347:        while (scb->ie_cmd != 0)        /* XXX */
                    348:                if (timebomb-- <= 0) return TIMEOUT;
                    349: 
                    350:        /* Real receive buffer descriptor */
                    351:        *(short *)rbd = 0;
                    352:        rbd->ierbd_next = to_ieoff(es, (caddr_t)rbd2);          /* Fake */
                    353:        rbd->ierbd_el = 0;                                      /* Fake */
                    354:        rbd->ierbd_buf = to_ieaddr(es, es->es_rbuf);
                    355:        rbd->ierbd_sizehi = IERBUFSIZ >> 8;
                    356:        rbd->ierbd_sizelo = IERBUFSIZ & 0xFF;
                    357: 
                    358:        /* Fake receive buffer to avoid chip lockups in B0 mask */
                    359:        *(short *)rbd2 = 0;
                    360:        rbd2->ierbd_next = -1;          /* unnecessary since el = 1 */
                    361:        rbd2->ierbd_el = 1;
                    362:        rbd2->ierbd_buf = to_ieaddr(es, es->es_rbuf2);
                    363:        rbd2->ierbd_sizehi = 0;
                    364:        rbd2->ierbd_sizelo = sizeof(es->es_rbuf2) & 0xFF;
                    365: 
                    366:        /* Real receive frame descriptor */
                    367:        *(short *)rfd = 0;
                    368:        rfd->ierfd_next = -1;           /* Unused since el = 1 */
                    369:        rfd->ierfd_el = 1;
                    370:        rfd->ierfd_susp = 1;            /* Suspend after receiving one */
                    371:        rfd->ierfd_rbd = to_ieoff(es, (caddr_t)rbd);
                    372: 
                    373:        /*
                    374:         * Start the RU again.
                    375:         */
                    376:        scb->ie_rfa = to_ieoff(es, (caddr_t)rfd);
                    377:        scb->ie_cmd = IECMD_RU_START;
                    378:        ieca(es);
                    379:        return OK;
                    380: }
                    381: 
                    382: ieca(es)
                    383:        register struct ie_softc *es;
                    384: {
                    385:        if (es->es_type == IE_OB) {
                    386:                es->es_obie->obie_ca = 1;
                    387:                es->es_obie->obie_ca = 0;
                    388:        } else {
                    389:                es->es_mie->mie_ca = 1;
                    390:                es->es_mie->mie_ca = 0;
                    391:        }
                    392: }
                    393: 
                    394: int
                    395: iesimple(es, cb)
                    396:        register struct ie_softc *es;
                    397:        register struct iecb *cb;
                    398: {
                    399:        register struct iescb *scb = &es->es_scb;
                    400:        register timebomb = TIMEBOMB;
                    401: 
                    402:        *(short *)cb = 0;       /* clear status bits */
                    403:        cb->ie_el = 1;
                    404:        cb->ie_next = 0;
                    405: 
                    406:        /* start CU */
                    407:        while (scb->ie_cmd != 0)        /* XXX */
                    408:                if (timebomb-- <= 0) return TIMEOUT;
                    409:        scb->ie_cbl = to_ieoff(es, (caddr_t)cb);
                    410:        scb->ie_cmd = IECMD_CU_START;
                    411:        if (scb->ie_cx)
                    412:                scb->ie_cmd |= IECMD_ACK_CX;
                    413:        if (scb->ie_cnr)
                    414:                scb->ie_cmd |= IECMD_ACK_CNR;
                    415:        ieca(es);
                    416:        while (!cb->ie_done)            /* XXX */
                    417:                if (timebomb-- <= 0) return TIMEOUT;
                    418:        while (scb->ie_cmd != 0)        /* XXX */
                    419:                if (timebomb-- <= 0) return TIMEOUT;
                    420:        if (scb->ie_cx)
                    421:                scb->ie_cmd |= IECMD_ACK_CX;
                    422:        if (scb->ie_cnr)
                    423:                scb->ie_cmd |= IECMD_ACK_CNR;
                    424:        ieca(es);
                    425:        return OK;
                    426: }
                    427: 
                    428: /*
                    429:  * Transmit a packet.
                    430:  * Always copy the packet for the sake of Multibus
                    431:  * boards and Sun3's.  This is not a performance critical situation
                    432:  */
                    433: iexmit(es, buf, count)
                    434:        register struct ie_softc *es;
                    435:        char *buf;
                    436:        int count;
                    437: {
                    438:        register struct ietbd *tbd = &es->es_tbd;
                    439:        register struct ietfd *td = &es->es_tfd;
                    440: 
                    441:        bzero((caddr_t)tbd, sizeof *tbd);
                    442:        tbd->ietbd_eof = 1;
                    443:        tbd->ietbd_cntlo = count & 0xFF;
                    444:        tbd->ietbd_cnthi = count >> 8;
                    445:        bcopy(buf, es->es_xbuf, count);
                    446:        tbd->ietbd_buf = to_ieaddr(es, es->es_xbuf);
                    447:        td->ietfd_tbd = to_ieoff(es, (caddr_t)tbd);
                    448:        td->ietfd_cmd = IE_TRANSMIT;
                    449:        if (iesimple(es, (struct iecb *)td)) {
                    450:                printf("ie: xmit hang\n");
                    451:                return -1;
                    452:        }
                    453: #ifdef DEBUG
                    454:        if (!td->ietfd_ok) {
                    455:                /* Print status bits from transmit command */
                    456:                printf("ie xmit failed: %x\n", *(unsigned short *)td);
                    457:        }
                    458: #endif DEBUG
                    459:        if (td->ietfd_ok)
                    460:                return (0);
                    461:        if (td->ietfd_xcoll)
                    462:                printf("ie: Ethernet cable problem\n");
                    463:        return (-1);
                    464: }
                    465: 
                    466: 
                    467: 
                    468: int
                    469: iepoll(es, buf)
                    470:        register struct ie_softc *es;
                    471:        char *buf;
                    472: {
                    473:        register struct ierbd *rbd = &es->es_rbd;
                    474:        register struct ierfd *rfd = &es->es_rfd;
                    475:        register struct iescb *scb = &es->es_scb;
                    476:        int len;
                    477:        int timebomb = TIMEBOMB;
                    478:        
                    479: #ifdef DEBUG
                    480:        /* Check for error status, and printf if so */
                    481:        /*
                    482:         * Resource errors should be ignored, they happen even when we
                    483:         * are not interested in listening.
                    484:         */
                    485:        if (scb->ie_crcerrs || scb->ie_alnerrs || scb->ie_ovrnerrs) {
                    486:                printf("ie recv %x CRC %d, ALN %d, OVRN %d\n",
                    487:                        scb->ie_rus,
                    488:                        from_ieint(scb->ie_crcerrs),
                    489:                        from_ieint(scb->ie_alnerrs),
                    490:                        from_ieint(scb->ie_ovrnerrs));
                    491:                scb->ie_crcerrs = 0;
                    492:                scb->ie_alnerrs = 0;
                    493:                scb->ie_ovrnerrs = 0;
                    494:        }
                    495: #endif DEBUG
                    496: 
                    497:        /*
                    498:         * Note, this assumes that the RU is set up to get out of READY
                    499:         * state after receiving one packet.
                    500:         */
                    501:        if (scb->ie_rus == IERUS_READY) {
                    502:                return (0);                     /* No packet yet */
                    503:        } else {
                    504:                /* RU not ready, see if because we got a packet. */
                    505:                if (!rfd->ierfd_done || !rbd->ierbd_eof) {
                    506:                        /* No, randomness zapped it. */
                    507: #ifdef DEBUG
                    508:                        printf("ie recv restart from %x: scb %x frm %x buf %x\n"
                    509:                                , scb->ie_rus, 
                    510:                                *(unsigned short *)scb, *(unsigned short *)rfd,
                    511:                                *(unsigned short *)rbd);
                    512: #endif DEBUG
                    513:                        ierustart(es);
                    514:                        return (0);
                    515:                }
                    516:        }
                    517: 
                    518:        /*
                    519:         * We got a packet.
                    520:         */
                    521:        len = (rbd->ierbd_cnthi << 8) + rbd->ierbd_cntlo;
                    522:        bcopy(es->es_rbuf, buf, len);
                    523:        while (scb->ie_cmd != 0)        /* XXX */
                    524:                if (timebomb-- <= 0) return TIMEOUT;
                    525:        if (scb->ie_fr)
                    526:                scb->ie_cmd |= IECMD_ACK_FR;
                    527:        if (scb->ie_rnr)
                    528:                scb->ie_cmd |= IECMD_ACK_RNR;
                    529:        ieca(es);
                    530:        ierustart(es);
                    531:        return (len);
                    532: }
                    533: 
                    534: /*
                    535:  * Convert a CPU virtual address into an Ethernet virtual address.
                    536:  *
                    537:  * For Multibus, we assume it's in the Ethernet's memory space, and we
                    538:  * just subtract off the start of the memory space (==es).  For Model 50,
                    539:  * the Ethernet chip has full access to supervisor virtual memory.
                    540:  * For Carrera, the chip can access the top 16MB of virtual memory,
                    541:  * but we never give it addresses outside that range, so the high
                    542:  * order bits can be ignored.
                    543:  */
                    544: ieaddr_t
                    545: to_ieaddr(es, cp)
                    546:        struct ie_softc *es;
                    547:        caddr_t cp;
                    548: {
                    549:        union {
                    550:                int     n;
                    551:                char    c[4];
                    552:        } a, b;
                    553: 
                    554: #ifdef SUN3
                    555: #ifdef DEBUG
                    556:        if (cp < (char *)0x0F000000 || cp >= (char *)0x10000000) {
                    557:                /* printf("Bad ptr to_ieaddr(%x)\n", cp); */
                    558:                ;  asm(" .word 0xFFFF") ; ;
                    559:        }
                    560: #endif DEBUG
                    561: #endif SUN3
                    562:        if (es->es_type == IE_MB)
                    563:                a.n = cp - (caddr_t)es;
                    564:        else /* if (es->es_type == IE_OB) */
                    565:                a.n = (int)cp;
                    566:        b.c[0] = a.c[3];
                    567:        b.c[1] = a.c[2];
                    568:        b.c[2] = a.c[1];
                    569:        b.c[3] = 0;
                    570:        return (b.n);
                    571: }
                    572: 
                    573: /*
                    574:  * Convert a CPU virtual address into a 16-bit offset for the Ethernet
                    575:  * chip.
                    576:  *
                    577:  * This is the same for Onboard and Multibus, since the offset is based
                    578:  * on the absolute address supplied in the initial system configuration
                    579:  * block -- which we customize for Multibus or Onboard.
                    580:  */
                    581: ieoff_t
                    582: to_ieoff(es, addr)
                    583:        register struct ie_softc *es;
                    584:        caddr_t addr;
                    585: {
                    586:        union {
                    587:                short   s;
                    588:                char    c[2];
                    589:        } a, b;
                    590: 
                    591:        a.s = (short)(addr - (caddr_t)es);
                    592:        b.c[0] = a.c[1];
                    593:        b.c[1] = a.c[0];
                    594:        return (b.s);
                    595: }
                    596: 
                    597: 
                    598: #ifdef DEBUG
                    599: ieint_t
                    600: from_ieint(n)
                    601:        short n;
                    602: {
                    603:        union {
                    604:                short   s;
                    605:                char    c[2];
                    606:        } a, b;
                    607: 
                    608:        a.s = n;
                    609:        b.c[0] = a.c[1];
                    610:        b.c[1] = a.c[0];
                    611:        return (b.s);
                    612: }
                    613: #endif DEBUG
                    614: 
                    615: /*
                    616:  * Set default configuration parameters
                    617:  * As spec'd by Intel, except acloc == 1 for header in data
                    618:  */
                    619: iedefaultconf(ic)
                    620:        register struct ieconf *ic;
                    621: {
                    622:        bzero((caddr_t)ic, sizeof (struct ieconf));
                    623:        ic->ieconf_cb.ie_cmd = IE_CONFIG;
                    624:        ic->ieconf_bytes = 12;
                    625:        ic->ieconf_fifolim = 8;
                    626:        ic->ieconf_pream = 2;           /* 8 byte preamble */
                    627:        ic->ieconf_alen = 6;
                    628:        ic->ieconf_acloc = 1;
                    629:        ic->ieconf_space = 96;
                    630:        ic->ieconf_slttmh = 512 >> 8;
                    631:        ic->ieconf_minfrm = 64;
                    632:        ic->ieconf_retry = 15;
                    633: }
                    634: 
                    635: /*
                    636:  * Close down intel ethernet device.
                    637:  * On the Model 50, we reset the chip and take it off the wire, since
                    638:  * it is sharing main memory with us (occasionally reading and writing),
                    639:  * and most programs don't know how to deal with that -- they just assume
                    640:  * that main memory is theirs to play with.
                    641:  */
                    642: ieclose(sip)
                    643:        struct saioreq *sip;
                    644: {
                    645:        register struct ie_softc *es = (struct ie_softc *) sip->si_devdata;
                    646: 
                    647:        if (es->es_type == IE_OB)
                    648:                *es->es_obie = obie_reset;
                    649: }

unix.superglobalmegacorp.com

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