[U-Boot] ARM: net.c: UDP Checksum code failing every packet
Tom Evans
tom at ceos.com.au
Tue Aug 19 03:25:45 CEST 2008
UDP Checksumming is enabled with the configuration variable
CONFIG_UDP_CHECKSUM. This is only enabled in 7 out of 437
include/configs/*.h files. Enabling UDP checksumming can be useful, as
it allows any errors (in downloading via TFTP) to be retried rather than
resulting in an image CRC error when the whole download has finished.
The download isn't meant to fail, but I'm seeing intermittent corrupted
downloads currently.
If CONFIG_UDP_CHECKSUM is enabled on an ARM core, and the CPU is prior
to ARM Core Version 6, all packets are reported as having checksum errors.
This is due to the ARM's 32-bit alignment requirements and the following
four lines of code in net/net.c::NetReceive()
xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;
xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff;
xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;
xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff;
The original Ethernet packet is (usually, this is not controlled) 32-bit
aligned, the Ethernet header is 14 bytes long, so by design the aligned
fields in the IP (and other) headers are all misaligned, at least with
the NE2000 driver we're using.
ARM (prior to V6) "silently corrupts" misaligned reads. For 32-bit reads
offset by 16 bits it reads 32-bits from the aligned address two bytes
below that requested, and then swaps the words.
If the above lines are changed to match other related ARM-related
modifications as follows, then the UDP checksum code works:
tmp = NetReadIP(&ip->ip_src);
xsum += (ntohl(tmp) >> 16) & 0x0000ffff;
xsum += (ntohl(tmp) >> 0) & 0x0000ffff;
tmp = NetReadIP(&ip->ip_dst);
xsum += (ntohl(tmp) >> 16) & 0x0000ffff;
xsum += (ntohl(tmp) >> 0) & 0x0000ffff;
I'm afraid I can't generate a patch to do this. Could someone else
please incorporate this change if required?
----
Tom Evans
More information about the U-Boot
mailing list