|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.