From 031df3914990db0336a0d386fb53558b05de467e Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Apr 2018 09:53:31 +0200 Subject: bsps: Move legacy network drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c | 647 ---------------------------- 1 file changed, 647 deletions(-) delete mode 100644 c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c (limited to 'c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c') diff --git a/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c b/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c deleted file mode 100644 index d10361bf2c..0000000000 --- a/c/src/lib/libbsp/i386/pc386/wd8003/wd8003.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * RTEMS driver for WD800x - * - * Based on the 68360 Network Driver by: - * W. Eric Norum - * Saskatchewan Accelerator Laboratory - * University of Saskatchewan - * Saskatoon, Saskatchewan, CANADA - * eric@skatter.usask.ca - */ - -#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ - -#include -#include - -#include -#include -#include /* memcpy, memset */ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#define ET_MINLEN 60 /* minimum message length */ - -/* - * Number of WDs supported by this driver - */ -#define NWDDRIVER 1 - -/* - * Default number of buffer descriptors set aside for this driver. - * The number of transmit buffer descriptors has to be quite large - * since a single frame often uses four or more buffer descriptors. - */ -#define RX_BUF_COUNT 15 -#define TX_BUF_COUNT 4 -#define TX_BD_PER_BUF 4 - -/* - * RTEMS event used by interrupt handler to signal driver tasks. - * This must not be any of the events used by the network task synchronization. - */ -#define INTERRUPT_EVENT RTEMS_EVENT_1 - -/* - * RTEMS event used to start transmit daemon. - * This must not be the same as INTERRUPT_EVENT. - */ -#define START_TRANSMIT_EVENT RTEMS_EVENT_2 - -/* - * Receive buffer size -- Allow for a full ethernet packet including CRC - */ -#define RBUF_SIZE 1520 - -#if (MCLBYTES < RBUF_SIZE) -# error "Driver must have MCLBYTES > RBUF_SIZE" -#endif - -/* - * Per-device data - */ -struct wd_softc { - struct arpcom arpcom; - struct mbuf **rxMbuf; - struct mbuf **txMbuf; - int acceptBroadcast; - int rxBdCount; - int txBdCount; - int txBdHead; - int txBdTail; - int txBdActiveCount; - rtems_id rxDaemonTid; - rtems_id txDaemonTid; - rtems_vector_number name; - - unsigned int port; - unsigned char *base; - unsigned long bpar; - - /* - * Statistics - */ - unsigned long rxInterrupts; - unsigned long rxNotFirst; - unsigned long rxNotLast; - unsigned long rxGiant; - unsigned long rxNonOctet; - unsigned long rxRunt; - unsigned long rxBadCRC; - unsigned long rxOverrun; - unsigned long rxCollision; - - unsigned long txInterrupts; - unsigned long txDeferred; - unsigned long txHeartbeat; - unsigned long txLateCollision; - unsigned long txRetryLimit; - unsigned long txUnderrun; - unsigned long txLostCarrier; - unsigned long txRawWait; -}; - -#define RO 0x10 - -#define SHATOT (8*1024) /* size of shared memory */ -#define SHAPAGE 256 /* shared memory information */ -#define MAXSIZ 1536 /*(MAXBUF - MESSH_SZ)*/ -#define OUTPAGE ((SHATOT-(MAXSIZ+SHAPAGE-1))/SHAPAGE) - -static volatile unsigned long overrun; -static volatile unsigned long resend; -static struct wd_softc wd_softc[NWDDRIVER]; - -/* - * WD interrupt handler - */ -static void -wd8003Enet_interrupt_handler (void * unused) -{ - unsigned int tport; - unsigned char status, status2; - - tport = wd_softc[0].port ; - - /* - * Read status - */ - inport_byte(tport+ISR, status); - outport_byte(tport+IMR, 0x00); - - /* - * Ring overwrite - */ - - if (status & MSK_OVW){ - outport_byte(tport+CMDR, MSK_STP + MSK_RD2); /* stop 8390 */ - Wait_X_ms(2); - outport_byte(tport+RBCR0, 0); /* clear byte count */ - outport_byte(tport+RBCR1, 0); - inport_byte(tport+ISR, status2); - status |= (status2 & (MSK_PTX+MSK_TXE)) ; /* TX status */ - outport_byte(tport+TCR, MSK_LOOP); /* loopback mode */ - outport_byte(tport+CMDR, MSK_STA + MSK_RD2); /* start */ - overrun = 1 ; - if ((status & (MSK_PTX+MSK_TXE)) == 0) - resend = 1; - } - - /* - * Frame received? - */ - if (status & (MSK_PRX+MSK_RXE)) { - outport_byte(tport+ISR, status & (MSK_PRX+MSK_RXE)); - wd_softc[0].rxInterrupts++; - rtems_bsdnet_event_send (wd_softc[0].rxDaemonTid, INTERRUPT_EVENT); - } - -} - -/* - * Initialize the ethernet hardware - */ -static void -wd8003Enet_initialize_hardware (struct wd_softc *sc) -{ - int i1, ultra; - char cc1, cc2; - unsigned char temp; - rtems_status_code status; - unsigned int tport; - unsigned char *hwaddr; - - tport = sc->port; - - /* address from board ROM */ - inport_byte(tport+0x04, temp); - outport_byte(tport+0x04, temp & 0x7f); - - hwaddr = sc->arpcom.ac_enaddr; - for (i1=cc2=0; i1<8; i1++) { - inport_byte(tport + ADDROM + i1, cc1); - cc2 += cc1; - if (i1 < 6) - hwaddr[i1] = cc1; - } - - inport_byte(tport+0x04, temp); - outport_byte(tport+0x04, temp | 0x80); /* alternate registers */ - outport_byte(tport+W83CREG, MSK_RESET); /* reset board, set buffer */ - outport_byte(tport+W83CREG, 0); - outport_byte(tport+W83CREG, MSK_ENASH + (int)((sc->bpar>>13)&0x3f)); - - outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2); - cc1 = MSK_BMS + MSK_FT10; /* configure 8 or 16 bits */ - - inport_byte(tport+0x07, temp) ; - - ultra = ((temp & 0xf0) == 0x20 || (temp & 0xf0) == 0x40); - if (ultra) - cc1 = MSK_WTS + MSK_BMS + MSK_FT10; - outport_byte(tport+DCR, cc1); - outport_byte(tport+RBCR0, 0); - outport_byte(tport+RBCR1, 0); - outport_byte(tport+RCR, MSK_MON); /* disable the rxer */ - outport_byte(tport+TCR, 0); /* normal operation */ - outport_byte(tport+PSTOP, OUTPAGE); /* init PSTOP */ - outport_byte(tport+PSTART, 0); /* init PSTART */ - outport_byte(tport+BNRY, -1); /* init BNRY */ - outport_byte(tport+ISR, -1); /* clear IR's */ - outport_byte(tport+IMR, 0x15); /* enable interrupt */ - - outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2); - - for (i1=0; i1<6; i1++) /* initial physical addr */ - outport_byte(tport+PAR+i1, hwaddr[i1]); - - for (i1=0; i1name, - "wd8003", - RTEMS_INTERRUPT_UNIQUE, - wd8003Enet_interrupt_handler, - NULL - ); - assert(status == RTEMS_SUCCESSFUL); -} - -static void -wd_rxDaemon (void *arg) -{ - unsigned int tport; - struct ether_header *eh; - struct wd_softc *dp = (struct wd_softc *)&wd_softc[0]; - struct ifnet *ifp = &dp->arpcom.ac_if; - struct mbuf *m; - unsigned int i2; - unsigned int len; - volatile unsigned char start, next, current; - unsigned char *shp, *temp; - unsigned short *real_short_ptr; - rtems_event_set events; - - tport = wd_softc[0].port ; - - for (;;){ - - rtems_bsdnet_event_receive (INTERRUPT_EVENT, - RTEMS_WAIT|RTEMS_EVENT_ANY, - RTEMS_NO_TIMEOUT, - &events); - - for (;;){ - inport_byte(tport+BNRY, start); - - outport_byte(tport+CMDR, MSK_PG1 + MSK_RD2); - inport_byte(tport+CURR, current); - outport_byte(tport+CMDR, MSK_PG0 + MSK_RD2); - - start += 1; - if (start >= OUTPAGE){ - start = 0; - } - - if (current == start) - break; - - /* real_short_ptr avoids cast on lvalue which gcc no longer allows */ - shp = dp->base + 1 + (SHAPAGE * start); - next = *shp++; - real_short_ptr = (unsigned short *)shp; - len = *(real_short_ptr)++ - 4; - - if (next >= OUTPAGE){ - next = 0; - } - - MGETHDR (m, M_WAIT, MT_DATA); - MCLGET (m, M_WAIT); - m->m_pkthdr.rcvif = ifp; - - temp = (unsigned char *) m->m_data; - m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header); - - if ((i2 = (OUTPAGE - start) * SHAPAGE - 4) < len){ - memcpy(temp, shp, i2); - len -= i2; - temp += i2; - shp = dp->base; - } - memcpy(temp, shp, len); - - eh = mtod (m, struct ether_header *); - m->m_data += sizeof(struct ether_header); - ether_input (ifp, eh, m); - - outport_byte(tport+BNRY, next-1); - } - - /* - * Ring overwrite - */ - if (overrun){ - outport_byte(tport+ISR, MSK_OVW); /* reset IR */ - outport_byte(tport+TCR, 0); /* out of loopback */ - if (resend == 1) - outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); /* resend */ - resend = 0; - overrun = 0; - } - - outport_byte(tport+IMR, 0x15); /* re-enable IT rx */ - } -} - -static void -sendpacket (struct ifnet *ifp, struct mbuf *m) -{ - struct wd_softc *dp = ifp->if_softc; - struct mbuf *n; - unsigned int len, tport; - uint8_t *shp, txReady; - - tport = dp->port; - - /* - * Waiting for Transmitter ready - */ - inport_byte(tport+CMDR, txReady); - while(txReady & MSK_TXP) - inport_byte(tport+CMDR, txReady); - - len = 0; - shp = dp->base + (SHAPAGE * OUTPAGE); - - n = m; - - for (;;){ - len += m->m_len; - memcpy(shp, (char *)m->m_data, m->m_len); - shp += m->m_len ; - if ((m = m->m_next) == NULL) - break; - } - - m_freem(n); - - if (len < ET_MINLEN) len = ET_MINLEN; - outport_byte(tport+TBCR0, len); - outport_byte(tport+TBCR1, (len >> 8) ); - outport_byte(tport+TPSR, OUTPAGE); - outport_byte(tport+CMDR, MSK_TXP + MSK_RD2); -} - -/* - * Driver transmit daemon - */ -static void -wd_txDaemon (void *arg) -{ - struct wd_softc *sc = (struct wd_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); - - /* - * 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; - } -} - -/* - * Send packet (caller provides header). - */ -static void -wd_start (struct ifnet *ifp) -{ - struct wd_softc *sc = ifp->if_softc; - - rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT); - ifp->if_flags |= IFF_OACTIVE; -} - -/* - * Initialize and start the device - */ -static void -wd_init (void *arg) -{ - struct wd_softc *sc = arg; - struct ifnet *ifp = &sc->arpcom.ac_if; - - if (sc->txDaemonTid == 0) { - - /* - * Set up WD hardware - */ - wd8003Enet_initialize_hardware (sc); - - /* - * Start driver tasks - */ - sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, wd_txDaemon, sc); - sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, wd_rxDaemon, sc); - } - - /* - * Tell the world that we're running. - */ - ifp->if_flags |= IFF_RUNNING; - -} - -/* - * Stop the device - */ -static void -wd_stop (struct wd_softc *sc) -{ - unsigned int tport; - unsigned char temp; - struct ifnet *ifp = &sc->arpcom.ac_if; - - ifp->if_flags &= ~IFF_RUNNING; - - /* - * Stop the transmitter - */ - tport=wd_softc[0].port ; - inport_byte(tport+0x04,temp); - outport_byte(tport+0x04, temp & 0x7f); - outport_byte(tport + CMDR, MSK_STP + MSK_RD2); - -} - -/* - * Show interface statistics - */ -static void -wd_stats (struct wd_softc *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 (" 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 int -wd_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data) -{ - struct wd_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: - wd_stop (sc); - break; - - case IFF_UP: - wd_init (sc); - break; - - case IFF_UP | IFF_RUNNING: - wd_stop (sc); - wd_init (sc); - break; - - default: - break; - } - break; - - case SIO_RTEMS_SHOW_STATS: - wd_stats (sc); - break; - - /* - * FIXME: All sorts of multicast commands need to be added here! - */ - default: - error = EINVAL; - break; - } - return error; -} - -/* - * Attach an WD driver to the system - */ -int -rtems_wd_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach) -{ - struct wd_softc *sc; - struct ifnet *ifp; - int mtu; - int i; - - /* - * Find a free driver - */ - for (i = 0 ; i < NWDDRIVER ; i++) { - sc = &wd_softc[i]; - ifp = &sc->arpcom.ac_if; - if (ifp->if_softc == NULL) - break; - } - if (i >= NWDDRIVER) { - printf ("Too many WD drivers.\n"); - return 0; - } - - /* - * Process options - */ - 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; - - if (config->irno) - sc->name = config->irno; - else - sc->name = 5; - - if (config->port) - sc->port = config->port; - else - sc->port = 0x240; - - if (config->bpar) { - sc->bpar = config->bpar; - sc->base = (unsigned char*) config->bpar; - } - else { - sc->bpar = 0xD0000; - sc->base = (unsigned char*) 0xD0000; - } - - sc->acceptBroadcast = !config->ignore_broadcast; - - /* - * Set up network interface values - */ - ifp->if_softc = sc; - ifp->if_unit = i + 1; - ifp->if_name = "wd"; - ifp->if_mtu = mtu; - ifp->if_init = wd_init; - ifp->if_ioctl = wd_ioctl; - ifp->if_start = wd_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; - - /* - * init some variables - */ - overrun = 0; - resend = 0; - - /* - * Attach the interface - */ - if_attach (ifp); - ether_ifattach (ifp); - return 1; -}; -- cgit v1.2.3