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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
        rtems_bsdnet_event_receive (INTERRUPT_EVENT,                                    RTEMS_WAIT|RTEMS_EVENT_ANY,                                    RTEMS_NO_TIMEOUT,                                    &events);/*        printk( "Rxd " ); */      }    }        /*     * Check that packet is valid     */    if ((status & (M8260_BD_LAST |                   M8260_BD_FIRST_IN_FRAME |    		   M8260_BD_LONG |                   M8260_BD_NONALIGNED |                   M8260_BD_ABORT |                   M8260_BD_CRC_ERROR |                   M8260_BD_OVERRUN /*|                   M8260_BD_CARRIER_LOST*/)) ==                   (M8260_BD_LAST |                   M8260_BD_FIRST_IN_FRAME ) ) {/*      printk( "RxV " ); *//* * Invalidate the buffer for this descriptor */      rtems_cache_invalidate_multiple_data_lines((void *)rxBd->buffer, rxBd->length);      m = sc->rxMbuf[rxBdIndex];      /* strip off HDLC CRC */      m->m_len = m->m_pkthdr.len = rxBd->length - sizeof(rtems_unsigned16);      hdlc_input( ifp, m );      /*       * Allocate a new mbuf       */      MGETHDR (m, M_WAIT, MT_DATA);      MCLGET (m, M_WAIT);      m->m_pkthdr.rcvif = ifp;      sc->rxMbuf[rxBdIndex] = m;      rxBd->buffer = mtod (m, void *);    }    else {      printk( "RxErr[%04X,%d]", status, rxBd->length );      /*       * Something went wrong with the reception       */      if (!(status & M8260_BD_LAST))        sc->rxNotLast++;      if (!(status & M8260_BD_FIRST_IN_FRAME))        sc->rxNotFirst++;      if (status & M8260_BD_LONG)        sc->rxGiant++;      if (status & M8260_BD_NONALIGNED)        sc->rxNonOctet++;      if (status & M8260_BD_ABORT)        sc->rxAbort++;      if (status & M8260_BD_CRC_ERROR)        sc->rxBadCRC++;      if (status & M8260_BD_OVERRUN)        sc->rxOverrun++;      if (status & M8260_BD_CARRIER_LOST)        sc->rxLostCarrier++;    }        /*     * Reenable the buffer descriptor     */    rxBd->status = (status & (M8260_BD_WRAP | M8260_BD_INTERRUPT)) |                    M8260_BD_EMPTY;        /*     * Move to next buffer descriptor     */    if (++rxBdIndex == sc->rxBdCount)      rxBdIndex = 0;  }}static voidscc_sendpacket (struct ifnet *ifp, struct mbuf *m){  struct m8260_hdlc_struct *sc = ifp->if_softc;  volatile m8260BufferDescriptor_t *firstTxBd, *txBd;  struct mbuf *l = NULL;  rtems_unsigned16 status;  int nAdded;    /*   * Free up buffer descriptors   */  m8260Enet_retire_tx_bd (sc);    /*   * Set up the transmit buffer descriptors.   * No need to pad out short packets since the   * hardware takes care of that automatically.   * No need to copy the packet to a contiguous buffer   * since the hardware is capable of scatter/gather DMA.   */  nAdded = 0;  txBd = firstTxBd = sc->txBdBase + sc->txBdHead;/*  m8260.scc3.sccm |= (M8260_SCCE_TX | M8260_SCCE_TXE);*/  for (;;) {    /*     * Wait for buffer descriptor to become available.     */    if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {      /*       * Clear old events       */      m8260.scc3.scce = M8260_SCCE_TX | M8260_SCCE_TXE;            /*       * Wait for buffer descriptor to become available.       * Note that the buffer descriptors are checked       * *before* * entering the wait loop -- this catches       * the possibility that a buffer descriptor became       * available between the `if' above, and the clearing       * of the event register.       * This is to catch the case where the transmitter       * stops in the middle of a frame -- and only the       * last buffer descriptor in a frame can generate       * an interrupt.       */      m8260Enet_retire_tx_bd (sc);      while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {        rtems_event_set events;                /*         * Unmask TX (buffer transmitted) event         */        m8260.scc3.sccm |= (M8260_SCCE_TX | M8260_SCCE_TXE);        rtems_bsdnet_event_receive (INTERRUPT_EVENT,                                    RTEMS_WAIT|RTEMS_EVENT_ANY,                                    RTEMS_NO_TIMEOUT,                                    &events);        m8260Enet_retire_tx_bd (sc);      }    }        /*     * Don't set the READY flag till the     * whole packet has been readied.     */    status = nAdded ? M8260_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;      /*       * Flush the buffer for this descriptor       */      rtems_cache_flush_multiple_data_lines((void *)txBd->buffer, txBd->length);/* throw off the header for Ethernet Emulation mode *//*      txBd->buffer = mtod (m, void *);      txBd->buffer += sizeof( struct ether_header ) + 2;      txBd->length = m->m_len - sizeof( struct ether_header ) - 2;*/      sc->txMbuf[sc->txBdHead] = m;      nAdded++;      if (++sc->txBdHead == sc->txBdCount) {        status |= M8260_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 |= M8260_BD_LAST | M8260_BD_TX_CRC | M8260_BD_INTERRUPT;        txBd->status = status;        firstTxBd->status |= M8260_BD_READY;        sc->txBdActiveCount += nAdded;      }      break;    }    txBd->status = status;    txBd = sc->txBdBase + sc->txBdHead;  }}/* * Driver transmit daemon */voidscc_txDaemon (void *arg){  struct m8260_hdlc_struct *sc = (struct m8260_hdlc_struct *)arg;  struct ifnet *ifp = &sc->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;  }}/* * Send packet (caller provides header). */static voidm8260_hdlc_start (struct ifnet *ifp){  struct m8260_hdlc_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 m8260_hdlc_struct *sc = arg;  struct ifnet *ifp = &sc->ac_if;    if (sc->txDaemonTid == 0) {        /*     * Set up SCC hardware     */    m8260_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);      }  #if 0  /*   * Set flags appropriately   */  if (ifp->if_flags & IFF_PROMISC)    m8260.scc3.psmr |= 0x200;  else    m8260.scc3.psmr &= ~0x200;#endif  /*   * Tell the world that we're running.   */  ifp->if_flags |= IFF_RUNNING;    /*   * Enable receiver and transmitter   */  m8260.scc3.gsmr_l |= 0x30;}/* * Stop the device */static voidscc_stop (struct m8260_hdlc_struct *sc){  struct ifnet *ifp = &sc->ac_if;    ifp->if_flags &= ~IFF_RUNNING;    /*   * Shut down receiver and transmitter   */  m8260.scc3.gsmr_l &= ~0x30;}/* * Show interface statistics */static voidhdlc_stats (struct m8260_hdlc_struct *sc){  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);  printf ("              Giant:%-8lu", sc->rxGiant);  printf ("          Non-octet:%-8lu\n", sc->rxNonOctet);  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);  printf ("            Overrun:%-8lu", sc->rxOverrun);  printf ("         No Carrier:%-8lu\n", sc->rxLostCarrier);  printf ("          Discarded:%-8lu\n", (unsigned long)m8260.scc3p.un.hdlc.disfc);    printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);  printf ("         No Carrier:%-8lu", sc->txLostCarrier);  printf ("           Underrun:%-8lu\n", 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 m8260_hdlc_struct *sc = ifp->if_softc;  int error = 0;    switch (command) {  case SIOCGIFADDR:  case SIOCSIFADDR:    hdlc_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:    hdlc_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_scc3_driver_attach (struct rtems_bsdnet_ifconfig *config){  struct m8260_hdlc_struct *sc;  struct ifnet *ifp;  int mtu;  int i;    /*   * Find a free driver   */  for (i = 0 ; i < NIFACES ; i++) {    sc = &hdlc_driver[i];    ifp = &sc->ac_if;    if (ifp->if_softc == NULL)      break;  }  if (i >= NIFACES) {    printf ("Too many SCC drivers.\n");    return 0;  }#if 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;  }#endif  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 = m8260_hdlc_start;  ifp->if_output = hdlc_output;  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | /*IFF_PROMISC |*/ IFF_NOARP;  if (ifp->if_snd.ifq_maxlen == 0)    ifp->if_snd.ifq_maxlen = ifqmaxlen;    /*   * Attach the interface   */  if_attach (ifp);  hdlc_ifattach (ifp);  return 1;};intrtems_enet_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching){  return rtems_scc3_driver_attach( config );/*  if ((m8260.fec.mii_data & 0xffff) == 0x2000) {    return rtems_fec_driver_attach(config);  }  else {    return rtems_scc1_driver_attach(config);  }*/}

⌨️ 快捷键说明

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