[U-Boot] Consistently repeated TFTP timeouts (target directly connected to host PC)
Johnson Thomas
johnsonthomas at nanometrics.ca
Thu Jun 19 17:55:14 CEST 2014
Hi all,
I am facing an issue of repeated TFTP timeouts when downloading the kernel
image in U-Boot with target directly connected to host PC. The download
pattern almost 95% of the time looks like this
TFTP from server 10.11.2.47; our IP address is 10.11.6.94
Filename 'uImage'.
Load address: 0xc0700000
Loading: #################################################T #######T
#########
#################################################################
####T #############################################################
#################################################################
#################################################################
#################################################################
##############T ############T ##################T
#####################
##################
186.5 KiB/s
done
I did verify the solution provided in [1], the PHY has the setting 100Mbps
full duplex mode and the MAC is configured to the same setting by U-Boot in
davinci_emac.c (can be verified from the log snippets shown below,
MACCONTROL: 32801 = 0x8021 = 100Mbps Full Duplex mode).
Although, there are repeated TFTP timeouts, the kernel image is eventually
downloaded and boots up. It can also be noted that there were instances
where no TFTP timeouts were observed when downloading the kernel image.
The custom board that I am using has an OMAPL138 ARM processor. In order to
debug the issue, I applied the following debug patch to U-Boot
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 1db586d..c243e04 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -46,7 +46,7 @@
#include <asm/io.h>
#include "davinci_emac.h"
-unsigned int emac_dbg = 0;
+unsigned int emac_dbg = 1;
#define debug_emac(fmt,args...) if (emac_dbg) printf(fmt,##args)
#ifdef EMAC_HW_RAM_ADDR
@@ -699,12 +699,34 @@ static int davinci_eth_rcv_packet (struct eth_device
*dev)
volatile emac_desc *rx_curr_desc;
volatile emac_desc *curr_desc;
volatile emac_desc *tail_desc;
- int status, ret = -1;
-
+ int status, ret = -1, i;
+
davinci_invalidate_rx_descs();
rx_curr_desc = emac_rx_active_head;
status = rx_curr_desc->pkt_flag_len;
+ unsigned long tmp_status = rx_curr_desc->pkt_flag_len;
+ unsigned long tmp_macstatus, tmp_maccontrol, tmp_macintmaskset;
+ tmp_macstatus = readl(&adap_emac->MACSTATUS);
+ tmp_maccontrol = readl(&adap_emac->MACCONTROL);
+ tmp_macintmaskset = readl(&adap_emac->MACINTMASKSET);
+ printf("Receive Status: %ul\n",tmp_status);
+ printf("MACSTATUS = %ul, MACCONTROL = %ul\n", tmp_macstatus,
tmp_maccontrol);
+ if(rx_curr_desc != NULL) {
+ printf("Rx active head: %p\n",rx_curr_desc);
+ printf("Buffer length: %d\n",rx_curr_desc->buff_off_len &
0xffff);
+ printf("Packet length: %d\n",rx_curr_desc->pkt_flag_len &
0xffff);
+ struct ethernet_hdr *tmp_pkt = (struct ethernet_hdr
*)((uchar *) rx_curr_desc->buffer);
+ printf("Dest Node\n");
+ for(i=0;i<6;i++)
+ printf("%u ",tmp_pkt->et_dest[i]);
+ printf("\n");
+ printf("Src Node\n");
+ for(i=0;i<6;i++)
+ printf("%u ",tmp_pkt->et_src[i]);
+ printf("\n");
+ printf("ProtLen: %d\n",tmp_pkt->et_protlen);
+ }
if ((rx_curr_desc) && ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0)) {
if (status & EMAC_CPPI_RX_ERROR_FRAME) {
/* Error in packet - discard it and requeue desc */
diff --git a/include/net.h b/include/net.h
index 970d4d1..20e68f8 100644
--- a/include/net.h
+++ b/include/net.h
@@ -19,10 +19,10 @@
#include <asm/cache.h>
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
-#define DEBUG_LL_STATE 0 /* Link local state machine changes */
-#define DEBUG_DEV_PKT 0 /* Packets or info directed to the
device */
-#define DEBUG_NET_PKT 0 /* Packets on info on the network
at large */
-#define DEBUG_INT_STATE 0 /* Internal network state changes */
+#define DEBUG_LL_STATE 1 /* Link local state machine changes */
+#define DEBUG_DEV_PKT 1 /* Packets or info directed to the
device */
+#define DEBUG_NET_PKT 1 /* Packets on info on the network
at large */
+#define DEBUG_INT_STATE 1 /* Internal network state changes */
/*
* The number of receive packet buffers, and the required packet buffer
I observed the following log snippet repeated multiple times during each
TFTP timeout, after which the download works fine until the next timeout
Receive Status: 536870912l
MACSTATUS = 2147483648l, MACCONTROL = 32801l
Rx active head: 01e20060
Buffer length: 1518
Packet length: 0
Dest Node
0 17 64 47 0 4
Src Node
8 0 39 91 249 79
ProtLen: 8
Following are some log snippets which may be useful for debugging:
1) Log snippet just before a TFTP timeout:
Receive Status: 536870912l
MACSTATUS = 2147483648l, MACCONTROL = 32801l
Rx active head: 01e20060
Buffer length: 1518
Packet length: 0
Dest Node
0 17 64 47 0 4
Src Node
8 0 39 91 249 79
ProtLen: 8
--- NetLoop timeout
T --- NetLoop timeout handler set (cffa38e8)
sending UDP to 10.11.2.47/08:00:27:5b:f9:4f
2) Log snippet of a good TFTP transfer
Receive Status: 3221226986l
MACSTATUS = 2147483648l, MACCONTROL = 32801l
Rx active head: 01e20000
Buffer length: 1514
Packet length: 1514
Dest Node
0 17 64 47 0 4
Src Node
8 0 39 91 249 79
ProtLen: 8
packet received
Receive from protocol 0x800
Got IP
len=1500, v=45
received UDP (to=10.11.2.94, from=10.11.2.47, len=1500)
--- NetLoop timeout handler set (cffa38e8)
sending UDP to 10.11.2.47/08:00:27:5b:f9:4f
As far as I understand, the OWNERSHIP bit in the descriptor is not being
cleared (evident from the Receive Status: 536870912 = 0x20000000 =
EMAC_CPPI_OWNERSHIP_BIT) by the EMAC for some reason which leads to the
timeout. I am not sure how to debug further and find the root cause of this
issue. Any help would be great!
Thanks,
Johnson
PS: Sorry for the long email, just wanted to provide as much information as
possible :-)
[1] http://www.denx.de/wiki/view/DULG/TFTPTimeout
More information about the U-Boot
mailing list