📄 greth.c
字号:
#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 + -