aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/checksum.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/checksum.c b/lib/checksum.c
index 129775eb6de6..fcf38943132c 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -47,6 +47,15 @@ static inline unsigned short from32to16(unsigned int x)
47 return x; 47 return x;
48} 48}
49 49
50static inline u32 from64to32(u64 x)
51{
52 /* add up 32-bit and 32-bit for 32+c bit */
53 x = (x & 0xffffffff) + (x >> 32);
54 /* add up carry.. */
55 x = (x & 0xffffffff) + (x >> 32);
56 return (u32)x;
57}
58
50static unsigned int do_csum(const unsigned char *buff, int len) 59static unsigned int do_csum(const unsigned char *buff, int len)
51{ 60{
52 int odd; 61 int odd;
@@ -195,8 +204,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
195#else 204#else
196 s += (proto + len) << 8; 205 s += (proto + len) << 8;
197#endif 206#endif
198 s += (s >> 32); 207 return (__force __wsum)from64to32(s);
199 return (__force __wsum)s;
200} 208}
201EXPORT_SYMBOL(csum_tcpudp_nofold); 209EXPORT_SYMBOL(csum_tcpudp_nofold);
202#endif 210#endif