📄 network.c
字号:
*/ 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 + -