diff options
-rw-r--r-- | include/asm-arm/checksum.h | 83 |
1 files changed, 41 insertions, 42 deletions
diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h index 747bdd31a74b..8c0bb5bb14ee 100644 --- a/include/asm-arm/checksum.h +++ b/include/asm-arm/checksum.h | |||
@@ -23,7 +23,7 @@ | |||
23 | * | 23 | * |
24 | * it's best to have buff aligned on a 32-bit boundary | 24 | * it's best to have buff aligned on a 32-bit boundary |
25 | */ | 25 | */ |
26 | unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); | 26 | __wsum csum_partial(const void *buff, int len, __wsum sum); |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * the same as csum_partial, but copies from src while it | 29 | * the same as csum_partial, but copies from src while it |
@@ -33,26 +33,18 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
33 | * better 64-bit) boundary | 33 | * better 64-bit) boundary |
34 | */ | 34 | */ |
35 | 35 | ||
36 | unsigned int | 36 | __wsum |
37 | csum_partial_copy_nocheck(const char *src, char *dst, int len, int sum); | 37 | csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); |
38 | 38 | ||
39 | unsigned int | 39 | __wsum |
40 | csum_partial_copy_from_user(const char __user *src, char *dst, int len, int sum, int *err_ptr); | 40 | csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); |
41 | |||
42 | /* | ||
43 | * This is the old (and unsafe) way of doing checksums, a warning message will | ||
44 | * be printed if it is used and an exception occurs. | ||
45 | * | ||
46 | * this functions should go away after some time. | ||
47 | */ | ||
48 | #define csum_partial_copy(src,dst,len,sum) csum_partial_copy_nocheck(src,dst,len,sum) | ||
49 | 41 | ||
50 | /* | 42 | /* |
51 | * This is a version of ip_compute_csum() optimized for IP headers, | 43 | * This is a version of ip_compute_csum() optimized for IP headers, |
52 | * which always checksum on 4 octet boundaries. | 44 | * which always checksum on 4 octet boundaries. |
53 | */ | 45 | */ |
54 | static inline unsigned short | 46 | static inline __sum16 |
55 | ip_fast_csum(unsigned char * iph, unsigned int ihl) | 47 | ip_fast_csum(const void *iph, unsigned int ihl) |
56 | { | 48 | { |
57 | unsigned int sum, tmp1; | 49 | unsigned int sum, tmp1; |
58 | 50 | ||
@@ -78,14 +70,13 @@ ip_fast_csum(unsigned char * iph, unsigned int ihl) | |||
78 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) | 70 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) |
79 | : "1" (iph), "2" (ihl) | 71 | : "1" (iph), "2" (ihl) |
80 | : "cc", "memory"); | 72 | : "cc", "memory"); |
81 | return sum; | 73 | return (__force __sum16)sum; |
82 | } | 74 | } |
83 | 75 | ||
84 | /* | 76 | /* |
85 | * Fold a partial checksum without adding pseudo headers | 77 | * Fold a partial checksum without adding pseudo headers |
86 | */ | 78 | */ |
87 | static inline unsigned int | 79 | static inline __sum16 csum_fold(__wsum sum) |
88 | csum_fold(unsigned int sum) | ||
89 | { | 80 | { |
90 | __asm__( | 81 | __asm__( |
91 | "adds %0, %1, %1, lsl #16 @ csum_fold \n\ | 82 | "adds %0, %1, %1, lsl #16 @ csum_fold \n\ |
@@ -93,21 +84,25 @@ csum_fold(unsigned int sum) | |||
93 | : "=r" (sum) | 84 | : "=r" (sum) |
94 | : "r" (sum) | 85 | : "r" (sum) |
95 | : "cc"); | 86 | : "cc"); |
96 | return (~sum) >> 16; | 87 | return (__force __sum16)(~(__force u32)sum >> 16); |
97 | } | 88 | } |
98 | 89 | ||
99 | static inline unsigned int | 90 | static inline __wsum |
100 | csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, | 91 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, |
101 | unsigned int proto, unsigned int sum) | 92 | unsigned short proto, __wsum sum) |
102 | { | 93 | { |
103 | __asm__( | 94 | __asm__( |
104 | "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ | 95 | "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ |
105 | adcs %0, %0, %3 \n\ | 96 | adcs %0, %0, %3 \n" |
106 | adcs %0, %0, %4 \n\ | 97 | #ifdef __ARMEB__ |
107 | adcs %0, %0, %5 \n\ | 98 | "adcs %0, %0, %4 \n" |
99 | #else | ||
100 | "adcs %0, %0, %4, lsl #8 \n" | ||
101 | #endif | ||
102 | "adcs %0, %0, %5 \n\ | ||
108 | adc %0, %0, #0" | 103 | adc %0, %0, #0" |
109 | : "=&r"(sum) | 104 | : "=&r"(sum) |
110 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto)) | 105 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) |
111 | : "cc"); | 106 | : "cc"); |
112 | return sum; | 107 | return sum; |
113 | } | 108 | } |
@@ -115,23 +110,27 @@ csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, | |||
115 | * computes the checksum of the TCP/UDP pseudo-header | 110 | * computes the checksum of the TCP/UDP pseudo-header |
116 | * returns a 16-bit checksum, already complemented | 111 | * returns a 16-bit checksum, already complemented |
117 | */ | 112 | */ |
118 | static inline unsigned short int | 113 | static inline __sum16 |
119 | csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, | 114 | csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, |
120 | unsigned int proto, unsigned int sum) | 115 | unsigned short proto, __wsum sum) |
121 | { | 116 | { |
122 | __asm__( | 117 | __asm__( |
123 | "adds %0, %1, %2 @ csum_tcpudp_magic \n\ | 118 | "adds %0, %1, %2 @ csum_tcpudp_magic \n\ |
124 | adcs %0, %0, %3 \n\ | 119 | adcs %0, %0, %3 \n" |
125 | adcs %0, %0, %4 \n\ | 120 | #ifdef __ARMEB__ |
126 | adcs %0, %0, %5 \n\ | 121 | "adcs %0, %0, %4 \n" |
122 | #else | ||
123 | "adcs %0, %0, %4, lsl #8 \n" | ||
124 | #endif | ||
125 | "adcs %0, %0, %5 \n\ | ||
127 | adc %0, %0, #0 \n\ | 126 | adc %0, %0, #0 \n\ |
128 | adds %0, %0, %0, lsl #16 \n\ | 127 | adds %0, %0, %0, lsl #16 \n\ |
129 | addcs %0, %0, #0x10000 \n\ | 128 | addcs %0, %0, #0x10000 \n\ |
130 | mvn %0, %0" | 129 | mvn %0, %0" |
131 | : "=&r"(sum) | 130 | : "=&r"(sum) |
132 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (ntohs(len)), "Ir" (ntohs(proto)) | 131 | : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) |
133 | : "cc"); | 132 | : "cc"); |
134 | return sum >> 16; | 133 | return (__force __sum16)((__force u32)sum >> 16); |
135 | } | 134 | } |
136 | 135 | ||
137 | 136 | ||
@@ -139,20 +138,20 @@ csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, | |||
139 | * this routine is used for miscellaneous IP-like checksums, mainly | 138 | * this routine is used for miscellaneous IP-like checksums, mainly |
140 | * in icmp.c | 139 | * in icmp.c |
141 | */ | 140 | */ |
142 | static inline unsigned short | 141 | static inline __sum16 |
143 | ip_compute_csum(unsigned char * buff, int len) | 142 | ip_compute_csum(const void *buff, int len) |
144 | { | 143 | { |
145 | return csum_fold(csum_partial(buff, len, 0)); | 144 | return csum_fold(csum_partial(buff, len, 0)); |
146 | } | 145 | } |
147 | 146 | ||
148 | #define _HAVE_ARCH_IPV6_CSUM | 147 | #define _HAVE_ARCH_IPV6_CSUM |
149 | extern unsigned long | 148 | extern __wsum |
150 | __csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len, | 149 | __csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len, |
151 | __u32 proto, unsigned int sum); | 150 | __be32 proto, __wsum sum); |
152 | 151 | ||
153 | static inline unsigned short int | 152 | static inline __sum16 |
154 | csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, __u32 len, | 153 | csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len, |
155 | unsigned short proto, unsigned int sum) | 154 | unsigned short proto, __wsum sum) |
156 | { | 155 | { |
157 | return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len), | 156 | return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len), |
158 | htonl(proto), sum)); | 157 | htonl(proto), sum)); |