1
2#ifndef __UM_CHECKSUM_H
3#define __UM_CHECKSUM_H
4
5#include <linux/string.h>
6#include <linux/in6.h>
7#include <linux/uaccess.h>
8
9
10
11
12
13
14
15
16
17
18
19
20
21extern __wsum csum_partial(const void *buff, int len, __wsum sum);
22
23
24
25
26
27
28
29
30
31static inline __sum16 csum_fold(__wsum sum)
32{
33 __asm__(
34 " addl %1,%0\n"
35 " adcl $0xffff,%0"
36 : "=r" (sum)
37 : "r" ((__force u32)sum << 16),
38 "0" ((__force u32)sum & 0xffff0000)
39 );
40 return (__force __sum16)(~(__force u32)sum >> 16);
41}
42
43
44
45
46
47
48
49
50
51
52
53
54static inline __wsum
55csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
56 __u8 proto, __wsum sum)
57{
58 asm(" addl %1, %0\n"
59 " adcl %2, %0\n"
60 " adcl %3, %0\n"
61 " adcl $0, %0\n"
62 : "=r" (sum)
63 : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
64 return sum;
65}
66
67
68
69
70
71static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
72 __u32 len, __u8 proto,
73 __wsum sum)
74{
75 return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
76}
77
78
79
80
81
82
83static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
84{
85 unsigned int sum;
86
87 asm( " movl (%1), %0\n"
88 " subl $4, %2\n"
89 " jbe 2f\n"
90 " addl 4(%1), %0\n"
91 " adcl 8(%1), %0\n"
92 " adcl 12(%1), %0\n"
93 "1: adcl 16(%1), %0\n"
94 " lea 4(%1), %1\n"
95 " decl %2\n"
96 " jne 1b\n"
97 " adcl $0, %0\n"
98 " movl %0, %2\n"
99 " shrl $16, %0\n"
100 " addw %w2, %w0\n"
101 " adcl $0, %0\n"
102 " notl %0\n"
103 "2:"
104
105
106
107 : "=r" (sum), "=r" (iph), "=r" (ihl)
108 : "1" (iph), "2" (ihl)
109 : "memory");
110 return (__force __sum16)sum;
111}
112
113#ifdef CONFIG_X86_32
114# include "checksum_32.h"
115#else
116# include "checksum_64.h"
117#endif
118
119#endif
120