diff options
Diffstat (limited to 'arch/x86/um/asm/checksum_32.h')
-rw-r--r-- | arch/x86/um/asm/checksum_32.h | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h index caab74252e27..ab77b6f9a4bf 100644 --- a/arch/x86/um/asm/checksum_32.h +++ b/arch/x86/um/asm/checksum_32.h | |||
@@ -5,145 +5,6 @@ | |||
5 | #ifndef __UM_SYSDEP_CHECKSUM_H | 5 | #ifndef __UM_SYSDEP_CHECKSUM_H |
6 | #define __UM_SYSDEP_CHECKSUM_H | 6 | #define __UM_SYSDEP_CHECKSUM_H |
7 | 7 | ||
8 | #include "linux/in6.h" | ||
9 | #include "linux/string.h" | ||
10 | |||
11 | /* | ||
12 | * computes the checksum of a memory block at buff, length len, | ||
13 | * and adds in "sum" (32-bit) | ||
14 | * | ||
15 | * returns a 32-bit number suitable for feeding into itself | ||
16 | * or csum_tcpudp_magic | ||
17 | * | ||
18 | * this function must be called with even lengths, except | ||
19 | * for the last fragment, which may be odd | ||
20 | * | ||
21 | * it's best to have buff aligned on a 32-bit boundary | ||
22 | */ | ||
23 | __wsum csum_partial(const void *buff, int len, __wsum sum); | ||
24 | |||
25 | /* | ||
26 | * Note: when you get a NULL pointer exception here this means someone | ||
27 | * passed in an incorrect kernel address to one of these functions. | ||
28 | * | ||
29 | * If you use these functions directly please don't forget the | ||
30 | * access_ok(). | ||
31 | */ | ||
32 | |||
33 | static __inline__ | ||
34 | __wsum csum_partial_copy_nocheck(const void *src, void *dst, | ||
35 | int len, __wsum sum) | ||
36 | { | ||
37 | memcpy(dst, src, len); | ||
38 | return csum_partial(dst, len, sum); | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * the same as csum_partial, but copies from src while it | ||
43 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
44 | * | ||
45 | * here even more important to align src and dst on a 32-bit (or even | ||
46 | * better 64-bit) boundary | ||
47 | */ | ||
48 | |||
49 | static __inline__ | ||
50 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, | ||
51 | int len, __wsum sum, int *err_ptr) | ||
52 | { | ||
53 | if (copy_from_user(dst, src, len)) { | ||
54 | *err_ptr = -EFAULT; | ||
55 | return (__force __wsum)-1; | ||
56 | } | ||
57 | |||
58 | return csum_partial(dst, len, sum); | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
63 | * which always checksum on 4 octet boundaries. | ||
64 | * | ||
65 | * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by | ||
66 | * Arnt Gulbrandsen. | ||
67 | */ | ||
68 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
69 | { | ||
70 | unsigned int sum; | ||
71 | |||
72 | __asm__ __volatile__( | ||
73 | "movl (%1), %0 ;\n" | ||
74 | "subl $4, %2 ;\n" | ||
75 | "jbe 2f ;\n" | ||
76 | "addl 4(%1), %0 ;\n" | ||
77 | "adcl 8(%1), %0 ;\n" | ||
78 | "adcl 12(%1), %0 ;\n" | ||
79 | "1: adcl 16(%1), %0 ;\n" | ||
80 | "lea 4(%1), %1 ;\n" | ||
81 | "decl %2 ;\n" | ||
82 | "jne 1b ;\n" | ||
83 | "adcl $0, %0 ;\n" | ||
84 | "movl %0, %2 ;\n" | ||
85 | "shrl $16, %0 ;\n" | ||
86 | "addw %w2, %w0 ;\n" | ||
87 | "adcl $0, %0 ;\n" | ||
88 | "notl %0 ;\n" | ||
89 | "2: ;\n" | ||
90 | /* Since the input registers which are loaded with iph and ipl | ||
91 | are modified, we must also specify them as outputs, or gcc | ||
92 | will assume they contain their original values. */ | ||
93 | : "=r" (sum), "=r" (iph), "=r" (ihl) | ||
94 | : "1" (iph), "2" (ihl) | ||
95 | : "memory"); | ||
96 | return (__force __sum16)sum; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Fold a partial checksum | ||
101 | */ | ||
102 | |||
103 | static inline __sum16 csum_fold(__wsum sum) | ||
104 | { | ||
105 | __asm__( | ||
106 | "addl %1, %0 ;\n" | ||
107 | "adcl $0xffff, %0 ;\n" | ||
108 | : "=r" (sum) | ||
109 | : "r" ((__force u32)sum << 16), | ||
110 | "0" ((__force u32)sum & 0xffff0000) | ||
111 | ); | ||
112 | return (__force __sum16)(~(__force u32)sum >> 16); | ||
113 | } | ||
114 | |||
115 | static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, | ||
116 | unsigned short len, | ||
117 | unsigned short proto, | ||
118 | __wsum sum) | ||
119 | { | ||
120 | __asm__( | ||
121 | "addl %1, %0 ;\n" | ||
122 | "adcl %2, %0 ;\n" | ||
123 | "adcl %3, %0 ;\n" | ||
124 | "adcl $0, %0 ;\n" | ||
125 | : "=r" (sum) | ||
126 | : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); | ||
127 | return sum; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * computes the checksum of the TCP/UDP pseudo-header | ||
132 | * returns a 16-bit checksum, already complemented | ||
133 | */ | ||
134 | static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, | ||
135 | unsigned short len, | ||
136 | unsigned short proto, | ||
137 | __wsum sum) | ||
138 | { | ||
139 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
144 | * in icmp.c | ||
145 | */ | ||
146 | |||
147 | static inline __sum16 ip_compute_csum(const void *buff, int len) | 8 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
148 | { | 9 | { |
149 | return csum_fold (csum_partial(buff, len, 0)); | 10 | return csum_fold (csum_partial(buff, len, 0)); |
@@ -198,4 +59,3 @@ static __inline__ __wsum csum_and_copy_to_user(const void *src, | |||
198 | } | 59 | } |
199 | 60 | ||
200 | #endif | 61 | #endif |
201 | |||