public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver
@ 2008-01-16  0:23 Tsi-Chung Liew
  2008-01-16  2:34 ` Ben Warren
  0 siblings, 1 reply; 10+ messages in thread
From: Tsi-Chung Liew @ 2008-01-16  0:23 UTC (permalink / raw)
  To: u-boot

Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
---
 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

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 41e1bde..b9723fa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -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
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
new file mode 100644
index 0000000..5f6b730
--- /dev/null
+++ b/drivers/net/fsl_mcdmafec.c
@@ -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 | \
+			 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, int 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 mcdmafec_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 */
diff --git a/net/eth.c b/net/eth.c
index 5d9e9c1..bcd7d42 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -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 mcdmafec_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)
+	mcdmafec_initialize(bis);
+#endif
 
 	if (!eth_devices) {
 		puts ("No ethernet found.\n");
-- 
1.5.2

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver
  2008-01-16  0:23 [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver Tsi-Chung Liew
@ 2008-01-16  2:34 ` Ben Warren
  2008-01-16 12:46   ` Wolfgang Denk
  0 siblings, 1 reply; 10+ messages in thread
From: Ben Warren @ 2008-01-16  2:34 UTC (permalink / raw)
  To: u-boot

Tsi-Chung Liew wrote:
> Signed-off-by: TsiChungLiew <Tsi-Chung.Liew@freescale.com>
> ---
>  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
>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 41e1bde..b9723fa 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -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
> diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
> new file mode 100644
> index 0000000..5f6b730
> --- /dev/null
> +++ b/drivers/net/fsl_mcdmafec.c
> @@ -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
>   
Please align better
> +#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 | \
> +			 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, int 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)
>   
set_fec_duple_speed()
I asked you last time to make functions static, but you haven't done 
that yet
> +{
> +	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;
> +}
>   
This needs to return 0 on success. I mentioned this before as well.
> +
> +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 mcdmafec_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 */
> diff --git a/net/eth.c b/net/eth.c
> index 5d9e9c1..bcd7d42 100644
> --- a/net/eth.c
> +++ b/net/eth.c
> @@ -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 mcdmafec_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)
> +	mcdmafec_initialize(bis);
> +#endif
>  
>  	if (!eth_devices) {
>  		puts ("No ethernet found.\n");
>   
Please incorporate my feedback before submitting again.

regards,
Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver
  2008-01-16  2:34 ` Ben Warren
@ 2008-01-16 12:46   ` Wolfgang Denk
  2008-01-16 15:00     ` Ben Warren
  2008-01-16 21:44     ` [U-Boot-Users] ColdFire patches Liew Tsi Chung
  0 siblings, 2 replies; 10+ messages in thread
From: Wolfgang Denk @ 2008-01-16 12:46 UTC (permalink / raw)
  To: u-boot

Dear Ben,
, the alignment is perfect. If it looked bad to you, i. e. if this is
what you saw:


in message <478D6D2A.5090608@gmail.com> you wrote:
>
> > +/* Ethernet Transmit and Receive Buffers */
> > +#define DBUF_LENGTH		1520
> > +#define PKT_MAXBUF_SIZE		1518
> > +#define PKT_MINBUF_SIZE		64
> > +#define PKT_MAXBLR_SIZE		1536
> >   
> Please align better

Please don't get fooled. As you (probably) can see above, the
alignment is perfect. If it looked bad to you, i. e. if this is what
you saw:

> +/* Ethernet Transmit and Receive Buffers */
> +#define DBUF_LENGTH		1520
> +#define PKT_MAXBUF_SIZE		1518
> +#define PKT_MINBUF_SIZE		64
> +#define PKT_MAXBLR_SIZE		1536

...then this was caused by the fact that you did  not  see  the  code
alone,  but  with additional characters added at the beginning of the
line ("> +") - depending on where you are on a line, a TAB may or may
not get shifted then.

You have to *apply* the patch to really comment on formatting.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
CAUTION:  The Mass of This Product Contains the Energy Equivalent  of
85 Million Tons of TNT per Net Ounce of Weight.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver
  2008-01-16 12:46   ` Wolfgang Denk
