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

📄 greth.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef CPU_U32_FIX                    /*printf("Ip aligning\n");*/                    ipalign(m);	/* Align packet on 32-bit boundary */#endif                    /*printf("Calling stack\n");*/                    /*printf("Ifp: %x, Eh: %x, M: %x\n", (int)ifp, (int)eh, (int)m);*/                    ether_input (ifp, eh, m);                    /*printf("Returned from stack\n");*/                    /* get a new mbuf */                    /*printf("Getting new mbuf\n");*/                    MGETHDR (m, M_WAIT, MT_DATA);                    MCLGET (m, M_WAIT);                    /*printf("Got new mbuf\n");*/                    dp->rxmbuf[dp->rx_ptr] = m;                    m->m_pkthdr.rcvif = ifp;                    dp->rxdesc[dp->rx_ptr].addr =                      (unsigned32 *) mtod (m, unsigned32 *);                    dp->rxPackets++;                  }                /*printf("Reenabling desc\n");*/                dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;                if (dp->rx_ptr == dp->rxbufs - 1) {                  dp->rxdesc[dp->rx_ptr].ctrl |= GRETH_RXD_WRAP;                }                dp->regs->ctrl |= GRETH_CTRL_RXEN;                /*printf("rxptr: %i\n", dp->rx_ptr);*/                dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;                /*printf("RxDesc reenabled\n");*/            }      }    }static int inside = 0;static voidsendpacket (struct ifnet *ifp, struct mbuf *m){    struct greth_softc *dp = ifp->if_softc;    unsigned char *temp;    struct mbuf *n;    unsigned int len;        /*printf("Send packet entered\n");*/    if (inside) printf ("error: sendpacket re-entered!!\n");    inside = 1;    /*     * Waiting for Transmitter ready     */    n = m;    while (dp->txdesc[dp->tx_ptr].ctrl & GRETH_TXD_ENABLE)      {#ifdef GRETH_SUSPEND_NOTXBUF        dp->txdesc[dp->tx_ptr].ctrl |= GRETH_TXD_IRQ;        rtems_event_set events;        rtems_bsdnet_event_receive (GRETH_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].addr;#ifdef GRETH_DEBUG    printf("TXD: 0x%08x\n", (int) m->m_data);#endif    for (;;)        {#ifdef GRETH_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 <= GRETH_MAXBUF_LEN) {      if (dp->tx_ptr < dp->txbufs-1) {        dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;      } else {        dp->txdesc[dp->tx_ptr].ctrl =           GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;      }      dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;      dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;    }    inside = 0;}/* * Driver transmit daemon */voidgreth_txDaemon (void *arg){    struct greth_softc *sc = (struct greth_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 GRETH_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 voidgreth_start (struct ifnet *ifp){    struct greth_softc *sc = ifp->if_softc;        ifp->if_flags |= IFF_OACTIVE;    rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);    }/* * Initialize and start the device */static voidgreth_init (void *arg){    struct greth_softc *sc = arg;    struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0)      {	  /*	   * Set up GRETH hardware	   */          greth_initialize_hardware (sc);	  /*	   * Start driver tasks	   */	  sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,						  greth_rxDaemon, sc);	  sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,						  greth_txDaemon, sc);      }    /*     * Tell the world that we're running.     */    ifp->if_flags |= IFF_RUNNING;}/* * Stop the device */static voidgreth_stop (struct greth_softc *sc){    struct ifnet *ifp = &sc->arpcom.ac_if;    ifp->if_flags &= ~IFF_RUNNING;    sc->regs->ctrl = 0;		        /* RX/TX OFF */    sc->regs->ctrl = GRETH_CTRL_RST;	/* Reset ON */    sc->regs->ctrl = 0;	         	/* Reset OFF */}/* * Show interface statistics */static voidgreth_stats (struct greth_softc *sc){  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);  printf ("      Rx Packets:%-8lu", sc->rxPackets);  printf ("          Length:%-8lu", sc->rxLengthError);  printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);  printf ("         Overrun:%-8lu", sc->rxOverrun);  printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);}/* * Driver ioctl handler */static intgreth_ioctl (struct ifnet *ifp, int command, caddr_t data){    struct greth_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:		greth_stop (sc);                break;	    case IFF_UP:		greth_init (sc);		break;	    case IFF_UP | IFF_RUNNING:		greth_stop (sc);		greth_init (sc);		break;       default:		break;	    }	  break;      case SIO_RTEMS_SHOW_STATS:	  greth_stats (sc);	  break;	  /*	   * FIXME: All sorts of multicast commands need to be added here!	   */      default:	  error = EINVAL;	  break;      }    return error;}/* * Attach an GRETH driver to the system */intrtems_greth_driver_attach (struct rtems_bsdnet_ifconfig *config,			   greth_configuration_t *chip){    struct greth_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 = &greth;    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;        /*     * Set up network interface values     */    ifp->if_softc = sc;    ifp->if_unit = unitNumber;    ifp->if_name = unitName;    ifp->if_mtu = mtu;    ifp->if_init = greth_init;    ifp->if_ioctl = greth_ioctl;    ifp->if_start = greth_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 GRETH_DEBUG    printf ("GRETH : driver has been attached\n");#endif    return 1;};

⌨️ 快捷键说明

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