Annotation of cci/d/ether/veiu.c, revision 1.1

1.1     ! root        1: #include "veiu.h"
        !             2: #include "conf.h"
        !             3: #include "const.h"
        !             4: #include "pte.h"
        !             5: 
        !             6: #define ACEBASE                0xff0000        /* ACE device base address      */
        !             7: #define ACEVECTOR      0x90            /*                              */
        !             8: #define RXHDLR         0x90            /* Receive vector interrupt     */
        !             9: #define TXHDLR                 0x91            /* Transmit vector interrupt    */
        !            10: #define VEIU_LEN       1               /* 1K for I/O registers         */
        !            11: #define DPM_SIZE       32              /* 32K DMP                      */
        !            12: 
        !            13: #define        LOWBUF          0               /* lowest dmp buffer index      */
        !            14: #define        HIGHBUF         15              /* highest dmp buffer index     */
        !            15: /*
        !            16:        Errors
        !            17: */
        !            18: 
        !            19: struct errors  {
        !            20:        short   tx_retries;     /* number of retries            */
        !            21:        short   tx_discarded;   /* discarded packet count       */
        !            22:        short   tx_datagrams;   /* transmitted packet count     */
        !            23:        short   rx_overrn;      /* overrun error count          */
        !            24:        short   rx_oddbit;      /* odd # of bits count          */
        !            25:        short   rx_crcerr;      /* crc error                    */
        !            26:        short   rx_undern;      /* underrun error               */
        !            27:        short   rx_datagrams;   /* received packet count        */
        !            28:        short   rx_mismtch;     /* Xmit & Rec msgs mismatched   */
        !            29:        short   rx_rbcerr       /* rbc (of received messg) error*/
        !            30: };
        !            31: 
        !            32: /*
        !            33:        Xmit / Receive queue tracking pointers
        !            34: */
        !            35: 
        !            36: struct XRqueue {
        !            37:        short   currnd;                 /* current random number        */
        !            38:        short   boundry;                /* Xmit/Rec boundary            */
        !            39:        char    *dpmptr;                /* Pointer to dpm               */
        !            40:        short   Rptr;                   /* Rx segment tracking ptr      */
        !            41:        short   Xptr;                   /* Tx segment tracking ptr      */
        !            42:        short   Xnxt;                   /* Next avail Xmit buffer       */
        !            43:        struct errors stats;            /* error tracker                */
        !            44: };
        !            45: 
        !            46: struct XRqueue   aceq;
        !            47: struct acedevice *addr;                        /* Pointer to device I/O registers */
        !            48: long IObase;
        !            49: 
        !            50: #define NACE           2               /* No. of V/EIU devices         */
        !            51: #define NOFRAME                16              /* No. of available frames      */
        !            52: #define FRAMESZ                2048            /* Frames size: 2K              */
        !            53: /*
        !            54:        Oftenly-used write routines
        !            55: */
        !            56: #define NL             writes("\n");
        !            57: 
        !            58: long ace[NACE];                                /* V/EIU address slots          */
        !            59: long dpmmap[] = {0xfff80000,0xfff90000};/* dpm address                 */
        !            60: 
        !            61: extern long savvec3, unused, clk_cnt, proc_no;
        !            62: long oldunu;
        !            63: 
        !            64: char   ace_station[6*NACE] = {                         /* addresses    */
        !            65:        ~0x8,~0x0,~0x3,~0x0,~0x0,~0x1,
        !            66:        ~0x8,~0x0,~0x3,~0x0,~0x0,~0x2,
        !            67: };
        !            68: 
        !            69: /*     Test message                                                    */
        !            70: 
        !            71: char testmsg[] = "ABCDEFGHIJKLMNOPQRSTXYUYWZ0123456789\
        !            72: abcdefghijklmnopqrstxyuv";
        !            73: 
        !            74: #define TMSGSZ (sizeof(testmsg) -1 )
        !            75: 
        !            76: char ace_hash_code[8*NACE]={                           /* hash tables  */
        !            77:        ~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,/*u 0*/
        !            78:         ~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,~0xF,/*u 1*/
        !            79: }; 
        !            80: 
        !            81: short random_mask_tbl[16] = {                          /* backoff table*/
        !            82:        0x0040, 0x00C0, 0x01C0, 0x03C0, 
        !            83:         0x07C0, 0x0FC0, 0x1FC0, 0x3FC0,
        !            84:         0x7FC0, 0xFFC0, 0xFFC0, 0xFFC0,
        !            85:         0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0 
        !            86:        };
        !            87: 
        !            88: short msgno, testno, reddy, firstrep;  /* global variables     */
        !            89: 
        !            90: veiu() 
        !            91: {      short ix;
        !            92:        short Csr;
        !            93: 
        !            94:        for (ix=0; (ix < NACE) && ace[ix] ; ix++) { 
        !            95:               NL; writes("\nBEGIN TESTING V/EIU NO. "); writed(ix); NL;
        !            96:               if (!veiu_reset(ix)) {
        !            97:                   writes("\n3. MODE 2 TEST------------------------------> ");
        !            98:                   NL; NL;
        !            99:                   testno = 2;          /* current test number */
        !           100:                   veiu_ex();           /* Test this ACE    */
        !           101:                   DELAY(0x200000);
        !           102:                   Csr = (short)addr->csr;
        !           103:                   Csr &= ~CSR_GO;      /* turn off mode 2  */
        !           104:                   movew((short)Csr,&addr->csr);/* stop mode 2 */
        !           105: 
        !           106:                   movew((short)CSR_GO,&addr->csr);
        !           107:                   Csr = (short)addr->csr;
        !           108:                   if (Csr & CSR_ACTIVE)
        !           109:                     {
        !           110:                       Csr |= CSR_ENINT | CSR_LOOP3 | CSR_PROMISCUOUS;          
        !           111:                       movew(Csr,&addr->csr);
        !           112:                     }
        !           113:                   else
        !           114:                     {
        !           115:                       writes("*** Controller would not go active.");
        !           116:                       writes("  Test aborted ***");
        !           117:                     }
        !           118:                   NL;
        !           119:                   writes("\n4. MODE 3 TEST------------------------------> ");
        !           120:                   NL; NL;
        !           121:                   testno = 3;          /* current test number */
        !           122:                   init_erc();
        !           123:                   veiu_ex();           /* Test this ACE    */
        !           124: 
        !           125:                   DELAY(0x200000);
        !           126:                   Csr = (short)addr->csr;
        !           127:                   Csr |= CSR_ENXMITODD;        /* enable oddbit */
        !           128:                   movew((short)Csr,&addr->csr);/* update csr word */
        !           129:                   NL;
        !           130:                   writes("\n5. MODE 3, ODD # OF BITS ERROR TEST---------> ");
        !           131:                   NL; NL;
        !           132:                   testno = 4;          /* current test number */
        !           133:                   init_erc();
        !           134:                   veiu_ex();           /* Test this ACE    */
        !           135:                   DELAY(0x200000);
        !           136:                   Csr = (short)addr->csr;
        !           137:                   Csr &= ~CSR_ENXMITODD;       /* disable oddbit  */
        !           138:                   Csr |= CSR_NOXMITCRC;        /* suppressed crc  */
        !           139:                   movew((short)Csr,&addr->csr);/* update csr word */
        !           140:                   NL;
        !           141: /*
        !           142:                   writes("\n6. MODE 3, CRC ERROR TEST-------------------> ");
        !           143:                   NL; NL;
        !           144:                   testno = 5;
        !           145:                   init_erc();
        !           146:                   veiu_ex();
        !           147:                   DELAY(200000);
        !           148:                   NL;
        !           149:                   writes("\n7. MODE 3, OVERRUN ERROR TEST---------------> ");
        !           150:                   NL; NL;
        !           151:                   testno = 6;
        !           152:                   init_erc();
        !           153:                   firstrep = 25;
        !           154:                   veiu_ex();
        !           155: */
        !           156:                   writes("\nEND TESTING OF UNIT: "); writed(ix); NL;
        !           157:                }
        !           158:             } /* end for loop */
        !           159: }
        !           160: 
        !           161: /* 
        !           162:        Diagnostic routine
        !           163: */
        !           164: 
        !           165: veiu_ex()
        !           166: {
        !           167: short mxnofmsg, lostmsg, timecount;    /* max. number of messages      */
        !           168: 
        !           169:        if (testno == 2)
        !           170:             mxnofmsg = 22;
        !           171:        else    /* mode 3 */
        !           172:             mxnofmsg = 13;
        !           173:        lostmsg = 0;
        !           174:        for (msgno = 2; msgno < mxnofmsg; msgno++)
        !           175:            {
        !           176:             load_txbf();               /* fill up tx buffer    */
        !           177:             reddy = 1;                 /* block next message   */
        !           178:             timecount = 0;
        !           179:             while (reddy) {            /* wait for rcvr to response    */
        !           180:                DELAY(0x5000);          /* wait for receiver to finish  */
        !           181:                timecount++;            /* count waiting time           */
        !           182:                if (timecount > 100)    /* is receiver still not responding */
        !           183:                   {                    /* time out                     */
        !           184:                    lostmsg++;          /* count lost message           */
        !           185:                    reddy = 0;          /* unlock next message          */
        !           186:                   }
        !           187:                }
        !           188:            }                           /* OK!ready for next message    */
        !           189:        report(lostmsg);                /* generate report              */
        !           190: }
        !           191: 
        !           192: /*
        !           193:        load transmit buffer
        !           194: */
        !           195: 
        !           196: load_txbf()
        !           197: {
        !           198:        register struct XRqueue *is = &aceq;
        !           199:        register struct tx_segment *txmbf; 
        !           200:        short  ix, iy, cmd, bfptr, length, repetition;
        !           201: 
        !           202:        txmbf = (struct tx_segment *) (is->dpmptr + (is->Xnxt << 11));
        !           203:        bfptr = 0;
        !           204:        is->stats.tx_retries = 0; /* init number of retries */
        !           205:        switch (testno) {
        !           206:           case 2: {
        !           207:                    repetition = msgno;
        !           208:                    length = TMSGSZ;
        !           209:                    break;
        !           210:                   }
        !           211:           case 3:
        !           212:           case 4:
        !           213:           case 5: {
        !           214:                    length = 5*msgno;
        !           215:                    repetition = 1;
        !           216:                    break;
        !           217:                   }
        !           218:           case 6: {
        !           219:                    repetition = firstrep++;
        !           220:                    length = TMSGSZ;
        !           221:                   }
        !           222:        };
        !           223: 
        !           224: /* now, fill up buffer                         */
        !           225: 
        !           226:        for (ix=0; ix < repetition; ix++)
        !           227:          for (iy=0; iy < length; iy++) 
        !           228:             txmbf->tx_data[bfptr++] = testmsg[iy];  /* fill buffer up */
        !           229: 
        !           230: /* update transmit command word & issue transmit command */
        !           231: 
        !           232: /*
        !           233: if (testno > 2) {
        !           234:    writes("Transmit message #"); writed(msgno-1);
        !           235:    DELAY(1000);        
        !           236: }
        !           237: */
        !           238:        cmd = (bfptr & TCS_TBC) | TCS_TBFULL;   /* update rbc     */
        !           239:        movew((short)cmd,&(txmbf->tx_csr));
        !           240: 
        !           241:        if (++is->Xnxt >= 16)   /* reach buf upper limit ? */
        !           242:           is->Xnxt = is->boundry; /* so, point to buf lower limit */
        !           243: }
        !           244: 
        !           245: /* 
        !           246:        Report generator
        !           247: */
        !           248: 
        !           249: report(lostmsg)
        !           250: short lostmsg;         /* no of msgs sent but not received     */
        !           251: {
        !           252:        short ix;
        !           253:        register struct XRqueue *is = &aceq;
        !           254: 
        !           255:            NL; writes("Transmit: ");
        !           256:            writed(is->stats.tx_datagrams); writes(" messages"); NL;
        !           257:            writes("Receive : ");
        !           258:            writed(is->stats.rx_datagrams); writes(" message(s)"); NL;
        !           259:            writes("Discard: ");
        !           260:            writed(is->stats.tx_discarded); writes(" message(s)"); NL;
        !           261:            if (lostmsg)  {     /* there're lost msgs, report...        */
        !           262:                writes("Warning: Reveiver not responding. ");writed(lostmsg);
        !           263:                writes(" message(s) are lost.\n\n");
        !           264:            }
        !           265:            if (testno > 2) {
        !           266:                NL; NL; writes("\t Number of Message(s) With"); NL;
        !           267:                NL; writes("Overrun   Underrun   CRC   Odd # of bits");
        !           268:                NL; NL; writes("   ");
        !           269:                writed(is->stats.rx_overrn); writes("        ");
        !           270:                writed(is->stats.rx_undern); writes("       ");
        !           271:                writed(is->stats.rx_crcerr); writes("         ");
        !           272:                writed(is->stats.rx_oddbit); NL; NL;
        !           273:            }
        !           274:            writes("Done with: ");
        !           275:            writed(is->stats.rx_mismtch);  
        !           276:            writes("  mismatched message(s)"); NL;
        !           277:            if (testno > 2) {
        !           278:                writes("           ");
        !           279:                writed(is->stats.rx_rbcerr);
        !           280:                writes("  received message(s) w/ incorrect byte count"); NL; NL;
        !           281:            }
        !           282:            DELAY(0x10000);     /* relax        */
        !           283: }
        !           284: 
        !           285: 
        !           286: /*
        !           287:    VEIU test routine
        !           288:        Return code: 0-----------------Error
        !           289:                     1-----------------Good
        !           290: */
        !           291: 
        !           292: veiu_reset(unit)
        !           293: short unit;            /* current vioc no */
        !           294: {      register long ix, vbase;
        !           295:        int veiu_init();
        !           296: 
        !           297:        NL; writes("\n1. RESET AND INITIALIZATION------------------>");
        !           298:        vbase = ace[unit];
        !           299:        NL; writes("\nInitialize V/EIU at: "); writeh(vbase);
        !           300:        m_veiu(unit,vbase);             /* Set up map for IO space */
        !           301:        if (veiu_init(unit))    /* Reset and init. VEIU */
        !           302:                return(1);
        !           303:        return(0);      /* good return */
        !           304: }
        !           305: 
        !           306: /*
        !           307:   Check vioc controllers' buffer address
        !           308: */
        !           309: 
        !           310: chk_veiu_adr()
        !           311: {      register long curadr;           /* current examine vioc address */
        !           312:         short len, aceno, naces;       /* address length               */
        !           313: 
        !           314:        len = 2;
        !           315:        naces = 0;
        !           316:        curadr = ACEBASE + IOBASE;      /* first ACE buffer address     */
        !           317:        writes("\nProbing for V/EIUs...");
        !           318:        for (aceno= 0; aceno < NACE; aceno++)
        !           319:           {
        !           320:           if (!badaddr(curadr,len))
        !           321:              {
        !           322:               ace[aceno] = curadr - IOBASE;
        !           323:               writes("\nV/EIU no. "); writed(aceno); 
        !           324:               writes(" at virtual address ");
        !           325:                writeh((long)curadr);
        !           326:               naces++;
        !           327:              }
        !           328:           else   /* bad address return */
        !           329:              {         
        !           330:               ace[aceno] = 0;          /* bad address indicator        */
        !           331:              }
        !           332:           curadr += 0x100;             /* get to next dev io regs' address */
        !           333:            }
        !           334:         NL; writed(naces); writes(" V/EIUs found."); NL;
        !           335:          return(naces);
        !           336: }
        !           337: 
        !           338: /*     Routine to Reset VEIU   
        !           339:                     1---------------Good
        !           340:                     0---------------Error
        !           341: */
        !           342: veiu_init(unit)
        !           343: short unit;
        !           344: {
        !           345:        short Csr;
        !           346: 
        !           347:            writes("\nReset V/EIU unit no. "); writed(unit); NL; NL;
        !           348:        /*
        !           349:         * Reset the controller, initialize the recieve buffers,
        !           350:         * and turn the controller on again and set board online.
        !           351:         */
        !           352:            movew((short)CSR_RESET,&addr->csr);
        !           353:            DELAY(10000);
        !           354: 
        !           355:          /* clean up dpm since the controller might jumble dpm after
        !           356:             reset                                                      */
        !           357: 
        !           358:            if (acesetetaddr(unit)) /* set station addr &  */
        !           359:                return(1);           /* emergency return    */
        !           360:            Csr = (short)addr->csr;
        !           361:            aceclean();
        !           362:            movew((short)CSR_GO,&addr->csr);    /* addr->csr = CSR_GO; */
        !           363:            Csr = (short)addr->csr;
        !           364:            if (Csr & CSR_ACTIVE)
        !           365:              {
        !           366:                movew((short)ACEVECTOR,&addr->ivct);
        !           367:                Csr |= CSR_ENINT | CSR_LOOP2 | CSR_PROMISCUOUS;
        !           368:                movew(Csr,&addr->csr);
        !           369:                return(0);
        !           370:              }
        !           371:            else
        !           372:             {
        !           373:               writes("*** Controller would not go active.");
        !           374:               writes("  Test aborted ***"); NL;
        !           375:               return(1);               /* bad return   */
        !           376:             }
        !           377: 
        !           378: }
        !           379: 
        !           380: acesetetaddr(unit)
        !           381: short unit;
        !           382: {
        !           383: register short *pData0, i;
        !           384: register char *pData1;
        !           385: short Csr;
        !           386: 
        !           387:        for (pData0 = (short *)&(addr->rar.station_addr[0]),
        !           388:                pData1 = &ace_station[unit*6], i = 6; --i >= 0;) {
        !           389:            movew((short)(*pData1++),(pData0++)); 
        !           390:            }
        !           391: 
        !           392:        for (pData0 = (short *)&(addr->rar.mcast_hash_code[0]), 
        !           393:             pData1 = &ace_hash_code[unit * 8], i =  8;
        !           394:             --i >= 0;){
        !           395:            movew((short)(*pData1++),(pData0++)); 
        !           396:            }
        !           397: 
        !           398:        movew((short)0x0,&addr->rar.broadcast_en[0]); 
        !           399:        movew((short)0x0,&addr->rar.broadcast_en[1]);
        !           400: 
        !           401:        Csr = (short)addr->csr;
        !           402:        if (Csr & CSR_ACTIVE) /* make sure ctlr is not active before */
        !           403:           {                      /* reading RARs                       */
        !           404:            Csr |= ~CSR_ACTIVE;
        !           405:            movew((short)Csr,&addr->csr);
        !           406:           }
        !           407:         if (reg_test(unit,(short *)&addr->rar.station_addr[0]))
        !           408:           {
        !           409:            writes("\nRVT Fatal error(s) detected. Test aborted.");
        !           410:            return(1);  /* bad return */
        !           411:           }
        !           412:        return(0);      /* good return*/
        !           413: }
        !           414: 
        !           415: Xd_int()
        !           416: {
        !           417:        asm(".align 2");
        !           418:        asm(".globl Xd_hdlr");
        !           419: asm("Xd_hdlr:");
        !           420:        chk_Xd();
        !           421:        asm("rei");
        !           422: }
        !           423: 
        !           424: /*
        !           425:  * Transmit done handler.
        !           426:  */
        !           427: 
        !           428: chk_Xd()
        !           429: {
        !           430: register struct XRqueue *is = &aceq;
        !           431: register struct tx_segment *txseg;     /* ptr to V/EIU tx seg            */
        !           432: short eostat;
        !           433: 
        !           434:        txseg = (struct tx_segment *)((is->Xptr << 11) + is->dpmptr);
        !           435:        if (((eostat = txseg->tx_csr) & TCS_TBFULL) == 0) {
        !           436:                is->stats.tx_retries += (eostat & TCS_RTC);
        !           437:                if (eostat & TCS_RTFAIL) { 
        !           438:                    is->stats.tx_discarded++;
        !           439:                    reddy = 0;          /* unlock next message Xmission */
        !           440:                    }
        !           441:                else 
        !           442:                    is->stats.tx_datagrams++;
        !           443: 
        !           444:                if (++is->Xptr >= 16)
        !           445:                    is->Xptr = is->boundry; 
        !           446:           } 
        !           447: }
        !           448: 
        !           449: /*
        !           450:  * Ethernet interface receiver interrupt.
        !           451:  * If input error just drop packet.
        !           452:  * Otherwise purge input buffered data path and examine 
        !           453:  * packet to determine type.  If can't determine length
        !           454:  * from type, then have to drop packet.  Othewise decapsulate
        !           455:  * packet based on type and pass to type specific higher-level
        !           456:  * input routine.
        !           457:  */
        !           458: 
        !           459: Rxd_int()
        !           460: {
        !           461:        asm(".align 2");
        !           462:        asm(".globl Rxd_hdlr");
        !           463: asm("Rxd_hdlr:");
        !           464:        chk_Rxd();
        !           465:        asm("rei");
        !           466: }
        !           467: 
        !           468: chk_Rxd()
        !           469: {
        !           470: register struct XRqueue *is = &aceq;
        !           471: register struct rx_segment *rxseg;     /* ptr to V/EIU rx seg            */
        !           472: short eistat;
        !           473: int len;
        !           474:        
        !           475:        DELAY(0x1000);          /* To make sure crs is updated */
        !           476:        rxseg = (struct rx_segment *)((is->Rptr << 11) + is->dpmptr);
        !           477: 
        !           478: /*
        !           479: if (testno > 2) {
        !           480:    writes("...receive status: "); writeh(rxseg->rx_csr & 0xFFFF); NL;
        !           481:    DELAY(5000);
        !           482: }
        !           483: if (testno >= 3) {
        !           484:    dumpchar(&(rxseg->rx_data[0]),5*msgno);
        !           485:    DELAY(100000);
        !           486: }
        !           487: */
        !           488: 
        !           489:        if ((eistat = rxseg->rx_csr) & RCS_RBFULL)
        !           490:          {
        !           491:            if (++is->Rptr >= is->boundry) 
        !           492:                    is->Rptr = 0;
        !           493: 
        !           494:            len = (eistat & RCS_RBC);
        !           495: 
        !           496:            if ((eistat & (RCS_ROVRN | RCS_RCRC | RCS_RODD)) ||
        !           497:                 (len > (ET_MAXLEN+CRC_SIZE)))
        !           498:              {
        !           499:                if (eistat & RCS_ROVRN) is->stats.rx_overrn++;
        !           500:                if (eistat & RCS_RCRC) is->stats.rx_crcerr++;
        !           501:                if (eistat & RCS_RODD) is->stats.rx_oddbit++;
        !           502:                if ((testno > 2) & (len < ET_MINLEN)) is->stats.rx_undern++;
        !           503:                if (len > (ET_MAXLEN+CRC_SIZE)) is->stats.rx_overrn++;
        !           504:                compare(rxseg,is);  /* compare receive & Xmit mssgs */
        !           505:              }
        !           506:            else  
        !           507:                compare(rxseg,is);  /* compare receive & Xmit mssgs */
        !           508:          }
        !           509:        is->stats.rx_datagrams++;
        !           510:        rxseg->rx_csr = 0;      
        !           511:        reddy = 0;              /* unlock next message Xmission */
        !           512: }
        !           513: 
        !           514: /*
        !           515:        Initialize Tahoe SCB vectors to handle Rec & Xmit interrupts
        !           516: */
        !           517: 
        !           518: init_veiu_vec()
        !           519: {      long old_vec1, old_vec2, old_vec3;
        !           520: 
        !           521:        asm("movab Rxd_hdlr,_savvec3");
        !           522:        set_handler(RXHDLR,&old_vec1,savvec3);  /* Set handler for VEIU Rxr */
        !           523:        asm("movab Xd_hdlr,_savvec3");
        !           524:        set_handler(TXHDLR,&old_vec2,savvec3); /* Set handler for VEIU Txr */
        !           525: }
        !           526: 
        !           527: /*
        !           528:        I/O registers access routines
        !           529: */
        !           530: 
        !           531: movew(data,to)
        !           532: short data;
        !           533: short *to;
        !           534: {
        !           535:        asm("movow 6(fp),*8(fp)");
        !           536: }
        !           537: 
        !           538: aceclean()
        !           539: {
        !           540: register struct XRqueue *is = &aceq;
        !           541: register short i, data;
        !           542: register char *pData1;
        !           543: short ix;
        !           544: 
        !           545:        init_erc();
        !           546:        is->currnd = (short)49123;
        !           547:        for (pData1 = (char *)(is->dpmptr + (is->boundry << 11)),
        !           548:             i = (SEG_MAX + 1) - is->boundry;
        !           549:             (--i >= 0); pData1 += sizeof (struct tx_segment))
        !           550:             acebakoff(((struct tx_segment*)pData1),15);
        !           551: 
        !           552: }
        !           553: 
        !           554: /*
        !           555:        Initialize error counts & clear dpm buffer
        !           556: */
        !           557: 
        !           558: init_erc()
        !           559: {
        !           560: register struct XRqueue *is = &aceq;
        !           561: short *bptr, ix, reg;
        !           562: 
        !           563:        bptr = (short *)is->dpmptr;
        !           564:        for (ix=0; ix < 16383; ix++)
        !           565:           {
        !           566:             *bptr = 0; 
        !           567:              bptr++;
        !           568:           }                                    
        !           569:        is->stats.tx_datagrams = 0; 
        !           570:        is->stats.tx_discarded = 0; 
        !           571:        is->stats.rx_datagrams = 0; 
        !           572:        is->stats.rx_overrn = 0;
        !           573:        is->stats.rx_crcerr = 0;
        !           574:        is->stats.rx_undern = 0; 
        !           575:        is->stats.rx_oddbit = 0;
        !           576:        is->stats.rx_mismtch = 0;
        !           577:        is->stats.rx_rbcerr = 0;
        !           578:        DELAY(0x2000);  /* try to avoid machine check error     */
        !           579:        reg = (short)addr->rseg;
        !           580:        DELAY(0x2000);
        !           581:        is->Rptr =  (reg & 0x7800) >> 11;
        !           582:        DELAY(0x2000);
        !           583:        reg = (short)addr->tseg;
        !           584:        DELAY(0x2000);
        !           585:        is->Xptr = is->Xnxt = (reg & 0x7800) >> 11;
        !           586: }
        !           587: 
        !           588: /*
        !           589:        back off
        !           590: */
        !           591: 
        !           592: acebakoff(txseg, retries)
        !           593: struct tx_segment *txseg;      /* ptr to V/EIU tx seg            */
        !           594: register int retries;          /* # of randoms to generate       */
        !           595: {
        !           596:        short *pMask;                   /* ptr to mask table.             */
        !           597:        register short *pBakNum;        /* ptr to # entry in Tx seg table */
        !           598:        register short random_num;      /* random number value.           */
        !           599: 
        !           600: 
        !           601:        pMask   = &random_mask_tbl[0];
        !           602:        pBakNum = &txseg->tx_backoff[0];
        !           603: 
        !           604:        for (; --retries >= 0;)
        !           605:          {
        !           606:            random_num   = (aceq.currnd = (aceq.currnd * 18741)-13849);
        !           607:            random_num  &= *(pMask++);
        !           608:            *(pBakNum++) = random_num ^ (short)(0xFF00 | 0x00FC);
        !           609:          }
        !           610:        return(0);
        !           611: }
        !           612: 
        !           613: /*
        !           614:        Compare receive msg against Xmit msg to see if they are matched
        !           615: */
        !           616: 
        !           617: compare(rxbuf,is)
        !           618: struct rx_segment *rxbuf;
        !           619: struct XRqueue *is;
        !           620: {
        !           621:        short bytc, rbc, ix, iy;
        !           622: 
        !           623: 
        !           624:        switch(testno) {
        !           625:           case 2: {
        !           626:                    bytc = msgno*TMSGSZ;
        !           627:                    break;
        !           628:                   }
        !           629:           case 3:
        !           630:           case 4: { /* received with crc */
        !           631:                    rbc = (rxbuf->rx_csr & (short)RCS_RBC) - (short)CRC_SIZE;
        !           632:                    bytc = msgno*5;
        !           633:                    if (rbc != bytc) 
        !           634:                        is->stats.rx_rbcerr++;
        !           635:                    break;
        !           636:                   }
        !           637:           case 5: { /* crc suppressed */
        !           638:                    rbc = (rxbuf->rx_csr & (short)RCS_RBC);
        !           639:                    bytc = msgno*5;
        !           640:                    if (rbc != bytc) 
        !           641:                        is->stats.rx_rbcerr++;
        !           642:                   }
        !           643:           default:
        !           644:                   break;
        !           645:        };
        !           646:        iy = 0;
        !           647:        for (ix=0; ix < bytc; ix++, iy++)
        !           648:           {
        !           649:            if (iy >= TMSGSZ)
        !           650:                 iy = 0;
        !           651:            if (rxbuf->rx_data[ix] != testmsg[iy]) {
        !           652:                 is->stats.rx_mismtch++;
        !           653:                 break;
        !           654:                 }
        !           655:           }
        !           656:        return(0);   /* matched */
        !           657: }
        !           658: 
        !           659: /*
        !           660:        Routine to map VEIU :
        !           661:        VEIU space is map from 1st unused virtual page on
        !           662: */
        !           663: 
        !           664: m_veiu(unit,vbase)
        !           665: long unit, vbase;                      /* device's base address        */
        !           666: {
        !           667:        register long phys_pg, pte, which1;
        !           668:        register struct XRqueue *is = &aceq;
        !           669:        long old_pte, at;
        !           670: 
        !           671:        if (!unit) {
        !           672:           phys_pg = ((vbase+IOBASE) >> PGSHIFT) & 0x3fffff;
        !           673:                                /* 1st physical page of VEIU IOR space */
        !           674:           pte = phys_pg | PG_KW | PG_V | PG_NC;
        !           675:           fix_pte(SBR,unused,&old_pte,pte);
        !           676:           addr = (struct acedevice *)(unused << PGSHIFT);
        !           677:           IObase = (long)addr;
        !           678:           unused++;            /* Next unused PTE in system map */
        !           679:           }
        !           680:        else
        !           681:           addr = (struct acedevice *)(IObase + 0x100);
        !           682:        phys_pg = (dpmmap[unit] >> PGSHIFT) & 0x3fffff;
        !           683:                                /* 1st physical page of DMP      */
        !           684:        pte = phys_pg | PG_KW | PG_V | PG_NC;
        !           685:        for (which1=unused; which1<(unused+DPM_SIZE); which1++) {
        !           686:                fix_pte(SBR,which1,&old_pte,pte);
        !           687:                pte++;
        !           688:                }
        !           689:        is->dpmptr = (char *)((unused << PGSHIFT));
        !           690:        unused = which1;
        !           691:           asm("mfpr $SLR,_savvec3");
        !           692:           savvec3 += (DPM_SIZE + VEIU_LEN);
        !           693:           asm("mtpr _savvec3,$SLR");
        !           694:        asm("mtpr $1,$TBIA");
        !           695:        asm("mtpr $1,$PADC");
        !           696: }
        !           697: 
        !           698: /*
        !           699:        Print mismatched message - For debuging aid only
        !           700: */
        !           701: print_msg(ptr,bytcnt)
        !           702: char *ptr;                     /* pointer to received data     */
        !           703: short bytcnt;                  /* number of char in rev buffer */
        !           704: {
        !           705:        short ix;
        !           706: 
        !           707:        for (ix=0; ix < bytcnt; ix++)
        !           708:            writec(ptr[ix]);
        !           709:        NL;
        !           710: }
        !           711: 
        !           712: /*
        !           713:        Debuging aid
        !           714: */
        !           715: 
        !           716: dumpchar(addr,size)
        !           717: register char *addr;
        !           718: long size;
        !           719: {
        !           720:        register long ix;
        !           721: 
        !           722:        for (;size > 0; size-=30) {
        !           723:                
        !           724:            for (ix=30;ix;--ix) {
        !           725:                  writec((*addr++)&0xff); writes(" ");
        !           726:                }
        !           727:            NL;
        !           728:        }
        !           729: }
        !           730: 
        !           731: /*
        !           732:        Registers validation test
        !           733: */
        !           734: 
        !           735: reg_test(unit,pdata0)
        !           736: short unit;
        !           737: short *pdata0;
        !           738: {
        !           739:        register struct XRqueue *is = &aceq;
        !           740:        short ix, reg, regerr, xseg, rseg, errcode = 0;
        !           741:        char *pdata1;
        !           742: 
        !           743:        writes("2. REGISTER VALIDATION TEST------------------>");
        !           744:        NL; NL;
        !           745:        regerr = 0;
        !           746:        pdata1 = (char *)&ace_station[unit*6];
        !           747:        for (ix=0; ix < 6; ix++, pdata0++, pdata1++)
        !           748:           {
        !           749:            reg = *pdata0;
        !           750:            if ((char)(reg & 0xff)!= (char)(*pdata1 & 0xff)) {
        !           751:                regerr++;
        !           752:                }
        !           753:           }
        !           754:        for (ix=0; ix < 2; ix++, pdata0++)
        !           755:           {
        !           756:            reg = *pdata0;
        !           757:            if ((char)(reg & 0x00)) {
        !           758:                regerr++;
        !           759:                }
        !           760:           }
        !           761:        pdata1 = (char *)&ace_hash_code[unit*8];
        !           762:        for (ix=0; ix < 8; ix++, pdata0++, pdata1++)
        !           763:            {
        !           764:            reg = *pdata0;
        !           765:            if ( (char)(reg & 0xff) != (char)(*pdata1 & 0xff)) {
        !           766:                regerr++;
        !           767:                }
        !           768:             }
        !           769:        writes("RAR registers test:  ");
        !           770:        writed(regerr); writes(" error(s)\n\n");
        !           771:        writes("Transmit segment register (tseg): "); 
        !           772:        DELAY(0x2000);          /* wait for write done  */
        !           773:        reg = (short)addr->tseg;
        !           774:        DELAY(0x2000);          /* wait for data avail  */
        !           775:        xseg = (reg & 0x7800) >> 11;
        !           776:        writed(xseg); NL;
        !           777:        writes("Receive segment register  (rseg): "); 
        !           778:        DELAY(0x2000);
        !           779:        reg = (short)addr->rseg;
        !           780:        DELAY(0x2000);
        !           781:        rseg = (reg & 0x7800) >> 11;
        !           782:        writed(rseg); NL;
        !           783:        writes("Segment boundary register (segb): ");
        !           784:        DELAY(0x2000);
        !           785:        reg = (short)addr->segb;
        !           786:        DELAY(0x2000);
        !           787:        is->boundry = (reg & 0x7800) >> 11;
        !           788:        writed(is->boundry); NL;
        !           789:        if (rseg)
        !           790:           writes("\nWarning: rseg is not pointing at the 1st recv buffer");
        !           791:        if (rseg > is->boundry)
        !           792:           writes("\nWarning: rseg register > segb register");
        !           793:        if (xseg != is->boundry)
        !           794:           writes("\nWarning: tseg register <> segb register");
        !           795:        DELAY(0x10000);         /* just to take a break */
        !           796:        return(errcode);        /* good return */
        !           797: }

unix.superglobalmegacorp.com

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