Skip to contentSkip to conversation

net: Adds Fast Ethernet Controller driver for Armada100

PATCH Superseded Ajay Bhargav 3 participants 8 messages Aug 24, 2011 – Aug 25, 2011

Subsystems (2)

v2 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

This patch adds support for Fast Ethernet Controller driver for Armada100 series.

---
Changes for v2:
- removed random MAC generation
- driver init function changed to register as per new naming convention
- code cleanup (Thanks to Wolfgang, Marek & Mike for tips)

 arch/arm/include/asm/arch-armada100/armada100.h |    1 +
 drivers/net/Makefile                            |    1 +
 drivers/net/armada100_fec.c                     |  761 +++++++++++++++++++++++
 drivers/net/armada100_fec.h                     |  232 +++++++
 include/netdev.h                                |    1 +
 5 files changed, 996 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/armada100_fec.c
 create mode 100644 drivers/net/armada100_fec.h
arch/arm/include/asm/arch-armada100/armada100.h +1 -0
index d5d125a..3d567eb 100644
@@ -59,6 +59,7 @@
 #define ARMD1_MPMU_BASE		0xD4050000
 #define ARMD1_APMU_BASE		0xD4282800
 #define ARMD1_CPU_BASE		0xD4282C00
+#define ARMD1_FEC_BASE		0xC0800000
 
 /*
  * Main Power Management (MPMU) Registers
drivers/net/Makefile +1 -0
index 819b197..34b4322 100644
@@ -28,6 +28,7 @@ LIB	:= $(obj)libnet.o
 COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
 COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
 COBJS-$(CONFIG_ALTERA_TSE) += altera_tse.o
+COBJS-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
 COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
 COBJS-$(CONFIG_BCM570x) += bcm570x.o
drivers/net/armada100_fec.c new file +761 -0

761 lines not on this page · raw message

drivers/net/armada100_fec.h new file +232 -0

232 lines not on this page · raw message

include/netdev.h +1 -0
index 6f0a971..d12f179 100644
@@ -94,6 +94,7 @@ int xilinx_emaclite_initialize (bd_t *bis, int base_addr);
 int sh_eth_initialize(bd_t *bis);
 int dm9000_initialize(bd_t *bis);
 int fecmxc_initialize(bd_t *bis);
+int armada100_fec_register(void);
 
 /* Boards with PCI network controllers can call this from their board_eth_init()
  * function to initialize whatever's on board.
Signature · 1 line
1.7.0.4
#1 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

drivers/net/armada100_fec.c line 697

Quoted 2 lines · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:
drivers/net/armada100_fec.c new file +2 -0
+       darmdfec->p_rxdesc = (struct rx_desc *) memalign(PKTALIGN,
+                       ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);

memalign() returns a void*, so you shouldnt need to cast its return value (you do this a couple of times)

drivers/net/armada100_fec.c line 724

Quoted 2 lines
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of this for you when you set write_hwaddr

also, it seems like some of my previous feedback wasnt addressed ?

drivers/net/armada100_fec.c line 610

Quoted 3 lines
drivers/net/armada100_fec.c new file +2 -0
+     while (cmd_sts & BUF_OWNED_BY_DMA) {
...
+     };

no semi-colon needed

drivers/net/armada100_fec.c line 718

Quoted 4 lines
drivers/net/armada100_fec.c new file +3 -0
+int armada100_fec_initialize()
+{
...
+     darmdfec->regs = (void *) ARMD1_FEC_BASE;

make the reg base a parameter to armada100_fec_initialize()

Quoted 5 lines
drivers/net/armada100_fec.c new file +5 -0
+#if defined(CONFIG_PHY_BASE_ADR)
+     miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ,
+                  (u16) CONFIG_PHY_BASE_ADR);
+#else
+     /* Search phy address from range 0-31 */

drivers/net/armada100_fec.c line 749

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+     phy_adr = ethernet_phy_detect(dev);
+     if (phy_adr < 0) {
+             printf("Error: PHY not detected at address range 0-31\n");
+             return -1;
+     } else {
+             debug("PHY detected at addr %d\n", phy_adr);
+             miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ,
+                          (u16) phy_adr);
+     }
+#endif

this should be done in the armdfec_init() func, not the initialize func -mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110824/ad840bed/attachment.pgp

#2 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

Quoted 7 lines · Mike Frysinger

drivers/net/armada100_fec.c line 697

