]>
Commit | Line | Data |
---|---|---|
e4270eee JR |
1 | --- dip-3.3.7o/command.c.orig Thu Jan 21 15:37:13 1999 |
2 | +++ dip-3.3.7o/command.c Thu Jan 21 15:45:04 1999 | |
3 | @@ -2585,6 +2585,92 @@ | |
4 | return((~sum) & 0xffff); | |
5 | } | |
6 | ||
7 | +#elif defined (__arm__) | |
8 | + | |
9 | +/* | |
10 | + * This is a version of ip_compute_csum() optimized for IP headers, | |
11 | + * which always checksum on 4 octet boundaries. | |
12 | + * | |
13 | + * Converted and optimised for ARM by R. M. King. | |
14 | + * | |
15 | + * Note: the order that the LDM registers are loaded with respect to | |
16 | + * the adc's doesn't matter. | |
17 | + */ | |
18 | +static inline unsigned short | |
19 | +ip_fast_csum(unsigned char * iph, unsigned int ihl) | |
20 | +{ | |
21 | + unsigned int sum, tmp1; | |
22 | + | |
23 | + __asm__ __volatile__(" | |
24 | + sub %2, %2, #5 | |
25 | + ldr %0, [%1], #4 | |
26 | + ldr %3, [%1], #4 | |
27 | + adds %0, %0, %3 | |
28 | + ldr %3, [%1], #4 | |
29 | + adcs %0, %0, %3 | |
30 | + ldr %3, [%1], #4 | |
31 | + adcs %0, %0, %3 | |
32 | +1: ldr %3, [%1], #4 | |
33 | + adcs %0, %0, %3 | |
34 | + tst %2, #15 | |
35 | + subne %2, %2, #1 | |
36 | + bne 1b | |
37 | + adc %0, %0, #0 | |
38 | + adds %0, %0, %0, lsl #16 | |
39 | + addcs %0, %0, #0x10000 | |
40 | + mvn %0, %0 | |
41 | + mov %0, %0, lsr #16 | |
42 | + " | |
43 | + : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (tmp1) | |
44 | + : "1" (iph), "2" (ihl)); | |
45 | + return(sum); | |
46 | +} | |
47 | + | |
48 | +/* | |
49 | + * Fold a partial checksum without adding pseudo headers | |
50 | + */ | |
51 | +static inline unsigned int | |
52 | +csum_fold(unsigned int sum) | |
53 | +{ | |
54 | + __asm__(" | |
55 | + adds %0, %0, %0, lsl #16 | |
56 | + addcs %0, %0, #0x10000" | |
57 | + : "=r" (sum) | |
58 | + : "0" (sum)); | |
59 | + return (~sum) >> 16; | |
60 | +} | |
61 | + | |
62 | +static inline unsigned long | |
63 | +csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len, | |
64 | + unsigned short proto, unsigned int sum) | |
65 | +{ | |
66 | + __asm__(" | |
67 | + adds %0, %0, %1 | |
68 | + adcs %0, %0, %2 | |
69 | + adcs %0, %0, %3 | |
70 | + adc %0, %0, #0" | |
71 | + : "=&r"(sum) | |
72 | + : "r" (daddr), "r" (saddr), "r" ((ntohs(len)<<16)+proto*256), "0" (sum)); | |
73 | + return sum; | |
74 | +} | |
75 | +/* | |
76 | + * computes the checksum of the TCP/UDP pseudo-header | |
77 | + * returns a 16-bit checksum, already complemented | |
78 | + */ | |
79 | +static inline unsigned short int | |
80 | +csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, unsigned short len, | |
81 | + unsigned short proto, unsigned int sum) | |
82 | +{ | |
83 | + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); | |
84 | +} | |
85 | + | |
86 | +static unsigned short | |
87 | +udp_check(struct udphdr *uh, int len, | |
88 | + unsigned long saddr, unsigned long daddr) | |
89 | +{ | |
90 | + return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, 0)); | |
91 | +} | |
92 | + | |
93 | #else | |
94 | ||
95 | #error You need to write tcp/ip checksum routines for your architecture |