@ 2008-01-16 15:00     ` Ben Warren
  2008-01-16 21:44     ` [U-Boot-Users] ColdFire patches Liew Tsi Chung
  1 sibling, 0 replies; 10+ messages in thread
From: Ben Warren @ 2008-01-16 15:00 UTC (permalink / raw)
  To: u-boot

Wolfgang Denk wrote:
> Dear Ben,
> , the alignment is perfect. If it looked bad to you, i. e. if this is
> what you saw:
>
>
> in message <478D6D2A.5090608@gmail.com> you wrote:
>   
>>> +/* Ethernet Transmit and Receive Buffers */
>>> +#define DBUF_LENGTH		1520
>>> +#define PKT_MAXBUF_SIZE		1518
>>> +#define PKT_MINBUF_SIZE		64
>>> +#define PKT_MAXBLR_SIZE		1536
>>>   
>>>       
>> Please align better
>>     
>
> Please don't get fooled. As you (probably) can see above, the
> alignment is perfect. If it looked bad to you, i. e. if this is what
> you saw:
>
>   
>> +/* Ethernet Transmit and Receive Buffers */
>> +#define DBUF_LENGTH		1520
>> +#define PKT_MAXBUF_SIZE		1518
>> +#define PKT_MINBUF_SIZE		64
>> +#define PKT_MAXBLR_SIZE		1536
>>     
>
> ...then this was caused by the fact that you did  not  see  the  code
> alone,  but  with additional characters added at the beginning of the
> line ("> +") - depending on where you are on a line, a TAB may or may
> not get shifted then.
>
> You have to *apply* the patch to really comment on formatting.
>
>
>   
Silly tabs.  Sorry for the noise.  I'll try to be less reflexive in the 
future.

regards,
Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 12:46   ` Wolfgang Denk
  2008-01-16 15:00     ` Ben Warren
@ 2008-01-16 21:44     ` Liew Tsi Chung
  2008-01-16 21:50       ` Ben Warren
  2008-02-12  6:13       ` Wolfgang Denk
  1 sibling, 2 replies; 10+ messages in thread
From: Liew Tsi Chung @ 2008-01-16 21:44 UTC (permalink / raw)
  To: u-boot

Wolfgang,

	Are all the ColdFire patches ok to commit?

	Thanks.

Regards,
TsiChung

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 21:44     ` [U-Boot-Users] ColdFire patches Liew Tsi Chung
@ 2008-01-16 21:50       ` Ben Warren
  2008-01-16 22:01         ` Liew Tsi Chung
  2008-02-12  6:13       ` Wolfgang Denk
  1 sibling, 1 reply; 10+ messages in thread
From: Ben Warren @ 2008-01-16 21:50 UTC (permalink / raw)
  To: u-boot

Liew Tsi Chung wrote:
> Wolfgang,
>
> 	Are all the ColdFire patches ok to commit?
>
> 	Thanks.
>
> Regards,
> TsiChung
>
>
>   
Waiting for you to make the functions in the ethernet driver static.

regards,
Ben
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users
>
>   

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 21:50       ` Ben Warren
@ 2008-01-16 22:01         ` Liew Tsi Chung
  2008-01-16 22:16           ` Ben Warren
  0 siblings, 1 reply; 10+ messages in thread
From: Liew Tsi Chung @ 2008-01-16 22:01 UTC (permalink / raw)
  To: u-boot

Ben,

	Are you referring to fecdma_initialize() in
drivers/net/fsl_mcdmafec.c and net/eth.c? If it is, the changes had
applied. You and I agreed on last email that renamed to
mcdmafec_initialize().

http://www.mail-archive.com/u-boot-users at lists.sourceforge.net/msg00310.
html

Regards,
TsiChung

-----Original Message-----
From: Ben Warren [mailto:biggerbadderben at gmail.com] 
Sent: Wednesday, January 16, 2008 3:50 PM
To: Liew Tsi Chung
Cc: wd at denx.de; U-Boot-Users; Rigby John
Subject: Re: [U-Boot-Users] ColdFire patches

Liew Tsi Chung wrote:
> Wolfgang,
>
> 	Are all the ColdFire patches ok to commit?
>
> 	Thanks.
>
> Regards,
> TsiChung
>
>
>   
Waiting for you to make the functions in the ethernet driver static.

regards,
Ben
> ----------------------------------------------------------------------
> --- This SF.net email is sponsored by: Microsoft Defy all challenges. 
> Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users
>
>   

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 22:01         ` Liew Tsi Chung
@ 2008-01-16 22:16           ` Ben Warren
  2008-01-16 23:36             ` Liew Tsi Chung
  0 siblings, 1 reply; 10+ messages in thread
From: Ben Warren @ 2008-01-16 22:16 UTC (permalink / raw)
  To: u-boot

Liew Tsi Chung wrote:
> Ben,
>
> 	Are you referring to fecdma_initialize() in
> drivers/net/fsl_mcdmafec.c and net/eth.c? If it is, the changes had
> applied. You and I agreed on last email that renamed to
> mcdmafec_initialize().
>   
In the new file, drivers/net/fsl_mcdmafec.c, most of the functions, such 
as setFecDuplexSpeed(), fec_send() and so on, are private to the driver 
(i.e. have file scope), and should be declared as static to avoid name 
space confusion.

In addition, the function name setFecDuplexSpeed() goes against the 
coding standard.  It should be set_fec_duplex_speed().

regards,
Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 22:16           ` Ben Warren
@ 2008-01-16 23:36             ` Liew Tsi Chung
  0 siblings, 0 replies; 10+ messages in thread
From: Liew Tsi Chung @ 2008-01-16 23:36 UTC (permalink / raw)
  To: u-boot

Resend. Ignore the first patch. 

-----Original Message-----
From: Ben Warren [mailto:biggerbadderben at gmail.com] 
Sent: Wednesday, January 16, 2008 4:17 PM
To: Liew Tsi Chung
Cc: wd at denx.de; U-Boot-Users; Rigby John
Subject: Re: [U-Boot-Users] ColdFire patches

Liew Tsi Chung wrote:
> Ben,
>
> 	Are you referring to fecdma_initialize() in 
> drivers/net/fsl_mcdmafec.c and net/eth.c? If it is, the changes had 
> applied. You and I agreed on last email that renamed to 
> mcdmafec_initialize().
>   
In the new file, drivers/net/fsl_mcdmafec.c, most of the functions, such as setFecDuplexSpeed(), fec_send() and so on, are private to the driver (i.e. have file scope), and should be declared as static to avoid name space confusion.

In addition, the function name setFecDuplexSpeed() goes against the coding standard.  It should be set_fec_duplex_speed().

regards,
Ben

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [U-Boot-Users] ColdFire patches
  2008-01-16 21:44     ` [U-Boot-Users] ColdFire patches Liew Tsi Chung
  2008-01-16 21:50       ` Ben Warren
@ 2008-02-12  6:13       ` Wolfgang Denk
  1 sibling, 0 replies; 10+ messages in thread
From: Wolfgang Denk @ 2008-02-12  6:13 UTC (permalink / raw)
  To: u-boot

In message <4791E710007FEB4BBF83775D787F462F05E8932B@az33exm22.fsl.freescale.net> you wrote:
> 
> 	Are all the ColdFire patches ok to commit?

I haven't seen any complaints / change  requests  lately  (and  don't
have  time for a thorough review myself at the moment), so please ask
John Rigby to check into the ColdFire custodian repo and send a  pull
request.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Small is beautiful.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-02-12  6:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-16  0:23 [U-Boot-Users] resend#2 [PATCH 6/8] ColdFire: Add MCF547x_8x FEC driver Tsi-Chung Liew
2008-01-16  2:34 ` Ben Warren
2008-01-16 12:46   ` Wolfgang Denk
2008-01-16 15:00     ` Ben Warren
2008-01-16 21:44     ` [U-Boot-Users] ColdFire patches Liew Tsi Chung
2008-01-16 21:50       ` Ben Warren
2008-01-16 22:01         ` Liew Tsi Chung
2008-01-16 22:16           ` Ben Warren
2008-01-16 23:36             ` Liew Tsi Chung
2008-02-12  6:13       ` Wolfgang Denk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox