Altera_Forum
Honored Contributor
15 years agoTCP/UDP Checksum Error
Hi all,
I met a weird issue about tcp/udp checksum. The TSE works well under uClinux without any FCS error. It can ping remote deivces, but fails to communicate with others due to the tcp/udp checksum error. I found the issue is caused by the assembler code of checksum. if I rewrite the code in C, everything works well. here is my patch. arch/nios/include/asm/checksum.h
static inline __wsum
__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
unsigned short proto, __wsum sum)
{
#if 0
__asm__ __volatile__(
"add %0, %0, %1\n"
"cmpltu r8, %0, %1\n"
"add %0, %0, r8\n" /* add carry */
"add %0, %0, %2\n"
"cmpltu r8, %0, %2\n"
"add %0, %0, r8\n" /* add carry */
"add %0, %0, %3\n"
"cmpltu r8, %0, %3\n"
"add %0, %0, r8\n" /* add carry */
: "=r" (sum)
: "r" (sum), "r" (saddr), "r" (daddr), "r" ((len + proto) << 8)
: "r8");
#else
sum += saddr;
if (sum < saddr)
sum++;
sum += daddr;
if (sum < daddr)
sum++;
sum += ((len + proto) << 8);
if (sum < ((len + proto) << 8))
sum++;# endif
return sum;
}
The assembler code looks correct and it should work ok. but the result is incorrect. for example: first line of assembler code should do adding 'saddr' value into 'sum'. but the actual result is adding 'saddr' memory address into 'sum'. does it mean the toolchain has bug?. uClinux: v2.6.34 toolchain: nios2-linux-gnu-gcc version 4.1.2 all are update-to-date by git from sopc.et.ntust.edu.tw.