📄 if_ne2kd.c
字号:
// ***** Enable interrupts from NIC (set IMR) OUTPORTB(PG0W_IMR, IMR); // If new or pending interrupts from NIC they should be generated here PAUSE;}u_short Ne2kReceiveReady(void){ BufferHeader Header; u_char Imr; // ***** Remember NIC IMR and disable interrupt from NIC (ATOMIC OPERATION!) DISABLE_INTERRUPTS; // Select PAGE 2 OUTPORTB(NIC_CR, CR_PAGE2 | CR_NO_DMA | CR_START); PAUSE; // Read IMR register Imr = INPORTB(PG2R_IMR); PAUSE; // Select PAGE 0 again OUTPORTB(NIC_CR, CR_PAGE0 | CR_NO_DMA | CR_START); PAUSE; // Disable interrupts from NIC OUTPORTB(PG0W_IMR, 0x00); PAUSE; ENABLE_INTERRUPTS; // ***** Read the NIC packet header which is 4 bytes // ***** IF ReadBuffer(header, NULL, 0) THEN if (ReadBuffer(&Header, NULL, 0)) { // ***** Restore NIC IMR OUTPORTB(PG0W_IMR, Imr); PAUSE; // ***** RETURN packet length field in header - 4 (we don't want to count buffer header) return Header.Length - 4; } // ***** Restore NIC IMR OUTPORTB(PG0W_IMR, Imr); PAUSE; // ***** No packets in buffer // ***** RETURN FALSE return FALSE;}int Ne2kReceive(u_char *packet, u_short length){ int Success, Resend, TxpBit; u_short PacketLength; u_char Imr; BufferHeader Header;// printf("Ne2kReceive\n"); // Sanity check parameters if (packet) PacketLength = length; else PacketLength = 0;// printf("PacketLength=%d\n",PacketLength); // ***** IF length > 1514 THEN RETURN FALSE if (PacketLength > 1514) return FALSE; // ***** Remember NIC IMR and disable interrupt from NIC (ATOMIC OPERATION!) DISABLE_INTERRUPTS; // Select PAGE 2 OUTPORTB(NIC_CR, CR_PAGE2 | CR_NO_DMA | CR_START); PAUSE; // Read IMR register Imr = INPORTB(PG2R_IMR); PAUSE; // Select PAGE 0 again OUTPORTB(NIC_CR, CR_PAGE0 | CR_NO_DMA | CR_START); PAUSE; // Disable interrupts from NIC OUTPORTB(PG0W_IMR, 0x00); PAUSE; ENABLE_INTERRUPTS; // ***** Success = FALSE; Success = FALSE; Resend = FALSE; // ***** IF NIC buffer overwrite warning THEN if (INPORTB(PG0R_ISR) & ISR_OVW) { PAUSE; printf("overwrite\n"); // ***** Update statistics Statistics.OverrunErrors++; // *********************************************************************************** // ***** The following buffer ring overflow procedure is taken from the datasheet // ***** DP8390D/NS32490D NIC Network Interface Controller (July 1995) from National // ***** Semiconductor. This procedure is mandatory! // ***** 1. Read and store the value of the TXP bit (from command register) TxpBit = (INPORTB(NIC_CR) & CR_TXP); PAUSE; // ***** 2. Issue a stop command OUTPORTB(NIC_CR, CR_STOP | CR_NO_DMA | CR_PAGE0); PAUSE; // ***** 3. Wait for at least 1.6 ms LONGPAUSE; // ***** 4. Clear NIC's Remote Byte Count registers (RBCR0 and RBCR1) OUTPORTB(PG0W_RBCR0, 0x00); PAUSE; OUTPORTB(PG0W_RBCR1, 0x00); PAUSE; // ***** 5. Read the stored value of the TXP bit from step 1 (determine if we stopped the NIC // ***** when it was transmitting). // ***** IF TXP bit = 1 THEN if (TxpBit) // ***** IF PTX = 1 OR TXE = 1 THEN if (INPORTB(PG0R_ISR) & (ISR_PTX | ISR_TXE)) { PAUSE; // ***** Resend = FALSE Resend = FALSE; } else { PAUSE; // ***** Resend = TRUE Resend = TRUE; } else // ***** Resend = FALSE Resend = FALSE; // ***** 6. Place the NIC in mode 1 (internal loopback) OUTPORTB(PG0W_TCR, TCR_LB0); PAUSE; // ***** 7. Start the NIC OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE0); PAUSE; } else PAUSE; // ***** 8. Remove one or more packets from the NIC // ***** IF (packet = NULL) OR (length = 0) THEN - Just remove one packet from the receive buffer ring if (!PacketLength) { // ***** IF ReadBuffer(header, NULL, 0) THEN if (ReadBuffer(&Header, NULL, 0)) { // ***** Remove packet! // ***** NextPacket = Header.NextPage; NextPacket = Header.NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP_PG - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; // ***** Success = TRUE Success = TRUE; // ***** Update statistics Statistics.BytesReceived += Header.Length - 4; Statistics.PacketsReceived++; }else{// printf("ReadBuffer failled???\n"); } } else { // ***** IF ReadBuffer(header, packet, length) THEN if (ReadBuffer(&Header, packet, PacketLength)) { // ***** Remove packet! // ***** NextPacket = Header.NextPage; NextPacket = Header.NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP_PG - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; // ***** Success = TRUE Success = TRUE; // ***** Update statistics Statistics.BytesReceived += Header.Length - 4; Statistics.PacketsReceived++; } } // ***** IF NIC buffer overwrite warning THEN if (INPORTB(PG0R_ISR) & ISR_OVW) { PAUSE; // ***** 9. Reset the overwrite warning bit in the Interrupt Status Register. OUTPORTB(PG0W_ISR, ISR_OVW); PAUSE; // ***** 10. Take the NIC out of loopback mode (that means normal operation) OUTPORTB(PG0W_TCR, 0x00); PAUSE; // ***** 11. IF Resend = 1 THEN reissue a transmit if (Resend) { // Reissue transmit OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_TXP); PAUSE; } } else PAUSE; // ***** Restore NIC IMR OUTPORTB(PG0W_IMR, Imr); PAUSE; // ***** RETURN Success return Success;}/** * Recieve packets from the Ne2k * @param flush 0=return an NBuf chain containing the data, 1=remove one packet from ring buffer * @param length Length of packet to retrieve * @return points to start of NBuf chain, or NULL if flushing... */NBuf *Ne2kRxPacketInternal(int flush, int length){ int Success, Resend, TxpBit;// u_short PacketLength; u_char Imr; BufferHeader Header; NBuf *rtn=NULL;// printf("Ne2kRxPacket\n");// printf("length=%d\n",length); // ***** IF length > 1514 THEN RETURN FALSE if (length > 1514) return FALSE; // ***** Remember NIC IMR and disable interrupt from NIC (ATOMIC OPERATION!) DISABLE_INTERRUPTS; // Select PAGE 2 OUTPORTB(NIC_CR, CR_PAGE2 | CR_NO_DMA | CR_START); PAUSE; // Read IMR register Imr = INPORTB(PG2R_IMR); PAUSE; // Select PAGE 0 again OUTPORTB(NIC_CR, CR_PAGE0 | CR_NO_DMA | CR_START); PAUSE; // Disable interrupts from NIC OUTPORTB(PG0W_IMR, 0x00); PAUSE; ENABLE_INTERRUPTS; // ***** Success = FALSE; Success = FALSE; Resend = FALSE; // ***** IF NIC buffer overwrite warning THEN if (INPORTB(PG0R_ISR) & ISR_OVW) { PAUSE;// printf("overwrite\n"); // ***** Update statistics Statistics.OverrunErrors++; // *********************************************************************************** // ***** The following buffer ring overflow procedure is taken from the datasheet // ***** DP8390D/NS32490D NIC Network Interface Controller (July 1995) from National // ***** Semiconductor. This procedure is mandatory! // ***** 1. Read and store the value of the TXP bit (from command register) TxpBit = (INPORTB(NIC_CR) & CR_TXP); PAUSE; // ***** 2. Issue a stop command OUTPORTB(NIC_CR, CR_STOP | CR_NO_DMA | CR_PAGE0); PAUSE; // ***** 3. Wait for at least 1.6 ms LONGPAUSE; // ***** 4. Clear NIC's Remote Byte Count registers (RBCR0 and RBCR1) OUTPORTB(PG0W_RBCR0, 0x00); PAUSE; OUTPORTB(PG0W_RBCR1, 0x00); PAUSE; // ***** 5. Read the stored value of the TXP bit from step 1 (determine if we stopped the NIC // ***** when it was transmitting). // ***** IF TXP bit = 1 THEN if (TxpBit) { // ***** IF PTX = 1 OR TXE = 1 THEN if (INPORTB(PG0R_ISR) & (ISR_PTX | ISR_TXE)) { PAUSE; // ***** Resend = FALSE Resend = FALSE; }else{ PAUSE; // ***** Resend = TRUE Resend = TRUE; } }else{ // ***** Resend = FALSE Resend = FALSE; } // ***** 6. Place the NIC in mode 1 (internal loopback) OUTPORTB(PG0W_TCR, TCR_LB0); PAUSE; // ***** 7. Start the NIC OUTPORTB(NIC_CR, CR_START | CR_NO_DMA | CR_PAGE0); PAUSE; }else{ PAUSE; } // ***** 8. Remove one or more packets from the NIC // ***** IF (flush) THEN - Just remove one packet from the receive buffer ring if (flush) { // ***** IF ReadBuffer(header, NULL, 0) THEN if (ReadBuffer(&Header, NULL, 0)) { // ***** Remove packet! // ***** NextPacket = Header.NextPage; NextPacket = Header.NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP_PG - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; // ***** Success = TRUE Success = TRUE; // ***** Update statistics Statistics.BytesReceived += Header.Length - 4; Statistics.PacketsReceived++; }else{// printf("ReadBuffer failled???\n"); } }else{ // ***** IF ReadBuffer(header, packet, length) THEN rtn=ReadBufferNBuf(&Header, length); if (rtn) { // ***** Remove packet! // ***** NextPacket = Header.NextPage; NextPacket = Header.NextPage; // ***** Initialize Boundary (read) Pointer to the value of NextPacket - 1 // ***** IF Boundary Pointer < RSTART_PG THEN BNDRY = RSTOP_PG - 1 if ( (NextPacket - 1) < RSTART_PG ) OUTPORTB(PG0W_BNRY, RSTOP_PG - 1); else OUTPORTB(PG0W_BNRY, NextPacket - 1); PAUSE; // ***** Success = TRUE Success = TRUE; // ***** Update statistics Statistics.BytesReceived += Header.Length - 4; Statistics.PacketsReceived++; } } // ***** IF NIC buffer overwrite warning THEN if (INPORTB(PG0R_ISR) & ISR_OVW) { PAUSE; // ***** 9. Reset the overwrite warning bit in the Interrupt Status Register. OUTPORTB(PG0W_ISR, ISR_OVW); PAUSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -