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

📄 open_eth.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
		  {		      dp->rxMiss++;		      bad = 1;		  }		if (len_status & OETH_RX_BD_LATECOL)		  {		      dp->rxCollision++;		      bad = 1;		  }		if (!bad)		  {		      /* pass on the packet in the receive buffer */		      len = len_status >> 16;		      m = (struct mbuf *) (dp->rxdesc[dp->rx_ptr].m);		      m->m_len = m->m_pkthdr.len =			  len - sizeof (struct ether_header);		      eh = mtod (m, struct ether_header *);		      m->m_data += sizeof (struct ether_header);#ifdef CPU_U32_FIX	              ipalign(m);	/* Align packet on 32-bit boundary */#endif		      ether_input (ifp, eh, m);		      /* get a new mbuf */		      MGETHDR (m, M_WAIT, MT_DATA);		      MCLGET (m, M_WAIT);		      m->m_pkthdr.rcvif = ifp;		      dp->rxdesc[dp->rx_ptr].m = m;		      dp->regs->xd[dp->rx_ptr + dp->txbufs].addr =			  (unsigned32 *) mtod (m, void *);		      dp->rxPackets++;		  }		dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status =		  (dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status &		    ~OETH_TX_BD_STATS) | OETH_TX_BD_READY;		dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;	    }      }}static int inside = 0;static voidsendpacket (struct ifnet *ifp, struct mbuf *m){    struct open_eth_softc *dp = ifp->if_softc;    unsigned char *temp;    struct mbuf *n;    unsigned int len, len_status;    if (inside) printf ("error: sendpacket re-entered!!\n");    inside = 1;    /*     * Waiting for Transmitter ready     */    n = m;    while (dp->regs->xd[dp->tx_ptr].len_status & OETH_TX_BD_READY)      {#ifdef OETH_SUSPEND_NOTXBUF          rtems_event_set events;	  rtems_bsdnet_event_receive (OPEN_ETH_TX_WAIT_EVENT,				      RTEMS_WAIT | RTEMS_EVENT_ANY,				      TOD_MILLISECONDS_TO_TICKS(500), &events);#endif      }    len = 0;    temp = (unsigned char *) dp->txdesc[dp->tx_ptr].buf;    dp->regs->xd[dp->tx_ptr].addr = (unsigned32 *) temp;#ifdef OPEN_ETH_DEBUG    printf("TXD: 0x%08x\n", (int) m->m_data);#endif    for (;;)        {#ifdef OPEN_ETH_DEBUG	  int i;          printf("MBUF: 0x%08x : ", (int) m->m_data);	  for (i=0;i<m->m_len;i++)	    printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);	  printf("\n");#endif	  len += m->m_len;	  if (len <= RBUF_SIZE)	    memcpy ((void *) temp, (char *) m->m_data, m->m_len);	  temp += m->m_len;	  if ((m = m->m_next) == NULL)	      break;        }    m_freem (n);    /* don't send long packets */    if (len <= RBUF_SIZE) {     /* Clear all of the status flags.  */     len_status = dp->regs->xd[dp->tx_ptr].len_status & ~OETH_TX_BD_STATS;     /* If the frame is short, tell CPM to pad it.  */     if (len < ET_MINLEN) {	len_status |= OETH_TX_BD_PAD;	len = ET_MINLEN;     }     else	len_status &= ~OETH_TX_BD_PAD;      /* write buffer descriptor length and status */      len_status &= 0x0000ffff;      len_status |= (len << 16) | (OETH_TX_BD_READY | OETH_TX_BD_CRC);      dp->regs->xd[dp->tx_ptr].len_status = len_status;      dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;    }    inside = 0;}/* * Driver transmit daemon */voidopen_eth_txDaemon (void *arg){    struct open_eth_softc *sc = (struct open_eth_softc *) arg;    struct ifnet *ifp = &sc->arpcom.ac_if;    struct mbuf *m;    rtems_event_set events;    for (;;)      {	  /*	   * Wait for packet	   */	  rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,				      RTEMS_EVENT_ANY | RTEMS_WAIT,				      RTEMS_NO_TIMEOUT, &events);#ifdef OPEN_ETH_DEBUG    printf ("t\n");#endif	  /*	   * Send packets till queue is empty	   */	  for (;;)	    {		/*		 * Get the next mbuf chain to transmit.		 */		IF_DEQUEUE (&ifp->if_snd, m);		if (!m)		    break;		sendpacket (ifp, m);	    }	  ifp->if_flags &= ~IFF_OACTIVE;      }}static voidopen_eth_start (struct ifnet *ifp){    struct open_eth_softc *sc = ifp->if_softc;    rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);    ifp->if_flags |= IFF_OACTIVE;}/* * Initialize and start the device */static voidopen_eth_init (void *arg){    struct open_eth_softc *sc = arg;    struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0)      {	  /*	   * Set up OPEN_ETH hardware	   */	  open_eth_initialize_hardware (sc);	  /*	   * Start driver tasks	   */	  sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,						  open_eth_rxDaemon, sc);	  sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,						  open_eth_txDaemon, sc);      }    /*     * Tell the world that we're running.     */    ifp->if_flags |= IFF_RUNNING;}/* * Stop the device */static voidopen_eth_stop (struct open_eth_softc *sc){    struct ifnet *ifp = &sc->arpcom.ac_if;    ifp->if_flags &= ~IFF_RUNNING;    sc->regs->moder = 0;		/* RX/TX OFF */    sc->regs->moder = OETH_MODER_RST;	/* Reset ON */    sc->regs->moder = 0;		/* Reset OFF */}/* * Show interface statistics */static voidopen_eth_stats (struct open_eth_softc *sc){    printf ("         Rx Packets:%-8lu", sc->rxPackets);    printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);    printf ("          Length:%-8lu", sc->rxLengthError);    printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);    printf ("            Bad CRC:%-8lu", sc->rxBadCRC);    printf ("         Overrun:%-8lu", sc->rxOverrun);    printf ("            Miss:%-8lu", sc->rxMiss);    printf ("       Collision:%-8lu\n", sc->rxCollision);    printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);    printf ("        Deferred:%-8lu", sc->txDeferred);    printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);    printf ("         No Carrier:%-8lu", sc->txLostCarrier);    printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);    printf ("  Late Collision:%-8lu\n", sc->txLateCollision);    printf ("           Underrun:%-8lu", sc->txUnderrun);    printf (" Raw output wait:%-8lu\n", sc->txRawWait);}/* * Driver ioctl handler */static intopen_eth_ioctl (struct ifnet *ifp, int command, caddr_t data){    struct open_eth_softc *sc = ifp->if_softc;    int error = 0;    switch (command)      {      case SIOCGIFADDR:      case SIOCSIFADDR:	  ether_ioctl (ifp, command, data);	  break;      case SIOCSIFFLAGS:	  switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))	    {	    case IFF_RUNNING:		open_eth_stop (sc);		break;	    case IFF_UP:		open_eth_init (sc);		break;	    case IFF_UP | IFF_RUNNING:		open_eth_stop (sc);		open_eth_init (sc);		break;	    default:		break;	    }	  break;      case SIO_RTEMS_SHOW_STATS:	  open_eth_stats (sc);	  break;	  /*	   * FIXME: All sorts of multicast commands need to be added here!	   */      default:	  error = EINVAL;	  break;      }    return error;}/* * Attach an OPEN_ETH driver to the system */intrtems_open_eth_driver_attach (struct rtems_bsdnet_ifconfig *config,			      open_eth_configuration_t * chip){    struct open_eth_softc *sc;    struct ifnet *ifp;    int mtu;    int unitNumber;    char *unitName;      /* parse driver name */    if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)	return 0;    sc = &oc;    ifp = &sc->arpcom.ac_if;    memset (sc, 0, sizeof (*sc));    if (config->hardware_address)      {	  memcpy (sc->arpcom.ac_enaddr, config->hardware_address,		  ETHER_ADDR_LEN);      }    else      {	  memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);      }    if (config->mtu)	mtu = config->mtu;    else	mtu = ETHERMTU;    sc->acceptBroadcast = !config->ignore_broadcast;    sc->regs = (void *) chip->base_address;    sc->vector = chip->vector;    sc->txbufs = chip->txd_count;    sc->rxbufs = chip->rxd_count;    sc->en100MHz = chip->en100MHz;    /*     * Set up network interface values     */    ifp->if_softc = sc;    ifp->if_unit = unitNumber;    ifp->if_name = unitName;    ifp->if_mtu = mtu;    ifp->if_init = open_eth_init;    ifp->if_ioctl = open_eth_ioctl;    ifp->if_start = open_eth_start;    ifp->if_output = ether_output;    ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;    if (ifp->if_snd.ifq_maxlen == 0)	ifp->if_snd.ifq_maxlen = ifqmaxlen;    /*     * Attach the interface     */    if_attach (ifp);    ether_ifattach (ifp);#ifdef OPEN_ETH_DEBUG    printf ("OPEN_ETH : driver has been attached\n");#endif    return 1;};

⌨️ 快捷键说明

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