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

📄 dp83815.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
  DP_REG16_WRITE(DP_TBTSCR,  0x0866);   /* suppress heartbeat */  DP_REG32_WRITE(DP_MIBC,    0x0000);   /* don't freeze MIB counters */  dp_cfg_val = (DP_CFG_PESEL           | /* parity error detect */                DP_CFG_ANEG_SEL_ALL_XD | /* negotiate 10/100 full/half */                DP_CFG_PAUSE_ADV       | /* pause capable */                DP_CFG_PINT_ACEN       | /* phy intr auto clear */                0x00040000);             /* phy config */  DP_REG32_WRITE(DP_CFG, dp_cfg_val | DP_CFG_PHY_RST);  microsleep(500);  DP_REG32_WRITE(DP_CFG, dp_cfg_val);  /*-------------------------------------------------------------------*/  /* Wait for auto-negotiation to finish.                              */  /*-------------------------------------------------------------------*/  for (timeout = 10000; timeout; --timeout)  {    if (DP_REG32_READ(DP_CFG) & DP_CFG_ANEG_DN)      break;    microsleep(500);  }  if (timeout == 0)    return -1;  /*-------------------------------------------------------------------*/  /* Read negotiation status.                                          */  /*-------------------------------------------------------------------*/  phy_status = DP_REG16_READ(DP_PHYSTS);  /*-------------------------------------------------------------------*/  /* Set flag if full duplex is enabled.                               */  /*-------------------------------------------------------------------*/  FullDuplex = phy_status & DP_PHYSTS_FDX;  /*-------------------------------------------------------------------*/  /* Display the interface status.                                     */  /*-------------------------------------------------------------------*/  printf("dp83815: speed=%s duplex=%s link=%s\n",         (phy_status & DP_PHYSTS_SPEED_10) ? "10" : "100",         FullDuplex ? "full" : "half",         (phy_status & DP_PHYSTS_LNK_VALID) ? "up" : "down");  return 0;}/***********************************************************************//*     ni_init: Initialize the Ethernet hardware                       *//*                                                                     *//***********************************************************************/static int ni_init(void){  tmLibdevErr_t tm_err;  PnP pnp;  ui16  pci_cfgcmd;  BufDescType *bd_ptr;  ui32 temp;  /*-------------------------------------------------------------------*/  /* See if the device exists.                                         */  /*-------------------------------------------------------------------*/  tm_err = PnPOpen(DP83815_VENDOR_ID, DP83815_DEVICE_ID, 0, &pnp);  if (tm_err != TMLIBDEV_OK)  {    printf("dp83815: PnPOpen failed %08X\n", tm_err);    return -1;  }  /*-------------------------------------------------------------------*/  /* Get I/O base address.                                             */  /*-------------------------------------------------------------------*/  PnPGetBaseAddress(pnp, 0, &IoAddress);  /*-------------------------------------------------------------------*/  /* Enable bus-mastering.                                             */  /*-------------------------------------------------------------------*/  PnPConfigRead16(pnp, 4, &pci_cfgcmd);  pci_cfgcmd |= 0x04;  PnPConfigWrite16(pnp, 4, pci_cfgcmd);  /*-------------------------------------------------------------------*/  /* Disable power management.                                         */  /*-------------------------------------------------------------------*/  PnPConfigWrite32(pnp, 0x44, 0);  /*-------------------------------------------------------------------*/  /* Get the Ethernet address.                                         */  /*-------------------------------------------------------------------*/  if (get_eth_addr(OurAddress.byte))    return -1;  printf("dp83815: MAC Address = ");  printEth(OurAddress.byte);  putchar('\n');  /*-------------------------------------------------------------------*/  /* Reset the device.                                                 */  /*-------------------------------------------------------------------*/  if (dev_reset())  {    printf("dp83815: Device Reset failed\n");    return -1;  }  /*-------------------------------------------------------------------*/  /* Set the Ethernet address in hardware.                             */  /*-------------------------------------------------------------------*/  set_eth_addr(OurAddress.byte);  /*-------------------------------------------------------------------*/  /* Install and enable ISR.                                           */  /*-------------------------------------------------------------------*/  tm_err = PnPSetHandler(pnp, &ni_isr, TW_INTS_HND_AMD_PNA, 0);  if (tm_err != TMLIBDEV_OK)  {    printf("dp83815: PnPSetHandler() error status = %08X\n", tm_err);    return -1;  }  /*-------------------------------------------------------------------*/  /* Allocate memory for the receive and transmit buffer descriptors.  */  /*-------------------------------------------------------------------*/  BufDesc = _cache_malloc(sizeof(BufDescType) *                                          (NUM_RX_BDS + NUM_TX_BDS), -1);  if (BufDesc == NULL)    return -1;  /*-------------------------------------------------------------------*/  /* Initialize the receive buffer descriptors as a ring.              */  /*-------------------------------------------------------------------*/  RxFillBD = RxNextBD = bd_ptr = &BufDesc[BEG_RX_BD];  for (; bd_ptr < &BufDesc[END_RX_BD]; ++bd_ptr)  {    bd_ptr->link = htopl((ui32)(bd_ptr + 1));    bd_ptr->cmdsts = 0;    bd_ptr->bufptr = 0;  }  bd_ptr->link = htopl((ui32)RxFillBD);  bd_ptr->cmdsts = 0;  bd_ptr->bufptr = 0;  _cache_copyback(RxFillBD, sizeof(BufDescType) * NUM_RX_BDS);  fill_rx_ring();  /*-------------------------------------------------------------------*/  /* Initialize the transmit buffer descriptors as a ring.             */  /*-------------------------------------------------------------------*/  TxFreeBD = TxNextBD = bd_ptr = &BufDesc[BEG_TX_BD];  for (; bd_ptr < &BufDesc[END_TX_BD]; ++bd_ptr)  {    bd_ptr->link = htopl((ui32)(bd_ptr + 1));    bd_ptr->cmdsts = 0;    bd_ptr->bufptr = 0;  }  bd_ptr->link = htopl((ui32)TxFreeBD);  bd_ptr->cmdsts = 0;  bd_ptr->bufptr = 0;  _cache_copyback(TxFreeBD, sizeof(BufDescType) * NUM_TX_BDS);  /*-------------------------------------------------------------------*/  /* Assign initial receive and transmit buffer descriptor pointers.   */  /*-------------------------------------------------------------------*/  DP_REG32_WRITE(DP_RXDP, RxNextBD);  DP_REG32_WRITE(DP_TXDP, TxNextBD);  /*-------------------------------------------------------------------*/  /* Setup phy capabilities.                                           */  /*-------------------------------------------------------------------*/  while (phy_setup())    printf("dp83815: Warning PHY setup did not complete. Check cable.\n");  /*-------------------------------------------------------------------*/  /* Setup transmit control.                                           */  /*-------------------------------------------------------------------*/  temp = DP_TXCFG_DRTH_SET(48) | DP_TXCFG_FLTH_SET(16) |         DP_TXCFG_MXDMA_32     | DP_TXCFG_ATP;  if (FullDuplex)    temp |= DP_TXCFG_CSI | DP_TXCFG_HBI;  DP_REG32_WRITE(DP_TXCFG, temp);  /*-------------------------------------------------------------------*/  /* Setup receive control.                                            */  /*-------------------------------------------------------------------*/  temp = DP_RXCFG_DRTH_SET(8) | DP_RXCFG_MXDMA_32;  if (FullDuplex)    temp |= DP_RXCFG_ATX;  DP_REG32_WRITE(DP_RXCFG, temp);  /*-------------------------------------------------------------------*/  /* Receive perfect match and broadcast packets.                      */  /*-------------------------------------------------------------------*/  DP_REG32_WRITE(DP_RFCR, 0);  DP_REG32_WRITE(DP_RFCR, (DP_RFCR_AAB  | /* all broadcast pkts */                           DP_RFCR_APM  | /* perfect match pkts */                           DP_RFCR_RFEN));  /*-------------------------------------------------------------------*/  /* Turn on device interrupts.                                        */  /*-------------------------------------------------------------------*/  DP_REG32_WRITE(DP_IMR, (DP_INT_RXOK  | DP_INT_MIB   |                          DP_INT_RTABT | DP_INT_RMABT |                          DP_INT_SSERR | DP_INT_PHY   |                          DP_INT_TXERR | DP_INT_RXERR |                          DP_INT_TXOK));  DP_REG32_WRITE(DP_IER, DP_IER_IE);  /*-------------------------------------------------------------------*/  /* Activate the receiver.                                            */  /*-------------------------------------------------------------------*/  DP_REG32_WRITE(DP_CR, DP_CR_TXE | DP_CR_RXE);  /*-------------------------------------------------------------------*/  /* We appear to be semi-functional.                                  */  /*-------------------------------------------------------------------*/  return 0;}/***********************************************************************//*    transmit: Add a buffer to transmitter's output queue             *//*                                                                     *//*      Inputs: buf = pointer to outbound buffer                       *//*              hwa = pointer to destination hardware address          *//*                                                                     *//***********************************************************************/static void transmit(NetBuf *buf, void *hwa){  int i;  FRAME *frame;  char *eth_hwa = hwa;  /*-------------------------------------------------------------------*/  /* Convert to Ethernet frame pointer and add Ethernet header length. */  /*-------------------------------------------------------------------*/  buf->ip_pkt -= ETH_HDR_LEN;  buf->length += ETH_HDR_LEN;  /*-------------------------------------------------------------------*/  /* Check for over-long frames.                                       */  /*-------------------------------------------------------------------*/  assert(buf->length <= 1514);  /*-------------------------------------------------------------------*/  /* Convert "length" to just length of first data region.             */  /*-------------------------------------------------------------------*/  buf->length -= (buf->app_len + buf->app_len2);  /*-------------------------------------------------------------------*/  /* Build Ethernet header immediately in front of IP packet.          */  /*-------------------------------------------------------------------*/  frame = (FRAME *)buf->ip_pkt;  for (i = 0; i < ETH_ALEN; ++i)    frame->daddr.byte[i] = eth_hwa[i];  frame->saddr.word1 = OurAddress.word1;  frame->saddr.word2 = OurAddress.word2;  frame->saddr.word3 = OurAddress.word3;  frame->type = buf->type;  /*-------------------------------------------------------------------*/  /* Add buffer to end of outbound list.                               */  /*-------------------------------------------------------------------*/  buf->next = NULL;  if (TxMsgQHead == NULL)    TxMsgQHead = buf;  else    TxMsgQTail->next = buf;  TxMsgQTail = buf;  /*-------------------------------------------------------------------*/  /* Add to transmit decriptor ring, if there is room.                 */  /*-------------------------------------------------------------------*/  if ((NUM_TX_BDS - NumBusyTxBds) > TxMsgQHead->order)    fill_tx_ring();}/***********************************************************************//*   broadcast: Add a buffer to output queue using broadcast address   *//*                                                                     *//*       Input: buf = pointer to outbound buffer                       *//*                                                                     *//***********************************************************************/static void broadcast(NetBuf *buf){  transmit(buf, "\xFF\xFF\xFF\xFF\xFF\xFF");}/***********************************************************************//* free_tx_bufs: Reclaim buffer's that have already been transmitted   *//*                                                                     *//***********************************************************************/static void free_tx_bufs(void){  NetBuf *buf;  ui32 status;  static int num_bds_nframe;  /*-------------------------------------------------------------------*/  /* Free up some buffer descriptors if possible.                      */  /*-------------------------------------------------------------------*/  for (;;)  {    /*-----------------------------------------------------------------*/    /* Break if all previously assigned buffers have been recovered.   */    /*-----------------------------------------------------------------*/    if (NumBusyTxBds == 0)      break;    /*-----------------------------------------------------------------*/    /* Invalidate any stale descriptor data in cache.                  */    /*-----------------------------------------------------------------*/    _cache_invalidate(TxFreeBD, sizeof(BufDescType));    /*-----------------------------------------------------------------*/    /* Break upon reaching a buffer yet to be transmitted.             */    /*-----------------------------------------------------------------*/    status = ptohl(TxFreeBD->cmdsts);    if (status & DP_DESC_CMDSTS_OWN)      break;    /*-----------------------------------------------------------------*/    /* Count number of buffer descriptors used by frame.               */    /*-----------------------------------------------------------------*/    ++num_bds_nframe;    /*-----------------------------------------------------------------*/    /* Advance TxFreeBD to next buffer descriptor in transmit ring.    */    /*-----------------------------------------------------------------*/    if (TxFreeBD == &BufDesc[END_TX_BD])      TxFreeBD = &BufDesc[BEG_TX_BD];    else      ++TxFreeBD;    /*-----------------------------------------------------------------*/    /* Check if this is the last descriptor in the frame.              */    /*-----------------------------------------------------------------*/    if ((status & DP_DESC_CMDSTS_MORE) == 0)    {      /*---------------------------------------------------------------*/      /* Adjust the number of busy buffer descriptors and reset count. */      /*---------------------------------------------------------------*/      NumBusyTxBds -= num_bds_nframe;      num_bds_nframe = 0;      /*---------------------------------------------------------------*/      /* Record packet transmission and check for errors.              */      /*---------------------------------------------------------------*/      ++dp83815Ni.opkts;      if (status & DP_DESC_CMDSTS_TX_ERRORS)        ++dp83815Ni.oerrs;      /*---------------------------------------------------------------*/      /* Return buffer to TargetTCP's buffer manager.                  */

⌨️ 快捷键说明

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