Quoted 2 lines · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:
drivers/net/armada100_fec.c new file +2 -0
+       darmdfec->p_rxdesc = (struct rx_desc *) memalign(PKTALIGN,
+                       ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);

memalign() returns a void*, so you shouldnt need to cast its return value (you do this a couple of times)

Quoted 7 lines

drivers/net/armada100_fec.c line 724

Quoted 2 lines
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of this for you when you set write_hwaddr

also, it seems like some of my previous feedback wasnt addressed ?

I have exactly the same feeling :-(

Ajay, please go through the feedback, if you don't understand something, just ask instead of hoping we won't notice ... we will, we see everything ;-)

Cheers

#3 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

Quoted 20 lines · ----- "Marek Vasut
Quoted 2 lines · Mike Frysinger
Quoted 1 line · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:

+ darmdfec->p_rxdesc = (struct rx_desc *)

memalign(PKTALIGN,

Quoted 1 line
Quoted 1 line

+ ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ +

1);

Quoted 2 lines

memalign() returns a void*, so you shouldnt need to cast its return

value

Quoted 6 lines

(you do this a couple of times)

drivers/net/armada100_fec.c line 724

Quoted 2 lines
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of

this for

Quoted 3 lines

you when you set write_hwaddr

also, it seems like some of my previous feedback wasnt addressed ?

Quoted 9 lines

I have exactly the same feeling :-(

Ajay, please go through the feedback, if you don't understand something, just
ask instead of hoping we won't notice ... we will, we see everything ;-)

Cheers

I did go through your feedbacks.. My apologies if I missed. Marek, Its good for me that you guys are monitoring :) it will surely help me to write a better code :)

Thanks,
Ajay Bhargav

#4 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

Quoted 35 lines · Ajay Bhargav
Quoted 34 lines · ----- "Marek Vasut
Quoted 2 lines · Mike Frysinger
Quoted 1 line · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:

+ darmdfec->p_rxdesc = (struct rx_desc *)

memalign(PKTALIGN,

Quoted 1 line
Quoted 1 line

+ ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ +

1);

Quoted 1 line

memalign() returns a void*, so you shouldnt need to cast its return

value

Quoted 6 lines

(you do this a couple of times)

drivers/net/armada100_fec.c line 724

Quoted 2 lines
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of

this for

Quoted 3 lines

you when you set write_hwaddr

also, it seems like some of my previous feedback wasnt addressed ?

I have exactly the same feeling :-(

Ajay, please go through the feedback, if you don't understand something, just
ask instead of hoping we won't notice ... we will, we see everything ;-)

Quoted 5 lines
Quoted 1 line

Cheers

I did go through your feedbacks.. My apologies if I missed. Marek, Its good for me that you guys are monitoring :) it will surely help me to write a better code :)

It's good thing you don't whine and run away ... some people do. Btw. your code is quite good, it just need the finishing touch :)

Cheers

Quoted 3 lines

Thanks,
Ajay Bhargav

#5 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

In reply to Mike Frysinger
Quoted 9 lines · ----- "Mike Frysinger

Review

Quoted 2 lines · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:
(quoted diff) +2 -0
+       darmdfec->p_rxdesc = (struct rx_desc *) memalign(PKTALIGN,
+                       ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ +

1);

memalign() returns a void*, so you shouldnt need to cast its return value (you
do this a couple of times)

Quoted 7 lines

drivers/net/armada100_fec.c line 724

Quoted 2 lines
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of this for
you when you set write_hwaddr

I do not have a hardware storage for MAC on my controller. write_hwaddr is not needed for me.

Quoted 2 lines

also, it seems like some of my previous feedback wasnt addressed ?

I might have missed some points. My apologies.

Quoted 4 lines

drivers/net/armada100_fec.c line 610

Quoted 3 lines
drivers/net/armada100_fec.c new file +2 -0
+     while (cmd_sts & BUF_OWNED_BY_DMA) {
...
+     };
Quoted 9 lines

no semi-colon needed

drivers/net/armada100_fec.c line 718

