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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
        /*         * Unmask TXB (buffer transmitted) and         * TXE (transmitter error) events.         */        m8xx.fec.ievent |= M8xx_FEC_IEVENT_TFINT;        rtems_bsdnet_event_receive (INTERRUPT_EVENT,                                    RTEMS_WAIT|RTEMS_EVENT_ANY,                                    RTEMS_NO_TIMEOUT,                                    &events);        m860Enet_retire_tx_bd (sc);      }    }        /*     * Don't set the READY flag till the     * whole packet has been readied.     */    status = nAdded ? M8xx_BD_READY : 0;        /*     *  FIXME: Why not deal with empty mbufs at at higher level?     * The IP fragmentation routine in ip_output     * can produce packet fragments with zero length.     * I think that ip_output should be changed to get     * rid of these zero-length mbufs, but for now,     * I'll deal with them here.     */    if (m->m_len) {      /*       * Fill in the buffer descriptor       */      txBd->buffer = mtod (m, void *);      txBd->length = m->m_len;      sc->txMbuf[sc->txBdHead] = m;      nAdded++;      if (++sc->txBdHead == sc->txBdCount) {        status |= M8xx_BD_WRAP;        sc->txBdHead = 0;      }      /*      l = m;*/      m = m->m_next;    }    else {      /*       * Just toss empty mbufs       */      struct mbuf *n;      MFREE (m, n);      m = n;      /*      if (l != NULL)        l->m_next = m;      */    }        /*     * Set the transmit buffer status.     * Break out of the loop if this mbuf is the last in the frame.     */    if (m == NULL) {      if (nAdded) {        status |= M8xx_BD_LAST | M8xx_BD_TX_CRC;        txBd->status = status;        firstTxBd->status |= M8xx_BD_READY;        m8xx.fec.x_des_active = 0x1000000;        sc->txBdActiveCount += nAdded;      }      break;    }    txBd->status = status;    txBd = sc->txBdBase + sc->txBdHead;  }}/* * Driver transmit daemon */voidscc_txDaemon (void *arg){  struct m860_enet_struct *sc = (struct m860_enet_struct *)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);        /*     * Send packets till queue is empty     */    for (;;) {      /*       * Get the next mbuf chain to transmit.       */      IF_DEQUEUE(&ifp->if_snd, m);      if (!m)        break;      scc_sendpacket (ifp, m);    }    ifp->if_flags &= ~IFF_OACTIVE;  }}voidfec_txDaemon (void *arg){  struct m860_enet_struct *sc = (struct m860_enet_struct *)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);        /*     * Send packets till queue is empty     */    for (;;) {      /*       * Get the next mbuf chain to transmit.       */      IF_DEQUEUE(&ifp->if_snd, m);      if (!m)        break;      fec_sendpacket (ifp, m);    }    ifp->if_flags &= ~IFF_OACTIVE;  }}/* * Send packet (caller provides header). */static voidm860_enet_start (struct ifnet *ifp){  struct m860_enet_struct *sc = ifp->if_softc;    rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);  ifp->if_flags |= IFF_OACTIVE;}/* * Initialize and start the device */static voidscc_init (void *arg){  struct m860_enet_struct *sc = arg;  struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0) {        /*     * Set up SCC hardware     */    m860_scc_initialize_hardware (sc);        /*     * Start driver tasks     */    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, scc_txDaemon, sc);    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, scc_rxDaemon, sc);      }    /*   * Set flags appropriately   */  if (ifp->if_flags & IFF_PROMISC)    m8xx.scc1.psmr |= 0x200;  else    m8xx.scc1.psmr &= ~0x200;    /*   * Tell the world that we're running.   */  ifp->if_flags |= IFF_RUNNING;    /*   * Enable receiver and transmitter   */  m8xx.scc1.gsmr_l |= 0x30;}static voidfec_init (void *arg){  struct m860_enet_struct *sc = arg;  struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0) {        /*     * Set up SCC hardware     */    m860_fec_initialize_hardware (sc);        /*     * Start driver tasks     */    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, fec_txDaemon, sc);    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, fec_rxDaemon, sc);      }    /*   * Set flags appropriately   */  if (ifp->if_flags & IFF_PROMISC)    m8xx.fec.r_cntrl |= 0x8;  else    m8xx.fec.r_cntrl &= ~0x8;    /*   * Tell the world that we're running.   */  ifp->if_flags |= IFF_RUNNING;    /*   * Enable receiver and transmitter   */  m8xx.fec.ecntrl = 0x2;}/* * Stop the device */static voidscc_stop (struct m860_enet_struct *sc){  struct ifnet *ifp = &sc->arpcom.ac_if;    ifp->if_flags &= ~IFF_RUNNING;    /*   * Shut down receiver and transmitter   */  m8xx.scc1.gsmr_l &= ~0x30;}static voidfec_stop (struct m860_enet_struct *sc){  struct ifnet *ifp = &sc->arpcom.ac_if;    ifp->if_flags &= ~IFF_RUNNING;    /*   * Shut down receiver and transmitter   */  m8xx.fec.ecntrl = 0x0;}/* * Show interface statistics */static voidenet_stats (struct m860_enet_struct *sc){  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);  printf ("       Not First:%-8lu", sc->rxNotFirst);  printf ("        Not Last:%-8lu\n", sc->rxNotLast);  printf ("              Giant:%-8lu", sc->rxGiant);  printf ("            Runt:%-8lu", sc->rxRunt);  printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);  printf ("         Overrun:%-8lu", sc->rxOverrun);  printf ("       Collision:%-8lu\n", sc->rxCollision);  printf ("          Discarded:%-8lu\n", (unsigned long)m8xx.scc1p.un.ethernet.disfc);    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 intscc_ioctl (struct ifnet *ifp, int command, caddr_t data){  struct m860_enet_struct *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:      scc_stop (sc);      break;          case IFF_UP:      scc_init (sc);      break;          case IFF_UP | IFF_RUNNING:      scc_stop (sc);      scc_init (sc);      break;          default:      break;    }    break;      case SIO_RTEMS_SHOW_STATS:    enet_stats (sc);    break;        /*     * FIXME: All sorts of multicast commands need to be added here!     */  default:    error = EINVAL;    break;  }  return error;}static intfec_ioctl (struct ifnet *ifp, int command, caddr_t data){  struct m860_enet_struct *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:      fec_stop (sc);      break;          case IFF_UP:      fec_init (sc);      break;          case IFF_UP | IFF_RUNNING:      fec_stop (sc);      fec_init (sc);      break;          default:      break;    }    break;      case SIO_RTEMS_SHOW_STATS:    enet_stats (sc);    break;        /*     * FIXME: All sorts of multicast commands need to be added here!     */  default:    error = EINVAL;    break;  }  return error;}/* * Attach an SCC driver to the system */intrtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config){  struct m860_enet_struct *sc;  struct ifnet *ifp;  int mtu;  int i;    /*   * Find a free driver   */  for (i = 0 ; i < NIFACES ; i++) {    sc = &enet_driver[i];    ifp = &sc->arpcom.ac_if;    if (ifp->if_softc == NULL)      break;  }  if (i >= NIFACES) {    printf ("Too many SCC drivers.\n");    return 0;  }    /*   * Process options   */  if (config->hardware_address) {    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {    sc->arpcom.ac_enaddr[0] = 0x44;    sc->arpcom.ac_enaddr[1] = 0x22;    sc->arpcom.ac_enaddr[2] = 0x33;    sc->arpcom.ac_enaddr[3] = 0x33;    sc->arpcom.ac_enaddr[4] = 0x22;    sc->arpcom.ac_enaddr[5] = 0x44;  }  if (config->mtu)    mtu = config->mtu;  else    mtu = ETHERMTU;  if (config->rbuf_count)    sc->rxBdCount = config->rbuf_count;  else    sc->rxBdCount = RX_BUF_COUNT;  if (config->xbuf_count)    sc->txBdCount = config->xbuf_count;  else    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;  sc->acceptBroadcast = !config->ignore_broadcast;    /*   * Set up network interface values   */  ifp->if_softc = sc;  ifp->if_unit = i + 1;  ifp->if_name = "eth";  ifp->if_mtu = mtu;  ifp->if_init = scc_init;  ifp->if_ioctl = scc_ioctl;  ifp->if_start = m860_enet_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);  return 1;};intrtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config){  struct m860_enet_struct *sc;  struct ifnet *ifp;  int mtu;    /*   * Find a free driver   */  sc = &enet_driver[0];  ifp = &sc->arpcom.ac_if;  if (ifp->if_softc != NULL)    return 0;    /*   * Process options   */  if (config->hardware_address) {    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {    sc->arpcom.ac_enaddr[0] = 0x44;    sc->arpcom.ac_enaddr[1] = 0x22;    sc->arpcom.ac_enaddr[2] = 0x33;    sc->arpcom.ac_enaddr[3] = 0x33;    sc->arpcom.ac_enaddr[4] = 0x22;    sc->arpcom.ac_enaddr[5] = 0x44;  }  if (config->mtu)    mtu = config->mtu;  else    mtu = ETHERMTU;  if (config->rbuf_count)    sc->rxBdCount = config->rbuf_count;  else    sc->rxBdCount = RX_BUF_COUNT;  if (config->xbuf_count)    sc->txBdCount = config->xbuf_count;  else    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;  sc->acceptBroadcast = !config->ignore_broadcast;    /*   * Set up network interface values   */  ifp->if_softc = sc;  ifp->if_unit = 1;  ifp->if_name = "eth";  ifp->if_mtu = mtu;  ifp->if_init = fec_init;  ifp->if_ioctl = fec_ioctl;  ifp->if_start = m860_enet_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);  return 1;};intrtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config){  if ((m8xx.fec.mii_data & 0xffff) == 0x2000) {/*    rtems_scc1_driver_attach(config);*/    return rtems_fec_driver_attach(config);  }  else {    return rtems_scc1_driver_attach(config);  }}

⌨️ 快捷键说明

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