📄 if_ne2kd.c
字号:
{ DISABLE_INTERRUPTS; // Copy statistics to caller memcpy(statistics, &Statistics, sizeof(Statistics)); ENABLE_INTERRUPTS;}static int ReadBuffer(BufferHeader *header, u_char *packet, u_short length){ u_char Save_curr; Word Word; int OddLength; int Count = 0;// printf("ReadBuffer(header=%p,packet=%p,length=%d)\n",header,packet,length); // ***** IF packet pointer = NULL THEN length = 0 if (!packet) length = 0; // ***** Clear REMOTE DMA COMPLETE bit in ISR OUTPORTB(PG0W_ISR, ISR_RDC); PAUSE; // ***** Make length an even value OddLength = length & 0x0001; length++; length &= 0xfffe; // ***** Read CURR // Read Current Page of rcv ring // Go to page 1 OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE1); PAUSE; // Read CURR Save_curr = INPORTB(PG1R_CURR); PAUSE; // Go to page 0 OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE0); PAUSE;// printf("NextPacket=%x Save_curr=%x\n",NextPacket,Save_curr); // ***** LOOP WHILE CURR <> NextPacket - While we have a packet in buffer while (Save_curr != NextPacket) {// printf("NextPacket=%x, setting up DMA read\n",NextPacket); // Setup Remote Byte Counts and Remote Start Address to read length + 4 bytes for buffer header OUTPORTB(PG0W_RSAR0, 0); PAUSE; OUTPORTB(PG0W_RSAR1, NextPacket); PAUSE; OUTPORTB(PG0W_RBCR0, (length + 4) & 0xFF); PAUSE; OUTPORTB(PG0W_RBCR1, ((length + 4) >> 8) & 0xFF); PAUSE; // ***** Issue the Remote Read command OUTPORTB(NIC_CR, CR_START | CR_DMA_READ); PAUSE; // ***** Read buffer header (4 bytes)*/ Word.Word = INPORTW(NIC_DATAPORT); header->Status = Word.Uchar[0]; header->NextPage = Word.Uchar[1]; Word.Word = INPORTW(NIC_DATAPORT); header->Length= (Word.Uchar[1]<<8)|Word.Uchar[0]; //header->Length = INPORTW(NIC_DATAPORT);// printf("header->Status=%x\n",header->Status);// printf("header->NextPage=%x\n",header->NextPage);// printf("header->Length=%x\n",header->Length); if (length) {// printf("reading packet (length=%d)\n",length); for (Count = 0; Count < (length - 2); Count+=2) { Word.Word = INPORTW(NIC_DATAPORT);// printf("0x%x\n",Word.Word); packet[Count] = Word.Uchar[0]; packet[Count+1] = Word.Uchar[1]; // The line below might very well be a bit faster... // *((u_short *)(packet+Count)) = INPORTW(NIC_DATAPORT); } Word.Word = INPORTW(NIC_DATAPORT); } // ***** Stop REMOTE DMA OUTPORTB(NIC_CR, CR_START | CR_NO_DMA); PAUSE; if (length) {// printf("reading odd trailing byte\n"); packet[Count] = Word.Uchar[0]; if (!OddLength) packet[Count+1] = Word.Uchar[1]; } // Clear REMOTE DMA COMPLETE bit in ISR OUTPORTB(PG0W_ISR, ISR_RDC); PAUSE;// printf("RSTART_PG=%d RSTOP_PG=%d\n",RSTART_PG,RSTOP_PG); // ***** IF next page pointer is out of receive buffer range THEN // We have a serious problem if ( (header->NextPage < RSTART_PG) || (header->NextPage > RSTOP_PG) ) { // ***** Initialize NextPacket pointer to last known good value of the Current (write) Pointer. // This means that we drop a lot of packets, but beats winding up in the weeds! NextPacket = Save_curr; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = PSTOP - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE;// printf("page error\n"); // ***** This will drop a lot of packets! Count this error! Statistics.NextPageErrors++; } else {// printf("checking header status %x\n",header->Status); // ***** Packets should always be OK, but you never know // (the NIC is configured to only store valid packets) // ***** IF status field is OK (valid packet) THEN RETURN length if (header->Status & RSR_PRX) { return header->Length - 4; } else { // ***** Discard packet in receive buffer // ***** Set NextPacket to next page pointer NextPacket = header->NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP - 1 // (drops invalid packet) if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; } } }// printf("no packets in buffer?\n"); // ***** No valid packets in buffer, RETURN FALSE return FALSE;}/** * Read NE2K ring buffer data into an NBuf chain */static NBuf *ReadBufferNBuf(BufferHeader *header, u_short length){ u_char Save_curr; Word Word; int OddLength; int Count = 0,countNBuf; NBuf *curNBuf,*head; //printf("ReadBufferNBuf(header=%p,length=%d)\n",header,length); // ***** Clear REMOTE DMA COMPLETE bit in ISR OUTPORTB(PG0W_ISR, ISR_RDC); PAUSE; // ***** Make length an even value OddLength = length & 0x0001; length++; length &= 0xfffe; // ***** Read CURR // Read Current Page of rcv ring // Go to page 1 OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE1); PAUSE; // Read CURR Save_curr = INPORTB(PG1R_CURR); PAUSE; // Go to page 0 OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE0); PAUSE;// printf("NextPacket=%x Save_curr=%x\n",NextPacket,Save_curr); // ***** LOOP WHILE CURR <> NextPacket - While we have a packet in buffer while (Save_curr != NextPacket) {// printf("NextPacket=%x, setting up DMA read\n",NextPacket); // Setup Remote Byte Counts and Remote Start Address to read length + 4 bytes for buffer header OUTPORTB(PG0W_RSAR0, 0); PAUSE; OUTPORTB(PG0W_RSAR1, NextPacket); PAUSE; OUTPORTB(PG0W_RBCR0, (length + 4) & 0xFF); PAUSE; OUTPORTB(PG0W_RBCR1, ((length + 4) >> 8) & 0xFF); PAUSE; // ***** Issue the Remote Read command OUTPORTB(NIC_CR, CR_START | CR_DMA_READ); PAUSE; // ***** Read buffer header (4 bytes)*/ Word.Word = INPORTW(NIC_DATAPORT); header->Status = Word.Uchar[0]; header->NextPage = Word.Uchar[1]; Word.Word = INPORTW(NIC_DATAPORT); header->Length= (Word.Uchar[1]<<8)|Word.Uchar[0];// printf("header->Status=%x\n",header->Status);// printf("header->NextPage=%x\n",header->NextPage);// printf("header->Length=%x\n",header->Length);// printf("reading packet (length=%d)\n",length); do{ nGET(curNBuf); }while(!curNBuf); countNBuf=0; curNBuf->len = 0; curNBuf->nextBuf = NULL; head=curNBuf; head->chainLen=length; head->nextChain=NULL; for (Count = 0; Count<(length - 2); Count+=2) { Word.Word = INPORTW(NIC_DATAPORT);// printf("0x%x\n",Word.Word); if(countNBuf<NBUFSZ-1) { curNBuf->data[countNBuf++]=Word.Uchar[0]; curNBuf->data[countNBuf++]=Word.Uchar[1]; curNBuf->len+=2; }else{ do{ nGET(curNBuf->nextBuf); }while(!curNBuf->nextBuf); curNBuf=curNBuf->nextBuf; curNBuf->nextBuf=NULL; curNBuf->data[0]=Word.Uchar[0]; curNBuf->data[1]=Word.Uchar[1]; curNBuf->len=2; countNBuf=2; } } Word.Word = INPORTW(NIC_DATAPORT); if(countNBuf<NBUFSZ) { curNBuf->data[countNBuf++]=Word.Uchar[0]; curNBuf->len++; }else{ do{ nGET(curNBuf->nextBuf); }while(!curNBuf->nextBuf); curNBuf=curNBuf->nextBuf; curNBuf->nextBuf=NULL; curNBuf->data[0]=Word.Uchar[0]; curNBuf->len=1; countNBuf=1; } Count++; if (!OddLength) { Count++; if(countNBuf<NBUFSZ) { curNBuf->data[countNBuf]=Word.Uchar[1]; curNBuf->len++; }else{ do{ nGET(curNBuf->nextBuf); }while(!curNBuf->nextBuf); curNBuf=curNBuf->nextBuf; curNBuf->nextBuf=NULL; curNBuf->data[0]=Word.Uchar[1]; curNBuf->len=1; } } // ***** Stop REMOTE DMA OUTPORTB(NIC_CR, CR_START | CR_NO_DMA); PAUSE; // Clear REMOTE DMA COMPLETE bit in ISR OUTPORTB(PG0W_ISR, ISR_RDC); PAUSE;// printf("RSTART_PG=%d RSTOP_PG=%d\n",RSTART_PG,RSTOP_PG); // ***** IF next page pointer is out of receive buffer range THEN // We have a serious problem if ( (header->NextPage < RSTART_PG) || (header->NextPage > RSTOP_PG) ) { // ***** Initialize NextPacket pointer to last known good value of the Current (write) Pointer. // This means that we drop a lot of packets, but beats winding up in the weeds! NextPacket = Save_curr; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = PSTOP - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE;// printf("ReadBufferNBuf:page error\n"); // ***** This will drop a lot of packets! Count this error! Statistics.NextPageErrors++; }else{// printf("checking header status %x\n",header->Status); // ***** Packets should always be OK, but you never know // (the NIC is configured to only store valid packets) // ***** IF status field is OK (valid packet) THEN RETURN length if (header->Status & RSR_PRX) { head->chainLen=head->len; return head; }else{ // ***** Discard packet in receive buffer // ***** Set NextPacket to next page pointer NextPacket = header->NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP - 1 // (drops invalid packet) if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; nFreeChain(head); } } } // ***** No valid packets in buffer, RETURN NULL return NULL;}static u_char Ne2kStart(void){ return Ne2kInitialize(NULL);}static u_char statistics(if_statistics* pStats){ return FALSE;}static void ProcessISQ(Interface* pInterface){}Interface *ne2kEthInterface;extern NBuf *Ne2kRxPacket(void);u_char Ne2k_DriverEntry(Interface* pInterface){ pInterface->start = Ne2kStart; pInterface->stop = Ne2kStop; pInterface->receive = Ne2kRxPacket; pInterface->receive_ready = Ne2kReceiveReady; pInterface->transmit = Ne2kTxPacket; pInterface->transmit_ready = Ne2kTransmitReady; pInterface->statistics = statistics; pInterface->interrupt = ProcessISQ; ne2kEthInterface=pInterface; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -