[U-Boot] [PATCH 1/1] net: Add Xilinx LL Temac driver version2

Michal Simek monstr at monstr.eu
Tue Feb 24 16:11:38 CET 2009


Hi Ben,
> Hi Michal,
> 
> Michal Simek wrote:
> 
> <snip>
>>> All of the above mentioned issues are ones that I could easily deal
>>> with, but one thing that really does need to change is that you need to
>>> use the CONFIG_NET_MULTI API.  In other words, your driver should have a
>>> single initialize() function (prototyped in include/netdev.h), and an
>>> eth_device struct that gets registered.  All your access functions
>>> (eth_init, eth_send, eth_recv etc.) will be static and pointed to by the
>>> eth_device struct.  Most drivers are already this way.
>>>     
>>
>> I look at it and I did some change and the main problem is in
>> Microblaze GCC.
>> We use GCC 3.4.1 and CONFIG_NET_MULTI use weak function and
>> board_eth_init is
>> never called. We are working on GCC 4.1.2 but I don't know when I get it.
>>
>>   
> According to the documentation I could find, weak symbols were present
> in gcc 3.4.1.  Are you sure you're using them properly?  Due to the way
> linking is performed in U-boot, any weak symbol overrides need to be in
> source files that have strongly linked symbols.  You'll see that all
> implementations of cpu_eth_init() and board_eth_init() are in files that
> already contain stuff that is sure to be linked.


hmm. I did some tests and I found that the my problem is with this line 40. (I
use board_eth_init initialization)
int board_eth_init(bd_t *bis) __attribute((weak, alias("__def_eth_init")));
I am not gcc specialist but I smell problem with GCC.

First log is when this line is there. -> here is board_eth_init called

SDRAM :
                Icache:OK
                Dcache:OK
        U-Boot Start:0x91800000
FLASH: 32 MB
MAC:00:E0:0C:00:00:FD
before
after
No ethernet found.
*** Warning - bad CRC, using default environment

U-BOOT for hw

U-Boot-mONStR>


Commented that line.


SDRAM :
                Icache:OK
                Dcache:OK
        U-Boot Start:0x91800000
FLASH: 32 MB
MAC:00:E0:0C:00:00:FD
before
board_eth_initafter
Xilinx LL Temac
*** Warning - bad CRC, using default environment

U-BOOT for hw

U-Boot-mONStR> ping 192.168.0.1
Xilinx LL Temac: Xilinx XPS LocalLink Tri-Mode Ether MAC #0 at 0x81C00000.
100BASE-T/FD
Using Xilinx LL Temac device
host 192.168.0.1 is alive
U-Boot-mONStR>


Not working -> dump

918038c8:	b000ffff 	imm	-1
918038cc:	b9f4fdf8 	brlid	r15, -520	// 918036c4 <cpu_eth_init>
918038d0:	10b30000 	addk	r5, r19, r0
918038d4:	bca30010 	bgei	r3, 16		// 918038e4
918038d8:	b000ffff 	imm	-1
918038dc:	b9f4fde8 	brlid	r15, -536	// 918036c4 <cpu_eth_init>

Working dump

918038c8:	b0000001 	imm	1
918038cc:	b9f49268 	brlid	r15, -28056	// 9181cb34 <board_eth_init>
918038d0:	10b30000 	addk	r5, r19, r0
918038d4:	bca30010 	bgei	r3, 16		// 918038e4
918038d8:	b000ffff 	imm	-1
918038dc:	b9f4fde8 	brlid	r15, -536	// 918036c4 <cpu_eth_init>

Using cpu_eth_init nothing solve -> gcc has problem with attributes - weak or
alias?

>> I have two more Xilinx eth drivers in U-BOOT and I think that will be
>> the best
>> to do all changes together. What do you think?
>>
>> Thanks,
>> Michal
>>
>>   
> If you're really unable to make this change due to your tools, I'm not
> opposed to pulling this driver in.  I just want to know that you intend
> to port all the Xilinx drivers over some time in the near future.

Yes. I will do it. Below are my changes for ll_temac driver. Do you see any
problem in it?

Thanks,
Michal

> regards,
> Ben


diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c
b/board/xilinx/microblaze-generic/microblaze-generic.c
index f388b77..878a2a3 100644
--- a/board/xilinx/microblaze-generic/microblaze-generic.c
+++ b/board/xilinx/microblaze-generic/microblaze-generic.c
@@ -27,6 +27,7 @@

 #include <common.h>
 #include <config.h>
+#include <netdev.h>
 #include <asm/microblaze_intc.h>
 #include <asm/asm.h>

@@ -67,3 +68,11 @@ void fsl_init2 (void) {
  NULL);
 }
 #endif
+
+int board_eth_init(bd_t *bis)
+{
+	puts (__func__);
+#ifdef CONFIG_XILINX_LL_TEMAC
+	return lltemac_eth_initialize(bis);
+#endif
+}
diff --git a/drivers/net/xilinx_ll_temac.c b/drivers/net/xilinx_ll_temac.c
index 4f897d2..d6d767a 100644
--- a/drivers/net/xilinx_ll_temac.c
+++ b/drivers/net/xilinx_ll_temac.c
@@ -21,6 +21,7 @@
 #include <common.h>
 #include <net.h>
 #include <malloc.h>
+#include <netdev.h>
 #include <asm/processor.h>
 #include <asm/io.h>

@@ -394,16 +395,16 @@ static int xps_ll_temac_recv_fifo()

 	if (ll_fifo->isr & 0x04000000 ) {
 		ll_fifo->isr = 0xffffffff; /* reset isr */
-	
+
 		/* while (ll_fifo->isr); */
 		len = ll_fifo->rlf & 0x7FF;
 		len2 = (len / 4) + 1;
-	
+
 		for (i = 0; i < len2; i++) {
 			val = ll_fifo->rdfd;
 			*buf++ = val ;
 		}
-	
+
 		/* debugll(1); */
 		NetReceive (&rx_buffer, len);
 	}
@@ -479,35 +480,19 @@ static int xps_ll_temac_halt(void)
 #endif

 /* halt device */
