This source file includes following definitions.
- from32to16
- do_csum
- ip_fast_csum
- csum_partial
- csum_partial_copy
- ip_compute_csum
- csum_fold
- csum_tcpudp_magic
1
2 #ifndef __SPARC_CHECKSUM_H
3 #define __SPARC_CHECKSUM_H
4
5
6
7
8
9
10
11
12
13 extern inline unsigned short from32to16(unsigned long x)
14 {
15
16 x = (x & 0xffff) + (x >> 16);
17
18 x = (x & 0xffff) + (x >> 16);
19
20 x = (x & 0xffff) + (x >> 16);
21 return x;
22 }
23
24 extern inline unsigned long
25 do_csum(unsigned char * buff, int len)
26 {
27 int odd, count;
28 unsigned long result = 0;
29
30 if (len <= 0)
31 goto out;
32 odd = 1 & (unsigned long) buff;
33 if (odd) {
34 result = *buff << 8;
35 len--;
36 buff++;
37 }
38 count = len >> 1;
39 if (count) {
40 if (2 & (unsigned long) buff) {
41 result += *(unsigned short *) buff;
42 count--;
43 len -= 2;
44 buff += 2;
45 }
46 count >>= 1;
47 if (count) {
48 unsigned long carry = 0;
49 do {
50 unsigned long w = *(unsigned long *) buff;
51 count--;
52 buff += 4;
53 len -= 4;
54 result += carry;
55 result += w;
56 carry = (w > result);
57 } while (count);
58 result += carry;
59 result = (result & 0xffff) + (result >> 16);
60 }
61 if (len & 2) {
62 result += *(unsigned short *) buff;
63 buff += 2;
64 }
65 }
66 if (len & 1)
67 result += (*buff) << 8;
68 result = from32to16(result);
69 if (odd)
70 result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
71 out:
72 return result;
73 }
74
75 extern inline unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl)
76 {
77 return ~do_csum(iph,ihl*4);
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91
92 extern inline unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum)
93 {
94 unsigned long result = do_csum(buff, len);
95
96
97 result += sum;
98
99 result = (result & 0xffff) + (result >> 16);
100 return result;
101 }
102
103
104
105
106
107
108
109
110 extern inline unsigned int csum_partial_copy(char *src, char *dst, int len, int sum)
111 {
112
113
114
115
116
117
118
119 sum = csum_partial(src, len, sum);
120 memcpy(dst, src, len);
121 return sum;
122 }
123
124
125
126
127
128 extern inline unsigned short ip_compute_csum(unsigned char * buff, int len)
129 {
130 return ~from32to16(do_csum(buff,len));
131 }
132
133 #define csum_partial_copy_fromuser(s, d, l, w) \
134 csum_partial_copy((char *) (s), (d), (l), (w))
135
136
137
138
139
140 static inline unsigned short csum_fold(unsigned int sum)
141 {
142 sum = (sum & 0xffff) + (sum >> 16);
143 sum = (sum & 0xffff) + (sum >> 16);
144 return ~sum;
145 }
146
147
148
149
150
151 extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
152 unsigned long daddr,
153 unsigned short len,
154 unsigned short proto,
155 unsigned int sum)
156 {
157 return ~from32to16 (((saddr >> 16) + (saddr & 0xffff) + (daddr >> 16)
158 + (daddr & 0xffff) + (sum >> 16) +
159 (sum & 0xffff) + proto + len));
160 }
161
162 #endif