Annotation of researchv9/sys/boot/stand/if_ie.c, revision 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.