ColdFire: Add MCF547x_8x FEC driver
Subsystems (2)
PATCH 6/8 ColdFire: Add MCF547x_8x FEC driver
ColdFire: Add MCF547x_8x FEC driver
--- drivers/net/Makefile | 1 + drivers/net/fsl_mcdmafec.c | 582 +++++++++++++++++++++++++++++++++++++ +++++++ net/eth.c | 4 + 3 files changed, 587 insertions(+), 0 deletions(-) create mode 100644 drivers/net/fsl_mcdmafec.c
drivers/net/Makefile +1 -0
@@ -33,6 +33,7 @@ COBJS-y += dm9000x.o COBJS-y += e1000.o COBJS-y += eepro100.o COBJS-y += enc28j60.o +COBJS-y += fsl_mcdmafec.o COBJS-y += inca-ip_sw.o COBJS-y += ks8695eth.o COBJS-y += lan91c96.o
drivers/net/fsl_mcdmafec.c new file +117 -0
118 lines not on this page · raw message
length);
+int fec_recv(struct eth_device *dev);
+int fec_init(struct eth_device *dev, bd_t * bd);
+void fec_halt(struct eth_device *dev);
+extern int fecpin_setclear(struct eth_device *dev, int setclear); +
+#ifdef CFG_DISCOVER_PHY
+extern void mii_init(void);
+extern uint mii_send(uint mii_cmd);
+extern int mii_discover_phy(struct eth_device *dev); +extern int mcffec_miiphy_read(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short *value);
+extern int mcffec_miiphy_write(char *devname, unsigned char addr,
+ unsigned char reg, unsigned short value);
+#endif
+
+#ifdef ET_DEBUG
+void dbgFecRegs(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+ printf("=====\n");
+ printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir);
+ printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr);
+ printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr);
+ printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
+ printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr);
+ printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
+ printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr);
+ printf("r hash %x - %x\n", (int)&fecp->rhr, fecp->rhr);
+ printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr);
+ printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr);
+ printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur);
+ printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd);
+ printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur);
+ printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr);
+ printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur);
+ printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr);
+ printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
+ printf("r_fdata %x - %x\n", (int)&fecp->rfdr, fecp->rfdr);
+ printf("r_fstat %x - %x\n", (int)&fecp->rfsr, fecp->rfsr);
+ printf("r_fctrl %x - %x\n", (int)&fecp->rfcr, fecp->rfcr);
+ printf("r_flrfp %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp);
+ printf("r_flwfp %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp);
+ printf("r_frfar %x - %x\n", (int)&fecp->rfar, fecp->rfar);
+ printf("r_frfrp %x - %x\n", (int)&fecp->rfrp, fecp->rfrp);
+ printf("r_frfwp %x - %x\n", (int)&fecp->rfwp, fecp->rfwp);
+ printf("t_fdata %x - %x\n", (int)&fecp->tfdr, fecp->tfdr);
+ printf("t_fstat %x - %x\n", (int)&fecp->tfsr, fecp->tfsr);
+ printf("t_fctrl %x - %x\n", (int)&fecp->tfcr, fecp->tfcr);
+ printf("t_flrfp %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp);
+ printf("t_flwfp %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp);
+ printf("t_ftfar %x - %x\n", (int)&fecp->tfar, fecp->tfar);
+ printf("t_ftfrp %x - %x\n", (int)&fecp->tfrp, fecp->tfrp);
+ printf("t_ftfwp %x - %x\n", (int)&fecp->tfwp, fecp->tfwp);
+ printf("frst %x - %x\n", (int)&fecp->frst, fecp->frst);
+ printf("ctcwr %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr);+}
+#endif
+
+void setFecDuplexSpeed(volatile fecdma_t * fecp, bd_t * bd, int dup_spd)
+{
+ if ((dup_spd >> 16) == FULL) {
+ /* Set maximum frame length */
+ fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
+ FEC_RCR_PROM | 0x100;
+ fecp->tcr = FEC_TCR_FDEN;
+ } else {
+ /* Half duplex mode */
+ fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
+ FEC_RCR_MII_MODE | FEC_RCR_DRT;
+ fecp->tcr &= ~FEC_TCR_FDEN;
+ }
+
+ if ((dup_spd & 0xFFFF) == _100BASET) {
+#ifdef MII_DEBUG
+ printf("100Mbps\n");
+#endif
+ bd->bi_ethspeed = 100;
+ } else {
+#ifdef MII_DEBUG
+ printf("10Mbps\n");
+#endif
+ bd->bi_ethspeed = 10;
+ }
+}
+
+int fec_send(struct eth_device *dev, volatile void *packet, int length) +{
+ struct fec_info_dma *info = dev->priv;
+ cbd_t *pTbd, *pUsedTbd;
+ u16 phyStatus;
+
+ miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &phyStatus);
+
+ /* process all the consumed TBDs */
+ while (info->cleanTbdNum < CFG_TX_ETH_BUFFER) {
+ pUsedTbd = &info->txbd[info->usedTbdIdx];
+ if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) {
+#ifdef ET_DEBUG
+ printf("Cannot clean TBD %d, in use\n",
+ info->cleanTbdNum);
+#endif
+ return 0;
+ }
+
+ /* clean this buffer descriptor */
+ if (info->usedTbdIdx == (CFG_TX_ETH_BUFFER - 1))
+ pUsedTbd->cbd_sc = BD_ENET_TX_WRAP;
+ else
+ pUsedTbd->cbd_sc = 0;
+
+ /* update some indeces for a correct handling of the TBD ring */
+ info->cleanTbdNum++;
+ info->usedTbdIdx = (info->usedTbdIdx + 1) % CFG_TX_ETH_BUFFER;
+ }
+
+ /* Check for valid length of data. */
+ if ((length > 1500) || (length <= 0)) {
+ return -1;
+ }
+
+ /* Check the number of vacant TxBDs. */
+ if (info->cleanTbdNum < 1) {
+ printf("No available TxBDs ...\n");
+ return -1;
+ }
+
+ /* Get the first TxBD to send the mac header */
+ pTbd = &info->txbd[info->txIdx];
+ pTbd->cbd_datlen = length;
+ pTbd->cbd_bufaddr = (u32) packet;
+ pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY;
+ info->txIdx = (info->txIdx + 1) % CFG_TX_ETH_BUFFER;
+
+ /* Enable DMA transmit task */
+ MCD_continDma(info->txTask);
+
+ info->cleanTbdNum -= 1;
+
+ /* wait until frame is sent . */
+ while (pTbd->cbd_sc & BD_ENET_TX_READY) {
+ udelay(10);
+ }
+
+ return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
+}
+
+int fec_recv(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+ cbd_t *pRbd = &info->rxbd[info->rxIdx];
+ u32 ievent;
+ int frame_length, len = 0;
+
+ /* Check if any critical events have happened */
+ ievent = fecp->eir;
+ if (ievent != 0) {
+ fecp->eir = ievent;
+
+ if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {
+ printf("fec_recv: error\n");
+ fec_halt(dev);
+ fec_init(dev, NULL);
+ return 0;
+ }
+
+ if (ievent & FEC_EIR_HBERR) {
+ /* Heartbeat error */
+ fecp->tcr |= FEC_TCR_GTS;
+ }
+
+ if (ievent & FEC_EIR_GRA) {
+ /* Graceful stop complete */
+ if (fecp->tcr & FEC_TCR_GTS) {
+ printf("fec_recv: tcr_gts\n");
+ fec_halt(dev);
+ fecp->tcr &= ~FEC_TCR_GTS;
+ fec_init(dev, NULL);
+ }
+ }
+ }
+
+ if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) {
+ if ((pRbd->cbd_sc & BD_ENET_RX_LAST)
+ && !(pRbd->cbd_sc & BD_ENET_RX_ERR)
+ && ((pRbd->cbd_datlen - 4) > 14)) {
+
+ /* Get buffer address and size */
+ frame_length = pRbd->cbd_datlen - 4;
+
+ /* Fill the buffer and pass it to upper layers */
+ NetReceive((volatile uchar *)pRbd->cbd_bufaddr,
+ frame_length);
+ len = frame_length;
+ }
+
+ /* Reset buffer descriptor as empty */
+ if ((info->rxIdx) == (PKTBUFSRX - 1))
+ pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+ else
+ pRbd->cbd_sc = BD_ENET_RX_EMPTY;
+
+ pRbd->cbd_datlen = PKTSIZE_ALIGN;
+
+ /* Now, we have an empty RxBD, restart the DMA receive task */
+ MCD_continDma(info->rxTask);
+
+ /* Increment BD count */
+ info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX;
+ }
+
+ return len;
+}
+
+void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac)
+{
+ u8 currByte; /* byte for which to compute the CRC */
+ int byte; /* loop - counter */
+ int bit; /* loop - counter */
+ u32 crc = 0xffffffff; /* initial value */
+
+ 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) {
+ fecp->ialr = (1 << (crc - 32));
+ fecp->iaur = 0;
+ } else {
+ fecp->ialr = 0;
+ fecp->iaur = (1 << crc);
+ }
+
+ /* Set physical address */
+ fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
+ fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+
+ /* Clear multicast address hash table */
+ fecp->gaur = 0;
+ fecp->galr = 0;
+}
+
+int fec_init(struct eth_device *dev, bd_t * bd)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+ int i;
+
+#ifdef ET_DEBUG
+ printf("fec_init: iobase 0x%08x ...\n", info->iobase);
+#endif
+
+ fecpin_setclear(dev, 1);
+
+ fec_halt(dev);
+
+#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
+ defined (CFG_DISCOVER_PHY)
+
+ mii_init();
+
+ setFecDuplexSpeed(fecp, bd, info->dup_spd);
+#else
+#ifndef CFG_DISCOVER_PHY
+ setFecDuplexSpeed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
+#endif /* ifndef CFG_DISCOVER_PHY */
+#endif /* CONFIG_CMD_MII || CONFIG_MII */
+
+ /* We use strictly polling mode only */
+ fecp->eimr = 0;
+
+ /* Clear any pending interrupt */
+ fecp->eir = 0xffffffff;
+
+ /* Set station address */
+ if ((u32) fecp == CFG_FEC0_IOBASE) {
+ fec_set_hwaddr(fecp, bd->bi_enetaddr);
+ } else {
+ fec_set_hwaddr(fecp, bd->bi_enet1addr);
+ }
+
+ /* Set Opcode/Pause Duration Register */
+ fecp->opd = 0x00010020;
+
+ /* Setup Buffers and Buffer Desriptors */
+ info->rxIdx = 0;
+ info->txIdx = 0;
+
+ /* Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings: Empty, Wrap */
+ for (i = 0; i < PKTBUFSRX; i++) {
+ info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+ info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;
+ info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ }
+ info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings: Last, Tx CRC */
+ for (i = 0; i < CFG_TX_ETH_BUFFER; i++) {
+ info->txbd[i].cbd_sc = 0;
+ info->txbd[i].cbd_datlen = 0;
+ info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
+ }
+ info->txbd[CFG_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+ info->usedTbdIdx = 0;
+ info->cleanTbdNum = CFG_TX_ETH_BUFFER;
+
+ /* Set Rx FIFO alarm and granularity value */
+ fecp->rfcr = 0x0c000000;
+ fecp->rfar = 0x0000030c;
+
+ /* Set Tx FIFO granularity value */
+ fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;
+ fecp->tfar = 0x00000080;
+
+ fecp->tfwr = 0x2;
+ fecp->ctcwr = 0x03000000;
+
+ /* Enable DMA receive task */
+ MCD_startDma(info->rxTask, /* Dma channel */
+ (s8 *) info->rxbd, /*Source Address */ + 0, /* Source increment */ + (s8 *) (&fecp->rfdr), /* dest */ + 4, /* dest increment */ + 0, /* DMA size */ + 4, /* xfer size */ + info->rxInit, /* initiator */ + info->rxPri, /* priority */ + (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF), /* Flags */ + (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+ );
+
+ /* Enable DMA tx task with no ready buffer descriptors */
+ MCD_startDma(info->txTask, /* Dma channel */
+ (s8 *) info->txbd, /*Source Address */ + 0, /* Source increment */ + (s8 *) (&fecp->tfdr), /* dest */ + 4, /* dest incr */ + 0, /* DMA size */ + 4, /* xfer size */ + info->txInit, /* initiator */ + info->txPri, /* priority */ + (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF), /* Flags */ + (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+ );
+
+ /* Now enable the transmit and receive processing */
+ fecp->ecr |= FEC_ECR_ETHER_EN;
+
+ return 1;
+}
+
+void fec_halt(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+ int counter = 0xffff;
+
+ /* issue graceful stop command to the FEC transmitter if necessary */
+ fecp->tcr |= FEC_TCR_GTS;
+
+ /* wait for graceful stop to register */
+ while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ;
+
+ /* Disable DMA tasks */
+ MCD_killDma(info->txTask);
+ MCD_killDma(info->rxTask);;
+
+ /* Disable the Ethernet Controller */
+ fecp->ecr &= ~FEC_ECR_ETHER_EN;
+
+ /* Clear FIFO status registers */
+ fecp->rfsr &= FIFO_ERRSTAT;
+ fecp->tfsr &= FIFO_ERRSTAT;
+
+ fecp->frst = 0x01000000;
+
+ /* Issue a reset command to the FEC chip */
+ fecp->ecr |= FEC_ECR_RESET;
+
+ /* wait at least 20 clock cycles */
+ udelay(10000);
+
+#ifdef ET_DEBUG
+ printf("Ethernet task stopped\n");
+#endif
+}
+
+int fecdma_initialize(bd_t * bis)
+{
+ struct eth_device *dev;
+ int i;
+
+ for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {
+
+ dev =
+ (struct eth_device *)memalign(CFG_CACHELINE_SIZE,
+ sizeof *dev);
+ if (dev == NULL)
+ hang();
+
+ memset(dev, 0, sizeof(*dev));
+
+ sprintf(dev->name, "FEC%d", fec_info[i].index);
+
+ dev->priv = &fec_info[i];
+ dev->init = fec_init;
+ dev->halt = fec_halt;
+ dev->send = fec_send;
+ dev->recv = fec_recv;
+
+ /* setup Receive and Transmit buffer descriptor */
+ fec_info[i].rxbd =
+ (cbd_t *) memalign(CFG_CACHELINE_SIZE,
+ (PKTBUFSRX * sizeof(cbd_t)));
+ fec_info[i].txbd =
+ (cbd_t *) memalign(CFG_CACHELINE_SIZE,
+ (CFG_TX_ETH_BUFFER * sizeof(cbd_t)));
+ fec_info[i].txbuf =
+ (char *)memalign(CFG_CACHELINE_SIZE, DBUF_LENGTH);
+
+#ifdef ET_DEBUG
+ printf("rxbd %x txbd %x\n",
+ (int)fec_info[i].rxbd, (int)fec_info[i].txbd);
+#endif
+
+ fec_info[i].phy_name = (char *)memalign(CFG_CACHELINE_SIZE, 32);
+
+ eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+ miiphy_register(dev->name,
+ mcffec_miiphy_read, mcffec_miiphy_write);
+#endif
+
+ if (i > 0)
+ fec_info[i - 1].next = &fec_info[i];
+ }
+ fec_info[i - 1].next = &fec_info[0];
+
+ /* default speed */
+ bis->bi_ethspeed = 10;
+
+ return 1;
+}
+
+#endif /* CONFIG_CMD_NET && CONFIG_NET_MULTI */
+#endif /* CONFIG_FSLDMAFEC */
net/eth.c +4 -0
@@ -61,6 +61,7 @@ extern int uec_initialize(int);extern int bfin_EMAC_initialize (bd_t *);extern int atstk1000_eth_initialize (bd_t *);extern int mcffec_initialize (bd_t *); +extern int fecdma_initialize (bd_t *);#ifdef CONFIG_API extern void (*push_packet)(volatile void *,int );
@@ -272,6 +273,9 @@ int eth_initialize(bd_t *bis)#if defined(CONFIG_MCFFEC )mcffec_initialize (bis);#endif +#if defined(CONFIG_FSLDMAFEC ) +fecdma_initialize (bis); +#endif if (!eth_devices) {puts ("No ethernet found.\n" );
Signature · 1 line
1.5.2
PATCH 6/8 ColdFire: Add MCF547x_8x FEC driver
Quoted 156 lines · TsiChung Liew
ColdFire: Add
MCF547x_8xFEC driverSigned-off-by TsiChungLiew <[email protected]>--- drivers/net/Makefile | 1 + drivers/net/fsl_mcdmafec.c | 582 +++++++++++++++++++++++++++++++++++++ +++++++ net/eth.c | 4 + 3 files changed, 587 insertions(+), 0 deletions(-) create mode 100644 drivers/net/fsl_mcdmafec.cdrivers/net/Makefile +1
-0@@ -33,6 +33,7 @@ COBJS-y += dm9000x.o COBJS-y += e1000.o COBJS-y += eepro100.o COBJS-y += enc28j60.o +COBJS-y += fsl_mcdmafec.o COBJS-y += inca-ip_sw.o COBJS-y += ks8695eth.o COBJS-y += lan91c96.odrivers/net/fsl_mcdmafec.c new file +49
-0@@ -0,0 +1,582 @@ +/* +* (C) Copyright 2000-2004 +* Wolfgang Denk, DENX Software Engineering, wd at denx.de. +* +* (C) Copyright 2007 Freescale Semiconductor, Inc. +* TsiChung Liew (Tsi-Chung.Liew at freescale.com) +* +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#include <common.h> +#include <malloc.h> +#include <command.h> +#include <config.h> +#include <net.h> +#include <miiphy.h> + +#ifdef CONFIG_FSLDMAFEC +#undef ET_DEBUG +#undef MII_DEBUG + +/* Ethernet Transmit and Receive Buffers */ +#define DBUF_LENGTH 1520 +#define PKT_MAXBUF_SIZE 1518 +#define PKT_MINBUF_SIZE 64 +#define PKT_MAXBLR_SIZE 1536 +#define LAST_PKTBUFSRX PKTBUFSRX - 1 +#define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY) +#define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST) +#define FIFO_ERRSTAT (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF) + +/* RxBD bits definitions */ +#define BD_ENET_RX_ERR (BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR |\
drivers/net/fsl_mcdmafec.c new file +68
-0+ BD_ENET_RX_OV | BD_ENET_RX_TR) + +#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) +#include <asm/immap.h> +#include <asm/fsl_mcdmafec.h> + +#include "MCD_dma.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct fec_info_dma fec_info[] = { +#ifdef CFG_FEC0_IOBASE + { + 0, /* index */ + CFG_FEC0_IOBASE, /* io base */ + CFG_FEC0_PINMUX, /* gpio pin muxing */ + CFG_FEC0_MIIBASE, /* mii base */ + -1, /* phy_addr */ + 0, /* duplex and speed */ + 0, /* phy name */ + 0, /* phyname init */ + 0, /* RX BD */ + 0, /* TX BD */ + 0, /* rx Index */ + 0, /* tx Index */ + 0, /* tx buffer */ + 0, /* initialized flag */ + (struct fec_info_dma *)-1, /* next */ + FEC0_RX_TASK, /* rxTask */ + FEC0_TX_TASK, /* txTask */ + FEC0_RX_PRIORITY, /* rxPri */ + FEC0_TX_PRIORITY, /* txPri */ + FEC0_RX_INIT, /* rxInit */ + FEC0_TX_INIT, /* txInit */ + 0, /* usedTbdIndex */ + 0, /* cleanTbdNum */ + }, +#endif +#ifdef CFG_FEC1_IOBASE + { + 1, /* index */ + CFG_FEC1_IOBASE, /* io base */ + CFG_FEC1_PINMUX, /* gpio pin muxing */ + CFG_FEC1_MIIBASE, /* mii base */ + -1, /* phy_addr */ + 0, /* duplex and speed */ + 0, /* phy name */ + 0, /* phy name init */ + 0, /* RX BD */ + 0, /* TX BD */ + 0, /* rx Index */ + 0, /* tx Index */ + 0, /* tx buffer */ + 0, /* initialized flag */ + (struct fec_info_dma *)-1, /* next */ + FEC1_RX_TASK, /* rxTask */ + FEC1_TX_TASK, /* txTask */ + FEC1_RX_PRIORITY, /* rxPri */ + FEC1_TX_PRIORITY, /* txPri */ + FEC1_RX_INIT, /* rxInit */ + FEC1_TX_INIT, /* txInit */ + 0, /* usedTbdIndex */ + 0, /* cleanTbdNum */ + } +#endif +}; + +int fec_send(struct eth_device *dev, volatile void *packet, intlength);
drivers/net/fsl_mcdmafec.c new file +7
-0+int fec_recv (struct eth_device *dev); +int fec_init (struct eth_device *dev,bd_t * bd); +void fec_halt (struct eth_device *dev); +extern int fecpin_setclear (struct eth_device *dev,int setclear); + +#ifdef CFG_DISCOVER_PHY +extern void mii_init (void );
drivers/net/fsl_mcdmafec.c
Quoted 10 lines
drivers/net/fsl_mcdmafec.c new file +10
-0+extern uint mii_send (uint mii_cmd); +extern int mii_discover_phy (struct eth_device *dev); +extern int mcffec_miiphy_read (char *devname,unsigned char addr, +unsigned char reg,unsigned short *value); +extern int mcffec_miiphy_write (char *devname,unsigned char addr, +unsigned char reg,unsigned short value); +#endif + +#ifdef ET_DEBUG +void dbgFecRegs (struct eth_device *dev)
This, and most other functions, should be static
Quoted 44 lines
drivers/net/fsl_mcdmafec.c new file +44
-0+{ +struct fec_info_dma *info = dev->priv; +volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); + +printf ("=====\n" ); +printf ("ievent %x - %x\n" , (int )&fecp->eir, fecp->eir); +printf ("imask %x - %x\n" , (int )&fecp->eimr, fecp->eimr); +printf ("ecntrl %x - %x\n" , (int )&fecp->ecr, fecp->ecr); +printf ("mii_mframe %x - %x\n" , (int )&fecp->mmfr, fecp->mmfr); +printf ("mii_speed %x - %x\n" , (int )&fecp->mscr, fecp->mscr); +printf ("mii_ctrlstat %x - %x\n" , (int )&fecp->mibc, fecp->mibc); +printf ("r_cntrl %x - %x\n" , (int )&fecp->rcr, fecp->rcr); +printf ("r hash %x - %x\n" , (int )&fecp->rhr, fecp->rhr); +printf ("x_cntrl %x - %x\n" , (int )&fecp->tcr, fecp->tcr); +printf ("padr_l %x - %x\n" , (int )&fecp->palr, fecp->palr); +printf ("padr_u %x - %x\n" , (int )&fecp->paur, fecp->paur); +printf ("op_pause %x - %x\n" , (int )&fecp->opd, fecp->opd); +printf ("iadr_u %x - %x\n" , (int )&fecp->iaur, fecp->iaur); +printf ("iadr_l %x - %x\n" , (int )&fecp->ialr, fecp->ialr); +printf ("gadr_u %x - %x\n" , (int )&fecp->gaur, fecp->gaur); +printf ("gadr_l %x - %x\n" , (int )&fecp->galr, fecp->galr); +printf ("x_wmrk %x - %x\n" , (int )&fecp->tfwr, fecp->tfwr); +printf ("r_fdata %x - %x\n" , (int )&fecp->rfdr, fecp->rfdr); +printf ("r_fstat %x - %x\n" , (int )&fecp->rfsr, fecp->rfsr); +printf ("r_fctrl %x - %x\n" , (int )&fecp->rfcr, fecp->rfcr); +printf ("r_flrfp %x - %x\n" , (int )&fecp->rlrfp, fecp->rlrfp); +printf ("r_flwfp %x - %x\n" , (int )&fecp->rlwfp, fecp->rlwfp); +printf ("r_frfar %x - %x\n" , (int )&fecp->rfar, fecp->rfar); +printf ("r_frfrp %x - %x\n" , (int )&fecp->rfrp, fecp->rfrp); +printf ("r_frfwp %x - %x\n" , (int )&fecp->rfwp, fecp->rfwp); +printf ("t_fdata %x - %x\n" , (int )&fecp->tfdr, fecp->tfdr); +printf ("t_fstat %x - %x\n" , (int )&fecp->tfsr, fecp->tfsr); +printf ("t_fctrl %x - %x\n" , (int )&fecp->tfcr, fecp->tfcr); +printf ("t_flrfp %x - %x\n" , (int )&fecp->tlrfp, fecp->tlrfp); +printf ("t_flwfp %x - %x\n" , (int )&fecp->tlwfp, fecp->tlwfp); +printf ("t_ftfar %x - %x\n" , (int )&fecp->tfar, fecp->tfar); +printf ("t_ftfrp %x - %x\n" , (int )&fecp->tfrp, fecp->tfrp); +printf ("t_ftfwp %x - %x\n" , (int )&fecp->tfwp, fecp->tfwp); +printf ("frst %x - %x\n" , (int )&fecp->frst, fecp->frst); +printf ("ctcwr %x - %x\n" , (int )&fecp->ctcwr, fecp->ctcwr); +} +#endif + +void setFecDuplexSpeed(volatile fecdma_t * fecp, bd_t * bd, int
Quoted 2 lines
dup_spd)
Weird line wrap?
Quoted 297 lines
drivers/net/fsl_mcdmafec.c new file +296
-0+{ +if ((dup_spd >>16 ) ==FULL ) { +/* Set maximum frame length */ + fecp->rcr =FEC_RCR_MAX_FL (PKT_MAXBUF_SIZE ) |FEC_RCR_MII_MODE | +FEC_RCR_PROM |0x100 ; + fecp->tcr =FEC_TCR_FDEN ; + }else { +/* Half duplex mode */ + fecp->rcr =FEC_RCR_MAX_FL (PKT_MAXBUF_SIZE ) | +FEC_RCR_MII_MODE |FEC_RCR_DRT ; + fecp->tcr &= ~FEC_TCR_FDEN ; + } + +if ((dup_spd &0xFFFF ) == _100BASET) { +#ifdef MII_DEBUG +printf ("100Mbps\n" ); +#endif + bd->bi_ethspeed =100 ; + }else { +#ifdef MII_DEBUG +printf ("10Mbps\n" ); +#endif + bd->bi_ethspeed =10 ; + } +} + +int fec_send (struct eth_device *dev,volatile void *packet,int length) +{ +struct fec_info_dma *info = dev->priv; +cbd_t *pTbd, *pUsedTbd; +u16 phyStatus; + +miiphy_read (dev->name, info->phy_addr,PHY_BMSR , &phyStatus); + +/* process all the consumed TBDs */ +while (info->cleanTbdNum <CFG_TX_ETH_BUFFER ) { + pUsedTbd = &info->txbd[info->usedTbdIdx]; +if (pUsedTbd->cbd_sc &BD_ENET_TX_READY ) { +#ifdef ET_DEBUG +printf ("Cannot clean TBD %d, in use\n" , + info->cleanTbdNum); +#endif +return 0 ; + } + +/* clean this buffer descriptor */ +if (info->usedTbdIdx == (CFG_TX_ETH_BUFFER -1 )) + pUsedTbd->cbd_sc =BD_ENET_TX_WRAP ; +else + pUsedTbd->cbd_sc =0 ; + +/* update some indeces for a correct handling of the TBD ring */ + info->cleanTbdNum++; + info->usedTbdIdx = (info->usedTbdIdx +1 ) %CFG_TX_ETH_BUFFER ; + } + +/* Check for valid length of data. */ +if ((length >1500 ) || (length <=0 )) { +return -1 ; + } + +/* Check the number of vacant TxBDs. */ +if (info->cleanTbdNum <1 ) { +printf ("No available TxBDs ...\n" ); +return -1 ; + } + +/* Get the first TxBD to send the mac header */ + pTbd = &info->txbd[info->txIdx]; + pTbd->cbd_datlen = length; + pTbd->cbd_bufaddr = (u32 ) packet; + pTbd->cbd_sc |=BD_ENET_TX_LAST |BD_ENET_TX_TC |BD_ENET_TX_READY ; + info->txIdx = (info->txIdx +1 ) %CFG_TX_ETH_BUFFER ; + +/* Enable DMA transmit task */ +MCD_continDma (info->txTask); + + info->cleanTbdNum -=1 ; + +/* wait until frame is sent . */ +while (pTbd->cbd_sc &BD_ENET_TX_READY ) { +udelay (10 ); + } + +return (int )(info->txbd[info->txIdx].cbd_sc &BD_ENET_TX_STATS ); +} + +int fec_recv (struct eth_device *dev) +{ +struct fec_info_dma *info = dev->priv; +volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); + +cbd_t *pRbd = &info->rxbd[info->rxIdx]; +u32 ievent; +int frame_length, len =0 ; + +/* Check if any critical events have happened */ + ievent = fecp->eir; +if (ievent !=0 ) { + fecp->eir = ievent; + +if (ievent & (FEC_EIR_BABT |FEC_EIR_TXERR |FEC_EIR_RXERR )) { +printf ("fec_recv: error\n" ); +fec_halt (dev); +fec_init (dev,NULL ); +return 0 ; + } + +if (ievent &FEC_EIR_HBERR ) { +/* Heartbeat error */ + fecp->tcr |=FEC_TCR_GTS ; + } + +if (ievent &FEC_EIR_GRA ) { +/* Graceful stop complete */ +if (fecp->tcr &FEC_TCR_GTS ) { +printf ("fec_recv: tcr_gts\n" ); +fec_halt (dev); + fecp->tcr &= ~FEC_TCR_GTS ; +fec_init (dev,NULL ); + } + } + } + +if (!(pRbd->cbd_sc &BD_ENET_RX_EMPTY )) { +if ((pRbd->cbd_sc &BD_ENET_RX_LAST ) + && !(pRbd->cbd_sc &BD_ENET_RX_ERR ) + && ((pRbd->cbd_datlen -4 ) >14 )) { + +/* Get buffer address and size */ + frame_length = pRbd->cbd_datlen -4 ; + +/* Fill the buffer and pass it to upper layers */ +NetReceive ((volatile uchar *)pRbd->cbd_bufaddr, + frame_length); + len = frame_length; + } + +/* Reset buffer descriptor as empty */ +if ((info->rxIdx) == (PKTBUFSRX -1 )) + pRbd->cbd_sc = (BD_ENET_RX_WRAP |BD_ENET_RX_EMPTY ); +else + pRbd->cbd_sc =BD_ENET_RX_EMPTY ; + + pRbd->cbd_datlen =PKTSIZE_ALIGN ; + +/* Now, we have an empty RxBD, restart the DMA receive task */ +MCD_continDma (info->rxTask); + +/* Increment BD count */ + info->rxIdx = (info->rxIdx +1 ) %PKTBUFSRX ; + } + +return len; +} + +void fec_set_hwaddr (volatile fecdma_t * fecp,u8 * mac) +{ +u8 currByte;/* byte for which to compute the CRC */ +int byte;/* loop - counter */ +int bit;/* loop - counter */ +u32 crc =0xffffffff ;/* initial value */ + +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 ) { + fecp->ialr = (1 << (crc -32 )); + fecp->iaur =0 ; + }else { + fecp->ialr =0 ; + fecp->iaur = (1 << crc); + } + +/* Set physical address */ + fecp->palr = (mac[0 ] <<24 ) + (mac[1 ] <<16 ) + (mac[2 ] <<8 ) + mac[3 ]; + fecp->paur = (mac[4 ] <<24 ) + (mac[5 ] <<16 ) +0x8808 ; + +/* Clear multicast address hash table */ + fecp->gaur =0 ; + fecp->galr =0 ; +} + +int fec_init (struct eth_device *dev,bd_t * bd) +{ +struct fec_info_dma *info = dev->priv; +volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); +int i; + +#ifdef ET_DEBUG +printf ("fec_init: iobase 0x%08x ...\n" , info->iobase); +#endif + +fecpin_setclear (dev,1 ); + +fec_halt (dev); + +#if defined(CONFIG_CMD_MII ) || defined (CONFIG_MII ) || \ + defined (CFG_DISCOVER_PHY ) + +mii_init (); + +setFecDuplexSpeed (fecp, bd, info->dup_spd); +#else +#ifndef CFG_DISCOVER_PHY +setFecDuplexSpeed (fecp, bd, (FECDUPLEX <<16 ) |FECSPEED ); +#endif /* ifndef CFG_DISCOVER_PHY */ +#endif /* CONFIG_CMD_MII || CONFIG_MII */ + +/* We use strictly polling mode only */ + fecp->eimr =0 ; + +/* Clear any pending interrupt */ + fecp->eir =0xffffffff ; + +/* Set station address */ +if ((u32 ) fecp ==CFG_FEC0_IOBASE ) { +fec_set_hwaddr (fecp, bd->bi_enetaddr); + }else { +fec_set_hwaddr (fecp, bd->bi_enet1addr); + } + +/* Set Opcode/Pause Duration Register */ + fecp->opd =0x00010020 ; + +/* Setup Buffers and Buffer Desriptors */ + info->rxIdx =0 ; + info->txIdx =0 ; + +/* Setup Receiver Buffer Descriptors (13.14.24.18) +* Settings: Empty, Wrap */ +for (i =0 ; i <PKTBUFSRX ; i++) { + info->rxbd[i].cbd_sc =BD_ENET_RX_EMPTY ; + info->rxbd[i].cbd_datlen =PKTSIZE_ALIGN ; + info->rxbd[i].cbd_bufaddr = (uint ) NetRxPackets[i]; + } + info->rxbd[PKTBUFSRX -1 ].cbd_sc |=BD_ENET_RX_WRAP ; + +/* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) +* Settings: Last, Tx CRC */ +for (i =0 ; i <CFG_TX_ETH_BUFFER ; i++) { + info->txbd[i].cbd_sc =0 ; + info->txbd[i].cbd_datlen =0 ; + info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0 ]); + } + info->txbd[CFG_TX_ETH_BUFFER -1 ].cbd_sc |=BD_ENET_TX_WRAP ; + + info->usedTbdIdx =0 ; + info->cleanTbdNum =CFG_TX_ETH_BUFFER ; + +/* Set Rx FIFO alarm and granularity value */ + fecp->rfcr =0x0c000000 ; + fecp->rfar =0x0000030c ; + +/* Set Tx FIFO granularity value */ + fecp->tfcr =FIFO_CTRL_FRAME |FIFO_CTRL_GR (6 ) |0x00040000 ; + fecp->tfar =0x00000080 ; + + fecp->tfwr =0x2 ; + fecp->ctcwr =0x03000000 ; + +/* Enable DMA receive task */ +MCD_startDma (info->rxTask,/* Dma channel */ + (s8 *) info->rxbd,/*Source Address */ +0 ,/* Source increment */ + (s8 *) (&fecp->rfdr),/* dest */ +4 ,/* dest increment */ +0 ,/* DMA size */ +4 ,/* xfer size */ + info->rxInit,/* initiator */ + info->rxPri,/* priority */ + (MCD_FECRX_DMA |MCD_TT_FLAGS_DEF ),/* Flags */ + (MCD_NO_CSUM |MCD_NO_BYTE_SWAP )/* Function description */ + ); + +/* Enable DMA tx task with no ready buffer descriptors */ + MCD_startDma(info->txTask, /* Dma channel */ + (s8 *) info->txbd, /*Source Address */ + 0, /* Source increment */ + (s8 *) (&fecp->tfdr), /* dest */ + 4, /* dest incr */ + 0, /* DMA size */ + 4, /* xfer size */
drivers/net/fsl_mcdmafec.c
Quoted 10 lines
drivers/net/fsl_mcdmafec.c new file +10
-0+ info->txInit,/* initiator */ + info->txPri,/* priority */ + (MCD_FECTX_DMA |MCD_TT_FLAGS_DEF ),/* Flags */ + (MCD_NO_CSUM |MCD_NO_BYTE_SWAP )/* Function description */ + ); + +/* Now enable the transmit and receive processing */ + fecp->ecr |=FEC_ECR_ETHER_EN ; + +return 1 ;
Return 0 on success
Quoted 103 lines
drivers/net/fsl_mcdmafec.c new file +98
-0+} + +void fec_halt (struct eth_device *dev) +{ +struct fec_info_dma *info = dev->priv; +volatile fecdma_t *fecp = (fecdma_t *) (info->iobase); +int counter =0xffff ; + +/* issue graceful stop command to the FEC transmitter if necessary */ + fecp->tcr |=FEC_TCR_GTS ; + +/* wait for graceful stop to register */ +while ((counter--) && (!(fecp->eir &FEC_EIR_GRA ))) ; + +/* Disable DMA tasks */ +MCD_killDma (info->txTask); +MCD_killDma (info->rxTask);; + +/* Disable the Ethernet Controller */ + fecp->ecr &= ~FEC_ECR_ETHER_EN ; + +/* Clear FIFO status registers */ + fecp->rfsr &=FIFO_ERRSTAT ; + fecp->tfsr &=FIFO_ERRSTAT ; + + fecp->frst =0x01000000 ; + +/* Issue a reset command to the FEC chip */ + fecp->ecr |=FEC_ECR_RESET ; + +/* wait at least 20 clock cycles */ +udelay (10000 ); + +#ifdef ET_DEBUG +printf ("Ethernet task stopped\n" ); +#endif +} + +int fecdma_initialize (bd_t * bis) +{ +struct eth_device *dev; +int i; + +for (i =0 ; i <sizeof (fec_info) /sizeof (fec_info[0 ]); i++) { + + dev = + (struct eth_device *)memalign (CFG_CACHELINE_SIZE , +sizeof *dev); +if (dev ==NULL ) +hang (); + +memset (dev,0 ,sizeof (*dev)); + +sprintf (dev->name,"FEC%d" , fec_info[i].index); + + dev->priv = &fec_info[i]; + dev->init = fec_init; + dev->halt = fec_halt; + dev->send = fec_send; + dev->recv = fec_recv; + +/* setup Receive and Transmit buffer descriptor */ + fec_info[i].rxbd = + (cbd_t *)memalign (CFG_CACHELINE_SIZE , + (PKTBUFSRX *sizeof (cbd_t))); + fec_info[i].txbd = + (cbd_t *)memalign (CFG_CACHELINE_SIZE , + (CFG_TX_ETH_BUFFER *sizeof (cbd_t))); + fec_info[i].txbuf = + (char *)memalign (CFG_CACHELINE_SIZE ,DBUF_LENGTH ); + +#ifdef ET_DEBUG +printf ("rxbd %x txbd %x\n" , + (int )fec_info[i].rxbd, (int )fec_info[i].txbd); +#endif + + fec_info[i].phy_name = (char *)memalign (CFG_CACHELINE_SIZE ,32 ); + +eth_register (dev); + +#if defined(CONFIG_MII ) || defined(CONFIG_CMD_MII ) +miiphy_register (dev->name, + mcffec_miiphy_read, mcffec_miiphy_write); +#endif + +if (i >0 ) + fec_info[i -1 ].next = &fec_info[i]; + } + fec_info[i -1 ].next = &fec_info[0 ]; + +/* default speed */ + bis->bi_ethspeed =10 ; + +return 1 ; +} + +#endif /* CONFIG_CMD_NET && CONFIG_NET_MULTI */ +#endif /* CONFIG_FSLDMAFEC */ net/eth.c +0
-0
net/eth.c extern int uec_initialize(int); · line 65
Quoted 5 lines
net/eth.c +1
-0@@ -61,6 +61,7 @@ extern int uec_initialize(int);extern int bfin_EMAC_initialize (bd_t *);extern int atstk1000_eth_initialize (bd_t *);extern int mcffec_initialize (bd_t *); +extern int fecdma_initialize (bd_t *);
Can you pick a more descriptive name than fecdma, please. At the very least it should be mcffecdma so we know it's Coldfire.
Quoted 14 lines
net/eth.c +3
-0#ifdef CONFIG_API extern void (*push_packet)(volatile void *,int );@@ -272,6 +273,9 @@ int eth_initialize(bd_t *bis)#if defined(CONFIG_MCFFEC )mcffec_initialize (bis);#endif +#if defined(CONFIG_FSLDMAFEC ) +fecdma_initialize (bis); +#endif if (!eth_devices) {puts ("No ethernet found.\n" );
PATCH 6/8 ColdFire: Add MCF547x_8x FEC driver
Ben,
Yes. I agree the function name is not very descriptive. Willmcdmafec_initialize() work (mcdma - multi-channel dma)? I can't name it specific to coldfire, because this driver will also work on MPC8220.
Regards,
TsiChung
Quoted 10 lines
net/eth.c +0
-0@@ -61,6 +61,7 @@ extern int uec_initialize(int); extern int
bfin_EMAC_initialize(bd_t *); extern intatstk1000_eth_initialize(bd_t *); extern intmcffec_initialize(bd_t*);
+extern intfecdma_initialize(bd_t*);
Can you pick a more descriptive name than fecdma, please. At the very least it should be mcffecdma so we know it's Coldfire.
Quoted 14 lines
#ifdef
CONFIG_API
extern void (*push_packet)(volatile void *, int); @@ -272,6 +273,9 @@int
eth_initialize(bd_t *bis)#ifdefined(CONFIG_MCFFEC)net/eth.c +3
-0mcffec_initialize (bis);#endif +#if defined(CONFIG_FSLDMAFEC ) +fecdma_initialize (bis); +#endif if (!eth_devices) {puts ("No ethernet found.\n" );
PATCH 6/8 ColdFire: Add MCF547x_8x FEC driver
Quoted 11 lines · Liew Tsi Chung
Ben,
Yes. I agree the function name is not very descriptive. Will
mcdmafec_initialize()work (mcdma - multi-channel dma)? I can't name it specific to coldfire, because this driver will also work on MPC8220.Regards,
TsiChung
Sure, that's better.
Quoted 36 lines
Quoted 11 lines
net/eth.c +0
-0@@ -61,6 +61,7 @@ extern int uec_initialize(int); extern int
bfin_EMAC_initialize(bd_t *); extern intatstk1000_eth_initialize(bd_t *); extern intmcffec_initialize(bd_t*);
+extern intfecdma_initialize(bd_t*);Can you pick a more descriptive name than fecdma, please. At the very least it should be mcffecdma so we know it's Coldfire.
Quoted 17 lines
#ifdef
CONFIG_API
extern void (*push_packet)(volatile void *, int); @@ -272,6 +273,9 @@int
eth_initialize(bd_t *bis)#ifdefined(CONFIG_MCFFEC)net/eth.c +3
-0mcffec_initialize (bis);#endif +#if defined(CONFIG_FSLDMAFEC ) +fecdma_initialize (bis); +#endif if (!eth_devices) {puts ("No ethernet found.\n" );