📄 drv_8019.c
字号:
next_frame = ethernet_8390_hdr[1];
/* This _should_ never happen: it's here for avoiding bad clones. */
if (next_frame >= RX_STOP_PG) { /* next frame inconsistency */
next_frame = RX_START_PG;
}
current_page = next_frame;
EN0_BOUNDARY = next_frame-1;
}
/* We used to also ack ENISR_OVER here, but that would sometimes mask
a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
EN0_ISR = ENISR_RX+ENISR_RX_ERR;
}
//void ei_input(byte *buf, word StartAddr, word Count)
void ei_input(byte *buf, word StartAddr, word Count) reentrant
{
word loop;
EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
/* Set Remote byte count */
EN0_RCNTLO = (byte)(Count & 0xff); /* Low byte of tx byte count */
EN0_RCNTHI = (byte)(Count >> 8); /* High byte of tx byte count Transmit byte count register */
/* Set Remote Start Address */
EN0_RSARLO = (byte)(StartAddr & 0xff); /*LSB Remote start address reg */
EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
for(loop=0;loop < Count;loop++){
*buf++ = EN_DATA;
}
EN0_ISR = ENISR_RDC; /* Ack intr. to Remote DMA */
}
//void ethernet_get_8390_hdr( word StartAddr, word Count)
void ethernet_get_8390_hdr( word StartAddr, word Count) reentrant
{
word loop;
EN_CMD = EN_PAGE0 + EN_RREAD + EN_START;
/* Set Remote byte count */
EN0_RCNTLO = (byte)(Count & 0xff); /* Low byte of tx byte count */
EN0_RCNTHI = (byte)(Count >> 8); /* High byte of tx byte count Transmit byte count register */
/* Set Remote Start Address */
EN0_RSARLO = (byte)(StartAddr & 0xff); /*LSB Remote start address reg */
EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
EN_CMD = EN_PAGE0 + EN_RREAD + EN_START; /* Remote Read, Start the chip, clear reset */
for(loop=0;loop < Count;loop++){
ethernet_8390_hdr[loop] = EN_DATA;
}
EN0_ISR = ENISR_RDC; /* Ack intr. to Remote DMA */
}
void ei_rx_overrun( void )
{
byte was_txing, must_resend = 0;
//print_int("OVER");
/* Record whether a Tx was in progress
and then issue the stop command. */
was_txing = EN_CMD & EN_TRANS;
EN_CMD = EN_NODMA + EN_PAGE0 + EN_STOP;
delay_1ms(2); /* I don't know exactly time yet.. at least 2ms */
/** Reset RBCR[01] back to zero as per magic incantation. */
EN0_RCNTLO = 0x00;
EN0_RCNTHI = 0x00;
/* See if any Tx was interrupted or not. According to NS, this
step is vital, and skipping it will cause no end of havoc. */
if (was_txing) {
if (!(EN0_ISR & (ENISR_TX + ENISR_TX_ERR))) must_resend = 1;
}
/* Have to enter loopback mode and then restart the NIC before
you are allowed to slurp packets up off the ring. */
EN0_TXCR = E8390_TXOFF;
EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
/* Clear the Rx ring of all the debris(颇祈), and ack the interrupt. */
ei_receive();
EN0_ISR = ENISR_OVER;
/* Leave loopback mode, and resend any packet that got stopped. */
EN0_TXCR = E8390_TXCONFIG;
if (must_resend) EN_CMD = EN_NODMA + EN_PAGE0 + EN_START + EN_TRANS;
}
void ethernet_register_test(void) /* All Register test */
{
byte i,read,write;
print("\n\r------------------------------------------------------------------------");
print("\n\rAddr Page0 Page1 Page2 Page3");
print("\n\r Write/Read Write/Read Write/Read Write/Read");
print("\n\r------------------------------------------------------------------------");
for (i=0; i < 16; i++) {
/* Page0 select */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
print("\n\r"); putb_ser(i);print(" ");
write = EN_PAGE0 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write);
print(" "); read = inportb(i);
putb_ser(read); print(" ");
/* Page1 select */
EN_CMD = EN_PAGE1 + EN_NODMA + EN_START;
write = EN_PAGE1 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write); print(" ");
read = inportb(i);
putb_ser(read); print(" ");
/* Page2 select */
EN_CMD = EN_PAGE2 + EN_NODMA + EN_START;
print("x ");
read = inportb(i);
putb_ser(read); print(" ");
/* Page3 select */
EN_CMD = EN_PAGE3 + EN_NODMA + EN_START;
write = EN_PAGE3 + EN_NODMA + EN_START;
/* outportb(i,write); */
putb_ser(write);
print(" ");
read = inportb(i);
putb_ser(read); print(" ");
}
print("\n\r------------------------------------------------------------------------\n\r");
}
//*****************************************************************************/
//* D M A Write */
//*****************************************************************************/
void DMA_write(byte *buffer, word StartAddr, word Count)
{
word loop;
//print("\n\rDMA write : ");
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START; /* Remote DMA, Start the chip, clear reset */
EN0_RCNTLO = (byte)(Count & 0xff); /* LSB Remote byte count reg */
EN0_RCNTHI = (byte)(Count >> 8); /* MSB Remote byte count reg */
EN0_RSARLO = (byte)(StartAddr & 0xff); /* LSB Remote start address reg */
EN0_RSARHI = (byte)(StartAddr >> 8); /* MSB Remote start address reg */
EN_CMD = EN_PAGE0 + EN_RWRITE + EN_START; /* Remote Write, Start the chip, clear reset */
for(loop=0;loop < Count;loop++){
EN_DATA = *buffer++;
//putb_ser(*buffer++);
}
}
/*****************************************************************************/
/* D M A Read */
/*****************************************************************************/
void ethernet_test(void)
{
byte temp1,temp2;
print("\n\n\r/*****************************************************************/\n\r");
print("/* RTL8019AS TEST ROUTINE 0.5.2 */\n\r");
print("/* If you see 0x50 and 0x70 or 'P' and 'p', it operate well */\n\r");
print("/*****************************************************************/\n\r");
temp1 = EN0_8019ID0; /* EN0_8019ID0 */
temp2 = EN0_8019ID1; /* EN0_8019ID1 */
putb_ser(temp1);
putb_ser(temp2);
if ((temp1 != 0x50)|(temp2 != 0x70)) {
print(" Circuit have H/W problem.\n\r");
}
print(" Circuit OK!\n\r");
#ifdef STRING_TEST
test = 0x1234;
printf("\n\n\r%x %d ",test,test);
putb_ser(test);
test1 = (byte)test;
printf("\n\n\r%x %d ",test1,test1);
#endif
}
/*****************************************************************************/
/* RTL8019AS Initialize */
/*****************************************************************************/
void ethernet_init(void)
{
word i;
#ifdef RTL8019AS_ID_CHECK
ethernet_test();
#endif
EN_RESET = 0x00; /* very important !!!!! */
for (i=0;i<DELAY;i++);
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_BOS; /* ?FIFO treshold 8byte !!,normal operation, byte transfer mode selection */
/* Clear the remote byte count registers. */
EN0_RCNTHI = 0x00; /* MSB remote byte count reg */
EN0_RCNTLO = 0x00; /* LSB remote byte count reg */
EN0_RXCR = E8390_RXOFF; /* RX configuration reg Monitor mode (no packet receive) */
EN0_TXCR = E8390_TXOFF; /* TX configuration reg set internal loopback mode */
EN0_TPSR = NE_START_PG;
EN0_STARTPG = RX_START_PG ; /* 菩哦 荐脚矫俊 肺拿 DMA啊 荐脚窍绰 其捞瘤甫 瘤沥茄促. 46h */
/* Starting page of ring buffer. First page of Rx ring buffer 46h*/
EN0_BOUNDARY = RX_START_PG; /* Boundary page of ring buffer */
EN0_STOPPG = NE_STOP_PG; /* Ending page +1 of ring buffer */
EN_CMD = EN_PAGE1 + EN_NODMA + EN_STOP;
EN1_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */
current_page = RX_START_PG + 1; /* assert boundary+1 */
next_pkt = RX_START_PG + 1;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP;
EN0_ISR = 0xff; /* INTerrupt stauts reg */
/* Host绰 牢磐反飘甫 老栏虐绰 巴阑 茫酒郴扁困秦 佬绰促.
阿 厚飘绰 包访等 bit俊 1阑 结 持澜栏肺辑 努府绢 等促.
弊巴篮 颇况诀 饶俊 馆靛矫 努府绢 登绢具茄促.(must) */
EN0_IMR = 0; /* INTerrupt mask reg = Disable all Interrupt */
EN_CMD = EN_NODMA + EN_PAGE1 + EN_STOP; /* Select page 1, remote DMA */
EN1_PAR0 = 0x12;
EN1_PAR1 = 0x34;
EN1_PAR2 = 0x56;
EN1_PAR3 = 0x78;
EN1_PAR4 = 0x9A;
EN1_PAR5 = 0xBC;
/* Initialize the multicast list to accept-all. If we enable multicast
the higher levels can do the filtering. multicast filter mask array (8 bytes) */
EN1_MAR0 = 0xff;
EN1_MAR1 = 0xff;
EN1_MAR2 = 0xff;
EN1_MAR3 = 0xff;
EN1_MAR4 = 0xff;
EN1_MAR5 = 0xff;
EN1_MAR6 = 0xff;
EN1_MAR7 = 0xff;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
EN0_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */
/* It must be cleared after power up. */
EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
EN0_TXCR = ENTXCR_TXCONFIG; /* xmit on. */
/* 3c503 TechMan says rxconfig only after the NIC is started. */
EN0_RXCR = ENRXCR_RXCONFIG; /* rx on(broadcasts, no multicast,errors */
CONFIG1 = 0x90; /* IRQ enable + INT0:IRQ2/9(pin 4) + I/O BASE(300H) */
CONFIG2 = 0x00;
CONFIG3 = 0xf0;
CONFIG4 = 0x00;
EthRxBufRdPtr = 0;
EthRxBufWrPtr = EthRxBufRdPtr + 1;
EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -