summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/gen5200
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 09:53:31 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-23 15:18:44 +0200
commit031df3914990db0336a0d386fb53558b05de467e (patch)
tree4661e22f0cdb3f9d06879f0194b77c75f62bac79 /c/src/lib/libbsp/powerpc/gen5200
parentbsps: Move interrupt controller support to bsps (diff)
downloadrtems-031df3914990db0336a0d386fb53558b05de467e.tar.bz2
bsps: Move legacy network drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/gen5200')
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/Makefile.am2
-rw-r--r--c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c1581
2 files changed, 1 insertions, 1582 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am
index 66c7379c36..f72583af21 100644
--- a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am
@@ -104,7 +104,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/start/uboot_supp
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/start/bestcomm.c
if HAS_NETWORKING
-librtemsbsp_a_SOURCES += network_5200/network.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/gen5200/net/network.c
endif
librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/cache/cache.c
diff --git a/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c b/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c
deleted file mode 100644
index 2e11915b26..0000000000
--- a/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c
+++ /dev/null
@@ -1,1581 +0,0 @@
-/*===============================================================*\
-| Project: RTEMS generic MPC5200 BSP |
-+-----------------------------------------------------------------+
-| Partially based on the code references which are named below. |
-| Adaptions, modifications, enhancements and any recent parts of |
-| the code are: |
-| Copyright (c) 2005 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-| this file contains the networking driver |
-\*===============================================================*/
-/*
- * RTEMS/TCPIP driver for MPC5200 FEC Ethernet
- *
- * Modified for Motorola MPC5200 by Thomas Doerfler, <Thomas.Doerfler@imd-systems.de>
- * COPYRIGHT (c) 2003, IMD
- *
- * Modified for Motorola IceCube (mgt5100) by Peter Rasmussen <prasmus@ipr-engineering.de>
- * COPYRIGHT (c) 2003, IPR Engineering
- *
- * Parts of code are also under property of Driver Information Systems and based
- * on Motorola Proprietary Information.
- * COPYRIGHT (c) 2002 MOTOROLA INC.
- *
- * Modified for MPC860 by Jay Monkman (jmonkman@frasca.com)
- *
- * This supports Ethernet on either SCC1 or the FEC of the MPC860T.
- * Right now, we only do 10 Mbps, even with the FEC. The function
- * rtems_enet_driver_attach determines which one to use. Currently,
- * only one may be used at a time.
- *
- * Based on the MC68360 network driver by
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- *
- * This supports ethernet on SCC1. Right now, we only do 10 Mbps.
- *
- * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
- * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
- * Copyright (c) 1999, National Research Council of Canada
- *
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ 1
-#define __BSD_VISIBLE 1
-
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/rtems_mii_ioctl.h>
-#include <stdio.h>
-#include <inttypes.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.h>
-#include <bsp/irq.h>
-#include <bsp/mpc5200.h>
-#include <net/if_var.h>
-#include <errno.h>
-
-#include <bsp/bestcomm/include/ppctypes.h>
-#include <bsp/bestcomm/dma_image.h>
-#include <bsp/bestcomm/bestcomm_glue.h>
-#include <bsp/bestcomm/bestcomm_api.h>
-#include <bsp/bestcomm/task_api/bestcomm_cntrl.h>
-#include <bsp/bestcomm/task_api/tasksetup_bdtable.h>
-
-/* #define ETH_DEBUG */
-
-#define FEC_BD_LAST TASK_BD_TFD
-#define FEC_BD_INT TASK_BD_INT
-#define FEC_BD_READY SDMA_BD_MASK_READY
-
-/*
- * Number of interfaces supported by this driver
- */
-#define NIFACES 1
-
-/*
- * Default number of buffer descriptors set aside for this driver.
- * The number of transmit buffer descriptors has to be quite large
- * since a single frame often uses four or more buffer descriptors.
- */
-#define RX_BUF_COUNT 64
-#define TX_BUF_COUNT 64
-
-#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255")
-
-#define FEC_EVENT RTEMS_EVENT_0
-
-/* Task number assignment */
-#define FEC_RECV_TASK_NO TASK_FEC_RX
-#define FEC_XMIT_TASK_NO TASK_FEC_TX
-
-
-/* BD and parameters are stored in SRAM(refer to sdma.h) */
-#define MPC5200_FEC_BD_BASE ETH_BD_BASE
-
-/* FEC transmit watermark settings */
-#define MPC5200_FEC_X_WMRK_64 0x0 /* or 0x1 */
-#define MPC5200_FEC_X_WMRK_128 0x2
-#define MPC5200_FEC_X_WMRK_192 0x3
-
-/* RBD bits definitions */
-#define MPC5200_FEC_RBD_EMPTY 0x8000 /* Buffer is empty */
-#define MPC5200_FEC_RBD_WRAP 0x2000 /* Last BD in ring */
-#define MPC5200_FEC_RBD_INT 0x1000 /* Interrupt */
-#define MPC5200_FEC_RBD_LAST 0x0800 /* Buffer is last in frame(useless) */
-#define MPC5200_FEC_RBD_MISS 0x0100 /* Miss bit for prom mode */
-#define MPC5200_FEC_RBD_BC 0x0080 /* The received frame is broadcast frame */
-#define MPC5200_FEC_RBD_MC 0x0040 /* The received frame is multicast frame */
-#define MPC5200_FEC_RBD_LG 0x0020 /* Frame length violation */
-#define MPC5200_FEC_RBD_NO 0x0010 /* Nonoctet align frame */
-#define MPC5200_FEC_RBD_SH 0x0008 /* Short frame, FEC does not support SH and this bit is always cleared */
-#define MPC5200_FEC_RBD_CR 0x0004 /* CRC error */
-#define MPC5200_FEC_RBD_OV 0x0002 /* Receive FIFO overrun */
-#define MPC5200_FEC_RBD_TR 0x0001 /* The receive frame is truncated */
-#define MPC5200_FEC_RBD_ERR (MPC5200_FEC_RBD_LG | \
- MPC5200_FEC_RBD_NO | \
- MPC5200_FEC_RBD_CR | \
- MPC5200_FEC_RBD_OV | \
- MPC5200_FEC_RBD_TR)
-
-/* TBD bits definitions */
-#define MPC5200_FEC_TBD_READY 0x8000 /* Buffer is ready */
-#define MPC5200_FEC_TBD_WRAP 0x2000 /* Last BD in ring */
-#define MPC5200_FEC_TBD_INT 0x1000 /* Interrupt */
-#define MPC5200_FEC_TBD_LAST 0x0800 /* Buffer is last in frame */
-#define MPC5200_FEC_TBD_TC 0x0400 /* Transmit the CRC */
-#define MPC5200_FEC_TBD_ABC 0x0200 /* Append bad CRC */
-
-/* MII-related definitios */
-#define MPC5200_FEC_MII_DATA_ST 0x40000000 /* Start of frame delimiter */
-#define MPC5200_FEC_MII_DATA_OP_RD 0x20000000 /* Perform a read operation */
-#define MPC5200_FEC_MII_DATA_OP_WR 0x10000000 /* Perform a write operation */
-#define MPC5200_FEC_MII_DATA_PA_MSK 0x0f800000 /* PHY Address field mask */
-#define MPC5200_FEC_MII_DATA_RA_MSK 0x007c0000 /* PHY Register field mask */
-#define MPC5200_FEC_MII_DATA_TA 0x00020000 /* Turnaround */
-#define MPC5200_FEC_MII_DATA_DATAMSK 0x0000fff /* PHY data field */
-
-#define MPC5200_FEC_MII_DATA_RA_SHIFT 0x12 /* MII Register address bits */
-#define MPC5200_FEC_MII_DATA_PA_SHIFT 0x17 /* MII PHY address bits */
-
-#define FEC_INTR_MASK_USED \
-(FEC_INTR_LCEN |FEC_INTR_CRLEN |\
- FEC_INTR_XFUNEN|FEC_INTR_XFERREN|FEC_INTR_RFERREN)
-
-typedef enum {
- FEC_STATE_RESTART_0,
- FEC_STATE_RESTART_1,
- FEC_STATE_NORMAL,
-} mpc5200_fec_state;
-
-/*
- * Device data
- */
-typedef struct {
- struct arpcom arpcom;
- struct mbuf **rxMbuf;
- struct mbuf **txMbuf;
- mpc5200_fec_state state;
- int acceptBroadcast;
- int rxBdCount;
- int txBdCount;
- int txBdHead;
- int txBdTail;
- int txBdActiveCount;
-
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- unsigned long rxInterrupts;
- unsigned long rxNotLast;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxFIFOError;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txLateCollision;
- unsigned long txUnderrun;
- unsigned long txFIFOError;
- unsigned long txMisaligned;
- unsigned long rxNotFirst;
- unsigned long txRetryLimit;
-
- struct rtems_mdio_info mdio;
- int phyAddr;
- bool phyInitialized;
-} mpc5200_fec_context;
-
-static mpc5200_fec_context enet_driver[NIFACES];
-
-static void mpc5200_fec_send_event(rtems_id task)
-{
- rtems_bsdnet_event_send(task, FEC_EVENT);
-}
-
-static void mpc5200_fec_wait_for_event(void)
-{
- rtems_event_set out;
- rtems_bsdnet_event_receive(
- FEC_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &out
- );
-}
-
-static void mpc5200_fec_stop_dma(void)
-{
- TaskStop(FEC_RECV_TASK_NO);
- TaskStop(FEC_XMIT_TASK_NO);
-}
-
-static void mpc5200_fec_request_restart(mpc5200_fec_context *self)
-{
- self->state = FEC_STATE_RESTART_0;
- mpc5200_fec_send_event(self->txDaemonTid);
- mpc5200_fec_send_event(self->rxDaemonTid);
-}
-
-static void mpc5200_fec_start_dma_and_controller(void)
-{
- TaskStart(FEC_RECV_TASK_NO, 1, FEC_RECV_TASK_NO, 1);
- TaskStart(FEC_XMIT_TASK_NO, 1, FEC_XMIT_TASK_NO, 1);
-
- mpc5200.ecntrl |= FEC_ECNTRL_OE | FEC_ECNTRL_EN;
-}
-
-/*
- * Function: MPC5200_eth_addr_filter_set
- *
- * Description: Set individual address filter for unicast address and
- * set physical address registers.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_eth_addr_filter_set(mpc5200_fec_context *self) {
- unsigned char *mac;
- unsigned char currByte; /* byte for which to compute the CRC */
- int byte; /* loop - counter */
- int bit; /* loop - counter */
- unsigned long crc = 0xffffffff; /* initial value */
-
- /*
- * Get the mac address of ethernet controller
- */
- mac = (unsigned char *)(&self->arpcom.ac_enaddr);
-
- /*
- * The algorithm used is the following:
- * we loop on each of the six bytes of the provided address,
- * and we compute the CRC by left-shifting the previous
- * value by one position, so that each bit in the current
- * byte of the address may contribute the calculation. If
- * the latter and the MSB in the CRC are different, then
- * the CRC value so computed is also ex-ored with the
- * "polynomium generator". The current byte of the address
- * is also shifted right by one bit at each iteration.
- * This is because the CRC generatore in hardware is implemented
- * as a shift-register with as many ex-ores as the radixes
- * in the polynomium. This suggests that we represent the
- * polynomiumm itself as a 32-bit constant.
- */
- for(byte = 0; byte < 6; byte++)
- {
-
- currByte = mac[byte];
-
- for(bit = 0; bit < 8; bit++)
- {
-
- if((currByte & 0x01) ^ (crc & 0x01))
- {
-
- crc >>= 1;
- crc = crc ^ 0xedb88320;
-
- }
- else
- {
-
- crc >>= 1;
-
- }
-
- currByte >>= 1;
-
- }
-
- }
-
- crc = crc >> 26;
-
- /*
- * Set individual hash table register
- */
- if(crc >= 32)
- {
-
- mpc5200.iaddr1 = (1 << (crc - 32));
- mpc5200.iaddr2 = 0;
-
- }
- else
- {
-
- mpc5200.iaddr1 = 0;
- mpc5200.iaddr2 = (1 << crc);
-
- }
-
- /*
- * Set physical address
- */
- mpc5200.paddr1 = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
- mpc5200.paddr2 = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
-
- }
-
-static int mpc5200_eth_mii_transfer(
- int phyAddr,
- unsigned regAddr,
- uint32_t data
-)
-{
- int timeout = 0xffff;
-
- mpc5200.ievent = FEC_INTR_MII;
-
- mpc5200.mii_data = MPC5200_FEC_MII_DATA_ST
- | MPC5200_FEC_MII_DATA_TA
- | (phyAddr << MPC5200_FEC_MII_DATA_PA_SHIFT)
- | (regAddr << MPC5200_FEC_MII_DATA_RA_SHIFT)
- | data;
-
- while (timeout > 0 && (mpc5200.ievent & FEC_INTR_MII) == 0) {
- --timeout;
- }
-
- return timeout > 0 ? 0 : -1;
-}
-
-/* FIXME: Make this static, this needs a fix in an application */
-int mpc5200_eth_mii_read(
- int phyAddr,
- void *arg,
- unsigned regAddr,
- uint32_t *retVal
-)
-{
- int rv = mpc5200_eth_mii_transfer(
- phyAddr,
- regAddr,
- MPC5200_FEC_MII_DATA_OP_RD
- );
-
- *retVal = mpc5200.mii_data & 0xffff;
-
- return rv;
-}
-
-static int mpc5200_eth_mii_write(
- int phyAddr,
- void *arg,
- unsigned regAddr,
- uint32_t data
-)
-{
- return mpc5200_eth_mii_transfer(
- phyAddr,
- regAddr,
- MPC5200_FEC_MII_DATA_OP_WR | data
- );
-}
-
-
-/*
- * Reset a running ethernet driver including the hardware FIFOs and the FEC.
- */
-static void mpc5200_fec_reset(mpc5200_fec_context *self)
-{
- volatile int delay;
- /*
- * Clear FIFO status registers
- */
- mpc5200.rfifo_status &= FEC_FIFO_STAT_ERROR;
- mpc5200.tfifo_status &= FEC_FIFO_STAT_ERROR;
-
- /*
- * reset the FIFOs
- */
- mpc5200.reset_cntrl = 0x03000000;
-
- for (delay = 0;delay < 16*4;delay++) {};
-
- mpc5200.reset_cntrl = 0x01000000;
-
- /*
- * Issue a reset command to the FEC chip
- */
- mpc5200.ecntrl |= FEC_ECNTRL_RESET;
-
- /*
- * wait at least 16 clock cycles
- */
- for (delay = 0;delay < 16*4;delay++) {};
-}
-
-
-/*
- * Function: mpc5200_fec_off
- *
- * Description: Stop the FEC and disable the ethernet SmartComm tasks.
- * This function "turns off" the driver.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_fec_off(mpc5200_fec_context *self)
- {
- int counter = 0xffff;
-
-
-#if defined(ETH_DEBUG)
- uint32_t phyStatus;
- int i;
-
- for(i = 0; i < 9; i++)
- {
-
- mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
- printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
-
- }
-
- for(i = 16; i < 21; i++)
- {
-
- mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
- printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
-
- }
-#endif /* ETH_DEBUG */
-
- /*
- * block FEC chip interrupts
- */
- mpc5200.imask = 0;
-
- /*
- * issue graceful stop command to the FEC transmitter if necessary
- */
- mpc5200.x_cntrl |= FEC_XCNTRL_GTS;
-
- /*
- * wait for graceful stop to register
- * FIXME: add rtems_task_wake_after here, if it takes to long
- */
- while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA)));
-
- mpc5200_fec_stop_dma();
-
- /*
- * Disable transmit / receive interrupts
- */
- bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);
- bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);
-
- /*
- * Disable the Ethernet Controller
- */
- mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN);
-}
-
-/*
- * MPC5200 FEC interrupt handler
- */
-static void mpc5200_fec_irq_handler(rtems_irq_hdl_param handle)
-{
- mpc5200_fec_context *self = (mpc5200_fec_context *) handle;
- volatile uint32_t ievent;
-
- ievent = mpc5200.ievent;
-
- mpc5200.ievent = ievent;
- /*
- * check errors, update statistics
- */
- if (ievent & FEC_INTR_LATE_COL) {
- self->txLateCollision++;
- }
- if (ievent & FEC_INTR_COL_RETRY) {
- self->txRetryLimit++;
- }
- if (ievent & FEC_INTR_XFIFO_UN) {
- self->txUnderrun++;
- }
- if (ievent & FEC_INTR_XFIFO_ERR) {
- self->txFIFOError++;
- }
- if (ievent & FEC_INTR_RFIFO_ERR) {
- self->rxFIFOError++;
- }
- /*
- * fatal error ocurred?
- */
- if (ievent & (FEC_INTR_XFIFO_ERR | FEC_INTR_RFIFO_ERR)) {
- mpc5200.imask &= ~(FEC_INTR_XFERREN | FEC_INTR_RFERREN);
- mpc5200_fec_request_restart(self);
- }
-}
-
-static void mpc5200_smartcomm_rx_irq_handler(void *arg)
-{
- mpc5200_fec_context *self = arg;
-
- ++self->rxInterrupts;
- mpc5200_fec_send_event(self->rxDaemonTid);
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_RECV_TASK_NO);
- bestcomm_glue_irq_disable(FEC_RECV_TASK_NO);
-}
-
-static void mpc5200_smartcomm_tx_irq_handler(void *arg)
-{
- mpc5200_fec_context *self = arg;
-
- ++self->txInterrupts;
- mpc5200_fec_send_event(self->txDaemonTid);
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_XMIT_TASK_NO);
- bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO);
-}
-
-static void mpc5200_fec_init_mib(mpc5200_fec_context *self)
-{
- memset(RTEMS_DEVOLATILE(uint8_t *, &mpc5200.RES [0]), 0, 0x2e4);
- mpc5200.mib_control = 0x40000000;
-}
-
-/*
- * Function: mpc5200_fec_initialize_hardware
- *
- * Description: Configure the MPC5200 FEC registers and enable the
- * SmartComm tasks. This function "turns on" the driver.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_fec_initialize_hardware(mpc5200_fec_context *self)
-{
- /* We want at most 2.5MHz */
- uint32_t div = 2 * 2500000;
- uint32_t mii_speed = (IPB_CLOCK + div - 1) / div;
-
- /*
- * Reset mpc5200 FEC
- */
- mpc5200_fec_reset(self);
- mpc5200_fec_init_mib(self);
-
- /*
- * Clear FEC-Lite interrupt event register (IEVENT)
- */
- mpc5200.ievent = FEC_INTR_CLEAR_ALL;
-
- /*
- * Set interrupt mask register
- */
- mpc5200.imask = FEC_INTR_MASK_USED;
- /*
- * Set FEC-Lite receive control register (R_CNTRL)
- * frame length=1518, MII mode for 18-wire-transceiver
- */
- mpc5200.r_cntrl = ((ETHER_MAX_LEN << FEC_RCNTRL_MAX_FL_SHIFT)
- | FEC_RCNTRL_FCE
- | FEC_RCNTRL_MII_MODE);
-
- /*
- * Set FEC-Lite transmit control register (X_CNTRL)
- * full-duplex, heartbeat disabled
- */
- mpc5200.x_cntrl = FEC_XCNTRL_FDEN;
-
-
-
- /*
- * Set MII_SPEED = IPB clock / (2 * mii_speed))
- * and do not drop the Preamble.
- */
- mpc5200.mii_speed = mii_speed << 1;
-
- /*
- * Set Opcode/Pause Duration Register
- */
- mpc5200.op_pause = 0x00010020;
-
- /*
- * Set Rx FIFO alarm and granularity value
- */
- mpc5200.rfifo_cntrl = (FEC_FIFO_CNTRL_FRAME
- | (0x7 << FEC_FIFO_CNTRL_GR_SHIFT));
- mpc5200.rfifo_alarm = 0x0000030c;
-
- /*
- * Set Tx FIFO granularity value
- */
- mpc5200.tfifo_cntrl = (FEC_FIFO_CNTRL_FRAME
- | (0x7 << FEC_FIFO_CNTRL_GR_SHIFT));
-
- /*
- * Set transmit fifo watermark register (X_WMRK), default = 64
- */
- mpc5200.tfifo_alarm = 0x00000100; /* 256 bytes */
- mpc5200.x_wmrk = FEC_XWMRK_256; /* 256 bytes */
-
- /*
- * Set individual address filter for unicast address
- * and set physical address registers.
- */
- mpc5200_eth_addr_filter_set(self);
-
- /*
- * Set multicast address filter
- */
- mpc5200.gaddr1 = 0x00000000;
- mpc5200.gaddr2 = 0x00000000;
-
- /*
- * enable CRC in finite state machine register
- */
- mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM;
-}
-
- /*
- * Initialize PHY(LXT971A):
- *
- * Generally, on power up, the LXT971A reads its configuration
- * pins to check for forced operation, If not cofigured for
- * forced operation, it uses auto-negotiation/parallel detection
- * to automatically determine line operating conditions.
- * If the PHY device on the other side of the link supports
- * auto-negotiation, the LXT971A auto-negotiates with it
- * using Fast Link Pulse(FLP) Bursts. If the PHY partner does not
- * support auto-negotiation, the LXT971A automatically detects
- * the presence of either link pulses(10Mbps PHY) or Idle
- * symbols(100Mbps) and sets its operating conditions accordingly.
- *
- * When auto-negotiation is controlled by software, the following
- * steps are recommended.
- *
- * Note:
- * The physical address is dependent on hardware configuration.
- *
- * Returns: void
- *
- * Notes:
- *
- */
-static void mpc5200_fec_initialize_phy(mpc5200_fec_context *self)
-{
- if (self->phyInitialized) {
- return;
- } else {
- self->phyInitialized = true;
- }
-
- /*
- * Reset PHY, then delay 300ns
- */
- mpc5200_eth_mii_write(self->phyAddr, self, 0x0, 0x8000);
-
- rtems_task_wake_after(2);
-
- /* MII100 */
-
- /*
- * Set the auto-negotiation advertisement register bits
- */
- mpc5200_eth_mii_write(self->phyAddr, self, 0x4, 0x01e1);
-
- /*
- * Set MDIO bit 0.12 = 1(&& bit 0.9=1?) to enable auto-negotiation
- */
- mpc5200_eth_mii_write(self->phyAddr, self, 0x0, 0x1200);
-
- /*
- * Wait for AN completion
- */
-#if 0
- int timeout = 0x100;
- uint32_t phyStatus;
- do
- {
-
- rtems_task_wake_after(2);
-
- if((timeout--) == 0)
- {
-
-#if defined(ETH_DEBUG)
- printf ("MPC5200FEC PHY auto neg failed." "\r\n");
-#endif
-
- }
-
- if(mpc5200_eth_mii_read(self->phyAddr, self, 0x1, &phyStatus) != true)
- {
-
-#if defined(ETH_DEBUG)
- printf ("MPC5200FEC PHY auto neg failed: 0x%04" PRIx32 ".\r\n", phyStatus);
-#endif
-
- return;
-
- }
-
- } while((phyStatus & 0x0020) != 0x0020);
-
-#endif
-#if ETH_PROMISCOUS_MODE
- mpc5200.r_cntrl |= 0x00000008; /* set to promiscous mode */
-#endif
-
-#if ETH_LOOP_MODE
- mpc5200.r_cntrl |= 0x00000001; /* set to loop mode */
-#endif
-
-#if defined(ETH_DEBUG)
- int i;
- uint32_t phyStatus;
- /*
- * Print PHY registers after initialization.
- */
- for(i = 0; i < 9; i++)
- {
-
- mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
- printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
-
- }
-
- for(i = 16; i < 21; i++)
- {
-
- mpc5200_eth_mii_read(self->phyAddr, self, i, &phyStatus);
- printf ("Mii reg %d: 0x%04" PRIx32 "\r\n", i, phyStatus);
-
- }
-#endif /* ETH_DEBUG */
-
- }
-
-static void mpc5200_fec_restart(mpc5200_fec_context *self, rtems_id otherDaemon)
-{
- if (self->state == FEC_STATE_RESTART_1) {
- mpc5200_fec_initialize_hardware(self);
- mpc5200_fec_initialize_phy(self);
- mpc5200_fec_start_dma_and_controller();
- self->state = FEC_STATE_NORMAL;
- } else {
- self->state = FEC_STATE_RESTART_1;
- }
-
- mpc5200_fec_send_event(otherDaemon);
- while (self->state != FEC_STATE_NORMAL) {
- mpc5200_fec_wait_for_event();
- }
-}
-
-/*
- * Send packet (caller provides header).
- */
-static void mpc5200_fec_tx_start(struct ifnet *ifp)
- {
-
- mpc5200_fec_context *self = ifp->if_softc;
-
- ifp->if_flags |= IFF_OACTIVE;
-
- mpc5200_fec_send_event(self->txDaemonTid);
-
- }
-
-static TaskBD1_t *mpc5200_fec_init_tx_dma(int bdCount, struct mbuf **mbufs)
-{
- TaskSetupParamSet_t param = {
- .NumBD = bdCount,
- .Size = {
- .MaxBuf = ETHER_MAX_LEN
- },
- .Initiator = 0,
- .StartAddrSrc = 0,
- .IncrSrc = sizeof(uint32_t),
- .SzSrc = sizeof(uint32_t),
- .StartAddrDst = (uint32) &mpc5200.tfifo_data,
- .IncrDst = 0,
- .SzDst = sizeof(uint32_t)
- };
- int bdIndex = 0;
-
- TaskSetup(FEC_XMIT_TASK_NO, &param);
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- mbufs [bdIndex] = NULL;
- }
-
- return (TaskBD1_t *) TaskGetBDRing(FEC_XMIT_TASK_NO);
-}
-
-#if 0
-static void mpc5200_fec_requeue_and_discard_tx_frames(
- int bdIndex,
- int bdCount,
- TaskBD1_t *bdRing,
- struct mbuf **mbufs
-)
-{
- int bdStop = bdIndex;
- struct mbuf *previous = NULL;
-
- do {
- struct mbuf *current = NULL;
- uint32 status = 0;
- TaskBD1_t *bd = NULL;
-
- if (bdIndex > 1) {
- --bdIndex;
- } else {
- bdIndex = bdCount - 1;
- }
-
- current = mbufs [bdIndex];
- mbufs [bdIndex] = NULL;
-
- status = bdRing [bdIndex].Status;
- bdRing [bdIndex].Status = 0;
-
- if (current != NULL) {
- if ((status & FEC_BD_LAST) != 0) {
- if (previous != NULL) {
- IF_PREPEND(&ifp->if_snd, previous);
- }
- }
- } else {
- break;
- }
-
- previous = current;
- } while (bdIndex != bdStop);
-}
-#endif
-
-static void mpc5200_fec_discard_tx_frames(
- int bdCount,
- struct mbuf **mbufs
-)
-{
- int bdIndex = 0;
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- struct mbuf *m = mbufs [bdIndex];
-
- if (m != NULL) {
- mbufs [bdIndex] = NULL;
- m_free(m);
- }
- }
-}
-
-static void mpc5200_fec_reset_tx_dma(
- int bdCount,
- TaskBD1_t *bdRing,
- struct mbuf **mbufs,
- struct mbuf *m
-)
-{
- TaskStop(FEC_XMIT_TASK_NO);
- TaskBDReset(FEC_XMIT_TASK_NO);
- mpc5200_fec_discard_tx_frames(bdCount, mbufs);
- while (m != NULL) {
- m = m_free(m);
- }
-}
-
-static struct mbuf *mpc5200_fec_next_fragment(
- struct ifnet *ifp,
- struct mbuf *m,
- bool *isFirst
-)
-{
- struct mbuf *n = NULL;
-
- *isFirst = false;
-
- while (true) {
- if (m == NULL) {
- IF_DEQUEUE(&ifp->if_snd, m);
-
- if (m != NULL) {
- *isFirst = true;
- } else {
- ifp->if_flags &= ~IFF_OACTIVE;
-
- return NULL;
- }
- }
-
- if (m->m_len > 0) {
- break;
- } else {
- m = m_free(m);
- }
- }
-
- n = m->m_next;
- while (n != NULL && n->m_len <= 0) {
- n = m_free(n);
- }
- m->m_next = n;
-
- return m;
-}
-
-static bool mpc5200_fec_transmit(
- struct ifnet *ifp,
- int bdCount,
- TaskBD1_t *bdRing,
- struct mbuf **mbufs,
- int *bdIndexPtr,
- struct mbuf **mPtr,
- TaskBD1_t **firstPtr
-)
-{
- bool bdShortage = false;
- int bdIndex = *bdIndexPtr;
- struct mbuf *m = *mPtr;
- TaskBD1_t *first = *firstPtr;
-
- while (true) {
- TaskBD1_t *bd = &bdRing [bdIndex];
-
- if (bd->Status == 0) {
- struct mbuf *done = mbufs [bdIndex];
- bool isFirst = false;
-
- if (done != NULL) {
- m_free(done);
- mbufs [bdIndex] = NULL;
- }
-
- m = mpc5200_fec_next_fragment(ifp, m, &isFirst);
- if (m != NULL) {
- uint32 status = (uint32) m->m_len;
-
- mbufs [bdIndex] = m;
-
- rtems_cache_flush_multiple_data_lines(mtod(m, void *), m->m_len);
-
- if (isFirst) {
- first = bd;
- } else {
- status |= FEC_BD_READY;
- }
-
- bd->DataPtr [0] = mtod(m, uint32);
-
- if (m->m_next != NULL) {
- bd->Status = status;
- } else {
- bd->Status = status | FEC_BD_INT | FEC_BD_LAST;
- first->Status |= FEC_BD_READY;
- SDMA_TASK_ENABLE(SDMA_TCR, FEC_XMIT_TASK_NO);
- }
-
- m = m->m_next;
- } else {
- break;
- }
- } else {
- bdShortage = true;
- break;
- }
-
- if (bdIndex < bdCount - 1) {
- ++bdIndex;
- } else {
- bdIndex = 0;
- }
- }
-
- *bdIndexPtr = bdIndex;
- *mPtr = m;
- *firstPtr = first;
-
- return bdShortage;
-}
-
-static void mpc5200_fec_tx_daemon(void *arg)
-{
- mpc5200_fec_context *self = arg;
- struct ifnet *ifp = &self->arpcom.ac_if;
- int bdIndex = 0;
- int bdCount = self->txBdCount;
- struct mbuf **mbufs = &self->txMbuf [0];
- struct mbuf *m = NULL;
- TaskBD1_t *bdRing = mpc5200_fec_init_tx_dma(bdCount, mbufs);
- TaskBD1_t *first = NULL;
- bool bdShortage = false;
-
- while (true) {
- if (bdShortage) {
- bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO);
- }
- mpc5200_fec_wait_for_event();
-
- if (self->state != FEC_STATE_NORMAL) {
- mpc5200_fec_reset_tx_dma(bdCount, bdRing, mbufs, m);
- mpc5200_fec_restart(self, self->rxDaemonTid);
- bdIndex = 0;
- m = NULL;
- first = NULL;
- }
-
- bdShortage = mpc5200_fec_transmit(
- ifp,
- bdCount,
- bdRing,
- mbufs,
- &bdIndex,
- &m,
- &first
- );
- }
-}
-
-static struct mbuf *mpc5200_fec_add_mbuf(struct ifnet *ifp, TaskBD1_t *bd)
-{
- struct mbuf *m = NULL;
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
-
- /* XXX: The dcbi operation does not work properly */
- rtems_cache_flush_multiple_data_lines(mtod(m, void *), ETHER_MAX_LEN);
-
- bd->DataPtr [0] = mtod(m, uint32);
- bd->Status = ETHER_MAX_LEN | FEC_BD_READY;
-
- return m;
-}
-
-static TaskBD1_t *mpc5200_fec_init_rx_dma(
- struct ifnet *ifp,
- int bdCount,
- struct mbuf **mbufs
-)
-{
- TaskSetupParamSet_t param = {
- .NumBD = bdCount,
- .Size = {
- .MaxBuf = ETHER_MAX_LEN
- },
- .Initiator = 0,
- .StartAddrSrc = (uint32) &mpc5200.rfifo_data,
- .IncrSrc = 0,
- .SzSrc = sizeof(uint32_t),
- .StartAddrDst = 0,
- .IncrDst = sizeof(uint32_t),
- .SzDst = sizeof(uint32_t)
- };
- TaskBD1_t *bdRing = NULL;
- int bdIndex = 0;
-
- TaskSetup(FEC_RECV_TASK_NO, &param);
- bdRing = (TaskBD1_t *) TaskGetBDRing(FEC_RECV_TASK_NO);
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- mbufs [bdIndex] = mpc5200_fec_add_mbuf(ifp, &bdRing [bdIndex]);
- }
-
- return bdRing;
-}
-
-static void mpc5200_fec_reset_rx_dma(int bdCount, TaskBD1_t *bdRing)
-{
- int bdIndex = 0;
-
- TaskStop(FEC_RECV_TASK_NO);
- TaskBDReset(FEC_RECV_TASK_NO);
-
- for (bdIndex = 0; bdIndex < bdCount; ++bdIndex) {
- bdRing [bdIndex].Status = ETHER_MAX_LEN | FEC_BD_READY;
- }
-}
-
-static int mpc5200_fec_ether_input(
- struct ifnet *ifp,
- int bdIndex,
- int bdCount,
- TaskBD1_t *bdRing,
- struct mbuf **mbufs
-)
-{
- while (true) {
- TaskBD1_t *bd = &bdRing [bdIndex];
- struct mbuf *m = mbufs [bdIndex];
- uint32 status = 0;
- int len = 0;
- struct ether_header *eh = NULL;
-
- SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend, FEC_RECV_TASK_NO);
- status = bd->Status;
-
- if ((status & FEC_BD_READY) != 0) {
- break;
- }
-
- eh = mtod(m, struct ether_header *);
-
- len = (status & 0xffff) - ETHER_HDR_LEN - ETHER_CRC_LEN;
- m->m_len = len;
- m->m_pkthdr.len = len;
- m->m_data = mtod(m, char *) + ETHER_HDR_LEN;
-
- ether_input(ifp, eh, m);
-
- mbufs [bdIndex] = mpc5200_fec_add_mbuf(ifp, bd);
-
- if (bdIndex < bdCount - 1) {
- ++bdIndex;
- } else {
- bdIndex = 0;
- }
- }
-
- return bdIndex;
-}
-
-static void mpc5200_fec_rx_daemon(void *arg)
-{
- mpc5200_fec_context *self = arg;
- struct ifnet *ifp = &self->arpcom.ac_if;
- int bdIndex = 0;
- int bdCount = self->rxBdCount;
- struct mbuf **mbufs = &self->rxMbuf [0];
- TaskBD1_t *bdRing = mpc5200_fec_init_rx_dma(ifp, bdCount, mbufs);
-
- while (true) {
- bestcomm_glue_irq_enable(FEC_RECV_TASK_NO);
- mpc5200_fec_wait_for_event();
-
- bdIndex = mpc5200_fec_ether_input(ifp, bdIndex, bdCount, bdRing, mbufs);
-
- if (self->state != FEC_STATE_NORMAL) {
- mpc5200_fec_reset_rx_dma(bdCount, bdRing);
- mpc5200_fec_restart(self, self->txDaemonTid);
- bdIndex = 0;
- }
- }
-}
-
-/*
- * Initialize and start the device
- */
-static void mpc5200_fec_init(void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- mpc5200_fec_context *self = (mpc5200_fec_context *)arg;
- struct ifnet *ifp = &self->arpcom.ac_if;
-
- if(self->txDaemonTid == 0)
- {
- size_t rxMbufTableSize = self->rxBdCount * sizeof(*self->rxMbuf);
- size_t txMbufTableSize = self->txBdCount * sizeof(*self->txMbuf);
-
- /*
- * Allocate a set of mbuf pointers
- */
- self->rxMbuf = malloc(rxMbufTableSize, M_MBUF, M_NOWAIT);
- self->txMbuf = malloc(txMbufTableSize, M_MBUF, M_NOWAIT);
-
- if(!self->rxMbuf || !self->txMbuf)
- rtems_panic ("No memory for mbuf pointers");
-
- /*
- * DMA setup
- */
- bestcomm_glue_init();
- mpc5200.sdma.ipr [0] = 4; /* always initiator */
- mpc5200.sdma.ipr [3] = 6; /* eth rx initiator */
- mpc5200.sdma.ipr [4] = 5; /* eth tx initiator */
-
- /*
- * Set up interrupts
- */
- bestcomm_glue_irq_install(FEC_RECV_TASK_NO,
- mpc5200_smartcomm_rx_irq_handler,
- self);
- bestcomm_glue_irq_install(FEC_XMIT_TASK_NO,
- mpc5200_smartcomm_tx_irq_handler,
- self);
- sc = rtems_interrupt_handler_install(
- BSP_SIU_IRQ_ETH,
- "FEC",
- RTEMS_INTERRUPT_UNIQUE,
- mpc5200_fec_irq_handler,
- self
- );
- if(sc != RTEMS_SUCCESSFUL) {
- rtems_panic ("Can't attach MPC5x00 FEX interrupt handler\n");
- }
-
- /*
- * Start driver tasks
- */
- self->txDaemonTid = rtems_bsdnet_newproc("FEtx", 4096, mpc5200_fec_tx_daemon, self);
- self->rxDaemonTid = rtems_bsdnet_newproc("FErx", 4096, mpc5200_fec_rx_daemon, self);
- }
-
- mpc5200_fec_request_restart(self);
-
- /*
- * Set flags appropriately
- */
- if(ifp->if_flags & IFF_PROMISC)
- mpc5200.r_cntrl |= 0x08;
- else
- mpc5200.r_cntrl &= ~0x08;
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-static void enet_stats (mpc5200_fec_context *self)
-{
- if (self->phyAddr >= 0) {
- struct ifnet *ifp = &self->arpcom.ac_if;
- int media = IFM_MAKEWORD(0, 0, 0, self->phyAddr);
- int rv = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t) &media);
-
- if (rv == 0) {
- rtems_ifmedia2str(media, NULL, 0);
- printf ("\n");
- } else {
- printf ("PHY communication error\n");
- }
- }
- printf (" Rx Interrupts:%-8lu", self->rxInterrupts);
- printf (" Rx Not First:%-8lu", self->rxNotFirst);
- printf (" Rx Not Last:%-8lu\n", self->rxNotLast);
- printf (" Rx Giant:%-8lu", self->rxGiant);
- printf (" Rx Non-octet:%-8lu", self->rxNonOctet);
- printf (" Rx Bad CRC:%-8lu\n", self->rxBadCRC);
- printf (" Rx FIFO Error:%-8lu", self->rxFIFOError);
- printf (" Rx Collision:%-8lu", self->rxCollision);
-
- printf (" Tx Interrupts:%-8lu\n", self->txInterrupts);
- printf (" Tx Deferred:%-8lu", self->txDeferred);
- printf (" Tx Late Collision:%-8lu", self->txLateCollision);
- printf (" Tx Retransmit Limit:%-8lu\n", self->txRetryLimit);
- printf (" Tx Underrun:%-8lu", self->txUnderrun);
- printf (" Tx FIFO Error:%-8lu", self->txFIFOError);
- printf (" Tx Misaligned:%-8lu\n", self->txMisaligned);
-}
-
-static int32_t mpc5200_fec_setMultiFilter(struct ifnet *ifp)
-{
- /*mpc5200_fec_context *self = ifp->if_softc; */
- /* XXX anything to do? */
- return 0;
-}
-
-
-/*
- * Driver ioctl handler
- */
-static int mpc5200_fec_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
- {
- mpc5200_fec_context *self = ifp->if_softc;
- int error = 0;
-
- switch(command)
- {
-
- case SIOCGIFADDR:
- case SIOCSIFADDR:
-
- ether_ioctl(ifp, command, data);
-
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI: {
- struct ifreq* ifr = (struct ifreq*) data;
- error = (command == SIOCADDMULTI)
- ? ether_addmulti(ifr, &self->arpcom)
- : ether_delmulti(ifr, &self->arpcom);
-
- if (error == ENETRESET) {
- if (ifp->if_flags & IFF_RUNNING)
- error = mpc5200_fec_setMultiFilter(ifp);
- else
- error = 0;
- }
- break;
- }
-
- case SIOCSIFFLAGS:
-
- switch(ifp->if_flags & (IFF_UP | IFF_RUNNING))
- {
-
- case IFF_RUNNING:
-
- mpc5200_fec_off(self);
-
- break;
-
- case IFF_UP:
-
- mpc5200_fec_init(self);
-
- break;
-
- case IFF_UP | IFF_RUNNING:
-
- mpc5200_fec_off(self);
- mpc5200_fec_init(self);
-
- break;
-
- default:
- break;
-
- }
-
- break;
-
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = rtems_mii_ioctl(&self->mdio, self, command, (int *) data);
- break;
-
- case SIO_RTEMS_SHOW_STATS:
-
- enet_stats(self);
-
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
-
- error = EINVAL;
-
- break;
-
- }
-
- return error;
-
- }
-
-
-/*
- * Attach the MPC5200 fec driver to the system
- */
-static int rtems_mpc5200_fec_driver_attach(struct rtems_bsdnet_ifconfig *config)
- {
- mpc5200_fec_context *self;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /*
- * Parse driver name
- */
- if((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber <= 0) || (unitNumber > NIFACES))
- {
-
- printf ("Bad FEC unit number.\n");
- return 0;
-
- }
-
- self = &enet_driver[unitNumber - 1];
- ifp = &self->arpcom.ac_if;
-
- if(ifp->if_softc != NULL)
- {
-
- printf ("Driver already in use.\n");
- return 0;
-
- }
-
- self->mdio.mdio_r = mpc5200_eth_mii_read;
- self->mdio.mdio_w = mpc5200_eth_mii_write;
-
- /*
- * Process options
- */
-#if NVRAM_CONFIGURE == 1
-
- /* Configure from NVRAM */
- if(addr = nvram->ipaddr)
- {
-
- /* We have a non-zero entry, copy the value */
- if(pAddr = malloc(INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT))
- config->ip_address = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1);
- else
- rtems_panic("Can't allocate ip_address buffer!\n");
-
- }
-
- if(addr = nvram->netmask)
- {
-
- /* We have a non-zero entry, copy the value */
- if (pAddr = malloc (INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT))
- config->ip_netmask = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1);
- else
- rtems_panic("Can't allocate ip_netmask buffer!\n");
-
- }
-
- /* Ethernet address requires special handling -- it must be copied into
- * the arpcom struct. The following if construct serves only to give the
- * User Area NVRAM parameter the highest priority.
- *
- * If the ethernet address is specified in NVRAM, go ahead and copy it.
- * (ETHER_ADDR_LEN = 6 bytes).
- */
- if(nvram->enaddr[0] || nvram->enaddr[1] || nvram->enaddr[2])
- {
-
- /* Anything in the first three bytes indicates a non-zero entry, copy value */
- memcpy((void *)self->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN);
-
- }
- else
- if(config->hardware_address)
- {
-
- /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */
- memcpy((void *)self->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- }
- else
- {
- /* There is no ethernet address provided, so it could be read
- * from the Ethernet protocol block of SCC1 in DPRAM.
- */
- rtems_panic("No Ethernet address specified!\n");
- }
-
-#else /* NVRAM_CONFIGURE != 1 */
-
- if(config->hardware_address)
- {
-
- memcpy(self->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
-
- }
- else
- {
-
- /* There is no ethernet address provided, so it could be read
- * from the Ethernet protocol block of SCC1 in DPRAM.
- */
- rtems_panic("No Ethernet address specified!\n");
-
- }
-
-#endif /* NVRAM_CONFIGURE != 1 */
-#ifdef HAS_UBOOT
- if ((self->arpcom.ac_enaddr[0] == 0) &&
- (self->arpcom.ac_enaddr[1] == 0) &&
- (self->arpcom.ac_enaddr[2] == 0)) {
- memcpy(
- (void *)self->arpcom.ac_enaddr,
- bsp_uboot_board_info.bi_enetaddr,
- ETHER_ADDR_LEN
- );
- }
-#endif
- if(config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- if(config->rbuf_count)
- self->rxBdCount = config->rbuf_count;
- else
- self->rxBdCount = RX_BUF_COUNT;
-
- if(config->xbuf_count)
- self->txBdCount = config->xbuf_count;
- else
- self->txBdCount = TX_BUF_COUNT;
-
- self->acceptBroadcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = self;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = mpc5200_fec_init;
- ifp->if_ioctl = mpc5200_fec_ioctl;
- ifp->if_start = mpc5200_fec_tx_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
- /*ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;*/
-
- if(ifp->if_snd.ifq_maxlen == 0)
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
-
- ether_ifattach(ifp);
-
- return 1;
- }
-
-
-int rtems_mpc5200_fec_driver_attach_detach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- if (attaching) {
- return rtems_mpc5200_fec_driver_attach(config);
- }
- else {
- return 0;
- }
-}
-
-