Quoted 4 lines
drivers/net/armada100_fec.c new file +3 -0
+int armada100_fec_initialize()
+{
...
+     darmdfec->regs = (void *) ARMD1_FEC_BASE;

make the reg base a parameter to armada100_fec_initialize()

This driver is for Armada100 series and base address is same for the whole series, so i did not feel passing it as a parameter. Can you please tell me if there is any specific reason for the same?

Quoted 17 lines

drivers/net/armada100_fec.c

Quoted 8 lines
drivers/net/armada100_fec.c new file +8 -0
+#if defined(CONFIG_PHY_BASE_ADR)
+     miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ,
+                  (u16) CONFIG_PHY_BASE_ADR);
+#else
+     /* Search phy address from range 0-31 */
+     phy_adr = ethernet_phy_detect(dev);
+     if (phy_adr < 0) {
+             printf("Error: PHY not detected at address range

0-31\n");

drivers/net/armada100_fec.c line 749

Quoted 7 lines
drivers/net/armada100_fec.c new file +7 -0
+             return -1;
+     } else {
+             debug("PHY detected at addr %d\n", phy_adr);
+             miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ,
+                          (u16) phy_adr);
+     }
+#endif
Quoted 3 lines

this should be done in the armdfec_init() func, not the initialize func
-mike

Okay.. will move it there.

Thanks & Regards,
Ajay Bhargav

#6 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

Quoted 11 lines · On Thursday, August 25, 2011 01:10:30 Ajay Bhargav wrote:
Quoted 7 lines · ----- "Mike Frysinger

drivers/net/armada100_fec.c line 724

Quoted 2 lines · On Wednesday, August 24, 2011 09:07:18 Ajay Bhargav wrote:
drivers/net/armada100_fec.c new file +2 -0
+	/* Read mac from env if available */
+	eth_getenv_enetaddr("ethaddr", dev->enetaddr);

you shouldnt need to do this. the higher layers will take care of this for
you when you set write_hwaddr

I do not have a hardware storage for MAC on my controller. write_hwaddr is not needed for me.

ok, but you should not be touching dev->enetaddr in your registration function. the main net/eth.c:eth_initialize() takes care of this for you.

Quoted 10 lines
Quoted 6 lines

drivers/net/armada100_fec.c line 718

