xref: /linux/arch/nios2/include/asm/checksum.h (revision 6e41c585)
1eea9507aSLey Foon Tan /*
2eea9507aSLey Foon Tan  * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
3eea9507aSLey Foon Tan  * Copyright (C) 2004 Microtronix Datacom Ltd.
4eea9507aSLey Foon Tan  *
5eea9507aSLey Foon Tan  * This file is subject to the terms and conditions of the GNU General Public
6eea9507aSLey Foon Tan  * License. See the file "COPYING" in the main directory of this archive
7eea9507aSLey Foon Tan  * for more details.
8eea9507aSLey Foon Tan  */
9eea9507aSLey Foon Tan 
10eea9507aSLey Foon Tan #ifndef _ASM_NIOS_CHECKSUM_H
11eea9507aSLey Foon Tan #define _ASM_NIOS_CHECKSUM_H
12eea9507aSLey Foon Tan 
13eea9507aSLey Foon Tan /* Take these from lib/checksum.c */
14eea9507aSLey Foon Tan extern __wsum csum_partial(const void *buff, int len, __wsum sum);
15eea9507aSLey Foon Tan extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
16eea9507aSLey Foon Tan extern __sum16 ip_compute_csum(const void *buff, int len);
17eea9507aSLey Foon Tan 
18eea9507aSLey Foon Tan /*
19eea9507aSLey Foon Tan  * Fold a partial checksum
20eea9507aSLey Foon Tan  */
csum_fold(__wsum sum)21eea9507aSLey Foon Tan static inline __sum16 csum_fold(__wsum sum)
22eea9507aSLey Foon Tan {
23eea9507aSLey Foon Tan 	__asm__ __volatile__(
24eea9507aSLey Foon Tan 		"add	%0, %1, %0\n"
25eea9507aSLey Foon Tan 		"cmpltu	r8, %0, %1\n"
26eea9507aSLey Foon Tan 		"srli	%0, %0, 16\n"
27eea9507aSLey Foon Tan 		"add	%0, %0, r8\n"
28eea9507aSLey Foon Tan 		"nor	%0, %0, %0\n"
29eea9507aSLey Foon Tan 		: "=r" (sum)
30eea9507aSLey Foon Tan 		: "r" (sum << 16), "0" (sum)
31eea9507aSLey Foon Tan 		: "r8");
32eea9507aSLey Foon Tan 	return (__force __sum16) sum;
33eea9507aSLey Foon Tan }
34eea9507aSLey Foon Tan 
35eea9507aSLey Foon Tan /*
36eea9507aSLey Foon Tan  * computes the checksum of the TCP/UDP pseudo-header
37eea9507aSLey Foon Tan  * returns a 16-bit checksum, already complemented
38eea9507aSLey Foon Tan  */
39eea9507aSLey Foon Tan #define csum_tcpudp_nofold csum_tcpudp_nofold
csum_tcpudp_nofold(__be32 saddr,__be32 daddr,__u32 len,__u8 proto,__wsum sum)40eea9507aSLey Foon Tan static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
41*01cfbad7SAlexander Duyck 					__u32 len, __u8 proto,
42eea9507aSLey Foon Tan 					__wsum sum)
43eea9507aSLey Foon Tan {
44eea9507aSLey Foon Tan 	__asm__ __volatile__(
45eea9507aSLey Foon Tan 		"add	%0, %1, %0\n"
46eea9507aSLey Foon Tan 		"cmpltu	r8, %0, %1\n"
47eea9507aSLey Foon Tan 		"add	%0, %0, r8\n"	/* add carry */
48eea9507aSLey Foon Tan 		"add	%0, %2, %0\n"
49eea9507aSLey Foon Tan 		"cmpltu	r8, %0, %2\n"
50eea9507aSLey Foon Tan 		"add	%0, %0, r8\n"	/* add carry */
51eea9507aSLey Foon Tan 		"add	%0, %3, %0\n"
52eea9507aSLey Foon Tan 		"cmpltu	r8, %0, %3\n"
53eea9507aSLey Foon Tan 		"add	%0, %0, r8\n"	/* add carry */
54eea9507aSLey Foon Tan 		: "=r" (sum), "=r" (saddr)
55*01cfbad7SAlexander Duyck 		: "r" (daddr), "r" ((len + proto) << 8),
56eea9507aSLey Foon Tan 		  "0" (sum),
57eea9507aSLey Foon Tan 		  "1" (saddr)
58eea9507aSLey Foon Tan 		: "r8");
59eea9507aSLey Foon Tan 
60eea9507aSLey Foon Tan 	return sum;
61eea9507aSLey Foon Tan }
62eea9507aSLey Foon Tan 
csum_tcpudp_magic(__be32 saddr,__be32 daddr,__u32 len,__u8 proto,__wsum sum)63eea9507aSLey Foon Tan static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
64*01cfbad7SAlexander Duyck 					__u32 len, __u8 proto,
65*01cfbad7SAlexander Duyck 					__wsum sum)
66eea9507aSLey Foon Tan {
67eea9507aSLey Foon Tan 	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
68eea9507aSLey Foon Tan }
69eea9507aSLey Foon Tan 
70eea9507aSLey Foon Tan #endif /* _ASM_NIOS_CHECKSUM_H */
71