-void eth_halt(void){
+static void lltemac_eth_halt(struct eth_device *dev)
+{
 	link = 0;
 #ifdef ETH_HALTING
 	xps_ll_temac_halt();
 #endif
 }

-int eth_init(bd_t *bis)
+static int lltemac_eth_init(struct eth_device *dev, bd_t * bis)
 {
-	static int first = 1;
-	struct eth_device *dev;
-	struct xps_ll_temac_private *lp;
 #ifdef DEBUG
 	int i;
 #endif
-
-	if(!first)
-		return 0;
-	first = 0;
-	dev = (struct eth_device *) calloc(1, sizeof(struct eth_device));
-	if (NULL == dev)
-		return 0;
-
-	lp = (struct xps_ll_temac_private *) calloc(1, sizeof(struct
xps_ll_temac_private));
-	if (lp == NULL)
-		return 0;
-	dev->priv = lp;
-	sprintf(dev->name, "eth0");
-
 	xps_ll_temac_init(dev, bis);

 	printf("%s: Xilinx XPS LocalLink Tri-Mode Ether MAC #%d at 0x%08X.\n",
@@ -522,7 +507,9 @@ int eth_init(bd_t *bis)
 	return 1;
 }

-int eth_send(volatile void *packet, int length)
+
+static int lltemac_eth_send(struct eth_device *dev, volatile void *packet,
+						int length)
 {
 #ifdef SDMA_MODE
 	return xps_ll_temac_send_sdma((unsigned char *)packet, length);
@@ -532,7 +519,7 @@ int eth_send(volatile void *packet, int length)
 #endif
 }

-int eth_rx(void)
+static int lltemac_eth_recv(struct eth_device *dev)
 {
 #ifdef SDMA_MODE
 	return xps_ll_temac_recv_sdma();
@@ -541,3 +528,31 @@ int eth_rx(void)
 	return xps_ll_temac_recv_fifo();
 #endif
 }
+
+int lltemac_eth_initialize(bd_t * bis)
+{
+	struct eth_device *dev;
+	struct xps_ll_temac_private *lp;
+
+	dev = (struct eth_device *) calloc(1, sizeof(struct eth_device));
+	if (NULL == dev)
+	{
+		puts("Failed to allocate memory\n");
+		return -1;
+	}
+	memset(dev, 0, sizeof(*dev));
+
+	sprintf(dev->name, "Xilinx LL Temac");
+	dev->init = lltemac_eth_init;
+	dev->halt = lltemac_eth_halt;
+	dev->send = lltemac_eth_send;
+	dev->recv = lltemac_eth_recv;
+
+	lp = (struct xps_ll_temac_private *) calloc(1, sizeof(struct
xps_ll_temac_private));
+	if (lp == NULL)
+		return 0;
+	dev->priv = lp;
+
+	eth_register(dev);
+	return 0;
+}
diff --git a/include/configs/microblaze-generic.h
b/include/configs/microblaze-generic.h
index 7110f91..2035923 100644
--- a/include/configs/microblaze-generic.h
+++ b/include/configs/microblaze-generic.h
@@ -67,6 +67,7 @@
 #elif XILINX_LLTEMAC_BASEADDR
 	#define CONFIG_XILINX_LL_TEMAC	1
 	#define CONFIG_SYS_ENET
+	#define CONFIG_NET_MULTI
 #endif

 #undef ET_DEBUG

diff --git a/include/netdev.h b/include/netdev.h
index 751f0da..398c589 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -51,6 +51,7 @@ int fec_initialize (bd_t *bis);
 int greth_initialize(bd_t *bis);
 void gt6426x_eth_initialize(bd_t *bis);
 int inca_switch_initialize(bd_t *bis);
+int lltemac_eth_initialize(bd_t * bis);
 int macb_eth_initialize(int id, void *regs, unsigned int phy_addr);
 int mcdmafec_initialize(bd_t *bis);
 int mcffec_initialize(bd_t *bis);
diff --git a/lib_microblaze/board.c b/lib_microblaze/board.c
index 30d7641..1274934 100644
--- a/lib_microblaze/board.c
+++ b/lib_microblaze/board.c
@@ -29,6 +29,7 @@
 #include <malloc.h>
 #include <timestamp.h>
 #include <version.h>
+#include <net.h>
 #include <watchdog.h>

 DECLARE_GLOBAL_DATA_PTR;
@@ -43,7 +44,7 @@ extern int interrupts_init (void);
 #endif
 #if defined(CONFIG_CMD_NET)
 extern int eth_init (bd_t * bis);
-extern int getenv_IPaddr (char *);
+//extern int getenv_IPaddr (char *);
 #endif

 /*
@@ -183,7 +184,9 @@ void board_init (void)
 	}
 	/* IP Address */
 	bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
-	eth_init (bd);
+//	eth_init (bd);
+	eth_initialize (bd);
+
 #endif

 	/* relocate environment function pointers etc. */
diff --git a/net/eth.c b/net/eth.c
index b7ef09f..f5e6bc4 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -37,7 +37,7 @@ static int __def_eth_init(bd_t *bis)
 	return -1;
 }
 int cpu_eth_init(bd_t *bis) __attribute((weak, alias("__def_eth_init")));
-int board_eth_init(bd_t *bis) __attribute((weak, alias("__def_eth_init")));
+//int board_eth_init(bd_t *bis) __attribute((weak, alias("__def_eth_init")));

 extern int mv6436x_eth_initialize(bd_t *);
 extern int mv6446x_eth_initialize(bd_t *);
@@ -143,9 +143,13 @@ int eth_initialize(bd_t *bis)
 #endif
 	/* Try board-specific initialization first.  If it fails or isn't
 	 * present, try the cpu-specific initialization */
+	puts ("before\n");
+
 	if (board_eth_init(bis) < 0)
 		cpu_eth_init(bis);

+	puts("after\n");
+
 #if defined(CONFIG_DB64360) || defined(CONFIG_CPCI750)
 	mv6436x_eth_initialize(bis);
 #endif


-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854


More information about the U-Boot mailing list