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