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

📄 if_ne2kd.c

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