
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