summaryrefslogtreecommitdiffstats
path: root/bsps/arm
diff options
context:
space:
mode:
authorVijay Kumar Banerjee <vijay@rtems.org>2021-02-24 19:09:56 -0700
committerVijay Kumar Banerjee <vijay@rtems.org>2021-04-07 16:15:38 -0600
commitc90fa83041f1467ac9795c489b7151db3a041ab5 (patch)
treeee3ebcd4af33202b34f89133a301d268609e355c /bsps/arm
parentcpukit/libfs: Remove nfsclient (diff)
downloadrtems-c90fa83041f1467ac9795c489b7151db3a041ab5.tar.bz2
bsps: Remove networking drivers
Update #3850
Diffstat (limited to 'bsps/arm')
-rw-r--r--bsps/arm/atsam/net/if_atsam.c1255
-rw-r--r--bsps/arm/csb336/net/lan91c11x.c261
-rw-r--r--bsps/arm/csb336/net/lan91c11x.h229
-rw-r--r--bsps/arm/csb336/net/network.c708
-rw-r--r--bsps/arm/csb337/net/network.c864
-rw-r--r--bsps/arm/edb7312/net/network.c126
-rw-r--r--bsps/arm/gumstix/net/rtl8019.c1197
-rw-r--r--bsps/arm/gumstix/net/wd80x3.h303
-rw-r--r--bsps/arm/rtl22xx/net/network.c126
-rw-r--r--bsps/arm/shared/net/lpc-ethernet.c1839
10 files changed, 0 insertions, 6908 deletions
diff --git a/bsps/arm/atsam/net/if_atsam.c b/bsps/arm/atsam/net/if_atsam.c
deleted file mode 100644
index 9665aa1bcb..0000000000
--- a/bsps/arm/atsam/net/if_atsam.c
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <info@embedded-brains.de>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <libchip/chip.h>
-#include <libchip/include/gmacd.h>
-#include <libchip/include/pio.h>
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-
-#include <stdio.h>
-
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/rtems_mii_ioctl.h>
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/if_types.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <dev/mii/mii.h>
-
-/*
- * Number of interfaces supported by the driver
- */
-#define NIFACES 1
-
-/** Enable/Disable CopyAllFrame */
-#define GMAC_CAF_DISABLE 0
-#define GMAC_CAF_ENABLE 1
-
-/** Enable/Disable NoBroadCast */
-#define GMAC_NBC_DISABLE 0
-#define GMAC_NBC_ENABLE 1
-
-/** The PIN list of PIO for GMAC */
-#define BOARD_GMAC_PINS \
- { (PIO_PD0A_GTXCK | PIO_PD1A_GTXEN | PIO_PD2A_GTX0 | PIO_PD3A_GTX1 \
- | PIO_PD4A_GRXDV | PIO_PD5A_GRX0 | PIO_PD6A_GRX1 \
- | PIO_PD7A_GRXER \
- | PIO_PD8A_GMDC | PIO_PD9A_GMDIO), PIOD, ID_PIOD, PIO_PERIPH_A, \
- PIO_DEFAULT }
-/** The runtime pin configure list for GMAC */
-#define BOARD_GMAC_RUN_PINS BOARD_GMAC_PINS
-
-/** The PIN list of PIO for GMAC */
-#define BOARD_GMAC_RESET_PIN \
- { PIO_PC10, PIOC, ID_PIOC, \
- PIO_OUTPUT_1, \
- PIO_PULLUP }
-
-/** Multicast Enable */
-#define GMAC_MC_ENABLE (1u << 6)
-#define HASH_INDEX_AMOUNT 6
-#define HASH_ELEMENTS_PER_INDEX 8
-#define MAC_ADDR_MASK 0x0000FFFFFFFFFFFF
-#define MAC_IDX_MASK (1u << 0)
-
-/** Promiscuous Mode Enable */
-#define GMAC_PROM_ENABLE (1u << 4)
-
-/** RX Defines */
-#define GMAC_RX_BUFFER_SIZE 1536
-#define GMAC_RX_BUF_DESC_ADDR_MASK 0xFFFFFFFC
-#define GMAC_RX_SET_OFFSET (1u << 15)
-#define GMAC_RX_SET_USED_WRAP ((1u << 1) | (1u << 0))
-#define GMAC_RX_SET_WRAP (1u << 1)
-#define GMAC_RX_SET_USED (1u << 0)
-/** TX Defines */
-#define GMAC_TX_SET_EOF (1u << 15)
-#define GMAC_TX_SET_WRAP (1u << 30)
-#define GMAC_TX_SET_USED (1u << 31)
-
-#define GMAC_DESCRIPTOR_ALIGNMENT 8
-
-/** Events */
-#define ATSAMV7_ETH_RX_EVENT_INTERRUPT RTEMS_EVENT_1
-#define ATSAMV7_ETH_TX_EVENT_INTERRUPT RTEMS_EVENT_2
-#define ATSAMV7_ETH_START_TRANSMIT_EVENT RTEMS_EVENT_3
-
-#define ATSAMV7_ETH_RX_DATA_OFFSET 2
-
-#define WATCHDOG_TIMEOUT 5
-
-/** The PINs for GMAC */
-static const Pin gmacPins[] = { BOARD_GMAC_RUN_PINS };
-
-static const Pin gmacResetPin = BOARD_GMAC_RESET_PIN;
-
-typedef struct if_atsam_gmac {
- /** The GMAC driver instance */
- sGmacd gGmacd;
- uint32_t retries;
- uint8_t phy_address;
-} if_atsam_gmac;
-
-typedef struct ring_buffer {
- unsigned tx_bd_used;
- unsigned tx_bd_free;
- size_t length;
-} ring_buffer;
-
-/*
- * Per-device data
- */
-typedef struct if_atsam_softc {
- /*
- * Data
- */
- struct arpcom arpcom;
- if_atsam_gmac Gmac_inst;
- struct rtems_mdio_info mdio;
- uint8_t GMacAddress[6];
- rtems_id rx_daemon_tid;
- rtems_id tx_daemon_tid;
- rtems_vector_number interrupt_number;
- struct mbuf **rx_mbuf;
- struct mbuf **tx_mbuf;
- volatile sGmacTxDescriptor *tx_bd_base;
- uint32_t anlpar;
- size_t rx_bd_fill_idx;
- size_t amount_rx_buf;
- size_t amount_tx_buf;
- ring_buffer tx_ring;
-
- /*
- * Statistics
- */
- unsigned rx_overrun_errors;
- unsigned rx_interrupts;
- unsigned tx_complete_int;
- unsigned tx_tur_errors;
- unsigned tx_rlex_errors;
- unsigned tx_tfc_errors;
- unsigned tx_hresp_errors;
- unsigned tx_interrupts;
-} if_atsam_softc;
-
-static struct if_atsam_softc if_atsam_softc_inst;
-
-static struct mbuf *if_atsam_new_mbuf(struct ifnet *ifp)
-{
- struct mbuf *m;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m != NULL) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) != 0) {
- m->m_pkthdr.rcvif = ifp;
- m->m_data = mtod(m, char *);
- rtems_cache_invalidate_multiple_data_lines(mtod(m, void *),
- GMAC_RX_BUFFER_SIZE);
- } else {
- m_free(m);
- m = NULL;
- }
- }
- return (m);
-}
-
-
-static uint8_t if_atsam_wait_phy(Gmac *pHw, uint32_t retry)
-{
- volatile uint32_t retry_count = 0;
-
- while (!GMAC_IsIdle(pHw)) {
- if (retry == 0) {
- continue;
- }
- retry_count++;
-
- if (retry_count >= retry) {
- return (1);
- }
- rtems_task_wake_after(1);
- }
-
- return (0);
-}
-
-
-static uint8_t
-if_atsam_write_phy(Gmac *pHw, uint8_t PhyAddress, uint8_t Address,
- uint32_t Value, uint32_t retry)
-{
- GMAC_PHYMaintain(pHw, PhyAddress, Address, 0, (uint16_t)Value);
- if (if_atsam_wait_phy(pHw, retry) == 1) {
- return (1);
- }
- return (0);
-}
-
-
-static uint8_t
-if_atsam_read_phy(Gmac *pHw,
- uint8_t PhyAddress, uint8_t Address, uint32_t *pvalue, uint32_t retry)
-{
- GMAC_PHYMaintain(pHw, PhyAddress, Address, 1, 0);
- if (if_atsam_wait_phy(pHw, retry) == 1) {
- return (1);
- }
- *pvalue = GMAC_PHYData(pHw);
- return (0);
-}
-
-
-static void atsamv7_find_valid_phy(if_atsam_gmac *gmac_inst)
-{
- Gmac *pHw = gmac_inst->gGmacd.pHw;
- uint32_t value = 0;
- uint8_t phy_address;
- int i;
-
- if (gmac_inst->phy_address != 0xFF) {
- return;
- }
-
- /* Find another one */
- phy_address = 0xFF;
-
- for (i = 31; i >= 0; --i) {
- int rv;
-
- rv = if_atsam_read_phy(pHw, (uint8_t)i, MII_PHYIDR1,
- &value, gmac_inst->retries);
- if (rv == 0 && value != 0 && value < 0xffff) {
- phy_address = (uint8_t)i;
- break;
- }
- }
-
- if (phy_address != 0xFF) {
- if_atsam_read_phy(pHw, phy_address, MII_PHYIDR1, &value,
- gmac_inst->retries);
- if_atsam_read_phy(pHw, phy_address, MII_PHYIDR2, &value,
- gmac_inst->retries);
- gmac_inst->phy_address = phy_address;
- }
-}
-
-
-static uint8_t if_atsam_reset_phy(if_atsam_gmac *gmac_inst)
-{
- uint32_t retry_max;
- uint32_t bmcr;
- uint8_t phy_address;
- uint32_t timeout = 10;
- uint8_t ret = 0;
-
- Gmac *pHw = gmac_inst->gGmacd.pHw;
-
- phy_address = gmac_inst->phy_address;
- retry_max = gmac_inst->retries;
-
- bmcr = BMCR_RESET;
- if_atsam_write_phy(pHw, phy_address, MII_BMCR, bmcr, retry_max);
- do {
- if_atsam_read_phy(pHw, phy_address, MII_BMCR, &bmcr,
- retry_max);
- timeout--;
- } while ((bmcr & BMCR_RESET) && timeout);
-
- if (!timeout) {
- ret = 1;
- }
- return (ret);
-}
-
-
-static uint8_t
-if_atsam_init_phy(if_atsam_gmac *gmac_inst, uint32_t mck,
- const Pin *pResetPins, uint32_t nbResetPins, const Pin *pGmacPins,
- uint32_t nbGmacPins)
-{
- uint8_t rc = 1;
- Gmac *pHw = gmac_inst->gGmacd.pHw;
-
- /* Perform RESET */
- if (pResetPins) {
- /* Configure PINS */
- PIO_Configure(pResetPins, nbResetPins);
- PIO_Clear(pResetPins);
- rtems_task_wake_after(1);
- PIO_Set(pResetPins);
- }
- /* Configure GMAC runtime pins */
- if (rc) {
- PIO_Configure(pGmacPins, nbGmacPins);
- rc = GMAC_SetMdcClock(pHw, mck);
-
- if (!rc) {
- return (0);
- }
- if_atsam_reset_phy(gmac_inst);
- }
- return (rc);
-}
-
-static bool if_atsam_is_valid_phy(int phy)
-{
- return phy >= 0 && phy <= 31;
-}
-
-static int if_atsam_mdio_read(int phy, void *arg, unsigned reg, uint32_t *pval)
-{
- if_atsam_softc *sc = (if_atsam_softc *)arg;
-
- if (!if_atsam_is_valid_phy(phy)) {
- return (EINVAL);
- }
-
- return (if_atsam_read_phy(sc->Gmac_inst.gGmacd.pHw,
- (uint8_t)phy, (uint8_t)reg, pval, sc->Gmac_inst.retries));
-}
-
-
-static int if_atsam_mdio_write(int phy, void *arg, unsigned reg, uint32_t pval)
-{
- if_atsam_softc *sc = (if_atsam_softc *)arg;
-
- if (!if_atsam_is_valid_phy(phy)) {
- return (EINVAL);
- }
-
- return if_atsam_write_phy(sc->Gmac_inst.gGmacd.pHw,
- (uint8_t)phy, (uint8_t)reg, pval, sc->Gmac_inst.retries);
-}
-
-
-/*
- * Interrupt Handler for the network driver
- */
-static void if_atsam_interrupt_handler(void *arg)
-{
- if_atsam_softc *sc = (if_atsam_softc *)arg;
- uint32_t irq_status_val;
- rtems_event_set rx_event = 0;
- rtems_event_set tx_event = 0;
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
- /* Get interrupt status */
- irq_status_val = GMAC_GetItStatus(pHw, 0);
-
- /* Check receive interrupts */
- if ((irq_status_val & GMAC_IER_ROVR) != 0) {
- ++sc->rx_overrun_errors;
- rx_event = ATSAMV7_ETH_RX_EVENT_INTERRUPT;
- }
- if ((irq_status_val & GMAC_IER_RCOMP) != 0) {
- rx_event = ATSAMV7_ETH_RX_EVENT_INTERRUPT;
- }
- /* Send events to receive task and switch off rx interrupts */
- if (rx_event != 0) {
- ++sc->rx_interrupts;
- /* Erase the interrupts for RX completion and errors */
- GMAC_DisableIt(pHw, GMAC_IER_RCOMP | GMAC_IER_ROVR, 0);
- (void)rtems_bsdnet_event_send(sc->rx_daemon_tid, rx_event);
- }
- if ((irq_status_val & GMAC_IER_TUR) != 0) {
- ++sc->tx_tur_errors;
- tx_event = ATSAMV7_ETH_TX_EVENT_INTERRUPT;
- }
- if ((irq_status_val & GMAC_IER_RLEX) != 0) {
- ++sc->tx_rlex_errors;
- tx_event = ATSAMV7_ETH_TX_EVENT_INTERRUPT;
- }
- if ((irq_status_val & GMAC_IER_TFC) != 0) {
- ++sc->tx_tfc_errors;
- tx_event = ATSAMV7_ETH_TX_EVENT_INTERRUPT;
- }
- if ((irq_status_val & GMAC_IER_HRESP) != 0) {
- ++sc->tx_hresp_errors;
- tx_event = ATSAMV7_ETH_TX_EVENT_INTERRUPT;
- }
- if ((irq_status_val & GMAC_IER_TCOMP) != 0) {
- ++sc->tx_complete_int;
- tx_event = ATSAMV7_ETH_TX_EVENT_INTERRUPT;
- }
- /* Send events to transmit task and switch off tx interrupts */
- if (tx_event != 0) {
- ++sc->tx_interrupts;
- /* Erase the interrupts for TX completion and errors */
- GMAC_DisableIt(pHw, GMAC_INT_TX_BITS, 0);
- (void)rtems_bsdnet_event_send(sc->tx_daemon_tid, tx_event);
- }
-}
-/*
- * Receive daemon
- */
-static void if_atsam_rx_daemon(void *arg)
-{
- if_atsam_softc *sc = (if_atsam_softc *)arg;
- rtems_event_set events = 0;
- void *rx_bd_base;
- struct mbuf *m;
- struct mbuf *n;
- volatile sGmacRxDescriptor *buffer_desc;
- int frame_len;
- struct ether_header *eh;
- uint32_t tmp_rx_bd_address;
-
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
- /* Allocate memory space for priority queue descriptor list */
- rx_bd_base = rtems_cache_coherent_allocate(sizeof(sGmacRxDescriptor),
- GMAC_DESCRIPTOR_ALIGNMENT, 0);
- assert(rx_bd_base != NULL);
-
- buffer_desc = (sGmacRxDescriptor *)rx_bd_base;
- buffer_desc->addr.val = GMAC_RX_SET_USED_WRAP;
- buffer_desc->status.val = 0;
-
- GMAC_SetRxQueue(pHw, (uint32_t)buffer_desc, 1);
- GMAC_SetRxQueue(pHw, (uint32_t)buffer_desc, 2);
-
- /* Allocate memory space for buffer descriptor list */
- rx_bd_base = rtems_cache_coherent_allocate(
- sc->amount_rx_buf * sizeof(sGmacRxDescriptor),
- GMAC_DESCRIPTOR_ALIGNMENT, 0);
- assert(rx_bd_base != NULL);
- buffer_desc = (sGmacRxDescriptor *)rx_bd_base;
-
- /* Create descriptor list and mark as empty */
- for (sc->rx_bd_fill_idx = 0; sc->rx_bd_fill_idx < sc->amount_rx_buf;
- ++sc->rx_bd_fill_idx) {
- m = if_atsam_new_mbuf(&sc->arpcom.ac_if);
- assert(m != NULL);
- sc->rx_mbuf[sc->rx_bd_fill_idx] = m;
- buffer_desc->addr.val = ((uint32_t)m->m_data) &
- GMAC_RX_BUF_DESC_ADDR_MASK;
- buffer_desc->status.val = 0;
- if (sc->rx_bd_fill_idx == (sc->amount_rx_buf - 1)) {
- buffer_desc->addr.bm.bWrap = 1;
- } else {
- buffer_desc++;
- }
- }
- buffer_desc = (sGmacRxDescriptor *)rx_bd_base;
-
- /* Set 2 Byte Receive Buffer Offset */
- pHw->GMAC_NCFGR |= GMAC_RX_SET_OFFSET;
-
- /* Write Buffer Queue Base Address Register */
- GMAC_ReceiveEnable(pHw, 0);
- GMAC_SetRxQueue(pHw, (uint32_t)buffer_desc, 0);
-
- /* Set address for address matching */
- GMAC_SetAddress(pHw, 0, sc->GMacAddress);
-
- /* Enable Receiving of data */
- GMAC_ReceiveEnable(pHw, 1);
-
- /* Setup the interrupts for RX completion and errors */
- GMAC_EnableIt(pHw, GMAC_IER_RCOMP | GMAC_IER_ROVR, 0);
-
- sc->rx_bd_fill_idx = 0;
-
- while (true) {
- /* Wait for events */
- rtems_bsdnet_event_receive(ATSAMV7_ETH_RX_EVENT_INTERRUPT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-
- /*
- * Check for all packets with a set ownership bit
- */
- while (buffer_desc->addr.bm.bOwnership == 1) {
- if (buffer_desc->status.bm.bEof == 1) {
- m = sc->rx_mbuf[sc->rx_bd_fill_idx];
-
- /* New mbuf for desc */
- n = if_atsam_new_mbuf(&sc->arpcom.ac_if);
- if (n != NULL) {
- frame_len = (int)
- (buffer_desc->status.bm.len);
-
- /* Discard Ethernet header */
- int sz = frame_len - ETHER_HDR_LEN;
-
- /* Update mbuf */
- eh = (struct ether_header *)
- (mtod(m, char *) + 2);
- m->m_len = sz;
- m->m_pkthdr.len = sz;
- m->m_data = (void *)(eh + 1);
- ether_input(&sc->arpcom.ac_if, eh, m);
- m = n;
- } else {
- (void)rtems_bsdnet_event_send(
- sc->tx_daemon_tid, ATSAMV7_ETH_START_TRANSMIT_EVENT);
- }
- sc->rx_mbuf[sc->rx_bd_fill_idx] = m;
- tmp_rx_bd_address = (uint32_t)m->m_data &
- GMAC_RX_BUF_DESC_ADDR_MASK;
-
- /* Switch pointer to next buffer descriptor */
- if (sc->rx_bd_fill_idx ==
- (sc->amount_rx_buf - 1)) {
- tmp_rx_bd_address |= GMAC_RX_SET_WRAP;
- sc->rx_bd_fill_idx = 0;
- } else {
- ++sc->rx_bd_fill_idx;
- }
-
- /*
- * Give ownership to GMAC for further processing
- */
- tmp_rx_bd_address &= ~GMAC_RX_SET_USED;
- _ARM_Data_synchronization_barrier();
- buffer_desc->addr.val = tmp_rx_bd_address;
-
- buffer_desc = (sGmacRxDescriptor *)rx_bd_base
- + sc->rx_bd_fill_idx;
- }
- }
- /* Setup the interrupts for RX completion and errors */
- GMAC_EnableIt(pHw, GMAC_IER_RCOMP | GMAC_IER_ROVR, 0);
- }
-}
-
-/*
- * Update of current transmit buffer position.
- */
-static void if_atsam_tx_bd_pos_update(size_t *pos, size_t amount_tx_buf)
-{
- *pos = (*pos + 1) % amount_tx_buf;
-}
-
-/*
- * Is RingBuffer empty
- */
-static bool if_atsam_ring_buffer_empty(ring_buffer *ring_buffer)
-{
- return (ring_buffer->tx_bd_used == ring_buffer->tx_bd_free);
-}
-
-/*
- * Is RingBuffer full
- */
-static bool if_atsam_ring_buffer_full(ring_buffer *ring_buffer)
-{
- size_t tx_bd_used_next = ring_buffer->tx_bd_used;
-
- if_atsam_tx_bd_pos_update(&tx_bd_used_next, ring_buffer->length);
- return (tx_bd_used_next == ring_buffer->tx_bd_free);
-}
-
-/*
- * Cleanup transmit file descriptors by freeing mbufs which are not needed any
- * longer due to correct transmission.
- */
-static void if_atsam_tx_bd_cleanup(if_atsam_softc *sc)
-{
- struct mbuf *m;
- volatile sGmacTxDescriptor *cur;
- bool eof_needed = false;
-
- while (!if_atsam_ring_buffer_empty(&sc->tx_ring)){
- cur = sc->tx_bd_base + sc->tx_ring.tx_bd_free;
- if (((cur->status.bm.bUsed == 1) && !eof_needed) || eof_needed) {
- eof_needed = true;
- cur->status.val |= GMAC_TX_SET_USED;
- m = sc->tx_mbuf[sc->tx_ring.tx_bd_free];
- m_free(m);
- sc->tx_mbuf[sc->tx_ring.tx_bd_free] = 0;
- if_atsam_tx_bd_pos_update(&sc->tx_ring.tx_bd_free,
- sc->tx_ring.length);
- if (cur->status.bm.bLastBuffer) {
- eof_needed = false;
- }
- } else {
- break;
- }
- }
-}
-
-/*
- * Prepare Ethernet frame to start transmission.
- */
-static bool if_atsam_send_packet(if_atsam_softc *sc, struct mbuf *m)
-{
- volatile sGmacTxDescriptor *cur;
- volatile sGmacTxDescriptor *start_packet_tx_bd = 0;
- int pos = 0;
- uint32_t tmp_val = 0;
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
- bool success;
-
- if_atsam_tx_bd_cleanup(sc);
- /* Wait for interrupt in case no buffer descriptors are available */
- /* Wait for events */
- while (true) {
- if (if_atsam_ring_buffer_full(&sc->tx_ring)) {
- /* Setup the interrupts for TX completion and errors */
- GMAC_EnableIt(pHw, GMAC_INT_TX_BITS, 0);
- success = false;
- break;
- }
-
- /*
- * Get current mbuf for data fill
- */
- cur = &sc->tx_bd_base[sc->tx_ring.tx_bd_used];
- /* Set the transfer data */
- if (m->m_len) {
- uintptr_t cache_adjustment = mtod(m, uintptr_t) % 32;
-
- rtems_cache_flush_multiple_data_lines(
- mtod(m, const char *) - cache_adjustment,
- (size_t)(m->m_len + cache_adjustment));
-
- cur->addr = mtod(m, uint32_t);
- tmp_val = (uint32_t)m->m_len | GMAC_TX_SET_USED;
- if (sc->tx_ring.tx_bd_used == (sc->tx_ring.length - 1)) {
- tmp_val |= GMAC_TX_SET_WRAP;
- }
- if (pos == 0) {
- start_packet_tx_bd = cur;
- }
- sc->tx_mbuf[sc->tx_ring.tx_bd_used] = m;
- m = m->m_next;
- if_atsam_tx_bd_pos_update(&sc->tx_ring.tx_bd_used,
- sc->tx_ring.length);
- } else {
- /* Discard empty mbufs */
- m = m_free(m);
- }
-
- /*
- * Send out the buffer once the complete mbuf_chain has been
- * processed
- */
- if (m == NULL) {
- tmp_val |= GMAC_TX_SET_EOF;
- tmp_val &= ~GMAC_TX_SET_USED;
- _ARM_Data_synchronization_barrier();
- cur->status.val = tmp_val;
- start_packet_tx_bd->status.val &= ~GMAC_TX_SET_USED;
- _ARM_Data_synchronization_barrier();
- GMAC_TransmissionStart(pHw);
- success = true;
- break;
- } else {
- if (pos > 0) {
- tmp_val &= ~GMAC_TX_SET_USED;
- }
- pos++;
- cur->status.val = tmp_val;
- }
- }
- return success;
-}
-
-
-/*
- * Transmit daemon
- */
-static void if_atsam_tx_daemon(void *arg)
-{
- if_atsam_softc *sc = (if_atsam_softc *)arg;
- rtems_event_set events = 0;
- sGmacTxDescriptor *buffer_desc;
- int bd_number;
- void *tx_bd_base;
- struct mbuf *m;
- bool success;
-
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- GMAC_TransmitEnable(pHw, 0);
-
- /* Allocate memory space for priority queue descriptor list */
- tx_bd_base = rtems_cache_coherent_allocate(sizeof(sGmacTxDescriptor),
- GMAC_DESCRIPTOR_ALIGNMENT, 0);
- assert(tx_bd_base != NULL);
-
- buffer_desc = (sGmacTxDescriptor *)tx_bd_base;
- buffer_desc->addr = 0;
- buffer_desc->status.val = GMAC_TX_SET_USED | GMAC_TX_SET_WRAP;
-
- GMAC_SetTxQueue(pHw, (uint32_t)buffer_desc, 1);
- GMAC_SetTxQueue(pHw, (uint32_t)buffer_desc, 2);
-
- /* Allocate memory space for buffer descriptor list */
- tx_bd_base = rtems_cache_coherent_allocate(
- sc->amount_tx_buf * sizeof(sGmacTxDescriptor),
- GMAC_DESCRIPTOR_ALIGNMENT, 0);
- assert(tx_bd_base != NULL);
- buffer_desc = (sGmacTxDescriptor *)tx_bd_base;
-
- /* Create descriptor list and mark as empty */
- for (bd_number = 0; bd_number < sc->amount_tx_buf; bd_number++) {
- buffer_desc->addr = 0;
- buffer_desc->status.val = GMAC_TX_SET_USED;
- if (bd_number == (sc->amount_tx_buf - 1)) {
- buffer_desc->status.bm.bWrap = 1;
- } else {
- buffer_desc++;
- }
- }
- buffer_desc = (sGmacTxDescriptor *)tx_bd_base;
-
- /* Write Buffer Queue Base Address Register */
- GMAC_SetTxQueue(pHw, (uint32_t)buffer_desc, 0);
-
- /* Enable Transmission of data */
- GMAC_TransmitEnable(pHw, 1);
-
- /* Set variables in context */
- sc->tx_bd_base = tx_bd_base;
-
- while (true) {
- /* Wait for events */
- rtems_bsdnet_event_receive(ATSAMV7_ETH_START_TRANSMIT_EVENT | ATSAMV7_ETH_TX_EVENT_INTERRUPT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
- //printf("TX Transmit Event received\n");
-
- /*
- * Send packets till queue is empty
- */
- while (true) {
- /*
- * Get the mbuf chain to transmit
- */
- if_atsam_tx_bd_cleanup(sc);
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
- if (!m) {
- ifp->if_flags &= ~IFF_OACTIVE;
- break;
- }
- success = if_atsam_send_packet(sc, m);
- if (!success){
- break;
- }
- }
- }
-}
-
-
-/*
- * Send packet (caller provides header).
- */
-static void if_atsam_enet_start(struct ifnet *ifp)
-{
- if_atsam_softc *sc = (if_atsam_softc *)ifp->if_softc;
-
- ifp->if_flags |= IFF_OACTIVE;
- rtems_bsdnet_event_send(sc->tx_daemon_tid,
- ATSAMV7_ETH_START_TRANSMIT_EVENT);
-}
-
-
-/*
- * Attach a watchdog for autonegotiation to the system
- */
-static void if_atsam_interface_watchdog(struct ifnet *ifp)
-{
- uint32_t anlpar;
- uint8_t speed = GMAC_SPEED_100M;
- uint8_t full_duplex = GMAC_DUPLEX_FULL;
-
- if_atsam_softc *sc = (if_atsam_softc *)ifp->if_softc;
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
- uint8_t phy = sc->Gmac_inst.phy_address;
- uint32_t retries = sc->Gmac_inst.retries;
-
- if (if_atsam_read_phy(pHw, phy, MII_ANLPAR, &anlpar, retries)) {
- anlpar = 0;
- }
- if (sc->anlpar != anlpar) {
- /* Set up the GMAC link speed */
- if (anlpar & ANLPAR_TX_FD) {
- /* Set MII for 100BaseTx and Full Duplex */
- speed = GMAC_SPEED_100M;
- full_duplex = GMAC_DUPLEX_FULL;
- } else if (anlpar & ANLPAR_10_FD) {
- /* Set MII for 10BaseTx and Full Duplex */
- speed = GMAC_SPEED_10M;
- full_duplex = GMAC_DUPLEX_FULL;
- } else if (anlpar & ANLPAR_TX) {
- /* Set MII for 100BaseTx and half Duplex */
- speed = GMAC_SPEED_100M;
- full_duplex = GMAC_DUPLEX_HALF;
- } else if (anlpar & ANLPAR_10) {
- /* Set MII for 10BaseTx and half Duplex */
- speed = GMAC_SPEED_10M;
- full_duplex = GMAC_DUPLEX_HALF;
- } else {
- /* Set MII for 100BaseTx and Full Duplex */
- speed = GMAC_SPEED_100M;
- full_duplex = GMAC_DUPLEX_FULL;
- }
- GMAC_SetLinkSpeed(pHw, speed, full_duplex);
- sc->anlpar = anlpar;
- }
- ifp->if_timer = WATCHDOG_TIMEOUT;
-}
-
-
-/*
- * Sets up the hardware and chooses the interface to be used
- */
-static void if_atsam_init(void *arg)
-{
- rtems_status_code status;
-
- if_atsam_softc *sc = (if_atsam_softc *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- uint32_t dmac_cfg = 0;
- uint32_t gmii_val = 0;
-
- if (sc->arpcom.ac_if.if_flags & IFF_RUNNING) {
- return;
- }
- sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
- sc->interrupt_number = GMAC_IRQn;
-
- /* Enable Peripheral Clock */
- if ((PMC->PMC_PCSR1 & (1u << 7)) != (1u << 7)) {
- PMC->PMC_PCER1 = 1 << 7;
- }
- /* Setup interrupts */
- NVIC_ClearPendingIRQ(GMAC_IRQn);
- NVIC_EnableIRQ(GMAC_IRQn);
-
- GMACD_Init(&sc->Gmac_inst.gGmacd, GMAC, ID_GMAC, GMAC_CAF_ENABLE,
- GMAC_NBC_DISABLE);
-
- /* Enable MDIO interface */
- GMAC_EnableMdio(sc->Gmac_inst.gGmacd.pHw);
-
- /* PHY initialize */
- if_atsam_init_phy(&sc->Gmac_inst, BOARD_MCK, &gmacResetPin, 1,
- gmacPins, PIO_LISTSIZE(gmacPins));
- /* Find valid Phy */
- atsamv7_find_valid_phy(&sc->Gmac_inst);
-
- /* Set Link Speed */
- sc->anlpar = 0xFFFFFFFF;
- if_atsam_interface_watchdog(ifp);
-
- /* Enable autonegotation */
- if_atsam_read_phy(sc->Gmac_inst.gGmacd.pHw, sc->Gmac_inst.phy_address,
- MII_BMCR, &gmii_val, sc->Gmac_inst.retries);
- if_atsam_write_phy(sc->Gmac_inst.gGmacd.pHw, sc->Gmac_inst.phy_address,
- MII_BMCR, (gmii_val | BMCR_AUTOEN), sc->Gmac_inst.retries);
-
- /* Configuration of DMAC */
- dmac_cfg = (GMAC_DCFGR_DRBS(GMAC_RX_BUFFER_SIZE >> 6)) |
- GMAC_DCFGR_RXBMS(3) | GMAC_DCFGR_TXPBMS | GMAC_DCFGR_FBLDO_INCR16;
- GMAC_SetDMAConfig(sc->Gmac_inst.gGmacd.pHw, dmac_cfg, 0);
-
- /* Shut down Transmit and Receive */
- GMAC_ReceiveEnable(sc->Gmac_inst.gGmacd.pHw, 0);
- GMAC_TransmitEnable(sc->Gmac_inst.gGmacd.pHw, 0);
-
- GMAC_StatisticsWriteEnable(sc->Gmac_inst.gGmacd.pHw, 1);
-
- /*
- * Allocate mbuf pointers
- */
- sc->rx_mbuf = malloc(sc->amount_rx_buf * sizeof *sc->rx_mbuf,
- M_MBUF, M_NOWAIT);
- sc->tx_mbuf = malloc(sc->amount_tx_buf * sizeof *sc->tx_mbuf,
- M_MBUF, M_NOWAIT);
-
- /* Install interrupt handler */
- status = rtems_interrupt_handler_install(sc->interrupt_number,
- "Ethernet",
- RTEMS_INTERRUPT_UNIQUE,
- if_atsam_interrupt_handler,
- sc);
- assert(status == RTEMS_SUCCESSFUL);
-
- /*
- * Start driver tasks
- */
- sc->rx_daemon_tid = rtems_bsdnet_newproc("SCrx", 4096,
- if_atsam_rx_daemon, sc);
- sc->tx_daemon_tid = rtems_bsdnet_newproc("SCtx", 4096,
- if_atsam_tx_daemon, sc);
-
- /* Start Watchdog Timer */
- ifp->if_timer = 1;
-}
-
-
-/*
- * Stop the device
- */
-static void if_atsam_stop(struct if_atsam_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /* Disable MDIO interface and TX/RX */
- pHw->GMAC_NCR &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
- pHw->GMAC_NCR &= ~GMAC_NCR_MPE;
-}
-
-
-/*
- * Show interface statistics
- */
-static void if_atsam_stats(struct if_atsam_softc *sc)
-{
- int eno = EIO;
- int media = 0;
- Gmac *pHw;
-
- media = (int)IFM_MAKEWORD(0, 0, 0, sc->Gmac_inst.phy_address);
- eno = rtems_mii_ioctl(&sc->mdio, sc, SIOCGIFMEDIA, &media);
-
- rtems_bsdnet_semaphore_release();
-
- if (eno == 0) {
- rtems_ifmedia2str(media, NULL, 0);
- printf("\n");
- }
- pHw = sc->Gmac_inst.gGmacd.pHw;
-
- printf("\n** Context Statistics **\n");
- printf("Rx interrupts: %u\n", sc->rx_interrupts);
- printf("Tx interrupts: %u\n", sc->tx_interrupts);
- printf("Error Tur Tx interrupts: %u\n\n", sc->tx_tur_errors);
- printf("Error Rlex Tx interrupts: %u\n\n", sc->tx_rlex_errors);
- printf("Error Tfc Tx interrupts: %u\n\n", sc->tx_tfc_errors);
- printf("Error Hresp Tx interrupts: %u\n\n", sc->tx_hresp_errors);
- printf("Tx complete interrupts: %u\n\n", sc->tx_complete_int);
- printf("\n** Statistics **\n");
- printf("Octets Transmitted Low: %lu\n", pHw->GMAC_OTLO);
- printf("Octets Transmitted High: %lu\n", pHw->GMAC_OTHI);
- printf("Frames Transmitted: %lu\n", pHw->GMAC_FT);
- printf("Broadcast Frames Transmitted: %lu\n", pHw->GMAC_BCFT);
- printf("Multicast Frames Transmitted: %lu\n", pHw->GMAC_MFT);
- printf("Pause Frames Transmitted: %lu\n", pHw->GMAC_PFT);
- printf("64 Byte Frames Transmitted: %lu\n", pHw->GMAC_BFT64);
- printf("65 to 127 Byte Frames Transmitted: %lu\n", pHw->GMAC_TBFT127);
- printf("128 to 255 Byte Frames Transmitted: %lu\n", pHw->GMAC_TBFR255);
- printf("256 to 511 Byte Frames Transmitted: %lu\n", pHw->GMAC_TBFT511);
- printf("512 to 1023 Byte Frames Transmitted: %lu\n",
- pHw->GMAC_TBFT1023);
- printf("1024 to 1518 Byte Frames Transmitted: %lu\n",
- pHw->GMAC_TBFT1518);
- printf("Greater Than 1518 Byte Frames Transmitted: %lu\n",
- pHw->GMAC_GTBFT1518);
- printf("Transmit Underruns: %lu\n", pHw->GMAC_TUR);
- printf("Single Collision Frames: %lu\n", pHw->GMAC_SCF);
- printf("Multiple Collision Frames: %lu\n", pHw->GMAC_MCF);
- printf("Excessive Collisions: %lu\n", pHw->GMAC_EC);
- printf("Late Collisions: %lu\n", pHw->GMAC_LC);
- printf("Deferred Transmission Frames: %lu\n", pHw->GMAC_DTF);
- printf("Carrier Sense Errors: %lu\n", pHw->GMAC_CSE);
- printf("Octets Received Low: %lu\n", pHw->GMAC_ORLO);
- printf("Octets Received High: %lu\n", pHw->GMAC_ORHI);
- printf("Frames Received: %lu\n", pHw->GMAC_FR);
- printf("Broadcast Frames Received: %lu\n", pHw->GMAC_BCFR);
- printf("Multicast Frames Received: %lu\n", pHw->GMAC_MFR);
- printf("Pause Frames Received: %lu\n", pHw->GMAC_PFR);
- printf("64 Byte Frames Received: %lu\n", pHw->GMAC_BFR64);
- printf("65 to 127 Byte Frames Received: %lu\n", pHw->GMAC_TBFR127);
- printf("128 to 255 Byte Frames Received: %lu\n", pHw->GMAC_TBFR255);
- printf("256 to 511 Byte Frames Received: %lu\n", pHw->GMAC_TBFR511);
- printf("512 to 1023 Byte Frames Received: %lu\n", pHw->GMAC_TBFR1023);
- printf("1024 to 1518 Byte Frames Received: %lu\n", pHw->GMAC_TBFR1518);
- printf("1519 to Maximum Byte Frames Received: %lu\n",
- pHw->GMAC_TBFR1518);
- printf("Undersize Frames Received: %lu\n", pHw->GMAC_UFR);
- printf("Oversize Frames Received: %lu\n", pHw->GMAC_OFR);
- printf("Jabbers Received: %lu\n", pHw->GMAC_JR);
- printf("Frame Check Sequence Errors: %lu\n", pHw->GMAC_FCSE);
- printf("Length Field Frame Errors: %lu\n", pHw->GMAC_LFFE);
- printf("Receive Symbol Errors: %lu\n", pHw->GMAC_RSE);
- printf("Alignment Errors: %lu\n", pHw->GMAC_AE);
- printf("Receive Resource Errors: %lu\n", pHw->GMAC_RRE);
- printf("Receive Overrun: %lu\n", pHw->GMAC_ROE);
- printf("IP Header Checksum Errors: %lu\n", pHw->GMAC_IHCE);
- printf("TCP Checksum Errors: %lu\n", pHw->GMAC_TCE);
- printf("UDP Checksum Errors: %lu\n", pHw->GMAC_UCE);
-
- rtems_bsdnet_semaphore_obtain();
-}
-
-
-/*
- * Calculates the index that is to be sent into the hash registers
- */
-static void if_atsam_get_hash_index(uint64_t addr, uint32_t *val)
-{
- uint64_t tmp_val;
- uint8_t i, j;
- uint64_t idx;
- int offset = 0;
-
- addr &= MAC_ADDR_MASK;
-
- for (i = 0; i < HASH_INDEX_AMOUNT; ++i) {
- tmp_val = 0;
- offset = 0;
- for (j = 0; j < HASH_ELEMENTS_PER_INDEX; j++) {
- idx = (addr >> (offset + i)) & MAC_IDX_MASK;
- tmp_val ^= idx;
- offset += HASH_INDEX_AMOUNT;
- }
- if (tmp_val > 0) {
- *val |= (1u << i);
- }
- }
-}
-
-
-/*
- * Dis/Enable promiscuous Mode
- */
-static void if_atsam_promiscuous_mode(if_atsam_softc *sc, bool enable)
-{
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
- if (enable) {
- pHw->GMAC_NCFGR |= GMAC_PROM_ENABLE;
- } else {
- pHw->GMAC_NCFGR &= ~GMAC_PROM_ENABLE;
- }
-}
-
-
-/*
- * Multicast handler
- */
-static int
-if_atsam_multicast_control(bool add, struct ifreq *ifr, if_atsam_softc *sc)
-{
- int eno = 0;
- struct arpcom *ac = &sc->arpcom;
- Gmac *pHw = sc->Gmac_inst.gGmacd.pHw;
-
- /* Switch off Multicast Hashing */
- pHw->GMAC_NCFGR &= ~GMAC_MC_ENABLE;
-
- if (add) {
- eno = ether_addmulti(ifr, ac);
- } else {
- eno = ether_delmulti(ifr, ac);
- }
-
- if (eno == ENETRESET) {
- struct ether_multistep step;
- struct ether_multi *enm;
-
- eno = 0;
-
- pHw->GMAC_HRB = 0;
- pHw->GMAC_HRT = 0;
-
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- uint64_t addrlo = 0;
- uint64_t addrhi = 0;
- uint32_t val = 0;
-
- memcpy(&addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
- memcpy(&addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
- while (addrlo <= addrhi) {
- if_atsam_get_hash_index(addrlo, &val);
- if (val < 32) {
- pHw->GMAC_HRB |= (1u << val);
- } else {
- pHw->GMAC_HRT |= (1u << (val - 32));
- }
- ++addrlo;
- }
- ETHER_NEXT_MULTI(step, enm);
- }
- }
- /* Switch on Multicast Hashing */
- pHw->GMAC_NCFGR |= GMAC_MC_ENABLE;
- return (eno);
-}
-
-
-/*
- * Driver ioctl handler
- */
-static int
-if_atsam_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct if_atsam_softc *sc = (if_atsam_softc *)ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- int rv = 0;
- bool prom_enable;
-
- switch (command) {
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- rtems_mii_ioctl(&sc->mdio, sc, command, &ifr->ifr_media);
- break;
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- ether_ioctl(ifp, command, data);
- break;
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_flags & IFF_RUNNING) {
- /* Don't do anything */
- } else {
- if_atsam_init(sc);
- }
- prom_enable = ((ifp->if_flags & IFF_PROMISC) != 0);
- if_atsam_promiscuous_mode(sc, prom_enable);
- } else {
- if (ifp->if_flags & IFF_RUNNING) {
- if_atsam_stop(sc);
- }
- }
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- if_atsam_multicast_control(command == SIOCADDMULTI, ifr, sc);
- break;
- case SIO_RTEMS_SHOW_STATS:
- if_atsam_stats(sc);
- break;
- default:
- rv = EINVAL;
- break;
- }
- return (rv);
-}
-
-
-/*
- * Attach an SAMV71 driver to the system
- */
-static int if_atsam_driver_attach(struct rtems_bsdnet_ifconfig *config)
-{
- if_atsam_softc *sc = &if_atsam_softc_inst;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- const if_atsam_config *conf = config->drv_ctrl;
- int unitNumber;
- char *unitName;
-
- if (conf != NULL) {
- sc->Gmac_inst.retries = conf->mdio_retries;
- sc->Gmac_inst.phy_address = conf->phy_addr;
- } else {
- sc->Gmac_inst.retries = 10;
- sc->Gmac_inst.phy_address = 0xFF;
- }
-
- /* The MAC address used */
- memcpy(sc->GMacAddress, config->hardware_address, ETHER_ADDR_LEN);
- memcpy(sc->arpcom.ac_enaddr, sc->GMacAddress, ETHER_ADDR_LEN);
-
- /*
- * Parse driver name
- */
- unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName);
- assert(unitNumber == 0);
-
- assert(ifp->if_softc == NULL);
-
- /* MDIO */
- sc->mdio.mdio_r = if_atsam_mdio_read;
- sc->mdio.mdio_w = if_atsam_mdio_write;
- sc->mdio.has_gmii = 1;
-
- if (config->rbuf_count > 0) {
- sc->amount_rx_buf = config->rbuf_count;
- } else {
- sc->amount_rx_buf = 8;
- }
-
- if (config->xbuf_count > 0) {
- sc->amount_tx_buf = config->xbuf_count;
- } else {
- sc->amount_tx_buf = 64;
- }
-
- sc->tx_ring.tx_bd_used = 0;
- sc->tx_ring.tx_bd_free = 0;
- sc->tx_ring.length = sc->amount_tx_buf;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = (short int)unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = ETHERMTU;
- ifp->if_init = if_atsam_init;
- ifp->if_ioctl = if_atsam_ioctl;
- ifp->if_start = if_atsam_enet_start;
- ifp->if_output = ether_output;
- ifp->if_watchdog = if_atsam_interface_watchdog;
- ifp->if_flags = IFF_MULTICAST | IFF_BROADCAST | IFF_SIMPLEX;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_timer = 0;
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
- ether_ifattach(ifp);
- return (1);
-}
-
-
-int if_atsam_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- (void)attaching;
- return (if_atsam_driver_attach(config));
-}
diff --git a/bsps/arm/csb336/net/lan91c11x.c b/bsps/arm/csb336/net/lan91c11x.c
deleted file mode 100644
index 779fbdc039..0000000000
--- a/bsps/arm/csb336/net/lan91c11x.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/**
- * @file
- *
- * @ingroup RTEMSBSPsARMCSB336
- *
- * @brief Helper functions for SMSC LAN91C11x
- */
-
-/*
- * Helper functions for SMSC LAN91C11x
- *
- * Copyright (c) 2004 by Cogent Computer Systems
- * Written by Jay Monkman <jtm@lopingdog.com>
- *
- * 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.
- */
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <sys/types.h>
-#include <rtems.h>
-#include "lan91c11x.h"
-
-uint16_t lan91c11x_read_reg(int reg)
-{
- volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
- uint16_t old_bank;
- uint16_t val;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
-
- /* save the bank register */
- old_bank = ptr[7] & 0x7;
-
- /* set the bank register */
- ptr[7] = (reg >> 4) & 0x7;
-
- val = ptr[((reg & 0xf) >> 1)];
-
- /* restore the bank register */
- ptr[7] = old_bank;
-
- rtems_interrupt_enable(level);
- return val;
-}
-
-void lan91c11x_write_reg(int reg, uint16_t value)
-{
- volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
- uint16_t old_bank;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
-
- /* save the bank register */
- old_bank = ptr[7] & 0x7;
-
- /* set the bank register */
- ptr[7] = (reg >> 4) & 0x7;
-
- ptr[((reg & 0xf) >> 1)] = value;
-
- /* restore the bank register */
- ptr[7] = old_bank;
-
- rtems_interrupt_enable(level);
-}
-
-uint16_t lan91c11x_read_reg_fast(int reg)
-{
- volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
- uint16_t val;
-
- val = ptr[((reg & 0xf) >> 1)];
-
- return val;
-}
-
-void lan91c11x_write_reg_fast(int reg, uint16_t value)
-{
- volatile uint16_t *ptr = (uint16_t *)LAN91C11X_BASE_ADDR;
-
- ptr[((reg & 0xf) >> 1)] = value;
-}
-
-
-uint16_t lan91c11x_read_phy_reg(int reg)
-{
- int i;
- uint16_t mask;
- uint16_t bits[64];
- int clk_idx = 0;
- int input_idx = 0;
- uint16_t phydata;
-
- /* 32 consecutive ones on MDO to establish sync */
- for (i = 0; i < 32; ++i) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- }
-
- /* Start code <01> */
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
-
- /* Read command <10> */
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
-
- /* Output the PHY address, msb first - Internal PHY is address 0 */
- for (i = 0; i < 5; ++i) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- }
-
- /* Output the phy register number, msb first */
- mask = 0x10;
- for (i = 0; i < 5; ++i) {
- if (reg & mask) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- } else {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- }
-
-
- /* Shift to next lowest bit */
- mask >>= 1;
- }
-
- /* 1 bit time for turnaround */
- bits[clk_idx++] = 0;
-
- /* Input starts at this bit time */
- input_idx = clk_idx;
-
- /* Will input 16 bits */
- for (i = 0; i < 16; ++i) {
- bits[clk_idx++] = 0;
- }
-
- /* Final clock bit */
- bits[clk_idx++] = 0;
-
- /* Turn off all MII Interface bits */
- lan91c11x_write_reg(LAN91C11X_MGMT,
- lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
-
- /* Clock all 64 cycles */
- for (i = 0; i < sizeof bits; ++i) {
- /* Clock Low - output data */
- lan91c11x_write_reg(LAN91C11X_MGMT, bits[i]);
- rtems_task_wake_after(1);
-
- /* Clock Hi - input data */
- lan91c11x_write_reg(LAN91C11X_MGMT, bits[i] | LAN91C11X_MGMT_MCLK);
- rtems_task_wake_after(1);
- bits[i] |= lan91c11x_read_reg(LAN91C11X_MGMT) & LAN91C11X_MGMT_MDI;
- }
-
- /* Return to idle state */
- /* Set clock to low, data to low, and output tristated */
- lan91c11x_write_reg(LAN91C11X_MGMT, lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
- rtems_task_wake_after(1);
-
- /* Recover input data */
- phydata = 0;
- for (i = 0; i < 16; ++i) {
- phydata <<= 1;
-
- if (bits[input_idx++] & LAN91C11X_MGMT_MDI) {
- phydata |= 0x0001;
- }
- }
-
- return phydata;
-}
-
-
-
-void lan91c11x_write_phy_reg(int reg, uint16_t phydata)
-{
- int i;
- ushort mask;
- ushort bits[64];
- int clk_idx = 0;
-
- /* 32 consecutive ones on MDO to establish sync */
- for (i = 0; i < 32; ++i) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- }
-
- /* Start code <01> */
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
-
- /* Write command <01> */
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
-
- /* Output the PHY address, msb first - Internal PHY is address 0 */
- for (i = 0; i < 5; ++i) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- }
-
- /* Output the phy register number, msb first */
- mask = 0x10;
- for (i = 0; i < 5; ++i) {
- if (reg & mask) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- } else {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- }
-
- /* Shift to next lowest bit */
- mask >>= 1;
- }
-
- /* 2 extra bit times for turnaround */
- bits[clk_idx++] = 0;
- bits[clk_idx++] = 0;
-
- /* Write out 16 bits of data, msb first */
- mask = 0x8000;
- for (i = 0; i < 16; ++i) {
- if (phydata & mask) {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE | LAN91C11X_MGMT_MDO;
- } else {
- bits[clk_idx++] = LAN91C11X_MGMT_MDOE;
- }
-
- /* Shift to next lowest bit */
- mask >>= 1;
- }
-
- /* Turn off all MII Interface bits */
- lan91c11x_write_reg(LAN91C11X_MGMT,
- lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
-
- /* Clock all 64 cycles */
- for (i = 0; i < sizeof bits; ++i) {
- /* Clock Low - output data */
- lan91c11x_write_reg(LAN91C11X_MGMT, bits[i]);
- rtems_task_wake_after(1);
-
- /* Clock Hi - input data */
- lan91c11x_write_reg(LAN91C11X_MGMT, bits[i] | LAN91C11X_MGMT_MCLK);
- rtems_task_wake_after(1);
- bits[i] |= lan91c11x_read_reg(LAN91C11X_MGMT) & LAN91C11X_MGMT_MDI;
- }
-
- /* Return to idle state */
- /* Set clock to low, data to low, and output tristated */
- lan91c11x_write_reg(LAN91C11X_MGMT,
- lan91c11x_read_reg(LAN91C11X_MGMT) & 0xfff0);
- rtems_task_wake_after(1);
-
-}
-
-
-
diff --git a/bsps/arm/csb336/net/lan91c11x.h b/bsps/arm/csb336/net/lan91c11x.h
deleted file mode 100644
index c1181bda69..0000000000
--- a/bsps/arm/csb336/net/lan91c11x.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * @file
- *
- * @ingroup RTEMSBSPsARMCSB336
- *
- * @brief SMSC LAN91C11x ethernet devices definitions.
- */
-
-/**
- * @defgroup arm_csb336_lan91c11x SMSC LAN91C11x
- *
- * @ingroup RTEMSBSPsARMCSB336
- *
- * @brief SMSC LAN91C11x ethernet devices definitions.
- */
-
-/*
- * Header file for SMSC LAN91C11x ethernet devices
- *
- * Copyright (c) 2004 by Cogent Computer Systems
- * Written by Jay Monkman <jtm@lopingdog.com>
- *
- * 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.
- */
-#ifndef __LAN91C11X_H__
-#define __LAN91C11X_H__
-
-#include <rtems.h>
-#include <bsp.h>
-
-uint16_t lan91c11x_read_reg(int);
-void lan91c11x_write_reg(int, uint16_t);
-uint16_t lan91c11x_read_reg_fast(int);
-void lan91c11x_write_reg_fast(int, uint16_t);
-void lan91c11x_write_phy_reg(int , uint16_t);
-uint16_t lan91c11x_read_phy_reg(int);
-void lan91c11x_unlock(void);
-void lan91c11x_lock(void);
-
-#define LAN91C11X_BASE_ADDR 0x12000000
-
-#define LAN91C11X_REG(_b_, _r_) ((((_b_) & 0xf) << 4) | ((_r_) & 0xf))
-
-
-#define LAN91C11X_TCR (LAN91C11X_REG(0, 0x0))
-#define LAN91C11X_EPHSTAT (LAN91C11X_REG(0, 0x2))
-#define LAN91C11X_RCR (LAN91C11X_REG(0, 0x4))
-#define LAN91C11X_CNTR (LAN91C11X_REG(0, 0x6))
-#define LAN91C11X_MIR (LAN91C11X_REG(0, 0x8))
-#define LAN91C11X_RPCR (LAN91C11X_REG(0, 0xa))
-#define LAN91C11X_BANK (LAN91C11X_REG(0, 0xe))
-#define LAN91C11X_CONFIG (LAN91C11X_REG(1, 0x0))
-#define LAN91C11X_BASE (LAN91C11X_REG(1, 0x2))
-#define LAN91C11X_IA0 (LAN91C11X_REG(1, 0x4))
-#define LAN91C11X_IA2 (LAN91C11X_REG(1, 0x6))
-#define LAN91C11X_IA4 (LAN91C11X_REG(1, 0x8))
-#define LAN91C11X_GNRL (LAN91C11X_REG(1, 0xa))
-#define LAN91C11X_CTRL (LAN91C11X_REG(1, 0xc))
-#define LAN91C11X_MMUCMD (LAN91C11X_REG(2, 0x0))
-#define LAN91C11X_PNR (LAN91C11X_REG(2, 0x2))
-#define LAN91C11X_FIFO (LAN91C11X_REG(2, 0x4))
-#define LAN91C11X_PTR (LAN91C11X_REG(2, 0x6))
-#define LAN91C11X_DATA (LAN91C11X_REG(2, 0x8))
-#define LAN91C11X_INT (LAN91C11X_REG(2, 0xc))
-#define LAN91C11X_MT0 (LAN91C11X_REG(3, 0x0))
-#define LAN91C11X_MT2 (LAN91C11X_REG(3, 0x2))
-#define LAN91C11X_MT4 (LAN91C11X_REG(3, 0x4))
-#define LAN91C11X_MT6 (LAN91C11X_REG(3, 0x6))
-#define LAN91C11X_MGMT (LAN91C11X_REG(3, 0x8))
-#define LAN91C11X_REV (LAN91C11X_REG(3, 0xa))
-#define LAN91C11X_ERCV (LAN91C11X_REG(3, 0xc))
-
-
-#define LAN91C11X_TCR_TXENA (bit(0))
-#define LAN91C11X_TCR_LOOP (bit(1))
-#define LAN91C11X_TCR_FORCOL (bit(2))
-#define LAN91C11X_TCR_PADEN (bit(7))
-#define LAN91C11X_TCR_NOCRC (bit(8))
-#define LAN91C11X_TCR_MONCSN (bit(10))
-#define LAN91C11X_TCR_FDUPLX (bit(11))
-#define LAN91C11X_TCR_STPSQET (bit(12))
-#define LAN91C11X_TCR_EPHLOOP (bit(13))
-#define LAN91C11X_TCR_SWFDUP (bit(15))
-
-#define LAN91C11X_EPHSTAT_TXSUC (bit(0))
-#define LAN91C11X_EPHSTAT_SNGLCOL (bit(1))
-#define LAN91C11X_EPHSTAT_MULCOL (bit(2))
-#define LAN91C11X_EPHSTAT_LTXMUL (bit(3))
-#define LAN91C11X_EPHSTAT_16COL (bit(4))
-#define LAN91C11X_EPHSTAT_SQET (bit(5))
-#define LAN91C11X_EPHSTAT_LTXBRD (bit(6))
-#define LAN91C11X_EPHSTAT_TXDFR (bit(7))
-#define LAN91C11X_EPHSTAT_LATCOL (bit(9))
-#define LAN91C11X_EPHSTAT_LOST (bit(10))
-#define LAN91C11X_EPHSTAT_EXCDEF (bit(11))
-#define LAN91C11X_EPHSTAT_CTRROL (bit(12))
-#define LAN91C11X_EPHSTAT_LINK (bit(14))
-#define LAN91C11X_EPHSTAT_TXUNRN (bit(15))
-
-#define LAN91C11X_RCR_RXABT (bit(0))
-#define LAN91C11X_RCR_PRMS (bit(1))
-#define LAN91C11X_RCR_ALMUL (bit(2))
-#define LAN91C11X_RCR_RXEN (bit(8))
-#define LAN91C11X_RCR_STRIP (bit(9))
-#define LAN91C11X_RCR_ABTENB (bit(13))
-#define LAN91C11X_RCR_FILT (bit(14))
-#define LAN91C11X_RCR_RST (bit(15))
-
-#define LAN91C11X_RPCR_LS0B (bit(2))
-#define LAN91C11X_RPCR_LS1B (bit(3))
-#define LAN91C11X_RPCR_LS2B (bit(4))
-#define LAN91C11X_RPCR_LS0A (bit(5))
-#define LAN91C11X_RPCR_LS1A (bit(6))
-#define LAN91C11X_RPCR_LS2A (bit(7))
-#define LAN91C11X_RPCR_ANEG (bit(11))
-#define LAN91C11X_RPCR_DPLX (bit(12))
-#define LAN91C11X_RPCR_SPEED (bit(13))
-
-#define LAN91C11X_CONFIG_EXTPHY (bit(9))
-#define LAN91C11X_CONFIG_GPCTRL (bit(10))
-#define LAN91C11X_CONFIG_NOWAIT (bit(12))
-#define LAN91C11X_CONFIG_PWR (bit(15))
-
-#define LAN91C11X_CTRL_STORE (bit(0))
-#define LAN91C11X_CTRL_RELOAD (bit(1))
-#define LAN91C11X_CTRL_EEPROM (bit(2))
-#define LAN91C11X_CTRL_TEEN (bit(5))
-#define LAN91C11X_CTRL_CREN (bit(6))
-#define LAN91C11X_CTRL_LEEN (bit(7))
-#define LAN91C11X_CTRL_AUTO (bit(11))
-#define LAN91C11X_CTRL_RCVBAD (bit(14))
-
-#define LAN91C11X_MMUCMD_BUSY (bit(0))
-#define LAN91C11X_MMUCMD_NOOP (0 << 5)
-#define LAN91C11X_MMUCMD_ALLOCTX (1 << 5)
-#define LAN91C11X_MMUCMD_RESETMMU (2 << 5)
-#define LAN91C11X_MMUCMD_REMFRM (3 << 5)
-#define LAN91C11X_MMUCMD_REMTOP (4 << 5)
-#define LAN91C11X_MMUCMD_RELEASE (5 << 5)
-#define LAN91C11X_MMUCMD_ENQUEUE (6 << 5)
-#define LAN91C11X_MMUCMD_RESETTX (7 << 5)
-
-#define LAN91C11X_PTR_MASK (0x7ff)
-#define LAN91C11X_PTR_NE (bit(11))
-#define LAN91C11X_PTR_ETEN (bit(12))
-#define LAN91C11X_PTR_READ (bit(13))
-#define LAN91C11X_PTR_AUTOINC (bit(14))
-#define LAN91C11X_PTR_RCV (bit(15))
-
-#define LAN91C11X_INT_RX (bit(0))
-#define LAN91C11X_INT_TX (bit(1))
-#define LAN91C11X_INT_TXE (bit(2))
-#define LAN91C11X_INT_ALLOC (bit(3))
-#define LAN91C11X_INT_RXOV (bit(4))
-#define LAN91C11X_INT_EPH (bit(5))
-#define LAN91C11X_INT_ERX (bit(6))
-#define LAN91C11X_INT_MD (bit(7))
-#define LAN91C11X_INT_RXMASK (bit(8))
-#define LAN91C11X_INT_TXMASK (bit(9))
-#define LAN91C11X_INT_TXEMASK (bit(10))
-#define LAN91C11X_INT_ALLOCMASK (bit(11))
-#define LAN91C11X_INT_RXOVMASK (bit(12))
-#define LAN91C11X_INT_EPHMASK (bit(13))
-#define LAN91C11X_INT_ERXMASK (bit(14))
-#define LAN91C11X_INT_MDMASK (bit(15))
-
-#define LAN91C11X_MGMT_MDO (bit(0))
-#define LAN91C11X_MGMT_MDI (bit(1))
-#define LAN91C11X_MGMT_MCLK (bit(2))
-#define LAN91C11X_MGMT_MDOE (bit(3))
-#define LAN91C11X_MGMT_MSKCRS100 (bit(14))
-
-
-#define LAN91C11X_PKT_CTRL_CRC (bit(4))
-#define LAN91C11X_PKT_CTRL_ODD (bit(5))
-
-
-/* PHY Registers */
-#define PHY_CTRL 0x00 /* PHY Control */
-#define PHY_STAT 0x01 /* PHY Status */
-#define PHY_ID1 0x02 /* PHY Identifier 1 */
-#define PHY_ID2 0x03 /* PHY Identifier 2 */
-#define PHY_AD 0x04 /* PHY Auto-negotiate Control */
-#define PHY_RMT 0x05 /* PHY Auto-neg Remote End Cap Register */
-#define PHY_CFG1 0x10 /* PHY Configuration 1 */
-#define PHY_CFG2 0x11 /* PHY Configuration 2 */
-#define PHY_INT 0x12 /* Status Output (Interrupt Status) */
-#define PHY_MASK 0x13 /* Interrupt Mask */
-
-/* PHY Control Register Bit Defines */
-#define PHY_CTRL_RST 0x8000 /* PHY Reset */
-#define PHY_CTRL_LPBK 0x4000 /* PHY Loopback */
-#define PHY_CTRL_SPEED 0x2000 /* 100Mbps, 0=10Mpbs */
-#define PHY_CTRL_ANEGEN 0x1000 /* Enable Auto negotiation */
-#define PHY_CTRL_PDN 0x0800 /* PHY Power Down mode */
-#define PHY_CTRL_MIIDIS 0x0400 /* MII 4 bit interface disabled */
-#define PHY_CTRL_ANEGRST 0x0200 /* Reset Auto negotiate */
-#define PHY_CTRL_DPLX 0x0100 /* Full Duplex, 0=Half Duplex */
-#define PHY_CTRL_COLTST 0x0080 /* MII Colision Test */
-
-#define PHY_STAT_CAPT4 0x8000
-#define PHY_STAT_CAPTXF 0x4000
-#define PHY_STAT_CAPTXH 0x2000
-#define PHY_STAT_CAPTF 0x1000
-#define PHY_STAT_CAPTH 0x0800
-#define PHY_STAT_CAPSUPR 0x0040
-#define PHY_STAT_ANEGACK 0x0020
-#define PHY_STAT_REMFLT 0x0010
-#define PHY_STAT_CAPANEG 0x0008
-#define PHY_STAT_LINK 0x0004
-#define PHY_STAT_JAB 0x0002
-#define PHY_STAT_EXREG 0x0001
-
-#define PHY_ADV_NP 0x8000
-#define PHY_ADV_ACK 0x4000
-#define PHY_ADV_RF 0x2000
-#define PHY_ADV_T4 0x0200
-#define PHY_ADV_TXFDX 0x0100
-#define PHY_ADV_TXHDX 0x0080
-#define PHY_ADV_10FDX 0x0040
-#define PHY_ADV_10HDX 0x0020
-#define PHY_ADV_CSMA 0x0001
-
-
-
-
-#endif /* __LAN91C11X_H__ */
diff --git a/bsps/arm/csb336/net/network.c b/bsps/arm/csb336/net/network.c
deleted file mode 100644
index ddc671a4cd..0000000000
--- a/bsps/arm/csb336/net/network.c
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * MC9323MXL Ethernet driver
- *
- * Copyright (c) 2004 by Cogent Computer Systems
- * Written by Jay Monkman <jtm@lopingdog.com>
- *
- * 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.
- */
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet.h>
-#include <mc9328mxl.h>
-#include "lan91c11x.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/bspIo.h>
-#include <assert.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 <bsp/irq.h>
-
-/* RTEMS event used by interrupt handler to start receive daemon. */
-#define START_RECEIVE_EVENT RTEMS_EVENT_1
-
-/* RTEMS event used to start transmit daemon. */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
-static void enet_isr(void *);
-static void enet_isr_on(void);
-
-typedef struct {
- unsigned long rx_packets; /* total packets received */
- unsigned long tx_packets; /* total packets transmitted */
- unsigned long rx_bytes; /* total bytes received */
- unsigned long tx_bytes; /* total bytes transmitted */
- unsigned long interrupts; /* total number of interrupts */
- unsigned long rx_interrupts; /* total number of rx interrupts */
- unsigned long tx_interrupts; /* total number of tx interrupts */
- unsigned long txerr_interrupts; /* total number of tx error interrupts */
-
-} eth_stats_t;
-
-/*
- * Hardware-specific storage
- */
-typedef struct
-{
- /*
- * Connection to networking code
- * This entry *must* be the first in the sonic_softc structure.
- */
- struct arpcom arpcom;
-
- int accept_bcast;
-
- /* Tasks waiting for interrupts */
- rtems_id rx_task;
- rtems_id tx_task;
-
- eth_stats_t stats;
-
-} mc9328mxl_enet_softc_t;
-
-static mc9328mxl_enet_softc_t softc;
-
-
-/* function prototypes */
-int rtems_mc9328mxl_enet_attach(struct rtems_bsdnet_ifconfig *config,
- void *chip);
-void mc9328mxl_enet_init(void *arg);
-void mc9328mxl_enet_init_hw(mc9328mxl_enet_softc_t *sc);
-void mc9328mxl_enet_start(struct ifnet *ifp);
-void mc9328mxl_enet_stop (mc9328mxl_enet_softc_t *sc);
-void mc9328mxl_enet_tx_task (void *arg);
-void mc9328mxl_enet_sendpacket (struct ifnet *ifp, struct mbuf *m);
-void mc9328mxl_enet_rx_task(void *arg);
-void mc9328mxl_enet_stats(mc9328mxl_enet_softc_t *sc);
-static int mc9328mxl_enet_ioctl(struct ifnet *ifp,
- ioctl_command_t command, caddr_t data);
-
-
-int rtems_mc9328mxl_enet_attach (
- struct rtems_bsdnet_ifconfig *config,
- void *chip /* only one ethernet, so no chip number */
- )
-{
- struct ifnet *ifp;
- int mtu;
- int unitnumber;
- char *unitname;
- int tmp;
-
- /*
- * Parse driver name
- */
- unitnumber = rtems_bsdnet_parse_driver_name(config, &unitname);
- if (unitnumber < 0) {
- return 0;
- }
-
- /*
- * Is driver free?
- */
- if (unitnumber != 0) {
- printf ("Bad MC9328MXL unit number.\n");
- return 0;
- }
-
- ifp = &softc.arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printf ("Driver already in use.\n");
- return 0;
- }
-
- /* zero out the control structure */
- memset( &softc, 0, sizeof(softc) );
-
-
- /* set the MAC address */
- tmp = lan91c11x_read_reg(LAN91C11X_IA0);
- softc.arpcom.ac_enaddr[0] = tmp & 0xff;
- softc.arpcom.ac_enaddr[1] = (tmp >> 8) & 0xff;
-
- tmp = lan91c11x_read_reg(LAN91C11X_IA2);
- softc.arpcom.ac_enaddr[2] = tmp & 0xff;
- softc.arpcom.ac_enaddr[3] = (tmp >> 8) & 0xff;
-
- tmp = lan91c11x_read_reg(LAN91C11X_IA4);
- softc.arpcom.ac_enaddr[4] = tmp & 0xff;
- softc.arpcom.ac_enaddr[5] = (tmp >> 8) & 0xff;
-
- if (config->mtu) {
- mtu = config->mtu;
- } else {
- mtu = ETHERMTU;
- }
-
- softc.accept_bcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = &softc;
- ifp->if_unit = unitnumber;
- ifp->if_name = unitname;
- ifp->if_mtu = mtu;
- ifp->if_init = mc9328mxl_enet_init;
- ifp->if_ioctl = mc9328mxl_enet_ioctl;
- ifp->if_start = mc9328mxl_enet_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST;
- if (ifp->if_snd.ifq_maxlen == 0) {
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- }
-
- /* Attach the interface */
- if_attach (ifp);
- ether_ifattach (ifp);
- return 1;
-}
-
-void mc9328mxl_enet_init(void *arg)
-{
- mc9328mxl_enet_softc_t *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- /*
- *This is for stuff that only gets done once (mc9328mxl_enet_init()
- * gets called multiple times
- */
- if (sc->tx_task == 0)
- {
- /* Set up ENET hardware */
- mc9328mxl_enet_init_hw(sc);
-
- /* Start driver tasks */
- sc->rx_task = rtems_bsdnet_newproc("ENrx",
- 4096,
- mc9328mxl_enet_rx_task,
- sc);
- sc->tx_task = rtems_bsdnet_newproc("ENtx",
- 4096,
- mc9328mxl_enet_tx_task,
- sc);
- } /* if tx_task */
-
-
- /* Configure for promiscuous if needed */
- if (ifp->if_flags & IFF_PROMISC) {
- lan91c11x_write_reg(LAN91C11X_RCR,
- (lan91c11x_read_reg(LAN91C11X_RCR) |
- LAN91C11X_RCR_PRMS));
- }
-
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /* Enable TX/RX */
- lan91c11x_write_reg(LAN91C11X_TCR,
- (lan91c11x_read_reg(LAN91C11X_TCR) |
- LAN91C11X_TCR_TXENA));
-
- lan91c11x_write_reg(LAN91C11X_RCR,
- (lan91c11x_read_reg(LAN91C11X_RCR) |
- LAN91C11X_RCR_RXEN));
-
-
-} /* mc9328mxl_enet_init() */
-
-void mc9328mxl_enet_init_hw(mc9328mxl_enet_softc_t *sc)
-{
- uint16_t stat;
- uint16_t my = 0;
- rtems_status_code status = RTEMS_SUCCESSFUL;
-
- lan91c11x_write_reg(LAN91C11X_RCR, LAN91C11X_RCR_RST);
- lan91c11x_write_reg(LAN91C11X_RCR, 0);
- rtems_task_wake_after(1);
-
- /* Reset the PHY */
- lan91c11x_write_phy_reg(PHY_CTRL, PHY_CTRL_RST);
- while(lan91c11x_read_phy_reg(PHY_CTRL) & PHY_CTRL_RST) {
- rtems_task_wake_after(1);
- }
-
-
- stat = lan91c11x_read_phy_reg(PHY_STAT);
-
- if(stat & PHY_STAT_CAPT4) {
- my |= PHY_ADV_T4;
- }
-/* 100Mbs doesn't work, so we won't advertise it */
-
- if(stat & PHY_STAT_CAPTXF) {
- my |= PHY_ADV_TXFDX;
- }
- if(stat & PHY_STAT_CAPTXH) {
- my |= PHY_ADV_TXHDX;
- }
-
- if(stat & PHY_STAT_CAPTF) {
- my |= PHY_ADV_10FDX;
- }
-
- if(stat & PHY_STAT_CAPTH) {
- my |= PHY_ADV_10HDX;
- }
-
- my |= PHY_ADV_CSMA;
-
- lan91c11x_write_phy_reg(PHY_AD, my);
-
-
- /* Enable Autonegotiation */
-#if 0
- lan91c11x_write_phy_reg(PHY_CTRL,
- (PHY_CTRL_ANEGEN | PHY_CTRL_ANEGRST));
-#endif
-
- /* Enable full duplex, let MAC take care
- * of padding and CRC.
- */
- lan91c11x_write_reg(LAN91C11X_TCR,
- (LAN91C11X_TCR_PADEN |
- LAN91C11X_TCR_SWFDUP));
-
- /* Disable promisc, don'tstrip CRC */
- lan91c11x_write_reg(LAN91C11X_RCR, 0);
-
- /* Enable auto-negotiation, LEDA is link, LEDB is traffic */
- lan91c11x_write_reg(LAN91C11X_RPCR,
- (LAN91C11X_RPCR_ANEG |
- LAN91C11X_RPCR_LS2B));
-
- /* Don't add wait states, enable PHY power */
- lan91c11x_write_reg(LAN91C11X_CONFIG,
- (LAN91C11X_CONFIG_NOWAIT |
- LAN91C11X_CONFIG_PWR));
-
- /* Disable error interrupts, enable auto release */
- lan91c11x_write_reg(LAN91C11X_CTRL, LAN91C11X_CTRL_AUTO);
-
- /* Reset MMU */
- lan91c11x_write_reg(LAN91C11X_MMUCMD,
- LAN91C11X_MMUCMD_RESETMMU );
-
-
- rtems_task_wake_after(100);
- /* Enable Autonegotiation */
- lan91c11x_write_phy_reg(PHY_CTRL, 0x3000);
- rtems_task_wake_after(100);
-
- /* Enable Interrupts for RX */
- lan91c11x_write_reg(LAN91C11X_INT, LAN91C11X_INT_RXMASK);
-
- /* Enable interrupts on GPIO Port A3 */
- /* Make pin 3 an input */
- MC9328MXL_GPIOA_DDIR &= ~bit(3);
-
- /* Use GPIO function for pin 3 */
- MC9328MXL_GPIOA_GIUS |= bit(3);
-
- /* Set for active high, level triggered interupt */
- MC9328MXL_GPIOA_ICR1 = ((MC9328MXL_GPIOA_ICR1 & ~(3 << 6)) |
- (2 << 6));
-
- /* Enable GPIO port A3 interrupt */
- MC9328MXL_GPIOA_IMR |= bit(3);
-
- /* Install the interrupt handler */
- status = rtems_interrupt_handler_install(
- BSP_INT_GPIO_PORTA,
- "Network",
- RTEMS_INTERRUPT_UNIQUE,
- enet_isr,
- (void *)BSP_INT_GPIO_PORTA
- );
- assert(status == RTEMS_SUCCESSFUL);
- enet_isr_on();
-
-} /* mc9328mxl_enet_init_hw() */
-
-void mc9328mxl_enet_start(struct ifnet *ifp)
-{
- mc9328mxl_enet_softc_t *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->tx_task, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-void mc9328mxl_enet_stop (mc9328mxl_enet_softc_t *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
-
- /* Stop the transmitter and receiver. */
- lan91c11x_write_reg(LAN91C11X_TCR,
- (lan91c11x_read_reg(LAN91C11X_TCR) &
- ~LAN91C11X_TCR_TXENA));
-
- lan91c11x_write_reg(LAN91C11X_RCR,
- (lan91c11x_read_reg(LAN91C11X_RCR) &
- ~LAN91C11X_RCR_RXEN));
-
-}
-
-/*
- * Driver transmit daemon
- */
-void mc9328mxl_enet_tx_task(void *arg)
-{
- mc9328mxl_enet_softc_t *sc = (mc9328mxl_enet_softc_t *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for (;;)
- {
- 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;
- }
- mc9328mxl_enet_sendpacket (ifp, m);
- softc.stats.tx_packets++;
-
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-/* Send packet */
-void mc9328mxl_enet_sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct mbuf *l = NULL;
- int size = 0;
- int tmp;
- int i;
- int start;
- uint16_t d;
-
- /* How big is the packet ? */
- l = m;
- do {
- size += l->m_len;
- l = l->m_next;
- } while (l != NULL);
-
- /* Allocate a TX buffer */
- lan91c11x_write_reg(LAN91C11X_MMUCMD,
- (LAN91C11X_MMUCMD_ALLOCTX |
- (size >> 8)));
-
- /* Wait for the allocation */
- while ((lan91c11x_read_reg(LAN91C11X_INT) & LAN91C11X_INT_ALLOC) == 0) {
- continue;
- }
-
- tmp = lan91c11x_read_reg(LAN91C11X_PNR);
- lan91c11x_write_reg(LAN91C11X_PNR, ((tmp >> 8) & 0xff));
-
- /* Set the data pointer for auto increment */
- lan91c11x_write_reg(LAN91C11X_PTR, LAN91C11X_PTR_AUTOINC);
-
- /* A delay is needed between pointer and data access ?!? */
- for (i = 0; i < 10; i++) {
- continue;
- }
-
- /* Write status word */
- lan91c11x_write_reg(LAN91C11X_DATA, 0);
-
- /* Write byte count */
- if (size & 1) {
- size++;
- }
- lan91c11x_write_reg(LAN91C11X_DATA, size + 6);
-
- lan91c11x_lock();
-
- /* Copy the mbuf */
- l = m;
- start = 0;
- d = 0;
- while (l != NULL)
- {
- uint8_t *data;
-
- data = mtod(l, uint8_t *);
-
- for (i = start; i < l->m_len; i++) {
- if ((i & 1) == 0) {
- d = data[i] << 8;
- } else {
- d = d | data[i];
- lan91c11x_write_reg_fast(LAN91C11X_DATA, htons(d));
- }
- }
-
- /* If everything is 2 byte aligned, i will be even */
- start = (i & 1);
-
- l = l->m_next;
- }
-
- /* write control byte */
- if (i & 1) {
- lan91c11x_write_reg_fast(LAN91C11X_DATA,
- htons(LAN91C11X_PKT_CTRL_ODD | d));
- } else {
- lan91c11x_write_reg_fast(LAN91C11X_DATA, 0);
- }
-
- lan91c11x_unlock();
-
- /* Enable TX interrupts */
- lan91c11x_write_reg(LAN91C11X_INT,
- (lan91c11x_read_reg(LAN91C11X_INT) |
- LAN91C11X_INT_TXMASK |
- LAN91C11X_INT_TXEMASK));
-
- /* Enqueue it */
- lan91c11x_write_reg(LAN91C11X_MMUCMD,
- LAN91C11X_MMUCMD_ENQUEUE);
-
- /* free the mbuf chain we just copied */
- m_freem(m);
-
-} /* mc9328mxl_enet_sendpacket () */
-
-
-/* reader task */
-void mc9328mxl_enet_rx_task(void *arg)
-{
- mc9328mxl_enet_softc_t *sc = (mc9328mxl_enet_softc_t *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- struct ether_header *eh;
- rtems_event_set events;
- int pktlen;
- uint16_t rsw;
- uint16_t bc;
- uint16_t cbyte;
- int i;
- uint16_t int_reg;
-
- /* Input packet handling loop */
- while (1) {
- rtems_bsdnet_event_receive(
- START_RECEIVE_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
-
- /* Configure for reads from RX data area */
- lan91c11x_write_reg(LAN91C11X_PTR,
- (LAN91C11X_PTR_AUTOINC |
- LAN91C11X_PTR_RCV |
- LAN91C11X_PTR_READ));
-
- /* read the receive status word */
- rsw = lan91c11x_read_reg(LAN91C11X_DATA);
- /* TBD: Need to check rsw here */
-
- /* read the byte count */
- bc = lan91c11x_read_reg(LAN91C11X_DATA);
- pktlen = (bc & 0x7ff) - 6;
-
- /* get an mbuf for this packet */
- MGETHDR(m, M_WAIT, MT_DATA);
-
- /* now get a cluster pointed to by the mbuf */
- /* since an mbuf by itself is too small */
- MCLGET(m, M_WAIT);
-
- lan91c11x_lock();
-
- /* Copy the received packet into an mbuf */
- for (i = 0; i < (pktlen / 2); i++) {
- ((uint16_t*)m->m_ext.ext_buf)[i] =
- lan91c11x_read_reg_fast(LAN91C11X_DATA);
- }
-
- cbyte = lan91c11x_read_reg_fast(LAN91C11X_DATA);
- if (cbyte & LAN91C11X_PKT_CTRL_ODD) {
- ((uint16_t*)m->m_ext.ext_buf)[i] = cbyte;
- pktlen++;
- }
- lan91c11x_unlock();
-
- /* Release the packets memory */
- lan91c11x_write_reg(LAN91C11X_MMUCMD,
- LAN91C11X_MMUCMD_REMTOP);
-
- /* set the receiving interface */
- m->m_pkthdr.rcvif = ifp;
- m->m_nextpkt = 0;
-
- /* set the length of the mbuf */
- m->m_len = pktlen - (sizeof(struct ether_header));
- m->m_pkthdr.len = m->m_len;
-
- /* strip off the ethernet header from the mbuf */
- /* but save the pointer to it */
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
-
-
- softc.stats.rx_packets++;
-
- /* give all this stuff to the stack */
- ether_input(ifp, eh, m);
-
- /* renable RX interrupts */
- int_reg = lan91c11x_read_reg(LAN91C11X_INT);
- int_reg |= LAN91C11X_INT_RXMASK;
- lan91c11x_write_reg(LAN91C11X_INT, int_reg);
-
- }
-} /* mc9328mxl_enet_rx_task */
-
-
-/* Show interface statistics */
-void mc9328mxl_enet_stats (mc9328mxl_enet_softc_t *sc)
-{
- printf (" Total Interrupts:%-8lu", sc->stats.interrupts);
- printf (" Rx Interrupts:%-8lu", sc->stats.rx_interrupts);
- printf (" Tx Interrupts:%-8lu\n", sc->stats.tx_interrupts);
- printf (" Tx Error Interrupts:%-8lu\n", sc->stats.txerr_interrupts);
- printf (" Rx Packets:%-8lu", sc->stats.rx_packets);
- printf (" Tx Packets:%-8lu\n", sc->stats.tx_packets);
-}
-
-
-/* Enables mc9328mxl_enet interrupts. */
-static void enet_isr_on(void)
-{
- /* Enable interrupts */
- MC9328MXL_AITC_INTENNUM = MC9328MXL_INT_GPIO_PORTA;
-
- return;
-}
-
-/* Driver ioctl handler */
-static int
-mc9328mxl_enet_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- mc9328mxl_enet_softc_t *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:
- mc9328mxl_enet_stop (sc);
- break;
-
- case IFF_UP:
- mc9328mxl_enet_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- mc9328mxl_enet_stop (sc);
- mc9328mxl_enet_init (sc);
- break;
-
- default:
- break;
- } /* switch (if_flags) */
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- mc9328mxl_enet_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- } /* switch (command) */
- return error;
-}
-
-/* interrupt handler */
-static void enet_isr(void * unused)
-{
- uint16_t int_reg;
-
- softc.stats.interrupts++;
- /* get the ISR status and determine RX or TX */
- int_reg = lan91c11x_read_reg(LAN91C11X_INT);
-
- /* Handle RX interrupts */
- if ((int_reg & LAN91C11X_INT_RX) && (int_reg & LAN91C11X_INT_RXMASK)) {
- softc.stats.rx_interrupts++;
-
- /* Disable the interrupt */
- int_reg &= ~LAN91C11X_INT_RXMASK;
-
- rtems_bsdnet_event_send (softc.rx_task, START_RECEIVE_EVENT);
- }
-
- /* Handle TX Empty interrupts */
- if ((int_reg & LAN91C11X_INT_TXE) && (int_reg & LAN91C11X_INT_TXEMASK)) {
- softc.stats.tx_interrupts++;
-
- /* Disable the interrupt */
- int_reg &= ~LAN91C11X_INT_TXEMASK;
-
- /* Acknowledge the interrupt */
- int_reg |= LAN91C11X_INT_TXE;
-
- rtems_bsdnet_event_send(softc.tx_task, START_TRANSMIT_EVENT);
-
- }
-
- /* Handle interrupts for transmit errors */
- if ((int_reg & LAN91C11X_INT_TX) && (int_reg & LAN91C11X_INT_TXMASK)) {
- softc.stats.txerr_interrupts++;
- printk("Caught TX interrupt - error on transmission\n");
- }
-
- /* Update the interrupt register on the 91c11x */
- lan91c11x_write_reg(LAN91C11X_INT, int_reg);
-
- /* clear GPIO Int. status */
- MC9328MXL_GPIOA_ISR |= bit(3);
-}
-
diff --git a/bsps/arm/csb337/net/network.c b/bsps/arm/csb337/net/network.c
deleted file mode 100644
index b795cf4bce..0000000000
--- a/bsps/arm/csb337/net/network.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * AT91RM9200 ethernet driver
- *
- * Copyright (c) 2003 by Cogent Computer Systems
- * Written by Mike Kelly <mike@cogcomp.com>
- * and Jay Monkman <jtm@lopingdog.com>
- *
- *
- * July 2009: Joel Sherrill merged csb637 PHY differences from
- * MicroMonitor 1.17.
- */
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/bspIo.h>
-#include <at91rm9200.h>
-#include <at91rm9200_emac.h>
-#include <at91rm9200_gpio.h>
-#include <at91rm9200_pmc.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <errno.h>
-#include <rtems/error.h>
-#include <assert.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 <bsp/irq.h>
-#include <bspopts.h>
-
-/* enable debugging of the PHY code */
-#define PHY_DBG
-
-/* enable debugging of the EMAC code */
-/* #define EMAC_DBG */
-
-#if csb637
- /* Bit defines for the PHY Status Register #1 (phy address 0x01) */
- /* 1 = PHY able to perform 100BASE-T4 */
- #define PHY_STAT_100BASE_T4 BIT15
- /* 1 = PHY able to perform full-duplex 100BASE-X */
- #define PHY_STAT_100BASE_X_FDX BIT14
- /* 1 = PHY able to perform half-duplex 100BASE-X */
- #define PHY_STAT_100BASE_X_HDX BIT13
- /* 1 = PHY able to operate at 10 Mbps in full-duplex mode */
- #define PHY_STAT_10BASE_FDX BIT12
- /* 1 = PHY able to operate at 10 Mbps in half-duplex mode */
- #define PHY_STAT_10BASE_HDX BIT11
- /* 1 = PHY will accept management frames with preamble suppressed */
- #define PHY_STAT_MF_PREAMBLE BIT6
- /* 1 = Auto-negotiation complete */
- #define PHY_STAT_AUTO_NEG_DONE BIT5
- /* 1 = Remote fault condition detected */
- #define PHY_STAT_REM_FLT BIT4
- /* 1 = PHY is able to perform Auto-Negotiation */
- #define PHY_STAT_AUTO_NEG_ABLE BIT3
- /* 1 = Link is up */
- #define PHY_STAT_LINK_UP BIT2
- /* 1 = Jabber condition detected */
- #define PHY_STAT_JABBER BIT1
- /* 1 = Extended register capabilities */
- #define PHY_STAT_EXT_REG BIT0
-
- /* Bit defines for the Auxillary Mode 3 register */
- #define PHY_AUX_MODE2_TRAFFIC_LED BIT6
-#endif
-
- /* interrupt stuff */
- #define EMAC_INT_PRIORITY 0 /* lowest priority */
-
- /* RTEMS event used by interrupt handler to start receive daemon. */
- #define START_RECEIVE_EVENT RTEMS_EVENT_1
-
- /* RTEMS event used to start transmit daemon. */
- #define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
-static void at91rm9200_emac_isr (void *);
-static void at91rm9200_emac_isr_on(void);
-
-/* use the values defined in linkcmds for our use of SRAM */
-extern void * at91rm9200_emac_rxbuf_hdrs;
-extern void * at91rm9200_emac_txbuf;
-extern void * at91rm9200_emac_rxbufs;
-
-/* Set up EMAC hardware */
-/* Number of Receive and Transmit Buffers and Buffer Descriptors */
-#define NUM_RXBDS 8
-#define NUM_TXBDS 1
-#define RX_BUFFER_SIZE 0x600
-
-/* use internal SRAM for buffers and descriptors
- * also insure that the receive descriptors
- * start on a 64byte boundary
- * Receive Buffer Descriptor Header
- */
-
-typedef struct
-{
- unsigned long address;
- unsigned long status;
-} RXBUF_HDR;
-
-RXBUF_HDR *rxbuf_hdrs;
-unsigned char *txbuf;
-unsigned char *rxbuf;
-
-int delay_cnt;
-
-/*
- * Hardware-specific storage
- */
-typedef struct
-{
- /*
- * Connection to networking code
- * This entry *must* be the first in the sonic_softc structure.
- */
- struct arpcom arpcom;
-
- /*
- * Interrupt vector
- */
- rtems_vector_number vector;
-
- /*
- * Indicates configuration
- */
- int acceptBroadcast;
-
- /*
- * Task waiting for interrupts
- */
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * current receive header
- */
- int rx_buf_idx;
-
-
-
- /*
- * Statistics
- */
- unsigned long Interrupts;
- unsigned long rxInterrupts;
- unsigned long rxMissed;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txSingleCollision;
- unsigned long txMultipleCollision;
- unsigned long txCollision;
- unsigned long txDeferred;
- unsigned long txUnderrun;
- unsigned long txLateCollision;
- unsigned long txExcessiveCollision;
- unsigned long txExcessiveDeferral;
- unsigned long txLostCarrier;
- unsigned long txRawWait;
-} at91rm9200_emac_softc_t;
-
-static at91rm9200_emac_softc_t softc;
-
-
-/* The AT91RM9200 ethernet fifos are very undersized. Therefore
- * we use the internal SRAM to hold 4 receive packets and one
- * transmit packet. Note that the AT91RM9200 can only queue
- * one transmit packet at a time.
- */
-
-/* function prototypes */
-int rtems_at91rm9200_emac_attach (struct rtems_bsdnet_ifconfig *config,
- void *chip);
-void at91rm9200_emac_init(void *arg);
-void at91rm9200_emac_init_hw(at91rm9200_emac_softc_t *sc);
-void at91rm9200_emac_start(struct ifnet *ifp);
-void at91rm9200_emac_stop (at91rm9200_emac_softc_t *sc);
-void at91rm9200_emac_txDaemon (void *arg);
-void at91rm9200_emac_sendpacket (struct ifnet *ifp, struct mbuf *m);
-void at91rm9200_emac_rxDaemon(void *arg);
-void at91rm9200_emac_stats (at91rm9200_emac_softc_t *sc);
-static int at91rm9200_emac_ioctl (struct ifnet *ifp,
- ioctl_command_t command,
- caddr_t data);
-
-#if csb637
-/*
- * phyread(): Read the PHY
- */
-static uint32_t phyread(uint8_t reg)
-{
- EMAC_REG(EMAC_MAN) = (0x01 << 30 /* Start of Frame Delimiter */
- | 0x02 << 28 /* Operation, 0x01 = Write, 0x02 = Read */
- | 0x00 << 23 /* Phy Number, 0 as we only have one */
- | reg << 18 /* Phy Register */
- | 0x02 << 16); /* must be 0x02 for turn around field */
-
- /* wait for phy read to complete (was udelay(5000)) */
- rtems_task_wake_after(1);
-
- #if defined(EMAC_DBG)
- printk(
- "EMAC: Phy 0, Reg %d, Read 0x%04lx.\n",
- reg,
- (EMAC_REG(EMAC_MAN) & 0xffff)
- );
- #endif
-
- return EMAC_REG(EMAC_MAN) & 0xffff;
-}
-#endif
-
-/*
- * phywrite(): Write the PHY
- */
-static void phywrite(uint8_t reg, uint16_t data)
-{
- EMAC_REG(EMAC_MAN) = (0x01 << 30 /* Start of Frame Delimiter */
- | 0x01 << 28 /* Operation, 0x01 = Write, 0x02 = Read */
- | 0x00 << 23 /* Phy Number, BCM5221 is address 0 */
- | reg << 18 /* Phy Register */
- | 0x02 << 16 /* must be 0x02 for turn around field */
- | data);
- #if defined(EMAC_DBG)
- printk("EMAC: Phy 0, Reg %d, Write 0x%04x.\n", reg, data);
- #endif
-
- /* wait for phy write to complete (was udelay(5000)) */
- rtems_task_wake_after(1);
-}
-
-
-int rtems_at91rm9200_emac_attach (
- struct rtems_bsdnet_ifconfig *config,
- void *chip /* only one ethernet, so no chip number */
- )
-{
- struct ifnet *ifp;
- int mtu;
- int unitnumber;
- char *unitname;
- void *p;
-
- /* an array of receive buffer descriptors -- avoid type punned warning */
- p = (void *)&at91rm9200_emac_rxbuf_hdrs;
- rxbuf_hdrs = (RXBUF_HDR *)p;
-
- /* one transmit buffer, 1536 bytes maximum */
- txbuf = (unsigned char *)&at91rm9200_emac_txbuf;
-
- /* receive buffers starting address */
- rxbuf = (unsigned char *)&at91rm9200_emac_rxbufs;
- /*
- * Parse driver name
- */
- if ((unitnumber = rtems_bsdnet_parse_driver_name (config, &unitname)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if (unitnumber != 0) {
- printk ("Bad AT91RM9200 EMAC unit number.\n");
- return 0;
- }
- ifp = &softc.arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printk ("Driver already in use.\n");
- return 0;
- }
-
- /*
- * zero out the control structure
- */
-
- memset( &softc, 0, sizeof(softc) );
-
-
- /* get the MAC address from the chip */
- softc.arpcom.ac_enaddr[0] = (EMAC_REG(EMAC_SA1L) >> 0) & 0xff;
- softc.arpcom.ac_enaddr[1] = (EMAC_REG(EMAC_SA1L) >> 8) & 0xff;
- softc.arpcom.ac_enaddr[2] = (EMAC_REG(EMAC_SA1L) >> 16) & 0xff;
- softc.arpcom.ac_enaddr[3] = (EMAC_REG(EMAC_SA1L) >> 24) & 0xff;
- softc.arpcom.ac_enaddr[4] = (EMAC_REG(EMAC_SA1H) >> 0) & 0xff;
- softc.arpcom.ac_enaddr[5] = (EMAC_REG(EMAC_SA1H) >> 8) & 0xff;
-
- #if 0
- printk( "MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
- softc.arpcom.ac_enaddr[0],
- softc.arpcom.ac_enaddr[1],
- softc.arpcom.ac_enaddr[2],
- softc.arpcom.ac_enaddr[3],
- softc.arpcom.ac_enaddr[4],
- softc.arpcom.ac_enaddr[5]
- );
- #endif
-
- if (config->mtu) {
- mtu = config->mtu;
- } else {
- mtu = ETHERMTU;
- }
-
- softc.acceptBroadcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = &softc;
- ifp->if_unit = unitnumber;
- ifp->if_name = unitname;
- ifp->if_mtu = mtu;
- ifp->if_init = at91rm9200_emac_init;
- ifp->if_ioctl = at91rm9200_emac_ioctl;
- ifp->if_start = at91rm9200_emac_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST;
- if (ifp->if_snd.ifq_maxlen == 0) {
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- }
-
- softc.rx_buf_idx = 0;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
- return 1;
-}
-
-void at91rm9200_emac_init(void *arg)
-{
- at91rm9200_emac_softc_t *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- rtems_status_code status = RTEMS_SUCCESSFUL;
-
- /*
- *This is for stuff that only gets done once (at91rm9200_emac_init()
- * gets called multiple times
- */
- if (sc->txDaemonTid == 0) {
- /* Set up EMAC hardware */
- at91rm9200_emac_init_hw(sc);
-
- /* Start driver tasks */
- sc->rxDaemonTid = rtems_bsdnet_newproc("ENrx",
- 4096,
- at91rm9200_emac_rxDaemon,
- sc);
- sc->txDaemonTid = rtems_bsdnet_newproc("ENtx",
- 4096,
- at91rm9200_emac_txDaemon,
- sc);
- } /* if txDaemonTid */
-
- /* set our priority in the AIC */
- AIC_SMR_REG(AIC_SMR_EMAC) = AIC_SMR_PRIOR(EMAC_INT_PRIORITY);
-
- /* install the interrupt handler */
- status = rtems_interrupt_handler_install(
- AT91RM9200_INT_EMAC,
- "Network",
- RTEMS_INTERRUPT_UNIQUE,
- at91rm9200_emac_isr,
- NULL
- );
- assert(status == RTEMS_SUCCESSFUL);
- at91rm9200_emac_isr_on();
-
- /* EMAC doesn't support promiscuous, so ignore requests */
- if (ifp->if_flags & IFF_PROMISC) {
- printk ("Warning - AT91RM9200 Ethernet driver"
- " doesn't support Promiscuous Mode!\n");
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /* Enable TX/RX and clear the statistics counters */
- EMAC_REG(EMAC_CTL) = (EMAC_CTL_TE | EMAC_CTL_RE | EMAC_CTL_CSR);
-
- /* clear any pending interrupts */
- EMAC_REG(EMAC_TSR) = 0xffffffff;
- EMAC_REG(EMAC_RSR) = 0xffffffff;
-
-} /* at91rm9200_emac_init() */
-
-void at91rm9200_emac_init_hw(at91rm9200_emac_softc_t *sc)
-{
- int i;
-
- /* Configure shared pins for Ethernet, not GPIO */
- PIOA_REG(PIO_PDR) = ( BIT7 | /* tx clock */
- BIT8 | /* tx enable */
- BIT9 | /* tx data 0 */
- BIT10 | /* tx data 1 */
- BIT11 | /* carrier sense */
- BIT12 | /* rx data 0 */
- BIT13 | /* rx data 1 */
- BIT14 | /* rx error */
- BIT15 | /* MII clock */
- BIT16 ); /* MII data */
-
- PIOB_REG(PIO_PDR) = ( BIT12 | /* tx data 2 */
- BIT13 | /* tx data 3 */
- BIT14 | /* tx error */
- BIT15 | /* rx data 2 */
- BIT16 | /* rx data 3 */
- BIT17 | /* rx data valid */
- BIT18 | /* rx collistion */
- BIT19 ); /* rx clock */
-
- PIOB_REG(PIO_BSR) = ( BIT12 | /* tx data 2 */
- BIT13 | /* tx data 3 */
- BIT14 | /* tx error */
- BIT15 | /* rx data 2 */
- BIT16 | /* rx data 3 */
- BIT17 | /* rx data valid */
- BIT18 | /* rx collistion */
- BIT19 ); /* rx clock */
-
-
- /* Enable the clock to the EMAC */
- PMC_REG(PMC_PCER) |= PMC_PCR_PID_EMAC;
-
- /* initialize our receive buffer descriptors */
- for (i = 0; i < NUM_RXBDS-1; i++) {
- rxbuf_hdrs[i].address = (unsigned long)(&rxbuf[i * RX_BUFFER_SIZE]);
- rxbuf_hdrs[i].status = 0x00000000;
- }
-
- /* last one needs the wrapbit set as well */
- rxbuf_hdrs[i].address = ((unsigned long)(&rxbuf[i * RX_BUFFER_SIZE]) |
- RXBUF_ADD_WRAP);
- rxbuf_hdrs[i].status = 0x00000000;
-
- /* point to our receive buffer queue */
- EMAC_REG(EMAC_RBQP) = (unsigned long)rxbuf_hdrs;
-
- /* clear any left over status bits */
- EMAC_REG(EMAC_RSR) &= ~(EMAC_RSR_OVR | EMAC_RSR_REC | EMAC_RSR_BNA);
-
- /* set the MII clock divder to MCK/64 */
- EMAC_REG(EMAC_CFG) &= EMAC_CFG_CLK_MASK;
- EMAC_REG(EMAC_CFG) = (EMAC_CFG_CLK_64 | EMAC_CFG_BIG | EMAC_CFG_FD);
-
- /* enable the MII interface */
- EMAC_REG(EMAC_CTL) = EMAC_CTL_MPE;
-
- #if csb637
- {
- int timeout;
- uint32_t emac_link_status;
-
- #if defined(PHY_DBG)
- printk("EMAC: Getting Link Status.\n");
- #endif
- /* read the PHY ID registers */
- emac_link_status = phyread(0x02);
- emac_link_status = phyread(0x03);
-
- /* Get the link status - wait for done with a timeout */
- for (timeout = 10000 ; timeout ; ) {
- for (i = 0; i < 100; i++)
- ;
- emac_link_status = phyread(0x01);
- if (!(emac_link_status & PHY_STAT_AUTO_NEG_ABLE)) {
- #if defined(PHY_DBG)
- printk("EMAC: PHY is unable to Auto-Negotatiate!\n");
- #endif
- timeout = 0;
- break;
- }
- if (emac_link_status & PHY_STAT_AUTO_NEG_DONE) {
- #if defined(PHY_DBG)
- printk("EMAC: Auto-Negotiate Complete, Link = ");
- #endif
- break;
- }
- timeout-- ;
- }
- if (!timeout) {
- #if defined(PHY_DBG)
- printk(
- "EMAC: Auto-Negotatiate Failed, Status = 0x%04lx!\n"
- "EMAC: Initialization Halted.\n",
- emac_link_status
- );
- #endif
- /* if autonegotiation fails, just force to 10HD... */
- emac_link_status = PHY_STAT_10BASE_HDX;
- }
-
- /* Set SPD and FD based on the return link status */
- if (emac_link_status & (PHY_STAT_100BASE_X_FDX | PHY_STAT_100BASE_X_HDX)){
- EMAC_REG(EMAC_CFG) |= EMAC_CFG_SPD;
- #if defined(PHY_DBG)
- printk("100MBIT, ");
- #endif
- } else {
- EMAC_REG(EMAC_CFG) &= ~EMAC_CFG_SPD;
- #if defined(PHY_DBG)
- printk("10MBIT, ");
- #endif
- }
-
- if (emac_link_status & (PHY_STAT_100BASE_X_FDX | PHY_STAT_10BASE_FDX)) {
- EMAC_REG(EMAC_CFG) |= EMAC_CFG_FD;
- #if defined(PHY_DBG)
- printk("Full Duplex.\n");
- #endif
- } else {
- EMAC_REG(EMAC_CFG) &= ~EMAC_CFG_FD;
- #if defined(PHY_DBG)
- printk("Half Duplex.\n");
- #endif
- }
-
- /* Set PHY LED modes. Traffic Meter Mode for ACTLED
- * Set Bit 6 - Traffic Mode on
- */
- phywrite(0x1b, PHY_AUX_MODE2_TRAFFIC_LED);
- }
- #else
- /* must be csb337 */
- /* Set PHY LED2 to combined Link/Activity and enable pulse stretching */
- phywrite( 18, 0x0d0a );
- #endif
-
- #if 0
- EMAC_REG(EMAC_MAN) = (0x01 << 30 | /* Start of Frame Delimiter */
- 0x01 << 28 | /* Operation, 0x01 = Write */
- 0x00 << 23 | /* Phy Number */
- 0x14 << 18 | /* Phy Register */
- 0x02 << 16 | /* must be 0x02 */
- 0x0D0A); /* Write data (0x0000 if read) */
- #endif
-
-} /* at91rm9200_emac_init_hw() */
-
-void at91rm9200_emac_start(struct ifnet *ifp)
-{
- at91rm9200_emac_softc_t *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-void at91rm9200_emac_stop (at91rm9200_emac_softc_t *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Stop the transmitter and receiver.
- */
- EMAC_REG(EMAC_CTL) &= ~(EMAC_CTL_TE | EMAC_CTL_RE);
-}
-
-/*
- * Driver transmit daemon
- */
-void at91rm9200_emac_txDaemon (void *arg)
-{
- at91rm9200_emac_softc_t *sc = (at91rm9200_emac_softc_t *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for (;;)
- {
- /* turn on TX interrupt, then wait for one */
- EMAC_REG(EMAC_IER) = EMAC_INT_TCOM; /* Transmit complete */
-
- 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;
- at91rm9200_emac_sendpacket (ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-/* Send packet */
-void at91rm9200_emac_sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct mbuf *l = NULL;
- unsigned int pkt_offset = 0;
- delay_cnt = 0;
- /* printk("at91rm9200_emac_sendpacket %p\n", m); */
-
- /* Wait for EMAC Transmit Queue to become available. */
- while (((EMAC_REG(EMAC_TSR) & EMAC_TSR_COMP) == 0) &&
- ((EMAC_REG(EMAC_TSR) & EMAC_TSR_TXIDLE) == 0))
-
- {
- delay_cnt++;
-/* sleep(0); make sure we don't hog the cpu */
- continue;
- }
-
- /* copy the mbuf chain into the transmit buffer */
- l = m;
- while (l != NULL) {
- memcpy(((char *)txbuf + pkt_offset), /* offset into pkt for mbuf */
- (char *)mtod(l, void *), /* cast to void */
- l->m_len); /* length of this mbuf */
-
- pkt_offset += l->m_len; /* update offset */
- l = l->m_next; /* get next mbuf, if any */
- }
-
- /* free the mbuf chain we just copied */
- m_freem(m);
-
- /* clear any pending status */
- EMAC_REG(EMAC_TSR) = (EMAC_TSR_OVR | EMAC_TSR_COL | EMAC_TSR_RLE
- | EMAC_TSR_COMP | EMAC_TSR_UND);
-
- /* tell the EMAC about our buffer */
- EMAC_REG(EMAC_TAR) = (unsigned long)txbuf;
- EMAC_REG(EMAC_TCR) = (unsigned long)pkt_offset;
-} /* at91rm9200_emac_sendpacket () */
-
-
-/* SONIC reader task */
-void at91rm9200_emac_rxDaemon(void *arg)
-{
- at91rm9200_emac_softc_t *sc = (at91rm9200_emac_softc_t *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- struct ether_header *eh;
- rtems_event_set events;
- int pktlen;
-
- /* Input packet handling loop */
- for (;;) {
- /* turn on RX interrupts, then wait for one */
- EMAC_REG(EMAC_IER) = (EMAC_INT_RCOM | /* Receive complete */
- EMAC_INT_RBNA | /* Receive buf not available */
- EMAC_INT_ROVR); /* Receive overrun */
-
- rtems_bsdnet_event_receive(
- START_RECEIVE_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
-
- if (EMAC_REG(EMAC_RSR) & EMAC_RSR_BNA) {
- printk("1: EMAC_BNA\n");
- }
-
- if (EMAC_REG(EMAC_RSR) & EMAC_RSR_OVR) {
- printk("1: EMAC_OVR\n");
- }
-
- /* clear the receive status as we do not use it anyway */
- EMAC_REG(EMAC_RSR) = (EMAC_RSR_REC | EMAC_RSR_OVR | EMAC_RSR_BNA);
-
- /* scan the buffer descriptors looking for any with data in them */
- while (rxbuf_hdrs[sc->rx_buf_idx].address & RXBUF_ADD_OWNED) {
- pktlen = rxbuf_hdrs[sc->rx_buf_idx].status & RXBUF_STAT_LEN_MASK;
-
- /* get an mbuf this packet */
- MGETHDR(m, M_WAIT, MT_DATA);
-
- /* now get a cluster pointed to by the mbuf */
- /* since an mbuf by itself is too small */
- MCLGET(m, M_WAIT);
-
- /* set the type of mbuf to ifp (ethernet I/F) */
- m->m_pkthdr.rcvif = ifp;
- m->m_nextpkt = 0;
-
- /* copy the packet into the cluster pointed to by the mbuf */
- memcpy((char *)m->m_ext.ext_buf,
- (char *)(rxbuf_hdrs[sc->rx_buf_idx].address & 0xfffffffc),
- pktlen);
-
- /* Release the buffer ASAP back to the EMAC */
- rxbuf_hdrs[sc->rx_buf_idx].address &= ~RXBUF_ADD_OWNED;
-
- /* set the length of the mbuf */
- m->m_len = pktlen - (sizeof(struct ether_header) + 4);
- m->m_pkthdr.len = m->m_len;
-
- /* strip off the ethernet header from the mbuf */
- /* but save the pointer to it */
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
-
- /* increment the buffer index */
- sc->rx_buf_idx++;
- if (sc->rx_buf_idx >= NUM_RXBDS) {
- sc->rx_buf_idx = 0;
- }
-
- /* give all this stuff to the stack */
- ether_input(ifp, eh, m);
-
- } /* while ADD_OWNED = 0 */
-
- if (EMAC_REG(EMAC_RSR) & EMAC_RSR_BNA) {
- printk("2:EMAC_BNA\n");
- }
- if (EMAC_REG(EMAC_RSR) & EMAC_RSR_OVR) {
- printk("2:EMAC_OVR\n");
- }
-
-
- } /* for (;;) */
-} /* at91rm9200_emac_rxDaemon() */
-
-
-/* Show interface statistics */
-void at91rm9200_emac_stats (at91rm9200_emac_softc_t *sc)
-{
- printf (" Total Interrupts:%-8lu", sc->Interrupts);
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Collision:%-8lu", sc->rxCollision);
- printf (" Missed:%-8lu\n", sc->rxMissed);
-
- printf ( " Tx Interrupts:%-8lu", sc->txInterrupts);
- printf ( " Deferred:%-8lu", sc->txDeferred);
- printf (" Lost Carrier:%-8lu\n", sc->txLostCarrier);
- printf ( "Single Collisions:%-8lu", sc->txSingleCollision);
- printf ( "Multiple Collisions:%-8lu", sc->txMultipleCollision);
- printf ("Excessive Collisions:%-8lu\n", sc->txExcessiveCollision);
- printf ( " Total Collisions:%-8lu", sc->txCollision);
- printf ( " Late Collision:%-8lu", sc->txLateCollision);
- printf (" Underrun:%-8lu\n", sc->txUnderrun);
- printf ( " Raw output wait:%-8lu\n", sc->txRawWait);
-}
-
-
-/* Enables at91rm9200_emac interrupts. */
-static void at91rm9200_emac_isr_on(void)
-{
- /* Enable various TX/RX interrupts */
- EMAC_REG(EMAC_IER) = (EMAC_INT_RCOM | /* Receive complete */
- EMAC_INT_RBNA | /* Receive buffer not available */
- EMAC_INT_TCOM | /* Transmit complete */
- EMAC_INT_ROVR | /* Receive overrun */
- EMAC_INT_ABT); /* Abort on DMA transfer */
-
- return;
-}
-
-/* Driver ioctl handler */
-static int
-at91rm9200_emac_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- at91rm9200_emac_softc_t *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:
- at91rm9200_emac_stop (sc);
- break;
-
- case IFF_UP:
- at91rm9200_emac_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- at91rm9200_emac_stop (sc);
- at91rm9200_emac_init (sc);
- break;
-
- default:
- break;
- } /* switch (if_flags) */
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- at91rm9200_emac_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- } /* switch (command) */
- return error;
-}
-
-/* interrupt handler */
-static void at91rm9200_emac_isr (void * unused)
-{
- unsigned long status32;
-
- /* get the ISR status and determine RX or TX */
- status32 = EMAC_REG(EMAC_ISR);
-
- if (status32 & EMAC_INT_ABT) {
- EMAC_REG(EMAC_IDR) = EMAC_INT_ABT; /* disable it */
- rtems_panic("AT91RM9200 Ethernet MAC has received an Abort.\n");
- }
-
- if (status32 & (EMAC_INT_RCOM | /* Receive complete */
- EMAC_INT_RBNA | /* Receive buffer not available */
- EMAC_INT_ROVR)) { /* Receive overrun */
-
- /* disable the RX interrupts */
- EMAC_REG(EMAC_IDR) = (EMAC_INT_RCOM | /* Receive complete */
- EMAC_INT_RBNA | /* Receive buf not available */
- EMAC_INT_ROVR); /* Receive overrun */
-
- rtems_bsdnet_event_send (softc.rxDaemonTid, START_RECEIVE_EVENT);
- }
-
- if (status32 & EMAC_INT_TCOM) { /* Transmit buffer register empty */
-
- /* disable the TX interrupts */
- EMAC_REG(EMAC_IDR) = EMAC_INT_TCOM;
-
- rtems_bsdnet_event_send (softc.txDaemonTid, START_TRANSMIT_EVENT);
- }
-}
-
diff --git a/bsps/arm/edb7312/net/network.c b/bsps/arm/edb7312/net/network.c
deleted file mode 100644
index 9a832293f9..0000000000
--- a/bsps/arm/edb7312/net/network.c
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <rtems.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <bsp/irq.h>
-#include <libchip/cs8900.h>
-#include <assert.h>
-
-#define CS8900_BASE 0x20000300
-unsigned int bsp_cs8900_io_base = 0;
-unsigned int bsp_cs8900_memory_base = 0;
-static void cs8900_isr(void *);
-
-char g_enetbuf[1520];
-
-static void cs8900_isr(void *arg)
-{
- cs8900_interrupt(BSP_EINT3, arg);
-}
-
-/* cs8900_io_set_reg - set one of the I/O addressed registers */
-void cs8900_io_set_reg (cs8900_device *cs, unsigned short reg, unsigned short data)
-{
- /* works the same for all values of dev */
-/*
- printf("cs8900_io_set_reg: reg: %#6x, val %#6x\n",
- CS8900_BASE + reg,
- data);
-*/
- *(unsigned short *)(CS8900_BASE + reg) = data;
-}
-
-/* cs8900_io_get_reg - reads one of the I/O addressed registers */
-unsigned short cs8900_io_get_reg (cs8900_device *cs, unsigned short reg)
-{
- unsigned short val;
- /* works the same for all values of dev */
- val = *(unsigned short *)(CS8900_BASE + reg);
-/*
- printf("cs8900_io_get_reg: reg: %#6x, val %#6x\n", reg, val);
-*/
- return val;
-}
-
-/* cs8900_mem_set_reg - sets one of the registers mapped through
- * PacketPage
- */
-void cs8900_mem_set_reg (cs8900_device *cs, unsigned long reg, unsigned short data)
-{
- /* works the same for all values of dev */
- cs8900_io_set_reg(cs, CS8900_IO_PACKET_PAGE_PTR, reg);
- cs8900_io_set_reg(cs, CS8900_IO_PP_DATA_PORT0, data);
-}
-
-/* cs8900_mem_get_reg - reads one of the registers mapped through
- * PacketPage
- */
-unsigned short cs8900_mem_get_reg (cs8900_device *cs, unsigned long reg)
-{
- /* works the same for all values of dev */
- cs8900_io_set_reg(cs, CS8900_IO_PACKET_PAGE_PTR, reg);
- return cs8900_io_get_reg(cs, CS8900_IO_PP_DATA_PORT0);
-}
-
-void cs8900_attach_interrupt (cs8900_device *cs)
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
-
- status = rtems_interrupt_handler_install(
- BSP_EINT3,
- "Network",
- RTEMS_INTERRUPT_UNIQUE,
- cs8900_isr,
- cs
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-void cs8900_detach_interrupt (cs8900_device *cs)
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
-
- status = rtems_interrupt_handler_remove(
- BSP_EINT3,
- cs8900_isr,
- cs
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-unsigned short cs8900_get_data_block (cs8900_device *cs, unsigned char *data)
-{
- int len;
- int i;
-
- len = cs8900_mem_get_reg(cs, CS8900_PP_RxLength);
-
- for (i = 0; i < ((len + 1) / 2); i++) {
- ((short *)data)[i] = cs8900_io_get_reg(cs,
- CS8900_IO_RX_TX_DATA_PORT0);
- }
- return len;
-}
-
-void cs8900_tx_load (cs8900_device *cs, struct mbuf *m)
-{
- int len;
- unsigned short *data;
- int i;
-
- len = 0;
-
- do {
- memcpy(&g_enetbuf[len], mtod(m, const void *), m->m_len);
- len += m->m_len;
- m = m->m_next;
- } while (m != 0);
-
- data = (unsigned short *) &g_enetbuf[0];
- for (i = 0; i < ((len + 1) / 2); i++) {
- cs8900_io_set_reg(cs,
- CS8900_IO_RX_TX_DATA_PORT0,
- data[i]);
- }
-}
diff --git a/bsps/arm/gumstix/net/rtl8019.c b/bsps/arm/gumstix/net/rtl8019.c
deleted file mode 100644
index 00fd2fdf09..0000000000
--- a/bsps/arm/gumstix/net/rtl8019.c
+++ /dev/null
@@ -1,1197 +0,0 @@
-/*
- *By Yang Xi <hiyangxi@gmail.com>.
- *RTL8019 ethernet driver for Gumstix on SKYEYE simulator
- *Based on NE2000 driver for pc386 bsp
- *
- * 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.
- */
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-#include "wd80x3.h"
-
-#include <stdio.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <rtems/bspIo.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 <net/if_arp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-
-/* Define this to force byte-wide data transfers with the NIC. This
- is needed for boards like the TS-1325 386EX PC, which support only
- an 8-bit PC/104 bus. Undefine this on a normal PC.*/
-
-#define NE2000_BYTE_TRANSFERS
-
-/* Define this to print debugging messages with printk. */
-
-/*#define DEBUG_NE2000
- #define DEBUG_NE*/
-
-/* We expect to be able to read a complete packet into an mbuf. */
-
-#if (MCLBYTES < 1520)
-# error "Driver must have MCLBYTES >= 1520"
-#endif
-
-/* The 8390 macro definitions in wd80x3.h expect RO to be defined. */
-#define RO 0
-
-/* Minimum size of Ethernet packet. */
-#define ET_MINLEN 60
-
-/* The number of NE2000 devices supported by this driver. */
-
-#define NNEDRIVER 1
-
-/* RTEMS event number used by the interrupt handler to signal the
- driver task. This must not be any of the events used by the
- network task synchronization. */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/* RTEMS event number used to start the transmit daemon. This must
- not be the same as INTERRUPT_EVENT. */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
-/* Interrupts we want to handle from the device. */
-
-#define NE_INTERRUPTS \
- (MSK_PRX | MSK_PTX | MSK_RXE | MSK_TXE | MSK_OVW | MSK_CNT)
-
-/* The size of a page in device memory. */
-
-#define NE_PAGE_SIZE (256)
-
-/* The first page address in device memory. */
-
-#define NE_START_PAGE (0x40)
-
-/* The last page address, plus 1. */
-
-#define NE_STOP_PAGE (0x80)
-
-/* The number of pages used for a single transmit buffer. This is
- 1536 bytes, enough for a full size packet. */
-
-#define NE_TX_PAGES (6)
-
-/* The number of transmit buffers. We use two, so we can load one
- packet while the other is being sent. */
-
-#define NE_TX_BUFS (2)
-
-/* We use the first pages in memory as transmit buffers, and the
- remaining ones as receive buffers. */
-
-#define NE_FIRST_TX_PAGE (NE_START_PAGE)
-
-#define NE_FIRST_RX_PAGE (NE_FIRST_TX_PAGE + NE_TX_PAGES * NE_TX_BUFS)
-
-/* Data we store for each NE2000 device. */
-
-struct ne_softc {
- /* The bsdnet information structure. */
- struct arpcom arpcom;
-
- /* The interrupt request number. */
- unsigned int irno;
- /* The base IO port number. */
- unsigned int port;
-
- /* Whether we accept broadcasts. */
- int accept_broadcasts;
-
- /* The thread ID of the transmit task. */
- rtems_id tx_daemon_tid;
- /* The thread ID of the receive task. */
- rtems_id rx_daemon_tid;
-
- /* Whether we use byte-transfers with the device. */
- bool byte_transfers;
-
- /* The number of memory buffers which the transmit daemon has loaded
- with data to be sent, but which have not yet been completely
- sent. */
- int inuse;
- /* The index of the next available transmit memory buffer. */
- int nextavail;
- /* The index of the next transmit buffer to send. */
- int nextsend;
- /* Nonzero if the device is currently transmitting a packet. */
- int transmitting;
- /* The length of the data stored in each transmit buffer. */
- int sendlen[NE_TX_BUFS];
-
- /* Set if we have a packet overrun while receiving. */
- int overrun;
- /* Set if we should resend after an overrun. */
- int resend;
-
- /* Statistics. */
- struct {
- /* Number of packets received. */
- unsigned long rx_packets;
- /* Number of packets sent. */
- unsigned long tx_packets;
- /* Number of interrupts. */
- unsigned long interrupts;
- /* Number of receive acknowledgements. */
- unsigned long rx_acks;
- /* Number of transmit acknowledgements. */
- unsigned long tx_acks;
- /* Number of packet overruns. */
- unsigned long overruns;
- /* Number of frame errors. */
- unsigned long rx_frame_errors;
- /* Number of CRC errors. */
- unsigned long rx_crc_errors;
- /* Number of missed packets. */
- unsigned long rx_missed_errors;
- } stats;
-};
-
-/* The list of NE2000 devices on this system. */
-
-static struct ne_softc ne_softc[NNEDRIVER];
-
-/*
- * receive ring descriptor
- *
- * The National Semiconductor DS8390 Network interface controller uses
- * the following receive ring headers. The way this works is that the
- * memory on the interface card is chopped up into 256 bytes blocks.
- * A contiguous portion of those blocks are marked for receive packets
- * by setting start and end block #'s in the NIC. For each packet that
- * is put into the receive ring, one of these headers (4 bytes each) is
- * tacked onto the front. The first byte is a copy of the receiver status
- * register at the time the packet was received.
- */
-struct ne_ring
-{
- unsigned char rsr; /* receiver status */
- unsigned char next; /* pointer to next packet */
- unsigned short count; /* bytes in packet (length + 4) */
-};
-
-/* Forward declarations to avoid warnings */
-
-static void ne_init_irq_handler (struct ne_softc *sc);
-static void ne_stop (struct ne_softc *sc);
-static void ne_stop_hardware (struct ne_softc *sc);
-static void ne_init (void *arg);
-static void ne_init_hardware (struct ne_softc *sc);
-
-static void ne_reset(struct ne_softc *sc);
-#ifdef DEBUG_NE
-static void ne_dump(struct ne_softc *sc);
-#endif
-
-/* Read data from an NE2000 device. Read LEN bytes at ADDR, storing
- them into P. */
-
-static void
-ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p)
-{
- unsigned int port = sc->port;
- unsigned int dport = port + DATAPORT;
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
- outport_byte (port + RBCR0, len);
- outport_byte (port + RBCR1, len >> 8);
- outport_byte (port + RSAR0, addr);
- outport_byte (port + RSAR1, addr >> 8);
- outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
-
- if (sc->byte_transfers)
- {
- unsigned char d;
- while (len > 0)
- {
- inport_byte(dport, d);
- *p++ = d;
- len--;
- }
- }
- else /* word transfers */
- {
- unsigned short d;
- while (len > 1)
- {
- inport_word(dport, d);
- *p++ = d;
- *p++ = d >> 8;
- len -= 2;
- }
- if (len)
- {
- inport_word(dport, d);
- *p++ = d;
- }
- }
-
- outport_byte (port + ISR, MSK_RDC);
-}
-
-/* Handle the current NE2000 status. This is called when the device
- signals an interrupt. It is also called at other times while
- NE2000 interrupts have been disabled. */
-
-static void
-ne_check_status (struct ne_softc *sc, int from_irq_handler)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
- unsigned char status;
-
- /* It seems that we need to use a loop here, because if the NE2000
- signals an interrupt because packet transmission is complete, and
- then receives a packet while interrupts are disabled, it seems to
- sometimes fail to signal the interrupt for the received packet
- when interrupts are reenabled. (Based on the behaviour of the
- Realtek 8019AS chip). */
-
- /* int count = 0; */
- while (1)
- {
- inport_byte (port + ISR, status);
-#ifdef DEBUG_NE2000
- printk ("NE2000 status 0x%x\n", status);
-#endif
- if (status == 0)
- break;
-
- /* ack */
- outport_byte (port + ISR, status);
-
- /* Check for incoming packet overwrite. */
- if (status & MSK_OVW)
- {
- ifp->if_timer = 0;
-#ifdef DEBUG_NE
- printk("^\n");
-#endif
- ++sc->stats.overruns;
- ne_reset(sc);
- /* Reenable device interrupts. */
- if (from_irq_handler)
- outport_byte(port + IMR, NE_INTERRUPTS);
- return;
- }
-
- /* Check for transmitted packet. The transmit daemon may now be
- able to send another packet to the device. */
- if ((status & (MSK_PTX | MSK_TXE)) != 0)
- {
- ifp->if_timer = 0;
- ++sc->stats.tx_acks;
- --sc->inuse;
- sc->transmitting = 0;
- if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
- rtems_bsdnet_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
- }
-
- /* Check for received packet. */
- if ((status & (MSK_PRX | MSK_RXE)) != 0)
- {
- ++sc->stats.rx_acks;
- rtems_bsdnet_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
- }
-
- /* Check for counter change. */
- if ((status & MSK_CNT) != 0)
- {
- unsigned char add;
- inport_byte (port + CNTR0, add);
- sc->stats.rx_frame_errors += add;
- inport_byte (port + CNTR1, add);
- sc->stats.rx_crc_errors += add;
- inport_byte (port + CNTR2, add);
- sc->stats.rx_missed_errors += add;
- }
-
- break;
- }
-
- outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
-
-}
-
-/* Handle an NE2000 interrupt. */
-
-static void
-ne_interrupt_handler (void *arg)
-{
- struct ne_softc *sc = arg;
-
- if (sc == NULL)
- return;
-
- ++sc->stats.interrupts;
-
-#ifdef DEBUG_NE
- printk("!");
-#endif
- ne_check_status(sc, 1);
-}
-
-/* Turn NE2000 interrupts on. */
-
-static void
-ne_interrupt_on (struct ne_softc *sc)
-{
-#ifdef DEBUG_NE
- printk ("ne_interrupt_on()\n");
-#endif
- if (sc != NULL)
- outport_byte (sc->port + IMR, NE_INTERRUPTS);
-}
-
-/* Initialize the NE2000 hardware. */
-
-static void
-ne_init_hardware (struct ne_softc *sc)
-{
- unsigned int port = sc->port;
- int i;
-
-#ifdef DEBUG_NE2000
- printk ("ne_init_hardware()\n");
-#endif
-
- /* Initialize registers. */
-
- /* Set interface for page 0, Remote DMA complete, Stopped */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- /* Set FIFO threshold to 8, No auto-init Remote DMA, byte order=80x86 */
- /* byte-wide DMA xfers */
- if (sc->byte_transfers)
- outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
- /* word-wide DMA xfers */
- else
- outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
-
- /* Clear Remote Byte Count Registers */
- outport_byte (port + RBCR0, 0);
- outport_byte (port + RBCR1, 0);
-
- /* For the moment, don't store incoming packets in memory. */
- outport_byte (port + RCR, MSK_MON);
-
- /* Place NIC in internal loopback mode */
- outport_byte (port + TCR, MSK_LOOP);
-
- /* Initialize transmit/receive (ring-buffer) Page Start */
- outport_byte (port + TPSR, NE_FIRST_TX_PAGE);
- outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
-
- /* Initialize Receiver (ring-buffer) Page Stop and Boundary */
- outport_byte (port + PSTOP, NE_STOP_PAGE);
- outport_byte (port + BNRY, NE_STOP_PAGE - 1);
-
- /* Clear all interrupts */
- outport_byte (port + ISR, 0xff);
- /* Disable all interrupts */
- outport_byte (port + IMR, 0);
-
- /* Program Command Register for page 1 */
- outport_byte (port + CMDR, MSK_PG1 | MSK_RD2 | MSK_STP);
-
- /* Set the Ethernet hardware address. */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
-
- /* Set Current Page pointer to next_packet */
- outport_byte (port + CURR, NE_FIRST_RX_PAGE);
-
- /* Clear the multicast address. */
- for (i = 0; i < MARsize; ++i)
- outport_byte (port + MAR + i, 0);
-
- /* Set page 0 registers */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- /* accept broadcast */
- outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0));
-
- /* Start interface */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
-
- /* Take interface out of loopback */
- outport_byte (port + TCR, 0);
-}
-
-/* Set up interrupts.
-*/
-static void
-ne_init_irq_handler(struct ne_softc *sc)
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
-
-#ifdef DEBUG_NE
- printk("ne_init_irq_handler(%d)\n", sc->irno);
-#endif
-
- status = rtems_interrupt_handler_install(
- sc->irno,
- "RTL8019",
- RTEMS_INTERRUPT_UNIQUE,
- ne_interrupt_handler,
- sc
- );
- assert(status == RTEMS_SUCCESSFUL);
- ne_interrupt_on(sc);
-}
-
-/* The NE2000 packet receive daemon. This task is started when the
- NE2000 driver is initialized. */
-
-#ifdef DEBUG_NE
-static int ccc = 0; /* experinent! */
-#endif
-
-static void
-ne_rx_daemon (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
-
- while (1)
- {
- rtems_event_set events;
-
- /* Wait for the interrupt handler to tell us that there is a
- packet ready to receive. */
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- /* Don't let the device interrupt us now. */
- outport_byte (port + IMR, 0);
-
- while (1)
- {
- unsigned char startpage, currpage;
- unsigned short len;
- unsigned char next, cnt1, cnt2;
- struct mbuf *m = NULL;
- unsigned char *p;
- int startaddr;
- int toend;
- struct ether_header *eh;
- struct ne_ring hdr; /* ring buffer header */
- int reset;
-
- inport_byte (port + BNRY, startpage);
-
- outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
- inport_byte (port + CURR, currpage);
- outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
-
- ++startpage;
- if (startpage >= NE_STOP_PAGE)
- startpage = NE_FIRST_RX_PAGE;
-
- if (startpage == currpage)
- break;
-
-#ifdef DEBUG_NE2000
- printk ("ne_rx_daemon: start page %x; current page %x\n",
- startpage, currpage);
-#endif
-
- reset = 0;
-
- /* Read the buffer header */
- startaddr = startpage * NE_PAGE_SIZE;
- ne_read_data(sc, startaddr, sizeof(hdr), (unsigned char *)&hdr);
- next = hdr.next;
-
- if (next >= NE_STOP_PAGE)
- next = NE_FIRST_RX_PAGE;
-
- /* check packet length */
- len = hdr.count;
- if (currpage < startpage)
- cnt1 = currpage + (NE_STOP_PAGE - NE_FIRST_RX_PAGE) - startpage;
- else
- cnt1 = currpage - startpage;
- cnt2 = len / NE_PAGE_SIZE;
- if (len % NE_PAGE_SIZE)
- cnt2++;
- if (cnt1 < cnt2)
- {
-#ifdef DEBUG_NE
- printk("(%x<%x:%x)\n", cnt1, cnt2, len);
-/*
- printk("start page 0x%x; current page 0x%x\n",
- startpage, currpage);
- printk("cnt1 < cnt2 (0x%x, 0x%x); len 0x%x\n",
- cnt1, cnt2, len);
-*/
-#endif
- reset = 1;
- }
- if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
- len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
- len > MCLBYTES)
- {
-#ifdef DEBUG_NE
- printk("(%x)", len);
-
- printk("start page 0x%x; current page 0x%x\n",
- startpage, currpage);
- printk("len out of range: 0x%x\n", len);
- printk("stat: 0x%x, next: 0x%x\n", hdr.rsr, hdr.next);
-#endif
- reset = 1;
- }
-#ifdef DEBUG_NE
- if (++ccc == 100)
- { ccc = 0; reset = 1;
- printk("T");
- }
-#endif
-
- /* reset interface */
- if (reset)
- {
- printk("Reset in RX\n");
- ne_reset(sc);
- goto Next;
- }
-
- /* The first four bytes of the length are the buffer header
- * Just decrease them by 2 since in ARM, we have to make sure
- * 4bytes memory access align on 4bytes
- */
- len -= 2;
- startaddr += 2;
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
-
- if (m == NULL)
- panic ("ne_rx_daemon");
-
- m->m_pkthdr.rcvif = ifp;
- m->m_nextpkt = 0;
-
- p = mtod (m, unsigned char *);
- m->m_len = m->m_pkthdr.len = len - (sizeof(struct ether_header) + 2);
-
- toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
- if (toend < len)
- {
- ne_read_data (sc, startaddr, toend, p);
- p += toend;
- len -= toend;
- startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
- }
-
- if (len > 0)
- ne_read_data (sc, startaddr, len, p);
-
- m->m_data +=2;
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof (struct ether_header);
-
-#ifdef DEBUG_NE
- /*printk("[r%d]", hdr.count - sizeof(hdr));*/
- printk("<\n");
-#endif
- ether_input (ifp, eh, m);
- ++sc->stats.rx_packets;
- outport_byte (port + BNRY, next - 1);
- }
-
- if (sc->overrun) {
- outport_byte (port + ISR, MSK_OVW);
- outport_byte (port + TCR, 0);
- if (sc->resend)
- outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
- sc->resend = 0;
- sc->overrun = 0;
- }
-
- Next:
- /* Reenable device interrupts. */
- outport_byte (port + IMR, NE_INTERRUPTS);
- }
-}
-
-/* Load an NE2000 packet onto the device. */
-
-static void
-ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
-{
- unsigned int port = sc->port;
- unsigned int dport = port + DATAPORT;
- struct mbuf *mhold = m;
- int leftover;
- unsigned char leftover_data;
- int timeout;
- int send_cnt = 0;
-
-#ifdef DEBUG_NE2000
- printk ("Uploading NE2000 packet\n");
-#endif
-
- /* Reset remote DMA complete flag. */
- outport_byte (port + ISR, MSK_RDC);
-
- /* Write out the count. */
- outport_byte (port + RBCR0, m->m_pkthdr.len);
- outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
-
- sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
-
- /* Tell the device which address we want to write to. */
- outport_byte (port + RSAR0, 0);
- outport_byte (port + RSAR1,
- NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
-
- /* Set up the write. */
- outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
-
- /* Transfer the mbuf chain to device memory. NE2000 devices require
- that the data be transferred as words, so we need to handle odd
- length mbufs. Never occurs if we force byte transfers. */
-
- leftover = 0;
- leftover_data = '\0';
-
- for (; m != NULL; m = m->m_next) {
- int len;
- unsigned char *data;
-
- len = m->m_len;
- if (len == 0)
- continue;
-
- data = mtod (m, unsigned char *);
-
- if (leftover) {
- unsigned char next;
-
- /* Data left over from previous mbuf in chain. */
- next = *data++;
- --len;
- outport_word (dport, leftover_data | (next << 8));
- send_cnt += 2;
- leftover = 0;
- }
-
- /* If using byte transfers, len always ends up as zero so
- there are no leftovers. */
-
- if (sc->byte_transfers)
- while (len > 0) {
- outport_byte (dport, *data++);
- len--;
- }
- else
- while (len > 1) {
- outport_word (dport, data[0] | (data[1] << 8));
- data += 2;
- len -= 2;
- send_cnt += 2;
- }
-
- if (len > 0)
- {
- leftover = 1;
- leftover_data = *data++;
- }
- }
-
- if (leftover)
- {
- outport_word (dport, leftover_data);
- send_cnt += 2;
- }
-
-#ifdef DEBUG_NE
- /* printk("{l%d|%d}", send_cnt, sc->nextavail); */
- printk("v");
-#endif
- m_freem (mhold);
-
- /* Wait for the device to complete accepting the data, with a
- limiting counter so that we don't wait too long. */
- for (timeout = 0; timeout < 1000; ++timeout)
- {
- unsigned char status;
-
- inport_byte (port + ISR, status);
-
-#ifdef DEBUG_NE2000
- if ((status &~ MSK_RDC) != 0)
- printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
- status);
-#endif
-
- if ((status & MSK_RDC) != 0) {
- outport_byte (port + ISR, MSK_RDC);
- break;
- }
- }
-
- if (timeout >= 1000)
- printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
-
- ++sc->nextavail;
- if (sc->nextavail == NE_TX_BUFS)
- sc->nextavail = 0;
-}
-
-/* Tell the NE2000 to transmit a buffer whose contents we have already
- loaded onto the device. */
-
-static void
-ne_transmit (struct ne_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned int port = sc->port;
- int len;
-
-#ifdef DEBUG_NE2000
- printk ("Transmitting NE2000 packet\n");
-#endif
-
- len = sc->sendlen[sc->nextsend];
- if (len < ET_MINLEN)
- len = ET_MINLEN;
- outport_byte (port + TBCR0, len);
- outport_byte (port + TBCR1, len >> 8);
-
- outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
-
- outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
-
-#ifdef DEBUG_NE
- /* printk("{s%d|%d}", len, sc->nextsend); */
- printk(">");
-#endif
- ++sc->nextsend;
- if (sc->nextsend == NE_TX_BUFS)
- sc->nextsend = 0;
-
- ++sc->stats.tx_packets;
-
- /* set watchdog timer */
- ifp->if_timer = 2;
-}
-
-/* The NE2000 packet transmit daemon. This task is started when the
- NE2000 driver is initialized. */
-
-static void
-ne_tx_daemon (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- unsigned int port = sc->port;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- while (1) {
- rtems_event_set events;
-
- /* Wait for a packet to be ready for sending, or for there to be
- room for another packet in the device memory. */
- rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events);
-
-#ifdef DEBUG_NE2000
- printk ("ne_tx_daemon\n");
-#endif
-
- /* This daemon handles both uploading data onto the device and
- telling the device to transmit data which has been uploaded.
- These are separate tasks, because while the device is
- transmitting one buffer we will upload another. */
-
- /* Don't let the device interrupt us now. */
- outport_byte (port + IMR, 0);
-
- while (1) {
- struct mbuf *m;
-
- /* If the device is not transmitting a packet, and we have
- uploaded a packet, tell the device to transmit it. */
- if (! sc->transmitting && sc->inuse > 0) {
- sc->transmitting = 1;
- ne_transmit (sc);
- }
-
- /* If we don't have any more buffers to send, quit now. */
- if (ifp->if_snd.ifq_head == NULL) {
- ifp->if_flags &= ~IFF_OACTIVE;
- break;
- }
-
- /* Allocate a buffer to load data into. If there are none
- available, quit until a buffer has been transmitted. */
- if (sc->inuse >= NE_TX_BUFS)
- break;
-
- ++sc->inuse;
-
- IF_DEQUEUE (&ifp->if_snd, m);
- if (m == NULL)
- panic ("ne_tx_daemon");
-
- ne_loadpacket (sc, m);
-
- /* Check the device status. It may have finished transmitting
- the last packet. */
- ne_check_status(sc, 0);
- }
-
- /* Reenable device interrupts. */
- outport_byte (port + IMR, NE_INTERRUPTS);
- }
-}
-
-/* Start sending an NE2000 packet. */
-
-static void
-ne_start (struct ifnet *ifp)
-{
- struct ne_softc *sc = ifp->if_softc;
-
-#ifdef DEBUG_NE
- printk("S");
-#endif
- /* Tell the transmit daemon to wake up and send a packet. */
- rtems_bsdnet_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/* Initialize and start and NE2000. */
-
-static void
-ne_init (void *arg)
-{
- struct ne_softc *sc = (struct ne_softc *) arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
-#ifdef DEBUG_NE
- printk("ne_init()\n");
- ne_dump(sc);
-#endif
-
- /* only once... */
- if (sc->tx_daemon_tid == 0)
- {
- sc->inuse = 0;
- sc->nextavail = 0;
- sc->nextsend = 0;
- sc->transmitting = 0;
-
- ne_init_hardware (sc);
-
- sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
- sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
-
- /* install rtems irq handler */
- ne_init_irq_handler(sc);
- }
-
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/* Stop an NE2000. */
-
-static void
-ne_stop (struct ne_softc *sc)
-{
- sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
-
- ne_stop_hardware(sc);
-
- sc->inuse = 0;
- sc->nextavail = 0;
- sc->nextsend = 0;
- sc->transmitting = 0;
- sc->overrun = 0;
- sc->resend = 0;
-}
-
-static void
-ne_stop_hardware (struct ne_softc *sc)
-{
- unsigned int port = sc->port;
- int i;
-
- /* Stop everything. */
- outport_byte (port + CMDR, MSK_STP | MSK_RD2);
-
- /* Wait for the interface to stop, using I as a time limit. */
- for (i = 0; i < 5000; ++i)
- {
- unsigned char status;
-
- inport_byte (port + ISR, status);
- if ((status & MSK_RST) != 0)
- break;
- }
-}
-
-/* reinitializing interface
-*/
-static void
-ne_reset(struct ne_softc *sc)
-{
- ne_stop(sc);
- ne_init_hardware(sc);
- sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-#ifdef DEBUG_NE
- printk("*");
-#endif
-}
-
-#ifdef DEBUG_NE
-/* show anything about ne
-*/
-static void
-ne_dump(struct ne_softc *sc)
-{
- int i;
- printk("\nne configuration:\n");
- printk("ethernet addr:");
- for (i=0; i<ETHER_ADDR_LEN; i++)
- printk(" %x", sc->arpcom.ac_enaddr[i]);
- printk("\n");
- printk("irq = %d\n", sc->irno);
- printk("port = 0x%x\n", sc->port);
- printk("accept_broadcasts = %d\n", sc->accept_broadcasts);
- printk("byte_transfers = %d\n", sc->byte_transfers);
-}
-#endif
-
-/* Show NE2000 interface statistics. */
-
-static void
-ne_stats (struct ne_softc *sc)
-{
- printf (" Received packets: %-8lu", sc->stats.rx_packets);
- printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
- printf (" Receive acks: %-8lu", sc->stats.rx_acks);
- printf (" Transmit acks: %-8lu\n", sc->stats.tx_acks);
- printf (" Packet overruns: %-8lu", sc->stats.overruns);
- printf (" Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
- printf (" CRC errors: %-8lu", sc->stats.rx_crc_errors);
- printf (" Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
- printf (" Interrupts: %-8lu\n", sc->stats.interrupts);
-}
-
-/* NE2000 driver ioctl handler. */
-
-static int
-ne_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct ne_softc *sc = ifp->if_softc;
- int error = 0;
-
- switch (command) {
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- error = ether_ioctl (ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
- case IFF_RUNNING:
- ne_stop (sc);
- break;
-
- case IFF_UP:
- printk("IFF_UP\n");
- ne_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- ne_stop (sc);
- ne_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- ne_stats (sc);
- break;
-
- /* FIXME: Multicast commands must be added here. */
-
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/*
- * Device timeout/watchdog routine. Entered if the device neglects to
- * generate an interrupt after a transmit has been started on it.
- */
-static void
-ne_watchdog(struct ifnet *ifp)
-{
- struct ne_softc *sc = ifp->if_softc;
-
- printk("ne2000: device timeout\n");
- ifp->if_oerrors++;
-
- ne_reset(sc);
-}
-
-static void
-print_byte(unsigned char b)
-{
- printk("%x%x", b >> 4, b & 0x0f);
-}
-
-/* Attach an NE2000 driver to the system. */
-
-int
-rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
-{
- int i;
- struct ne_softc *sc;
- struct ifnet *ifp;
- int mtu;
-
- /* dettach ... */
- if (!attach)
- return 0;
-
- /* Find a free driver. */
- sc = NULL;
- for (i = 0; i < NNEDRIVER; ++i) {
- sc = &ne_softc[i];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc == NULL)
- break;
- }
-
- if (sc == NULL) {
- printf ("Too many NE2000 drivers.\n");
- return 0;
- }
-
- memset (sc, 0, sizeof *sc);
-
- /* Check whether we do byte-wide or word-wide transfers. */
-
-#ifdef NE2000_BYTE_TRANSFERS
- sc->byte_transfers = true;
-#else
- sc->byte_transfers = false;
-#endif
-
- /* Handle the options passed in by the caller. */
-
- if (config->mtu != 0)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- /* We use 16 as the default IRQ. */
- sc->irno = XSCALE_IRQ_NETWORK;
-
-
-
- /*IO prts are mapped to 0X40000600 */
- sc->port = 0x40000600;
-
- sc->accept_broadcasts = ! config->ignore_broadcast;
-
- if (config->hardware_address != NULL)
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
- ETHER_ADDR_LEN);
- else
- {
- unsigned char prom[16];
- int ia;
-
- /* Read the PROM to get the Ethernet hardware address. */
-
- outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- if (sc->byte_transfers) {
- outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
- }
- else {
- outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
- }
-
- outport_byte (sc->port + RBCR0, 0);
- outport_byte (sc->port + RBCR1, 0);
- outport_byte (sc->port + RCR, MSK_MON);
- outport_byte (sc->port + TCR, MSK_LOOP);
- outport_byte (sc->port + IMR, 0);
- outport_byte (sc->port + ISR, 0xff);
-
- ne_read_data (sc, 0, sizeof prom, prom);
-
- outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
-
- for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
- sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
- }
-
- /* Set up the network interface. */
-
- ifp->if_softc = sc;
- ifp->if_unit = i + 1;
- ifp->if_name = "ne";
- ifp->if_mtu = mtu;
- ifp->if_init = ne_init;
- ifp->if_ioctl = ne_ioctl;
- ifp->if_watchdog = ne_watchdog;
- ifp->if_start = ne_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);
-
- printk("network device '%s' <", config->name);
- print_byte(sc->arpcom.ac_enaddr[0]);
- for (i=1; i<ETHER_ADDR_LEN; i++)
- { printk(":");
- print_byte(sc->arpcom.ac_enaddr[i]);
- }
- printk("> initialized on port 0x%x, irq %d\n", sc->port, sc->irno);
-
- return 1;
-}
diff --git a/bsps/arm/gumstix/net/wd80x3.h b/bsps/arm/gumstix/net/wd80x3.h
deleted file mode 100644
index 0a9f3432bc..0000000000
--- a/bsps/arm/gumstix/net/wd80x3.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
- * @file
- * @ingroup gumstix_dp8390
- * @brief DP8390 Ethernet Controller Support
- */
-
-/*
- * Information about the DP8390 Ethernet controller.
- */
-
-#ifndef __BSP_WD80x3_h
-#define __BSP_WD80x3_h
-
-/* Register descriptions */
-
-/**
- * @defgroup gumstix_dp8390 DP8390 Support
- * @ingroup RTEMSBSPsARMGumstix
- * @brief DP8390 Ethernet Controller Support
- * @{
- */
-
-/**
- * @name Controller DP8390.
- * @{
- */
-
-/** @brief Port Window. */
-#define DATAPORT 0x10
-/** @brief Issue a read for reset */
-#define RESET 0x1f
-/** @brief I/O port definition */
-#define W83CREG 0x00
-#define ADDROM 0x08
-
-/** @} */
-
-/**
- * @name page 0 read or read/write registers
- * @{
- */
-
-#define CMDR 0x00+RO
-/** @brief current local dma addr 0 for read */
-#define CLDA0 0x01+RO
-/** @brief current local dma addr 1 for read */
-#define CLDA1 0x02+RO
-/** @brief boundary reg for rd and wr */
-#define BNRY 0x03+RO
-/** @brief tx status reg for rd */
-#define TSR 0x04+RO
-/** @brief number of collision reg for rd */
-#define NCR 0x05+RO
-/** @breif FIFO for rd */
-#define FIFO 0x06+RO
-/** @brief interrupt status reg for rd and wr */
-#define ISR 0x07+RO
-/** @brief current remote dma address 0 for rd */
-#define CRDA0 0x08+RO
-/** @brief current remote dma address 1 for rd */
-#define CRDA1 0x09+RO
-/** @brief rx status reg for rd */
-#define RSR 0x0C+RO
-/** @brief tally cnt 0 for frm alg err for rd */
-#define CNTR0 0x0D+RO
-/** @brief tally cnt 1 for crc err for rd */
-#define CNTR1 RO+0x0E
-/** @brief tally cnt 2 for missed pkt for rd */
-#define CNTR2 0x0F+RO
-
-/** @} */
-
-/**
- * @name page 0 write registers
- * @{
- */
-
-/** @brief page start register */
-#define PSTART 0x01+RO
-/** @brief page stop register */
-#define PSTOP 0x02+RO
-/** @breif tx start page start reg */
-#define TPSR 0x04+RO
-/** @brief tx byte count 0 reg */
-#define TBCR0 0x05+RO
-/** @brief tx byte count 1 reg */
-#define TBCR1 0x06+RO
-/** @brief remote start address reg 0 */
-#define RSAR0 0x08+RO
-/** @brief remote start address reg 1 */
-#define RSAR1 0x09+RO
-/** @brief remote byte count reg 0 */
-#define RBCR0 0x0A+RO
-/** @brief remote byte count reg 1 */
-#define RBCR1 0x0B+RO
-/** @brief rx configuration reg */
-#define RCR 0x0C+RO
-/** @brief tx configuration reg */
-#define TCR 0x0D+RO
-/** @brief data configuration reg */
-#define DCR RO+0x0E
-/** @brief interrupt mask reg */
-#define IMR 0x0F+RO
-
-/** @} */
-
-/**
- * @name page 1 registers
- * @{
- */
-
-/** @brief physical addr reg base for rd and wr */
-#define PAR 0x01+RO
-/** @brief current page reg for rd and wr */
-#define CURR 0x07+RO
-/** @brief multicast addr reg base fro rd and WR */
-#define MAR 0x08+RO
-/** @brief size of multicast addr space */
-#define MARsize 8
-
-/** @} */
-
-/**
- * @name W83CREG command bits
- * @{
- */
-
-/** @brief W83CREG masks */
-#define MSK_RESET 0x80
-#define MSK_ENASH 0x40
-/** @brief memory decode bits, corresponding */
-#define MSK_DECOD 0x3F
-
-/** @} */
-
-/**
- * @name CMDR command bits
- * @{
- */
-
-/** @brief stop the chip */
-#define MSK_STP 0x01
-/** @brief start the chip */
-#define MSK_STA 0x02
-/** @brief initial txing of a frm */
-#define MSK_TXP 0x04
-/** @brief remote read */
-#define MSK_RRE 0x08
-/** @brief remote write */
-#define MSK_RWR 0x10
-/** @brief no DMA used */
-#define MSK_RD2 0x20
-/** @brief select register page 0 */
-#define MSK_PG0 0x00
-/** @brief select register page 1 */
-#define MSK_PG1 0x40
-/** @brief select register page 2 */
-#define MSK_PG2 0x80
-
-/** @} */
-
-/**
- * @name ISR and TSR status bits
- * @{
- */
-
-/* @brief rx with no error */
-#define MSK_PRX 0x01
-/* @brief tx with no error */
-#define MSK_PTX 0x02
-/* @brief rx with error */
-#define MSK_RXE 0x04
-/* @brief tx with error */
-#define MSK_TXE 0x08
-/* @brief overwrite warning */
-#define MSK_OVW 0x10
-/* @brief MSB of one of the tally counters is set */
-#define MSK_CNT 0x20
-/* @brief remote dma completed */
-#define MSK_RDC 0x40
-/* @brief reset state indicator */
-#define MSK_RST 0x80
-
-/** @} */
-
-/**
- * @name DCR command bits
- * @{
- */
-
-/** @brief word transfer mode selection */
-#define MSK_WTS 0x01
-/** @brief byte order selection */
-#define MSK_BOS 0x02
-/** @brief long addr selection */
-#define MSK_LAS 0x04
-/** @brief burst mode selection */
-#define MSK_BMS 0x08
-/** @brief autoinitialize remote */
-#define MSK_ARM 0x10
-/** @brief burst lrngth selection */
-#define MSK_FT00 0x00
-/** @brief burst lrngth selection */
-#define MSK_FT01 0x20
-/** @brief burst lrngth selection */
-#define MSK_FT10 0x40
-/** @brief burst lrngth selection */
-#define MSK_FT11 0x60
-
-/** @} */
-
-/**
- * @name RCR command bits
- * @{
- */
-
-/** @brief save error pkts */
-#define MSK_SEP 0x01
-/** @brief accept runt pkt */
-#define MSK_AR 0x02
-/** @brief 8390 RCR */
-#define MSK_AB 0x04
-/** @brief accept multicast */
-#define MSK_AM 0x08
-/** @brief accept all pkt with physical adr */
-#define MSK_PRO 0x10
-/** @brief monitor mode */
-#define MSK_MON 0x20
-
-/** @} */
-
-/**
- * @name TCR command bits
- * @{
- */
-
-/** @brief inhibit CRC, do not append crc */
-#define MSK_CRC 0x01
-/** @brief set loopback mode */
-#define MSK_LOOP 0x02
-/** @brief Accept broadcasts */
-#define MSK_BCST 0x04
-/** @brief encoded loopback control */
-#define MSK_LB01 0x06
-/** @brief auto tx disable */
-#define MSK_ATD 0x08
-/** @brief collision offset enable */
-#define MSK_OFST 0x10
-
-/** @} */
-
-/**
- * @name receive status bits
- * @{
- */
-
-/** @brief rx without error */
-#define SMK_PRX 0x01
-/** @brief CRC error */
-#define SMK_CRC 0x02
-/** @brief frame alignment error */
-#define SMK_FAE 0x04
-/** @brief FIFO overrun */
-#define SMK_FO 0x08
-/** @brief missed pkt */
-#define SMK_MPA 0x10
-/** @brief physical/multicase address */
-#define SMK_PHY 0x20
-/** @brief receiver disable. set in monitor mode */
-#define SMK_DIS 0x40
-/** @brief deferring */
-#define SMK_DEF 0x80
-
-/** @} */
-
-/**
- * @name transmit status bits
- * @{
- */
-
-/** @brief tx without error */
-#define SMK_PTX 0x01
-/** @brief non deferred tx */
-#define SMK_DFR 0x02
-/** @brief tx collided */
-#define SMK_COL 0x04
-/** @brief tx abort because of excessive collisions */
-#define SMK_ABT 0x08
-/** @brief carrier sense lost */
-#define SMK_CRS 0x10
-/** @brief FIFO underrun */
-#define SMK_FU 0x20
-/** @brief collision detect heartbeat */
-#define SMK_CDH 0x40
-/** @brief out of window collision */
-#define SMK_OWC 0x80
-
-/** @} */
-
-/** @} */
-
-#endif
-/* end of include */
diff --git a/bsps/arm/rtl22xx/net/network.c b/bsps/arm/rtl22xx/net/network.c
deleted file mode 100644
index 5581b8fab5..0000000000
--- a/bsps/arm/rtl22xx/net/network.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*Note: this file is copy from 7312 BSP, and untested yet*/
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <rtems.h>
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <bsp/irq.h>
-#include <libchip/cs8900.h>
-#include <assert.h>
-
-#define CS8900_BASE 0x20000300
-unsigned int bsp_cs8900_io_base = 0;
-unsigned int bsp_cs8900_memory_base = 0;
-static void cs8900_isr(void *);
-
-char g_enetbuf[1520];
-
-static void cs8900_isr(void *arg)
-{
- cs8900_interrupt(LPC22xx_INTERRUPT_EINT2, arg);
-}
-
-/* cs8900_io_set_reg - set one of the I/O addressed registers */
-void cs8900_io_set_reg (cs8900_device *cs, unsigned short reg, unsigned short data)
-{
- /* works the same for all values of dev */
-/*
- printf("cs8900_io_set_reg: reg: %#6x, val %#6x\n",
- CS8900_BASE + reg,
- data);
-*/
- *(unsigned short *)(CS8900_BASE + reg) = data;
-}
-
-/* cs8900_io_get_reg - reads one of the I/O addressed registers */
-unsigned short cs8900_io_get_reg (cs8900_device *cs, unsigned short reg)
-{
- unsigned short val;
- /* works the same for all values of dev */
- val = *(unsigned short *)(CS8900_BASE + reg);
-/*
- printf("cs8900_io_get_reg: reg: %#6x, val %#6x\n", reg, val);
-*/
- return val;
-}
-
-/* cs8900_mem_set_reg - sets one of the registers mapped through
- * PacketPage
- */
-void cs8900_mem_set_reg (cs8900_device *cs, unsigned long reg, unsigned short data)
-{
- /* works the same for all values of dev */
- cs8900_io_set_reg(cs, CS8900_IO_PACKET_PAGE_PTR, reg);
- cs8900_io_set_reg(cs, CS8900_IO_PP_DATA_PORT0, data);
-}
-
-/* cs8900_mem_get_reg - reads one of the registers mapped through
- * PacketPage
- */
-unsigned short cs8900_mem_get_reg (cs8900_device *cs, unsigned long reg)
-{
- /* works the same for all values of dev */
- cs8900_io_set_reg(cs, CS8900_IO_PACKET_PAGE_PTR, reg);
- return cs8900_io_get_reg(cs, CS8900_IO_PP_DATA_PORT0);
-}
-
-void cs8900_attach_interrupt (cs8900_device *cs)
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
- status = rtems_interrupt_handler_install(
- LPC22xx_INTERRUPT_EINT2,
- "Network",
- RTEMS_INTERRUPT_UNIQUE,
- cs8900_isr,
- cs
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-void cs8900_detach_interrupt (cs8900_device *cs)
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
- status = rtems_interrupt_handler_remove(
- LPC22xx_INTERRUPT_EINT2,
- cs8900_isr,
- cs
- );
- assert(status == RTEMS_SUCCESSFUL);
-}
-
-unsigned short cs8900_get_data_block (cs8900_device *cs, unsigned char *data)
-{
- int len;
- int i;
-
- len = cs8900_mem_get_reg(cs, CS8900_PP_RxLength);
-
- for (i = 0; i < ((len + 1) / 2); i++) {
- ((short *)data)[i] = cs8900_io_get_reg(cs,
- CS8900_IO_RX_TX_DATA_PORT0);
- }
- return len;
-}
-
-void cs8900_tx_load (cs8900_device *cs, struct mbuf *m)
-{
- int len;
- unsigned short *data;
- int i;
-
- len = 0;
-
- do {
- memcpy(&g_enetbuf[len], mtod(m, const void *), m->m_len);
- len += m->m_len;
- m = m->m_next;
- } while (m != 0);
-
- data = (unsigned short *) &g_enetbuf[0];
- for (i = 0; i < ((len + 1) / 2); i++) {
- cs8900_io_set_reg(cs,
- CS8900_IO_RX_TX_DATA_PORT0,
- data[i]);
- }
-}
diff --git a/bsps/arm/shared/net/lpc-ethernet.c b/bsps/arm/shared/net/lpc-ethernet.c
deleted file mode 100644
index ccfe1696eb..0000000000
--- a/bsps/arm/shared/net/lpc-ethernet.c
+++ /dev/null
@@ -1,1839 +0,0 @@
-/**
- * @file
- *
- * @ingroup lpc_eth
- *
- * @brief Ethernet driver.
- */
-
-/*
- * Copyright (c) 2009-2012 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 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.
- */
-
-#include <machine/rtems-bsd-kernel-space.h>
-
-#include <errno.h>
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/rtems_mii_ioctl.h>
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/lpc-ethernet-config.h>
-#include <bsp/utility.h>
-
-#if MCLBYTES > (2 * 1024)
- #error "MCLBYTES to large"
-#endif
-
-#ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- #define LPC_ETH_CONFIG_TX_BUF_SIZE sizeof(struct mbuf *)
-#else
- #define LPC_ETH_CONFIG_TX_BUF_SIZE 1518U
-#endif
-
-#define DEFAULT_PHY 0
-#define WATCHDOG_TIMEOUT 5
-
-typedef struct {
- uint32_t start;
- uint32_t control;
-} lpc_eth_transfer_descriptor;
-
-typedef struct {
- uint32_t info;
- uint32_t hash_crc;
-} lpc_eth_receive_status;
-
-typedef struct {
- uint32_t mac1;
- uint32_t mac2;
- uint32_t ipgt;
- uint32_t ipgr;
- uint32_t clrt;
- uint32_t maxf;
- uint32_t supp;
- uint32_t test;
- uint32_t mcfg;
- uint32_t mcmd;
- uint32_t madr;
- uint32_t mwtd;
- uint32_t mrdd;
- uint32_t mind;
- uint32_t reserved_0 [2];
- uint32_t sa0;
- uint32_t sa1;
- uint32_t sa2;
- uint32_t reserved_1 [45];
- uint32_t command;
- uint32_t status;
- uint32_t rxdescriptor;
- uint32_t rxstatus;
- uint32_t rxdescriptornum;
- uint32_t rxproduceindex;
- uint32_t rxconsumeindex;
- uint32_t txdescriptor;
- uint32_t txstatus;
- uint32_t txdescriptornum;
- uint32_t txproduceindex;
- uint32_t txconsumeindex;
- uint32_t reserved_2 [10];
- uint32_t tsv0;
- uint32_t tsv1;
- uint32_t rsv;
- uint32_t reserved_3 [3];
- uint32_t flowcontrolcnt;
- uint32_t flowcontrolsts;
- uint32_t reserved_4 [34];
- uint32_t rxfilterctrl;
- uint32_t rxfilterwolsts;
- uint32_t rxfilterwolclr;
- uint32_t reserved_5 [1];
- uint32_t hashfilterl;
- uint32_t hashfilterh;
- uint32_t reserved_6 [882];
- uint32_t intstatus;
- uint32_t intenable;
- uint32_t intclear;
- uint32_t intset;
- uint32_t reserved_7 [1];
- uint32_t powerdown;
-} lpc_eth_controller;
-
-static volatile lpc_eth_controller *const lpc_eth =
- (volatile lpc_eth_controller *) LPC_ETH_CONFIG_REG_BASE;
-
-/* ETH_RX_CTRL */
-
-#define ETH_RX_CTRL_SIZE_MASK 0x000007ffU
-#define ETH_RX_CTRL_INTERRUPT 0x80000000U
-
-/* ETH_RX_STAT */
-
-#define ETH_RX_STAT_RXSIZE_MASK 0x000007ffU
-#define ETH_RX_STAT_BYTES 0x00000100U
-#define ETH_RX_STAT_CONTROL_FRAME 0x00040000U
-#define ETH_RX_STAT_VLAN 0x00080000U
-#define ETH_RX_STAT_FAIL_FILTER 0x00100000U
-#define ETH_RX_STAT_MULTICAST 0x00200000U
-#define ETH_RX_STAT_BROADCAST 0x00400000U
-#define ETH_RX_STAT_CRC_ERROR 0x00800000U
-#define ETH_RX_STAT_SYMBOL_ERROR 0x01000000U
-#define ETH_RX_STAT_LENGTH_ERROR 0x02000000U
-#define ETH_RX_STAT_RANGE_ERROR 0x04000000U
-#define ETH_RX_STAT_ALIGNMENT_ERROR 0x08000000U
-#define ETH_RX_STAT_OVERRUN 0x10000000U
-#define ETH_RX_STAT_NO_DESCRIPTOR 0x20000000U
-#define ETH_RX_STAT_LAST_FLAG 0x40000000U
-#define ETH_RX_STAT_ERROR 0x80000000U
-
-/* ETH_TX_CTRL */
-
-#define ETH_TX_CTRL_SIZE_MASK 0x7ffU
-#define ETH_TX_CTRL_SIZE_SHIFT 0
-#define ETH_TX_CTRL_OVERRIDE 0x04000000U
-#define ETH_TX_CTRL_HUGE 0x08000000U
-#define ETH_TX_CTRL_PAD 0x10000000U
-#define ETH_TX_CTRL_CRC 0x20000000U
-#define ETH_TX_CTRL_LAST 0x40000000U
-#define ETH_TX_CTRL_INTERRUPT 0x80000000U
-
-/* ETH_TX_STAT */
-
-#define ETH_TX_STAT_COLLISION_COUNT_MASK 0x01e00000U
-#define ETH_TX_STAT_DEFER 0x02000000U
-#define ETH_TX_STAT_EXCESSIVE_DEFER 0x04000000U
-#define ETH_TX_STAT_EXCESSIVE_COLLISION 0x08000000U
-#define ETH_TX_STAT_LATE_COLLISION 0x10000000U
-#define ETH_TX_STAT_UNDERRUN 0x20000000U
-#define ETH_TX_STAT_NO_DESCRIPTOR 0x40000000U
-#define ETH_TX_STAT_ERROR 0x80000000U
-
-/* ETH_INT */
-
-#define ETH_INT_RX_OVERRUN 0x00000001U
-#define ETH_INT_RX_ERROR 0x00000002U
-#define ETH_INT_RX_FINISHED 0x00000004U
-#define ETH_INT_RX_DONE 0x00000008U
-#define ETH_INT_TX_UNDERRUN 0x00000010U
-#define ETH_INT_TX_ERROR 0x00000020U
-#define ETH_INT_TX_FINISHED 0x00000040U
-#define ETH_INT_TX_DONE 0x00000080U
-#define ETH_INT_SOFT 0x00001000U
-#define ETH_INT_WAKEUP 0x00002000U
-
-/* ETH_RX_FIL_CTRL */
-
-#define ETH_RX_FIL_CTRL_ACCEPT_UNICAST 0x00000001U
-#define ETH_RX_FIL_CTRL_ACCEPT_BROADCAST 0x00000002U
-#define ETH_RX_FIL_CTRL_ACCEPT_MULTICAST 0x00000004U
-#define ETH_RX_FIL_CTRL_ACCEPT_UNICAST_HASH 0x00000008U
-#define ETH_RX_FIL_CTRL_ACCEPT_MULTICAST_HASH 0x00000010U
-#define ETH_RX_FIL_CTRL_ACCEPT_PERFECT 0x00000020U
-#define ETH_RX_FIL_CTRL_MAGIC_PACKET_WOL 0x00001000U
-#define ETH_RX_FIL_CTRL_RX_FILTER_WOL 0x00002000U
-
-/* ETH_CMD */
-
-#define ETH_CMD_RX_ENABLE 0x00000001U
-#define ETH_CMD_TX_ENABLE 0x00000002U
-#define ETH_CMD_REG_RESET 0x00000008U
-#define ETH_CMD_TX_RESET 0x00000010U
-#define ETH_CMD_RX_RESET 0x00000020U
-#define ETH_CMD_PASS_RUNT_FRAME 0x00000040U
-#define ETH_CMD_PASS_RX_FILTER 0X00000080U
-#define ETH_CMD_TX_FLOW_CONTROL 0x00000100U
-#define ETH_CMD_RMII 0x00000200U
-#define ETH_CMD_FULL_DUPLEX 0x00000400U
-
-/* ETH_STAT */
-
-#define ETH_STAT_RX_ACTIVE 0x00000001U
-#define ETH_STAT_TX_ACTIVE 0x00000002U
-
-/* ETH_MAC2 */
-
-#define ETH_MAC2_FULL_DUPLEX BSP_BIT32(8)
-
-/* ETH_SUPP */
-
-#define ETH_SUPP_SPEED BSP_BIT32(8)
-
-/* ETH_MCFG */
-
-#define ETH_MCFG_CLOCK_SELECT(val) BSP_FLD32(val, 2, 4)
-
-#define ETH_MCFG_RESETMIIMGMT BSP_BIT32(15)
-
-/* ETH_MCMD */
-
-#define ETH_MCMD_READ BSP_BIT32(0)
-#define ETH_MCMD_SCAN BSP_BIT32(1)
-
-/* ETH_MADR */
-
-#define ETH_MADR_REG(val) BSP_FLD32(val, 0, 4)
-#define ETH_MADR_PHY(val) BSP_FLD32(val, 8, 12)
-
-/* ETH_MIND */
-
-#define ETH_MIND_BUSY BSP_BIT32(0)
-#define ETH_MIND_SCANNING BSP_BIT32(1)
-#define ETH_MIND_NOT_VALID BSP_BIT32(2)
-#define ETH_MIND_MII_LINK_FAIL BSP_BIT32(3)
-
-/* Events */
-
-#define LPC_ETH_EVENT_INITIALIZE RTEMS_EVENT_1
-
-#define LPC_ETH_EVENT_TXSTART RTEMS_EVENT_2
-
-#define LPC_ETH_EVENT_INTERRUPT RTEMS_EVENT_3
-
-#define LPC_ETH_EVENT_STOP RTEMS_EVENT_4
-
-/* Status */
-
-#define LPC_ETH_INTERRUPT_RECEIVE \
- (ETH_INT_RX_ERROR | ETH_INT_RX_FINISHED | ETH_INT_RX_DONE)
-
-#define LPC_ETH_INTERRUPT_TRANSMIT \
- (ETH_INT_TX_DONE | ETH_INT_TX_FINISHED | ETH_INT_TX_ERROR)
-
-#define LPC_ETH_RX_STAT_ERRORS \
- (ETH_RX_STAT_CRC_ERROR \
- | ETH_RX_STAT_SYMBOL_ERROR \
- | ETH_RX_STAT_LENGTH_ERROR \
- | ETH_RX_STAT_ALIGNMENT_ERROR \
- | ETH_RX_STAT_OVERRUN \
- | ETH_RX_STAT_NO_DESCRIPTOR)
-
-#define LPC_ETH_LAST_FRAGMENT_FLAGS \
- (ETH_TX_CTRL_OVERRIDE \
- | ETH_TX_CTRL_PAD \
- | ETH_TX_CTRL_CRC \
- | ETH_TX_CTRL_INTERRUPT \
- | ETH_TX_CTRL_LAST)
-
-/* Debug */
-
-#ifdef DEBUG
- #define LPC_ETH_PRINTF(...) printf(__VA_ARGS__)
- #define LPC_ETH_PRINTK(...) printk(__VA_ARGS__)
-#else
- #define LPC_ETH_PRINTF(...)
- #define LPC_ETH_PRINTK(...)
-#endif
-
-typedef enum {
- LPC_ETH_STATE_NOT_INITIALIZED = 0,
- LPC_ETH_STATE_DOWN,
- LPC_ETH_STATE_UP
-} lpc_eth_state;
-
-typedef struct {
- struct arpcom arpcom;
- lpc_eth_state state;
- struct rtems_mdio_info mdio;
- uint32_t anlpar;
- rtems_id receive_task;
- rtems_id transmit_task;
- unsigned rx_unit_count;
- unsigned tx_unit_count;
- volatile lpc_eth_transfer_descriptor *rx_desc_table;
- volatile lpc_eth_receive_status *rx_status_table;
- struct mbuf **rx_mbuf_table;
- volatile lpc_eth_transfer_descriptor *tx_desc_table;
- volatile uint32_t *tx_status_table;
- void *tx_buf_table;
- unsigned received_frames;
- unsigned receive_interrupts;
- unsigned transmitted_frames;
- unsigned transmit_interrupts;
- unsigned receive_drop_errors;
- unsigned receive_overrun_errors;
- unsigned receive_fragment_errors;
- unsigned receive_crc_errors;
- unsigned receive_symbol_errors;
- unsigned receive_length_errors;
- unsigned receive_alignment_errors;
- unsigned receive_no_descriptor_errors;
- unsigned receive_fatal_errors;
- unsigned transmit_underrun_errors;
- unsigned transmit_late_collision_errors;
- unsigned transmit_excessive_collision_errors;
- unsigned transmit_excessive_defer_errors;
- unsigned transmit_no_descriptor_errors;
- unsigned transmit_overflow_errors;
- unsigned transmit_fatal_errors;
- uint32_t phy_id;
- int phy;
- rtems_vector_number interrupt_number;
- rtems_id control_task;
-} lpc_eth_driver_entry;
-
-static lpc_eth_driver_entry lpc_eth_driver_data;
-
-static void lpc_eth_control_request_complete(const lpc_eth_driver_entry *e)
-{
- rtems_status_code sc = rtems_event_transient_send(e->control_task);
- assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void lpc_eth_control_request(
- lpc_eth_driver_entry *e,
- rtems_id task,
- rtems_event_set event
-)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- uint32_t nest_count = 0;
-
- e->control_task = rtems_task_self();
-
- sc = rtems_bsdnet_event_send(task, event);
- assert(sc == RTEMS_SUCCESSFUL);
-
- nest_count = rtems_bsdnet_semaphore_release_recursive();
- sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- assert(sc == RTEMS_SUCCESSFUL);
- rtems_bsdnet_semaphore_obtain_recursive(nest_count);
-
- e->control_task = 0;
-}
-
-static inline uint32_t lpc_eth_increment(
- uint32_t value,
- uint32_t cycle
-)
-{
- if (value < cycle) {
- return ++value;
- } else {
- return 0;
- }
-}
-
-static void lpc_eth_enable_promiscous_mode(bool enable)
-{
- if (enable) {
- lpc_eth->rxfilterctrl = ETH_RX_FIL_CTRL_ACCEPT_UNICAST
- | ETH_RX_FIL_CTRL_ACCEPT_MULTICAST
- | ETH_RX_FIL_CTRL_ACCEPT_BROADCAST;
- } else {
- lpc_eth->rxfilterctrl = ETH_RX_FIL_CTRL_ACCEPT_PERFECT
- | ETH_RX_FIL_CTRL_ACCEPT_MULTICAST_HASH
- | ETH_RX_FIL_CTRL_ACCEPT_BROADCAST;
- }
-}
-
-static void lpc_eth_interrupt_handler(void *arg)
-{
- lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) arg;
- rtems_event_set re = 0;
- rtems_event_set te = 0;
- uint32_t ie = 0;
-
- /* Get interrupt status */
- uint32_t im = lpc_eth->intenable;
- uint32_t is = lpc_eth->intstatus & im;
-
- /* Check receive interrupts */
- if ((is & ETH_INT_RX_OVERRUN) != 0) {
- re = LPC_ETH_EVENT_INITIALIZE;
- ++e->receive_fatal_errors;
- } else if ((is & LPC_ETH_INTERRUPT_RECEIVE) != 0) {
- re = LPC_ETH_EVENT_INTERRUPT;
- ie |= LPC_ETH_INTERRUPT_RECEIVE;
- }
-
- /* Send events to receive task */
- if (re != 0) {
- ++e->receive_interrupts;
- (void) rtems_bsdnet_event_send(e->receive_task, re);
- }
-
- /* Check transmit interrupts */
- if ((is & ETH_INT_TX_UNDERRUN) != 0) {
- te = LPC_ETH_EVENT_INITIALIZE;
- ++e->transmit_fatal_errors;
- } else if ((is & LPC_ETH_INTERRUPT_TRANSMIT) != 0) {
- te = LPC_ETH_EVENT_INTERRUPT;
- ie |= LPC_ETH_INTERRUPT_TRANSMIT;
- }
-
- /* Send events to transmit task */
- if (te != 0) {
- ++e->transmit_interrupts;
- (void) rtems_bsdnet_event_send(e->transmit_task, te);
- }
-
- LPC_ETH_PRINTK("interrupt: rx = 0x%08x, tx = 0x%08x\n", re, te);
-
- /* Update interrupt mask */
- lpc_eth->intenable = im & ~ie;
-
- /* Clear interrupts */
- lpc_eth->intclear = is;
-}
-
-static void lpc_eth_enable_receive_interrupts(void)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- lpc_eth->intenable |= LPC_ETH_INTERRUPT_RECEIVE;
- rtems_interrupt_enable(level);
-}
-
-static void lpc_eth_disable_receive_interrupts(void)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- lpc_eth->intenable &= ~LPC_ETH_INTERRUPT_RECEIVE;
- rtems_interrupt_enable(level);
-}
-
-static void lpc_eth_enable_transmit_interrupts(void)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- lpc_eth->intenable |= LPC_ETH_INTERRUPT_TRANSMIT;
- rtems_interrupt_enable(level);
-}
-
-static void lpc_eth_disable_transmit_interrupts(void)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable(level);
- lpc_eth->intenable &= ~LPC_ETH_INTERRUPT_TRANSMIT;
- rtems_interrupt_enable(level);
-}
-
-#define LPC_ETH_RX_DATA_OFFSET 2
-
-static struct mbuf *lpc_eth_new_mbuf(struct ifnet *ifp, bool wait)
-{
- struct mbuf *m = NULL;
- int mw = wait ? M_WAIT : M_DONTWAIT;
-
- MGETHDR(m, mw, MT_DATA);
- if (m != NULL) {
- MCLGET(m, mw);
- if ((m->m_flags & M_EXT) != 0) {
- /* Set receive interface */
- m->m_pkthdr.rcvif = ifp;
-
- /* Adjust by two bytes for proper IP header alignment */
- m->m_data = mtod(m, char *) + LPC_ETH_RX_DATA_OFFSET;
-
- return m;
- } else {
- m_free(m);
- }
- }
-
- return NULL;
-}
-
-static bool lpc_eth_add_new_mbuf(
- struct ifnet *ifp,
- volatile lpc_eth_transfer_descriptor *desc,
- struct mbuf **mbufs,
- uint32_t i,
- bool wait
-)
-{
- /* New mbuf */
- struct mbuf *m = lpc_eth_new_mbuf(ifp, wait);
-
- /* Check mbuf */
- if (m != NULL) {
- /* Cache invalidate */
- rtems_cache_invalidate_multiple_data_lines(
- mtod(m, void *),
- MCLBYTES - LPC_ETH_RX_DATA_OFFSET
- );
-
- /* Add mbuf to queue */
- desc [i].start = mtod(m, uint32_t);
- desc [i].control = (MCLBYTES - LPC_ETH_RX_DATA_OFFSET - 1)
- | ETH_RX_CTRL_INTERRUPT;
-
- /* Cache flush of descriptor */
- rtems_cache_flush_multiple_data_lines(
- (void *) &desc [i],
- sizeof(desc [0])
- );
-
- /* Add mbuf to table */
- mbufs [i] = m;
-
- return true;
- } else {
- return false;
- }
-}
-
-static void lpc_eth_receive_task(void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_event_set events = 0;
- lpc_eth_driver_entry *const e = (lpc_eth_driver_entry *) arg;
- struct ifnet *const ifp = &e->arpcom.ac_if;
- volatile lpc_eth_transfer_descriptor *const desc = e->rx_desc_table;
- volatile lpc_eth_receive_status *const status = e->rx_status_table;
- struct mbuf **const mbufs = e->rx_mbuf_table;
- uint32_t const index_max = e->rx_unit_count - 1;
- uint32_t produce_index = 0;
- uint32_t consume_index = 0;
-
- LPC_ETH_PRINTF("%s\n", __func__);
-
- /* Main event loop */
- while (true) {
- /* Wait for events */
- sc = rtems_bsdnet_event_receive(
- LPC_ETH_EVENT_INITIALIZE
- | LPC_ETH_EVENT_STOP
- | LPC_ETH_EVENT_INTERRUPT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events
- );
- assert(sc == RTEMS_SUCCESSFUL);
-
- LPC_ETH_PRINTF("rx: wake up: 0x%08" PRIx32 "\n", events);
-
- /* Stop receiver? */
- if ((events & LPC_ETH_EVENT_STOP) != 0) {
- lpc_eth_control_request_complete(e);
-
- /* Wait for events */
- continue;
- }
-
- /* Initialize receiver? */
- if ((events & LPC_ETH_EVENT_INITIALIZE) != 0) {
- /* Disable receive interrupts */
- lpc_eth_disable_receive_interrupts();
-
- /* Disable receiver */
- lpc_eth->command &= ~ETH_CMD_RX_ENABLE;
-
- /* Wait for inactive status */
- while ((lpc_eth->status & ETH_STAT_RX_ACTIVE) != 0) {
- /* Wait */
- }
-
- /* Reset */
- lpc_eth->command |= ETH_CMD_RX_RESET;
-
- /* Clear receive interrupts */
- lpc_eth->intclear = LPC_ETH_INTERRUPT_RECEIVE;
-
- /* Move existing mbufs to the front */
- consume_index = 0;
- for (produce_index = 0; produce_index <= index_max; ++produce_index) {
- if (mbufs [produce_index] != NULL) {
- mbufs [consume_index] = mbufs [produce_index];
- ++consume_index;
- }
- }
-
- /* Fill receive queue */
- for (
- produce_index = consume_index;
- produce_index <= index_max;
- ++produce_index
- ) {
- lpc_eth_add_new_mbuf(ifp, desc, mbufs, produce_index, true);
- }
-
- /* Receive descriptor table */
- lpc_eth->rxdescriptornum = index_max;
- lpc_eth->rxdescriptor = (uint32_t) desc;
- lpc_eth->rxstatus = (uint32_t) status;
-
- /* Initialize indices */
- produce_index = lpc_eth->rxproduceindex;
- consume_index = lpc_eth->rxconsumeindex;
-
- /* Enable receiver */
- lpc_eth->command |= ETH_CMD_RX_ENABLE;
-
- /* Enable receive interrupts */
- lpc_eth_enable_receive_interrupts();
-
- lpc_eth_control_request_complete(e);
-
- /* Wait for events */
- continue;
- }
-
- while (true) {
- /* Clear receive interrupt status */
- lpc_eth->intclear = LPC_ETH_INTERRUPT_RECEIVE;
-
- /* Get current produce index */
- produce_index = lpc_eth->rxproduceindex;
-
- if (consume_index != produce_index) {
- uint32_t stat = 0;
-
- /* Fragment status */
- rtems_cache_invalidate_multiple_data_lines(
- (void *) &status [consume_index],
- sizeof(status [0])
- );
- stat = status [consume_index].info;
-
- if (
- (stat & ETH_RX_STAT_LAST_FLAG) != 0
- && (stat & LPC_ETH_RX_STAT_ERRORS) == 0
- ) {
- /* Received mbuf */
- struct mbuf *m = mbufs [consume_index];
-
- if (lpc_eth_add_new_mbuf(ifp, desc, mbufs, consume_index, false)) {
- /* Ethernet header */
- struct ether_header *eh = mtod(m, struct ether_header *);
-
- /* Discard Ethernet header and CRC */
- int sz = (int) (stat & ETH_RX_STAT_RXSIZE_MASK) + 1
- - ETHER_HDR_LEN - ETHER_CRC_LEN;
-
- /* Update mbuf */
- m->m_len = sz;
- m->m_pkthdr.len = sz;
- m->m_data = mtod(m, char *) + ETHER_HDR_LEN;
-
- LPC_ETH_PRINTF("rx: %02" PRIu32 ": %u\n", consume_index, sz);
-
- /* Hand over */
- ether_input(ifp, eh, m);
-
- /* Increment received frames counter */
- ++e->received_frames;
- } else {
- ++e->receive_drop_errors;
- }
- } else {
- /* Update error counters */
- if ((stat & ETH_RX_STAT_OVERRUN) != 0) {
- ++e->receive_overrun_errors;
- }
- if ((stat & ETH_RX_STAT_LAST_FLAG) == 0) {
- ++e->receive_fragment_errors;
- }
- if ((stat & ETH_RX_STAT_CRC_ERROR) != 0) {
- ++e->receive_crc_errors;
- }
- if ((stat & ETH_RX_STAT_SYMBOL_ERROR) != 0) {
- ++e->receive_symbol_errors;
- }
- if ((stat & ETH_RX_STAT_LENGTH_ERROR) != 0) {
- ++e->receive_length_errors;
- }
- if ((stat & ETH_RX_STAT_ALIGNMENT_ERROR) != 0) {
- ++e->receive_alignment_errors;
- }
- if ((stat & ETH_RX_STAT_NO_DESCRIPTOR) != 0) {
- ++e->receive_no_descriptor_errors;
- }
- }
-
- /* Increment and update consume index */
- consume_index = lpc_eth_increment(consume_index, index_max);
- lpc_eth->rxconsumeindex = consume_index;
- } else {
- /* Nothing to do, enable receive interrupts */
- lpc_eth_enable_receive_interrupts();
- break;
- }
- }
- }
-}
-
-static struct mbuf *lpc_eth_next_fragment(
- struct ifnet *ifp,
- struct mbuf *m,
- uint32_t *ctrl
-)
-{
- struct mbuf *n = NULL;
- int size = 0;
-
- while (true) {
- if (m == NULL) {
- /* Dequeue first fragment of the next frame */
- IF_DEQUEUE(&ifp->if_snd, m);
-
- /* Empty queue? */
- if (m == NULL) {
- return m;
- }
- }
-
- /* Get fragment size */
- size = m->m_len;
-
- if (size > 0) {
- /* Now we have a not empty fragment */
- break;
- } else {
- /* Discard empty fragments */
- m = m_free(m);
- }
- }
-
- /* Set fragment size */
- *ctrl = (uint32_t) (size - 1);
-
- /* Discard empty successive fragments */
- n = m->m_next;
- while (n != NULL && n->m_len <= 0) {
- n = m_free(n);
- }
- m->m_next = n;
-
- /* Is our fragment the last in the frame? */
- if (n == NULL) {
- *ctrl |= LPC_ETH_LAST_FRAGMENT_FLAGS;
- }
-
- return m;
-}
-
-static void lpc_eth_transmit_task(void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_event_set events = 0;
- lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) arg;
- struct ifnet *ifp = &e->arpcom.ac_if;
- volatile lpc_eth_transfer_descriptor *const desc = e->tx_desc_table;
- volatile uint32_t *const status = e->tx_status_table;
- #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- struct mbuf **const mbufs = e->tx_buf_table;
- #else
- char *const buf = e->tx_buf_table;
- #endif
- struct mbuf *m = NULL;
- uint32_t const index_max = e->tx_unit_count - 1;
- uint32_t produce_index = 0;
- uint32_t consume_index = 0;
- uint32_t ctrl = 0;
- #ifndef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- uint32_t frame_length = 0;
- char *frame_buffer = NULL;
- #endif
-
- LPC_ETH_PRINTF("%s\n", __func__);
-
- #ifndef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- /* Initialize descriptor table */
- for (produce_index = 0; produce_index <= index_max; ++produce_index) {
- desc [produce_index].start =
- (uint32_t) (buf + produce_index * LPC_ETH_CONFIG_TX_BUF_SIZE);
- }
- #endif
-
- /* Main event loop */
- while (true) {
- /* Wait for events */
- sc = rtems_bsdnet_event_receive(
- LPC_ETH_EVENT_INITIALIZE
- | LPC_ETH_EVENT_STOP
- | LPC_ETH_EVENT_TXSTART
- | LPC_ETH_EVENT_INTERRUPT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events
- );
- assert(sc == RTEMS_SUCCESSFUL);
-
- LPC_ETH_PRINTF("tx: wake up: 0x%08" PRIx32 "\n", events);
-
- /* Stop transmitter? */
- if ((events & LPC_ETH_EVENT_STOP) != 0) {
- lpc_eth_control_request_complete(e);
-
- /* Wait for events */
- continue;
- }
-
- /* Initialize transmitter? */
- if ((events & LPC_ETH_EVENT_INITIALIZE) != 0) {
- /* Disable transmit interrupts */
- lpc_eth_disable_transmit_interrupts();
-
- /* Disable transmitter */
- lpc_eth->command &= ~ETH_CMD_TX_ENABLE;
-
- /* Wait for inactive status */
- while ((lpc_eth->status & ETH_STAT_TX_ACTIVE) != 0) {
- /* Wait */
- }
-
- /* Reset */
- lpc_eth->command |= ETH_CMD_TX_RESET;
-
- /* Clear transmit interrupts */
- lpc_eth->intclear = LPC_ETH_INTERRUPT_TRANSMIT;
-
- /* Transmit descriptors */
- lpc_eth->txdescriptornum = index_max;
- lpc_eth->txdescriptor = (uint32_t) desc;
- lpc_eth->txstatus = (uint32_t) status;
-
- #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- /* Discard outstanding fragments (= data loss) */
- for (produce_index = 0; produce_index <= index_max; ++produce_index) {
- struct mbuf *victim = mbufs [produce_index];
-
- if (victim != NULL) {
- m_free(victim);
- mbufs [produce_index] = NULL;
- }
- }
- #endif
-
- /* Initialize indices */
- produce_index = lpc_eth->txproduceindex;
- consume_index = lpc_eth->txconsumeindex;
-
- #ifndef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- /* Fresh frame length and buffer start */
- frame_length = 0;
- frame_buffer = (char *) desc [produce_index].start;
- #endif
-
- /* Enable transmitter */
- lpc_eth->command |= ETH_CMD_TX_ENABLE;
-
- lpc_eth_control_request_complete(e);
- }
-
- /* Free consumed fragments */
- while (true) {
- /* Save last known consume index */
- uint32_t c = consume_index;
-
- /* Clear transmit interrupt status */
- lpc_eth->intclear = LPC_ETH_INTERRUPT_TRANSMIT;
-
- /* Get new consume index */
- consume_index = lpc_eth->txconsumeindex;
-
- /* Nothing consumed in the meantime? */
- if (c == consume_index) {
- break;
- }
-
- while (c != consume_index) {
- uint32_t s = status [c];
-
- /* Update error counters */
- if ((s & (ETH_TX_STAT_ERROR | ETH_TX_STAT_NO_DESCRIPTOR)) != 0) {
- if ((s & ETH_TX_STAT_UNDERRUN) != 0) {
- ++e->transmit_underrun_errors;
- }
- if ((s & ETH_TX_STAT_LATE_COLLISION) != 0) {
- ++e->transmit_late_collision_errors;
- }
- if ((s & ETH_TX_STAT_EXCESSIVE_COLLISION) != 0) {
- ++e->transmit_excessive_collision_errors;
- }
- if ((s & ETH_TX_STAT_EXCESSIVE_DEFER) != 0) {
- ++e->transmit_excessive_defer_errors;
- }
- if ((s & ETH_TX_STAT_NO_DESCRIPTOR) != 0) {
- ++e->transmit_no_descriptor_errors;
- }
- }
-
- #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- /* Release mbuf */
- m_free(mbufs [c]);
- mbufs [c] = NULL;
- #endif
-
- /* Next consume index */
- c = lpc_eth_increment(c, index_max);
- }
- }
-
- /* Transmit new fragments */
- while (true) {
- /* Compute next produce index */
- uint32_t p = lpc_eth_increment(produce_index, index_max);
-
- /* Get next fragment and control value */
- m = lpc_eth_next_fragment(ifp, m, &ctrl);
-
- /* Queue full? */
- if (p == consume_index) {
- LPC_ETH_PRINTF("tx: full queue: 0x%08x\n", m);
-
- /* The queue is full, wait for transmit interrupt */
- break;
- }
-
- /* New fragment? */
- if (m != NULL) {
- #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
- /* Set the transfer data */
- rtems_cache_flush_multiple_data_lines(
- mtod(m, const void *),
- (size_t) m->m_len
- );
- desc [produce_index].start = mtod(m, uint32_t);
- desc [produce_index].control = ctrl;
- rtems_cache_flush_multiple_data_lines(
- (void *) &desc [produce_index],
- sizeof(desc [0])
- );
- mbufs [produce_index] = m;
-
- LPC_ETH_PRINTF(
- "tx: %02" PRIu32 ": %u %s\n",
- produce_index, m->m_len,
- (ctrl & ETH_TX_CTRL_LAST) != 0 ? "L" : ""
- );
-
- /* Next produce index */
- produce_index = p;
-
- /* Last fragment of a frame? */
- if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
- /* Update the produce index */
- lpc_eth->txproduceindex = produce_index;
-
- /* Increment transmitted frames counter */
- ++e->transmitted_frames;
- }
-
- /* Next fragment of the frame */
- m = m->m_next;
- #else
- size_t fragment_length = (size_t) m->m_len;
- void *fragment_start = mtod(m, void *);
- uint32_t new_frame_length = frame_length + fragment_length;
-
- /* Check buffer size */
- if (new_frame_length > LPC_ETH_CONFIG_TX_BUF_SIZE) {
- LPC_ETH_PRINTF("tx: overflow\n");
-
- /* Discard overflow data */
- new_frame_length = LPC_ETH_CONFIG_TX_BUF_SIZE;
- fragment_length = new_frame_length - frame_length;
-
- /* Finalize frame */
- ctrl |= LPC_ETH_LAST_FRAGMENT_FLAGS;
-
- /* Update error counter */
- ++e->transmit_overflow_errors;
- }
-
- LPC_ETH_PRINTF(
- "tx: copy: %" PRIu32 "%s%s\n",
- fragment_length,
- (m->m_flags & M_EXT) != 0 ? ", E" : "",
- (m->m_flags & M_PKTHDR) != 0 ? ", H" : ""
- );
-
- /* Copy fragment to buffer in Ethernet RAM */
- memcpy(frame_buffer, fragment_start, fragment_length);
-
- if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
- /* Finalize descriptor */
- desc [produce_index].control = (ctrl & ~ETH_TX_CTRL_SIZE_MASK)
- | (new_frame_length - 1);
-
- LPC_ETH_PRINTF(
- "tx: %02" PRIu32 ": %" PRIu32 "\n",
- produce_index,
- new_frame_length
- );
-
- /* Cache flush of data */
- rtems_cache_flush_multiple_data_lines(
- (const void *) desc [produce_index].start,
- new_frame_length
- );
-
- /* Cache flush of descriptor */
- rtems_cache_flush_multiple_data_lines(
- (void *) &desc [produce_index],
- sizeof(desc [0])
- );
-
- /* Next produce index */
- produce_index = p;
-
- /* Update the produce index */
- lpc_eth->txproduceindex = produce_index;
-
- /* Fresh frame length and buffer start */
- frame_length = 0;
- frame_buffer = (char *) desc [produce_index].start;
-
- /* Increment transmitted frames counter */
- ++e->transmitted_frames;
- } else {
- /* New frame length */
- frame_length = new_frame_length;
-
- /* Update current frame buffer start */
- frame_buffer += fragment_length;
- }
-
- /* Free mbuf and get next */
- m = m_free(m);
- #endif
- } else {
- /* Nothing to transmit */
- break;
- }
- }
-
- /* No more fragments? */
- if (m == NULL) {
- /* Interface is now inactive */
- ifp->if_flags &= ~IFF_OACTIVE;
- } else {
- LPC_ETH_PRINTF("tx: enable interrupts\n");
-
- /* Enable transmit interrupts */
- lpc_eth_enable_transmit_interrupts();
- }
- }
-}
-
-static int lpc_eth_mdio_wait_for_not_busy(void)
-{
- rtems_interval one_second = rtems_clock_get_ticks_per_second();
- rtems_interval i = 0;
-
- while ((lpc_eth->mind & ETH_MIND_BUSY) != 0 && i < one_second) {
- rtems_task_wake_after(1);
- ++i;
- }
-
- LPC_ETH_PRINTK("tx: lpc_eth_mdio_wait %s after %d\n",
- i != one_second? "succeed": "timeout", i);
-
- return i != one_second ? 0 : ETIMEDOUT;
-}
-
-static uint32_t lpc_eth_mdio_read_anlpar(int phy)
-{
- uint32_t madr = ETH_MADR_REG(MII_ANLPAR) | ETH_MADR_PHY(phy);
- uint32_t anlpar = 0;
- int eno = 0;
-
- if (lpc_eth->madr != madr) {
- lpc_eth->madr = madr;
- }
-
- if (lpc_eth->mcmd != ETH_MCMD_READ) {
- lpc_eth->mcmd = 0;
- lpc_eth->mcmd = ETH_MCMD_READ;
- }
-
- eno = lpc_eth_mdio_wait_for_not_busy();
- if (eno == 0) {
- anlpar = lpc_eth->mrdd;
- }
-
- /* Start next read */
- lpc_eth->mcmd = 0;
- lpc_eth->mcmd = ETH_MCMD_READ;
-
- return anlpar;
-}
-
-static int lpc_eth_mdio_read(
- int phy,
- void *arg RTEMS_UNUSED,
- unsigned reg,
- uint32_t *val
-)
-{
- int eno = 0;
-
- if (0 <= phy && phy <= 31) {
- lpc_eth->madr = ETH_MADR_REG(reg) | ETH_MADR_PHY(phy);
- lpc_eth->mcmd = 0;
- lpc_eth->mcmd = ETH_MCMD_READ;
- eno = lpc_eth_mdio_wait_for_not_busy();
-
- if (eno == 0) {
- *val = lpc_eth->mrdd;
- }
- } else {
- eno = EINVAL;
- }
-
- return eno;
-}
-
-static int lpc_eth_mdio_write(
- int phy,
- void *arg RTEMS_UNUSED,
- unsigned reg,
- uint32_t val
-)
-{
- int eno = 0;
-
- if (0 <= phy && phy <= 31) {
- lpc_eth->madr = ETH_MADR_REG(reg) | ETH_MADR_PHY(phy);
- lpc_eth->mwtd = val;
- eno = lpc_eth_mdio_wait_for_not_busy();
- } else {
- eno = EINVAL;
- }
-
- return eno;
-}
-
-static int lpc_eth_phy_get_id(int phy, uint32_t *id)
-{
- uint32_t id1 = 0;
- int eno = lpc_eth_mdio_read(phy, NULL, MII_PHYIDR1, &id1);
-
- if (eno == 0) {
- uint32_t id2 = 0;
-
- eno = lpc_eth_mdio_read(phy, NULL, MII_PHYIDR2, &id2);
- if (eno == 0) {
- *id = (id1 << 16) | (id2 & 0xfff0);
- }
- }
-
- return eno;
-}
-
-#define PHY_KSZ80X1RNL 0x221550
-#define PHY_DP83848 0x20005c90
-
-typedef struct {
- unsigned reg;
- uint32_t set;
- uint32_t clear;
-} lpc_eth_phy_action;
-
-static int lpc_eth_phy_set_and_clear(
- lpc_eth_driver_entry *e,
- const lpc_eth_phy_action *actions,
- size_t n
-)
-{
- int eno = 0;
- size_t i;
-
- for (i = 0; eno == 0 && i < n; ++i) {
- const lpc_eth_phy_action *action = &actions [i];
- uint32_t val;
-
- eno = lpc_eth_mdio_read(e->phy, NULL, action->reg, &val);
- if (eno == 0) {
- val |= action->set;
- val &= ~action->clear;
- eno = lpc_eth_mdio_write(e->phy, NULL, action->reg, val);
- }
- }
-
- return eno;
-}
-
-static const lpc_eth_phy_action lpc_eth_phy_up_action_default [] = {
- { MII_BMCR, 0, BMCR_PDOWN },
- { MII_BMCR, BMCR_RESET, 0 },
- { MII_BMCR, BMCR_AUTOEN, 0 }
-};
-
-static const lpc_eth_phy_action lpc_eth_phy_up_pre_action_KSZ80X1RNL [] = {
- /* Disable slow oscillator mode */
- { 0x11, 0, 0x10 }
-};
-
-static const lpc_eth_phy_action lpc_eth_phy_up_post_action_KSZ80X1RNL [] = {
- /* Enable energy detect power down (EDPD) mode */
- { 0x18, 0x0800, 0 },
- /* Turn PLL of automatically in EDPD mode */
- { 0x10, 0x10, 0 }
-};
-
-static int lpc_eth_phy_up(lpc_eth_driver_entry *e)
-{
- int eno;
- int retries = 64;
- uint32_t val;
-
- e->phy = DEFAULT_PHY - 1;
- while (true) {
- e->phy = (e->phy + 1) % 32;
-
- --retries;
- eno = lpc_eth_phy_get_id(e->phy, &e->phy_id);
- if (
- (eno == 0 && e->phy_id != 0xfffffff0 && e->phy_id != 0)
- || retries <= 0
- ) {
- break;
- }
-
- rtems_task_wake_after(1);
- }
-
- LPC_ETH_PRINTF("lpc_eth_phy_get_id: 0x%08" PRIx32 " from phy %d retries %d\n",
- e->phy_id, e->phy, retries);
-
- if (eno == 0) {
- switch (e->phy_id) {
- case PHY_KSZ80X1RNL:
- eno = lpc_eth_phy_set_and_clear(
- e,
- &lpc_eth_phy_up_pre_action_KSZ80X1RNL [0],
- RTEMS_ARRAY_SIZE(lpc_eth_phy_up_pre_action_KSZ80X1RNL)
- );
- break;
- case PHY_DP83848:
- eno = lpc_eth_mdio_read(e->phy, NULL, 0x17, &val);
- LPC_ETH_PRINTF("phy PHY_DP83848 RBR 0x%08" PRIx32 "\n", val);
- /* val = 0x21; */
- val = 0x32 ;
- eno = lpc_eth_mdio_write(e->phy, NULL, 0x17, val);
- break;
- case 0:
- case 0xfffffff0:
- eno = EIO;
- e->phy = DEFAULT_PHY;
- break;
- default:
- break;
- }
-
- if (eno == 0) {
- eno = lpc_eth_phy_set_and_clear(
- e,
- &lpc_eth_phy_up_action_default [0],
- RTEMS_ARRAY_SIZE(lpc_eth_phy_up_action_default)
- );
- }
-
- if (eno == 0) {
- switch (e->phy_id) {
- case PHY_KSZ80X1RNL:
- eno = lpc_eth_phy_set_and_clear(
- e,
- &lpc_eth_phy_up_post_action_KSZ80X1RNL [0],
- RTEMS_ARRAY_SIZE(lpc_eth_phy_up_post_action_KSZ80X1RNL)
- );
- break;
- default:
- break;
- }
- }
- } else {
- e->phy_id = 0;
- }
-
- return eno;
-}
-
-static const lpc_eth_phy_action lpc_eth_phy_down_action_default [] = {
- { MII_BMCR, BMCR_PDOWN, 0 }
-};
-
-static const lpc_eth_phy_action lpc_eth_phy_down_post_action_KSZ80X1RNL [] = {
- /* Enable slow oscillator mode */
- { 0x11, 0x10, 0 }
-};
-
-static void lpc_eth_phy_down(lpc_eth_driver_entry *e)
-{
- int eno = lpc_eth_phy_set_and_clear(
- e,
- &lpc_eth_phy_down_action_default [0],
- RTEMS_ARRAY_SIZE(lpc_eth_phy_down_action_default)
- );
-
- if (eno == 0) {
- switch (e->phy_id) {
- case PHY_KSZ80X1RNL:
- eno = lpc_eth_phy_set_and_clear(
- e,
- &lpc_eth_phy_down_post_action_KSZ80X1RNL [0],
- RTEMS_ARRAY_SIZE(lpc_eth_phy_down_post_action_KSZ80X1RNL)
- );
- break;
- default:
- break;
- }
- }
-}
-
-static void lpc_eth_soft_reset(void)
-{
- lpc_eth->command = 0x38;
- lpc_eth->mac1 = 0xcf00;
- lpc_eth->mac1 = 0x0;
-}
-
-static int lpc_eth_up_or_down(lpc_eth_driver_entry *e, bool up)
-{
- int eno = 0;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- struct ifnet *ifp = &e->arpcom.ac_if;
-
- if (up && e->state == LPC_ETH_STATE_DOWN) {
-
- lpc_eth_config_module_enable();
-
- /* Enable RX/TX reset and disable soft reset */
- lpc_eth->mac1 = 0xf00;
-
- /* Initialize PHY */
- /* Clock value 10 (divide by 44 ) is safe on LPC178x up to 100 MHz AHB clock */
- lpc_eth->mcfg = ETH_MCFG_CLOCK_SELECT(10) | ETH_MCFG_RESETMIIMGMT;
- rtems_task_wake_after(1);
- lpc_eth->mcfg = ETH_MCFG_CLOCK_SELECT(10);
- rtems_task_wake_after(1);
- eno = lpc_eth_phy_up(e);
-
- if (eno == 0) {
- /*
- * We must have a valid external clock from the PHY at this point,
- * otherwise the system bus hangs and only a watchdog reset helps.
- */
- lpc_eth_soft_reset();
-
- /* Reinitialize registers */
- lpc_eth->mac2 = 0x31;
- lpc_eth->ipgt = 0x15;
- lpc_eth->ipgr = 0x12;
- lpc_eth->clrt = 0x370f;
- lpc_eth->maxf = 0x0600;
- lpc_eth->supp = ETH_SUPP_SPEED;
- lpc_eth->test = 0;
- #ifdef LPC_ETH_CONFIG_RMII
- lpc_eth->command = 0x0600;
- #else
- lpc_eth->command = 0x0400;
- #endif
- lpc_eth->intenable = ETH_INT_RX_OVERRUN | ETH_INT_TX_UNDERRUN;
- lpc_eth->intclear = 0x30ff;
- lpc_eth->powerdown = 0;
-
- /* MAC address */
- lpc_eth->sa0 = ((uint32_t) e->arpcom.ac_enaddr [5] << 8)
- | (uint32_t) e->arpcom.ac_enaddr [4];
- lpc_eth->sa1 = ((uint32_t) e->arpcom.ac_enaddr [3] << 8)
- | (uint32_t) e->arpcom.ac_enaddr [2];
- lpc_eth->sa2 = ((uint32_t) e->arpcom.ac_enaddr [1] << 8)
- | (uint32_t) e->arpcom.ac_enaddr [0];
-
- /* Enable receiver */
- lpc_eth->mac1 = 0x03;
-
- /* Initialize tasks */
- lpc_eth_control_request(e, e->receive_task, LPC_ETH_EVENT_INITIALIZE);
- lpc_eth_control_request(e, e->transmit_task, LPC_ETH_EVENT_INITIALIZE);
-
- /* Install interrupt handler */
- sc = rtems_interrupt_handler_install(
- e->interrupt_number,
- "Ethernet",
- RTEMS_INTERRUPT_UNIQUE,
- lpc_eth_interrupt_handler,
- e
- );
- assert(sc == RTEMS_SUCCESSFUL);
-
- /* Start watchdog timer */
- ifp->if_timer = 1;
-
- /* Change state */
- e->state = LPC_ETH_STATE_UP;
- }
-
- if (eno != 0) {
- ifp->if_flags &= ~IFF_UP;
- }
- } else if (!up && e->state == LPC_ETH_STATE_UP) {
- /* Remove interrupt handler */
- sc = rtems_interrupt_handler_remove(
- e->interrupt_number,
- lpc_eth_interrupt_handler,
- e
- );
- assert(sc == RTEMS_SUCCESSFUL);
-
- /* Stop tasks */
- lpc_eth_control_request(e, e->receive_task, LPC_ETH_EVENT_STOP);
- lpc_eth_control_request(e, e->transmit_task, LPC_ETH_EVENT_STOP);
-
- lpc_eth_soft_reset();
- lpc_eth_phy_down(e);
- lpc_eth_config_module_disable();
-
- /* Stop watchdog timer */
- ifp->if_timer = 0;
-
- /* Change state */
- e->state = LPC_ETH_STATE_DOWN;
- }
-
- return eno;
-}
-
-static void lpc_eth_interface_init(void *arg)
-{
- /* Nothing to do */
-}
-
-static void lpc_eth_interface_stats(lpc_eth_driver_entry *e)
-{
- int eno = EIO;
- int media = 0;
-
- if (e->state == LPC_ETH_STATE_UP) {
- media = IFM_MAKEWORD(0, 0, 0, 0);
- eno = rtems_mii_ioctl(&e->mdio, e, SIOCGIFMEDIA, &media);
- }
-
- rtems_bsdnet_semaphore_release();
-
- if (eno == 0) {
- rtems_ifmedia2str(media, NULL, 0);
- printf("\n");
- }
-
- printf("received frames: %u\n", e->received_frames);
- printf("receive interrupts: %u\n", e->receive_interrupts);
- printf("transmitted frames: %u\n", e->transmitted_frames);
- printf("transmit interrupts: %u\n", e->transmit_interrupts);
- printf("receive drop errors: %u\n", e->receive_drop_errors);
- printf("receive overrun errors: %u\n", e->receive_overrun_errors);
- printf("receive fragment errors: %u\n", e->receive_fragment_errors);
- printf("receive CRC errors: %u\n", e->receive_crc_errors);
- printf("receive symbol errors: %u\n", e->receive_symbol_errors);
- printf("receive length errors: %u\n", e->receive_length_errors);
- printf("receive alignment errors: %u\n", e->receive_alignment_errors);
- printf("receive no descriptor errors: %u\n", e->receive_no_descriptor_errors);
- printf("receive fatal errors: %u\n", e->receive_fatal_errors);
- printf("transmit underrun errors: %u\n", e->transmit_underrun_errors);
- printf("transmit late collision errors: %u\n", e->transmit_late_collision_errors);
- printf("transmit excessive collision errors: %u\n", e->transmit_excessive_collision_errors);
- printf("transmit excessive defer errors: %u\n", e->transmit_excessive_defer_errors);
- printf("transmit no descriptor errors: %u\n", e->transmit_no_descriptor_errors);
- printf("transmit overflow errors: %u\n", e->transmit_overflow_errors);
- printf("transmit fatal errors: %u\n", e->transmit_fatal_errors);
-
- rtems_bsdnet_semaphore_obtain();
-}
-
-static int lpc_eth_multicast_control(
- bool add,
- struct ifreq *ifr,
- struct arpcom *ac
-)
-{
- int eno = 0;
-
- if (add) {
- eno = ether_addmulti(ifr, ac);
- } else {
- eno = ether_delmulti(ifr, ac);
- }
-
- if (eno == ENETRESET) {
- struct ether_multistep step;
- struct ether_multi *enm;
-
- eno = 0;
-
- lpc_eth->hashfilterl = 0;
- lpc_eth->hashfilterh = 0;
-
- ETHER_FIRST_MULTI(step, ac, enm);
- while (enm != NULL) {
- uint64_t addrlo = 0;
- uint64_t addrhi = 0;
-
- memcpy(&addrlo, enm->enm_addrlo, ETHER_ADDR_LEN);
- memcpy(&addrhi, enm->enm_addrhi, ETHER_ADDR_LEN);
- while (addrlo <= addrhi) {
- /* XXX: ether_crc32_le() does not work, why? */
- uint32_t crc = ether_crc32_be((uint8_t *) &addrlo, ETHER_ADDR_LEN);
- uint32_t index = (crc >> 23) & 0x3f;
-
- if (index < 32) {
- lpc_eth->hashfilterl |= 1U << index;
- } else {
- lpc_eth->hashfilterh |= 1U << (index - 32);
- }
- ++addrlo;
- }
- ETHER_NEXT_MULTI(step, enm);
- }
- }
-
- return eno;
-}
-
-static int lpc_eth_interface_ioctl(
- struct ifnet *ifp,
- ioctl_command_t cmd,
- caddr_t data
-)
-{
- lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *) data;
- int eno = 0;
-
- LPC_ETH_PRINTF("%s\n", __func__);
-
- switch (cmd) {
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- rtems_mii_ioctl(&e->mdio, e, cmd, &ifr->ifr_media);
- break;
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- ether_ioctl(ifp, cmd, data);
- break;
- case SIOCSIFFLAGS:
- eno = lpc_eth_up_or_down(e, (ifp->if_flags & IFF_UP) != 0);
- if (eno == 0 && (ifp->if_flags & IFF_UP) != 0) {
- lpc_eth_enable_promiscous_mode((ifp->if_flags & IFF_PROMISC) != 0);
- }
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- eno = lpc_eth_multicast_control(cmd == SIOCADDMULTI, ifr, &e->arpcom);
- break;
- case SIO_RTEMS_SHOW_STATS:
- lpc_eth_interface_stats(e);
- break;
- default:
- eno = EINVAL;
- break;
- }
-
- return eno;
-}
-
-static void lpc_eth_interface_start(struct ifnet *ifp)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) ifp->if_softc;
-
- ifp->if_flags |= IFF_OACTIVE;
-
- if (e->state == LPC_ETH_STATE_UP) {
- sc = rtems_bsdnet_event_send(e->transmit_task, LPC_ETH_EVENT_TXSTART);
- assert(sc == RTEMS_SUCCESSFUL);
- }
-}
-
-static void lpc_eth_interface_watchdog(struct ifnet *ifp)
-{
- lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) ifp->if_softc;
-
- if (e->state == LPC_ETH_STATE_UP) {
- uint32_t anlpar = lpc_eth_mdio_read_anlpar(e->phy);
-
- if (e->anlpar != anlpar) {
- bool full_duplex = false;
- bool speed = false;
-
- e->anlpar = anlpar;
-
- if ((anlpar & ANLPAR_TX_FD) != 0) {
- full_duplex = true;
- speed = true;
- } else if ((anlpar & ANLPAR_T4) != 0) {
- speed = true;
- } else if ((anlpar & ANLPAR_TX) != 0) {
- speed = true;
- } else if ((anlpar & ANLPAR_10_FD) != 0) {
- full_duplex = true;
- }
-
- if (full_duplex) {
- lpc_eth->mac2 |= ETH_MAC2_FULL_DUPLEX;
- } else {
- lpc_eth->mac2 &= ~ETH_MAC2_FULL_DUPLEX;
- }
-
- if (speed) {
- lpc_eth->supp |= ETH_SUPP_SPEED;
- } else {
- lpc_eth->supp &= ~ETH_SUPP_SPEED;
- }
- }
-
- ifp->if_timer = WATCHDOG_TIMEOUT;
- }
-}
-
-static unsigned lpc_eth_fixup_unit_count(int count, int default_value, int max)
-{
- if (count <= 0) {
- count = default_value;
- } else if (count > max) {
- count = max;
- }
-
- return LPC_ETH_CONFIG_UNIT_MULTIPLE
- + (((unsigned) count - 1U) & ~(LPC_ETH_CONFIG_UNIT_MULTIPLE - 1U));
-}
-
-static int lpc_eth_attach(struct rtems_bsdnet_ifconfig *config)
-{
- lpc_eth_driver_entry *e = &lpc_eth_driver_data;
- struct ifnet *ifp = &e->arpcom.ac_if;
- char *unit_name = NULL;
- int unit_index = rtems_bsdnet_parse_driver_name(config, &unit_name);
- size_t table_area_size = 0;
- char *table_area = NULL;
- char *table_location = NULL;
-
- /* Check parameter */
- if (unit_index < 0) {
- return 0;
- }
- if (unit_index != 0) {
- goto cleanup;
- }
- if (config->hardware_address == NULL) {
- goto cleanup;
- }
- if (e->state != LPC_ETH_STATE_NOT_INITIALIZED) {
- goto cleanup;
- }
-
- /* MDIO */
- e->mdio.mdio_r = lpc_eth_mdio_read;
- e->mdio.mdio_w = lpc_eth_mdio_write;
- e->mdio.has_gmii = 0;
- e->anlpar = 0;
-
- /* Interrupt number */
- config->irno = LPC_ETH_CONFIG_INTERRUPT;
-
- /* Device control */
- config->drv_ctrl = e;
-
- /* Receive unit count */
- e->rx_unit_count = lpc_eth_fixup_unit_count(
- config->rbuf_count,
- LPC_ETH_CONFIG_RX_UNIT_COUNT_DEFAULT,
- LPC_ETH_CONFIG_RX_UNIT_COUNT_MAX
- );
- config->rbuf_count = (int) e->rx_unit_count;
-
- /* Transmit unit count */
- e->tx_unit_count = lpc_eth_fixup_unit_count(
- config->xbuf_count,
- LPC_ETH_CONFIG_TX_UNIT_COUNT_DEFAULT,
- LPC_ETH_CONFIG_TX_UNIT_COUNT_MAX
- );
- config->xbuf_count = (int) e->tx_unit_count;
-
- /* Remember interrupt number */
- e->interrupt_number = config->irno;
-
- /* Copy MAC address */
- memcpy(e->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
-
- /* Allocate and clear table area */
- table_area_size =
- e->rx_unit_count
- * (sizeof(lpc_eth_transfer_descriptor)
- + sizeof(lpc_eth_receive_status)
- + sizeof(struct mbuf *))
- + e->tx_unit_count
- * (sizeof(lpc_eth_transfer_descriptor)
- + sizeof(uint32_t)
- + LPC_ETH_CONFIG_TX_BUF_SIZE);
- table_area = lpc_eth_config_alloc_table_area(table_area_size);
- if (table_area == NULL) {
- goto cleanup;
- }
- memset(table_area, 0, table_area_size);
-
- table_location = table_area;
-
- /*
- * The receive status table must be the first one since it has the strictest
- * alignment requirements.
- */
- e->rx_status_table = (volatile lpc_eth_receive_status *) table_location;
- table_location += e->rx_unit_count * sizeof(e->rx_status_table [0]);
-
- e->rx_desc_table = (volatile lpc_eth_transfer_descriptor *) table_location;
- table_location += e->rx_unit_count * sizeof(e->rx_desc_table [0]);
-
- e->rx_mbuf_table = (struct mbuf **) table_location;
- table_location += e->rx_unit_count * sizeof(e->rx_mbuf_table [0]);
-
- e->tx_desc_table = (volatile lpc_eth_transfer_descriptor *) table_location;
- table_location += e->tx_unit_count * sizeof(e->tx_desc_table [0]);
-
- e->tx_status_table = (volatile uint32_t *) table_location;
- table_location += e->tx_unit_count * sizeof(e->tx_status_table [0]);
-
- e->tx_buf_table = table_location;
-
- /* Set interface data */
- ifp->if_softc = e;
- ifp->if_unit = (short) unit_index;
- ifp->if_name = unit_name;
- ifp->if_mtu = (config->mtu > 0) ? (u_long) config->mtu : ETHERMTU;
- ifp->if_init = lpc_eth_interface_init;
- ifp->if_ioctl = lpc_eth_interface_ioctl;
- ifp->if_start = lpc_eth_interface_start;
- ifp->if_output = ether_output;
- ifp->if_watchdog = lpc_eth_interface_watchdog;
- ifp->if_flags = IFF_MULTICAST | IFF_BROADCAST | IFF_SIMPLEX;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_timer = 0;
-
- /* Create tasks */
- e->receive_task = rtems_bsdnet_newproc(
- "ntrx",
- 4096,
- lpc_eth_receive_task,
- e
- );
- e->transmit_task = rtems_bsdnet_newproc(
- "nttx",
- 4096,
- lpc_eth_transmit_task,
- e
- );
-
- /* Change status */
- ifp->if_flags |= IFF_RUNNING;
- e->state = LPC_ETH_STATE_DOWN;
-
- /* Attach the interface */
- if_attach(ifp);
- ether_ifattach(ifp);
-
- return 1;
-
-cleanup:
-
- lpc_eth_config_free_table_area(table_area);
-
- /* FIXME: Type */
- free(unit_name, (int) 0xdeadbeef);
-
- return 0;
-}
-
-static int lpc_eth_detach(
- struct rtems_bsdnet_ifconfig *config RTEMS_UNUSED
-)
-{
- /* FIXME: Detach the interface from the upper layers? */
-
- /* Module soft reset */
- lpc_eth->command = 0x38;
- lpc_eth->mac1 = 0xcf00;
-
- /* FIXME: More cleanup */
-
- return 0;
-}
-
-int lpc_eth_attach_detach(
- struct rtems_bsdnet_ifconfig *config,
- int attaching
-)
-{
- /* FIXME: Return value */
-
- if (attaching) {
- return lpc_eth_attach(config);
- } else {
- return lpc_eth_detach(config);
- }
-}