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

📄 c5471_ethernet.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 5 页
字号:
{  if (EIM_RXDESC_WRAP_NEXT & getreg32(c5471->c_rxcpudesc))    {      /* Loop back around to base of descriptor queue */      c5471->c_rxcpudesc = getreg32(EIM_CPU_RXBA) + EIM_RAM_START;    }  else    {      c5471->c_rxcpudesc += 2*sizeof(uint32);    }  nvdbg("RX CPU desc: %08x\n", c5471->c_rxcpudesc);}/**************************************************************************** * Function: c5471_transmit * * Description: *   Start hardware transmission.  Called either from the txdone interrupt *   handling or from watchdog based polling. * * Parameters: *   c5471  - Reference to the driver state structure * * Returned Value: *   OK on success; a negated errno on failure * * Assumptions: * ****************************************************************************/static int c5471_transmit(struct c5471_driver_s *c5471){  struct uip_driver_s *dev = &c5471->c_dev;  volatile uint16 *packetmem;  uint16 framelen;  boolean bfirstframe;  int nbytes;  int nshorts;  unsigned int i;  unsigned int j;  nbytes                 = (dev->d_len + 1) & ~1;  j                      = 0;  bfirstframe            = TRUE;  c5471->c_lastdescstart = c5471->c_rxcpudesc;  nvdbg("Packet size: %d RX CPU desc: %08x\n", nbytes, c5471->c_rxcpudesc);  c5471_dumpbuffer(dev->d_buf, dev->d_len);  while (nbytes)    {      /* Verify that the hardware is ready to send another packet */      /* Words #0 and #1 of descriptor */      while (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc))       {         /* Loop until the SWITCH lets go of the descriptor giving us access          * rights to submit our new ether frame to it.          */       }      if (bfirstframe)        {          putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_FIF), c5471->c_rxcpudesc);        }      else        {          putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_FIF), c5471->c_rxcpudesc);        }      putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_PADCRC), c5471->c_rxcpudesc);      if (bfirstframe)        {          putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_PADCRC), c5471->c_rxcpudesc);        }      if (nbytes >= EIM_PACKET_BYTES)        {          framelen = EIM_PACKET_BYTES;        }      else        {          framelen = nbytes;        }      /* Submit ether frame bytes to the C5472 Ether Module packet memory space. */      /* Get the number of 16-bit values to transfer by dividing by 2 with round up. */      nshorts = (framelen + 1) >> 1;      /* Words #2 and #3 of descriptor */      packetmem = (uint16*)getreg32(c5471->c_rxcpudesc + sizeof(uint32));      for (i = 0; i < nshorts; i++, j++)        {          /* 16-bits at a time. */          packetmem[i] = htons(((uint16*)dev->d_buf)[j]);        }      putreg32(((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_BYTEMASK) | framelen), c5471->c_rxcpudesc);      nbytes -= framelen;      nvdbg("Wrote framelen: %d nbytes: %d nshorts: %d\n", framelen, nbytes, nshorts);      if (0 == nbytes)        {          putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_LIF), c5471->c_rxcpudesc);        }      else        {          putreg32((getreg32(c5471->c_rxcpudesc) & ~EIM_RXDESC_LIF), c5471->c_rxcpudesc);        }      /* We're done with that descriptor; give access rights back to h/w */      putreg32((getreg32(c5471->c_rxcpudesc) | EIM_RXDESC_OWN_HOST), c5471->c_rxcpudesc);      /* Next, tell Ether Module that those submitted bytes are ready for the wire */      putreg32(0x00000001, EIM_CPU_RXREADY);      c5471->c_lastdescend = c5471->c_rxcpudesc;      /* Advance to the next free descriptor */      c5471_incrxcpu(c5471);      bfirstframe = FALSE;    }  /* Packet transferred .. Update statistics */#ifdef CONFIG_C5471_NET_STATS  c5471->c_txpackets++;#endif  /* Setup the TX timeout watchdog (perhaps restarting the timer) */  (void)wd_start(c5471->c_txtimeout, C5471_TXTIMEOUT, c5471_txtimeout, 1, (uint32)c5471);  return OK;}/**************************************************************************** * Function: c5471_uiptxpoll * * Description: *   The transmitter is available, check if uIP has any outgoing packets ready *   to send.  This is a callback from uip_poll().  uip_poll() may be called: * *   1. When the preceding TX packet send is complete, *   2. When the preceding TX packet send timesout and the interface is reset *   3. During normal TX polling * * Parameters: *   dev  - Reference to the NuttX driver state structure * * Returned Value: *   OK on success; a negated errno on failure * * Assumptions: * ****************************************************************************/static int c5471_uiptxpoll(struct uip_driver_s *dev){  struct c5471_driver_s *c5471 = (struct c5471_driver_s *)dev->d_private;  /* If the polling resulted in data that should be sent out on the network,   * the field d_len is set to a value > 0.   */  if (c5471->c_dev.d_len > 0)    {      uip_arp_out(&c5471->c_dev);      c5471_transmit(c5471);      /* Check if the ESM has let go of the RX descriptor giving us access       * rights to submit another Ethernet frame.       */      if ((EIM_TXDESC_OWN_HOST & getreg32(c5471->c_rxcpudesc)) != 0)        {          /* No, then return non-zero to terminate the poll */          return 1;        }    }  /* If zero is returned, the polling will continue until all connections have   * been examined.   */  return 0;}/**************************************************************************** * Function: c5471_rxstatus * * Description: *   An interrupt was received indicating that the last RX packet(s) is done * * Parameters: *   c5471  - Reference to the driver state structure * * Returned Value: *   None * * Assumptions: * ****************************************************************************/#ifdef CONFIG_C5471_NET_STATSstatic void c5471_rxstatus(struct c5471_driver_s *c5471){  uint32 desc = c5471->c_txcpudesc;  uint32 rxstatus;  /* Walk that last packet we just received to collect xmit status bits. */  rxstatus = 0;  for (;;)    {      if (EIM_TXDESC_OWN_HOST & getreg32(desc))        {          /* The incoming packet queue is empty. */          break;        }      rxstatus |= (getreg32(desc) & EIM_TXDESC_STATUSMASK);      if ((getreg32(desc) & EIM_TXDESC_LIF) != 0)        {          break;        }      /* This packet is made up of several descriptors, find next one in chain. */      if (EIM_TXDESC_WRAP_NEXT & getreg32(desc))        {          /* Loop back around to base of descriptor queue. */          desc = getreg32(EIM_CPU_TXBA) + EIM_RAM_START;        }      else        {          desc += 2 * sizeof(uint32);        }    }  if (rxstatus != 0)    {      if ((rxstatus & EIM_TXDESC_RETRYERROR) != 0)        {          c5471->c_rxretries++;          nvdbg("c_rxretries: %d\n", c5471->c_rxretries);        }      if ((rxstatus & EIM_TXDESC_HEARTBEAT) != 0)        {          c5471->c_rxheartbeat++;          nvdbg("c_rxheartbeat: %d\n", c5471->c_rxheartbeat);        }      if ((rxstatus & EIM_TXDESC_LCOLLISON) != 0)        {          c5471->c_rxlcollision++;          nvdbg("c_rxlcollision: %d\n", c5471->c_rxlcollision);        }      if ((rxstatus & EIM_TXDESC_COLLISION) != 0)        {          c5471->c_rxcollision++;          nvdbg("c_rxcollision: %d\n", c5471->c_rxcollision);        }      if ((rxstatus & EIM_TXDESC_CRCERROR) != 0)        {          c5471->c_rxcrc++;          nvdbg("c_rxcrc: %d\n", c5471->c_rxcrc);        }      if ((rxstatus & EIM_TXDESC_UNDERRUN) != 0)        {          c5471->c_rxunderrun++;          nvdbg("c_rxunderrun: %d\n", c5471->c_rxunderrun);        }      if ((rxstatus & EIM_TXDESC_LOC) != 0)        {          c5471->c_rxloc++;          nvdbg("c_rxloc: %d\n", c5471->c_rxloc);        }    }}#endif/**************************************************************************** * Function: c5471_receive * * Description: *   An interrupt was received indicating the availability of a new RX packet * * Parameters: *   c5471  - Reference to the driver state structure * * Returned Value: *   None * * Assumptions: * ****************************************************************************/static void c5471_receive(struct c5471_driver_s *c5471){  struct uip_driver_s *dev = &c5471->c_dev;  uint16 *packetmem;  boolean bmore = TRUE;  int packetlen = 0;  int framelen;  int nshorts;  int i;  int j = 0;  /* Walk the newly received packet contained within the EIM and transfer   * its contents to the uIP buffer. This frees up the memory contained within   * the EIM for additional packets that might be received later from the network.   */  nvdbg("Reading TX CPU desc: %08x\n", c5471->c_txcpudesc);  while (bmore)    {      /* Words #0 and #1 of descriptor */      if (EIM_TXDESC_OWN_HOST & getreg32(c5471->c_txcpudesc))        {          /* No further packets to receive. */          break;        }      /* Get the size of the frame from words #0 and #1 of the descriptor       * and update the accumulated packet size       */      framelen   = (getreg32(c5471->c_txcpudesc) & EIM_TXDESC_BYTEMASK);      packetlen += framelen;      /* Check if the received packet will fit within the uIP packet buffer */      if (packetlen < (CONFIG_NET_BUFSIZE + 4))        {          /* Get the packet memory from words #2 and #3 of descriptor */          packetmem = (uint16*)getreg32(c5471->c_txcpudesc + sizeof(uint32));          /* Divide by 2 with round up to get the number of 16-bit words. */          nshorts = (framelen + 1) >> 1;          nvdbg("Reading framelen: %d packetlen: %d nshorts: %d packetmen: %p\n",                 framelen, packetlen, nshorts, packetmem);          for (i = 0 ; i < nshorts; i++, j++)            {              /* Copy the data data from the hardware to c5471->c_dev.d_buf 16-bits at               * a time.               */              ((uint16*)dev->d_buf)[j] = htons(packetmem[i]);            }        }      else        {          nvdbg("Discarding framelen: %d packetlen\n", framelen, packetlen);        }      if (getreg32(c5471->c_txcpudesc) & EIM_TXDESC_LIF)        {          bmore = FALSE;        }      /* Next, Clear all bits of words0/1 of the emptied descriptor except preserve       * the settings of a select few. Can leave descriptor words 2/3 alone.       */      putreg32((getreg32(c5471->c_txcpudesc) & (EIM_TXDESC_WRAP_NEXT|EIM_TXDESC_INTRE)),               c5471->c_txcpudesc);      /* Next, Give ownership of now emptied descriptor back to the Ether Module's SWITCH */      putreg32((getreg32(c5471->c_txcpudesc) | EIM_TXDESC_OWN_HOST), c5471->c_txcpudesc);      /* Advance to the next data buffer */      c5471_inctxcpu(c5471);    }  /* Adjust the packet length to remove the CRC bytes that uIP doesn't care about. */  packetlen -= 4;#ifdef CONFIG_C5471_NET_STATS  /* Increment the count of received packets */  c5471->c_rxpackets++;#endif  /* If we successfully transferred the data into the uIP buffer, then pass it on   * to uIP for processing.   */  if (packetlen > 0 && packetlen < CONFIG_NET_BUFSIZE)    {      /* Set amount of data in c5471->c_dev.d_len. */      dev->d_len = packetlen;      nvdbg("Received packet, packetlen: %d type: %02x\n", packetlen, ntohs(BUF->type));      c5471_dumpbuffer(dev->d_buf, dev->d_len);      /* We only accept IP packets of the configured type and ARP packets */#ifdef CONFIG_NET_IPv6      if (BUF->type == HTONS(UIP_ETHTYPE_IP6))#else      if (BUF->type == HTONS(UIP_ETHTYPE_IP))#endif        {          uip_arp_ipin();          uip_input(dev);

⌨️ 快捷键说明

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