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

📄 network.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 3 页
字号:
       */      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;  }}#endif/* * Driver transmit daemon */voidscc_txDaemon (void *arg){  struct m8xx_enet_struct *sc = (struct m8xx_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;  }}#ifdef MPC860Tvoidfec_txDaemon (void *arg){  struct m8xx_enet_struct *sc = (struct m8xx_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;  }}#endif/* * Send packet (caller provides header). */static voidm8xx_enet_start (struct ifnet *ifp){  struct m8xx_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 m8xx_enet_struct *sc = arg;  struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0) {        /*     * Set up SCC hardware     */    m8xx_enet_initialize (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;}#ifdef MPC860Tstatic voidfec_init (void *arg){  struct m8xx_enet_struct *sc = arg;  struct ifnet *ifp = &sc->arpcom.ac_if;    if (sc->txDaemonTid == 0) {        /*     * Set up SCC hardware     */    m8xx_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;}#endif/* * Stop the device */static voidscc_stop (struct m8xx_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;}#ifdef MPC860Tstatic voidfec_stop (struct m8xx_enet_struct *sc){  struct ifnet *ifp = &sc->arpcom.ac_if;    ifp->if_flags &= ~IFF_RUNNING;    /*   * Shut down receiver and transmitter   */  m8xx.fec.ecntrl = 0x0;}#endif/* * Show interface statistics */static voidenet_stats (struct m8xx_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 m8xx_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;}#ifdef MPC860Tstatic intfec_ioctl (struct ifnet *ifp, int command, caddr_t data){  struct m8xx_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;}#endif/* * Attach an SCC driver to the system */intrtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config){  struct m8xx_enet_struct *sc;  struct ifnet *ifp;  int mtu;  int unitNumber;  char *unitName;#if NVRAM_CONFIGURE == 1  char *pAddr;  unsigned long addr;#endif	/*	 * Parse driver name	 */	if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)		return 0;	/*	 * Is driver free?	 */	if ((unitNumber <= 0) || (unitNumber > NIFACES)) {		printf ("Bad SCC unit number.\n");		return 0;	}	sc = &enet_driver[unitNumber - 1];	ifp = &sc->arpcom.ac_if;	if (ifp->if_softc != NULL) {		printf ("Driver already in use.\n");		return 0;	}    /*   * Process options   */#if NVRAM_CONFIGURE == 1   /* Configure from NVRAM */  if ( (addr = nvram->ipaddr) ) {    /* We have a non-zero entry, copy the value */    if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) )      config->ip_address = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );    else      rtems_panic("Can't allocate ip_address buffer!\n");  }    if ( (addr = nvram->netmask) ) {    /* We have a non-zero entry, copy the value */    if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) )      config->ip_netmask = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 );    else      rtems_panic("Can't allocate ip_netmask buffer!\n");  }  /* Ethernet address requires special handling -- it must be copied into   * the arpcom struct. The following if construct serves only to give the   * User Area NVRAM parameter the highest priority.   *    * If the ethernet address is specified in NVRAM, go ahead and copy it.   * (ETHER_ADDR_LEN = 6 bytes).   */  if ( nvram->enaddr[0] || nvram->enaddr[1] || nvram->enaddr[2] ) {    /* Anything in the first three bytes indicates a non-zero entry, copy value */  	memcpy ((void *)sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);  }  else if ( config->hardware_address ) {    /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */    memcpy ((void *)sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {    /* There is no ethernet address provided, so it could be read     * from the Ethernet protocol block of SCC1 in DPRAM.     */    rtems_panic("No Ethernet address specified!\n");  }    #else /* NVRAM_CONFIGURE != 1 */   if (config->hardware_address) {    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {    /* There is no ethernet address provided, so it could be read     * from the Ethernet protocol block of SCC1 in DPRAM.     */    rtems_panic("No Ethernet address specified!\n");  }  #endif /* NVRAM_CONFIGURE != 1 */  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 = unitNumber;  ifp->if_name = unitName;  ifp->if_mtu = mtu;  ifp->if_init = scc_init;  ifp->if_ioctl = scc_ioctl;  ifp->if_start = m8xx_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;};#ifdef MPC860Tintrtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config){  struct m8xx_enet_struct *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;	/*	 * Is driver free?	 */	if ((unitNumber <= 0) || (unitNumber > NIFACES)) {		printf ("Bad SCC unit number.\n");		return 0;	}	sc = &enet_driver[unitNumber - 1];	ifp = &sc->arpcom.ac_if;	if (ifp->if_softc != NULL) {		printf ("Driver already in use.\n");		return 0;	}    /*   * Process options   */  if (config->hardware_address) {    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);  }  else {		/* FIXME to read the enaddr from NVRAM */  }  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 = unitNumber;  ifp->if_name = unitName;  ifp->if_mtu = mtu;  ifp->if_init = fec_init;  ifp->if_ioctl = fec_ioctl;  ifp->if_start = m8xx_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;};#endifintrtems_enet_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching){  #ifdef MPC860T  if ((m8xx.fec.mii_data & 0xffff) == 0x2000) {/*    rtems_scc1_driver_attach(config);*/    return rtems_fec_driver_attach(config);  }  else {#endif    return rtems_scc1_driver_attach(config);#ifdef MPC860T  }#endif}

⌨️ 快捷键说明

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