⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_ne2kd.c

📁 一个简单的TCP IP协议栈程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    // ***** 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 + -