00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "global.h"
00023 #include "timer.h"
00024 #include "rprintf.h"
00025
00026 #include "ax88796.h"
00027
00028
00029 #include "ax88796conf.h"
00030
00031
00032 static unsigned char NextPage;
00033 static unsigned int CurrentRetreiveAddress;
00034
00035
00036 void nicInit(void)
00037 {
00038 ax88796Init();
00039 }
00040
00041 void nicSend(unsigned int len, unsigned char* packet)
00042 {
00043 ax88796BeginPacketSend(len);
00044 ax88796SendPacketData(packet, len);
00045 ax88796EndPacketSend();
00046 }
00047
00048 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
00049 {
00050 unsigned int packetLength;
00051
00052 packetLength = ax88796BeginPacketRetreive();
00053
00054
00055 if( !packetLength )
00056 return 0;
00057
00058
00059 if( packetLength > maxlen )
00060 {
00061 ax88796EndPacketRetreive();
00062 return 0;
00063 }
00064
00065
00066 ax88796RetreivePacketData( packet, packetLength );
00067 ax88796EndPacketRetreive();
00068
00069 return packetLength;
00070 }
00071
00072 void nicGetMacAddress(u08* macaddr)
00073 {
00074 u08 tempCR;
00075
00076 tempCR = ax88796Read(CR);
00077 ax88796Write(CR,tempCR|PS0);
00078
00079 *macaddr++ = ax88796Read(PAR0);
00080 *macaddr++ = ax88796Read(PAR1);
00081 *macaddr++ = ax88796Read(PAR2);
00082 *macaddr++ = ax88796Read(PAR3);
00083 *macaddr++ = ax88796Read(PAR4);
00084 *macaddr++ = ax88796Read(PAR5);
00085
00086 ax88796Write(CR,tempCR);
00087 }
00088
00089 void nicSetMacAddress(u08* macaddr)
00090 {
00091 u08 tempCR;
00092
00093 tempCR = ax88796Read(CR);
00094 ax88796Write(CR,tempCR|PS0);
00095
00096 ax88796Write(PAR0, *macaddr++);
00097 ax88796Write(PAR1, *macaddr++);
00098 ax88796Write(PAR2, *macaddr++);
00099 ax88796Write(PAR3, *macaddr++);
00100 ax88796Write(PAR4, *macaddr++);
00101 ax88796Write(PAR5, *macaddr++);
00102
00103 ax88796Write(CR,tempCR);
00104 }
00105
00106 void nicRegDump(void)
00107 {
00108 ax88796RegDump();
00109 }
00110
00111
00112 void ax88796SetupPorts(void)
00113 {
00114 #if NIC_CONNECTION == MEMORY_MAPPED
00115
00116
00117
00118
00119
00120
00121 #else
00122
00123 AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK;
00124
00125
00126 AX88796_DATA_DDR = 0x00;
00127 AX88796_DATA_PORT = 0xFF;
00128
00129
00130 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN );
00131 sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN );
00132
00133 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN );
00134 sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN );
00135 #endif
00136
00137
00138 }
00139
00140
00141 #if NIC_CONNECTION == MEMORY_MAPPED
00142 inline void ax88796Write(u08 address, u08 data)
00143 {
00144 *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address) = data;
00145 }
00146 #else
00147 void ax88796Write(u08 address, u08 data)
00148 {
00149
00150 AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK);
00151
00152
00153 AX88796_DATA_DDR = 0xFF;
00154 AX88796_DATA_PORT = data;
00155
00156
00157 cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN);
00158 nop();
00159 nop();
00160 sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN);
00161
00162
00163 AX88796_DATA_DDR = 0x00;
00164 AX88796_DATA_PORT = 0xFF;
00165 }
00166 #endif
00167
00168
00169 #if NIC_CONNECTION == MEMORY_MAPPED
00170 inline u08 ax88796Read(u08 address)
00171 {
00172 return *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address);
00173 }
00174 #else
00175 u08 ax88796Read(u08 address)
00176 {
00177 u08 data;
00178
00179
00180 AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK);
00181
00182
00183 cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN);
00184 nop();
00185 nop();
00186
00187 data = AX88796_DATA_PIN;
00188
00189
00190 sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN);
00191
00192 return data;
00193 }
00194 #endif
00195
00196
00197 void ax88796Init(void)
00198 {
00199 unsigned char tcrFduFlag;
00200
00201
00202 ax88796SetupPorts();
00203
00204
00205
00206
00207
00208
00209
00210 ax88796Write(ISR, ax88796Read(ISR));
00211 delay_ms(50);
00212
00213
00214 ax88796Read(RSTPORT);
00215 while(ax88796Read(TR) & RST_B);
00216
00217
00218
00219 if(!(ax88796Read(TR) & AUTOD))
00220 {
00221 ax88796WriteMii(0x10,0x00,0x0800);
00222 delay_ms(2500);
00223 ax88796WriteMii(0x10,0x00,0x1200);
00224 }
00225
00226 ax88796Write(CR,(RD2|STOP));
00227 delay_ms(5);
00228 ax88796Write(DCR,DCR_INIT);
00229 ax88796Write(RBCR0,0x00);
00230 ax88796Write(RBCR1,0x00);
00231 ax88796Write(IMR,0x00);
00232 ax88796Write(ISR,0xFF);
00233 ax88796Write(RCR,0x20);
00234 ax88796Write(BNRY,RXSTART_INIT);
00235 ax88796Write(PSTART,RXSTART_INIT);
00236 ax88796Write(PSTOP,RXSTOP_INIT);
00237
00238
00239 ax88796Write(CR,(PS0|RD2|STOP));
00240
00241 ax88796Write(PAR0, AX88796_MAC0);
00242 ax88796Write(PAR1, AX88796_MAC1);
00243 ax88796Write(PAR2, AX88796_MAC2);
00244 ax88796Write(PAR3, AX88796_MAC3);
00245 ax88796Write(PAR4, AX88796_MAC4);
00246 ax88796Write(PAR5, AX88796_MAC5);
00247
00248 ax88796Write(CURR,RXSTART_INIT+1);
00249
00250 ax88796Write(CR,(RD2|START));
00251 ax88796Write(RCR,RCR_INIT);
00252
00253 if(ax88796Read(GPI) & I_SPD)
00254 tcrFduFlag = FDU;
00255 else
00256 tcrFduFlag = 0;
00257
00258 ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
00259
00260 ax88796Write(GPOC,MPSEL);
00261
00262 ax88796Write(TPSR,TXSTART_INIT);
00263
00264 ax88796Write(CR,(RD2|STOP));
00265 ax88796Write(DCR,DCR_INIT);
00266 ax88796Write(CR,(RD2|START));
00267 ax88796Write(ISR,0xFF);
00268 ax88796Write(IMR,IMR_INIT);
00269 ax88796Write(TCR,(tcrFduFlag|TCR_INIT));
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 }
00280
00281
00282 void ax88796BeginPacketSend(unsigned int packetLength)
00283 {
00284 unsigned int sendPacketLength;
00285 sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)?
00286 (packetLength):(ETHERNET_MIN_PACKET_LENGTH);
00287
00288
00289 ax88796Write(CR,(RD2|START));
00290
00291
00292 while( ax88796Read(CR) & TXP );
00293
00294
00295 ax88796Write(TPSR,TXSTART_INIT);
00296
00297
00298 ax88796Write(RSAR0,0x00);
00299 ax88796Write(RSAR1,0x40);
00300
00301
00302 ax88796Write(ISR, PTX);
00303
00304
00305 ax88796Write(RBCR0, packetLength);
00306 ax88796Write(RBCR1, packetLength>>8);
00307
00308 ax88796Write(TBCR0, sendPacketLength);
00309 ax88796Write(TBCR1, sendPacketLength>>8);
00310
00311
00312 ax88796Write(CR,(RD1|START));
00313 }
00314
00315
00316 void ax88796SendPacketData(unsigned char *localBuffer, unsigned int length)
00317 {
00318 unsigned int i;
00319
00320 for(i=0;i<length;i++)
00321 ax88796Write(RDMAPORT, localBuffer[i]);
00322 }
00323
00324
00325 void ax88796EndPacketSend(void)
00326 {
00327
00328 ax88796Write(CR,(RD2|TXP));
00329
00330
00331 ax88796Write(ISR, RDC);
00332 }
00333
00334
00335 unsigned int ax88796BeginPacketRetreive(void)
00336 {
00337 unsigned char writePagePtr;
00338 unsigned char readPagePtr;
00339 unsigned char bnryPagePtr;
00340 unsigned char i;
00341
00342 unsigned char pageheader[4];
00343 unsigned int rxlen;
00344
00345
00346 ax88796ProcessInterrupt();
00347
00348
00349 ax88796Write(CR,(PS0|RD2|START));
00350 writePagePtr = ax88796Read(CURR);
00351
00352 ax88796Write(CR,(RD2|START));
00353 bnryPagePtr = ax88796Read(BNRY);
00354
00355
00356 readPagePtr = bnryPagePtr+1;
00357 if(readPagePtr >= RXSTOP_INIT) readPagePtr = RXSTART_INIT;
00358
00359
00360 if( readPagePtr == writePagePtr )
00361 {
00362 return 0;
00363 }
00364
00365
00366 ax88796Write(ISR, PRX);
00367
00368
00369
00370 if( (bnryPagePtr < RXSTART_INIT) || (bnryPagePtr >= RXSTOP_INIT) )
00371 {
00372 ax88796Write(BNRY, RXSTART_INIT);
00373 ax88796Write(CR, (PS0|RD2|START));
00374 ax88796Write(CURR, RXSTART_INIT+1);
00375 ax88796Write(CR, (RD2|START));
00376
00377
00378 return 0;
00379 }
00380
00381
00382 ax88796Write(RBCR0, 4);
00383 ax88796Write(RBCR1, 0);
00384 ax88796Write(RSAR0, 0);
00385 ax88796Write(RSAR1, readPagePtr);
00386 ax88796Write(CR, (RD0|START));
00387 for(i=0;i<4;i++)
00388 pageheader[i] = ax88796Read(RDMAPORT);
00389
00390
00391 ax88796Write(CR, (RD2|START));
00392 for(i = 0; i <= 20; i++)
00393 if(ax88796Read(ISR) & RDC)
00394 break;
00395 ax88796Write(ISR, RDC);
00396
00397 rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL];
00398 NextPage = pageheader[PKTHEADER_NEXTPAGE];
00399
00400 CurrentRetreiveAddress = (readPagePtr<<8) + 4;
00401
00402
00403 if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) )
00404 {
00405
00406
00407 return 0;
00408 }
00409
00410 return rxlen-4;
00411 }
00412
00413
00414 void ax88796RetreivePacketData(unsigned char * localBuffer, unsigned int length)
00415 {
00416 unsigned int i;
00417
00418
00419 ax88796Write(RBCR0, (unsigned char)length);
00420 ax88796Write(RBCR1, (unsigned char)(length>>8));
00421 ax88796Write(RSAR0, (unsigned char)CurrentRetreiveAddress);
00422 ax88796Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8));
00423 ax88796Write(CR, (RD0|START));
00424 for(i=0;i<length;i++)
00425 localBuffer[i] = ax88796Read(RDMAPORT);
00426
00427
00428 ax88796Write(CR, (RD2|START));
00429 for(i = 0; i <= 20; i++)
00430 if(ax88796Read(ISR) & RDC)
00431 break;
00432 ax88796Write(ISR, RDC);
00433
00434 CurrentRetreiveAddress += length;
00435 if( CurrentRetreiveAddress >= 0x6000 )
00436 CurrentRetreiveAddress -= (0x6000-0x4600) ;
00437 }
00438
00439
00440 void ax88796EndPacketRetreive(void)
00441 {
00442 unsigned char i;
00443 unsigned char bnryPagePtr;
00444
00445
00446 ax88796Write(CR, (RD2|START));
00447 for(i = 0; i <= 20; i++)
00448 if(ax88796Read(ISR) & RDC)
00449 break;
00450 ax88796Write(ISR, RDC);
00451
00452
00453
00454 bnryPagePtr = NextPage-1;
00455 if(bnryPagePtr < RXSTART_INIT) bnryPagePtr = RXSTOP_INIT-1;
00456
00457 ax88796Write(BNRY, bnryPagePtr);
00458 }
00459
00460
00461 void ax88796ProcessInterrupt(void)
00462 {
00463 unsigned char intr = ax88796Read(ISR);
00464
00465
00466 if( intr & OVW )
00467 ax88796ReceiveOverflowRecover();
00468 }
00469
00470
00471 void ax88796ReceiveOverflowRecover(void)
00472 {
00473
00474
00475
00476 unsigned char cmdReg;
00477 unsigned char resend=0;
00478
00479
00480 cmdReg = ax88796Read(CR);
00481
00482 ax88796Write(CR, (RD2|STOP));
00483
00484 delay_ms(2);
00485
00486 ax88796Write(RBCR0, 0x00);
00487 ax88796Write(RBCR1, 0x00);
00488
00489
00490 if(cmdReg & TXP)
00491 {
00492
00493 cmdReg = ax88796Read(ISR);
00494 if((cmdReg & PTX) || (cmdReg & TXE))
00495 resend = 0;
00496 else
00497 resend = 1;
00498 }
00499
00500 ax88796Write(TCR, LB0);
00501
00502 ax88796Write(CR, (RD2|START));
00503
00504 ax88796Write(BNRY, RXSTART_INIT);
00505
00506 ax88796Write(CR, (PS0|RD2|START));
00507
00508 ax88796Write(CPR, RXSTART_INIT+1);
00509
00510 ax88796Write(CR, (RD2|START));
00511
00512 ax88796Write(ISR, OVW);
00513
00514 ax88796Write(TCR, TCR_INIT);
00515
00516
00517 if(resend)
00518 ax88796Write(CR, (RD2|TXP|START));
00519
00520
00521 }
00522
00523
00524 #define set_mdc ax88796Write(MEMR,ax88796Read(MEMR)|0x01);
00525 #define clr_mdc ax88796Write(MEMR,ax88796Read(MEMR)&0xFE);
00526
00527 #define mii_clk set_mdc; clr_mdc;
00528
00529 #define set_mdir ax88796Write(MEMR,ax88796Read(MEMR)|0x02);
00530 #define clr_mdir ax88796Write(MEMR,ax88796Read(MEMR)&0xFD);
00531
00532 #define set_mdo ax88796Write(MEMR,ax88796Read(MEMR)|0x08)
00533 #define clr_mdo ax88796Write(MEMR,ax88796Read(MEMR)&0xF7)
00534
00535 #define mii_write clr_mdo; mii_clk; \
00536 set_mdo; mii_clk; \
00537 clr_mdo; mii_clk; \
00538 set_mdo; mii_clk;
00539
00540 #define mii_read clr_mdo; mii_clk; \
00541 set_mdo; mii_clk; \
00542 set_mdo; mii_clk; \
00543 clr_mdo; mii_clk;
00544
00545 #define mii_r_ta mii_clk; mii_clk;
00546
00547 #define mii_w_ta set_mdo; mii_clk; \
00548 clr_mdo; mii_clk;
00549
00550 void ax88796WriteMii(unsigned char phyad,unsigned char regad,unsigned int mii_data)
00551 {
00552 unsigned char mask8;
00553 unsigned int i,mask16;
00554
00555 clr_mdir;
00556 mii_write;
00557
00558 mask8 = 0x10;
00559 for(i=0;i<5;++i)
00560 {
00561 if(mask8 & phyad)
00562 set_mdo;
00563 else
00564 clr_mdo;
00565 mii_clk;
00566 mask8 >>= 1;
00567 }
00568 mask8 = 0x10;
00569 for(i=0;i<5;++i)
00570 {
00571 if(mask8 & regad)
00572 set_mdo;
00573 else
00574 clr_mdo;
00575 mii_clk;
00576 mask8 >>= 1;
00577 }
00578 mii_w_ta;
00579
00580 mask16 = 0x8000;
00581 for(i=0;i<16;++i)
00582 {
00583 if(mask16 & mii_data)
00584 set_mdo;
00585 else
00586 clr_mdo;
00587 mii_clk;
00588 mask16 >>= 1;
00589 }
00590 }
00591
00592 unsigned int ax88796ReadMii(unsigned char phyad,unsigned char regad)
00593 {
00594 unsigned char mask8,i;
00595 unsigned int mask16,result16;
00596
00597 clr_mdir;
00598 mii_read;
00599
00600 mask8 = 0x10;
00601 for(i=0;i<5;++i)
00602 {
00603 if(mask8 & phyad)
00604 set_mdo;
00605 else
00606 clr_mdo;
00607 mii_clk;
00608 mask8 >>= 1;
00609 }
00610 mask8 = 0x10;
00611 for(i=0;i<5;++i)
00612 {
00613 if(mask8 & regad)
00614 set_mdo;
00615 else
00616 clr_mdo;
00617 mii_clk;
00618 mask8 >>= 1;
00619 }
00620
00621 set_mdir;
00622 mii_r_ta;
00623
00624 mask16 = 0x8000;
00625 result16 = 0x0000;
00626 for(i=0;i<16;++i)
00627 {
00628 if(ax88796Read(MEMR) & 0x04)
00629 {
00630 result16 |= mask16;
00631 }
00632 else
00633 {
00634 asm volatile ("nop");
00635
00636 }
00637 mii_clk;
00638 mask16 >>= 1;
00639 }
00640 return result16;
00641 }
00642
00643
00644 void ax88796RegDump(void)
00645 {
00646 unsigned char result;
00647 result = ax88796Read(TR);
00648
00649 rprintf("Media State: ");
00650 if(!(result & AUTOD))
00651 rprintf("Autonegotiation\r\n");
00652 else if(result & RST_B)
00653 rprintf("PHY in Reset \r\n");
00654 else if(!(result & RST_10B))
00655 rprintf("10BASE-T \r\n");
00656 else if(!(result & RST_TXB))
00657 rprintf("100BASE-T \r\n");
00658
00659
00660
00661
00662
00663 rprintfProgStrM("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n");
00664 rprintfProgStrM(" ");
00665 rprintfu08(ax88796Read(CR));
00666 rprintfProgStrM(" ");
00667 rprintfu08(ax88796Read(BNRY));
00668 rprintfProgStrM(" ");
00669 rprintfu08(ax88796Read(PSTART));
00670 rprintfProgStrM(" ");
00671 rprintfu08(ax88796Read(PSTOP));
00672 rprintfProgStrM(" ");
00673 rprintfu08(ax88796Read(ISR));
00674 rprintfProgStrM(" ");
00675 rprintfu08(ax88796Read(TSR));
00676 rprintfProgStrM(" ");
00677 rprintfu08(ax88796Read(RSR));
00678 rprintfProgStrM(" ");
00679 rprintfu08(ax88796Read(MEMR));
00680 rprintfProgStrM(" ");
00681 rprintfu08(ax88796Read(TR));
00682 rprintfProgStrM(" ");
00683 rprintfu08(ax88796Read(GPI));
00684 rprintfCRLF();
00685
00686 ax88796Write(CR,ax88796Read(CR)|PS0);
00687
00688 rprintf("Page1: CR PAR CPR\r\n");
00689 rprintfProgStrM(" ");
00690 rprintfu08(ax88796Read(CR));
00691 rprintfProgStrM(" ");
00692 rprintfChar(ax88796Read(PAR0));
00693 rprintfChar(ax88796Read(PAR1));
00694 rprintfChar(ax88796Read(PAR2));
00695 rprintfChar(ax88796Read(PAR3));
00696 rprintfChar(ax88796Read(PAR4));
00697 rprintfChar(ax88796Read(PAR5));
00698 rprintfProgStrM(" ");
00699 rprintfu08(ax88796Read(CPR));
00700
00701 ax88796Write(CR,ax88796Read(CR)&~PS0);
00702
00703 delay_ms(25);
00704 }
00705
00706 void ax88796PhyDump(void)
00707 {
00708 rprintfProgStrM("----- AX88796 PHY INFO -----\r\n");
00709 rprintfProgStrM("MR 0 (Control) = 0x"); rprintfu16( ax88796ReadMii(0x10, 0) ); rprintfCRLF();
00710 rprintfProgStrM("MR 1 (Status) = 0x"); rprintfu16( ax88796ReadMii(0x10, 1) ); rprintfCRLF();
00711 rprintfProgStrM("MR 2 (PHY ID1) = 0x"); rprintfu16( ax88796ReadMii(0x10, 2) ); rprintfCRLF();
00712 rprintfProgStrM("MR 3 (PHY ID2) = 0x"); rprintfu16( ax88796ReadMii(0x10, 3) ); rprintfCRLF();
00713 rprintfProgStrM("MR 4 (AutoNeg Adv) = 0x"); rprintfu16( ax88796ReadMii(0x10, 4) ); rprintfCRLF();
00714 rprintfProgStrM("MR 5 (AutoNeg Abil) = 0x"); rprintfu16( ax88796ReadMii(0x10, 5) ); rprintfCRLF();
00715 rprintfProgStrM("MR 6 (AutoNeg Exp) = 0x"); rprintfu16( ax88796ReadMii(0x10, 6) ); rprintfCRLF();
00716 rprintfProgStrM("MR 7 (NextPg Tx) = 0x"); rprintfu16( ax88796ReadMii(0x10, 7) ); rprintfCRLF();
00717 rprintfProgStrM("MR16 (PCS Ctrl) = 0x"); rprintfu16( ax88796ReadMii(0x10,16) ); rprintfCRLF();
00718 rprintfProgStrM("MR17 (AutoNeg RegA) = 0x"); rprintfu16( ax88796ReadMii(0x10,17) ); rprintfCRLF();
00719 rprintfProgStrM("MR18 (AutoNeg RegB) = 0x"); rprintfu16( ax88796ReadMii(0x10,18) ); rprintfCRLF();
00720 rprintfProgStrM("MR19 (Analog Test) = 0x"); rprintfu16( ax88796ReadMii(0x10,19) ); rprintfCRLF();
00721 rprintfProgStrM("MR21 (RXERR count) = 0x"); rprintfu16( ax88796ReadMii(0x10,21) ); rprintfCRLF();
00722 rprintfProgStrM("MR28 (Status Reg) = 0x"); rprintfu16( ax88796ReadMii(0x10,28) ); rprintfCRLF();
00723 rprintfProgStrM("MR29 (100Mbs Ctrl) = 0x"); rprintfu16( ax88796ReadMii(0x10,29) ); rprintfCRLF();
00724 rprintfProgStrM("MR30 (10Mbs Ctrl) = 0x"); rprintfu16( ax88796ReadMii(0x10,30) ); rprintfCRLF();
00725 rprintfProgStrM("MR31 (Quick Status) = 0x"); rprintfu16( ax88796ReadMii(0x10,31) ); rprintfCRLF();
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747