summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:53:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit031df3914990db0336a0d386fb53558b05de467e (patch)
tree4661e22f0cdb3f9d06879f0194b77c75f62bac79 /c/src/lib/libbsp/m68k
parentbsps: Move interrupt controller support to bsps (diff)
downloadrtems-031df3914990db0336a0d386fb53558b05de467e.tar.bz2
bsps: Move legacy network drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/m68k')
-rw-r--r--c/src/lib/libbsp/m68k/av5282/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/av5282/network/network.c940
-rw-r--r--c/src/lib/libbsp/m68k/csb360/network/network.c984
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/gen68360/network/network.c1062
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/genmcf548x/network/network.c1696
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mcf5235/network/network.c879
-rw-r--r--c/src/lib/libbsp/m68k/mcf5329/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mcf5329/network/network.c857
-rw-r--r--c/src/lib/libbsp/m68k/mvme162/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/network/network.c3099
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/network/uti596.h369
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/Makefile.am2
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/network/network.c1013
17 files changed, 8 insertions, 10907 deletions
diff --git a/c/src/lib/libbsp/m68k/av5282/Makefile.am b/c/src/lib/libbsp/m68k/av5282/Makefile.am
index 91f578f08a..456dd8a95f 100644
--- a/c/src/lib/libbsp/m68k/av5282/Makefile.am
+++ b/c/src/lib/libbsp/m68k/av5282/Makefile.am
@@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/av5282/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/av5282/btimer/btimer.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/av5282/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf5282.c
diff --git a/c/src/lib/libbsp/m68k/av5282/network/network.c b/c/src/lib/libbsp/m68k/av5282/network/network.c
deleted file mode 100644
index 457b43c5d6..0000000000
--- a/c/src/lib/libbsp/m68k/av5282/network/network.c
+++ /dev/null
@@ -1,940 +0,0 @@
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 1
-
-#define FEC_INTC0_TX_VECTOR (64+23)
-#define FEC_INTC0_RX_VECTOR (64+27)
-
-#define FEC_INTC0_TX_VECTOR (64+23)
-#define FEC_INTC0_RX_VECTOR (64+27)
-#define MII_VECTOR (64+7) /* IRQ7* pin connected to external transceiver */
-#define MII_EPPAR MCF5282_EPORT_EPPAR_EPPA7_LEVEL
-#define MII_EPDDR MCF5282_EPORT_EPDDR_EPDD7
-#define MII_EPIER MCF5282_EPORT_EPIER_EPIE7
-#define MII_EPPDR MCF5282_EPORT_EPPDR_EPPD7
-/*
- * 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 three or more buffer descriptors.
- */
-#define RX_BUF_COUNT 32
-#define TX_BUF_COUNT 20
-#define TX_BD_PER_BUF 3
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP task synchronization.
- */
-#define TX_INTERRUPT_EVENT RTEMS_EVENT_1
-#define RX_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 plus CRC (1518).
- * Round off to nearest multiple of RBUF_ALIGN.
- */
-#define MAX_MTU_SIZE 1518
-#define RBUF_ALIGN 4
-#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
-
-#if (MCLBYTES < RBUF_SIZE)
- #error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-typedef struct mcf5282BufferDescriptor_ {
- volatile uint16_t status;
- uint16_t length;
- volatile void *buffer;
-} mcf5282BufferDescriptor_t;
-
-/*
- * Per-device data
- */
-struct mcf5282_enet_struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- mcf5282BufferDescriptor_t *rxBdBase;
- mcf5282BufferDescriptor_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long txInterrupts;
- unsigned long miiInterrupts;
- unsigned long txRawWait;
- unsigned long txRealign;
- unsigned long txRealignDrop;
- uint16_t mii_sr2;
-};
-static struct mcf5282_enet_struct enet_driver[NIFACES];
-
-static int
-getMII(int phyNumber, int regNumber);
-
-
-static rtems_isr
-mcf5282_fec_rx_interrupt_handler( rtems_vector_number v )
-{
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
- MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_RXF;
- enet_driver[0].rxInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5282_fec_tx_interrupt_handler( rtems_vector_number v )
-{
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
- MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF;
- enet_driver[0].txInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5282_mii_interrupt_handler( rtems_vector_number v )
-{
- uint16_t sr2;
-
- enet_driver[0].miiInterrupts++;
- getMII(1, 19); /* Read and clear interrupt status bits */
- enet_driver[0].mii_sr2 = sr2 = getMII(1, 17);
- if (((sr2 & 0x200) != 0)
- && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) == 0))
- MCF5282_FEC_TCR |= MCF5282_FEC_TCR_FDEN;
- else if (((sr2 & 0x200) == 0)
- && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) != 0))
- MCF5282_FEC_TCR &= ~MCF5282_FEC_TCR_FDEN;
-}
-
-/*
- * Allocate buffer descriptors from (non-cached) on-chip static RAM
- * Ensure 128-bit (16-byte) alignment
- */
-extern char __SRAMBASE[];
-
-static mcf5282BufferDescriptor_t *
-mcf5282_bd_allocate(unsigned int count)
-{
- static mcf5282BufferDescriptor_t *bdp = (mcf5282BufferDescriptor_t *)__SRAMBASE;
- mcf5282BufferDescriptor_t *p = bdp;
-
- bdp += count;
- if ((int)bdp & 0xF)
- bdp = (mcf5282BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
- return p;
-}
-
-
-/*
- * Read MII register
- * Busy-waits, but transfer time should be short!
- */
-static int
-getMII(int phyNumber, int regNumber)
-{
- MCF5282_FEC_MMFR = (0x1 << 30) |
- (0x2 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16);
- while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0);
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII;
- return MCF5282_FEC_MMFR & 0xFFFF;
-}
-
-
-/*
- * Write MII register
- * Busy-waits, but transfer time should be short!
- */
-static void
-setMII(int phyNumber, int regNumber, int value)
-{
- MCF5282_FEC_MMFR = (0x1 << 30) |
- (0x1 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16) |
- (value & 0xFFFF);
- while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0);
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII;
-}
-
-static void
-mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc)
-{
- int i;
- const unsigned char *hwaddr;
- rtems_status_code status;
- rtems_isr_entry old_handler;
- uint32_t clock_speed = get_CPU_clock_speed();
-
- /*
- * Issue reset to FEC
- */
- MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET;
- rtems_task_wake_after(1);
- MCF5282_FEC_ECR = 0;
-
- /*
- * Configuration of I/O ports is done outside of this function
- */
-#if 0
- imm->gpio.pbcnt |= MCF5282_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
-#endif
-
- /*
- * Set our physical address
- */
- hwaddr = sc->arpcom.ac_enaddr;
- MCF5282_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
- (hwaddr[2] << 8) | (hwaddr[3] << 0);
- MCF5282_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
-
-
- /*
- * Clear the hash table
- */
- MCF5282_FEC_GAUR = 0;
- MCF5282_FEC_GALR = 0;
-
- /*
- * Set up receive buffer size
- */
- MCF5282_FEC_EMRBR = 1520; /* Standard Ethernet */
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf)
- rtems_panic("No memory for mbuf pointers");
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = mcf5282_bd_allocate(sc->rxBdCount);
- sc->txBdBase = mcf5282_bd_allocate(sc->txBdCount);
- MCF5282_FEC_ERDSR = (int)sc->rxBdBase;
- MCF5282_FEC_ETDSR = (int)sc->txBdBase;
-
- /*
- * Set up Receive Control Register:
- * Not promiscuous
- * MII mode
- * Full duplex
- * No loopback
- */
- MCF5282_FEC_RCR = MCF5282_FEC_RCR_MAX_FL(MAX_MTU_SIZE) |
- MCF5282_FEC_RCR_MII_MODE;
-
- /*
- * Set up Transmit Control Register:
- * Full duplex
- * No heartbeat
- */
- MCF5282_FEC_TCR = MCF5282_FEC_TCR_FDEN;
-
- /*
- * Initialize statistic counters
- */
- MCF5282_FEC_MIBC = MCF5282_FEC_MIBC_MIB_DISABLE;
- {
- vuint32 *vuip = &MCF5282_FEC_RMON_T_DROP;
- while (vuip <= &MCF5282_FEC_IEEE_R_OCTETS_OK)
- *vuip++ = 0;
- }
- MCF5282_FEC_MIBC = 0;
-
- /*
- * Set MII speed to <= 2.5 MHz
- */
- i = (clock_speed + 5000000 - 1) / 5000000;
- MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(i);
-
- /*
- * Set PHYS to 100 Mb/s, full duplex
- */
- setMII(1, 0, 0x2100);
- setMII(1, 4, 0x0181);
- setMII(1, 0, 0x0000);
- rtems_task_wake_after(2);
- sc->mii_sr2 = getMII(1, 17);
- setMII(1, 18, 0x0072);
- setMII(1, 0, 0x1000);
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0 ; i < sc->rxBdCount ; i++)
- (sc->rxBdBase + i)->status = 0;
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0 ; i < sc->txBdCount ; i++) {
- sc->txBdBase[i].status = 0;
- sc->txMbuf[i] = NULL;
- }
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Set up interrupts
- */
- status = rtems_interrupt_catch( mcf5282_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler );
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC TX interrupt handler: %s\n",
- rtems_status_text(status));
- status = rtems_interrupt_catch(mcf5282_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC RX interrupt handler: %s\n",
- rtems_status_text(status));
- MCF5282_INTC0_ICR23 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5282_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY);
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT23 | MCF5282_INTC_IMRL_MASKALL);
- MCF5282_INTC0_ICR27 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5282_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY);
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT27 | MCF5282_INTC_IMRL_MASKALL);
-
- status = rtems_interrupt_catch(mcf5282_mii_interrupt_handler, MII_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC MII interrupt handler: %s\n",
- rtems_status_text(status));
- MCF5282_EPORT_EPPAR &= ~MII_EPPAR;
- MCF5282_EPORT_EPDDR &= ~MII_EPDDR;
- MCF5282_EPORT_EPIER |= MII_EPIER;
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT7 | MCF5282_INTC_IMRL_MASKALL);
-}
-
-/*
- * Soak up buffer descriptors that have been sent.
- */
-void
-fec_retire_tx_bd(volatile struct mcf5282_enet_struct *sc )
-{
- struct mbuf *m, *n;
- uint16_t status;
-
- while ((sc->txBdActiveCount != 0)
- && (((status = sc->txBdBase[sc->txBdTail].status) & MCF5282_FEC_TxBD_R) == 0)) {
- if ((status & MCF5282_FEC_TxBD_TO1) == 0) {
- m = sc->txMbuf[sc->txBdTail];
- MFREE(m, n);
- }
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- sc->txBdActiveCount--;
- }
-}
-
-static void
-fec_rxDaemon (void *arg)
-{
- volatile struct mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg;
- struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
- struct mbuf *m;
- volatile uint16_t status;
- volatile mcf5282BufferDescriptor_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0 ; ;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR(m, M_WAIT, MT_DATA);
- MCLGET(m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod(m, void *);
- rxBd->status = MCF5282_FEC_RxBD_E;
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= MCF5282_FEC_RxBD_W;
- break;
- }
- }
-
- /*
- * Input packet handling loop
- */
- /* Indicate we have some ready buffers available */
- MCF5282_FEC_RDAR = 0;
-
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
- /*
- * Clear old events.
- */
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
-
- /*
- * Wait for packet to arrive.
- * Check the buffer descriptor before waiting for the event.
- * This catches the case when a packet arrives between the
- * `if' above, and the clearing of the RXF bit in the EIR.
- */
- while ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_RXF;
- rtems_interrupt_enable(level);
- rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- }
-
- /*
- * Check that packet is valid
- */
- if (status & MCF5282_FEC_RxBD_L) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
- int len = rxBd->length - sizeof(uint32_t);
-
- /*
- * Invalidate the cache and push the packet up.
- * The cache is so small that it's more efficient to just
- * invalidate the whole thing unless the packet is very small.
- */
- m = sc->rxMbuf[rxBdIndex];
- if (len < 128)
- rtems_cache_invalidate_multiple_data_lines(m->m_data, len);
- else
- rtems_cache_invalidate_entire_data();
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input(ifp, eh, 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 *);
- }
-
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & MCF5282_FEC_RxBD_W) | MCF5282_FEC_RxBD_E;
- MCF5282_FEC_RDAR = 0;
-
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount)
- rxBdIndex = 0;
- }
-}
-
-static void
-fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
-{
- struct mcf5282_enet_struct *sc = ifp->if_softc;
- volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd;
- int nAdded;
- uint16_t status;
-
- /*
- * Free up buffer descriptors
- */
- fec_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;
- firstTxBd = sc->txBdBase + sc->txBdHead;
-
- while(m != NULL) {
- /*
- * Wait for buffer descriptor to become available
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events.
- */
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
-
- /*
- * Wait for buffer descriptor to become available.
- * Check for buffer descriptors before waiting for the event.
- * This catches the case when a buffer became available between
- * the `if' above, and the clearing of the TXF bit in the EIR.
- */
- fec_retire_tx_bd(sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_TXF;
- rtems_interrupt_enable(level);
- sc->txRawWait++;
- rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- fec_retire_tx_bd(sc);
- }
- }
-
- /*
- * Don't set the READY flag on the first fragment
- * until the whole packet has been readied.
- */
- status = nAdded ? MCF5282_FEC_TxBD_R : 0;
-
- /*
- * The IP fragmentation routine in ip_output
- * can produce fragments with zero length.
- */
- if (m->m_len){
- char *p = mtod(m, char *);
- int offset = (int) p & 0x3;
- txBd = sc->txBdBase + sc->txBdHead;
- if (offset == 0) {
- txBd->buffer = p;
- txBd->length = m->m_len;
- sc->txMbuf[sc->txBdHead] = m;
- m = m->m_next;
- }
- else {
- /*
- * Stupid FEC can't handle misaligned data!
- * Move offending bytes to a local buffer.
- * Use buffer descriptor TO1 bit to indicate this.
- */
- int nmove = 4 - offset;
- char *d = (char *)&sc->txMbuf[sc->txBdHead];
- status |= MCF5282_FEC_TxBD_TO1;
- sc->txRealign++;
- if (nmove > m->m_len)
- nmove = m->m_len;
- m->m_data += nmove;
- m->m_len -= nmove;
- txBd->buffer = d;
- txBd->length = nmove;
- while (nmove--)
- *d++ = *p++;
- if (m->m_len == 0) {
- struct mbuf *n;
- sc->txRealignDrop++;
- MFREE(m, n);
- m = n;
- }
- }
- nAdded++;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= MCF5282_FEC_TxBD_W;
- sc->txBdHead = 0;
- }
- txBd->status = status;
- }
- else {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
- MFREE(m, n);
- m = n;
- }
- }
- if (nAdded) {
- txBd->status = status | MCF5282_FEC_TxBD_R
- | MCF5282_FEC_TxBD_L
- | MCF5282_FEC_TxBD_TC;
- if (nAdded > 1)
- firstTxBd->status |= MCF5282_FEC_TxBD_R;
- MCF5282_FEC_TDAR = 0;
- sc->txBdActiveCount += nAdded;
- }
-}
-
-void
-fec_txDaemon(void *arg)
-{
- struct mcf5282_enet_struct *sc = (struct mcf5282_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;
- }
-}
-
-
-/*
- * Send packet (caller provides header).
- */
-static void
-mcf5282_enet_start(struct ifnet *ifp)
-{
- struct mcf5282_enet_struct *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-static void
-fec_init(void *arg)
-{
- struct mcf5282_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
- /*
- * Set up hardware
- */
- mcf5282_fec_initialize_hardware(sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc);
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- MCF5282_FEC_RCR |= MCF5282_FEC_RCR_PROM;
- else
- MCF5282_FEC_RCR &= ~MCF5282_FEC_RCR_PROM;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- MCF5282_FEC_ECR = MCF5282_FEC_ECR_ETHER_EN;
-}
-
-
-static void
-fec_stop(struct mcf5282_enet_struct *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- MCF5282_FEC_ECR = 0x0;
-}
-
-/*
- * Show interface statistics
- */
-static void
-enet_stats(struct mcf5282_enet_struct *sc)
-{
- printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
- printf("Rx Packet Count:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_PACKETS);
- printf(" Rx Broadcast:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_BC_PKT);
- printf(" Rx Multicast:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_MC_PKT);
- printf("CRC/Align error:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_CRC_ALIGN);
- printf(" Rx Undersize:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_UNDERSIZE);
- printf(" Rx Oversize:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_OVERSIZE);
- printf(" Rx Fragment:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_FRAG);
- printf(" Rx Jabber:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_JAB);
- printf(" Rx 64:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P64);
- printf(" Rx 65-127:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P65T0127);
- printf(" Rx 128-255:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_P128TO255);
- printf(" Rx 256-511:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P256TO511);
- printf(" Rx 511-1023:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P512TO1023);
- printf(" Rx 1024-2047:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_P1024TO2047);
- printf(" Rx >=2048:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_GTE2048);
- printf(" Rx Octets:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_OCTETS);
- printf(" Rx Dropped:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_DROP);
- printf(" Rx frame OK:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_FRAME_OK);
- printf(" Rx CRC error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_CRC);
- printf(" Rx Align error:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_ALIGN);
- printf(" FIFO Overflow:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_MACERR);
- printf("Rx Pause Frames:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_FDXFC);
- printf(" Rx Octets OK:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_OCTETS_OK);
- printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
- printf("Tx Output Waits:%-10lu", sc->txRawWait);
- printf("Tx mbuf realign:%-10lu\n", sc->txRealign);
- printf("Tx realign drop:%-10lu", sc->txRealignDrop);
- printf(" Tx Unaccounted:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_DROP);
- printf("Tx Packet Count:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_PACKETS);
- printf(" Tx Broadcast:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_BC_PKT);
- printf(" Tx Multicast:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_MC_PKT);
- printf("CRC/Align error:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_CRC_ALIGN);
- printf(" Tx Undersize:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_UNDERSIZE);
- printf(" Tx Oversize:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_OVERSIZE);
- printf(" Tx Fragment:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_FRAG);
- printf(" Tx Jabber:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_JAB);
- printf(" Tx Collisions:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_COL);
- printf(" Tx 64:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P64);
- printf(" Tx 65-127:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P65TO127);
- printf(" Tx 128-255:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P128TO255);
- printf(" Tx 256-511:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P256TO511);
- printf(" Tx 511-1023:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P512TO1023);
- printf(" Tx 1024-2047:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P1024TO2047);
- printf(" Tx >=2048:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P_GTE2048);
- printf(" Tx Octets:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_OCTETS);
- printf(" Tx Dropped:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_DROP);
- printf(" Tx Frame OK:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_FRAME_OK);
- printf(" Tx 1 Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_1COL);
- printf("Tx >1 Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_MCOL);
- printf(" Tx Deferred:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_DEF);
- printf(" Late Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_LCOL);
- printf(" Excessive Coll:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_EXCOL);
- printf(" FIFO Underrun:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_MACERR);
- printf(" Carrier Error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_CSERR);
- printf(" Tx SQE Error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_SQE);
- printf("Tx Pause Frames:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_FDXFC);
- printf(" Tx Octets OK:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_OCTETS_OK);
- printf(" MII interrupts:%-10lu\n", sc->miiInterrupts);
-
- printf(" EIR:%8.8lx ", (uint32_t) MCF5282_FEC_EIR);
- printf("EIMR:%8.8lx ", (uint32_t) MCF5282_FEC_EIMR);
- printf("RDAR:%8.8lx ", (uint32_t) MCF5282_FEC_RDAR);
- printf("TDAR:%8.8lx\n", (uint32_t) MCF5282_FEC_TDAR);
- printf(" ECR:%8.8lx ", (uint32_t) MCF5282_FEC_ECR);
- printf(" RCR:%8.8lx ", (uint32_t) MCF5282_FEC_RCR);
- printf(" TCR:%8.8lx\n", (uint32_t) MCF5282_FEC_TCR);
- printf("FRBR:%8.8lx ", (uint32_t) MCF5282_FEC_FRBR);
- printf("FRSR:%8.8lx\n", (uint32_t) MCF5282_FEC_FRSR);
- if (sc->txBdActiveCount != 0) {
- int i, n;
- /*
- * Yes, there are races here with adding and retiring descriptors,
- * but this diagnostic is more for when things have backed up.
- */
- printf("Transmit Buffer Descriptors (Tail %d, Head %d, Unretired %d):\n",
- sc->txBdTail,
- sc->txBdHead,
- sc->txBdActiveCount);
- i = sc->txBdTail;
- for (n = 0 ; n < sc->txBdCount ; n++) {
- if ((sc->txBdBase[i].status & MCF5282_FEC_TxBD_R) != 0)
- printf(" %3d: status:%4.4x length:%-4d buffer:%p\n",
- i,
- sc->txBdBase[i].status,
- sc->txBdBase[i].length,
- sc->txBdBase[i].buffer);
- if (++i == sc->txBdCount)
- i = 0;
- }
- }
-}
-
-static int
-fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct mcf5282_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;
-}
-
-int
-rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching )
-{
- struct mcf5282_enet_struct *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
- unsigned char *hwaddr;
-
- /*
- * 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 FEC 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
- */
- printf("%s%d: Ethernet address: ", unitName, unitNumber );
- if (config->hardware_address) {
- hwaddr = config->hardware_address;
- printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
- hwaddr[0], hwaddr[1], hwaddr[2],
- hwaddr[3], hwaddr[4], hwaddr[5]);
- memcpy(sc->arpcom.ac_enaddr, hwaddr, ETHER_ADDR_LEN);
- } else {
- printf("UNKNOWN\n");
- }
-
- 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 = mcf5282_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;
-};
-
diff --git a/c/src/lib/libbsp/m68k/csb360/network/network.c b/c/src/lib/libbsp/m68k/csb360/network/network.c
deleted file mode 100644
index 47e0adb44d..0000000000
--- a/c/src/lib/libbsp/m68k/csb360/network/network.c
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- * RTEMS/TCPIP driver for MCF5272 Ethernet
- *
- * Modified for MPC860 by Jay Monkman (jmonkman@lopingdog.com)
- *
- * This supports Ethernet on either SCC1 or the FEC of the MPC860T.
- * Right now, we only do 10 Mbps, even with the FEC. The function
- * rtems_enet_driver_attach determines which one to use. Currently,
- * only one may be used at a time.
- *
- * Based on the MC68360 network driver by
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- *
- * This supports ethernet on SCC1. Right now, we only do 10 Mbps.
- *
- * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
- * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
- * Copyright (c) 1999, National Research Council of Canada
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <stdio.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 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 32
-#define TX_BUF_COUNT 16
-#define TX_BD_PER_BUF 4
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP 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 plus CRC (1518).
- * Round off to nearest multiple of RBUF_ALIGN.
- */
-#define MAX_MTU_SIZE 1518
-#define RBUF_ALIGN 4
-#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-typedef struct {
- uint16_t status;
- uint16_t length;
- void *buffer;
-} bd_t;
-#define MCF5272_BD_READY (bit(15))
-#define MCF5272_BD_TO1 (bit(14))
-#define MCF5272_BD_WRAP (bit(13))
-#define MCF5272_BD_TO2 (bit(12))
-#define MCF5272_BD_LAST (bit(11))
-#define MCF5272_BD_TX_CRC (bit(10))
-#define MCF5272_BD_DEFER (bit(9))
-#define MCF5272_BD_HEARTBEAT (bit(8))
-#define MCF5272_BD_LATE_COLLISION (bit(7))
-#define MCF5272_BD_RETRY_LIMIT (bit(6))
-#define MCF5272_BD_UNDERRUN (bit(1))
-#define MCF5272_BD_CARRIER_LOST (bit(0))
-
-#define MCF5272_BD_EMPTY (bit(15))
-#define MCF5272_BD_RO1 (bit(14))
-#define MCF5272_BD_WRAP (bit(13))
-#define MCF5272_BD_RO2 (bit(12))
-#define MCF5272_BD_M (bit(8))
-#define MCF5272_BD_BC (bit(7))
-#define MCF5272_BD_MC (bit(6))
-#define MCF5272_BD_LONG (bit(5))
-#define MCF5272_BD_NONALIGNED (bit(4))
-#define MCF5272_BD_SHORT (bit(3))
-#define MCF5272_BD_CRC_ERROR (bit(2))
-#define MCF5272_BD_OVERRUN (bit(1))
-#define MCF5272_BD_TRUNCATED (bit(0))
-
-
-/*
- * Per-device data
- */
-struct mcf5272_enet_struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- bd_t *rxBdBase;
- bd_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * 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 rxTruncated;
-
- unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txHeartbeat;
- unsigned long txLateCollision;
- unsigned long txRetryLimit;
- unsigned long txUnderrun;
- unsigned long txLostCarrier;
- unsigned long txRawWait;
-};
-static struct mcf5272_enet_struct enet_driver[NIFACES];
-
-
-void dump_enet_regs(void)
-{
- printf("**************************************************************\n");
- printf("ecr: 0x%08x eir: 0x%08x eimr: 0x%08x ivsr: 0x%08x\n\r",
- g_enet_regs->ecr, g_enet_regs->eir,
- g_enet_regs->eimr, g_enet_regs->ivsr);
- printf("rdar: 0x%08x tdar: 0x%08x mmfr: 0x%08x mscr: 0x%08x\n\r",
- g_enet_regs->rdar, g_enet_regs->tdar,
- g_enet_regs->mmfr, g_enet_regs->mscr);
- printf("frbr: 0x%08x frsr: 0x%08x tfwr: 0x%08x tfsr: 0x%08x\n\r",
- g_enet_regs->frbr, g_enet_regs->frsr,
- g_enet_regs->tfwr, g_enet_regs->tfsr);
- printf("rcr: 0x%08x mflr: 0x%08x tcr: 0x%08x malr: 0x%08x\n\r",
- g_enet_regs->rcr, g_enet_regs->mflr,
- g_enet_regs->tcr, g_enet_regs->malr);
- printf("maur: 0x%08x htur: 0x%08x htlr: 0x%08x erdsr: 0x%08x\n\r",
- g_enet_regs->maur, g_enet_regs->htur,
- g_enet_regs->htlr, g_enet_regs->erdsr);
- printf("etdsr: 0x%08x emrbr: 0x%08x\n\r",
- g_enet_regs->etdsr, g_enet_regs->emrbr);
-}
-
-
-
-
-/*#define cp printk("%s:%d\n\r", __FUNCTION__, __LINE__) */
-#define cp
-#define mcf5272_bd_allocate(_n_) malloc((_n_) * sizeof(bd_t), 0, M_NOWAIT)
-
-
-
-rtems_isr enet_rx_isr(rtems_vector_number vector)
-{
- cp;
- /*
- * Frame received?
- */
- if (g_enet_regs->eir & MCF5272_ENET_EIR_RXF) {
- cp;
- g_enet_regs->eir = MCF5272_ENET_EIR_RXF;
- enet_driver[0].rxInterrupts++;
- rtems_bsdnet_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
- }
- cp;
-}
-
-rtems_isr enet_tx_isr(rtems_vector_number vector)
-{
- cp;
- /*
- * Buffer transmitted or transmitter error?
- */
- if (g_enet_regs->eir & MCF5272_ENET_EIR_TXF) {
- cp;
- g_enet_regs->eir = MCF5272_ENET_EIR_TXF;
- enet_driver[0].txInterrupts++;
- rtems_bsdnet_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
- }
- cp;
-}
-
-
-/*
- * Initialize the ethernet hardware
- */
-
-
-static void
-mcf5272_enet_initialize_hardware (struct mcf5272_enet_struct *sc)
-{
- int i;
- unsigned char *hwaddr;
- uint32_t icr;
- /*
- * Issue reset to FEC
- */
- g_enet_regs->ecr=0x1;
-
- /*
- * Set the TX and RX fifo sizes. For now, we'll split it evenly
- */
- /* If you uncomment these, the FEC will not work right.
- g_enet_regs->r_fstart = ((g_enet_regs->r_bound & 0x3ff) >> 2) & 0x3ff;
- g_enet_regs->x_fstart = 0;
- */
-
- /* Copy mac address to device */
-
- hwaddr = sc->arpcom.ac_enaddr;
-
- g_enet_regs->malr = (hwaddr[0] << 24 |
- hwaddr[1] << 16 |
- hwaddr[2] << 8 |
- hwaddr[3]);
- g_enet_regs->maur = (hwaddr[4] << 24 |
- hwaddr[5] << 16);
-
- /*
- * Clear the hash table
- */
- g_enet_regs->htlr = 0;
- g_enet_regs->htur = 0;
-
- /*
- * Set up receive buffer size
- */
- g_enet_regs->emrbr = 0x5f0; /* set to 1520 */
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
- M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
- M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf) {
- rtems_panic ("No memory for mbuf pointers");
- }
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = mcf5272_bd_allocate(sc->rxBdCount);
- sc->txBdBase = mcf5272_bd_allocate(sc->txBdCount);
- g_enet_regs->erdsr = (int)sc->rxBdBase;
- g_enet_regs->etdsr = (int)sc->txBdBase;
-
- /*
- * Set up Receive Control Register:
- * Not promiscuous mode
- * MII mode
- * Full duplex
- * No loopback
- */
- g_enet_regs->rcr = 0x00000004;
-
- /*
- * Set up Transmit Control Register:
- * Full duplex
- * No heartbeat
- */
- g_enet_regs->tcr = 0x00000004;
-
- /*
- * Set MII speed to 2.5 MHz for 25 Mhz system clock
- */
- g_enet_regs->mscr = 0x0a;
- g_enet_regs->mmfr = 0x58021000;
-
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0 ; i < sc->rxBdCount ; i++) {
- (sc->rxBdBase + i)->status = 0;
- }
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0 ; i < sc->txBdCount ; i++) {
- (sc->txBdBase + i)->status = 0;
- sc->txMbuf[i] = NULL;
- }
-
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Mask all FEC interrupts and clear events
- */
- g_enet_regs->eimr = (MCF5272_ENET_EIR_TXF |
- MCF5272_ENET_EIR_RXF);
- g_enet_regs->eir = ~0;
-
- /*
- * Set up interrupts
- */
- set_vector(enet_rx_isr, BSP_INTVEC_ERX, 1);
- set_vector(enet_tx_isr, BSP_INTVEC_ETX, 1);
-
- /* Configure ethernet interrupts */
- icr = g_intctrl_regs->icr3;
- icr = icr & ~((MCF5272_ICR3_ERX_MASK | MCF5272_ICR3_ERX_PI) |
- (MCF5272_ICR3_ETX_MASK | MCF5272_ICR3_ETX_PI));
- icr |= ((MCF5272_ICR3_ERX_IPL(BSP_INTLVL_ERX) | MCF5272_ICR3_ERX_PI)|
- (MCF5272_ICR3_ETX_IPL(BSP_INTLVL_ETX) | MCF5272_ICR3_ETX_PI));
- g_intctrl_regs->icr3 = icr;
-
-}
-
-
-/*
- * Soak up buffer descriptors that have been sent.
- * Note that a buffer descriptor can't be retired as soon as it becomes
- * ready. The MPC860 manual (MPC860UM/AD 07/98 Rev.1) and the MPC821
- * manual state that, "If an Ethernet frame is made up of multiple
- * buffers, the user should not reuse the first buffer descriptor until
- * the last buffer descriptor of the frame has had its ready bit cleared
- * by the CPM".
- */
-static void
-mcf5272_enet_retire_tx_bd (struct mcf5272_enet_struct *sc)
-{
- uint16_t status;
- int i;
- int nRetired;
- struct mbuf *m, *n;
-
- i = sc->txBdTail;
- nRetired = 0;
- while ((sc->txBdActiveCount != 0) &&
- (((status = sc->txBdBase[i].status) & MCF5272_BD_READY) == 0)) {
- /*
- * See if anything went wrong
- */
- if (status & (MCF5272_BD_DEFER |
- MCF5272_BD_HEARTBEAT |
- MCF5272_BD_LATE_COLLISION |
- MCF5272_BD_RETRY_LIMIT |
- MCF5272_BD_UNDERRUN |
- MCF5272_BD_CARRIER_LOST)) {
- /*
- * Check for errors which stop the transmitter.
- */
- if (status & (MCF5272_BD_LATE_COLLISION |
- MCF5272_BD_RETRY_LIMIT |
- MCF5272_BD_UNDERRUN)) {
- if (status & MCF5272_BD_LATE_COLLISION) {
- enet_driver[0].txLateCollision++;
- }
- if (status & MCF5272_BD_RETRY_LIMIT) {
- enet_driver[0].txRetryLimit++;
- }
- if (status & MCF5272_BD_UNDERRUN) {
- enet_driver[0].txUnderrun++;
- }
- }
- if (status & MCF5272_BD_DEFER) {
- enet_driver[0].txDeferred++;
- }
- if (status & MCF5272_BD_HEARTBEAT) {
- enet_driver[0].txHeartbeat++;
- }
- if (status & MCF5272_BD_CARRIER_LOST) {
- enet_driver[0].txLostCarrier++;
- }
- }
- nRetired++;
- if (status & MCF5272_BD_LAST) {
- /*
- * A full frame has been transmitted.
- * Free all the associated buffer descriptors.
- */
- sc->txBdActiveCount -= nRetired;
- while (nRetired) {
- nRetired--;
- m = sc->txMbuf[sc->txBdTail];
- MFREE (m, n);
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- }
- }
- if (++i == sc->txBdCount) {
- i = 0;
- }
- }
-}
-
-static void
-mcf5272_enet_rxDaemon (void *arg)
-{
- struct mcf5272_enet_struct *sc = (struct mcf5272_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- uint16_t status;
- bd_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0 ; ;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod (m, void *);
- rxBd->status = MCF5272_BD_EMPTY;
- g_enet_regs->rdar = 0x1000000;
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= MCF5272_BD_WRAP;
- break;
- }
- }
-
- /*
- * Input packet handling loop
- */
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & MCF5272_BD_EMPTY) {
- /*
- * Clear old events
- */
- g_enet_regs->eir = MCF5272_ENET_EIR_RXF;
-
- /*
- * Wait for packet
- * Note that the buffer descriptor is checked
- * *before* the event wait -- this catches the
- * possibility that a packet arrived between the
- * `if' above, and the clearing of the event register.
- */
- while ((status = rxBd->status) & MCF5272_BD_EMPTY) {
- rtems_event_set events;
-
- /*
- * Unmask RXF (Full frame received) event
- */
- g_enet_regs->eir |= MCF5272_ENET_EIR_RXF;
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- cp;
- }
- }
- cp;
-
- /*
- * Check that packet is valid
- */
- if (status & MCF5272_BD_LAST) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
-
- m = sc->rxMbuf[rxBdIndex];
- m->m_len = m->m_pkthdr.len = (rxBd->length -
- sizeof(uint32_t) -
- sizeof(struct ether_header));
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input (ifp, eh, 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 {
- /*
- * Something went wrong with the reception
- */
- if (!(status & MCF5272_BD_LAST)) {
- sc->rxNotLast++;
- }
- if (status & MCF5272_BD_LONG) {
- sc->rxGiant++;
- }
- if (status & MCF5272_BD_NONALIGNED) {
- sc->rxNonOctet++;
- }
- if (status & MCF5272_BD_SHORT) {
- sc->rxRunt++;
- }
- if (status & MCF5272_BD_CRC_ERROR) {
- sc->rxBadCRC++;
- }
- if (status & MCF5272_BD_OVERRUN) {
- sc->rxOverrun++;
- }
- if (status & MCF5272_BD_TRUNCATED) {
- sc->rxTruncated++;
- }
- }
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & MCF5272_BD_WRAP) | MCF5272_BD_EMPTY;
- g_enet_regs->rdar = 0x1000000;
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount) {
- rxBdIndex = 0;
- }
- }
-}
-
-static void
-mcf5272_enet_sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct mcf5272_enet_struct *sc = ifp->if_softc;
- volatile bd_t *firstTxBd, *txBd;
- /* struct mbuf *l = NULL; */
- uint16_t status;
- int nAdded;
- cp;
-
- /*
- * Free up buffer descriptors
- */
- mcf5272_enet_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;
- for (;;) {
- cp;
- /*
- * Wait for buffer descriptor to become available.
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events
- */
- g_enet_regs->eir = MCF5272_ENET_EIR_TXF;
-
- /*
- * 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.
- */
- mcf5272_enet_retire_tx_bd (sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_event_set events;
-
- cp;
- /*
- * Unmask TXB (buffer transmitted) and
- * TXE (transmitter error) events.
- */
- g_enet_regs->eir |= MCF5272_ENET_EIR_TXF;
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- cp;
- mcf5272_enet_retire_tx_bd (sc);
- }
- }
-
- /*
- * Don't set the READY flag till the
- * whole packet has been readied.
- */
- status = nAdded ? MCF5272_BD_READY : 0;
- cp;
-
- /*
- * 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) {
- cp;
- /*
- * Fill in the buffer descriptor
- */
- txBd->buffer = mtod (m, void *);
- txBd->length = m->m_len;
-
- sc->txMbuf[sc->txBdHead] = m;
- nAdded++;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= MCF5272_BD_WRAP;
- sc->txBdHead = 0;
- }
- /* l = m;*/
- m = m->m_next;
- }
- else {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
- cp;
- 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) {
- cp;
- if (nAdded) {
- cp;
- status |= MCF5272_BD_LAST | MCF5272_BD_TX_CRC;
- txBd->status = status;
- firstTxBd->status |= MCF5272_BD_READY;
- g_enet_regs->tdar = 0x1000000;
- sc->txBdActiveCount += nAdded;
- }
- break;
- }
- txBd->status = status;
- txBd = sc->txBdBase + sc->txBdHead;
- }
- cp;
-/*
- dump_enet_regs();
- dump_intctrl;
-*/
-
-}
-
-
-void
-mcf5272_enet_txDaemon (void *arg)
-{
- struct mcf5272_enet_struct *sc = (struct mcf5272_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- cp;
- for (;;) {
- /*
- * Wait for packet
- */
- rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
- cp;
- /*
- * Send packets till queue is empty
- */
- cp;
- for (;;) {
- cp;
- /*
- * Get the next mbuf chain to transmit.
- */
- IF_DEQUEUE(&ifp->if_snd, m);
- if (!m)
- break;
- mcf5272_enet_sendpacket (ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-
-/*
- * Send packet (caller provides header).
- */
-static void
-mcf5272_enet_start (struct ifnet *ifp)
-{
- struct mcf5272_enet_struct *sc = ifp->if_softc;
-
- cp;
- rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
- cp;
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-
-static void
-mcf5272_enet_init (void *arg)
-{
- struct mcf5272_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up SCC hardware
- */
- mcf5272_enet_initialize_hardware (sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc("SCtx",
- 4096,
- mcf5272_enet_txDaemon,
- sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("SCrx",
- 4096,
- mcf5272_enet_rxDaemon,
- sc);
-
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC) {
- g_enet_regs->rcr |= 0x8;
- } else {
- g_enet_regs->rcr &= ~0x8;
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- g_enet_regs->ecr = 0x2;
-}
-
-
-static void
-mcf5272_enet_stop (struct mcf5272_enet_struct *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- g_enet_regs->ecr = 0x0;
-}
-
-
-/*
- * Show interface statistics
- */
-static void
-enet_stats (struct mcf5272_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 (" Truncated:%-8lu\n", sc->rxTruncated);
-/* printf (" Discarded:%-8lu\n", (unsigned long)mcf5272.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 int
-mcf5272_enet_ioctl (struct ifnet *ifp, int command, caddr_t data)
-{
- struct mcf5272_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:
- mcf5272_enet_stop (sc);
- break;
-
- case IFF_UP:
- mcf5272_enet_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- mcf5272_enet_stop (sc);
- mcf5272_enet_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;
-}
-
-
-int
-rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config)
-{
- struct mcf5272_enet_struct *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /*
- * Parse driver name
- */
- unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName);
- if (unitNumber < 0){
- return 0;
- }
-
- /*
- * Is driver free?
- */
- if ((unitNumber < 0) || (unitNumber > NIFACES)) {
- printf ("Bad unit number: %d.\n", unitNumber);
- return 0;
- }
-
- sc = &enet_driver[unitNumber];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printf ("Driver already in use.\n");
- return 0;
- }
-
- /*
- * Process options
- */
-
- sc->arpcom.ac_enaddr[0] = (g_enet_regs->malr >> 24) & 0xff;
- sc->arpcom.ac_enaddr[1] = (g_enet_regs->malr >> 16) & 0xff;
- sc->arpcom.ac_enaddr[2] = (g_enet_regs->malr >> 8) & 0xff;
- sc->arpcom.ac_enaddr[3] = (g_enet_regs->malr >> 0) & 0xff;
- sc->arpcom.ac_enaddr[4] = (g_enet_regs->maur >> 24) & 0xff;
- sc->arpcom.ac_enaddr[5] = (g_enet_regs->maur >> 16) & 0xff;
-
- 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 = mcf5272_enet_init;
- ifp->if_ioctl = mcf5272_enet_ioctl;
- ifp->if_start = mcf5272_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);
- cp;
- ether_ifattach (ifp);
- cp;
- return 1;
-};
-
-
diff --git a/c/src/lib/libbsp/m68k/gen68360/Makefile.am b/c/src/lib/libbsp/m68k/gen68360/Makefile.am
index d78babc776..d3cbc78599 100644
--- a/c/src/lib/libbsp/m68k/gen68360/Makefile.am
+++ b/c/src/lib/libbsp/m68k/gen68360/Makefile.am
@@ -38,7 +38,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/serial/printk-dummy.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68360/btimer/btimer.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/gen68360/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache.c
diff --git a/c/src/lib/libbsp/m68k/gen68360/network/network.c b/c/src/lib/libbsp/m68k/gen68360/network/network.c
deleted file mode 100644
index 0a038d3348..0000000000
--- a/c/src/lib/libbsp/m68k/gen68360/network/network.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * RTEMS driver for M68360 SCC1 Ethernet
- *
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <rtems/m68k/m68360.h>
-#include <stdio.h>
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-/*
- * Number of SCCs supported by this driver
- */
-#define NSCCDRIVER 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 scc_softc {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- m360BufferDescriptor_t *rxBdBase;
- m360BufferDescriptor_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * 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;
- unsigned long txCoalesced;
- unsigned long txCoalesceFailed;
- unsigned long txRetry;
-};
-static struct scc_softc scc_softc[NSCCDRIVER];
-
-extern void *_RomBase; /* From linkcmds */
-
-/*
- * SCC1 interrupt handler
- */
-static rtems_isr
-m360Enet_interrupt_handler (rtems_vector_number v)
-{
- /*
- * Frame received?
- */
- if ((m360.scc1.sccm & 0x8) && (m360.scc1.scce & 0x8)) {
- m360.scc1.scce = 0x8;
- m360.scc1.sccm &= ~0x8;
- scc_softc[0].rxInterrupts++;
- rtems_bsdnet_event_send (scc_softc[0].rxDaemonTid, INTERRUPT_EVENT);
- }
-
- /*
- * Buffer transmitted or transmitter error?
- */
- if ((m360.scc1.sccm & 0x12) && (m360.scc1.scce & 0x12)) {
- m360.scc1.scce = 0x12;
- m360.scc1.sccm &= ~0x12;
- scc_softc[0].txInterrupts++;
- rtems_bsdnet_event_send (scc_softc[0].txDaemonTid, INTERRUPT_EVENT);
- }
- m360.cisr = 1UL << 30; /* Clear SCC1 interrupt-in-service bit */
-}
-
-/*
- * Initialize the ethernet hardware
- */
-static void
-m360Enet_initialize_hardware (struct scc_softc *sc)
-{
- int i;
- unsigned char *hwaddr;
- rtems_status_code status;
- rtems_isr_entry old_handler;
-
- /*
- * Configure port A CLK1, CLK2, TXD1 and RXD1 pins
- */
- m360.papar |= 0x303;
- m360.padir &= ~0x303;
- m360.paodr &= ~0x303;
-
- /*
- * Configure port C CTS1* and CD1* pins
- */
- m360.pcpar &= ~0x30;
- m360.pcdir &= ~0x30;
- m360.pcso |= 0x30;
-
- /*
- * Connect CLK1 and CLK2 to SCC1
- */
- m360.sicr &= ~0xFF;
- m360.sicr |= (5 << 3) | 4;
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf)
- rtems_panic ("No memory for mbuf pointers");
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = M360AllocateBufferDescriptors(sc->rxBdCount);
- sc->txBdBase = M360AllocateBufferDescriptors(sc->txBdCount);
- m360.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m360;
- m360.scc1p.tbase = (char *)sc->txBdBase - (char *)&m360;
-
- /*
- * Send "Init parameters" command
- */
- M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SCC1);
-
- /*
- * Set receive and transmit function codes
- */
- m360.scc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
- m360.scc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
-
- /*
- * Set maximum receive buffer length
- */
- m360.scc1p.mrblr = RBUF_SIZE;
-
- /*
- * Set CRC parameters
- */
- m360.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
- m360.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
-
- /*
- * Clear diagnostic counters
- */
- m360.scc1p.un.ethernet.crcec = 0;
- m360.scc1p.un.ethernet.alec = 0;
- m360.scc1p.un.ethernet.disfc = 0;
-
- /*
- * Set pad value
- */
- m360.scc1p.un.ethernet.pads = 0x8888;
-
- /*
- * Set retry limit
- */
- m360.scc1p.un.ethernet.ret_lim = 15;
-
- /*
- * Set maximum and minimum frame length
- */
- m360.scc1p.un.ethernet.mflr = 1518;
- m360.scc1p.un.ethernet.minflr = 64;
- m360.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
- m360.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
-
- /*
- * Clear group address hash table
- */
- m360.scc1p.un.ethernet.gaddr1 = 0;
- m360.scc1p.un.ethernet.gaddr2 = 0;
- m360.scc1p.un.ethernet.gaddr3 = 0;
- m360.scc1p.un.ethernet.gaddr4 = 0;
-
- /*
- * Set our physical address
- */
- hwaddr = sc->arpcom.ac_enaddr;
- m360.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
- m360.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
- m360.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
-
- /*
- * Aggressive retry
- */
- m360.scc1p.un.ethernet.p_per = 0;
-
- /*
- * Clear individual address hash table
- */
- m360.scc1p.un.ethernet.iaddr1 = 0;
- m360.scc1p.un.ethernet.iaddr2 = 0;
- m360.scc1p.un.ethernet.iaddr3 = 0;
- m360.scc1p.un.ethernet.iaddr4 = 0;
-
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0 ; i < sc->rxBdCount ; i++)
- (sc->rxBdBase + i)->status = 0;
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0 ; i < sc->txBdCount ; i++) {
- (sc->txBdBase + i)->status = 0;
- sc->txMbuf[i] = NULL;
- }
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Clear any outstanding events
- */
- m360.scc1.scce = 0xFFFF;
-
- /*
- * Set up interrupts
- */
- status = rtems_interrupt_catch (m360Enet_interrupt_handler,
- (m360.cicr & 0xE0) | 0x1E,
- &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach M360 SCC1 interrupt handler: %s\n",
- rtems_status_text (status));
- m360.scc1.sccm = 0; /* No interrupts unmasked till necessary */
- m360.cimr |= (1UL << 30); /* Enable SCC1 interrupt */
-
- /*
- * Set up General SCC Mode Register
- * Ethernet configuration
- */
- m360.scc1.gsmr_h = 0x0;
- m360.scc1.gsmr_l = 0x1088000c;
-
- /*
- * Set up data synchronization register
- * Ethernet synchronization pattern
- */
- m360.scc1.dsr = 0xd555;
-
- /*
- * Set up protocol-specific mode register
- * Heartbeat check
- * No force collision
- * Discard short frames
- * Individual address mode
- * Ethernet CRC
- * Not promisuous
- * Ignore/accept broadcast packets as specified
- * Normal backoff timer
- * No loopback
- * No input sample at end of frame
- * 64-byte limit for late collision
- * Wait 22 bits before looking for start of frame delimiter
- * Disable full-duplex operation
- */
- m360.scc1.psmr = 0x880A | (sc->acceptBroadcast ? 0 : 0x100);
-
- /*
- * Enable the TENA (RTS1*) pin
- */
-#if (defined (M68360_ATLAS_HSB))
- m360.pbpar |= 0x1000;
- m360.pbdir |= 0x1000;
-#else
- m360.pcpar |= 0x1;
- m360.pcdir &= ~0x1;
-#endif
-}
-
-/*
- * Soak up buffer descriptors that have been sent
- * Note that a buffer descriptor can't be retired as soon as it becomes
- * ready. The MC68360 Errata (May 96) says that, "If an Ethernet frame is
- * made up of multiple buffers, the user should not reuse the first buffer
- * descriptor until the last buffer descriptor of the frame has had its
- * ready bit cleared by the CPM".
- */
-static void
-m360Enet_retire_tx_bd (struct scc_softc *sc)
-{
- uint16_t status;
- int i;
- int nRetired;
- struct mbuf *m, *n;
- int retries = 0;
- int saveStatus = 0;
-
- i = sc->txBdTail;
- nRetired = 0;
- while ((sc->txBdActiveCount != 0)
- && (((status = (sc->txBdBase + i)->status) & M360_BD_READY) == 0)) {
- /*
- * Check for errors which stop the transmitter.
- */
- if (status & (M360_BD_LATE_COLLISION |
- M360_BD_RETRY_LIMIT |
- M360_BD_UNDERRUN)) {
- int j;
-
- if (status & M360_BD_LATE_COLLISION)
- sc->txLateCollision++;
- if (status & M360_BD_RETRY_LIMIT)
- sc->txRetryLimit++;
- if (status & M360_BD_UNDERRUN)
- sc->txUnderrun++;
-
- /*
- * Reenable buffer descriptors
- */
- j = sc->txBdTail;
- for (;;) {
- status = (sc->txBdBase + j)->status;
- if (status & M360_BD_READY)
- break;
- (sc->txBdBase + j)->status = M360_BD_READY |
- (status & (M360_BD_PAD |
- M360_BD_WRAP |
- M360_BD_INTERRUPT |
- M360_BD_LAST |
- M360_BD_TX_CRC));
- if (status & M360_BD_LAST)
- break;
- if (++j == sc->txBdCount)
- j = 0;
- }
-
- /*
- * Move transmitter back to the first
- * buffer descriptor in the frame.
- */
- m360.scc1p._tbptr = m360.scc1p.tbase +
- sc->txBdTail * sizeof (m360BufferDescriptor_t);
-
- /*
- * Restart the transmitter
- */
- M360ExecuteRISC (M360_CR_OP_RESTART_TX | M360_CR_CHAN_SCC1);
- continue;
- }
- saveStatus |= status;
- retries += (status >> 2) & 0xF;
- nRetired++;
- if (status & M360_BD_LAST) {
- /*
- * A full frame has been transmitted.
- * Free all the associated buffer descriptors.
- */
- if (saveStatus & M360_BD_DEFER)
- sc->txDeferred++;
- if (saveStatus & M360_BD_HEARTBEAT)
- sc->txHeartbeat++;
- if (saveStatus & M360_BD_CARRIER_LOST)
- sc->txLostCarrier++;
- saveStatus = 0;
- sc->txRetry += retries;
- retries = 0;
- sc->txBdActiveCount -= nRetired;
- while (nRetired) {
- nRetired--;
- m = sc->txMbuf[sc->txBdTail];
- MFREE (m, n);
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- }
- }
- if (++i == sc->txBdCount)
- i = 0;
- }
-}
-
-/*
- * SCC reader task
- */
-static void
-scc_rxDaemon (void *arg)
-{
- struct scc_softc *sc = (struct scc_softc *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- uint16_t status;
- volatile m360BufferDescriptor_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0 ; ;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod (m, void *);
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status = M360_BD_EMPTY | M360_BD_INTERRUPT | M360_BD_WRAP;
- break;
- }
- rxBd->status = M360_BD_EMPTY | M360_BD_INTERRUPT;
- }
-
- /*
- * Input packet handling loop
- */
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & M360_BD_EMPTY) {
- /*
- * Clear old events
- */
- m360.scc1.scce = 0x8;
-
- /*
- * Wait for packet
- * Note that the buffer descriptor is checked
- * *before* the event wait -- this catches the
- * possibility that a packet arrived between the
- * `if' above, and the clearing of the event register.
- */
- while ((status = rxBd->status) & M360_BD_EMPTY) {
- rtems_interrupt_level level;
- rtems_event_set events;
-
- /*
- * Unmask RXF (Full frame received) event
- */
- rtems_interrupt_disable (level);
- m360.scc1.sccm |= 0x8;
- rtems_interrupt_enable (level);
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- }
-
- /*
- * Check that packet is valid
- */
- if ((status & (M360_BD_LAST |
- M360_BD_FIRST_IN_FRAME |
- M360_BD_LONG |
- M360_BD_NONALIGNED |
- M360_BD_SHORT |
- M360_BD_CRC_ERROR |
- M360_BD_OVERRUN |
- M360_BD_COLLISION)) ==
- (M360_BD_LAST |
- M360_BD_FIRST_IN_FRAME)) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
-
- m = sc->rxMbuf[rxBdIndex];
- m->m_len = m->m_pkthdr.len = rxBd->length -
- sizeof(uint32_t) -
- sizeof(struct ether_header);
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input (ifp, eh, 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 {
- /*
- * Something went wrong with the reception
- */
- if (!(status & M360_BD_LAST))
- sc->rxNotLast++;
- if (!(status & M360_BD_FIRST_IN_FRAME))
- sc->rxNotFirst++;
- if (status & M360_BD_LONG)
- sc->rxGiant++;
- if (status & M360_BD_NONALIGNED)
- sc->rxNonOctet++;
- if (status & M360_BD_SHORT)
- sc->rxRunt++;
- if (status & M360_BD_CRC_ERROR)
- sc->rxBadCRC++;
- if (status & M360_BD_OVERRUN)
- sc->rxOverrun++;
- if (status & M360_BD_COLLISION)
- sc->rxCollision++;
- }
-
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & (M360_BD_WRAP | M360_BD_INTERRUPT)) | M360_BD_EMPTY;
-
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount)
- rxBdIndex = 0;
- }
-}
-
-static void
-sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct scc_softc *sc = ifp->if_softc;
- volatile m360BufferDescriptor_t *firstTxBd, *txBd;
- struct mbuf *l = NULL;
- uint16_t status;
- int nAdded;
-
- /*
- * Free up buffer descriptors
- */
- m360Enet_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.
- */
- status = 0;
- nAdded = 0;
- txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
- while (m) {
- /*
- * There are more mbufs in the packet than there
- * are transmit buffer descriptors.
- * Coalesce into a single buffer.
- */
- if (nAdded == sc->txBdCount) {
- struct mbuf *nm;
- int j;
- char *dest;
-
- /*
- * Get the pointer to the first mbuf of the packet
- */
- if (sc->txBdTail != sc->txBdHead)
- rtems_panic ("sendpacket coalesce");
- m = sc->txMbuf[sc->txBdTail];
-
- /*
- * Rescind the buffer descriptor READY bits
- */
- for (j = 0 ; j < sc->txBdCount ; j++)
- (sc->txBdBase + j)->status = 0;
-
- /*
- * Allocate an mbuf cluster
- * Toss the packet if allocation fails
- */
- MGETHDR (nm, M_DONTWAIT, MT_DATA);
- if (nm == NULL) {
- sc->txCoalesceFailed++;
- m_freem (m);
- return;
- }
- MCLGET (nm, M_DONTWAIT);
- if (nm->m_ext.ext_buf == NULL) {
- sc->txCoalesceFailed++;
- m_freem (m);
- m_free (nm);
- return;
- }
- nm->m_pkthdr = m->m_pkthdr;
- nm->m_len = nm->m_pkthdr.len;
-
- /*
- * Copy data from packet chain to mbuf cluster
- */
- sc->txCoalesced++;
- dest = nm->m_ext.ext_buf;
- while (m) {
- struct mbuf *n;
-
- if (m->m_len) {
- memcpy (dest, mtod(m, caddr_t), m->m_len);
- dest += m->m_len;
- }
- MFREE (m, n);
- m = n;
- }
-
- /*
- * Redo the send with the new mbuf cluster
- */
- m = nm;
- nAdded = 0;
- status = 0;
- continue;
- }
-
- /*
- * Wait for buffer descriptor to become available.
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events
- */
- m360.scc1.scce = 0x12;
-
- /*
- * 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.
- */
- m360Enet_retire_tx_bd (sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_interrupt_level level;
- rtems_event_set events;
-
- /*
- * Unmask TXB (buffer transmitted) and
- * TXE (transmitter error) events.
- */
- rtems_interrupt_disable (level);
- m360.scc1.sccm |= 0x12;
- rtems_interrupt_enable (level);
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- m360Enet_retire_tx_bd (sc);
- }
- }
-
- /*
- * The IP fragmentation routine in ip_output
- * can produce packet fragments with zero length.
- */
- if (m->m_len) {
- /*
- * Fill in the buffer descriptor.
- * Don't set the READY flag in the first buffer
- * descriptor till the whole packet has been readied.
- */
- txBd = sc->txBdBase + sc->txBdHead;
- txBd->buffer = mtod (m, void *);
- txBd->length = m->m_len;
- sc->txMbuf[sc->txBdHead] = m;
- status = nAdded ? M360_BD_READY : 0;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= M360_BD_WRAP;
- sc->txBdHead = 0;
- }
- txBd->status = status;
- l = m;
- m = m->m_next;
- nAdded++;
- }
- else {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
- MFREE (m, n);
- m = n;
- if (l != NULL)
- l->m_next = m;
- }
- }
- if (nAdded) {
- /*
- * Send the packet
- */
- txBd->status = status | M360_BD_PAD | M360_BD_LAST | M360_BD_TX_CRC | M360_BD_INTERRUPT;
- firstTxBd->status |= M360_BD_READY;
- sc->txBdActiveCount += nAdded;
- }
-}
-
-/*
- * Driver transmit daemon
- */
-void
-scc_txDaemon (void *arg)
-{
- struct scc_softc *sc = (struct scc_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
-scc_start (struct ifnet *ifp)
-{
- struct scc_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
-scc_init (void *arg)
-{
- struct scc_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up SCC hardware
- */
- m360Enet_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);
-
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- m360.scc1.psmr |= 0x200;
- else
- m360.scc1.psmr &= ~0x200;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- m360.scc1.gsmr_l |= 0x30;
-}
-
-/*
- * Stop the device
- */
-static void
-scc_stop (struct scc_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- m360.scc1.gsmr_l &= ~0x30;
-}
-
-/*
- * Show interface statistics
- */
-static void
-scc_stats (struct scc_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 (" Discarded:%-8lu\n", (unsigned long)m360.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", sc->txRawWait);
- printf (" Coalesced:%-8lu\n", sc->txCoalesced);
- printf (" Coalesce failed:%-8lu", sc->txCoalesceFailed);
- printf (" Retries:%-8lu\n", sc->txRetry);
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-scc_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct scc_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:
- 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:
- scc_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
- */
-int
-rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- struct scc_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /*
- * Make sure we're really being attached
- */
- if (!attaching) {
- printf ("SCC1 driver can not be detached.\n");
- return 0;
- }
-
- /*
- * Parse driver name
- */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber <= 0) || (unitNumber > NSCCDRIVER)) {
- printf ("Bad SCC unit number.\n");
- return 0;
- }
- sc = &scc_softc[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 {
- /*
- * The first 4 bytes of the bootstrap prom
- * contain the value loaded into the stack
- * pointer as part of the CPU32's hardware
- * reset exception handler. The following
- * 4 bytes contain the value loaded into the
- * program counter. The boards' Ethernet
- * address is stored in the six bytes
- * immediately preceding this initial
- * program counter value.
- *
- * See start360/start360.s.
- */
- const unsigned long *ExceptionVectors;
- const unsigned char *entryPoint;
-
- /*
- * Sanity check -- assume entry point must be
- * within 1 MByte of beginning of boot ROM.
- */
- ExceptionVectors = (const unsigned long *)&_RomBase;
- entryPoint = (const unsigned char *)ExceptionVectors[1];
- if (((unsigned long)entryPoint - (unsigned long)ExceptionVectors)
- >= (1 * 1024 * 1024)) {
- printf ("Warning -- Ethernet address can not be found in bootstrap PROM.\n");
- sc->arpcom.ac_enaddr[0] = 0x08;
- sc->arpcom.ac_enaddr[1] = 0xF3;
- sc->arpcom.ac_enaddr[2] = 0x3E;
- sc->arpcom.ac_enaddr[3] = 0xC2;
- sc->arpcom.ac_enaddr[4] = 0x7E;
- sc->arpcom.ac_enaddr[5] = 0x38;
- }
- else {
- memcpy (sc->arpcom.ac_enaddr, entryPoint - ETHER_ADDR_LEN, ETHER_ADDR_LEN);
- }
- }
- 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 = scc_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;
-}
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
index b84cda2236..7cc1e39bb6 100644
--- a/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
+++ b/c/src/lib/libbsp/m68k/genmcf548x/Makefile.am
@@ -51,7 +51,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/genmcf548x/mcdma/mcdma_glue
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/genmcf548x/start/cache.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/genmcf548x/net/network.c
endif
include $(top_srcdir)/../../../../automake/local.am
diff --git a/c/src/lib/libbsp/m68k/genmcf548x/network/network.c b/c/src/lib/libbsp/m68k/genmcf548x/network/network.c
deleted file mode 100644
index 13cb5fbdce..0000000000
--- a/c/src/lib/libbsp/m68k/genmcf548x/network/network.c
+++ /dev/null
@@ -1,1696 +0,0 @@
-/*===============================================================*\
-| Project: RTEMS generic MCF548X BSP |
-+-----------------------------------------------------------------+
-| Partially based on the code references which are named below. |
-| Adaptions, modifications, enhancements and any recent parts of |
-| the code are: |
-| Copyright (c) 2009 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-| this file contains the networking driver |
-\*===============================================================*/
-/*
- * RTEMS/TCPIP driver for MCF548X FEC Ethernet
- *
- * Modified for Motorola MPC5200 by Thomas Doerfler, <Thomas.Doerfler@imd-systems.de>
- * COPYRIGHT (c) 2003, IMD
- *
- * Modified for Motorola IceCube (mgt5100) by Peter Rasmussen <prasmus@ipr-engineering.de>
- * COPYRIGHT (c) 2003, IPR Engineering
- *
- * Parts of code are also under property of Driver Information Systems and based
- * on Motorola Proprietary Information.
- * COPYRIGHT (c) 2002 MOTOROLA INC.
- *
- * Modified for Motorola MCF548X by Thomas Doerfler, <Thomas.Doerfler@imd-systems.de>
- * COPYRIGHT (c) 2009, IMD
- *
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <net/if_var.h>
-
-#include <bsp.h>
-#include <bsp/irq-generic.h>
-#include <mcf548x/mcf548x.h>
-#include <rtems/rtems_mii_ioctl.h>
-#include <errno.h>
-
-/* freescale-api-specifics... */
-#include <mcf548x/MCD_dma.h>
-#include <mcf548x/mcdma_glue.h>
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 2
-
-#define FEC_WATCHDOG_TIMEOUT 5 /* check media every 5 seconds */
-
-#define DMA_BD_RX_NUM 32 /* Number of receive buffer descriptors */
-#define DMA_BD_TX_NUM 32 /* Number of transmit buffer descriptors */
-
-#define FEC_EVENT RTEMS_EVENT_0
-
-/*
- * internal SRAM
- * Layout:
- * - RxBD channel 0
- * - TxBD channel 0
- * - RxBD channel 1
- * - TxBD channel 1
- * - DMA task memory
- */
-extern char _SysSramBase[];
-#define SRAM_RXBD_BASE(base,chan) (((MCD_bufDescFec*)(base)) \
- +((chan) \
- *(DMA_BD_RX_NUM+DMA_BD_TX_NUM)))
-
-#define SRAM_TXBD_BASE(base,chan) (((MCD_bufDescFec*)(base)) \
- +((chan) \
- *(DMA_BD_RX_NUM+DMA_BD_TX_NUM) \
- +DMA_BD_RX_NUM))
-
-#define SRAM_DMA_BASE(base) ((void *)SRAM_RXBD_BASE(base,NIFACES+1))
-
-
-#undef ETH_DEBUG
-
-/*
- * 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 DMA_BD_RX_NUM
-#define TX_BUF_COUNT DMA_BD_TX_NUM
-#define TX_BD_PER_BUF 1
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-#define MCF548X_FEC0_IRQ_VECTOR (39+64)
-#define MCF548X_FEC1_IRQ_VECTOR (38+64)
-
-#define MCF548X_FEC_IRQ_VECTOR(chan) (MCF548X_FEC0_IRQ_VECTOR \
- +(chan)*(MCF548X_FEC1_IRQ_VECTOR \
- -MCF548X_FEC0_IRQ_VECTOR))
-
-#define MCF548X_FEC_VECTOR2CHAN(vector) (((int)(vector)-MCF548X_FEC0_IRQ_VECTOR) \
- /(MCF548X_FEC1_IRQ_VECTOR \
- -MCF548X_FEC0_IRQ_VECTOR))
-
-#define MCDMA_FEC_RX_CHAN(chan) (0 + NIFACES*(chan))
-#define MCDMA_FEC_TX_CHAN(chan) (1 + NIFACES*(chan))
-
-#define MCF548X_FEC0_RX_INITIATOR (16)
-#define MCF548X_FEC1_RX_INITIATOR (30)
-#define MCF548X_FEC_RX_INITIATOR(chan) (MCF548X_FEC0_RX_INITIATOR \
- +(chan)*(MCF548X_FEC1_RX_INITIATOR \
- -MCF548X_FEC0_RX_INITIATOR))
-#define MCF548X_FEC0_TX_INITIATOR (17)
-#define MCF548X_FEC1_TX_INITIATOR (31)
-#define MCF548X_FEC_TX_INITIATOR(chan) (MCF548X_FEC0_TX_INITIATOR \
- +(chan)*(MCF548X_FEC1_TX_INITIATOR \
- -MCF548X_FEC0_TX_INITIATOR))
-
-/* BD and parameters are stored in SRAM(refer to sdma.h) */
-#define MCF548X_FEC_BD_BASE ETH_BD_BASE
-
-/* RBD bits definitions */
-#define MCF548X_FEC_RBD_EMPTY 0x8000 /* Buffer is empty */
-#define MCF548X_FEC_RBD_WRAP 0x2000 /* Last BD in ring */
-#define MCF548X_FEC_RBD_INT 0x1000 /* Interrupt */
-#define MCF548X_FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */
-#define MCF548X_FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */
-#define MCF548X_FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */
-#define MCF548X_FEC_RBD_MC 0x0040 /* The received frame is multicast frame */
-#define MCF548X_FEC_RBD_LG 0x0020 /* Frame length violation */
-#define MCF548X_FEC_RBD_NO 0x0010 /* Nonoctet align frame */
-#define MCF548X_FEC_RBD_SH 0x0008 /* Short frame, FEC does not support SH and this bit is always cleared */
-#define MCF548X_FEC_RBD_CR 0x0004 /* CRC error */
-#define MCF548X_FEC_RBD_OV 0x0002 /* Receive FIFO overrun */
-#define MCF548X_FEC_RBD_TR 0x0001 /* The receive frame is truncated */
-#define MCF548X_FEC_RBD_ERR (MCF548X_FEC_RBD_LG | \
- MCF548X_FEC_RBD_NO | \
- MCF548X_FEC_RBD_CR | \
- MCF548X_FEC_RBD_OV | \
- MCF548X_FEC_RBD_TR)
-
-/* TBD bits definitions */
-#define MCF548X_FEC_TBD_READY 0x8000 /* Buffer is ready */
-#define MCF548X_FEC_TBD_WRAP 0x2000 /* Last BD in ring */
-#define MCF548X_FEC_TBD_INT 0x1000 /* Interrupt */
-#define MCF548X_FEC_TBD_LAST 0x0800 /* Buffer is last in frame */
-#define MCF548X_FEC_TBD_TC 0x0400 /* Transmit the CRC */
-#define MCF548X_FEC_TBD_ABC 0x0200 /* Append bad CRC */
-
-#define FEC_INTR_MASK_USED \
-(MCF548X_FEC_EIMR_LC | MCF548X_FEC_EIMR_RL | \
- MCF548X_FEC_EIMR_XFUN | MCF548X_FEC_EIMR_XFERR | MCF548X_FEC_EIMR_RFERR)
-
-typedef enum {
- FEC_STATE_RESTART_0,
- FEC_STATE_RESTART_1,
- FEC_STATE_NORMAL,
-} fec_state;
-
-/*
- * Device data
- */
-struct mcf548x_enet_struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int chan;
- fec_state state;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- MCD_bufDescFec *rxBd;
- MCD_bufDescFec *txBd;
- int rxDmaChan; /* dma task */
- int txDmaChan; /* dma task */
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * MDIO/Phy info
- */
- struct rtems_mdio_info mdio_info;
- int phy_default;
- int phy_chan; /* which fec channel services this phy access? */
- int media_state; /* (last detected) state of media */
-
- unsigned long rxInterrupts;
- unsigned long rxNotLast;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxFIFOError;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txLateCollision;
- unsigned long txUnderrun;
- unsigned long txFIFOError;
- unsigned long txMisaligned;
- unsigned long rxNotFirst;
- unsigned long txRetryLimit;
- };
-
-static struct mcf548x_enet_struct enet_driver[NIFACES];
-
-static void mcf548x_fec_restart(struct mcf548x_enet_struct *sc, rtems_id otherDaemon);
-
-static void fec_send_event(rtems_id task)
-{
- rtems_bsdnet_event_send(task, FEC_EVENT);
-}
-
-static void fec_wait_for_event(void)
-{
- rtems_event_set out;
- rtems_bsdnet_event_receive(
- FEC_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &out
- );
-}
-
-static void mcf548x_fec_request_restart(struct mcf548x_enet_struct *sc)
-{
- sc->state = FEC_STATE_RESTART_0;
- fec_send_event(sc->txDaemonTid);
- fec_send_event(sc->rxDaemonTid);
-}
-
-/*
- * Function: MCF548X_eth_addr_filter_set
- *
- * Description: Set individual address filter for unicast address and
- * set physical address registers.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mcf548x_eth_addr_filter_set(struct mcf548x_enet_struct *sc) {
- unsigned char *mac;
- unsigned char currByte; /* byte for which to compute the CRC */
- int byte; /* loop - counter */
- int bit; /* loop - counter */
- unsigned long crc = 0xffffffff; /* initial value */
- int chan = sc->chan;
-
- /*
- * Get the mac address of ethernet controller
- */
- mac = (unsigned char *)(&sc->arpcom.ac_enaddr);
-
- /*
- * The algorithm used is the following:
- * we loop on each of the six bytes of the provided address,
- * and we compute the CRC by left-shifting the previous
- * value by one position, so that each bit in the current
- * byte of the address may contribute the calculation. If
- * the latter and the MSB in the CRC are different, then
- * the CRC value so computed is also ex-ored with the
- * "polynomium generator". The current byte of the address
- * is also shifted right by one bit at each iteration.
- * This is because the CRC generatore in hardware is implemented
- * as a shift-register with as many ex-ores as the radixes
- * in the polynomium. This suggests that we represent the
- * polynomiumm itsc as a 32-bit constant.
- */
- for(byte = 0; byte < 6; byte++)
- {
-
- currByte = mac[byte];
-
- for(bit = 0; bit < 8; bit++)
- {
-
- if((currByte & 0x01) ^ (crc & 0x01))
- {
-
- crc >>= 1;
- crc = crc ^ 0xedb88320;
-
- }
- else
- {
-
- crc >>= 1;
-
- }
-
- currByte >>= 1;
-
- }
-
- }
-
- crc = crc >> 26;
-
- /*
- * Set individual hash table register
- */
- if(crc >= 32)
- {
-
- MCF548X_FEC_IAUR(chan) = (1 << (crc - 32));
- MCF548X_FEC_IALR(chan) = 0;
-
- }
- else
- {
-
- MCF548X_FEC_IAUR(chan) = 0;
- MCF548X_FEC_IALR(chan) = (1 << crc);
-
- }
-
- /*
- * Set physical address
- */
- MCF548X_FEC_PALR(chan) = ((mac[0] << 24) +
- (mac[1] << 16) +
- (mac[2] << 8) +
- mac[3]);
- MCF548X_FEC_PAUR(chan) = ((mac[4] << 24)
- + (mac[5] << 16)) + 0x8808;
-
- }
-
-
-/*
- * Function: mcf548x_eth_mii_read
- *
- * Description: Read a media independent interface (MII) register on an
- * 18-wire ethernet tranceiver (PHY). Please see your PHY
- * documentation for the register map.
- *
- * Returns: 0 if ok
- *
- * Notes:
- *
- */
-int mcf548x_eth_mii_read(
- int phyAddr, /* PHY number to access or -1 */
- void *uarg, /* unit argument */
- unsigned regAddr, /* register address */
- uint32_t *retVal) /* ptr to read buffer */
-{
- struct mcf548x_enet_struct *sc = uarg;
- int timeout = 0xffff;
- int chan = sc->phy_chan;
-
- /*
- * reading from any PHY's register is done by properly
- * programming the FEC's MII data register.
- */
- MCF548X_FEC_MMFR(chan) = (MCF548X_FEC_MMFR_ST_01 |
- MCF548X_FEC_MMFR_OP_READ |
- MCF548X_FEC_MMFR_TA_10 |
- MCF548X_FEC_MMFR_PA(phyAddr) |
- MCF548X_FEC_MMFR_RA(regAddr));
-
- /*
- * wait for the related interrupt
- */
- while ((timeout--) && (!(MCF548X_FEC_EIR(chan) & MCF548X_FEC_EIR_MII)));
-
- if(timeout == 0) {
-
-#ifdef ETH_DEBUG
- iprintf ("Read MDIO failed..." "\r\n");
-#endif
-
- return 1;
-
- }
-
- /*
- * clear mii interrupt bit
- */
- MCF548X_FEC_EIR(chan) = MCF548X_FEC_EIR_MII;
-
- /*
- * it's now safe to read the PHY's register
- */
- *retVal = (unsigned short) MCF548X_FEC_MMFR(chan);
-
- return 0;
-
-}
-
-/*
- * Function: mcf548x_eth_mii_write
- *
- * Description: Write a media independent interface (MII) register on an
- * 18-wire ethernet tranceiver (PHY). Please see your PHY
- * documentation for the register map.
- *
- * Returns: Success (boolean)
- *
- * Notes:
- *
- */
-static int mcf548x_eth_mii_write(
- int phyAddr, /* PHY number to access or -1 */
- void *uarg, /* unit argument */
- unsigned regAddr, /* register address */
- uint32_t data) /* write data */
-{
- struct mcf548x_enet_struct *sc = uarg;
- int chan = sc->phy_chan;
- int timeout = 0xffff;
-
- MCF548X_FEC_MMFR(chan) = (MCF548X_FEC_MMFR_ST_01 |
- MCF548X_FEC_MMFR_OP_WRITE |
- MCF548X_FEC_MMFR_TA_10 |
- MCF548X_FEC_MMFR_PA(phyAddr) |
- MCF548X_FEC_MMFR_RA(regAddr) |
- MCF548X_FEC_MMFR_DATA(data));
-
- /*
- * wait for the MII interrupt
- */
- while ((timeout--) && (!(MCF548X_FEC_EIR(chan) & MCF548X_FEC_EIR_MII)));
-
- if(timeout == 0)
- {
-
-#ifdef ETH_DEBUG
- iprintf ("Write MDIO failed..." "\r\n");
-#endif
-
- return 1;
-
- }
-
- /*
- * clear MII interrupt bit
- */
- MCF548X_FEC_EIR(chan) = MCF548X_FEC_EIR_MII;
-
- return 0;
-
- }
-
-
-/*
- * Function: mcf548x_fec_reset
- *
- * Description: Reset a running ethernet driver including the hardware
- * FIFOs and the FEC.
- *
- * Returns: Success (boolean)
- *
- * Notes:
- *
- */
-static void mcf548x_fec_reset(struct mcf548x_enet_struct *sc) {
- volatile int delay;
- int chan = sc->chan;
- /*
- * Clear FIFO status registers
- */
- MCF548X_FEC_FECRFSR(chan) = ~0;
- MCF548X_FEC_FECTFSR(chan) = ~0;
-
- /*
- * reset the FIFOs
- */
- MCF548X_FEC_FRST(chan) = 0x03000000;
-
- for (delay = 0;delay < 16*4;delay++) {};
-
- MCF548X_FEC_FRST(chan) = 0x01000000;
-
- /*
- * Issue a reset command to the FEC chip
- */
- MCF548X_FEC_ECR(chan) |= MCF548X_FEC_ECR_RESET;
-
- /*
- * wait at least 16 clock cycles
- */
- for (delay = 0;delay < 16*4;delay++) {};
-}
-
-
-/*
- * Function: mcf548x_fec_off
- *
- * Description: Stop the FEC and disable the ethernet SmartComm tasks.
- * This function "turns off" the driver.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-void mcf548x_fec_off(struct mcf548x_enet_struct *sc)
- {
- int counter = 0xffff;
- int chan = sc->chan;
-
-
-#if defined(ETH_DEBUG)
- uint32_t phyStatus;
- int i;
-
- for(i = 0; i < 9; i++)
- {
-
- mcf548x_eth_mii_read(sc->phy_default, sc, i, &phyStatus);
- iprintf ("Mii reg %d: 0x%04lx" "\r\n", i, phyStatus);
-
- }
-
- for(i = 16; i < 21; i++)
- {
-
- mcf548x_eth_mii_read(sc->phy_default, sc, i, &phyStatus);
- iprintf ("Mii reg %d: 0x%04lx" "\r\n", i, phyStatus);
-
- }
- for(i = 0; i < 32; i++)
- {
-
- mcf548x_eth_mii_read(i, sc, 0, &phyStatus);
- iprintf ("Mii Phy=%d, reg 0: 0x%04lx" "\r\n", i, phyStatus);
-
- }
-#endif /* ETH_DEBUG */
-
- /*
- * block FEC chip interrupts
- */
- MCF548X_FEC_EIMR(chan) = 0;
-
- /*
- * issue graceful stop command to the FEC transmitter if necessary
- */
- MCF548X_FEC_TCR(chan) |= MCF548X_FEC_TCR_GTS;
-
- /*
- * wait for graceful stop to register
- * FIXME: add rtems_task_wake_after here, if it takes to long
- */
- while((counter--) && (!( MCF548X_FEC_EIR(chan) & MCF548X_FEC_EIR_GRA)));
-
- /*
- * Disable the SmartDMA transmit and receive tasks.
- */
- MCD_killDma( sc->rxDmaChan );
- MCD_killDma( sc->txDmaChan );
- /*
- * Disable transmit / receive interrupts
- */
- mcdma_glue_irq_disable(sc->txDmaChan);
- mcdma_glue_irq_disable(sc->rxDmaChan);
-
- /*
- * Disable the Ethernet Controller
- */
- MCF548X_FEC_ECR(chan) &= ~(MCF548X_FEC_ECR_ETHER_EN);
-}
-
-/*
- * MCF548X FEC interrupt handler
- */
-void mcf548x_fec_irq_handler(rtems_vector_number vector)
-{
- struct mcf548x_enet_struct *sc;
- volatile uint32_t ievent;
- int chan;
-
- sc = &(enet_driver[MCF548X_FEC_VECTOR2CHAN(vector)]);
- chan = sc->chan;
- ievent = MCF548X_FEC_EIR(chan);
-
- MCF548X_FEC_EIR(chan) = ievent;
- /*
- * check errors, update statistics
- */
- if (ievent & MCF548X_FEC_EIR_LC) {
- sc->txLateCollision++;
- }
- if (ievent & MCF548X_FEC_EIR_RL) {
- sc->txRetryLimit++;
- }
- if (ievent & MCF548X_FEC_EIR_XFUN) {
- sc->txUnderrun++;
- }
- if (ievent & MCF548X_FEC_EIR_XFERR) {
- sc->txFIFOError++;
- }
- if (ievent & MCF548X_FEC_EIR_RFERR) {
- sc->rxFIFOError++;
- }
- /*
- * fatal error ocurred?
- */
- if (ievent & (MCF548X_FEC_EIR_RFERR | MCF548X_FEC_EIR_XFERR)) {
- MCF548X_FEC_EIMR(chan) &=~(MCF548X_FEC_EIMR_RFERR | MCF548X_FEC_EIMR_XFERR);
- printk("fifo\n");
- mcf548x_fec_request_restart(sc);
- }
-}
-
-/*
- * MCF548X DMA ethernet interrupt handler
- */
-void mcf548x_mcdma_rx_irq_handler(void * param)
-{
- struct mcf548x_enet_struct *sc = (struct mcf548x_enet_struct *)param;
- /* Frame received? */
- if(MCDMA_GET_PENDING(sc->rxDmaChan)) {
- MCDMA_CLR_PENDING(sc->rxDmaChan);
-
- mcdma_glue_irq_disable(sc->rxDmaChan);/*Disable receive ints*/
- sc->rxInterrupts++; /* Rx int has occurred */
- fec_send_event(sc->rxDaemonTid);
- }
-}
-
-/*
- * MCF548X DMA ethernet interrupt handler
- */
-void mcf548x_mcdma_tx_irq_handler(void * param)
-{
- struct mcf548x_enet_struct *sc = (struct mcf548x_enet_struct *)param;
-
- /* Buffer transmitted or transmitter error? */
- if(MCDMA_GET_PENDING(sc->txDmaChan)) {
-
- MCDMA_CLR_PENDING(sc->txDmaChan);
-
- mcdma_glue_irq_disable(sc->txDmaChan);/*Disable tx ints*/
-
- sc->txInterrupts++; /* Tx int has occurred */
-
- fec_send_event(sc->txDaemonTid);
- }
-}
-
-/*
- * Function: mcf548x_fec_initialize_hardware
- *
- * Description: Configure the MCF548X FEC registers and enable the
- * SmartComm tasks. This function "turns on" the driver.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mcf548x_fec_initialize_hardware(struct mcf548x_enet_struct *sc)
- {
- int chan = sc->chan;
-
- /*
- * Reset mcf548x FEC
- */
- mcf548x_fec_reset(sc);
-
- /*
- * Clear FEC-Lite interrupt event register (IEVENT)
- */
- MCF548X_FEC_EIR(chan) = MCF548X_FEC_EIR_CLEAR_ALL;
-
- /*
- * Set interrupt mask register
- */
- MCF548X_FEC_EIMR(chan) = FEC_INTR_MASK_USED;
- /*
- * Set FEC-Lite receive control register (R_CNTRL)
- * frame length=1518, MII mode for 18-wire-transceiver
- */
- MCF548X_FEC_RCR(chan) = (MCF548X_FEC_RCR_MAX_FL(ETHER_MAX_LEN)
- | MCF548X_FEC_RCR_FCE
- | MCF548X_FEC_RCR_MII_MODE);
-
- /*
- * Set FEC-Lite transmit control register (X_CNTRL)
- * full-duplex, heartbeat disabled
- */
- MCF548X_FEC_TCR(chan) = MCF548X_FEC_TCR_FDEN;
-
-
-
- /*
- * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock(33Mhz)
- * and do not drop the Preamble.
- */
- MCF548X_FEC_MSCR(chan) = MCF548X_FEC_MSCR_MII_SPEED(7); /* ipb_clk = 33 MHz */
-
- /*
- * Set Opcode/Pause Duration Register
- */
- MCF548X_FEC_PAUR(chan) = 0x00010020;
-
- /*
- * Set Rx FIFO alarm and granularity value
- */
- MCF548X_FEC_FECRFCR(chan) = (MCF548X_FEC_FECRFCR_FRM
- | MCF548X_FEC_FECRFCR_GR(0x7));
- MCF548X_FEC_FECRFAR(chan) = MCF548X_FEC_FECRFAR_ALARM(256);
-
- /*
- * Set Tx FIFO granularity value
- */
- MCF548X_FEC_FECTFCR(chan) = (MCF548X_FEC_FECTFCR_FRM
- | MCF548X_FEC_FECTFCR_GR(7));
-
- /*
- * Set transmit fifo watermark register (X_WMRK), default = 64
- */
- MCF548X_FEC_FECTFAR(chan) = MCF548X_FEC_FECTFAR_ALARM(512);
- MCF548X_FEC_FECTFWR(chan) = MCF548X_FEC_FECTFWR_X_WMRK_256;
-
- /*
- * Set individual address filter for unicast address
- * and set physical address registers.
- */
- mcf548x_eth_addr_filter_set(sc);
-
- /*
- * Set multicast address filter
- */
- MCF548X_FEC_GAUR(chan) = 0x00000000;
- MCF548X_FEC_GALR(chan) = 0x00000000;
-
- /*
- * enable CRC in finite state machine register
- */
- MCF548X_FEC_CTCWR(chan) = MCF548X_FEC_CTCWR_TFCW | MCF548X_FEC_CTCWR_CRC;
- }
-
-
-/*
- * Send packet (caller provides header).
- */
-static void mcf548x_fec_tx_start(struct ifnet *ifp)
- {
-
- struct mcf548x_enet_struct *sc = ifp->if_softc;
-
- ifp->if_flags |= IFF_OACTIVE;
-
- fec_send_event(sc->txDaemonTid);
-
- }
-
-static void fec_start_dma_and_controller(struct mcf548x_enet_struct *sc)
-{
- int chan = sc->chan;
- int mcdma_rc;
- /*
- * Enable the SmartDMA receive task.
- */
- mcdma_rc = MCD_startDma
- (sc->rxDmaChan, /* the channel on which to run the DMA */
- (void *)sc->rxBd, /* the address to move data from, or buffer-descriptor addr */
- 0, /* the amount to increment the source address per transfer */
- (void *)&MCF548X_FEC_FECRFDR(chan), /* the address to move data to */
- 0, /* the amount to increment the destination address per transfer */
- ETHER_MAX_LEN, /* the number of bytes to transfer independent of the transfer size */
- 0, /* the number bytes in of each data movement (1, 2, or 4) */
- MCF548X_FEC_RX_INITIATOR(chan), /* what device initiates the DMA */
- 2, /* priority of the DMA */
- 0 /* flags describing the DMA */
- | MCD_FECRX_DMA
- | MCD_INTERRUPT
- | MCD_TT_FLAGS_CW
- | MCD_TT_FLAGS_RL
- | MCD_TT_FLAGS_SP
- ,
- 0 /* a description of byte swapping, bit swapping, and CRC actions */
- | MCD_NO_CSUM
- | MCD_NO_BYTE_SWAP
- );
- if (mcdma_rc != MCD_OK) {
- rtems_panic("FEC: cannot start rx DMA");
- }
- mcdma_rc = MCD_startDma
- (sc->txDmaChan, /* the channel on which to run the DMA */
- (void *)sc->txBd, /* the address to move data from, or buffer-descriptor addr */
- 0, /* the amount to increment the source address per transfer */
- (void *)&MCF548X_FEC_FECTFDR(chan), /* the address to move data to */
- 0, /* the amount to increment the destination address per transfer */
- ETHER_MAX_LEN, /* the number of bytes to transfer independent of the transfer size */
- 0, /* the number bytes in of each data movement (1, 2, or 4) */
- MCF548X_FEC_TX_INITIATOR(chan), /* what device initiates the DMA */
- 1, /* priority of the DMA */
- 0 /* flags describing the DMA */
- | MCD_FECTX_DMA
- | MCD_INTERRUPT
- | MCD_TT_FLAGS_CW
- | MCD_TT_FLAGS_RL
- | MCD_TT_FLAGS_SP
- ,
- 0 /* a description of byte swapping, bit swapping, and CRC actions */
- | MCD_NO_CSUM
- | MCD_NO_BYTE_SWAP
- );
- if (mcdma_rc != MCD_OK) {
- rtems_panic("FEC: cannot start tx DMA");
- }
-
- /*
- * Enable FEC-Lite controller
- */
- MCF548X_FEC_ECR(chan) |= MCF548X_FEC_ECR_ETHER_EN;
-}
-
-static void mcf548x_fec_restart(struct mcf548x_enet_struct *sc, rtems_id otherDaemon)
-{
- if (sc->state == FEC_STATE_RESTART_1) {
- mcf548x_fec_initialize_hardware(sc);
- fec_start_dma_and_controller(sc);
- sc->state = FEC_STATE_NORMAL;
- } else {
- sc->state = FEC_STATE_RESTART_1;
- }
-
- fec_send_event(otherDaemon);
- while (sc->state != FEC_STATE_NORMAL) {
- fec_wait_for_event();
- }
-}
-
-static void fec_reset_bd_and_discard_tx_frames(
- int bdCount,
- MCD_bufDescFec *bdRing,
- struct mbuf **mbufs
-)
-{
- int bdIndex = 0;
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- bool bdIsLast = bdIndex == bdCount - 1;
- struct mbuf *m = mbufs[bdIndex];
-
- bdRing[bdIndex].statCtrl = bdIsLast ? MCF548X_FEC_TBD_WRAP : 0;
-
- if (m != NULL) {
- mbufs[bdIndex] = NULL;
- m_free(m);
- }
- }
-}
-
-static void fec_reset_tx_dma(
- int dmaChan,
- int bdCount,
- MCD_bufDescFec *bdRing,
- struct mbuf **mbufs,
- struct mbuf *m
-)
-{
- if (m != NULL) {
- m_freem(m);
- }
-
- MCD_killDma(dmaChan);
-
- fec_reset_bd_and_discard_tx_frames(bdCount, bdRing, mbufs);
-}
-
-static struct mbuf *fec_next_fragment(
- struct ifnet *ifp,
- struct mbuf *m,
- bool *isFirst
-)
-{
- struct mbuf *n = NULL;
-
- *isFirst = false;
-
- while (true) {
- if (m == NULL) {
- IF_DEQUEUE(&ifp->if_snd, m);
-
- if (m != NULL) {
- *isFirst = true;
- } else {
- ifp->if_flags &= ~IFF_OACTIVE;
-
- return NULL;
- }
- }
-
- if (m->m_len > 0) {
- break;
- } else {
- m = m_free(m);
- }
- }
-
- n = m->m_next;
- while (n != NULL && n->m_len <= 0) {
- n = m_free(n);
- }
- m->m_next = n;
-
- return m;
-}
-
-static bool fec_transmit(
- struct ifnet *ifp,
- int dmaChan,
- int bdCount,
- MCD_bufDescFec *bdRing,
- struct mbuf **mbufs,
- int *bdIndexPtr,
- struct mbuf **mPtr,
- MCD_bufDescFec **firstPtr
-)
-{
- bool bdShortage = false;
- int bdIndex = *bdIndexPtr;
- struct mbuf *m = *mPtr;
- MCD_bufDescFec *first = *firstPtr;
-
- while (true) {
- MCD_bufDescFec *bd = &bdRing[bdIndex];
-
- MCDMA_CLR_PENDING(dmaChan);
- if ((bd->statCtrl & MCF548X_FEC_TBD_READY) == 0) {
- struct mbuf *done = mbufs[bdIndex];
- bool isFirst = false;
-
- if (done != NULL) {
- m_free(done);
- mbufs[bdIndex] = NULL;
- }
-
- m = fec_next_fragment(ifp, m, &isFirst);
- if (m != NULL) {
- bool bdIsLast = bdIndex == bdCount - 1;
- u16 status = bdIsLast ? MCF548X_FEC_TBD_WRAP : 0;
-
- bd->length = (u16) m->m_len;
- bd->dataPointer = mtod(m, u32);
-
- mbufs[bdIndex] = m;
-
- rtems_cache_flush_multiple_data_lines(mtod(m, void *), m->m_len);
-
- if (isFirst) {
- first = bd;
- } else {
- status |= MCF548X_FEC_TBD_READY;
- }
-
- if (m->m_next != NULL) {
- bd->statCtrl = status;
- } else {
- bd->statCtrl = status | MCF548X_FEC_TBD_INT | MCF548X_FEC_TBD_LAST;
- first->statCtrl |= MCF548X_FEC_TBD_READY;
- MCD_continDma(dmaChan);
- }
-
- m = m->m_next;
- } else {
- break;
- }
- } else {
- bdShortage = true;
- break;
- }
-
- if (bdIndex < bdCount - 1) {
- ++bdIndex;
- } else {
- bdIndex = 0;
- }
- }
-
- *bdIndexPtr = bdIndex;
- *mPtr = m;
- *firstPtr = first;
-
- return bdShortage;
-}
-
-static MCD_bufDescFec *fec_init_tx_dma(
- MCD_bufDescFec *bdRing,
- int bdCount
-)
-{
- int bdIndex;
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- bool bdIsLast = bdIndex == bdCount - 1;
-
- bdRing[bdIndex].dataPointer = 0;
- bdRing[bdIndex].length = 0;
- bdRing[bdIndex].statCtrl = bdIsLast ? MCF548X_FEC_RBD_WRAP : 0;
- }
-
- return bdRing;
-}
-
-static void mcf548x_fec_txDaemon(void *arg)
-{
- struct mcf548x_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int dmaChan = sc->txDmaChan;
- int bdIndex = 0;
- int bdCount = sc->txBdCount;
- struct mbuf **mbufs = &sc->txMbuf[0];
- struct mbuf *m = NULL;
- MCD_bufDescFec *bdRing = fec_init_tx_dma(sc->txBd, bdCount);
- MCD_bufDescFec *first = NULL;
- bool bdShortage = false;
-
- memset(mbufs, 0, bdCount * sizeof(*mbufs));
-
- while (true) {
- if (bdShortage) {
- mcdma_glue_irq_enable(dmaChan);
- }
- fec_wait_for_event();
-
- if (sc->state != FEC_STATE_NORMAL) {
- fec_reset_tx_dma(dmaChan, bdCount, bdRing, mbufs, m);
- mcf548x_fec_restart(sc, sc->rxDaemonTid);
- bdIndex = 0;
- m = NULL;
- first = NULL;
- }
-
- bdShortage = fec_transmit(
- ifp,
- dmaChan,
- bdCount,
- bdRing,
- mbufs,
- &bdIndex,
- &m,
- &first
- );
- }
-}
-
-static struct mbuf *fec_add_mbuf(
- int how,
- struct ifnet *ifp,
- MCD_bufDescFec *bd,
- bool bdIsLast
-)
-{
- struct mbuf *m;
-
- MGETHDR(m, how, MT_DATA);
- if (m != NULL) {
- MCLGET(m, how);
- if ((m->m_flags & M_EXT) != 0) {
- m->m_pkthdr.rcvif = ifp;
-
- rtems_cache_invalidate_multiple_data_lines(mtod(m, void *), ETHER_MAX_LEN);
-
- bd->dataPointer = mtod(m, u32);
- bd->length = ETHER_MAX_LEN;
- bd->statCtrl = MCF548X_FEC_RBD_EMPTY
- | MCF548X_FEC_RBD_INT
- | (bdIsLast ? MCF548X_FEC_RBD_WRAP : 0);
- } else {
- m_free(m);
- }
- }
-
- return m;
-}
-
-static MCD_bufDescFec *fec_init_rx_dma(
- MCD_bufDescFec *bdRing,
- struct ifnet *ifp,
- int bdCount,
- struct mbuf **mbufs
-)
-{
- int bdIndex;
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- bool bdIsLast = bdIndex == bdCount - 1;
-
- mbufs[bdIndex] = fec_add_mbuf(M_WAIT, ifp, &bdRing[bdIndex], bdIsLast);
- }
-
- return bdRing;
-}
-
-static void fec_reset_rx_dma(
- int dmaChan,
- int bdCount,
- MCD_bufDescFec *bdRing
-)
-{
- int bdIndex;
-
- MCD_killDma(dmaChan);
-
- for (bdIndex = 0; bdIndex < bdCount - 1; ++bdIndex) {
- bdRing[bdIndex].length = ETHER_MAX_LEN;
- bdRing[bdIndex].statCtrl = MCF548X_FEC_RBD_EMPTY | MCF548X_FEC_RBD_INT;
- }
-
- bdRing[bdIndex].length = ETHER_MAX_LEN;
- bdRing[bdIndex].statCtrl = MCF548X_FEC_RBD_EMPTY | MCF548X_FEC_RBD_INT | MCF548X_FEC_RBD_WRAP;
-}
-
-static int fec_ether_input(
- struct ifnet *ifp,
- int dmaChan,
- int bdIndex,
- int bdCount,
- MCD_bufDescFec *bdRing,
- struct mbuf **mbufs
-)
-{
- while (true) {
- bool bdIsLast = bdIndex == bdCount - 1;
- MCD_bufDescFec *bd = &bdRing[bdIndex];
- struct mbuf *m = mbufs[bdIndex];
- struct mbuf *n;
- u16 status;
-
- MCDMA_CLR_PENDING(dmaChan);
- status = bd->statCtrl;
-
- if ((status & MCF548X_FEC_RBD_EMPTY) != 0) {
- break;
- }
-
- n = fec_add_mbuf(0, ifp, bd, bdIsLast);
- if (n != NULL) {
- int len = bd->length - ETHER_HDR_LEN - ETHER_CRC_LEN;
- struct ether_header *eh = mtod(m, struct ether_header *);
-
- m->m_len = len;
- m->m_pkthdr.len = len;
- m->m_data = mtod(m, char *) + ETHER_HDR_LEN;
-
- ether_input(ifp, eh, m);
- } else {
- n = m;
- }
-
- mbufs[bdIndex] = n;
-
- if (bdIndex < bdCount - 1) {
- ++bdIndex;
- } else {
- bdIndex = 0;
- }
- }
-
- return bdIndex;
-}
-
-static void mcf548x_fec_rxDaemon(void *arg)
-{
- struct mcf548x_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int dmaChan = sc->rxDmaChan;
- int bdIndex = 0;
- int bdCount = sc->rxBdCount;
- struct mbuf **mbufs = &sc->rxMbuf[0];
- MCD_bufDescFec *bdRing = fec_init_rx_dma(sc->rxBd, ifp, bdCount, mbufs);
-
- while (true) {
- mcdma_glue_irq_enable(dmaChan);
- fec_wait_for_event();
-
- bdIndex = fec_ether_input(ifp, dmaChan, bdIndex, bdCount, bdRing, mbufs);
-
- if (sc->state != FEC_STATE_NORMAL) {
- fec_reset_rx_dma(dmaChan, bdCount, bdRing);
- mcf548x_fec_restart(sc, sc->txDaemonTid);
- bdIndex = 0;
- }
- }
-}
-
-/*
- * Initialize and start the device
- */
-static void mcf548x_fec_init(void *arg)
-{
- struct mcf548x_enet_struct *sc = (struct mcf548x_enet_struct *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int chan = sc->chan;
- rtems_isr_entry old_handler;
- char *txTaskName = "FTx0";
- char *rxTaskName = "FRx0";
- if(sc->txDaemonTid == 0)
- {
- /*
- * Allocate a set of BDs
- */
- sc->rxBd = SRAM_RXBD_BASE(_SysSramBase,chan);
- sc->txBd = SRAM_TXBD_BASE(_SysSramBase,chan);
-
- if(!sc->rxBd || !sc->txBd)
- rtems_panic ("No memory for BDs");
- /*
- * clear the BDs
- */
- memset((void *)sc->rxBd,0,sc->rxBdCount * sizeof *(sc->rxBd));
- memset((void *)sc->txBd,0,sc->txBdCount * sizeof *(sc->txBd));
- /*
- * Allocate a set of mbuf pointers
- */
- sc->rxMbuf =
- malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf =
- malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
-
- if(!sc->rxMbuf || !sc->txMbuf)
- rtems_panic ("No memory for mbuf pointers");
-
- sc->txDmaChan = MCDMA_FEC_TX_CHAN(chan);
- sc->rxDmaChan = MCDMA_FEC_RX_CHAN(chan);
-
- mcdma_glue_init(SRAM_DMA_BASE(_SysSramBase));
-
- /*
- * Set up interrupts
- */
- mcdma_glue_irq_install(sc->rxDmaChan,
- mcf548x_mcdma_rx_irq_handler,
- sc);
- mcdma_glue_irq_install(sc->txDmaChan,
- mcf548x_mcdma_tx_irq_handler,
- sc);
- if(rtems_interrupt_catch(mcf548x_fec_irq_handler,
- MCF548X_FEC_IRQ_VECTOR(chan),
- &old_handler)) {
- rtems_panic ("Can't attach MFC54xx FEX interrupt handler\n");
- }
-
- bsp_interrupt_vector_enable(MCF548X_IRQ_FEC(chan));
-
- MCF548X_FEC_EIMR(chan) = FEC_INTR_MASK_USED;
-
- /*
- * Start driver tasks
- */
- txTaskName[3] = '0'+chan;
- rxTaskName[3] = '0'+chan;
- sc->txDaemonTid = rtems_bsdnet_newproc(txTaskName, 4096,
- mcf548x_fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc(rxTaskName, 4096,
- mcf548x_fec_rxDaemon, sc);
- }
-
- mcf548x_fec_request_restart(sc);
-
- /*
- * Set flags appropriately
- */
- if(ifp->if_flags & IFF_PROMISC)
- MCF548X_FEC_RCR(chan) |= MCF548X_FEC_RCR_PROM;
- else
- MCF548X_FEC_RCR(chan) &= ~MCF548X_FEC_RCR_PROM;
-
- /*
- * init timer so the "watchdog function gets called periodically
- */
- ifp->if_timer = 1;
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-
-static void enet_stats (struct mcf548x_enet_struct *sc)
-{
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Rx Not First:%-8lu", sc->rxNotFirst);
- printf (" Rx Not Last:%-8lu\n", sc->rxNotLast);
- printf (" Rx Giant:%-8lu", sc->rxGiant);
- printf (" Rx Non-octet:%-8lu", sc->rxNonOctet);
- printf (" Rx Bad CRC:%-8lu\n", sc->rxBadCRC);
- printf (" Rx FIFO Error:%-8lu", sc->rxFIFOError);
- printf (" Rx Collision:%-8lu", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8lu\n", sc->txInterrupts);
- printf (" Tx Deferred:%-8lu", sc->txDeferred);
- printf (" Tx Late Collision:%-8lu", sc->txLateCollision);
- printf (" Tx Retransmit Limit:%-8lu\n", sc->txRetryLimit);
- printf (" Tx Underrun:%-8lu", sc->txUnderrun);
- printf (" Tx FIFO Error:%-8lu", sc->txFIFOError);
- printf (" Tx Misaligned:%-8lu\n", sc->txMisaligned);
-
-}
-
-int32_t mcf548x_fec_setMultiFilter(struct ifnet *ifp)
-{
- /*struct mcf548x_enet_struct *sc = ifp->if_softc; */
- /* XXX anything to do? */
- return 0;
-}
-
-
-/*
- * Driver ioctl handler
- */
-static int mcf548x_fec_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
- {
- struct mcf548x_enet_struct *sc = ifp->if_softc;
- int error = 0;
-
- switch(command)
- {
-
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- rtems_mii_ioctl (&(sc->mdio_info),sc,command,(void *)data);
- break;
-
- case SIOCGIFADDR:
- case SIOCSIFADDR:
-
- ether_ioctl(ifp, command, data);
-
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI: {
- struct ifreq* ifr = (struct ifreq*) data;
- error = (command == SIOCADDMULTI)
- ? ether_addmulti(ifr, &sc->arpcom)
- : ether_delmulti(ifr, &sc->arpcom);
-
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING)
- error = mcf548x_fec_setMultiFilter(ifp);
- else
- error = 0;
- }
- break;
- }
-
- case SIOCSIFFLAGS:
-
- switch(ifp->if_flags & (IFF_UP | IFF_RUNNING))
- {
-
- case IFF_RUNNING:
-
- mcf548x_fec_off(sc);
-
- break;
-
- case IFF_UP:
-
- mcf548x_fec_init(sc);
-
- break;
-
- case IFF_UP | IFF_RUNNING:
-
- mcf548x_fec_off(sc);
- mcf548x_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;
-
- }
-
-
-/*
- * init the PHY and adapt FEC settings
- */
-int mcf548x_fec_mode_adapt(struct ifnet *ifp)
-{
- int result = 0;
- struct mcf548x_enet_struct *sc = ifp->if_softc;
- int media = IFM_MAKEWORD( 0, 0, 0, sc->phy_default);
- int chan = sc->chan;
-
- /*
- * fetch media status
- */
- result = mcf548x_fec_ioctl(ifp,SIOCGIFMEDIA,(caddr_t)&media);
- if (result != 0) {
- return result;
- }
- /*
- * status is unchanged? then do nothing
- */
- if (media == sc->media_state) {
- return 0;
- }
- /*
- * otherwise: for the first call, try to negotiate mode
- */
- if (sc->media_state == 0) {
- /*
- * set media status: set auto negotiation -> start auto-negotiation
- */
- media = IFM_MAKEWORD(0,IFM_AUTO,0,sc->phy_default);
- result = mcf548x_fec_ioctl(ifp,SIOCSIFMEDIA,(caddr_t)&media);
- if (result != 0) {
- return result;
- }
- /*
- * wait for auto-negotiation to terminate
- */
- do {
- media = IFM_MAKEWORD(0,0,0,sc->phy_default);
- result = mcf548x_fec_ioctl(ifp,SIOCGIFMEDIA,(caddr_t)&media);
- if (result != 0) {
- return result;
- }
- } while (IFM_NONE == IFM_SUBTYPE(media));
- }
-
- /*
- * now set HW according to media results:
- */
-
- /*
- * if we are half duplex then switch to half duplex
- */
- if (0 == (IFM_FDX & IFM_OPTIONS(media))) {
- MCF548X_FEC_TCR(chan) &= ~MCF548X_FEC_TCR_FDEN;
- }
- else {
- MCF548X_FEC_TCR(chan) |= MCF548X_FEC_TCR_FDEN;
- }
- /*
- * store current media state for future compares
- */
- sc->media_state = media;
-
- return 0;
-}
-
-/*
- * periodically poll the PHY. if mode has changed,
- * then adjust the FEC settings
- */
-static void mcf548x_fec_watchdog( struct ifnet *ifp)
-{
- mcf548x_fec_mode_adapt(ifp);
- ifp->if_timer = FEC_WATCHDOG_TIMEOUT;
-}
-
-/*
- * Attach the MCF548X fec driver to the system
- */
-int rtems_mcf548x_fec_driver_attach(struct rtems_bsdnet_ifconfig *config)
- {
- struct mcf548x_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 FEC unit number.\n");
- return 0;
-
- }
-
- sc = &enet_driver[unitNumber - 1];
- sc->chan = 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 /* NVRAM_CONFIGURE != 1 */
-
- if(config->hardware_address)
- {
-
- memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
-
- }
-
-#endif /* NVRAM_CONFIGURE != 1 */
-#ifdef HAS_UBOOT
- if ((sc->arpcom.ac_enaddr[0] == 0) &&
- (sc->arpcom.ac_enaddr[1] == 0) &&
- (sc->arpcom.ac_enaddr[2] == 0)) {
- memcpy(
- (void *)sc->arpcom.ac_enaddr,
- bsp_uboot_board_info.bi_enetaddr,
- ETHER_ADDR_LEN
- );
- }
-#endif
-#ifdef HAS_DBUG
- if ((sc->arpcom.ac_enaddr[0] == 0) &&
- (sc->arpcom.ac_enaddr[1] == 0) &&
- (sc->arpcom.ac_enaddr[2] == 0)) {
- memcpy(
- (void *)sc->arpcom.ac_enaddr,
- DBUG_SETTINGS.macaddr,
- ETHER_ADDR_LEN
- );
- }
-#endif
- if ((sc->arpcom.ac_enaddr[0] == 0) &&
- (sc->arpcom.ac_enaddr[1] == 0) &&
- (sc->arpcom.ac_enaddr[2] == 0)) {
- /* 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");
- }
- 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;
-
- /*
- * setup info about mdio interface
- */
- sc->mdio_info.mdio_r = mcf548x_eth_mii_read;
- sc->mdio_info.mdio_w = mcf548x_eth_mii_write;
- sc->mdio_info.has_gmii = 0; /* we do not support gigabit IF */
-
- /*
- * XXX: Although most hardware builders will assign the PHY addresses
- * like this, this should be more configurable
- */
- sc->phy_default = unitNumber-1;
- sc->phy_chan = 0; /* assume all MII accesses are via FEC0 */
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = mcf548x_fec_init;
- ifp->if_ioctl = mcf548x_fec_ioctl;
- ifp->if_start = mcf548x_fec_tx_start;
- ifp->if_output = ether_output;
- ifp->if_watchdog = mcf548x_fec_watchdog; /* XXX: timer is set in "init" */
- ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
- /*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;
- }
-
-
-int rtems_mcf548x_fec_driver_attach_detach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- if (attaching) {
- return rtems_mcf548x_fec_driver_attach(config);
- }
- else {
- return 0;
- }
-}
-
-
diff --git a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am
index e6b30e5470..c036171923 100644
--- a/c/src/lib/libbsp/m68k/mcf5235/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mcf5235/Makefile.am
@@ -38,7 +38,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5235/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5235/btimer/btimer.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5235/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf5235.c
diff --git a/c/src/lib/libbsp/m68k/mcf5235/network/network.c b/c/src/lib/libbsp/m68k/mcf5235/network/network.c
deleted file mode 100644
index 6c8fa88be2..0000000000
--- a/c/src/lib/libbsp/m68k/mcf5235/network/network.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- * RTEMS/TCPIP driver for MCF5235 Fast Ethernet Controller
- *
- * TO DO: Check network stack code -- force longword alignment of all tx mbufs?
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 1
-
-#define FEC_INTC0_TX_VECTOR (64+23)
-#define FEC_INTC0_RX_VECTOR (64+27)
-
-/*
- * 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 three or more buffer descriptors.
- */
-#define RX_BUF_COUNT 32
-#define TX_BUF_COUNT 20
-#define TX_BD_PER_BUF 3
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP task synchronization.
- */
-#define TX_INTERRUPT_EVENT RTEMS_EVENT_1
-#define RX_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 plus CRC (1518).
- * Round off to nearest multiple of RBUF_ALIGN.
- */
-#define MAX_MTU_SIZE 1518
-#define RBUF_ALIGN 4
-#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
-
-#if (MCLBYTES < RBUF_SIZE)
- #error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-typedef struct mcf5235BufferDescriptor_ {
- volatile uint16_t status;
- uint16_t length;
- volatile void *buffer;
-} mcf5235BufferDescriptor_t;
-
-/*
- * Per-device data
- */
-struct mcf5235_enet_struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- mcf5235BufferDescriptor_t *rxBdBase;
- mcf5235BufferDescriptor_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long txInterrupts;
- unsigned long txRawWait;
- unsigned long txRealign;
-};
-static struct mcf5235_enet_struct enet_driver[NIFACES];
-
-static rtems_isr
-mcf5235_fec_rx_interrupt_handler( rtems_vector_number v )
-{
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF;
- MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_RXF;
- enet_driver[0].rxInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5235_fec_tx_interrupt_handler( rtems_vector_number v )
-{
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF;
- MCF5235_FEC_EIMR &= ~MCF5235_FEC_EIMR_TXF;
- enet_driver[0].txInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
-}
-
-/*
- * Allocate buffer descriptors from (non-cached) on-chip static RAM
- * Ensure 128-bit (16-byte) alignment
- */
-extern char __SRAMBASE[];
-
-static mcf5235BufferDescriptor_t *
-mcf5235_bd_allocate(unsigned int count)
-{
- static mcf5235BufferDescriptor_t *bdp = (mcf5235BufferDescriptor_t *)__SRAMBASE;
- mcf5235BufferDescriptor_t *p = bdp;
-
- bdp += count;
- if ((int)bdp & 0xF)
- bdp = (mcf5235BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
- return p;
-}
-
-#if UNUSED
-/*
- * Read MII register
- * Busy-waits, but transfer time should be short!
- */
-static int
-getMII(int phyNumber, int regNumber)
-{
- MCF5235_FEC_MMFR = (0x1 << 30) |
- (0x2 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16);
- while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0);
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII;
- return MCF5235_FEC_MMFR & 0xFFFF;
-}
-#endif
-
-/*
- * Write MII register
- * Busy-waits, but transfer time should be short!
- */
-static void
-setMII(int phyNumber, int regNumber, int value)
-{
- MCF5235_FEC_MMFR = (0x1 << 30) |
- (0x1 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16) |
- (value & 0xFFFF);
- while ((MCF5235_FEC_EIR & MCF5235_FEC_EIR_MII) == 0);
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_MII;
-}
-
-static void
-mcf5235_fec_initialize_hardware(struct mcf5235_enet_struct *sc)
-{
- int i;
- const unsigned char *hwaddr = 0;
- rtems_status_code status;
- rtems_isr_entry old_handler;
- uint32_t clock_speed = get_CPU_clock_speed();
-
- /*
- * Issue reset to FEC
- */
- MCF5235_FEC_ECR = MCF5235_FEC_ECR_RESET;
- rtems_task_wake_after(1);
- MCF5235_FEC_ECR = 0;
-
- /*
- * Configuration of I/O ports is done outside of this function
- */
-#if 0
- imm->gpio.pbcnt |= MCF5235_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
-#endif
-
- /*
- * Set our physical address
- */
- hwaddr = sc->arpcom.ac_enaddr;
- MCF5235_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
- (hwaddr[2] << 8) | (hwaddr[3] << 0);
- MCF5235_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
-
-
- /*
- * Clear the hash table
- */
- MCF5235_FEC_GAUR = 0;
- MCF5235_FEC_GALR = 0;
-
- /*
- * Set up receive buffer size
- */
- MCF5235_FEC_EMRBR = 1520; /* Standard Ethernet */
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf)
- rtems_panic("No memory for mbuf pointers");
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = mcf5235_bd_allocate(sc->rxBdCount);
- sc->txBdBase = mcf5235_bd_allocate(sc->txBdCount);
- MCF5235_FEC_ERDSR = (int)sc->rxBdBase;
- MCF5235_FEC_ETDSR = (int)sc->txBdBase;
-
- /*
- * Set up Receive Control Register:
- * Not promiscuous
- * MII mode
- * Full duplex
- * No loopback
- */
- MCF5235_FEC_RCR = MCF5235_FEC_RCR_MAX_FL(MAX_MTU_SIZE) |
- MCF5235_FEC_RCR_MII_MODE;
-
- /*
- * Set up Transmit Control Register:
- * Full duplex
- * No heartbeat
- */
- MCF5235_FEC_TCR = MCF5235_FEC_TCR_FDEN;
-
- /*
- * Initialize statistic counters
- */
- MCF5235_FEC_MIBC = MCF5235_FEC_MIBC_MIB_DISABLE;
- {
- vuint32 *vuip = &MCF5235_FEC_RMON_T_DROP;
- while (vuip <= &MCF5235_FEC_IEEE_R_OCTETS_OK)
- *vuip++ = 0;
- }
- MCF5235_FEC_MIBC = 0;
-
- /*
- * Set MII speed to <= 2.5 MHz
- */
- i = (clock_speed + 5000000 - 1) / 5000000;
- MCF5235_FEC_MSCR = MCF5235_FEC_MSCR_MII_SPEED(i);
-
- /*
- * Set PHYS to 100 Mb/s, full duplex
- */
- setMII(1, 0, 0x2100);
-
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0 ; i < sc->rxBdCount ; i++)
- (sc->rxBdBase + i)->status = 0;
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0 ; i < sc->txBdCount ; i++) {
- sc->txBdBase[i].status = 0;
- sc->txMbuf[i] = NULL;
- }
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Set up interrupts
- */
- status = rtems_interrupt_catch( mcf5235_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler );
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5235 FEC TX interrupt handler: %s\n",
- rtems_status_text(status));
- status = rtems_interrupt_catch(mcf5235_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5235 FEC RX interrupt handler: %s\n",
- rtems_status_text(status));
- MCF5235_INTC0_ICR23 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5235_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY);
- MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT23 | MCF5235_INTC0_IMRL_MASKALL);
- MCF5235_INTC0_ICR27 = MCF5235_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5235_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY);
- MCF5235_INTC0_IMRL &= ~(MCF5235_INTC0_IMRL_INT27 | MCF5235_INTC0_IMRL_MASKALL);
-}
-
-/*
- * Get the MAC address from the hardware.
- */
-static void
-fec_get_mac_address(volatile struct mcf5235_enet_struct *sc, unsigned char* hwaddr)
-{
- unsigned long addr;
-
- addr = MCF5235_FEC_PALR;
-
- hwaddr[0] = (addr >> 24) & 0xff;
- hwaddr[1] = (addr >> 16) & 0xff;
- hwaddr[2] = (addr >> 8) & 0xff;
- hwaddr[3] = (addr >> 0) & 0xff;
-
- addr = MCF5235_FEC_PAUR;
-
- hwaddr[4] = (addr >> 24) & 0xff;
- hwaddr[5] = (addr >> 16) & 0xff;
-}
-
-
-/*
- * Soak up buffer descriptors that have been sent.
- */
-static void
-fec_retire_tx_bd(volatile struct mcf5235_enet_struct *sc )
-{
- struct mbuf *m, *n;
-
- while ((sc->txBdActiveCount != 0)
- && ((sc->txBdBase[sc->txBdTail].status & MCF5235_FEC_TxBD_R) == 0)) {
- m = sc->txMbuf[sc->txBdTail];
- MFREE(m, n);
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- sc->txBdActiveCount--;
- }
-}
-
-static void
-fec_rxDaemon (void *arg)
-{
- volatile struct mcf5235_enet_struct *sc = (volatile struct mcf5235_enet_struct *)arg;
- struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
- struct mbuf *m;
- volatile uint16_t status;
- volatile mcf5235BufferDescriptor_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0 ; ;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR(m, M_WAIT, MT_DATA);
- MCLGET(m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod(m, void *);
- rxBd->status = MCF5235_FEC_RxBD_E;
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= MCF5235_FEC_RxBD_W;
- break;
- }
- }
-
- /*
- * Input packet handling loop
- */
- /* Indicate we have some ready buffers available */
- MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE;
-
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & MCF5235_FEC_RxBD_E) {
- /*
- * Clear old events.
- */
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_RXF;
-
- /*
- * Wait for packet to arrive.
- * Check the buffer descriptor before waiting for the event.
- * This catches the case when a packet arrives between the
- * `if' above, and the clearing of the RXF bit in the EIR.
- */
- while ((status = rxBd->status) & MCF5235_FEC_RxBD_E) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_RXF;
- rtems_interrupt_enable(level);
- rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- }
-
- /*
- * Check that packet is valid
- */
- if (status & MCF5235_FEC_RxBD_L) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
- int len = rxBd->length - sizeof(uint32_t);
-
- /*
- * Invalidate the cache and push the packet up.
- * The cache is so small that it's more efficient to just
- * invalidate the whole thing unless the packet is very small.
- */
- m = sc->rxMbuf[rxBdIndex];
- if (len < 128)
- rtems_cache_invalidate_multiple_data_lines(m->m_data, len);
- else
- rtems_cache_invalidate_entire_data();
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input(ifp, eh, 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 *);
- }
-
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & MCF5235_FEC_RxBD_W) | MCF5235_FEC_RxBD_E;
- MCF5235_FEC_RDAR = MCF5235_FEC_RDAR_R_DES_ACTIVE;
-
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount)
- rxBdIndex = 0;
- }
-}
-
-static void
-fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
-{
- struct mcf5235_enet_struct *sc = ifp->if_softc;
- volatile mcf5235BufferDescriptor_t *firstTxBd, *txBd;
- uint16_t status;
- int nAdded;
-
- /*
- * Free up buffer descriptors
- */
- fec_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;
- firstTxBd = sc->txBdBase + sc->txBdHead;
-
- for (;;) {
- /*
- * Wait for buffer descriptor to become available
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events.
- */
- MCF5235_FEC_EIR = MCF5235_FEC_EIR_TXF;
-
- /*
- * Wait for buffer descriptor to become available.
- * Check for buffer descriptors before waiting for the event.
- * This catches the case when a buffer became available between
- * the `if' above, and the clearing of the TXF bit in the EIR.
- */
- fec_retire_tx_bd(sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5235_FEC_EIMR |= MCF5235_FEC_EIMR_TXF;
- rtems_interrupt_enable(level);
- sc->txRawWait++;
- rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- fec_retire_tx_bd(sc);
- }
- }
-
- /*
- * Don't set the READY flag on the first fragment
- * until the whole packet has been readied.
- */
- status = nAdded ? MCF5235_FEC_TxBD_R : 0;
-
- /*
- * The IP fragmentation routine in ip_output
- * can produce fragments with zero length.
- */
- txBd = sc->txBdBase + sc->txBdHead;
- if (m->m_len) {
- char *p = mtod(m, char *);
- /*
- * Stupid FEC can't handle misaligned data!
- * Given the way that mbuf's are layed out it should be
- * safe to shuffle the data down like this.....
- * Perhaps this code could be improved with a "Duff's Device".
- */
- if ((int)p & 0x3) {
- int l = m->m_len;
- char *dest = p - ((int)p & 0x3);
- uint16_t *o = (uint16_t *)dest, *i = (uint16_t *)p;
- while (l > 0) {
- *o++ = *i++;
- l -= sizeof(uint16_t);
- }
- p = dest;
- sc->txRealign++;
- }
- txBd->buffer = p;
- txBd->length = m->m_len;
- sc->txMbuf[sc->txBdHead] = m;
- nAdded++;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= MCF5235_FEC_TxBD_W;
- sc->txBdHead = 0;
- }
- m = m->m_next;
- }
- else {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
- MFREE(m, n);
- m = n;
- }
- if (m == NULL) {
- if (nAdded) {
- txBd->status = status | MCF5235_FEC_TxBD_R
- | MCF5235_FEC_TxBD_L
- | MCF5235_FEC_TxBD_TC;
- if (nAdded > 1)
- firstTxBd->status |= MCF5235_FEC_TxBD_R;
- MCF5235_FEC_TDAR = MCF5235_FEC_TDAR_X_DES_ACTIVE;
- sc->txBdActiveCount += nAdded;
- }
- break;
- }
- txBd->status = status;
- }
-}
-
-void
-fec_txDaemon(void *arg)
-{
- struct mcf5235_enet_struct *sc = (struct mcf5235_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;
- }
-}
-
-
-/*
- * Send packet (caller provides header).
- */
-static void
-mcf5235_enet_start(struct ifnet *ifp)
-{
- struct mcf5235_enet_struct *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-static void
-fec_init(void *arg)
-{
- struct mcf5235_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
- /*
- * Set up hardware
- */
- mcf5235_fec_initialize_hardware(sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc);
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- MCF5235_FEC_RCR |= MCF5235_FEC_RCR_PROM;
- else
- MCF5235_FEC_RCR &= ~MCF5235_FEC_RCR_PROM;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- MCF5235_FEC_ECR = MCF5235_FEC_ECR_ETHER_EN;
-}
-
-
-static void
-fec_stop(struct mcf5235_enet_struct *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- MCF5235_FEC_ECR = 0x0;
-}
-
-/*
- * Show interface statistics
- */
-static void
-enet_stats(struct mcf5235_enet_struct *sc)
-{
- printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
- printf("Rx Packet Count:%-10lu", MCF5235_FEC_RMON_R_PACKETS);
- printf(" Rx Broadcast:%-10lu\n", MCF5235_FEC_RMON_R_BC_PKT);
- printf(" Rx Multicast:%-10lu", MCF5235_FEC_RMON_R_MC_PKT);
- printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_R_CRC_ALIGN);
- printf(" Rx Undersize:%-10lu\n", MCF5235_FEC_RMON_R_UNDERSIZE);
- printf(" Rx Oversize:%-10lu", MCF5235_FEC_RMON_R_OVERSIZE);
- printf(" Rx Fragment:%-10lu", MCF5235_FEC_RMON_R_FRAG);
- printf(" Rx Jabber:%-10lu\n", MCF5235_FEC_RMON_R_JAB);
- printf(" Rx 64:%-10lu", MCF5235_FEC_RMON_R_P64);
- printf(" Rx 65-127:%-10lu", MCF5235_FEC_RMON_R_P65T0127);
- printf(" Rx 128-255:%-10lu\n", MCF5235_FEC_RMON_R_P128TO255);
- printf(" Rx 256-511:%-10lu", MCF5235_FEC_RMON_R_P256TO511);
- printf(" Rx 511-1023:%-10lu", MCF5235_FEC_RMON_R_P512TO1023);
- printf(" Rx 1024-2047:%-10lu\n", MCF5235_FEC_RMON_R_P1024TO2047);
- printf(" Rx >=2048:%-10lu", MCF5235_FEC_RMON_R_GTE2048);
- printf(" Rx Octets:%-10lu", MCF5235_FEC_RMON_R_OCTETS);
- printf(" Rx Dropped:%-10lu\n", MCF5235_FEC_IEEE_R_DROP);
- printf(" Rx frame OK:%-10lu", MCF5235_FEC_IEEE_R_FRAME_OK);
- printf(" Rx CRC error:%-10lu", MCF5235_FEC_IEEE_R_CRC);
- printf(" Rx Align error:%-10lu\n", MCF5235_FEC_IEEE_R_ALIGN);
- printf(" FIFO Overflow:%-10lu", MCF5235_FEC_IEEE_R_MACERR);
- printf("Rx Pause Frames:%-10lu", MCF5235_FEC_IEEE_R_FDXFC);
- printf(" Rx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_R_OCTETS_OK);
- printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
- printf("Tx Output Waits:%-10lu", sc->txRawWait);
- printf("Tx Realignments:%-10lu\n", sc->txRealign);
- printf(" Tx Unaccounted:%-10lu", MCF5235_FEC_RMON_T_DROP);
- printf("Tx Packet Count:%-10lu", MCF5235_FEC_RMON_T_PACKETS);
- printf(" Tx Broadcast:%-10lu\n", MCF5235_FEC_RMON_T_BC_PKT);
- printf(" Tx Multicast:%-10lu", MCF5235_FEC_RMON_T_MC_PKT);
- printf("CRC/Align error:%-10lu", MCF5235_FEC_RMON_T_CRC_ALIGN);
- printf(" Tx Undersize:%-10lu\n", MCF5235_FEC_RMON_T_UNDERSIZE);
- printf(" Tx Oversize:%-10lu", MCF5235_FEC_RMON_T_OVERSIZE);
- printf(" Tx Fragment:%-10lu", MCF5235_FEC_RMON_T_FRAG);
- printf(" Tx Jabber:%-10lu\n", MCF5235_FEC_RMON_T_JAB);
- printf(" Tx Collisions:%-10lu", MCF5235_FEC_RMON_T_COL);
- printf(" Tx 64:%-10lu", MCF5235_FEC_RMON_T_P64);
- printf(" Tx 65-127:%-10lu\n", MCF5235_FEC_RMON_T_P65TO127);
- printf(" Tx 128-255:%-10lu", MCF5235_FEC_RMON_T_P128TO255);
- printf(" Tx 256-511:%-10lu", MCF5235_FEC_RMON_T_P256TO511);
- printf(" Tx 511-1023:%-10lu\n", MCF5235_FEC_RMON_T_P512TO1023);
- printf(" Tx 1024-2047:%-10lu", MCF5235_FEC_RMON_T_P1024TO2047);
- printf(" Tx >=2048:%-10lu", MCF5235_FEC_RMON_T_P_GTE2048);
- printf(" Tx Octets:%-10lu\n", MCF5235_FEC_RMON_T_OCTETS);
- printf(" Tx Dropped:%-10lu", MCF5235_FEC_IEEE_T_DROP);
- printf(" Tx Frame OK:%-10lu", MCF5235_FEC_IEEE_T_FRAME_OK);
- printf(" Tx 1 Collision:%-10lu\n", MCF5235_FEC_IEEE_T_1COL);
- printf("Tx >1 Collision:%-10lu", MCF5235_FEC_IEEE_T_MCOL);
- printf(" Tx Deferred:%-10lu", MCF5235_FEC_IEEE_T_DEF);
- printf(" Late Collision:%-10lu\n", MCF5235_FEC_IEEE_T_LCOL);
- printf(" Excessive Coll:%-10lu", MCF5235_FEC_IEEE_T_EXCOL);
- printf(" FIFO Underrun:%-10lu", MCF5235_FEC_IEEE_T_MACERR);
- printf(" Carrier Error:%-10lu\n", MCF5235_FEC_IEEE_T_CSERR);
- printf(" Tx SQE Error:%-10lu", MCF5235_FEC_IEEE_T_SQE);
- printf("Tx Pause Frames:%-10lu", MCF5235_FEC_IEEE_T_FDXFC);
- printf(" Tx Octets OK:%-10lu\n", MCF5235_FEC_IEEE_T_OCTETS_OK);
-}
-
-static int
-fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct mcf5235_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;
-}
-
-int
-rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching )
-{
- struct mcf5235_enet_struct *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
- unsigned char *hwaddr;
-
- /*
- * Parse driver name
- */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber < 0) || (unitNumber >= NIFACES)) {
- printf("mcf5235: bad FEC unit number.\n");
- return 0;
- }
- sc = &enet_driver[unitNumber];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printf("mcf5235: 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
- fec_get_mac_address(sc, sc->arpcom.ac_enaddr);
-
- hwaddr = config->hardware_address;
- printf("%s%d: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
- unitName, unitNumber,
- hwaddr[0], hwaddr[1], hwaddr[2],
- hwaddr[3], hwaddr[4], hwaddr[5]);
-
- 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 = mcf5235_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;
-};
-
diff --git a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am
index 7dd2265c7f..f269f930e3 100644
--- a/c/src/lib/libbsp/m68k/mcf5329/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mcf5329/Makefile.am
@@ -36,7 +36,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5329/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5329/btimer/btimer.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mcf5329/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf532x.c
diff --git a/c/src/lib/libbsp/m68k/mcf5329/network/network.c b/c/src/lib/libbsp/m68k/mcf5329/network/network.c
deleted file mode 100644
index c752f8d669..0000000000
--- a/c/src/lib/libbsp/m68k/mcf5329/network/network.c
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * RTEMS/TCPIP driver for MCF5329 Fast Ethernet Controller
- *
- * TO DO: Check network stack code -- force longword alignment of all tx mbufs?
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 1
-
-#define FEC_INTC0_TX_VECTOR (64+36)
-#define FEC_INTC0_RX_VECTOR (64+40)
-
-/*
- * 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 three or more buffer descriptors.
- */
-#define RX_BUF_COUNT 32
-#define TX_BUF_COUNT 20
-#define TX_BD_PER_BUF 3
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP task synchronization.
- */
-#define TX_INTERRUPT_EVENT RTEMS_EVENT_1
-#define RX_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 plus CRC (1518).
- * Round off to nearest multiple of RBUF_ALIGN.
- */
-#define MAX_MTU_SIZE 1518
-#define RBUF_ALIGN 4
-#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-typedef struct mcf5329BufferDescriptor_
-{
- volatile uint16_t status;
- uint16_t length;
- volatile void *buffer;
-} mcf5329BufferDescriptor_t;
-
-/*
- * Per-device data
- */
-struct mcf5329_enet_struct
-{
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- mcf5329BufferDescriptor_t *rxBdBase;
- mcf5329BufferDescriptor_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long txInterrupts;
- unsigned long txRawWait;
- unsigned long txRealign;
-};
-static struct mcf5329_enet_struct enet_driver[NIFACES];
-
-static rtems_isr mcf5329_fec_rx_interrupt_handler(rtems_vector_number v)
-{
- MCF_FEC_EIR = MCF_FEC_EIR_RXF;
- MCF_FEC_EIMR &= ~MCF_FEC_EIMR_RXF;
- enet_driver[0].rxInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
-}
-
-static rtems_isr mcf5329_fec_tx_interrupt_handler(rtems_vector_number v)
-{
- MCF_FEC_EIR = MCF_FEC_EIR_TXF;
- MCF_FEC_EIMR &= ~MCF_FEC_EIMR_TXF;
- enet_driver[0].txInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
-}
-
-extern char _CoreSRamBase[];
-
-/*
- * Allocate buffer descriptors from (non-cached) on-chip static RAM
- * Ensure 128-bit (16-byte) alignment
- */
-static mcf5329BufferDescriptor_t *mcf5329_bd_allocate(unsigned int count)
-{
- static mcf5329BufferDescriptor_t *bdp =
- (mcf5329BufferDescriptor_t *) _CoreSRamBase;
- mcf5329BufferDescriptor_t *p = bdp;
-
- bdp += count;
- if ((int) bdp & 0xF)
- bdp =
- (mcf5329BufferDescriptor_t *) ((char *) bdp + (16 - ((int) bdp & 0xF)));
- return p;
-}
-
-#if UNUSED
-
-/*
- * Read MII register
- * Busy-waits, but transfer time should be short!
- */
-static int getMII(int phyNumber, int regNumber)
-{
- MCF_FEC_MMFR = (0x1 << 30) |
- (0x2 << 28) | (phyNumber << 23) | (regNumber << 18) | (0x2 << 16);
- while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) ;
- MCF_FEC_EIR = MCF_FEC_EIR_MII;
- return MCF_FEC_MMFR & 0xFFFF;
-}
-#endif
-
-/*
- * Write MII register
- * Busy-waits, but transfer time should be short!
- */
-static void setMII(int phyNumber, int regNumber, int value)
-{
- MCF_FEC_MMFR = (0x1 << 30) |
- (0x1 << 28) |
- (phyNumber << 23) | (regNumber << 18) | (0x2 << 16) | (value & 0xFFFF);
- while ((MCF_FEC_EIR & MCF_FEC_EIR_MII) == 0) ;
- MCF_FEC_EIR = MCF_FEC_EIR_MII;
-}
-
-static void mcf5329_fec_initialize_hardware(struct mcf5329_enet_struct *sc)
-{
- int i;
- const unsigned char *hwaddr = 0;
- rtems_status_code status;
- rtems_isr_entry old_handler;
- uint32_t clock_speed = bsp_get_BUS_clock_speed();
-
- /*
- * Issue reset to FEC
- */
- MCF_FEC_ECR = MCF_FEC_ECR_RESET;
- rtems_task_wake_after(1);
- MCF_FEC_ECR = 0;
-
- /*
- * Configuration of I/O ports is done outside of this function
- */
-#if 0
- imm->gpio.pbcnt |= MCF_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
-#endif
-
- /*
- * Set our physical address
- */
- hwaddr = sc->arpcom.ac_enaddr;
- MCF_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
- (hwaddr[2] << 8) | (hwaddr[3] << 0);
- MCF_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
-
- /*
- * Clear the hash table
- */
- MCF_FEC_GAUR = 0;
- MCF_FEC_GALR = 0;
-
- /*
- * Set up receive buffer size
- */
- MCF_FEC_EMRBR = 1520; /* Standard Ethernet */
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf)
- rtems_panic("No memory for mbuf pointers");
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = mcf5329_bd_allocate(sc->rxBdCount);
- sc->txBdBase = mcf5329_bd_allocate(sc->txBdCount);
- MCF_FEC_ERDSR = (int) sc->rxBdBase;
- MCF_FEC_ETDSR = (int) sc->txBdBase;
-
- /*
- * Set up Receive Control Register:
- * Not promiscuous
- * MII mode
- * Full duplex
- * No loopback
- */
- MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(MAX_MTU_SIZE) | MCF_FEC_RCR_MII_MODE;
-
- /*
- * Set up Transmit Control Register:
- * Full duplex
- * No heartbeat
- */
- MCF_FEC_TCR = MCF_FEC_TCR_FDEN;
-
- /*
- * Initialize statistic counters
- */
- MCF_FEC_MIBC = MCF_FEC_MIBC_MIB_DISABLE;
- {
- vuint32 *vuip = &MCF_FEC_RMON_T_DROP;
-
- while (vuip <= &MCF_FEC_IEEE_R_OCTETS_OK)
- *vuip++ = 0;
- }
- MCF_FEC_MIBC = 0;
-
- /*
- * Set MII speed to <= 2.5 MHz
- */
- i = (clock_speed + 5000000 - 1) / 5000000;
- MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED(i);
-
- /*
- * Set PHYS to 100 Mb/s, full duplex
- */
- setMII(1, 0, 0x2100);
-
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0; i < sc->rxBdCount; i++)
- (sc->rxBdBase + i)->status = 0;
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0; i < sc->txBdCount; i++) {
- sc->txBdBase[i].status = 0;
- sc->txMbuf[i] = NULL;
- }
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Set up interrupts
- */
- status =
- rtems_interrupt_catch(mcf5329_fec_tx_interrupt_handler,
- FEC_INTC0_TX_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic("Can't attach MCF FEC TX interrupt handler: %s\n",
- rtems_status_text(status));
- status =
- rtems_interrupt_catch(mcf5329_fec_rx_interrupt_handler,
- FEC_INTC0_RX_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic("Can't attach MCF FEC RX interrupt handler: %s\n",
- rtems_status_text(status));
- MCF_INTC0_ICR36 = MCF_INTC_ICR_IL(FEC_IRQ_LEVEL);
- MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36);
- MCF_INTC0_ICR40 = MCF_INTC_ICR_IL(FEC_IRQ_LEVEL);
- MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK40);
-}
-
-/*
- * Get the MAC address from the hardware.
- */
-static void
-fec_get_mac_address(volatile struct mcf5329_enet_struct *sc,
- unsigned char *hwaddr)
-{
- unsigned long addr;
-
- addr = MCF_FEC_PALR;
-
- hwaddr[0] = (addr >> 24) & 0xff;
- hwaddr[1] = (addr >> 16) & 0xff;
- hwaddr[2] = (addr >> 8) & 0xff;
- hwaddr[3] = (addr >> 0) & 0xff;
-
- addr = MCF_FEC_PAUR;
-
- hwaddr[4] = (addr >> 24) & 0xff;
- hwaddr[5] = (addr >> 16) & 0xff;
-}
-
-/*
- * Soak up buffer descriptors that have been sent.
- */
-static void fec_retire_tx_bd(volatile struct mcf5329_enet_struct *sc)
-{
- struct mbuf *m, *n;
-
- while ((sc->txBdActiveCount != 0)
- && ((sc->txBdBase[sc->txBdTail].status & MCF_FEC_TxBD_R) == 0)) {
- m = sc->txMbuf[sc->txBdTail];
- MFREE(m, n);
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- sc->txBdActiveCount--;
- }
-}
-
-static void fec_rxDaemon(void *arg)
-{
- volatile struct mcf5329_enet_struct *sc =
- (volatile struct mcf5329_enet_struct *) arg;
- struct ifnet *ifp = (struct ifnet *) &sc->arpcom.ac_if;
- struct mbuf *m;
- volatile uint16_t status;
- volatile mcf5329BufferDescriptor_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR(m, M_WAIT, MT_DATA);
- MCLGET(m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod(m, void *);
-
- rxBd->status = MCF_FEC_RxBD_E;
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= MCF_FEC_RxBD_W;
- break;
- }
- }
-
- /*
- * Input packet handling loop
- */
- /* Indicate we have some ready buffers available */
- MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
-
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & MCF_FEC_RxBD_E) {
- /*
- * Clear old events.
- */
- MCF_FEC_EIR = MCF_FEC_EIR_RXF;
-
- /*
- * Wait for packet to arrive.
- * Check the buffer descriptor before waiting for the event.
- * This catches the case when a packet arrives between the
- * `if' above, and the clearing of the RXF bit in the EIR.
- */
- while ((status = rxBd->status) & MCF_FEC_RxBD_E) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF_FEC_EIMR |= MCF_FEC_EIMR_RXF;
- rtems_interrupt_enable(level);
- rtems_bsdnet_event_receive(RX_INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
- }
- }
-
- /*
- * Check that packet is valid
- */
- if (status & MCF_FEC_RxBD_L) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
- int len = rxBd->length - sizeof(uint32_t);
-
- m = sc->rxMbuf[rxBdIndex];
-
- rtems_cache_invalidate_multiple_data_lines(m->m_data, len);
-
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input(ifp, eh, 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 *);
- }
-
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & MCF_FEC_RxBD_W) | MCF_FEC_RxBD_E;
- MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
-
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount)
- rxBdIndex = 0;
- }
-}
-
-static void fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
-{
- struct mcf5329_enet_struct *sc = ifp->if_softc;
- volatile mcf5329BufferDescriptor_t *firstTxBd, *txBd;
- uint16_t status;
- int nAdded;
-
- /*
- * Free up buffer descriptors
- */
- fec_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;
- firstTxBd = sc->txBdBase + sc->txBdHead;
-
- for (;;) {
- /*
- * Wait for buffer descriptor to become available
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events.
- */
- MCF_FEC_EIR = MCF_FEC_EIR_TXF;
-
- /*
- * Wait for buffer descriptor to become available.
- * Check for buffer descriptors before waiting for the event.
- * This catches the case when a buffer became available between
- * the `if' above, and the clearing of the TXF bit in the EIR.
- */
- fec_retire_tx_bd(sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF_FEC_EIMR |= MCF_FEC_EIMR_TXF;
- rtems_interrupt_enable(level);
- sc->txRawWait++;
- rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
- fec_retire_tx_bd(sc);
- }
- }
-
- /*
- * Don't set the READY flag on the first fragment
- * until the whole packet has been readied.
- */
- status = nAdded ? MCF_FEC_TxBD_R : 0;
-
- /*
- * The IP fragmentation routine in ip_output
- * can produce fragments with zero length.
- */
- txBd = sc->txBdBase + sc->txBdHead;
- if (m->m_len) {
- char *p = mtod(m, char *);
-
- /*
- * Stupid FEC can't handle misaligned data!
- * Given the way that mbuf's are layed out it should be
- * safe to shuffle the data down like this.....
- * Perhaps this code could be improved with a "Duff's Device".
- */
- if ((int) p & 0x3) {
- int l = m->m_len;
- char *dest = p - ((int) p & 0x3);
- uint16_t *o = (uint16_t *) dest, *i = (uint16_t *) p;
-
- while (l > 0) {
- *o++ = *i++;
- l -= sizeof(uint16_t);
- }
- p = dest;
- sc->txRealign++;
- }
-
- txBd->buffer = p;
- txBd->length = m->m_len;
-
- rtems_cache_flush_multiple_data_lines(txBd->buffer, txBd->length);
-
- sc->txMbuf[sc->txBdHead] = m;
- nAdded++;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= MCF_FEC_TxBD_W;
- sc->txBdHead = 0;
- }
- m = m->m_next;
- } else {
- /*
- * Just toss empty mbufs
- */
- struct mbuf *n;
-
- MFREE(m, n);
- m = n;
- }
- if (m == NULL) {
- if (nAdded) {
- txBd->status = status | MCF_FEC_TxBD_R
- | MCF_FEC_TxBD_L | MCF_FEC_TxBD_TC;
- if (nAdded > 1)
- firstTxBd->status |= MCF_FEC_TxBD_R;
- MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
- sc->txBdActiveCount += nAdded;
- }
- break;
- }
- txBd->status = status;
- }
-}
-
-void fec_txDaemon(void *arg)
-{
- struct mcf5329_enet_struct *sc = (struct mcf5329_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;
- }
-}
-
-/*
- * Send packet (caller provides header).
- */
-static void mcf5329_enet_start(struct ifnet *ifp)
-{
- struct mcf5329_enet_struct *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-static void fec_init(void *arg)
-{
- struct mcf5329_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
- /*
- * Set up hardware
- */
- mcf5329_fec_initialize_hardware(sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc);
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- MCF_FEC_RCR |= MCF_FEC_RCR_PROM;
- else
- MCF_FEC_RCR &= ~MCF_FEC_RCR_PROM;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- MCF_FEC_ECR = MCF_FEC_ECR_ETHER_EN;
-}
-
-static void fec_stop(struct mcf5329_enet_struct *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- MCF_FEC_ECR = 0x0;
-}
-
-/*
- * Show interface statistics
- */
-static void enet_stats(struct mcf5329_enet_struct *sc)
-{
- printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
- printf("Rx Packet Count:%-10lu", MCF_FEC_RMON_R_PACKETS);
- printf(" Rx Broadcast:%-10lu\n", MCF_FEC_RMON_R_BC_PKT);
- printf(" Rx Multicast:%-10lu", MCF_FEC_RMON_R_MC_PKT);
- printf("CRC/Align error:%-10lu", MCF_FEC_RMON_R_CRC_ALIGN);
- printf(" Rx Undersize:%-10lu\n", MCF_FEC_RMON_R_UNDERSIZE);
- printf(" Rx Oversize:%-10lu", MCF_FEC_RMON_R_OVERSIZE);
- printf(" Rx Fragment:%-10lu", MCF_FEC_RMON_R_FRAG);
- printf(" Rx Jabber:%-10lu\n", MCF_FEC_RMON_R_JAB);
- printf(" Rx 64:%-10lu", MCF_FEC_RMON_R_P64);
- printf(" Rx 65-127:%-10lu", MCF_FEC_RMON_R_P65TO127);
- printf(" Rx 128-255:%-10lu\n", MCF_FEC_RMON_R_P128TO255);
- printf(" Rx 256-511:%-10lu", MCF_FEC_RMON_R_P256TO511);
- printf(" Rx 511-1023:%-10lu", MCF_FEC_RMON_R_512TO1023);
- printf(" Rx 1024-2047:%-10lu\n", MCF_FEC_RMON_R_1024TO2047);
- printf(" Rx >=2048:%-10lu", MCF_FEC_RMON_R_P_GTE2048);
- printf(" Rx Octets:%-10lu", MCF_FEC_RMON_R_OCTETS);
- printf(" Rx Dropped:%-10lu\n", MCF_FEC_IEEE_R_DROP);
- printf(" Rx frame OK:%-10lu", MCF_FEC_IEEE_R_FRAME_OK);
- printf(" Rx CRC error:%-10lu", MCF_FEC_IEEE_R_CRC);
- printf(" Rx Align error:%-10lu\n", MCF_FEC_IEEE_R_ALIGN);
- printf(" FIFO Overflow:%-10lu", MCF_FEC_IEEE_R_MACERR);
- printf("Rx Pause Frames:%-10lu", MCF_FEC_IEEE_R_FDXFC);
- printf(" Rx Octets OK:%-10lu\n", MCF_FEC_IEEE_R_OCTETS_OK);
- printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
- printf("Tx Output Waits:%-10lu", sc->txRawWait);
- printf("Tx Realignments:%-10lu\n", sc->txRealign);
- printf(" Tx Unaccounted:%-10lu", MCF_FEC_RMON_T_DROP);
- printf("Tx Packet Count:%-10lu", MCF_FEC_RMON_T_PACKETS);
- printf(" Tx Broadcast:%-10lu\n", MCF_FEC_RMON_T_BC_PKT);
- printf(" Tx Multicast:%-10lu", MCF_FEC_RMON_T_MC_PKT);
- printf("CRC/Align error:%-10lu", MCF_FEC_RMON_T_CRC_ALIGN);
- printf(" Tx Undersize:%-10lu\n", MCF_FEC_RMON_T_UNDERSIZE);
- printf(" Tx Oversize:%-10lu", MCF_FEC_RMON_T_OVERSIZE);
- printf(" Tx Fragment:%-10lu", MCF_FEC_RMON_T_FRAG);
- printf(" Tx Jabber:%-10lu\n", MCF_FEC_RMON_T_JAB);
- printf(" Tx Collisions:%-10lu", MCF_FEC_RMON_T_COL);
- printf(" Tx 64:%-10lu", MCF_FEC_RMON_T_P64);
- printf(" Tx 65-127:%-10lu\n", MCF_FEC_RMON_T_P65TO127);
- printf(" Tx 128-255:%-10lu", MCF_FEC_RMON_T_P128TO255);
- printf(" Tx 256-511:%-10lu", MCF_FEC_RMON_T_P256TO511);
- printf(" Tx 511-1023:%-10lu\n", MCF_FEC_RMON_T_P512TO1023);
- printf(" Tx 1024-2047:%-10lu", MCF_FEC_RMON_T_P1024TO2047);
- printf(" Tx >=2048:%-10lu", MCF_FEC_RMON_T_P_GTE2048);
- printf(" Tx Octets:%-10lu\n", MCF_FEC_RMON_T_OCTETS);
- printf(" Tx Dropped:%-10lu", MCF_FEC_IEEE_T_DROP);
- printf(" Tx Frame OK:%-10lu", MCF_FEC_IEEE_T_FRAME_OK);
- printf(" Tx 1 Collision:%-10lu\n", MCF_FEC_IEEE_T_1COL);
- printf("Tx >1 Collision:%-10lu", MCF_FEC_IEEE_T_MCOL);
- printf(" Tx Deferred:%-10lu", MCF_FEC_IEEE_T_DEF);
- printf(" Late Collision:%-10lu\n", MCF_FEC_IEEE_T_LCOL);
- printf(" Excessive Coll:%-10lu", MCF_FEC_IEEE_T_EXCOL);
- printf(" FIFO Underrun:%-10lu", MCF_FEC_IEEE_T_MACERR);
- printf(" Carrier Error:%-10lu\n", MCF_FEC_IEEE_T_CSERR);
- printf(" Tx SQE Error:%-10lu", MCF_FEC_IEEE_T_SQE);
- printf("Tx Pause Frames:%-10lu", MCF_FEC_IEEE_T_FDXFC);
- printf(" Tx Octets OK:%-10lu\n", MCF_FEC_IEEE_T_OCTETS_OK);
-}
-
-static int fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct mcf5329_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;
-}
-
-int
-rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- struct mcf5329_enet_struct *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
- unsigned char *hwaddr;
-
- /*
- * Parse driver name
- */
- if ((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber < 0) || (unitNumber >= NIFACES)) {
- printf("mcf5329: bad FEC unit number.\n");
- return 0;
- }
- sc = &enet_driver[unitNumber];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printf("mcf5329: 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
- fec_get_mac_address(sc, sc->arpcom.ac_enaddr);
-
- hwaddr = config->hardware_address;
- printf("%s%d: mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
- unitName, unitNumber,
- hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-
- 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 = mcf5329_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;
-};
diff --git a/c/src/lib/libbsp/m68k/mvme162/Makefile.am b/c/src/lib/libbsp/m68k/mvme162/Makefile.am
index 3847969efc..cfc146678a 100644
--- a/c/src/lib/libbsp/m68k/mvme162/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mvme162/Makefile.am
@@ -39,7 +39,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme162/btimer/timerisr.S
librtemsbsp_a_SOURCES += tod/tod.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += ../mvme167/network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache.c
diff --git a/c/src/lib/libbsp/m68k/mvme167/Makefile.am b/c/src/lib/libbsp/m68k/mvme167/Makefile.am
index 665b65fcea..01899a9076 100644
--- a/c/src/lib/libbsp/m68k/mvme167/Makefile.am
+++ b/c/src/lib/libbsp/m68k/mvme167/Makefile.am
@@ -35,7 +35,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/btimer/btimer.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/btimer/timerisr.S
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache.c
diff --git a/c/src/lib/libbsp/m68k/mvme167/network/network.c b/c/src/lib/libbsp/m68k/mvme167/network/network.c
deleted file mode 100644
index 06bcbfa84a..0000000000
--- a/c/src/lib/libbsp/m68k/mvme167/network/network.c
+++ /dev/null
@@ -1,3099 +0,0 @@
-/* network.c: An 82596 ethernet driver for rtems-bsd.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-#define KERNEL
-
-/*
- * Selectively define to debug the network driver. If you define any of these
- * you must run with polled console I/O.
- */
-
-/*
-#define DBG_ADD_CMD
-#define DBG_WAIT
-#define DBG_SEND
-#define DBG_MEM
-#define DBG_SELFTEST_CMD
-#define DBG_DUMP_CMD
-#define DBG_RESET
-#define DBG_ATTACH
-#define DBG_START
-#define DBG_INIT
-#define DBG_STOP
-#define DBG_RX
-#define DBG_ISR
-#define DBG_IOCTL
-#define DBG_STAT
-#define DBG_PACKETS
-*/
-
-#define IGNORE_SPURIOUS_IRQ
-#define IGNORE_NO_RFA
-#define IGNORE_MULTIPLE_RF
-
-/*
- * Default number of buffer descriptors and buffer sizes.
- */
-#define RX_BUF_COUNT 15
-#define TX_BUF_COUNT 4
-#define TX_BD_PER_BUF 4
-
-#define RBUF_SIZE 1520
-
-#define UTI_596_ETH_MIN_SIZE 60
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-/*
- * RTEMS events
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-#define NIC_RESET_EVENT RTEMS_EVENT_3
-
-#include <bsp.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <rtems/error.h>
-#include <rtems/bspIo.h>
-#include <rtems/rtems_bsdnet.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/types.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include "uti596.h"
-
-/* If we are running interrupt driven I/O no debug output is printed */
-#if CD2401_IO_MODE == 0
- #define printk(arglist) do { printk arglist; printk("\r"); } while (0);
-#else
- #define printk(arglist)
-#endif
-
-#define UTI_596_ASSERT( condition, str ) if (!( condition ) ) { printk((str)) }
-
-/* Types of PORT commands */
-#define UTI596_RESET_PORT_FUNCTION 0
-#define UTI596_SELFTEST_PORT_FUNCTION 1
-#define UTI596_SCP_PORT_FUNCTION 2
-#define UTI596_DUMP_PORT_FUNCTION 3
-
-/* Types of waiting for commands */
-#define UTI596_NO_WAIT 0
-#define UTI596_WAIT_FOR_CU_ACCEPT 1
-#define UTI596_WAIT_FOR_INITIALIZATION 2
-#define UTI596_WAIT_FOR_STAT_C 3
-
-/* Device dependent data structure */
-static uti596_softc_ uti596_softc;
-
-/* Globals */
-int count_rx = 0;
-static int scbStatus;
-static rtems_status_code sc;
-static i596_cmd *pIsrCmd;
-static i596_rfd *pIsrRfd;
-
-/*
- * Initial 596 configuration
- */
-char uti596initSetup[] = {
- 0x0E, /* Byte 0: length, prefetch off ( no RBD's ) */
- 0xC8, /* Byte 1: fifo to 8, monitor off */
- 0x40, /* Byte 2: don't save bad frames ( was save= 80, use intel's 40 )*/
- 0x2E, /* Byte 3: No source address insertion, 8 byte preamble */
- 0x00, /* Byte 4: priority and backoff defaults */
- 0x60, /* Byte 5: interframe spacing */
- 0x00, /* Byte 6: slot time LSB */
- 0xf2, /* Byte 7: slot time and retries */
- 0x0C, /* Byte 8: not promisc, enable bcast, tx no crs, crc inserted 32bit, 802.3 framing */
- 0x08, /* Byte 9: collision detect */
- 0x40, /* Byte 10: minimum frame length */
- 0xfb, /* Byte 11: tried C8 same as byte 1 in bits 6-7, else ignored*/
- 0x00, /* Byte 12: disable full duplex */
- 0x3f /* Byte 13: no multi IA, backoff enabled */
-};
-
-/* Local Routines */
-
-static unsigned long word_swap ( unsigned long );
-static void * malloc_16byte_aligned ( void **, void ** adjusted_pointer, size_t );
-RTEMS_INLINE_ROUTINE void uti596_writePortFunction ( volatile void *, unsigned long );
-/* currently unused by RTEMS */
-#if 0
-RTEMS_INLINE_ROUTINE void uti596_portReset( void );
-static unsigned long uti596_portSelfTest( i596_selftest * );
-static int uti596_portDump ( i596_dump_result * );
-static void uti596_CU_dump ( i596_dump_result * );
-#endif
-static int uti596_wait ( uti596_softc_ *, uint8_t);
-static int uti596_issueCA ( uti596_softc_ *, uint8_t);
-static void uti596_addCmd ( i596_cmd * );
-static void uti596_addPolledCmd ( i596_cmd * );
-static int uti596_setScpAndScb ( uti596_softc_ * );
-static int uti596_diagnose ( void );
-static int uti596_configure ( uti596_softc_ * );
-static int uti596_IAsetup ( uti596_softc_ * );
-static int uti596_initTBD ( uti596_softc_ * );
-static int uti596_initRFA ( int );
-static void uti596_initMem ( uti596_softc_ * );
-static void uti596_initialize ( uti596_softc_ * );
-static void uti596_initialize_hardware ( uti596_softc_ * );
-static void uti596_reset_hardware ( uti596_softc_ *);
-static void uti596_reset ( void );
-static void uti596_clearListStatus ( i596_rfd * );
-static i596_rfd * uti596_dequeue ( i596_rfd ** );
-static void uti596_append ( i596_rfd ** , i596_rfd * );
-static void uti596_supplyFD ( i596_rfd * );
-static void send_packet ( struct ifnet *, struct mbuf * );
-
-/* Required RTEMS network driver functions and tasks (plus reset daemon) */
-
-static void uti596_start ( struct ifnet * );
-void uti596_init ( void * );
-void uti596_stop ( uti596_softc_ * );
-void uti596_txDaemon ( void * );
-void uti596_rxDaemon ( void * );
-void uti596_resetDaemon( void * );
-rtems_isr uti596_DynamicInterruptHandler ( rtems_vector_number );
-static int uti596_ioctl ( struct ifnet *, u_long, caddr_t );
-void uti596_stats ( uti596_softc_ * );
-
-#ifdef DBG_PACKETS
-static void dumpQ( void );
-static void show_buffers( void );
-static void show_queues( void );
-static void print_eth ( unsigned char * );
-static void print_hdr ( unsigned char * );
-static void print_pkt ( unsigned char * );
-static void print_echo ( unsigned char * );
-#endif
-
-/*
- * word_swap
- *
- * Return a 32 bit value, swapping the upper and lower words first.
- *
- * Input parameters:
- * val - 32 bit value to swap
- *
- * Output parameters: NONE
- *
- * Return value:
- * Input value with upper and lower 16-bit words swapped
- */
-static unsigned long word_swap(
- unsigned long val
-)
-{
- return (((val >> 16)&(0x0000ffff)) | ((val << 16)&(0xffff0000)));
-}
-
-/*
- * malloc_16byte_aligned
- *
- * Allocate a block of a least nbytes aligned on a 16-byte boundary.
- * Clients are responsible to store both the real address and the adjusted
- * address. The real address must be used to free the block.
- *
- * Input parameters:
- * real_pointer - pointer to a void * pointer in which to store the starting
- * address of the block. Required for free.
- * adjusted_pointer - pointer to a void * pointer in which to store the
- * starting address of the block rounded up to the next
- * 16 byte boundary.
- * nbytes - number of bytes of storage requested
- *
- * Output parameters:
- * real_pointer - starting address of the block.
- * adjusted_pointer - starting address of the block rounded up to the next
- * 16 byte boundary.
- *
- * Return value:
- * starting address of the block rounded up to the next 16 byte boundary.
- * NULL if no storage was allocated.
- */
-static void * malloc_16byte_aligned(
- void ** real_pointer,
- void ** adjusted_pointer,
- size_t nbytes
-)
-{
- *real_pointer = malloc( nbytes + 0xF, 0, M_NOWAIT );
- *adjusted_pointer = (void *)(((unsigned long)*real_pointer + 0xF ) & 0xFFFFFFF0 );
- return *adjusted_pointer;
-}
-
-/*
- * uti596_scp_alloc
- *
- * Allocate a new scp, possibly freeing a previously allocated one.
- *
- * Input parameters:
- * sc - pointer to the global uti596_softc in which to store pointers
- * to the newly allocated block.
- *
- * Output parameters: NONE
- *
- * Return value:
- * Pointer to the newly allocated, 16-byte aligned scp.
- */
-static i596_scp * uti596_scp_alloc(
- uti596_softc_ * sc
-)
-{
- if( sc->base_scp != NULL ) {
- #ifdef DBG_MEM
- printk(("uti596_scp_alloc: Already have an SCP at %p\n", sc->base_scp))
- #endif
- return sc->pScp;
- }
-
- /* allocate enough memory for the Scp block to be aligned on 16 byte boundary */
- malloc_16byte_aligned( (void *)&(sc->base_scp), (void *)&(sc->pScp), sizeof( i596_scp ) );
-
- #ifdef DBG_MEM
- printk(("uti596_scp_alloc: Scp base address is %p\n", sc->base_scp))
- printk(("uti596_scp_alloc: Scp aligned address is : %p\n",sc->pScp))
- #endif
-
- return sc->pScp;
-}
-
-/*
- * uti596_writePortFunction
- *
- * Write the command into the PORT.
- *
- * Input parameters:
- * addr - 16-byte aligned address to write into the PORT.
- * cmd - 4-bit cmd to write into the PORT
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- *
- * The Motorola manual swapped the high and low registers.
- */
-RTEMS_INLINE_ROUTINE void uti596_writePortFunction(
- volatile void * addr,
- unsigned long cmd
-)
-{
- i82596->port_lower = (unsigned short)(((unsigned long)addr & 0xFFF0) | cmd);
- i82596->port_upper = (unsigned short)(((unsigned long)addr >> 16 ) & 0xFFFF);
-}
-
-/*
- * uti596_portReset
- *
- * Issue a port Reset to the uti596
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-RTEMS_INLINE_ROUTINE void uti596_portReset( void )
-{
- uti596_writePortFunction( NULL, UTI596_RESET_PORT_FUNCTION );
-}
-
-/* currently unused by RTEMS */
-#if 0
-/*
- * uti596_portSelfTest
- *
- * Perform a self-test. Wait for up to 1 second for the test to
- * complete. Normally, the test should complete in a very short time,
- * so busy waiting is not an issue.
- *
- * Input parameters:
- * stp - pointer to a 16-byte aligned uti596_selftest structure.
- *
- * Output parameters: NONE
- *
- * Return value:
- * 32-bit result field if successful, -1 otherwise.
- */
-static unsigned long uti596_portSelfTest(
- i596_selftest * stp
-)
-{
- rtems_interval ticks_per_second, start_ticks, end_ticks;
-
- stp->results = 0xFFFFFFFF;
- uti596_writePortFunction( stp, UTI596_SELFTEST_PORT_FUNCTION );
-
- ticks_per_second = rtems_clock_get_ticks_per_second();
-
- start_ticks = rtems_clock_get_ticks_since_boot();
- end_ticks = start_ticks + ticks_per_second;
-
- do {
- if( stp->results != 0xFFFFFFFF )
- break;
- else
- start_ticks = rtems_clock_get_ticks_since_boot();
- } while (start_ticks <= end_ticks);
-
- if (start_ticks > end_ticks ) {
- #ifdef DBG_SELFTEST_CMD
- printk(("uti596_selftest: Timed out\n" ))
- #endif
- return -1;
- }
- else {
- #ifdef DBG_SELFTEST_CMD
- printk(("uti596_selftest: Succeeded with signature = 0x%08x, result = 0x%08x\n",
- stp->signature,
- stp->results))
- #endif
- return stp->results;
- }
-}
-#endif
-
-/* currently unused by RTEMS */
-#if 0
-/*
- * uti596_portDump
- *
- * Perform a dump Wait for up to 1 second for the test to
- * complete. Normally, the test should complete in a very short time,
- * so busy waiting is not an issue.
- *
- * Input parameters:
- * dp - pointer to a 16-byte aligned uti596_dump structure.
- *
- * Output parameters: NONE
- *
- * Return value:
- * 16-bit dump_status field if successful, -1 otherwise.
- */
-static int uti596_portDump(
- i596_dump_result * dp
-)
-{
- rtems_interval ticks_per_second, start_ticks, end_ticks;
-
- dp->dump_status = 0;
- uti596_writePortFunction( dp, UTI596_DUMP_PORT_FUNCTION );
-
- ticks_per_second = rtems_clock_get_ticks_per_second();
- start_ticks = rtems_clock_get_ticks_since_boot();
- end_ticks = start_ticks + ticks_per_second;
-
- do {
- if( dp->dump_status != 0xA006 )
- break;
- else
- start_ticks = rtems_clock_get_ticks_since_boot();
- } while (start_ticks <= end_ticks);
-
- if (start_ticks > end_ticks ) {
- #ifdef DBG_DUMP_CMD
- printk(("uti596_dump: Timed out with dump at 0x%08x\n", (unsigned long)dp ))
- #endif
- return -1;
- }
- else {
- #ifdef DBG_DUMP_CMD
- printk(("uti596_dump: Succeeded with dump at = 0x%08x\n", (unsigned long)dp ))
- #endif
- return dp->dump_status;
- }
-}
-#endif
-
-/*
- * uti596_wait
- *
- * Wait for a certain condition.
- *
- * Input parameters:
- * sc - pointer to the uti596_softc struct
- * wait_type - UTI596_NO_WAIT
- * UTI596_WAIT
- * UTI596_WAIT_FOR_CU_ACCEPT
- * UTI596_WAIT_FOR_INITIALIZATION
- * UTI596_WAIT_FOR_STAT_C
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise.
- */
-static int uti596_wait(
- uti596_softc_ *sc,
- uint8_t waitType
-)
-{
- rtems_interval ticks_per_second, start_ticks, end_ticks;
-
- ticks_per_second = rtems_clock_get_ticks_per_second();
- start_ticks = rtems_clock_get_ticks_since_boot();
- end_ticks = start_ticks + ticks_per_second;
-
- switch( waitType ) {
-
- case UTI596_NO_WAIT:
- return 0;
-
- case UTI596_WAIT_FOR_CU_ACCEPT:
- do {
- if (sc->scb.command == 0)
- break;
- else
-
- start_ticks = rtems_clock_get_ticks_since_boot();
-
- } while (start_ticks <= end_ticks);
-
- if( (sc->scb.command != 0) || (start_ticks > end_ticks) ) {
- printf("i82596 timed out with status %x, cmd %x.\n",
- sc->scb.status, sc->scb.command);
- return -1;
- }
- else
- return 0;
-
- case UTI596_WAIT_FOR_INITIALIZATION:
- do {
- if( !sc->iscp.busy )
- break;
- else
- start_ticks = rtems_clock_get_ticks_since_boot();
- } while (start_ticks <= end_ticks);
-
- if (start_ticks > end_ticks ) {
- #ifdef DBG_WAIT
- printk(("uti596_setScpAndScb: Timed out\n" ))
- #endif
- return -1;
- }
- else {
- #ifdef DBG_WAIT
- printk(("uti596_setScpAndScb: Succeeded\n" ))
- #endif
- return 0;
- }
-
- case UTI596_WAIT_FOR_STAT_C:
- do {
- if( *sc->pCurrent_command_status & STAT_C )
- break;
- else
- start_ticks = rtems_clock_get_ticks_since_boot();
- } while (start_ticks <= end_ticks);
-
- if (start_ticks > end_ticks ) {
- #ifdef DBG_WAIT
- printk(("uti596_initMem: timed out - STAT_C not obtained\n" ))
- #endif
- return -1;
- }
- else {
- #ifdef DBG_WAIT
- printk(("uti596_initMem: STAT_C obtained OK\n" ))
- #endif
- return 0;
- }
- }
- return -1;
-}
-
-/*
- * uti596_issueCA
- *
- * Issue a Channel Attention command. Possibly wait for the
- * command to start or complete.
- *
- * Input parameters:
- * sc - pointer to the uti596_softc
- * wait_type - UTI596_NO_WAIT
- * UTI596_WAIT_BEGIN
- * UTI596_WAIT_COMPLETION
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise.
- */
-static int uti596_issueCA(
- uti596_softc_ *sc,
- uint8_t waitType
-)
-{
- /* Issue Channel Attention */
- i82596->chan_attn = 0x00000000;
-
- return (uti596_wait ( sc, waitType ));
-}
-
-/*
- * uti596_addCmd
- *
- * Add a uti596_cmd onto the end of the CBL command chain,
- * or to the start if the chain is empty.
- *
- * Input parameters:
- * pCmd - a pointer to the command to be added.
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-static void uti596_addCmd(
- i596_cmd *pCmd
-)
-{
- ISR_Level level;
-
- #ifdef DBG_ADD_CMD
- printk(("uti596_addCmd: Adding command 0x%x\n", pCmd -> command ))
- #endif
-
- /* Mark command as last in list, to return an interrupt */
- pCmd->command |= (CMD_EOL | CMD_INTR );
- pCmd->status = 0;
- pCmd->next = I596_NULL;
-
- _ISR_Local_disable(level);
-
- if (uti596_softc.pCmdHead == I596_NULL) {
- uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
- uti596_softc.scb.cmd_pointer = word_swap ((unsigned long)pCmd);
-
- uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
- uti596_softc.scb.command = CUC_START;
- uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
-
- _ISR_Local_enable(level);
- }
- else {
- uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd);
- uti596_softc.pCmdTail = pCmd;
- _ISR_Local_enable(level);
- }
-
- #ifdef DBG_ADD_CMD
- printk(("uti596_addCmd: Scb status & command 0x%x 0x%x\n",
- uti596_softc.scb.status,
- uti596_softc.scb.command ))
- #endif
-}
-
-/*
- * uti596_addPolledCmd
- *
- * Add a single uti596_cmd to the end of the command block list
- * for processing, send a CU_START and wait for its acceptance
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_addPolledCmd(
- i596_cmd *pCmd
-)
-{
-
- #ifdef DBG_ADD_CMD
- printk(("uti596_addPolledCmd: Adding command 0x%x\n", pCmd -> command ))
- #endif
-
- pCmd->status = 0;
- pCmd->command |= CMD_EOL ; /* only command in list*/
- pCmd->next = I596_NULL;
-
- uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
-
- uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
- uti596_softc.scb.cmd_pointer = word_swap((unsigned long)pCmd);
- uti596_softc.scb.command = CUC_START;
- uti596_issueCA ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
-
- uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
- uti596_softc.scb.cmd_pointer = (unsigned long) I596_NULL;
-
- #ifdef DBG_ADD_CMD
- printk(("uti596_addPolledCmd: Scb status & command 0x%x 0x%x\n",
- uti596_softc.scb.status,
- uti596_softc.scb.command ))
- #endif
-}
-
-/* currently unused by RTEMS */
-#if 0
-/*
- * uti596_CU_dump
- *
- * Dump the LANC 82596 registers
- * The outcome is the same as the portDump() but executed
- * via the CU instead of via a PORT access.
- *
- * Input parameters:
- * drp - a pointer to a i596_dump_result structure.
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-static void uti596_CU_dump ( i596_dump_result * drp)
-{
- i596_dump dumpCmd;
-
- dumpCmd.cmd.command = CmdDump;
- dumpCmd.cmd.next = I596_NULL;
- dumpCmd.pData = (char *) drp;
- uti596_softc.cmdOk = 0;
- uti596_addCmd ( (i596_cmd *) &dumpCmd );
-
-}
-#endif
-
-#if defined(DBG_STAT) || !defined(IGNORE_NO_RFA)
-/*
- * uti596_dump_scb
- *
- * Dump the system control block
- * This function expands to nothing when using interrupt driven I/O
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-static void uti596_dump_scb ( void )
-{
- printk(("status 0x%x\n",uti596_softc.scb.status))
- printk(("command 0x%x\n",uti596_softc.scb.command))
- printk(("cmd 0x%x\n",(int)uti596_softc.scb.pCmd))
- printk(("rfd 0x%x\n",(int)uti596_softc.scb.pRfd))
- printk(("crc_err 0x%" PRIx32 "\n",uti596_softc.scb.crc_err))
- printk(("align_err 0x%" PRIx32 "\n",uti596_softc.scb.align_err))
- printk(("resource_err 0x%" PRIx32 "\n",uti596_softc.scb.resource_err ))
- printk(("over_err 0x%" PRIx32 "\n",uti596_softc.scb.over_err))
- printk(("rcvdt_err 0x%" PRIx32 "\n",uti596_softc.scb.rcvdt_err))
- printk(("short_err 0x%" PRIx32 "\n",uti596_softc.scb.short_err))
- printk(("t_on 0x%x\n",uti596_softc.scb.t_on))
- printk(("t_off 0x%x\n",uti596_softc.scb.t_off))
-}
-#endif
-
-/*
- * uti596_setScpAndScb
- *
- * Issue the first channel attention after reset and wait for the busy
- * field to clear in the iscp.
- *
- * Input parameters:
- * sc - pointer to the global uti596_softc
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise.
- */
-static int uti596_setScpAndScb(
- uti596_softc_ * sc
-)
-{
- /* set the busy flag in the iscp */
- sc->iscp.busy = 1;
-
- /* the command block list (CBL) is empty */
- sc->scb.command = 0;
- sc->scb.cmd_pointer = (unsigned long) I596_NULL; /* all 1's */
- sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */
-
- uti596_writePortFunction( sc->pScp, UTI596_SCP_PORT_FUNCTION );
-
- /* Issue CA: pass the scb address to the 596 */
- return ( uti596_issueCA ( sc, UTI596_WAIT_FOR_INITIALIZATION ) );
-}
-
-/*
- * uti596_diagnose
- *
- * Send a diagnose command to the CU
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise
- */
-static int uti596_diagnose( void )
-{
- i596_cmd diagnose;
-
- diagnose.command = CmdDiagnose;
- diagnose.status = 0;
- uti596_softc.pCurrent_command_status = (unsigned short *)&diagnose.status;
- uti596_addPolledCmd(&diagnose);
- return (uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_STAT_C ));
-
- #ifdef DBG_INIT
- printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status))
- #endif
-}
-
-/*
- * uti596_configure
- *
- * Send the CU a configure command with the desired
- * configuration structure
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise
- */
-static int uti596_configure (
- uti596_softc_ * sc
-)
-{
- sc->set_conf.cmd.command = CmdConfigure;
- memcpy ( (void *)sc->set_conf.data, uti596initSetup, 14);
- uti596_addPolledCmd( (i596_cmd *) &sc->set_conf);
-
- /* Poll for successful command completion */
- sc->pCurrent_command_status = (unsigned short *)&(sc->set_conf.cmd.status);
- return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );
-}
-
-/*
- * uti596_IAsetup
- *
- * Send the CU an Individual Address setup command with
- * the ethernet hardware address
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise
- */
-static int uti596_IAsetup (
- uti596_softc_ * sc
-)
-{
- int i;
-
- sc->set_add.cmd.command = CmdSASetup;
- for ( i=0; i<6; i++) {
- sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
- }
- sc->cmdOk = 0;
- uti596_addPolledCmd((i596_cmd *)&sc->set_add);
-
- /* Poll for successful command completion */
- sc->pCurrent_command_status = (unsigned short *)&(sc->set_add.cmd.status);
- return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );
-}
-
-/*
- * uti596_initTBD
- *
- * Initialize transmit buffer descriptors
- * dynamically allocate mem for the number of tbd's required
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value:
- * 0 if successful, -1 otherwise
- */
-static int uti596_initTBD ( uti596_softc_ * sc )
-{
- int i;
- i596_tbd *pTbd, *pPrev;
-
- /* Set up a transmit command with a tbd ready */
- sc->pLastUnkRFD = I596_NULL;
- sc->pTxCmd = (i596_tx *) calloc (1,sizeof (struct i596_tx) );
- sc->pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
- if ((sc->pTxCmd == NULL) || (sc->pTbd == NULL)) {
- return -1;
- }
- sc->pTxCmd->pTbd = (i596_tbd *) word_swap ((unsigned long) sc->pTbd);
- sc->pTxCmd->cmd.command = CMD_FLEX|CmdTx;
- sc->pTxCmd->pad = 0;
- sc->pTxCmd->count = 0; /* all bytes are in list of TBD's */
-
- pPrev = pTbd = sc->pTbd;
-
- /* Allocate a linked list of tbd's each with it's 'next' field written
- * with upper and lower words swapped (for big endian), and mark the end.
- */
- for ( i=0; i<sc->txBdCount; i++) {
- if ( (pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) )) == NULL ) {
- return -1;
- }
- pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd);
- pPrev = pTbd;
- }
- pTbd->next = I596_NULL;
- return 0;
-}
-
-/*
- * uti596_initRFA
- *
- * Initialize the Receive Frame Area
- * dynamically allocate mem for the number of rfd's required
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value:
- * # of buffer descriptors successfully allocated
- */
-static int uti596_initRFA( int num )
-{
- i596_rfd *pRfd;
- int i = 0;
-
- #ifdef DBG_INIT
- printk(("uti596_initRFA: begins\n Requested frame descriptors ... %d.\n", num))
- #endif
-
- /*
- * Create the first RFD in the RFA
- */
- pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd));
- if ( !pRfd ) {
- printk(("Can't allocate first buffer.\n"))
- return 0;
- }
- else {
- uti596_softc.countRFD = 1;
- uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
- }
-
- /* Create remaining RFDs */
- for (i = 1; i < num; i++) {
- pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd) );
- if ( pRfd != NULL ) {
- uti596_softc.countRFD++; /* update count */
- uti596_softc.pEndRFA->next =
- (i596_rfd *) word_swap ((unsigned long) pRfd); /* write the link */
- uti596_softc.pEndRFA = pRfd; /* move the end */
- }
- else {
- printk(("Can't allocate all buffers: only %d allocated\n", i))
- break;
- }
- } /* end for */
-
- uti596_softc.pEndRFA->next = I596_NULL;
- UTI_596_ASSERT(uti596_softc.countRFD == num,"INIT:WRONG RFD COUNT\n" )
-
- #ifdef DBG_INIT
- printk (("uti596_initRFA: Head of RFA is buffer %p \n\
- uti596_initRFA: End of RFA is buffer %p \n",
- uti596_softc.pBeginRFA, uti596_softc.pEndRFA ))
- #endif
-
- /* Walk and initialize the RFD's */
- for ( pRfd = uti596_softc.pBeginRFA;
- pRfd != I596_NULL;
- pRfd = (i596_rfd *) word_swap ((unsigned long)pRfd->next) )
- {
- pRfd->cmd = 0x0000;
- pRfd->stat = 0x0000;
- pRfd->pRbd = I596_NULL;
- pRfd->count = 0; /* number of bytes in buffer: usually less than size */
- pRfd->size = 1532; /* was 1532; buffer size ( All RBD ) */
- } /* end for */
-
- /* mark the last RFD as the last one in the RDL */
- uti596_softc.pEndRFA -> cmd = CMD_EOL;
- uti596_softc.pSavedRfdQueue =
- uti596_softc.pEndSavedQueue = I596_NULL; /* initially empty */
-
- uti596_softc.savedCount = 0;
- uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */
-
- return (i); /* the number of allocated buffers */
-}
-
-/*
- * uti596_initMem
- *
- * Initialize the 82596 memory structures for Tx and Rx
- * dynamically allocate mem for the number of tbd's required
- *
- * Input parameters:
- * sc - a pointer to the uti596_softc struct
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_initMem(
- uti596_softc_ * sc
-)
-{
- int i;
-
- #ifdef DBG_INIT
- printk(("uti596_initMem: begins\n"))
- #endif
-
- sc->resetDone = 0;
-
- /*
- * Set up receive frame area (RFA)
- */
- i = uti596_initRFA( sc->rxBdCount );
- if ( i < sc->rxBdCount ) {
- printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i))
- }
-
- /*
- * Write the SCB with a pointer to the receive frame area
- * and keep a pointer for our use.
- */
- sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);
- sc->scb.pRfd = sc->pBeginRFA;
-
- /*
- * Diagnose the health of the board
- */
- uti596_diagnose();
-
- /*
- * Configure the 82596
- */
- uti596_configure( sc );
-
- /*
- * Set up the Individual (hardware) Address
- */
- uti596_IAsetup ( sc );
-
- /*
- * Initialize the transmit buffer descriptors
- */
- uti596_initTBD( sc );
-
- /* Padding used to fill short tx frames */
- memset ( RTEMS_DEVOLATILE( char *, sc->zeroes ), 0, 64);
-
- /* now need ISR */
- sc->resetDone = 1;
-}
-
-/*
- * uti596_initialize
- *
- * Reset the 82596 and initialize it with a new SCP.
- *
- * Input parameters:
- * sc - pointer to the uti596_softc
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_initialize(
- uti596_softc_ *sc
-)
-{
- /* Reset the device. Stops it from doing whatever it might be doing. */
- uti596_portReset();
-
- /* Get a new System Configuration Pointer */
- uti596_scp_alloc( sc );
-
- /* write the SYSBUS: interrupt pin active high, LOCK disabled,
- * internal triggering, linear mode
- */
- sc->pScp->sysbus = 0x44;
-
- /* provide the iscp to the scp, keep a pointer for our use */
- sc->pScp->iscp_pointer = word_swap((unsigned long)&sc->iscp);
- sc->pScp->iscp = &sc->iscp;
-
- /* provide the scb to the iscp, keep a pointer for our use */
- sc->iscp.scb_pointer = word_swap((unsigned long)&sc->scb);
- sc->iscp.scb = &sc->scb;
-
- #ifdef DBG_INIT
- printk(("uti596_initialize: Starting i82596.\n"))
- #endif
-
- /* Set up the 82596 */
- uti596_setScpAndScb( sc );
-
- /* clear the scb command word */
- sc->scb.command = 0;
-}
-
-/*
- * uti596_initialize_hardware
- *
- * Reset the 82596 and initialize it with a new SCP. Enable bus snooping.
- * Install the interrupt handlers.
- *
- * Input parameters:
- * sc - pointer to the uti596_softc
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_initialize_hardware(
- uti596_softc_ *sc
-)
-{
- printk(("uti596_initialize_hardware: begins\n"))
-
- /* Get the PCCChip2 to assert bus snooping signals on behalf of the i82596 */
- pccchip2->LANC_berr_ctl = 0x40;
-
- uti596_initialize( sc );
-
- /*
- * Configure interrupt control in PCCchip2
- */
- pccchip2->LANC_error = 0xff; /* clear status register */
- pccchip2->LANC_int_ctl = 0x5d; /* lvl 5, enabled, edge-sensitive rising */
- pccchip2->LANC_berr_ctl = 0x5d; /* bus error: lvl 5, enabled, snoop control
- * will supply dirty data and leave dirty data
- * on read access and sink any data on write
- */
- /*
- * Install the interrupt handler
- * calls rtems_interrupt_catch
- */
- set_vector( uti596_DynamicInterruptHandler, 0x57, 1 );
-
- /* Initialize the 82596 memory */
- uti596_initMem(sc);
-
- #ifdef DBG_INIT
- printk(("uti596_initialize_hardware: After attach, status of board = 0x%x\n", sc->scb.status ))
- #endif
-}
-
-/*
- * uti596_reset_hardware
- *
- * Reset the 82596 and initialize it with an SCP.
- *
- * Input parameters:
- * sc - pointer to the uti596_softc
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_reset_hardware(
- uti596_softc_ *sc
-)
-{
- rtems_status_code status_code;
- i596_cmd *pCmd;
-
- pCmd = sc->pCmdHead; /* This is a tx command for sure (99.99999%) */
-
- /* the command block list (CBL) is empty */
- sc->scb.cmd_pointer = (unsigned long) I596_NULL; /* all 1's */
- sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */
-
- #ifdef DBG_RESET
- printk(("uti596_reset_hardware\n"))
- #endif
- uti596_initialize( sc );
-
- /*
- * Wake the transmitter if needed.
- */
- if ( sc->txDaemonTid && pCmd != I596_NULL ) {
- printk(("****RESET: wakes transmitter!\n"))
- status_code = rtems_bsdnet_event_send (sc->txDaemonTid,
- INTERRUPT_EVENT);
-
- if ( status_code != RTEMS_SUCCESSFUL ) {
- printk(("****ERROR:Could NOT send event to tid 0x%" PRIx32 " : %s\n",
- sc->txDaemonTid, rtems_status_text (status_code) ))
- }
- }
-
- #ifdef DBG_RESET
- printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status ))
- #endif
-}
-
-/*
- * uti596_clearListStatus
- *
- * Clear the stat fields for all RFDs
- *
- * Input parameters:
- * pRfd - a pointer to the head of the RFA
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_clearListStatus(
- i596_rfd *pRfd
-)
-{
- while ( pRfd != I596_NULL ) {
- pRfd -> stat = 0;
- pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next);
- }
-}
-
-/*
- * uti596_reset
- *
- * Reset the 82596 and reconfigure
- *
- * Input parameters: NONE
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_reset( void )
-{
- uti596_softc_ *sc = &uti596_softc;
-
- #ifdef DBG_RESET
- printk(("uti596_reset: begin\n"))
- #endif
-
- /* Wait for the CU to be available, then
- * reset the ethernet hardware. Must re-config.
- */
- sc->resetDone = 0;
- uti596_wait ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
- uti596_reset_hardware ( &uti596_softc );
-
- #ifdef DBG_RESET
- uti596_diagnose();
- #endif
-
- /*
- * Configure the 82596
- */
- uti596_configure( sc );
-
- /*
- * Set up the Individual (hardware) Address
- */
- uti596_IAsetup ( sc );
-
- sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL;
-
- /* restore the RFA */
-
- if ( sc->pLastUnkRFD != I596_NULL ) {
- sc-> pEndRFA = sc->pLastUnkRFD; /* The end position can be updated */
- sc-> pLastUnkRFD = I596_NULL;
- }
-
- sc->pEndRFA->next = (i596_rfd*)word_swap((uint32_t)sc->pSavedRfdQueue);
- if ( sc->pSavedRfdQueue != I596_NULL ) {
- sc->pEndRFA = sc->pEndSavedQueue;
- sc->pSavedRfdQueue = sc->pEndSavedQueue = I596_NULL;
- sc -> countRFD = sc->rxBdCount ;
- }
-
- /* Re-address the head of the RFA in the SCB */
- sc->scb.pRfd = sc->pBeginRFA;
- sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);
-
- /* Clear the status of all RFDs */
- uti596_clearListStatus( sc->pBeginRFA );
-
- printk(("uti596_reset: Starting NIC\n"))
-
- /* Start the receiver */
- sc->scb.command = RX_START;
- sc->started = 1; /* assume that the start is accepted */
- sc->resetDone = 1;
- uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
-
- UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n")
-
- #ifdef DBG_RESET
- printk(("uti596_reset: completed\n"))
- #endif
-}
-
-/*
- * uti596_dequeue
- *
- * Remove an RFD from the received fram queue
- *
- * Input parameters:
- * ppQ - a pointer to a i596_rfd pointer
- *
- * Output parameters: NONE
- *
- * Return value:
- * pRfd - a pointer to the dequeued RFD
- */
-i596_rfd * uti596_dequeue(
- i596_rfd ** ppQ
-)
-{
- ISR_Level level;
- i596_rfd * pRfd;
-
- _ISR_Local_disable(level);
-
- /* invalid address, or empty queue or emptied queue */
- if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
- _ISR_Local_enable(level);
- return I596_NULL;
- }
-
- /*
- * Point to the dequeued buffer, then
- * adjust the queue pointer and detach the buffer
- */
- pRfd = *ppQ;
- *ppQ = (i596_rfd *) word_swap ((unsigned long) pRfd->next);
- pRfd->next = I596_NULL; /* unlink the rfd being returned */
-
- _ISR_Local_enable(level);
- return pRfd;
-}
-
-/*
- * uti596_append
- *
- * Remove an RFD buffer from the RFA and tack it on to
- * the received frame queue for processing.
- *
- * Input parameters:
- * ppQ - a pointer to the queue pointer
- * pRfd - a pointer to the buffer to be returned
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-
-void uti596_append(
- i596_rfd ** ppQ,
- i596_rfd * pRfd
-)
-{
-
- i596_rfd *p;
-
- if ( pRfd != NULL && pRfd != I596_NULL) {
- pRfd -> next = I596_NULL;
- pRfd -> cmd |= CMD_EOL; /* set EL bit */
-
- if ( *ppQ == NULL || *ppQ == I596_NULL ) {
- /* empty list */
- *ppQ = pRfd;
- }
- else {
- /* walk to the end of the list */
- for ( p=*ppQ;
- p->next != I596_NULL;
- p=(i596_rfd *) word_swap ((unsigned long)p->next) );
-
- /* append the rfd */
- p->cmd &= ~CMD_EOL; /* Clear EL bit at end */
- p->next = (i596_rfd *) word_swap ((unsigned long)pRfd);
- }
- }
- else {
- printk(("Illegal attempt to append: %p\n", pRfd))
- }
-}
-
-/*
- * uti596_supplyFD
- *
- * Return a buffer (RFD) to the receive frame area (RFA).
- * Call with interrupts disabled.
- *
- * Input parameters:
- * pRfd - a pointer to the buffer to be returned
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void uti596_supplyFD (
- i596_rfd * pRfd
-)
-{
- i596_rfd *pLastRfd;
-
- UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n")
-
- pRfd -> cmd = CMD_EOL;
- pRfd -> pRbd = I596_NULL;
- pRfd -> next = I596_NULL;
- pRfd -> stat = 0x0000; /* clear STAT_C and STAT_B bits */
-
- /*
- * Check if the list is empty:
- */
- if ( uti596_softc.pBeginRFA == I596_NULL ) {
-
- /* Start a list with one entry */
- uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
- UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n")
- if ( uti596_softc.pLastUnkRFD != I596_NULL ) {
- printk(("LastUnkRFD is NOT NULL!!\n"))
- }
- uti596_softc.countRFD = 1;
- return;
- }
-
- /*
- * Check if the last RFD is used/read by the 596.
- */
- pLastRfd = uti596_softc.pEndRFA;
-
- /* C = complete, B = busy (prefetched) */
- if ( pLastRfd != I596_NULL && ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) {
-
- /*
- * Not yet too late to add it
- */
- pLastRfd -> next = (i596_rfd *) word_swap ((unsigned long)pRfd);
- pLastRfd -> cmd &= ~CMD_EOL; /* RESET_EL : reset EL bit to 0 */
- uti596_softc.countRFD++; /* Lets assume we add it successfully
- If not, the RFD may be used, and may
- decrement countRFD < 0 !! */
- /*
- * Check if the last RFD was used while appending.
- */
- if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */
- /*
- * Either the EL bit of the last rfd has been read by the 82596,
- * and it will stop after reception,( true when RESET_EL not reached ) or
- * the EL bit was NOT read by the 82596 and it will use the linked
- * RFD for the next reception. ( true when RESET_EL was reached )
- * So, it is unknown whether or not the linked rfd will be used.
- * Therefore, the end of list CANNOT be updated.
- */
- UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" )
- uti596_softc.pLastUnkRFD = pRfd;
- return;
- }
- else {
- /*
- * The RFD being added was not touched by the 82596
- */
- if (uti596_softc.pLastUnkRFD != I596_NULL ) {
-
- uti596_append((i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */
- uti596_softc.pEndSavedQueue = pRfd;
- uti596_softc.savedCount++;
- uti596_softc.countRFD--;
-
- }
- else {
-
- uti596_softc.pEndRFA = pRfd; /* the RFA has been extended */
-
- if ( ( uti596_softc.scb.status & SCB_STAT_RNR ||
- uti596_softc.scb.status & RU_NO_RESOURCES ) &&
- uti596_softc.countRFD > 1 ) {
-
- /* Ensure that beginRFA is not EOL */
- uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL;
-
- UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n")
- UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n")
- UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n")
-
- #ifdef DBG_MEM
- printk(("uti596_supplyFD: starting receiver"))
- #endif
-
- /* start the receiver */
- UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n")
- uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
- uti596_softc.scb.rfd_pointer = word_swap ((unsigned long) uti596_softc.pBeginRFA);
-
- /* Don't ack RNR! The receiver should be stopped in this case */
- uti596_softc.scb.command = RX_START | SCB_STAT_RNR;
-
- UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n")
-
- /* send CA signal */
- uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
- }
- }
- return;
- }
- }
- else {
- /*
- * too late , pLastRfd in use ( or NULL ),
- * in either case, EL bit has been read, and RNR condition will occur
- */
- uti596_append( (i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
-
- uti596_softc.pEndSavedQueue = pRfd; /* reset end of saved queue */
- uti596_softc.savedCount++;
-
- return;
- }
-}
-
-/*
- * send_packet
- *
- * Send a raw ethernet packet, add a
- * transmit command to the CBL
- *
- * Input parameters:
- * ifp - a pointer to the ifnet structure
- * m - a pointer to the mbuf being sent
- *
- * Output parameters: NONE
- *
- * Return value: NONE
- */
-void send_packet(
- struct ifnet *ifp, struct mbuf *m
-)
-{
- i596_tbd *pPrev = I596_NULL;
- i596_tbd *pRemainingTbdList;
- i596_tbd *pTbd;
- struct mbuf *n, *input_m = m;
- uti596_softc_ *sc = ifp->if_softc;
- struct mbuf *l = NULL;
- unsigned int length = 0;
- rtems_status_code status;
- int bd_count = 0;
- rtems_event_set events;
-
- /*
- * For all mbufs in the chain,
- * fill a transmit buffer descriptor for each
- */
- pTbd = (i596_tbd*) word_swap ((unsigned long)sc->pTxCmd->pTbd);
-
- do {
- if (m->m_len) {
- /*
- * Fill in the buffer descriptor
- */
- length += m->m_len;
- pTbd->data = (char *) word_swap ((unsigned long) mtod (m, void *));
- pTbd->size = m->m_len;
- pPrev = pTbd;
- pTbd = (i596_tbd *) word_swap ((unsigned long) pTbd->next);
- l = m;
- m = m->m_next;
- }
- else {
- /*
- * Just toss empty mbufs
- */
- MFREE (m, n);
- m = n;
- if (l != NULL)
- l->m_next = m;
- }
- } while( m != NULL && ++bd_count < 16 );
-
- if ( length < UTI_596_ETH_MIN_SIZE ) {
- pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */
- pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */
- }
- else /* Don't use pTbd in the send routine */
- pTbd = pPrev;
-
- /* Disconnect the packet from the list of Tbd's */
- pRemainingTbdList = (i596_tbd *) word_swap ((unsigned long)pTbd->next);
- pTbd->next = I596_NULL;
- pTbd->size |= UTI_596_END_OF_FRAME;
-
- sc->rawsndcnt++;
-
- #ifdef DBG_SEND
- printk(("send_packet: sending packet\n"))
- #endif
-
- /* Sending Zero length packet: shouldn't happen */
- if (pTbd->size <= 0) return;
-
- #ifdef DBG_PACKETS
- printk (("\nsend_packet: Transmitter adds packet\n"))
- print_hdr ( sc->pTxCmd->pTbd->data ); /* print the first part */
- print_pkt ( sc->pTxCmd->pTbd->next->data ); /* print the first part */
- print_echo (sc->pTxCmd->pTbd->data);
- #endif
-
- /* add the command to the output command queue */
- uti596_addCmd ( (i596_cmd *) sc->pTxCmd );
-
- /* sleep until the command has been processed or Timeout encountered. */
- status= rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- if ( status != RTEMS_SUCCESSFUL ) {
- printk(("Could not sleep %s\n", rtems_status_text(status)))
- }
-
- #ifdef DBG_SEND
- printk(("send_packet: RAW - wake\n"))
- #endif
-
- sc->txInterrupts++;
-
- if ( sc->pTxCmd -> cmd.status & STAT_OK ) {
- sc->stats.tx_packets++;
- }
- else {
-
- printk(("*** send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status ))
-
- sc->stats.tx_errors++;
- if ( sc->pTxCmd->cmd.status & 0x0020 )
- sc->stats.tx_retries_exceeded++;
- if (!(sc->pTxCmd->cmd.status & 0x0040))
- sc->stats.tx_heartbeat_errors++;
- if ( sc->pTxCmd->cmd.status & 0x0400 )
- sc->stats.tx_carrier_errors++;
- if ( sc->pTxCmd->cmd.status & 0x0800 )
- sc->stats.collisions++;
- if ( sc->pTxCmd->cmd.status & 0x1000 )
- sc->stats.tx_aborted_errors++;
- } /* end if stat_ok */
-
- /*
- * Restore the transmitted buffer descriptor chain.
- */
- pTbd -> next = (i596_tbd *) word_swap ((unsigned long)pRemainingTbdList);
-
- /*
- * Free the mbufs used by the sender.
- */
- m = input_m;
- while ( m != NULL ) {
- MFREE(m,n);
- m = n;
- }
-}
-
-/***********************************************************************
- * Function: uti596_attach
- *
- * Description:
- * Configure the driver, and connect to the network stack
- *
- * Algorithm:
- *
- * Check parameters in the ifconfig structure, and
- * set driver parameters accordingly.
- * Initialize required rx and tx buffers.
- * Link driver data structure onto device list.
- * Return 1 on successful completion.
- *
- ***********************************************************************/
-
-int uti596_attach(
- struct rtems_bsdnet_ifconfig * pConfig,
- int attaching
-)
-{
- uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */
- struct ifnet * ifp = (struct ifnet *)&sc->arpcom.ac_if; /* ifnet structure */
- int unitNumber;
- char *unitName;
-#if defined(mvme167)
- unsigned char j1; /* State of J1 jumpers */
- char *pAddr;
- int addr;
-#endif
-
- #ifdef DBG_ATTACH
- printk(("uti596_attach: begins\n"))
- #endif
-
- /* The NIC is not started yet */
- sc->started = 0;
-
- /* Indicate to ULCS that this is initialized */
- ifp->if_softc = (void *)sc;
- sc->pScp = NULL;
-
- /* Parse driver name */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)
- return 0;
-
- ifp->if_name = unitName;
- ifp->if_unit = unitNumber;
-
- /* Assign mtu */
- if ( pConfig -> mtu )
- ifp->if_mtu = pConfig -> mtu;
- else
- ifp->if_mtu = ETHERMTU;
-
- /*
- * Check whether parameters should be obtained from NVRAM. If
- * yes, and if an IP address, netmask, or ethernet address are
- * provided in NVRAM, cheat, and stuff them into the ifconfig
- * structure, OVERRIDING and existing or NULL values.
- *
- * Warning: If values are provided in NVRAM, the ifconfig entries
- * must be NULL because buffer memory allocated to hold the
- * structure values is unrecoverable and would be lost here.
- */
-
-#if defined(mvme167)
- /* Read the J1 header */
- j1 = (unsigned char)(lcsr->vector_base & 0xFF);
-
- if ( !(j1 & 0x10) ) {
- /* Jumper J1-4 is on, 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 )) )
- pConfig->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 )) )
- pConfig->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
- * NVRAM parameter the highest priority if J1-4 indicates we are configuring
- * from NVRAM.
- *
- * 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 ( pConfig->hardware_address) {
- /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */
- memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
- }
- else {
- /* There is no ethernet address provided, so it will be read
- * from BBRAM at $FFFC1F2C by default. [mvme167 manual p. 1-47]
- */
- memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
- }
- }
- else if ( pConfig->hardware_address) {
- /* We are not configuring from NVRAM (J1-4 is off), and the ethernet address
- * is given in the ifconfig structure. Copy it.
- */
- memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
- }
- else
-#endif
- {
- /* We are not configuring from NVRAM (J1-4 is off), and there is no ethernet
- * address provided in the ifconfig struct, so it will be read from BBRAM at
- * $FFFC1F2C by default. [mvme167 manual p. 1-47]
- */
- memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
- }
-
- /* Possibly override default acceptance of broadcast packets */
- if (pConfig->ignore_broadcast)
- uti596initSetup[8] |= 0x02;
-
- /* Assign requested receive buffer descriptor count */
- if (pConfig->rbuf_count)
- sc->rxBdCount = pConfig->rbuf_count;
- else
- sc->rxBdCount = RX_BUF_COUNT;
-
- /* Assign requested tx buffer descriptor count */
- if (pConfig->xbuf_count)
- sc->txBdCount = pConfig->xbuf_count;
- else
- sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
-
- /* Set up fields in the ifnet structure*/
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_init = uti596_init;
- ifp->if_ioctl = uti596_ioctl;
- ifp->if_start = uti596_start;
- ifp->if_output = ether_output;
-
- /* uti596_softc housekeeping */
- sc->started = 1;
- sc->pInboundFrameQueue = I596_NULL;
- sc->scb.command = 0;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
- return 1;
-}
-
-/***********************************************************************
- * Function: uti596_start
- *
- * Description:
- * start the driver
- *
- * Algorithm:
- * send an event to the tx task
- * set the if_flags
- *
- ***********************************************************************/
-static void uti596_start(
- struct ifnet *ifp
-)
-{
- uti596_softc_ *sc = ifp->if_softc;
-
- #ifdef DBG_START
- printk(("uti596_start: begins\n"))
- #endif
-
- rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/***********************************************************************
- * Function: uti596_init
- *
- * Description:
- * driver initialization
- *
- * Algorithm:
- * initialize the 82596
- * start driver tx and rx tasks, and reset task
- * send the RX_START command the the RU
- * set if_flags
- *
- *
- ***********************************************************************/
-void uti596_init(
- void * arg
-)
-{
- uti596_softc_ *sc = arg;
- struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Initialize the 82596
- */
- #ifdef DBG_INIT
- printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n"))
- #endif
- uti596_initialize_hardware(sc);
-
- /*
- * Start driver tasks
- */
- #ifdef DBG_INIT
- printk(("uti596_init: starting driver tasks...\n"))
- #endif
- sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, (void *)sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, (void *)sc);
- sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, (void *)sc);
-
- #ifdef DBG_INIT
- printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status ))
- #endif
- }
-
- /*
- * In case the ISR discovers there are no resources it reclaims
- * them and restarts
- */
- sc->started = 1;
-
- /*
- * Enable receiver
- */
- #ifdef DBG_INIT
- printk(("uti596_init: enabling the reciever...\n" ))
- #endif
- sc->scb.command = RX_START;
- uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
- #ifdef DBG_INIT
- printk(("uti596_init: completed.\n"))
- #endif
-}
-
-/***********************************************************************
- * Function: uti596stop
- *
- * Description:
- * stop the driver
- *
- * Algorithm:
- * mark driver as not started,
- * mark transmitter as busy
- * abort any transmissions/receptions
- * clean-up all buffers ( RFD's et. al. )
- *
- *
- ***********************************************************************/
-
-/* static */ void uti596_stop(
- uti596_softc_ *sc
-)
-{
- struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
- sc->started = 0;
-
- #ifdef DBG_STOP
- printk(("uti596stop: %s: Shutting down ethercard, status was %4.4x.\n",
- uti596_softc.arpcom.ac_if.if_name, uti596_softc.scb.status))
- #endif
-
- printk(("Stopping interface\n"))
- sc->scb.command = CUC_ABORT | RX_ABORT;
- i82596->chan_attn = 0x00000000;
-}
-
-/***********************************************************************
- * Function: void uti596_txDaemon
- *
- * Description: Transmit task
- *
- * Algorithm: Get mbufs to be transmitted, stuff into RFDs, send
- *
- ***********************************************************************/
-
-void uti596_txDaemon(
- void *arg
-)
-{
- uti596_softc_ *sc = (uti596_softc_ *)arg;
- struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for (;;) {
- /*
- * Wait for packet from stack
- */
- rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-
- /*
- * Send packets till queue is empty.
- * Ensure that irq is on before sending.
- */
- for (;;) {
- /* Get the next mbuf chain to transmit. */
- IF_DEQUEUE(&ifp->if_snd, m);
- if (!m)
- break;
-
- send_packet (ifp, m); /* blocks */
- }
- ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive */
- }
-}
-
-/***********************************************************************
- * Function: uti596_rxDaemon
- *
- * Description: Receiver task
- *
- * Algorithm: Extract the packet from an RFD, and place into an
- * mbuf chain. Place the mbuf chain in the network task
- * queue. Assumes that the frame check sequence is removed
- * by the 82596.
- *
- ***********************************************************************/
-
-/* static */ void uti596_rxDaemon(
- void *arg
-)
-{
- uti596_softc_ *sc = (uti596_softc_ *)arg;
- struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if;
- struct mbuf *m;
-
- i596_rfd *pRfd;
- ISR_Level level;
- rtems_id tid;
- rtems_event_set events;
- struct ether_header *eh;
-
- int frames = 0;
-
- #ifdef DBG_RX
- printk(("uti596_rxDaemon: begin\n"))
- printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd))
- #endif
-
- rtems_task_ident (0, 0, &tid);
-
- for(;;) {
- /*
- * Wait for packet.
- */
- #ifdef DBG_RX
- printk(("uti596_rxDaemon: Receiver sleeps\n"))
- #endif
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- #ifdef DBG_RX
- printk(("uti596_rxDaemon: Receiver wakes\n"))
- #endif
- /*
- * While received frames are available. Note that the frame may be
- * a fragment, so it is NOT a complete packet.
- */
- pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue);
- while ( pRfd &&
- pRfd != I596_NULL &&
- pRfd -> stat & STAT_C )
- {
-
- if ( pRfd->stat & STAT_OK) { /* a good frame */
- int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */
-
- #ifdef DBG_RX
- printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len))
- #endif
- frames++;
-
- /*
- * Allocate an mbuf to give to the stack
- * The format of the data portion of the RFD is:
- * <ethernet header, payload>.
- * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596.
- * This is to be optimized later.... should not have to memcopy!
- */
- MGETHDR(m, M_WAIT, MT_DATA);
- MCLGET(m, M_WAIT);
-
- m->m_pkthdr.rcvif = ifp;
- /* move everything into an mbuf */
- memcpy(m->m_data, (const char *)pRfd->data, pkt_len);
- m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4;
-
- /* move the header to an mbuf */
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
-
- #ifdef DBG_PACKETS
- {
- int i;
- printk(("uti596_rxDaemon: mbuf contains:\n"))
- print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));
- for ( i = 0; i<20; i++) {
- printk(("."))
- }
- }
- #endif
-
- ether_input (ifp, eh, m);
-
- } /* end if STAT_OK */
-
- else {
- /*
- * A bad frame is present: Note that this could be the last RFD!
- */
- #ifdef DBG_RX
- printk(("uti596_rxDaemon: Bad frame\n"))
- #endif
- /*
- * FIX ME: use the statistics from the SCB
- */
- sc->stats.rx_errors++;
- if ((sc->scb.pRfd->stat) & 0x0001)
- sc->stats.collisions++;
- if ((sc->scb.pRfd->stat) & 0x0080)
- sc->stats.rx_length_errors++;
- if ((sc->scb.pRfd->stat) & 0x0100)
- sc->stats.rx_over_errors++;
- if ((sc->scb.pRfd->stat) & 0x0200)
- sc->stats.rx_fifo_errors++;
- if ((sc->scb.pRfd->stat) & 0x0400)
- sc->stats.rx_frame_errors++;
- if ((sc->scb.pRfd->stat) & 0x0800)
- sc->stats.rx_crc_errors++;
- if ((sc->scb.pRfd->stat) & 0x1000)
- sc->stats.rx_length_errors++;
- }
-
- UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n")
-
- _ISR_Local_disable(level);
- uti596_supplyFD ( pRfd ); /* Return RFD to RFA. */
- _ISR_Local_enable(level);
-
- pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue); /* grab next frame */
-
- } /* end while */
- } /* end for() */
-
- #ifdef DBG_RX
- printk (("uti596_rxDaemon: frames ... %d\n", frames))
- #endif
-}
-
-/***********************************************************************
- * Function: void uti596_resetDaemon
- *
- * Description:
- ***********************************************************************/
-void uti596_resetDaemon(
- void *arg
-)
-{
- uti596_softc_ *sc = (uti596_softc_ *)arg;
- rtems_event_set events;
- rtems_time_of_day tm_struct;
-
- /* struct ifnet *ifp = &sc->arpcom.ac_if; */
-
- for (;;) {
- /* Wait for reset event from ISR */
- rtems_bsdnet_event_receive (NIC_RESET_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-
- rtems_clock_get_tod(&tm_struct);
- printk(("reset daemon: Resetting NIC @ %" PRIu32 ":%" PRIu32 ":%" PRIu32 " \n",
- tm_struct.hour, tm_struct.minute, tm_struct.second))
-
- sc->stats.nic_reset_count++;
- /* Reinitialize the LANC */
- rtems_bsdnet_semaphore_obtain ();
- uti596_reset();
- rtems_bsdnet_semaphore_release ();
- }
-}
-
-/***********************************************************************
- * Function: uti596_DynamicInterruptHandler
- *
- * Description:
- * This is the interrupt handler for the uti596 board
- *
- ***********************************************************************/
-
-/* static */ rtems_isr uti596_DynamicInterruptHandler(
- rtems_vector_number irq
-)
-{
-int fullStatus;
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: begins"))
- #endif
-
- uti596_wait (&uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT);
-
- scbStatus = (fullStatus = uti596_softc.scb.status) & 0xf000;
-
- if ( scbStatus ) {
- /* acknowledge interrupts */
-
- /* Write to the ICLR bit in the PCCchip2 control registers to clear
- * the INT status bit. Clearing INT here *before* sending the CA signal
- * to the 82596 should ensure that interrupts won't be lost.
- */
- pccchip2->LANC_int_ctl |=0x08;
- pccchip2->LANC_berr_ctl |=0x08;
-
- /* printk(("***INFO: ACK %x\n", scbStatus))*/
-
- /* Send the CA signal to acknowledge interrupt */
- uti596_softc.scb.command = scbStatus;
- uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
-
- if( uti596_softc.resetDone ) {
- /* stack is attached */
- uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
- }
- else {
- printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus))
- return;
- }
- }
- else {
-#ifndef IGNORE_SPURIOUS_IRQ
- printk(("\n***ERROR: Spurious interrupt (full status 0x%x). Resetting...\n", fullStatus))
- uti596_softc.nic_reset = 1;
-#endif
- }
-
- if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ) {
- printk(("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus))
- uti596_softc.nic_reset = 1;
- return;
- }
-
- if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
- printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus))
- uti596_softc.nic_reset = 1;
- return;
- }
-
- if ( scbStatus & SCB_CUS_SUSPENDED ) {
- printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus))
- uti596_softc.nic_reset = 1;
- return;
- }
-
- if ( scbStatus & RU_SUSPENDED ) {
- printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus))
- uti596_softc.nic_reset = 1;
- return;
- }
-
- if ( scbStatus & SCB_STAT_RNR ) {
- printk(("\n*****WARNING: RNR %x\n",scbStatus))
- if (uti596_softc.pBeginRFA != I596_NULL) {
- printk(("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA->cmd,
- uti596_softc.pBeginRFA->stat))
- }
- else {
- printk(("*****WARNING: RNR condition with NULL BeginRFA\n"))
- }
- }
-
- /*
- * Receive Unit Control
- * a frame is received
- */
- if ( scbStatus & SCB_STAT_FR ) {
- uti596_softc.rxInterrupts++;
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: Frame received\n"))
- #endif
- if ( uti596_softc.pBeginRFA == I596_NULL ||
- !( uti596_softc.pBeginRFA -> stat & STAT_C)) {
-#ifndef IGNORE_NO_RFA
- uti596_dump_scb();
- uti596_softc.nic_reset = 1;
-#endif
- }
- else {
- while ( uti596_softc.pBeginRFA != I596_NULL &&
- ( uti596_softc.pBeginRFA -> stat & STAT_C)) {
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n"))
- #endif
- count_rx ++;
-#ifndef IGNORE_MULTIPLE_RF
- if ( count_rx > 1) {
- printk(("****WARNING: Received %i frames on 1 interrupt \n", count_rx))
- }
-#endif
- /* Give Received Frame to the ULCS */
- uti596_softc.countRFD--;
-
- if ( uti596_softc.countRFD < 0 ) {
- printk(("ISR: Count < 0 !!! count == %d, beginRFA = %p\n",
- uti596_softc.countRFD, uti596_softc.pBeginRFA))
- }
- uti596_softc.stats.rx_packets++;
- /* the rfd next link is stored with upper and lower words swapped so read it that way */
- pIsrRfd = (i596_rfd *) word_swap ((unsigned long)uti596_softc.pBeginRFA->next);
- /* the append destroys the link */
- uti596_append( (i596_rfd **)&uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
-
- /*
- * if we have just received the a frame in the last unknown RFD,
- * then it is certain that the RFA is empty.
- */
- if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {
- UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n")
- uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
- }
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid))
- #endif
- sc = rtems_bsdnet_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);
- if ( sc != RTEMS_SUCCESSFUL ) {
- rtems_panic("Can't notify rxDaemon: %s\n",
- rtems_status_text (sc));
- }
- #ifdef DBG_ISR
- else {
- printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid))
- }
- #endif
-
- uti596_softc.pBeginRFA = pIsrRfd;
- } /* end while */
- } /* end if */
-
- if ( uti596_softc.pBeginRFA == I596_NULL ) {
- /* adjust the pEndRFA to reflect an empty list */
- if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 ) {
- printk(("Last Unk is NULL, BeginRFA is null, and count == %d\n",
- uti596_softc.countRFD))
- }
- uti596_softc.pEndRFA = I596_NULL;
- if ( uti596_softc.countRFD != 0 ) {
- printk(("****ERROR:Count is %d, but begin ptr is NULL\n",
- uti596_softc.countRFD ))
- }
- }
- } /* end if ( scbStatus & SCB_STAT_FR ) */
-
- /*
- * Command Unit Control
- * a command is completed
- */
- if ( scbStatus & SCB_STAT_CX ) {
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: CU\n"))
- #endif
-
- pIsrCmd = uti596_softc.pCmdHead;
-
- /* For ALL completed commands */
- if ( pIsrCmd != I596_NULL && pIsrCmd->status & STAT_C ) {
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n"))
- #endif
-
- /* Adjust the command block list */
- uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next);
-
- /*
- * If there are MORE commands to process,
- * the serialization in the raw routine has failed.
- * ( Perhaps AddCmd is bad? )
- */
- UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL, "****ERROR: command serialization failed\n")
-
- /* What if the command did not complete OK? */
- switch ( pIsrCmd->command & 0x7) {
- case CmdConfigure:
-
- uti596_softc.cmdOk = 1;
- break;
-
- case CmdDump:
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: dump!\n"))
- #endif
- uti596_softc.cmdOk = 1;
- break;
-
- case CmdDiagnose:
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: diagnose!\n"))
- #endif
- uti596_softc.cmdOk = 1;
- break;
-
- case CmdSASetup:
- /* printk(("****INFO:Set address interrupt\n")) */
- if ( pIsrCmd -> status & STAT_OK ) {
- uti596_softc.cmdOk = 1;
- }
- else {
- printk(("****ERROR:SET ADD FAILED\n"))
- }
- break;
-
- case CmdTx:
- UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n")
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid))
- #endif
- if ( uti596_softc.txDaemonTid ) {
- /* Ensure that the transmitter is present */
- sc = rtems_bsdnet_event_send (uti596_softc.txDaemonTid,
- INTERRUPT_EVENT);
-
- if ( sc != RTEMS_SUCCESSFUL ) {
- printk(("****ERROR:Could NOT send event to tid 0x%" PRIu32 " : %s\n",
- uti596_softc.txDaemonTid, rtems_status_text (sc) ))
- }
- #ifdef DBG_ISR
- else {
- printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))
- }
- #endif
- }
- break;
-
- case CmdMulticastList:
- printk(("***ERROR:Multicast?!\n"))
- pIsrCmd->next = I596_NULL;
- break;
-
- case CmdTDR: {
- unsigned long status = *( (unsigned long *)pIsrCmd)+1;
- printk(("****ERROR:TDR?!\n"))
-
- if (status & STAT_C) {
- /* mark the TDR command successful */
- uti596_softc.cmdOk = 1;
- }
- else {
- if (status & 0x4000) {
- printk(("****WARNING:Transceiver problem.\n"))
- }
- if (status & 0x2000) {
- printk(("****WARNING:Termination problem.\n"))
- }
- if (status & 0x1000) {
- printk(("****WARNING:Short circuit.\n"))
- /* printk(("****INFO:Time %ld.\n", status & 0x07ff)) */
- }
- }
- }
- break;
-
- default: {
- /*
- * This should never be reached
- */
- printk(("CX but NO known command\n"))
- }
- } /* end switch */
-
- pIsrCmd = uti596_softc.pCmdHead; /* next command */
- if ( pIsrCmd != I596_NULL ) {
- printk(("****WARNING: more commands in list, but no start to NIC\n"))
- }
- } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C */
-
- else {
- if ( pIsrCmd != I596_NULL ) {
- /* The command MAY be NULL from a RESET */
- /* Reset the ethernet card, and wake the transmitter (if necessary) */
- printk(("****INFO: Request board reset ( tx )\n"))
- uti596_softc.nic_reset = 1;
- if ( uti596_softc.txDaemonTid) {
- /* Ensure that a transmitter is present */
- sc = rtems_bsdnet_event_send (uti596_softc.txDaemonTid,
- INTERRUPT_EVENT);
- if ( sc != RTEMS_SUCCESSFUL ) {
- printk(("****ERROR:Could NOT send event to tid 0x%" PRIu32 " : %s\n",
- uti596_softc.txDaemonTid, rtems_status_text (sc) ))
- }
- #ifdef DBG_ISR
- else {
- printk(("uti596_DynamicInterruptHandler: ****INFO:Tx wake: %#x\n",
- uti596_softc.txDaemonTid))
- }
- #endif
- }
- }
- }
- } /* end if command complete */
-
- /*
- * If the receiver has stopped,
- * check if this is a No Resources scenario,
- * Try to add more RFD's ( no RBDs are used )
- */
- if ( uti596_softc.started ) {
- if ( scbStatus & SCB_STAT_RNR ) {
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: INFO:RNR: status %#x \n",
- uti596_softc.scb.status ))
- #endif
- /*
- * THE RECEIVER IS OFF!
- */
- if ( uti596_softc.pLastUnkRFD != I596_NULL ) {
- /* We have an unknown RFD, it is not inbound */
- if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) { /* in use */
- uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD; /* update end */
- }
- else {
- /*
- * It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!
- * So, unlink it from the RFA and move it to the saved queue.
- * But pBegin can equal LastUnk!
- */
-
- if ( uti596_softc.pEndRFA != I596_NULL ) {
- /* check added feb24. */
- #ifdef DBG_ISR
- if ((i596_rfd *)word_swap((unsigned long)uti596_softc.pEndRFA->next) != uti596_softc.pLastUnkRFD) {
- printk(("***ERROR:UNK: %p not end->next: %p, end: %p\n",
- uti596_softc.pLastUnkRFD,
- uti596_softc.pEndRFA -> next,
- uti596_softc.pEndRFA))
- printk(("***INFO:countRFD now %d\n",
- uti596_softc.countRFD))
- printk(("\n\n"))
- }
- #endif
- uti596_softc.pEndRFA -> next = I596_NULL; /* added feb 16 */
- }
- uti596_append( (i596_rfd **)&uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
- uti596_softc.savedCount++;
- uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
- uti596_softc.countRFD--; /* It was not in the RFA */
- /*
- * The Begin pointer CAN advance this far. We must resynch the CPU side
- * with the chip.
- */
- if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
- #ifdef DBG_ISR
- if ( uti596_softc.countRFD != 0 ) {
- printk(("****INFO:About to set begin to NULL, with count == %d\n\n",
- uti596_softc.countRFD ))
- }
- #endif
- uti596_softc.pBeginRFA = I596_NULL;
- UTI_596_ASSERT(uti596_softc.countRFD == 0, "****ERROR:Count must be zero here!\n")
- }
- }
- uti596_softc.pLastUnkRFD = I596_NULL;
- } /* end if exists UnkRFD */
-
- /*
- * Append the saved queue to the RFA.
- * Any further RFD's being supplied will be added to
- * this new list.
- */
- if ( uti596_softc.pSavedRfdQueue != I596_NULL ) {
- /* entries to add */
- if ( uti596_softc.pBeginRFA == I596_NULL ) {
- /* add at beginning to list */
- #ifdef DBG_ISR
- if(uti596_softc.countRFD != 0) {
- printk(("****ERROR:Begin pointer is NULL, but count == %d\n",
- uti596_softc.countRFD))
- }
- #endif
- uti596_softc.pBeginRFA = uti596_softc.pSavedRfdQueue;
- uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue;
- uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
- }
- else {
- #ifdef DBG_ISR
- if ( uti596_softc.countRFD <= 0) {
- printk(("****ERROR:Begin pointer is not NULL, but count == %d\n",
- uti596_softc.countRFD))
- }
- #endif
- UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n")
- UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n")
-
- uti596_softc.pEndRFA->next = (i596_rfd *)word_swap((unsigned long)uti596_softc.pSavedRfdQueue);
- uti596_softc.pEndRFA->cmd &= ~CMD_EOL; /* clear the end of list */
- uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue;
- uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: count... %d, saved ... %d \n",
- uti596_softc.countRFD,
- uti596_softc.savedCount))
- #endif
- }
- /* printk(("Isr: countRFD = %d\n",uti596_softc.countRFD)) */
- uti596_softc.countRFD += uti596_softc.savedCount;
- /* printk(("Isr: after countRFD = %d\n",uti596_softc.countRFD)) */
- uti596_softc.savedCount = 0;
- }
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: The list starts here %p\n",uti596_softc.pBeginRFA ))
- #endif
-
- if ( uti596_softc.countRFD > 1) {
- printk(("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat))
- printk(("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd))
- uti596_softc.pBeginRFA -> stat = 0;
- UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n")
- uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
- uti596_softc.scb.rfd_pointer = word_swap((unsigned long)uti596_softc.pBeginRFA);
- /* start RX here */
- printk(("****INFO: ISR Starting receiver\n"))
- uti596_softc.scb.command = RX_START; /* should this also be CU start? */
- i82596->chan_attn = 0x00000000;
- }
- } /* end stat_rnr */
- } /* end if receiver started */
-
- #ifdef DBG_ISR
- printk(("uti596_DynamicInterruptHandler: X\n"))
- #endif
- count_rx=0;
-
- /* Do this last, to ensure that the reset is called at the right time. */
- if ( uti596_softc.nic_reset ) {
- uti596_softc.nic_reset = 0;
- sc = rtems_bsdnet_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
- if ( sc != RTEMS_SUCCESSFUL )
- rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
- }
- return;
-}
-
-/***********************************************************************
- * Function: uti596_ioctl
- *
- * Description:
- * driver ioctl function
- * handles SIOCGIFADDR, SIOCSIFADDR, SIOCSIFFLAGS
- *
- ***********************************************************************/
-
-static int uti596_ioctl(
- struct ifnet *ifp,
- u_long command,
- caddr_t data
-)
-{
- uti596_softc_ *sc = ifp->if_softc;
- int error = 0;
-
- #ifdef DBG_IOCTL
- printk(("uti596_ioctl: begins\n", sc->pScp))
- #endif
-
- switch (command) {
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- printk(("SIOCSIFADDR\n"))
- ether_ioctl (ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- printk(("SIOCSIFFLAGS\n"))
- switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
- case IFF_RUNNING:
- printk(("IFF_RUNNING\n"))
- uti596_stop (sc);
- break;
-
- case IFF_UP:
- printk(("IFF_UP\n"))
- uti596_init ( (void *)sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- printk(("IFF_UP and RUNNING\n"))
- uti596_stop (sc);
- uti596_init ( (void *)sc);
- break;
-
- default:
- printk(("default\n"))
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- printk(("show stats\n"))
- uti596_stats (sc);
- break;
-
- /* FIXME: All sorts of multicast commands need to be added here! */
- default:
- printk(("default: EINVAL\n"))
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/***********************************************************************
- * Function: uti596_stats
- *
- * Description:
- * print out the collected data
- *
- * Algorithm:
- * use printf
- *
- ***********************************************************************/
-
-void uti596_stats(
- uti596_softc_ *sc
-)
-{
- printf ("CPU Reports:\n");
- printf (" Tx raw send count:%-8lu", sc->rawsndcnt);
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Tx Interrupts:%-8lu\n", sc->txInterrupts);
- printf (" Rx Packets:%-8u", sc->stats.rx_packets);
- printf (" Tx Attempts:%-u\n", sc->stats.tx_packets);
-
- printf (" Rx Dropped:%-8u", sc->stats.rx_dropped);
- printf (" Rx IP Packets:%-8u", sc->stats.rx_packets);
- printf (" Tx Errors:%-8u\n", sc->stats.tx_errors);
- printf (" Tx aborted:%-8u", sc->stats.tx_aborted_errors);
- printf (" Tx Dropped:%-8u\n", sc->stats.tx_dropped);
- printf (" Tx IP packets:%-8u", sc->stats.tx_packets);
-
- printf (" Collisions Detected:%-8u\n", sc->stats.collisions);
- printf (" Tx Heartbeat Errors:%-8u", sc->stats.tx_heartbeat_errors);
- printf (" Tx Carrier Errors:%-8u\n", sc->stats.tx_carrier_errors);
- printf (" Tx Aborted Errors:%-8u", sc->stats.tx_aborted_errors);
- printf (" Rx Length Errors:%-8u\n", sc->stats.rx_length_errors);
- printf (" Rx Overrun Errors:%-8u", sc->stats.rx_over_errors);
- printf (" Rx Fifo Errors:%-8u\n", sc->stats.rx_fifo_errors);
- printf (" Rx Framing Errors:%-8u", sc->stats.rx_frame_errors);
- printf (" Rx crc errors:%-8u\n", sc->stats.rx_crc_errors);
-
- printf (" TX WAITS: %-8lu\n", sc->txRawWait);
-
- printf (" NIC resets: %-8u\n", sc->stats.nic_reset_count);
-
- printf (" NIC reports\n");
-
- #ifdef DBG_STAT
- uti596_dump_scb();
- #endif
-}
-
-/************************ PACKET DEBUG ROUTINES ************************/
-
-#ifdef DBG_PACKETS
-
-/*
- * dumpQ
- *
- * Dumps frame queues for debugging
- */
-static void dumpQ( void )
-{
- i596_rfd *pRfd;
-
- printk(("savedQ:\n"))
-
- for( pRfd = uti596_softc.pSavedRfdQueue;
- pRfd != I596_NULL;
- pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) {
- printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
- }
-
- printk(("Inbound:\n"))
-
- for( pRfd = uti596_softc.pInboundFrameQueue;
- pRfd != I596_NULL;
- pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) {
- printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
- }
-
- printk(("Last Unk: %p\n", uti596_softc.pLastUnkRFD ))
- printk(("RFA:\n"))
-
- for( pRfd = uti596_softc.pBeginRFA;
- pRfd != I596_NULL;
- pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) {
- printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
- }
-}
-
-/*
- * show_buffers
- *
- * Print out the RFA and frame queues
- */
-static void show_buffers (void)
-{
- i596_rfd *pRfd;
-
- printk(("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
- uti596_softc.scb.command,
- uti596_softc.scb.status,
- uti596_softc.countRFD))
-
- printk(("\nRFA: \n"))
-
- for ( pRfd = uti596_softc.pBeginRFA;
- pRfd != I596_NULL;
- pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) {
- printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
- pRfd, pRfd->stat, pRfd->cmd))
- }
- printk(("\nInbound: \n"))
-
- for ( pRfd = uti596_softc.pInboundFrameQueue;
- pRfd != I596_NULL;
- pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) {
- printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
- pRfd, pRfd->stat, pRfd->cmd))
- }
-
- printk(("\nSaved: \n"))
-
- for ( pRfd = uti596_softc.pSavedRfdQueue;
- pRfd != I596_NULL;
- pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) {
- printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
- pRfd, pRfd->stat, pRfd->cmd))
- }
-
- printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD))
-}
-
-/*
- * show_queues
- *
- * Print out the saved frame queue and the RFA
- */
-static void show_queues(void)
-{
- i596_rfd *pRfd;
-
- printk(("CMD: 0x%x, Status: 0x%x\n",
- uti596_softc.scb.command,
- uti596_softc.scb.status))
- printk(("saved Q\n"))
-
- for ( pRfd = uti596_softc.pSavedRfdQueue;
- pRfd != I596_NULL &&
- pRfd != NULL;
- pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) {
- printk(("0x%p\n", pRfd))
- }
-
- printk(("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue))
-
- printk(("\nRFA:\n"))
-
- for ( pRfd = uti596_softc.pBeginRFA;
- pRfd != I596_NULL &&
- pRfd != NULL;
- pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) {
- printk(("0x%p\n", pRfd))
- }
-
- printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA))
-}
-
-/*
- * print_eth
- *
- * Print the contents of an ethernet packet
- * CANNOT BE CALLED FROM ISR
- */
-static void print_eth(
- unsigned char *add
-)
-{
- int i;
- short int length;
-
- printk (("Packet Location %p\n", add))
- printk (("Dest "))
-
- for (i = 0; i < 6; i++) {
- printk ((" %2.2X", add[i]))
- }
- printk (("\n"))
- printk (("Source"))
-
- for (i = 6; i < 12; i++) {
- printk ((" %2.2X", add[i]))
- }
-
- printk (("\n"))
- printk (("frame type %2.2X%2.2X\n", add[12], add[13]))
-
- if ( add[12] == 0x08 && add[13] == 0x06 ) {
- /* an ARP */
- printk (("Hardware type : %2.2X%2.2X\n", add[14],add[15]))
- printk (("Protocol type : %2.2X%2.2X\n", add[16],add[17]))
- printk (("Hardware size : %2.2X\n", add[18]))
- printk (("Protocol size : %2.2X\n", add[19]))
- printk (("op : %2.2X%2.2X\n", add[20],add[21]))
- printk (("Sender Enet addr: "))
-
- for ( i=0; i< 5 ; i++) {
- printk (("%x:", add[22 + i]))
- }
- printk (("%x\n", add[27]))
- printk (("Sender IP addr: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[28 + i]))
- }
- printk (("%u\n", add[31]))
- printk (("Target Enet addr: "))
-
- for ( i=0; i< 5 ; i++) {
- printk (( "%x:", add[32 + i]))
- }
- printk (("%x\n", add[37]))
- printk (("Target IP addr: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (( "%u.", add[38 + i]))
- }
- printk (("%u\n", add[41]))
- }
-
- if ( add[12] == 0x08 && add[13] == 0x00 ) {
- /* an IP packet */
- printk (("*********************IP HEADER******************\n"))
- printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]))
- printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] )))
- printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
- add[18],add[19], add[20], add[21]))
- printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
- add[22],add[23],add[24],add[25]))
- printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35]))
- printk (("Source IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[26 + i]))
- }
- printk (("%u\n", add[29]))
- printk (("Destination IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[30 + i]))
- }
- printk (("%u\n", add[33]))
- }
-}
-
-/*
- * print_hdr
- *
- * Print the contents of an ethernet packet header
- * CANNOT BE CALLED FROM ISR
- */
-static void print_hdr(
- unsigned char *add
-)
-{
- int i;
-
- printk (("print_hdr: begins\n"))
- printk (("Header Location %p\n", add))
- printk (("Dest "))
-
- for (i = 0; i < 6; i++) {
- printk ((" %2.2X", add[i]))
- }
- printk (("\nSource"))
-
- for (i = 6; i < 12; i++) {
- printk ((" %2.2X", add[i]))
- }
- printk (("\nframe type %2.2X%2.2X\n", add[12], add[13]))
- printk (("print_hdr: completed"))
-}
-
-/*
- * Function: print_pkt
- *
- * Print the contents of an ethernet packet & data
- * CANNOT BE CALLED FROM ISR
- */
-static void print_pkt(
- unsigned char *add
-)
-{
- int i;
- short int length;
-
- printk (("print_pkt: begins"))
- printk (("Data Location %p\n", add))
-
- if ( add[0] == 0x08 && add[1] == 0x06 ) {
- /* an ARP */
- printk (("Hardware type : %2.2X%2.2X\n", add[14],add[15]))
- printk (("Protocol type : %2.2X%2.2X\n", add[16],add[17]))
- printk (("Hardware size : %2.2X\n", add[18]))
- printk (("Protocol size : %2.2X\n", add[19]))
- printk (("op : %2.2X%2.2X\n", add[20],add[21]))
- printk (("Sender Enet addr: "))
-
- for ( i=0; i< 5 ; i++) {
- printk (( "%x:", add[22 + i]))
- }
- printk (("%x\n", add[27]))
- printk (("Sender IP addr: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[28 + i]))
- }
- printk (("%u\n", add[31]))
- printk (("Target Enet addr: "))
-
- for ( i=0; i< 5 ; i++) {
- printk (( "%x:", add[32 + i]))
- }
- printk (("%x\n", add[37]))
- printk (("Target IP addr: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (( "%u.", add[38 + i]))
- }
- printk (("%u\n", add[41]))
- }
-
- if ( add[0] == 0x08 && add[1] == 0x00 ) {
- /* an IP packet */
- printk (("*********************IP HEADER******************\n"))
- printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]))
- printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] )))
- printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
- add[18],add[19], add[20], add[21]))
- printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
- add[22],add[23],add[24],add[25]))
- printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35]))
- printk (("Source IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk(( "%u.", add[26 + i]))
- }
- printk(("%u\n", add[29]))
- printk(("Destination IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk(( "%u.", add[30 + i]))
- }
- printk(("%u\n", add[33]))
- printk(("********************IP Packet Data*******************\n"))
- length -=20;
-
- for ( i=0; i < length ; i++) {
- printk(("0x%2.2x ", add[34+i]))
- }
- printk(("\n"))
- printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]))
- printk(("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]))
- printk(("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]))
- printk(("print_pkt: completed"))
- }
-}
-
-/*
- * print_echo
- *
- * Print the contents of an echo packet
- * CANNOT BE CALLED FROM ISR
- */
-static void print_echo(
- unsigned char *add
-)
-{
- int i;
- short int length;
-
- printk (("print_echo: begins"))
-
- if ( add[12] == 0x08 && add[13] == 0x00 ) {
- /* an IP packet */
- printk (("Packet Location %p\n", add))
- printk (("Dest "))
-
- for (i = 0; i < 6; i++) {
- printk ((" %2.2X", add[i]))
- }
- printk (("\n"))
- printk (("Source"))
-
- for (i = 6; i < 12; i++) {
- printk ((" %2.2X", add[i]))
- }
- printk (("\n"))
- printk (("frame type %2.2X%2.2X\n", add[12], add[13]))
-
- printk (("*********************IP HEADER******************\n"))
- printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]))
- printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] )))
- printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
- add[18],add[19], add[20], add[21]))
- printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
- add[22],add[23],add[24],add[25]))
- printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35]))
- printk (("Source IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[26 + i]))
- }
- printk (("%u\n", add[29]))
- printk (("Destination IP address: "))
-
- for ( i=0; i< 3 ; i++) {
- printk (("%u.", add[30 + i]))
- }
- printk (("%u\n", add[33]))
- printk(("********************IP Packet Data*******************\n"))
- length -=20;
-
- for ( i=0; i < length ; i++) {
- printk(("0x%2.2x ", add[34+i]))
- }
- printk(("\n"))
- printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]))
- printk(("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]))
- printk(("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]))
- printk(("print_echo: completed"))
- }
-}
-
-#endif
diff --git a/c/src/lib/libbsp/m68k/mvme167/network/uti596.h b/c/src/lib/libbsp/m68k/mvme167/network/uti596.h
deleted file mode 100644
index 29e4fed299..0000000000
--- a/c/src/lib/libbsp/m68k/mvme167/network/uti596.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/* uti596.h: Contains the defines and structures used by the uti596 driver */
-
-/*
- * EII: March 11: Created v. 0.0
- */
-
-#ifndef UTI596_H
-#define UTI596_H
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-/* Ethernet statistics */
-
-struct enet_statistics{
- int rx_packets; /* total packets received */
- int tx_packets; /* total packets transmitted */
- int rx_errors; /* bad packets received */
- int tx_errors; /* packet transmit problems */
- int rx_dropped; /* no space in buffers */
- int tx_dropped;
- int tx_retries_exceeded; /* excessive retries */
- int multicast; /* multicast packets received */
- int collisions;
-
- /* detailed rx_errors: */
- int rx_length_errors;
- int rx_over_errors; /* receiver ring buff overflow */
- int rx_crc_errors; /* recved pkt with crc error */
- int rx_frame_errors; /* recv'd frame alignment error */
- int rx_fifo_errors; /* recv'r fifo overrun */
- int rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- int tx_aborted_errors;
- int tx_carrier_errors;
- int tx_fifo_errors;
- int tx_heartbeat_errors;
- int tx_window_errors;
-
- /* NIC reset errors */
- int nic_reset_count; /* The number of times uti596reset() has been called. */
-};
-
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-#define CMD_FLEX 0x0008 /* Enable flexible memory model */
-
-#define SCB_STAT_CX 0x8000 /* Cmd completes with 'I' bit set */
-#define SCB_STAT_FR 0x4000 /* Frame Received */
-#define SCB_STAT_CNA 0x2000 /* Cmd unit Not Active */
-#define SCB_STAT_RNR 0x1000 /* Receiver Not Ready */
-
-#define SCB_CUS_SUSPENDED 0x0100
-#define SCB_CUS_ACTIVE 0x0200
-
-#define STAT_C 0x8000 /* Set to 1 after execution */
-#define STAT_B 0x4000 /* 1 : Cmd being executed, 0 : Cmd done. */
-#define STAT_OK 0x2000 /* 1: Command executed ok 0 : Error */
-#define STAT_A 0x1000 /* command has been aborted */
-
-#define STAT_S11 0x0800
-#define STAT_S10 0x0400
-#define STAT_S9 0x0200
-#define STAT_S8 0x0100
-#define STAT_S7 0x0080
-#define STAT_S6 0x0040
-#define STAT_S5 0x0020
-#define STAT_MAX_COLLS 0x000F
-
-#define RBD_STAT_P 0x4000 /* prefetch */
-#define RBD_STAT_F 0x4000 /* used */
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define CUC_ABORT 0x0400
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-#define RX_ABORT 0x0040
-
-#define RU_SUSPENDED 0x0010
-#define RU_NO_RESOURCES 0x0020
-#define RU_READY 0x0040
-
-#define I596_NULL ( ( void * ) 0xffffffff)
-#define UTI_596_END_OF_FRAME 0x8000
-
-struct i596_tbd; /* necessary forward declaration */
-
-enum commands {
- CmdNOp = 0,
- CmdSASetup = 1,
- CmdConfigure = 2,
- CmdMulticastList = 3,
- CmdTx = 4,
- CmdTDR = 5,
- CmdDump = 6,
- CmdDiagnose = 7
-};
-
-/*
- * 82596 Dump Command Result
- */
-typedef volatile struct i596_dump_result {
- unsigned char bf;
- unsigned char config_bytes[11];
- unsigned char reserved1[2];
- unsigned char ia_bytes[6];
- unsigned short last_tx_status;
- unsigned short tx_crc_byte01;
- unsigned short tx_crc_byte23;
- unsigned short rx_crc_byte01;
- unsigned short rx_crc_byte23;
- unsigned short rx_temp_mem01;
- unsigned short rx_temp_mem23;
- unsigned short rx_temp_mem45;
- unsigned short last_rx_status;
- unsigned short hash_reg01;
- unsigned short hash_reg23;
- unsigned short hash_reg45;
- unsigned short hash_reg67;
- unsigned short slot_time_counter;
- unsigned short wait_time_counter;
- unsigned short rx_frame_length;
- unsigned long reserved2;
- unsigned long cb_in3;
- unsigned long cb_in2;
- unsigned long cb_in1;
- unsigned long la_cb_addr;
- unsigned long rdb_pointer;
- unsigned long int_memory;
- unsigned long rfd_size;
- unsigned long tbd_pointer;
- unsigned long base_addr;
- unsigned long ru_temp_reg;
- unsigned long tcb_count;
- unsigned long next_rb_size;
- unsigned long next_rb_addr;
- unsigned long curr_rb_size;
- unsigned long la_rbd_addr;
- unsigned long next_rbd_addr;
- unsigned long curr_rbd_addr;
- unsigned long curr_rb_count;
- unsigned long next_fd_addr;
- unsigned long curr_fd_add;
- unsigned long temp_cu_reg;
- unsigned long next_tb_count;
- unsigned long buffer_addr;
- unsigned long la_tbd_addr;
- unsigned long next_tbd_addr;
- unsigned long cb_command;
- unsigned long next_cb_addr;
- unsigned long curr_cb_addr;
- unsigned long scb_cmd_word;
- unsigned long scb_pointer;
- unsigned long cb_stat_word;
- unsigned long mm_lfsr;
- unsigned char micro_machine_bit_array[28];
- unsigned char cu_port[16];
- unsigned long mm_alu;
- unsigned long reserved3;
- unsigned long mm_temp_a_rr;
- unsigned long mm_temp_a;
- unsigned long tx_dma_b_cnt;
- unsigned long mm_input_port_addr_reg;
- unsigned long tx_dma_addr;
- unsigned long mm_port_reg1;
- unsigned long rx_dma_b_cnt;
- unsigned long mm_port_reg2;
- unsigned long rx_dma_addr;
- unsigned long reserved4;
- unsigned long bus_t_timers;
- unsigned long diu_cntrl_reg;
- unsigned long reserved5;
- unsigned long sysbus;
- unsigned long biu_cntrl_reg;
- unsigned long mm_disp_reg;
- unsigned long mm_status_reg;
- unsigned short dump_status;
-} i596_dump_result;
-
-typedef volatile struct i596_selftest {
- unsigned long rom_signature;
- unsigned long results;
-} i596_selftest;
-
-/*
- * Action commands
- * (big endian, linear mode)
- */
-typedef volatile struct i596_cmd {
- unsigned short status;
- unsigned short command;
- volatile struct i596_cmd *next;
-} i596_cmd;
-
-typedef volatile struct i596_nop {
- i596_cmd cmd;
-} i596_nop;
-
-typedef volatile struct i596_set_add {
- i596_cmd cmd;
- char data[8];
-} i596_set_add;
-
-typedef volatile struct i596_configure {
- i596_cmd cmd;
- char data[16];
-} i596_configure;
-
-typedef volatile struct i596_tx {
- i596_cmd cmd;
- volatile struct i596_tbd *pTbd;
- unsigned short count;
- unsigned short pad;
- char data[6];
- unsigned short length;
-} i596_tx;
-
-typedef volatile struct i596_tdr {
- i596_cmd cmd;
- unsigned long data;
-} i596_tdr;
-
-typedef volatile struct i596_dump {
- i596_cmd cmd;
- char *pData;
-} i596_dump;
-
-/*
- * Transmit buffer descriptor
- */
-typedef volatile struct i596_tbd {
- unsigned short size;
- unsigned short pad;
- volatile struct i596_tbd *next;
- char *data;
-} i596_tbd;
-
-/*
- * Receive buffer descriptor
- * (flexible memory structure)
- */
-typedef volatile struct i596_rbd {
- unsigned short count;
- unsigned short offset;
- volatile struct i596_rbd *next;
- char *data;
- unsigned short size;
- unsigned short pad;
-} i596_rbd;
-
-/*
- * Receive Frame Descriptor
- */
-typedef volatile struct i596_rfd {
- unsigned short stat;
- unsigned short cmd;
- volatile struct i596_rfd *next;
- i596_rbd *pRbd;
- unsigned short count;
- unsigned short size;
- char data [1532];
-} i596_rfd;
-
-/*
- * System Control Block
- */
-typedef volatile struct i596_scb {
- unsigned short status;
- unsigned short command;
- unsigned long cmd_pointer;
- unsigned long rfd_pointer;
- unsigned long crc_err;
- unsigned long align_err;
- unsigned long resource_err;
- unsigned long over_err;
- unsigned long rcvdt_err;
- unsigned long short_err;
- unsigned short t_off;
- unsigned short t_on;
- i596_cmd *pCmd;
- i596_rfd *pRfd;
-} i596_scb;
-
-/*
- * Intermediate System Configuration Pointer
- */
-typedef volatile struct i596_iscp {
- uint8_t null1; /* Always zero */
- uint8_t busy; /* Busy byte */
- unsigned short scb_offset; /* Not used in linear mode */
- unsigned long scb_pointer; /* Swapped pointer to scb */
- i596_scb *scb; /* Real pointer to scb */
-} i596_iscp;
-
-/*
- * System Configuration Pointer
- */
-typedef volatile struct i596_scp {
- unsigned long sysbus; /* Only low 8 bits are used */
- unsigned long pad; /* Must be zero */
- unsigned long iscp_pointer; /* Swapped pointer to iscp */
- i596_iscp *iscp; /* Real pointer to iscp */
-} i596_scp;
-
-/*
- * Device Dependent Data Structure
- */
-typedef volatile struct uti596_softc {
- struct arpcom arpcom;
- i596_scp *pScp; /* Block aligned on 16 byte boundary */
- i596_scp *base_scp; /* Unaligned block. Need for free() */
- i596_iscp iscp;
- i596_scb scb;
- i596_set_add set_add;
- i596_configure set_conf;
- i596_tdr tdr;
- i596_nop nop;
- i596_tx *pTxCmd;
- i596_tbd *pTbd;
-
- i596_rfd *pBeginRFA;
- i596_rfd *pEndRFA;
- i596_rfd *pLastUnkRFD;
- i596_rbd *pLastUnkRBD;
- i596_rfd *pEndSavedQueue;
- i596_cmd *pCmdHead;
- i596_cmd *pCmdTail; /* unneeded, as chaining not used, but implemented */
-
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
- rtems_id resetDaemonTid;
-
- struct enet_statistics stats;
- int started;
- unsigned long rxInterrupts;
- unsigned long txInterrupts;
- volatile int cmdOk;
- unsigned short * pCurrent_command_status;
- int resetDone;
- unsigned long txRawWait;
- i596_rfd *pInboundFrameQueue;
- short int rxBdCount;
- short int txBdCount;
- short int countRFD;
- short int savedCount;
- i596_rfd *pSavedRfdQueue;
- rtems_name semaphore_name;
- rtems_id semaphore_id;
- char zeroes[64];
- unsigned long rawsndcnt;
- int nic_reset; /* flag for requesting that ISR issue a reset quest */
-} uti596_softc_;
-
-#endif /* UTI596_H */
diff --git a/c/src/lib/libbsp/m68k/uC5282/Makefile.am b/c/src/lib/libbsp/m68k/uC5282/Makefile.am
index 0838c41756..5949cb8209 100644
--- a/c/src/lib/libbsp/m68k/uC5282/Makefile.am
+++ b/c/src/lib/libbsp/m68k/uC5282/Makefile.am
@@ -34,7 +34,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/uC5282/console/console.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/uC5282/btimer/btimer.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/uC5282/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache-mcf5282.c
diff --git a/c/src/lib/libbsp/m68k/uC5282/network/network.c b/c/src/lib/libbsp/m68k/uC5282/network/network.c
deleted file mode 100644
index b8afa0b968..0000000000
--- a/c/src/lib/libbsp/m68k/uC5282/network/network.c
+++ /dev/null
@@ -1,1013 +0,0 @@
-/*
- * RTEMS driver for MCF5282 Fast Ethernet Controller
- *
- * Author: W. Eric Norum <norume@aps.anl.gov>
- *
- * COPYRIGHT (c) 2005.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <bsp.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 1
-
-#define FEC_INTC0_TX_VECTOR (64+23)
-#define FEC_INTC0_RX_VECTOR (64+27)
-#define MII_VECTOR (64+7) /* IRQ7* pin connected to external transceiver */
-#define MII_EPPAR MCF5282_EPORT_EPPAR_EPPA7_LEVEL
-#define MII_EPDDR MCF5282_EPORT_EPDDR_EPDD7
-#define MII_EPIER MCF5282_EPORT_EPIER_EPIE7
-#define MII_EPPDR MCF5282_EPORT_EPPDR_EPPD7
-
-/*
- * 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 three or more buffer descriptors.
- */
-#define RX_BUF_COUNT 32
-#define TX_BUF_COUNT 20
-#define TX_BD_PER_BUF 3
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- * This must *not* be the same event used by the TCP/IP task synchronization.
- */
-#define TX_INTERRUPT_EVENT RTEMS_EVENT_1
-#define RX_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 plus CRC (1518).
- * Round off to nearest multiple of RBUF_ALIGN.
- */
-#define MAX_MTU_SIZE 1518
-#define RBUF_ALIGN 4
-#define RBUF_SIZE ((MAX_MTU_SIZE + RBUF_ALIGN) & ~RBUF_ALIGN)
-
-#if (MCLBYTES < RBUF_SIZE)
- #error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/*
- * Per-device data
- */
-struct mcf5282_enet_struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
- mcf5282BufferDescriptor_t *rxBdBase;
- mcf5282BufferDescriptor_t *txBdBase;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long txInterrupts;
- unsigned long miiInterrupts;
- unsigned long txRawWait;
- unsigned long txRealign;
- unsigned long txRealignDrop;
-
- /*
- * Link parameters
- */
- enum { link_auto, link_100Full, link_10Half } link;
- uint16_t mii_cr;
- uint16_t mii_sr2;
-};
-static struct mcf5282_enet_struct enet_driver[NIFACES];
-
-/*
- * Read MII register
- * Busy-waits, but transfer time should be short!
- */
-static int
-getMII(int phyNumber, int regNumber)
-{
- MCF5282_FEC_MMFR = (0x1 << 30) |
- (0x2 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16);
- while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0);
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII;
- return MCF5282_FEC_MMFR & 0xFFFF;
-}
-
-/*
- * Write MII register
- * Busy-waits, but transfer time should be short!
- */
-static void
-setMII(int phyNumber, int regNumber, int value)
-{
- MCF5282_FEC_MMFR = (0x1 << 30) |
- (0x1 << 28) |
- (phyNumber << 23) |
- (regNumber << 18) |
- (0x2 << 16) |
- (value & 0xFFFF);
- while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0);
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII;
-}
-
-static rtems_isr
-mcf5282_fec_rx_interrupt_handler( rtems_vector_number v )
-{
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
- MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_RXF;
- enet_driver[0].rxInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5282_fec_tx_interrupt_handler( rtems_vector_number v )
-{
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
- MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF;
- enet_driver[0].txInterrupts++;
- rtems_bsdnet_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5282_mii_interrupt_handler( rtems_vector_number v )
-{
- uint16 sr2;
-
- enet_driver[0].miiInterrupts++;
- getMII(1, 19); /* Read and clear interrupt status bits */
- enet_driver[0].mii_sr2 = sr2 = getMII(1, 17);
- if (((sr2 & 0x200) != 0)
- && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) == 0))
- MCF5282_FEC_TCR |= MCF5282_FEC_TCR_FDEN;
- else if (((sr2 & 0x200) == 0)
- && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) != 0))
- MCF5282_FEC_TCR &= ~MCF5282_FEC_TCR_FDEN;
-}
-
-/*
- * Allocate buffer descriptors from (non-cached) on-chip static RAM
- * Ensure 128-bit (16-byte) alignment
- * Allow some space at the beginning for other diagnostic counters
- */
-static mcf5282BufferDescriptor_t *
-mcf5282_bd_allocate(unsigned int count)
-{
- static mcf5282BufferDescriptor_t *bdp = __SRAMBASE.fec_descriptors;
- mcf5282BufferDescriptor_t *p = bdp;
-
- bdp += count;
- if ((int)bdp & 0xF)
- bdp = (mcf5282BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
- return p;
-}
-
-static void
-mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc)
-{
- int i;
- const unsigned char *hwaddr;
- rtems_status_code status;
- rtems_isr_entry old_handler;
- uint32_t clock_speed = bsp_get_CPU_clock_speed();
-
- /*
- * Issue reset to FEC
- */
- MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET;
- rtems_task_wake_after(2);
- MCF5282_FEC_ECR = 0;
-
- /*
- * Configuration of I/O ports is done outside of this function
- */
-#if 0
- imm->gpio.pbcnt |= MCF5282_GPIO_PBCNT_SET_FEC; /* Set up port b FEC pins */
-#endif
-
- /*
- * Set our physical address
- */
- hwaddr = sc->arpcom.ac_enaddr;
- MCF5282_FEC_PALR = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
- (hwaddr[2] << 8) | (hwaddr[3] << 0);
- MCF5282_FEC_PAUR = (hwaddr[4] << 24) | (hwaddr[5] << 16);
-
-
- /*
- * Clear the hash table
- */
- MCF5282_FEC_GAUR = 0;
- MCF5282_FEC_GALR = 0;
-
- /*
- * Set up receive buffer size
- */
- MCF5282_FEC_EMRBR = 1520; /* Standard Ethernet */
-
- /*
- * Allocate mbuf pointers
- */
- sc->rxMbuf = malloc(sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
- sc->txMbuf = malloc(sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
- if (!sc->rxMbuf || !sc->txMbuf)
- rtems_panic("No memory for mbuf pointers");
-
- /*
- * Set receiver and transmitter buffer descriptor bases
- */
- sc->rxBdBase = mcf5282_bd_allocate(sc->rxBdCount);
- sc->txBdBase = mcf5282_bd_allocate(sc->txBdCount);
- MCF5282_FEC_ERDSR = (int)sc->rxBdBase;
- MCF5282_FEC_ETDSR = (int)sc->txBdBase;
-
- /*
- * Set up Receive Control Register:
- * Not promiscuous
- * MII mode
- * Full duplex
- * No loopback
- */
- MCF5282_FEC_RCR = MCF5282_FEC_RCR_MAX_FL(MAX_MTU_SIZE) |
- MCF5282_FEC_RCR_MII_MODE;
-
- /*
- * Set up Transmit Control Register:
- * Full or half duplex
- * No heartbeat
- */
- if (sc->link == link_10Half)
- MCF5282_FEC_TCR = 0;
- else
- MCF5282_FEC_TCR = MCF5282_FEC_TCR_FDEN;
-
- /*
- * Initialize statistic counters
- */
- MCF5282_FEC_MIBC = MCF5282_FEC_MIBC_MIB_DISABLE;
- {
- vuint32 *vuip = &MCF5282_FEC_RMON_T_DROP;
- while (vuip <= &MCF5282_FEC_IEEE_R_OCTETS_OK)
- *vuip++ = 0;
- }
- MCF5282_FEC_MIBC = 0;
-
- /*
- * Set MII speed to <= 2.5 MHz
- */
- i = (clock_speed + 5000000 - 1) / 5000000;
- MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(i);
-
- /*
- * Set PHYS
- * LED1 receive status, LED2 link status, LEDs stretched
- * Advertise 100 Mb/s, full-duplex, IEEE-802.3
- * Turn off auto-negotiate
- * Clear status
- */
- setMII(1, 20, 0x24F2);
- setMII(1, 4, 0x0181);
- setMII(1, 0, 0x0);
- rtems_task_wake_after(2);
- sc->mii_sr2 = getMII(1, 17);
- switch (sc->link) {
- case link_auto:
- /*
- * Enable speed-change, duplex-change and link-status-change interrupts
- * Enable auto-negotiate (start at 100/FULL)
- */
- setMII(1, 18, 0x0072);
- setMII(1, 0, 0x3100);
- break;
-
- case link_10Half:
- /*
- * Force 10/HALF
- */
- setMII(1, 0, 0x0);
- break;
-
- case link_100Full:
- /*
- * Force 100/FULL
- */
- setMII(1, 0, 0x2100);
- break;
- }
- sc->mii_cr = getMII(1, 0);
-
- /*
- * Set up receive buffer descriptors
- */
- for (i = 0 ; i < sc->rxBdCount ; i++)
- (sc->rxBdBase + i)->status = 0;
-
- /*
- * Set up transmit buffer descriptors
- */
- for (i = 0 ; i < sc->txBdCount ; i++) {
- sc->txBdBase[i].status = 0;
- sc->txMbuf[i] = NULL;
- }
- sc->txBdHead = sc->txBdTail = 0;
- sc->txBdActiveCount = 0;
-
- /*
- * Set up interrupts
- */
- status = rtems_interrupt_catch( mcf5282_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler );
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC TX interrupt handler: %s\n",
- rtems_status_text(status));
- bsp_allocate_interrupt(FEC_IRQ_LEVEL, FEC_IRQ_TX_PRIORITY);
- MCF5282_INTC0_ICR23 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5282_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY);
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT23 | MCF5282_INTC_IMRL_MASKALL);
-
- status = rtems_interrupt_catch(mcf5282_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC RX interrupt handler: %s\n",
- rtems_status_text(status));
- bsp_allocate_interrupt(FEC_IRQ_LEVEL, FEC_IRQ_RX_PRIORITY);
- MCF5282_INTC0_ICR27 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) |
- MCF5282_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY);
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT27 | MCF5282_INTC_IMRL_MASKALL);
-
- status = rtems_interrupt_catch(mcf5282_mii_interrupt_handler, MII_VECTOR, &old_handler);
- if (status != RTEMS_SUCCESSFUL)
- rtems_panic ("Can't attach MCF5282 FEC MII interrupt handler: %s\n",
- rtems_status_text(status));
- MCF5282_EPORT_EPPAR &= ~MII_EPPAR;
- MCF5282_EPORT_EPDDR &= ~MII_EPDDR;
- MCF5282_EPORT_EPIER |= MII_EPIER;
- MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT7 | MCF5282_INTC_IMRL_MASKALL);
-}
-
-/*
- * Soak up buffer descriptors that have been sent.
- */
-static void
-fec_retire_tx_bd(volatile struct mcf5282_enet_struct *sc )
-{
- struct mbuf *m, *n;
- uint16_t status;
-
- while ((sc->txBdActiveCount != 0)
- && (((status = sc->txBdBase[sc->txBdTail].status) & MCF5282_FEC_TxBD_R) == 0)) {
- if ((status & MCF5282_FEC_TxBD_TO1) == 0) {
- m = sc->txMbuf[sc->txBdTail];
- MFREE(m, n);
- }
- if (++sc->txBdTail == sc->txBdCount)
- sc->txBdTail = 0;
- sc->txBdActiveCount--;
- }
-}
-
-static void
-fec_rxDaemon (void *arg)
-{
- volatile struct mcf5282_enet_struct *sc = (volatile struct mcf5282_enet_struct *)arg;
- struct ifnet *ifp = (struct ifnet* )&sc->arpcom.ac_if;
- struct mbuf *m;
- uint16_t status;
- volatile mcf5282BufferDescriptor_t *rxBd;
- int rxBdIndex;
-
- /*
- * Allocate space for incoming packets and start reception
- */
- for (rxBdIndex = 0 ; ;) {
- rxBd = sc->rxBdBase + rxBdIndex;
- MGETHDR(m, M_WAIT, MT_DATA);
- MCLGET(m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- sc->rxMbuf[rxBdIndex] = m;
- rxBd->buffer = mtod(m, void *);
- rxBd->status = MCF5282_FEC_RxBD_E;
- if (++rxBdIndex == sc->rxBdCount) {
- rxBd->status |= MCF5282_FEC_RxBD_W;
- break;
- }
- }
-
- /*
- * Input packet handling loop
- */
- MCF5282_FEC_RDAR = 0;
-
- rxBdIndex = 0;
- for (;;) {
- rxBd = sc->rxBdBase + rxBdIndex;
-
- /*
- * Wait for packet if there's not one ready
- */
- if ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
- /*
- * Clear old events.
- */
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
-
- /*
- * Wait for packet to arrive.
- * Check the buffer descriptor before waiting for the event.
- * This catches the case when a packet arrives between the
- * `if' above, and the clearing of the RXF bit in the EIR.
- */
- while ((status = rxBd->status) & MCF5282_FEC_RxBD_E) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_RXF;
- rtems_interrupt_enable(level);
- rtems_bsdnet_event_receive (RX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- }
-
- /*
- * Check that packet is valid
- */
- if (status & MCF5282_FEC_RxBD_L) {
- /*
- * Pass the packet up the chain.
- * FIXME: Packet filtering hook could be done here.
- */
- struct ether_header *eh;
- int len = rxBd->length - sizeof(uint32_t);
-
- m = sc->rxMbuf[rxBdIndex];
-#ifdef RTEMS_MCF5282_BSP_ENABLE_DATA_CACHE
- /*
- * Invalidate the cache. The cache is so small that it's
- * reasonable to simply invalidate the whole thing.
- */
- rtems_cache_invalidate_entire_data();
-#endif
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input(ifp, eh, 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 *);
- }
-
- /*
- * Reenable the buffer descriptor
- */
- rxBd->status = (status & MCF5282_FEC_RxBD_W) | MCF5282_FEC_RxBD_E;
- MCF5282_FEC_RDAR = 0;
-
- /*
- * Move to next buffer descriptor
- */
- if (++rxBdIndex == sc->rxBdCount)
- rxBdIndex = 0;
- }
-}
-
-static void
-fec_sendpacket(struct ifnet *ifp, struct mbuf *m)
-{
- struct mcf5282_enet_struct *sc = ifp->if_softc;
- volatile mcf5282BufferDescriptor_t *firstTxBd, *txBd;
- uint16_t status;
- int nAdded;
-
- /*
- * Free up buffer descriptors
- */
- fec_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;
- firstTxBd = sc->txBdBase + sc->txBdHead;
-
- while (m != NULL) {
- /*
- * Wait for buffer descriptor to become available
- */
- if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- /*
- * Clear old events.
- */
- MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
-
- /*
- * Wait for buffer descriptor to become available.
- * Check for buffer descriptors before waiting for the event.
- * This catches the case when a buffer became available between
- * the `if' above, and the clearing of the TXF bit in the EIR.
- */
- fec_retire_tx_bd(sc);
- while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
- rtems_event_set events;
- int level;
-
- rtems_interrupt_disable(level);
- MCF5282_FEC_EIMR |= MCF5282_FEC_EIMR_TXF;
- rtems_interrupt_enable(level);
- sc->txRawWait++;
- rtems_bsdnet_event_receive(TX_INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- fec_retire_tx_bd(sc);
- }
- }
-
- /*
- * Don't set the READY flag on the first fragment
- * until the whole packet has been readied.
- */
- status = nAdded ? MCF5282_FEC_TxBD_R : 0;
-
- /*
- * The IP fragmentation routine in ip_output
- * can produce fragments with zero length.
- */
- txBd = sc->txBdBase + sc->txBdHead;
- if (m->m_len) {
- char *p = mtod(m, char *);
- int offset = (int)p & 0x3;
- if (offset == 0) {
- txBd->buffer = p;
- txBd->length = m->m_len;
- sc->txMbuf[sc->txBdHead] = m;
- m = m->m_next;
- }
- else {
- /*
- * Stupid FEC can't handle misaligned data!
- * Move offending bytes to a local buffer.
- * Use buffer descriptor TO1 bit to indicate this.
- */
- int nmove = 4 - offset;
- char *d = (char *)&sc->txMbuf[sc->txBdHead];
- status |= MCF5282_FEC_TxBD_TO1;
- sc->txRealign++;
- if (nmove > m->m_len)
- nmove = m->m_len;
- m->m_data += nmove;
- m->m_len -= nmove;
- txBd->buffer = d;
- txBd->length = nmove;
- while (nmove--)
- *d++ = *p++;
- if (m->m_len == 0) {
- struct mbuf *n;
- sc->txRealignDrop++;
- MFREE(m, n);
- m = n;
- }
- }
- nAdded++;
- if (++sc->txBdHead == sc->txBdCount) {
- status |= MCF5282_FEC_TxBD_W;
- sc->txBdHead = 0;
- }
- txBd->status = status;
- }
- else {
- /*
- * Toss empty mbufs.
- */
- struct mbuf *n;
- MFREE(m, n);
- m = n;
- }
- }
- if (nAdded) {
- txBd->status = status | MCF5282_FEC_TxBD_R
- | MCF5282_FEC_TxBD_L
- | MCF5282_FEC_TxBD_TC;
- if (nAdded > 1)
- firstTxBd->status |= MCF5282_FEC_TxBD_R;
- MCF5282_FEC_TDAR = 0;
- sc->txBdActiveCount += nAdded;
- }
-}
-
-void
-fec_txDaemon(void *arg)
-{
- struct mcf5282_enet_struct *sc = (struct mcf5282_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;
- }
-}
-
-
-/*
- * Send packet (caller provides header).
- */
-static void
-mcf5282_enet_start(struct ifnet *ifp)
-{
- struct mcf5282_enet_struct *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-static void
-fec_init(void *arg)
-{
- struct mcf5282_enet_struct *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0) {
- /*
- * Set up hardware
- */
- mcf5282_fec_initialize_hardware(sc);
-
- /*
- * Start driver tasks
- */
- sc->txDaemonTid = rtems_bsdnet_newproc("FECtx", 4096, fec_txDaemon, sc);
- sc->rxDaemonTid = rtems_bsdnet_newproc("FECrx", 4096, fec_rxDaemon, sc);
- }
-
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- MCF5282_FEC_RCR |= MCF5282_FEC_RCR_PROM;
- else
- MCF5282_FEC_RCR &= ~MCF5282_FEC_RCR_PROM;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- MCF5282_FEC_ECR = MCF5282_FEC_ECR_ETHER_EN;
-}
-
-
-static void
-fec_stop(struct mcf5282_enet_struct *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Shut down receiver and transmitter
- */
- MCF5282_FEC_ECR = 0x0;
-}
-
-/*
- * Show interface statistics
- */
-static void
-enet_stats(struct mcf5282_enet_struct *sc)
-{
- printf(" Rx Interrupts:%-10lu", sc->rxInterrupts);
- printf("Rx Packet Count:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_PACKETS);
- printf(" Rx Broadcast:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_BC_PKT);
- printf(" Rx Multicast:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_MC_PKT);
- printf("CRC/Align error:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_CRC_ALIGN);
- printf(" Rx Undersize:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_UNDERSIZE);
- printf(" Rx Oversize:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_OVERSIZE);
- printf(" Rx Fragment:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_FRAG);
- printf(" Rx Jabber:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_JAB);
- printf(" Rx 64:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P64);
- printf(" Rx 65-127:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P65T0127);
- printf(" Rx 128-255:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_P128TO255);
- printf(" Rx 256-511:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P256TO511);
- printf(" Rx 511-1023:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_P512TO1023);
- printf(" Rx 1024-2047:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_R_P1024TO2047);
- printf(" Rx >=2048:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_GTE2048);
- printf(" Rx Octets:%-10lu", (uint32_t) MCF5282_FEC_RMON_R_OCTETS);
- printf(" Rx Dropped:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_DROP);
- printf(" Rx frame OK:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_FRAME_OK);
- printf(" Rx CRC error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_CRC);
- printf(" Rx Align error:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_ALIGN);
- printf(" FIFO Overflow:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_MACERR);
- printf("Rx Pause Frames:%-10lu", (uint32_t) MCF5282_FEC_IEEE_R_FDXFC);
- printf(" Rx Octets OK:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_R_OCTETS_OK);
- printf(" Tx Interrupts:%-10lu", sc->txInterrupts);
- printf("Tx Output Waits:%-10lu", sc->txRawWait);
- printf("Tx mbuf realign:%-10lu\n", sc->txRealign);
- printf("Tx realign drop:%-10lu", sc->txRealignDrop);
- printf(" Tx Unaccounted:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_DROP);
- printf("Tx Packet Count:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_PACKETS);
- printf(" Tx Broadcast:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_BC_PKT);
- printf(" Tx Multicast:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_MC_PKT);
- printf("CRC/Align error:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_CRC_ALIGN);
- printf(" Tx Undersize:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_UNDERSIZE);
- printf(" Tx Oversize:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_OVERSIZE);
- printf(" Tx Fragment:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_FRAG);
- printf(" Tx Jabber:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_JAB);
- printf(" Tx Collisions:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_COL);
- printf(" Tx 64:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P64);
- printf(" Tx 65-127:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P65TO127);
- printf(" Tx 128-255:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P128TO255);
- printf(" Tx 256-511:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P256TO511);
- printf(" Tx 511-1023:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P512TO1023);
- printf(" Tx 1024-2047:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_P1024TO2047);
- printf(" Tx >=2048:%-10lu\n", (uint32_t) MCF5282_FEC_RMON_T_P_GTE2048);
- printf(" Tx Octets:%-10lu", (uint32_t) MCF5282_FEC_RMON_T_OCTETS);
- printf(" Tx Dropped:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_DROP);
- printf(" Tx Frame OK:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_FRAME_OK);
- printf(" Tx 1 Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_1COL);
- printf("Tx >1 Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_MCOL);
- printf(" Tx Deferred:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_DEF);
- printf(" Late Collision:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_LCOL);
- printf(" Excessive Coll:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_EXCOL);
- printf(" FIFO Underrun:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_MACERR);
- printf(" Carrier Error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_CSERR);
- printf(" Tx SQE Error:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_SQE);
- printf("Tx Pause Frames:%-10lu\n", (uint32_t) MCF5282_FEC_IEEE_T_FDXFC);
- printf(" Tx Octets OK:%-10lu", (uint32_t) MCF5282_FEC_IEEE_T_OCTETS_OK);
- printf(" MII interrupts:%-10lu\n", sc->miiInterrupts);
- if ((sc->mii_sr2 & 0x400) == 0) {
- printf("LINK DOWN!\n");
- }
- else {
- int speed;
- int full;
- int fixed;
- if (sc->mii_cr & 0x1000) {
- fixed = 0;
- speed = sc->mii_sr2 & 0x4000 ? 100 : 10;
- full = sc->mii_sr2 & 0x200 ? 1 : 0;
- }
- else {
- fixed = 1;
- speed = sc->mii_cr & 0x2000 ? 100 : 10;
- full = sc->mii_cr & 0x100 ? 1 : 0;
- }
- printf("Link %s %d Mb/s, %s-duplex.\n",
- fixed ? "fixed" : "auto-negotiate",
- speed,
- full ? "full" : "half");
- }
- printf(" EIR:%8.8lx ", (uint32_t) MCF5282_FEC_EIR);
- printf("EIMR:%8.8lx ", (uint32_t) MCF5282_FEC_EIMR);
- printf("RDAR:%8.8lx ", (uint32_t) MCF5282_FEC_RDAR);
- printf("TDAR:%8.8lx\n", (uint32_t) MCF5282_FEC_TDAR);
- printf(" ECR:%8.8lx ", (uint32_t) MCF5282_FEC_ECR);
- printf(" RCR:%8.8lx ", (uint32_t) MCF5282_FEC_RCR);
- printf(" TCR:%8.8lx\n", (uint32_t) MCF5282_FEC_TCR);
- printf("FRBR:%8.8lx ", (uint32_t) MCF5282_FEC_FRBR);
- printf("FRSR:%8.8lx\n", (uint32_t) MCF5282_FEC_FRSR);
- if (sc->txBdActiveCount != 0) {
- int i, n;
- /*
- * Yes, there are races here with adding and retiring descriptors,
- * but this diagnostic is more for when things have backed up.
- */
- printf("Transmit Buffer Descriptors (Tail %d, Head %d, Unretired %d):\n",
- sc->txBdTail,
- sc->txBdHead,
- sc->txBdActiveCount);
- i = sc->txBdTail;
- for (n = 0 ; n < sc->txBdCount ; n++) {
- if ((sc->txBdBase[i].status & MCF5282_FEC_TxBD_R) != 0)
- printf(" %3d: status:%4.4x length:%-4d buffer:%p\n",
- i,
- sc->txBdBase[i].status,
- sc->txBdBase[i].length,
- sc->txBdBase[i].buffer);
- if (++i == sc->txBdCount)
- i = 0;
- }
- }
-}
-
-static int
-fec_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct mcf5282_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;
-}
-
-int
-rtems_fec_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching )
-{
- struct mcf5282_enet_struct *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
- const unsigned char *hwaddr;
- const char *env;
-
- /*
- * 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 FEC 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) {
- hwaddr = config->hardware_address;
- } else if ((hwaddr = bsp_gethwaddr(unitNumber - 1)) == NULL) {
- /* Locally-administered address */
- static const unsigned char defaultAddress[ETHER_ADDR_LEN] = {
- 0x06, 'R', 'T', 'E', 'M', 'S'};
- printf ("WARNING -- No %s%d Ethernet address specified "
- "-- Using default address.\n", unitName, unitNumber);
- hwaddr = defaultAddress;
- }
- printf("%s%d: Ethernet address: %02x:%02x:%02x:%02x:%02x:%02x\n",
- unitName, unitNumber,
- hwaddr[0], hwaddr[1], hwaddr[2],
- hwaddr[3], hwaddr[4], hwaddr[5]);
- memcpy(sc->arpcom.ac_enaddr, hwaddr, ETHER_ADDR_LEN);
-
- 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 = mcf5282_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;
-
- /*
- * Check for environment overrides
- */
- if (((env = bsp_getbenv("IPADDR0_100FULL")) != NULL)
- && ((*env == 'y') || (*env == 'Y')))
- sc->link = link_100Full;
- else if (((env = bsp_getbenv("IPADDR0_10HALF")) != NULL)
- && ((*env == 'y') || (*env == 'Y')))
- sc->link = link_10Half;
- else
- sc->link = link_auto;
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
- ether_ifattach(ifp);
- return 1;
-};