Quoted 4 lines
drivers/net/armada100_fec.c new file +3 -0
+int armada100_fec_initialize()
+{
...
+     darmdfec->regs = (void *) ARMD1_FEC_BASE;

make the reg base a parameter to armada100_fec_initialize()

This driver is for Armada100 series and base address is same for the whole series, so i did not feel passing it as a parameter. Can you please tell me if there is any specific reason for the same?

drivers should be written for the IP they control, not for specific SoCs or boards. and what people often start off with "this SoC only has one MAC so screw multi-instance" quite frequently turns into "this next SoC supports multiple MACs!".

i'm not familiar with the Armada100, or the MAC IP that is in that SoC, but this story repeats itself constantly in the SoC world because people focus on the one specific SoC they have in their hand and not the bigger picture. simply witness the ARM hell that Linux is currently in and is being cleaned up through the Linaro organization.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20110825/1bb6d465/attachment.pgp

#7 lore raw

PATCH v2 1/3 net: Adds Fast Ethernet Controller driver for Armada100

In reply to Ajay Bhargav
Quoted 5 lines · Ajay Bhargav

This patch adds support for Fast Ethernet Controller driver for Armada100 series.

---

[...]

Quoted 62 lines
drivers/net/armada100_fec.c new file +56 -0
new file mode 100644
index 0000000..e36dca6
@@ -0,0 +1,761 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <[email protected]>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Contributor: Mahavir Jain <[email protected]>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <linux/err.h>
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/arch/armada100.h>
+#include "armada100_fec.h"
+
+#define  PHY_ADR_REQ     0xFF	/* Magic number to read/write PHY address */
+
+#ifdef DEBUG
+static int eth_dump_regs(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	unsigned int i = 0;
+
+	printf("\noffset: phy_adr, value: 0x%x\n", readl(&regs->phyadr));
+	printf("offset: smi, value: 0x%x\n", readl(&regs->smi));
+	for (i = 0x400; i <= 0x4e4; i += 4)
+		printf("offset: 0x%x, value: 0x%x\n",
+			i, readl(ARMD1_FEC_BASE + i));
+	return 0;

drivers/net/armada100_fec.c line 66

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+}
+#endif
+
+static int armdfec_phy_timeout(u32 reg, u32 flag, int cond)
+{
+	u32 timeout = PHY_WAIT_ITERATIONS;
+	while (--timeout) {
+		if (cond && (readl(reg) & flag))
+			break;
+		else if (!cond && !(readl(reg) & flag))

You can read the register into some temporary variable so you don't need the readl() at two places.

Quoted 24 lines
drivers/net/armada100_fec.c new file +24 -0
+			break;
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
+	return !timeout;
+}
+
+static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg,
+			u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	u32 val, reg_data;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		reg_data = readl(&regs->phyadr);
+		*value = (u16) (reg_data & 0x1f);
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("Err..(%s) Invalid phy address: 0x%X\n",
+				__func__, phy_addr);

drivers/net/armada100_fec.c line 100

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("Err..(%s) Invalid register offset: 0x%X\n",
+				__func__, phy_reg);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout((u32)&regs->smi, SMI_BUSY, FALSE)) {

Adjust the function so you don't need the cast.

drivers/net/armada100_fec.c line 105

Quoted 5 lines
drivers/net/armada100_fec.c new file +5 -0
+		printf("Error (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel(phy_addr << 16 | phy_reg << 21 | SMI_OP_R, &regs->smi);

Parentheses missing maybe ?

Quoted 59 lines
drivers/net/armada100_fec.c new file +59 -0
+
+	/* now wait for the data to be valid */
+	if (armdfec_phy_timeout((u32)&regs->smi, SMI_R_VALID, TRUE)) {
+		val = readl(&regs->smi);
+		printf("Err (%s) PHY Read timeout, val=0x%x\n", __func__, val);
+		return -1;
+	}
+	val = readl(&regs->smi);
+	*value = val & 0xffff;
+
+	return 0;
+}
+
+static int smi_reg_write(const char *devname,
+	 u8 phy_addr, u8 phy_reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		clrsetbits_le32(&regs->phyadr, 0x1f, value & 0x1f);
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("Err..(%s) Invalid phy address\n", __func__);
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("Err..(%s) Invalid register offset\n", __func__);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout((u32)&regs->smi, SMI_BUSY, FALSE)) {
+		printf("Error (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel(phy_addr << 16 | phy_reg << 21 | SMI_OP_W | (value & 0xffff),
+			&regs->smi);
+	return 0;
+}
+
+/*
+ * Abort any transmit and receive operations and put DMA
+ * in idle state. AT and AR bits are cleared upon entering
+ * in IDLE state. So poll those bits to verify operation.
+ */
+static void abortdma(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	int delay;
+	int maxretries = 40;
+
+	do {

drivers/net/armada100_fec.c line 174

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+		writel(SDMA_CMD_AR | SDMA_CMD_AT, &regs->sdma_cmd);
+		udelay(100);
+
+		delay = 10;
+		while ((readl(&regs->sdma_cmd) &
+			(SDMA_CMD_AR | SDMA_CMD_AT))
+			&& delay-- > 0) {
+			udelay(10);
+		}
+	} while (maxretries-- > 0 && delay <= 0);

Didn't I comment on this one in V1?

Quoted 4 lines
drivers/net/armada100_fec.c new file +4 -0
+
+	if (maxretries <= 0)
+		printf("%s : DMA Stuck\n", __func__);
+}

[...]

Quoted 14 lines
drivers/net/armada100_fec.c new file +14 -0
+int armada100_fec_register()
+{
+	struct armdfec_device *darmdfec;
+	struct eth_device *dev;
+	int phy_adr;
+
+	darmdfec = malloc(sizeof(struct armdfec_device));
+	if (!darmdfec)
+		goto error;
+
+	memset(darmdfec, 0, sizeof(struct armdfec_device));
+
+	darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE);
+	if (!darmdfec->htpr)

drivers/net/armada100_fec.c line 703

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+		goto error;
+
+	darmdfec->p_rxdesc = (struct rx_desc *) memalign(PKTALIGN,
+			ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
+
+	if (!darmdfec->p_rxdesc)
+		goto error;
+
+	darmdfec->p_rxbuf = (u8 *) memalign(PKTALIGN,
+			RINGSZ * PKTSIZE_ALIGN + 1);

Is the cast needed ? You should review your casts, most of them can be solved by using proper type!

Quoted 5 lines
drivers/net/armada100_fec.c new file +5 -0
+	if (!darmdfec->p_rxbuf)
+		goto error;
+
+	darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+	if (!darmdfec->p_aligned_txbuf)

drivers/net/armada100_fec.c line 718

Quoted 10 lines
drivers/net/armada100_fec.c new file +10 -0
+		goto error;
+
+	darmdfec->p_txdesc = (struct tx_desc *)
+		memalign(PKTALIGN, sizeof(struct tx_desc) + 1);
+	if (!darmdfec->p_txdesc)
+		goto error;
+
+	dev = &darmdfec->dev;
+	/* Assign ARMADA100 Fast Ethernet Controller Base Address */
+	darmdfec->regs = (void *) ARMD1_FEC_BASE;

Cheers!