diff options
Diffstat (limited to 'include/asm-m68knommu/checksum.h')
-rw-r--r-- | include/asm-m68knommu/checksum.h | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/include/asm-m68knommu/checksum.h b/include/asm-m68knommu/checksum.h new file mode 100644 index 000000000000..92cf102c2534 --- /dev/null +++ b/include/asm-m68knommu/checksum.h | |||
@@ -0,0 +1,133 @@ | |||
1 | #ifndef _M68K_CHECKSUM_H | ||
2 | #define _M68K_CHECKSUM_H | ||
3 | |||
4 | #include <linux/in6.h> | ||
5 | |||
6 | /* | ||
7 | * computes the checksum of a memory block at buff, length len, | ||
8 | * and adds in "sum" (32-bit) | ||
9 | * | ||
10 | * returns a 32-bit number suitable for feeding into itself | ||
11 | * or csum_tcpudp_magic | ||
12 | * | ||
13 | * this function must be called with even lengths, except | ||
14 | * for the last fragment, which may be odd | ||
15 | * | ||
16 | * it's best to have buff aligned on a 32-bit boundary | ||
17 | */ | ||
18 | unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum); | ||
19 | |||
20 | /* | ||
21 | * the same as csum_partial, but copies from src while it | ||
22 | * checksums | ||
23 | * | ||
24 | * here even more important to align src and dst on a 32-bit (or even | ||
25 | * better 64-bit) boundary | ||
26 | */ | ||
27 | |||
28 | unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum); | ||
29 | |||
30 | |||
31 | /* | ||
32 | * the same as csum_partial_copy, but copies from user space. | ||
33 | * | ||
34 | * here even more important to align src and dst on a 32-bit (or even | ||
35 | * better 64-bit) boundary | ||
36 | */ | ||
37 | |||
38 | extern unsigned int csum_partial_copy_from_user(const char *src, char *dst, | ||
39 | int len, int sum, int *csum_err); | ||
40 | |||
41 | #define csum_partial_copy_nocheck(src, dst, len, sum) \ | ||
42 | csum_partial_copy((src), (dst), (len), (sum)) | ||
43 | |||
44 | unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl); | ||
45 | |||
46 | /* | ||
47 | * Fold a partial checksum | ||
48 | */ | ||
49 | |||
50 | static inline unsigned int csum_fold(unsigned int sum) | ||
51 | { | ||
52 | #ifdef CONFIG_COLDFIRE | ||
53 | sum = (sum & 0xffff) + (sum >> 16); | ||
54 | sum = (sum & 0xffff) + (sum >> 16); | ||
55 | #else | ||
56 | unsigned int tmp = sum; | ||
57 | __asm__("swap %1\n\t" | ||
58 | "addw %1, %0\n\t" | ||
59 | "clrw %1\n\t" | ||
60 | "addxw %1, %0" | ||
61 | : "=&d" (sum), "=&d" (tmp) | ||
62 | : "0" (sum), "1" (sum)); | ||
63 | #endif | ||
64 | return ~sum; | ||
65 | } | ||
66 | |||
67 | |||
68 | /* | ||
69 | * computes the checksum of the TCP/UDP pseudo-header | ||
70 | * returns a 16-bit checksum, already complemented | ||
71 | */ | ||
72 | |||
73 | static inline unsigned int | ||
74 | csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, | ||
75 | unsigned short proto, unsigned int sum) | ||
76 | { | ||
77 | __asm__ ("addl %1,%0\n\t" | ||
78 | "addxl %4,%0\n\t" | ||
79 | "addxl %5,%0\n\t" | ||
80 | "clrl %1\n\t" | ||
81 | "addxl %1,%0" | ||
82 | : "=&d" (sum), "=&d" (saddr) | ||
83 | : "0" (daddr), "1" (saddr), "d" (len + proto), | ||
84 | "d"(sum)); | ||
85 | return sum; | ||
86 | } | ||
87 | |||
88 | static inline unsigned short int | ||
89 | csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, | ||
90 | unsigned short proto, unsigned int sum) | ||
91 | { | ||
92 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
97 | * in icmp.c | ||
98 | */ | ||
99 | |||
100 | extern unsigned short ip_compute_csum(const unsigned char * buff, int len); | ||
101 | |||
102 | #define _HAVE_ARCH_IPV6_CSUM | ||
103 | static __inline__ unsigned short int | ||
104 | csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, | ||
105 | __u32 len, unsigned short proto, unsigned int sum) | ||
106 | { | ||
107 | register unsigned long tmp; | ||
108 | __asm__("addl %2@,%0\n\t" | ||
109 | "movel %2@(4),%1\n\t" | ||
110 | "addxl %1,%0\n\t" | ||
111 | "movel %2@(8),%1\n\t" | ||
112 | "addxl %1,%0\n\t" | ||
113 | "movel %2@(12),%1\n\t" | ||
114 | "addxl %1,%0\n\t" | ||
115 | "movel %3@,%1\n\t" | ||
116 | "addxl %1,%0\n\t" | ||
117 | "movel %3@(4),%1\n\t" | ||
118 | "addxl %1,%0\n\t" | ||
119 | "movel %3@(8),%1\n\t" | ||
120 | "addxl %1,%0\n\t" | ||
121 | "movel %3@(12),%1\n\t" | ||
122 | "addxl %1,%0\n\t" | ||
123 | "addxl %4,%0\n\t" | ||
124 | "clrl %1\n\t" | ||
125 | "addxl %1,%0" | ||
126 | : "=&d" (sum), "=&d" (tmp) | ||
127 | : "a" (saddr), "a" (daddr), "d" (len + proto), | ||
128 | "0" (sum)); | ||
129 | |||
130 | return csum_fold(sum); | ||
131 | } | ||
132 | |||
133 | #endif /* _M68K_CHECKSUM_H */ | ||