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

📄 dp83815.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
      /*---------------------------------------------------------------*/      buf = TxNetBuf[TxFreeBD - &BufDesc[BEG_TX_BD]];      tcpRetBuf(&buf);    }  }}/***********************************************************************//*   prep_txbd: Prepare next transmit buffer descriptor                *//*                                                                     *//***********************************************************************/static void prep_txbd(void *bufptr, int length, ui32 status){  /*-------------------------------------------------------------------*/  /* Set descriptor's buffer pointer and command/status fields.        */  /*-------------------------------------------------------------------*/  TxNextBD->bufptr = htopl((ui32)bufptr);  TxNextBD->cmdsts = htopl(status | length);  /*-------------------------------------------------------------------*/  /* Copy buffer and then descriptor from cache.                       */  /*-------------------------------------------------------------------*/  _cache_copyback(bufptr, length);  if (status)    _cache_copyback(TxNextBD, sizeof(BufDescType));  /*-------------------------------------------------------------------*/  /* Increment busy descriptor count.                                  */  /*-------------------------------------------------------------------*/  ++NumBusyTxBds;  /*-------------------------------------------------------------------*/  /* Set status bit and advance TxNextBD.                              */  /*-------------------------------------------------------------------*/  if (TxNextBD == &BufDesc[END_TX_BD])    TxNextBD = &BufDesc[BEG_TX_BD];  else    ++TxNextBD;}/***********************************************************************//* fill_tx_ring: Move buffers from the outbound queue to the transmit  *//*               buffer descriptor ring, if possible.                  *//*                                                                     *//***********************************************************************/static void fill_tx_ring(void){  int added;  NetBuf *buf;  /*-------------------------------------------------------------------*/  /* Fill any empty transmit descriptors, setting flag if any filled.  */  /*-------------------------------------------------------------------*/  for (added = FALSE;; added = TRUE)  {    /*-----------------------------------------------------------------*/    /* Break if no outbound buffers are queued.                        */    /*-----------------------------------------------------------------*/    buf = TxMsgQHead;    if (buf == NULL)      break;    /*-----------------------------------------------------------------*/    /* Break if there are not enough free descriptors.                 */    /*-----------------------------------------------------------------*/    if ((NUM_TX_BDS - NumBusyTxBds) <= buf->order)      break;    /*-----------------------------------------------------------------*/    /* Extract the top outbound buffer.                                */    /*-----------------------------------------------------------------*/    TxMsgQHead = TxMsgQHead->next;    /*-----------------------------------------------------------------*/    /* Check if there is only one data region.                         */    /*-----------------------------------------------------------------*/    if (buf->app_len == 0)      prep_txbd(buf->ip_pkt, buf->length, DP_DESC_CMDSTS_OWN);    /*-----------------------------------------------------------------*/    /* Else multiple buffer descriptors need to be prepared.           */    /*-----------------------------------------------------------------*/    else    {      int first_len = buf->length;      BufDescType *first_bd = TxNextBD;      /*---------------------------------------------------------------*/      /* Prepare the first buffer descriptor.                          */      /*---------------------------------------------------------------*/      prep_txbd(buf->ip_pkt, first_len, 0);      /*---------------------------------------------------------------*/      /* If there are three data regions, prepare middle and last.     */      /*---------------------------------------------------------------*/      if (buf->app_len2)      {        prep_txbd(buf->app_data, buf->app_len, DP_DESC_CMDSTS_OWN |                                               DP_DESC_CMDSTS_MORE);        prep_txbd(buf->app_data2, buf->app_len2, DP_DESC_CMDSTS_OWN);      }      /*---------------------------------------------------------------*/      /* Else just prepare a buffer descriptor for the last region.    */      /*---------------------------------------------------------------*/      else        prep_txbd(buf->app_data, buf->app_len, DP_DESC_CMDSTS_OWN);      /*---------------------------------------------------------------*/      /* Finish initial descriptor, enabling start of transmission.    */      /*---------------------------------------------------------------*/      first_bd->cmdsts = htopl(DP_DESC_CMDSTS_OWN | DP_DESC_CMDSTS_MORE |                               first_len);      _cache_copyback(first_bd, sizeof(BufDescType));    }    /*-----------------------------------------------------------------*/    /* Save NetBuf pointer for tcpRetBuf() after transmission.         */    /*-----------------------------------------------------------------*/    TxNetBuf[TxNextBD - &BufDesc[BEG_TX_BD]] = buf;  }  /*-------------------------------------------------------------------*/  /* Re-enable DP83815 transmitter if any buffers were added.          */  /*-------------------------------------------------------------------*/  if (added)    DP_REG32_SET(DP_CR, DP_CR_TXE);}/***********************************************************************//* fill_rx_ring: Assign buffers to "used" receive buffer descriptors,  *//*               marking them as empty, available to be filled again   *//*               by the receiver.                                      *//*                                                                     *//***********************************************************************/static void fill_rx_ring(void){  NetBuf *buf;  int added;  ui8 *cp;  /*-------------------------------------------------------------------*/  /* Check for empty receive descriptors. Set flag if any were added.  */  /*-------------------------------------------------------------------*/  for (added = FALSE;; added = TRUE)  {    /*-----------------------------------------------------------------*/    /* Exit if receive buffer descriptor ring is filled with buffers.  */    /*-----------------------------------------------------------------*/    if (RxFillBD->bufptr)      break;    /*-----------------------------------------------------------------*/    /* Allocate 60 bytes for conversion from 4 to 64-byte alignment    */    /* and 1518 for truncation limit. Exit if no buffers available.    */    /*-----------------------------------------------------------------*/    buf = tcpGetBuf(60 + 1518);    if (buf == NULL)      break;    /*-----------------------------------------------------------------*/    /* Save NetBuf pointer for processing after reception.             */    /*-----------------------------------------------------------------*/    RxNetBuf[RxFillBD - &BufDesc[BEG_RX_BD]] = buf;    /*-----------------------------------------------------------------*/    /* Buffer pointer must be aligned on 64-byte boundary.             */    /*-----------------------------------------------------------------*/    cp = (ui8 *)((ui32)(buf->data + 63) & ~63);    /*-----------------------------------------------------------------*/    /* Ensure no stale data is left marked as valid.                   */    /*-----------------------------------------------------------------*/    _cache_invalidate(cp, 1514);    /*-----------------------------------------------------------------*/    /* Initialize buffer descriptor and write from cache.              */    /*-----------------------------------------------------------------*/    RxFillBD->bufptr = htopl((ui32)cp);    RxFillBD->cmdsts = htopl(1536);     /* size in 32 byte multiples */    _cache_copyback(RxFillBD, sizeof(BufDescType));    /*-----------------------------------------------------------------*/    /* Advance to next buffer descriptor.                              */    /*-----------------------------------------------------------------*/    if (RxFillBD == &BufDesc[END_RX_BD])      RxFillBD = &BufDesc[BEG_RX_BD];    else      ++RxFillBD;  }  /*-------------------------------------------------------------------*/  /* Re-enable DP83815 receiver if any buffers were added.             */  /*-------------------------------------------------------------------*/  if (added)    DP_REG32_SET(DP_CR, DP_CR_RXE);}/***********************************************************************//* receive_bufs: Process all received buffers                          *//*                                                                     *//***********************************************************************/static void receive_bufs(void){  uint length;  ui32 status;  FRAME *frame;  NetBuf *buf;  /*-------------------------------------------------------------------*/  /* Loop to process received buffers.                                 */  /*-------------------------------------------------------------------*/  for (;;)  {    /*-----------------------------------------------------------------*/    /* Exit upon reaching a buffer we've already processed.            */    /*-----------------------------------------------------------------*/    if (RxNextBD->bufptr == 0)      break;    /*-----------------------------------------------------------------*/    /* Invalidate any stale descriptor data in cache.                  */    /*-----------------------------------------------------------------*/    _cache_invalidate(RxNextBD, sizeof(BufDescType));    /*-----------------------------------------------------------------*/    /* Exit upon reaching a buffer we don't own.                       */    /*-----------------------------------------------------------------*/    status = ptohl(RxNextBD->cmdsts);    if ((status & DP_DESC_CMDSTS_OWN) == 0)      break;    /*-----------------------------------------------------------------*/    /* Get frame pointer and then mark descriptor as free.             */    /*-----------------------------------------------------------------*/    frame = (FRAME *)RxNextBD->bufptr;    RxNextBD->bufptr = 0;    /*-----------------------------------------------------------------*/    /* Record that another packet has been received.                   */    /*-----------------------------------------------------------------*/    ++dp83815Ni.ipkts;    /*-----------------------------------------------------------------*/    /* Load pointer to network buffer that holds this packet.          */    /*-----------------------------------------------------------------*/    buf = RxNetBuf[RxNextBD - &BufDesc[BEG_RX_BD]];    /*-----------------------------------------------------------------*/    /* Advance to the next buffer descriptor and reenable interrupts.  */    /*-----------------------------------------------------------------*/    if (RxNextBD == &BufDesc[END_RX_BD])      RxNextBD = &BufDesc[BEG_RX_BD];    else      ++RxNextBD;    /*-----------------------------------------------------------------*/    /* If there are errors, recycle buffer. Else pass up the frame.    */    /*-----------------------------------------------------------------*/    if (status & DP_DESC_CMDSTS_RX_ERRORS)    {      ++dp83815Ni.ierrs;      tcpRetBuf(&buf);    }    /*-----------------------------------------------------------------*/    /* Else need to report valid buffer received.                      */    /*-----------------------------------------------------------------*/    else    {      /*---------------------------------------------------------------*/      /* Determine packet length.                                      */      /*---------------------------------------------------------------*/      length = (status & DP_DESC_CMDSTS_SIZE) -               (ETH_HDR_LEN + ETH_CRC_LEN);      /*---------------------------------------------------------------*/      /* If IEEE encapsulation, skip past LLC/SNAP headers.            */      /*---------------------------------------------------------------*/      if (length >= ntohs(frame->type))      {        length -= IEEE_OFFSET;        frame = (FRAME *)((ui8 *)frame + IEEE_OFFSET);      }      /*---------------------------------------------------------------*/      /* Initialize buffer fields and then pass to TargetTCP.          */      /*---------------------------------------------------------------*/      buf->ni = &dp83815Ni;      buf->type = ntohs(frame->type);      buf->length = length;      buf->ip_pkt = (ui8 *)frame + ETH_HDR_LEN;      tcpDataInd(buf);    }  }}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//* dp83815Init: Initialize TargetTCP DP83815 Ethernet driver           *//*                                                                     *//***********************************************************************/void dp83815Init(ui32 ip_addr, ui32 ip_mask, uint flags){  /*-------------------------------------------------------------------*/  /* Configure the method of IP address assignment.                    */  /*-------------------------------------------------------------------*/  if (flags & NIF_USE_DHCP)    dp83815Ni.flags = NIF_USE_DHCP | NIF_DEF_GW;  else if (flags & NIF_USE_RARP)    dp83815Ni.flags = NIF_USE_RARP;  else    dp83815Ni.flags = 0;  dp83815Ni.ip_addr = ip_addr;  dp83815Ni.ip_mask = ip_mask;  /*-------------------------------------------------------------------*/  /* Complete the network interface structure.                         */  /*-------------------------------------------------------------------*/  dp83815Ni.mtu = ETH_MTU;  dp83815Ni.hw_addr = OurAddress.byte;  dp83815Ni.hw_type = ETH_DIX_HW;  dp83815Ni.ha_len = ETH_ALEN;  dp83815Ni.transmit = transmit;  dp83815Ni.broadcast = broadcast;  dp83815Ni.poll = poll;  dp83815Ni.name = "DP83815";  /*-------------------------------------------------------------------*/  /* Initialize hardware. If successful, add interface to TargetTCP.   */  /*-------------------------------------------------------------------*/  if (ni_init() == 0)    tcpAddNi(&dp83815Ni);}/***********************************************************************//* dp83815_dump:                                                       *//*                                                                     *//***********************************************************************/void dp83815_dump(void){  printf("rx: tot=%u  errs=%u\n", dp83815Ni.ipkts, dp83815Ni.ierrs);  printf("tx: tot=%u  errs=%u\n", dp83815Ni.opkts, dp83815Ni.oerrs);  printf("isr: tot=%u  rx=%u tx=%u\n", IsrCount, RxIsrCount, TxIsrCount);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -