0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef _ASM_ARC_CHECKSUM_H
0017 #define _ASM_ARC_CHECKSUM_H
0018
0019
0020
0021
0022
0023
0024
0025 static inline __sum16 csum_fold(__wsum s)
0026 {
0027 unsigned int r = s << 16 | s >> 16;
0028 s = ~s;
0029 s -= r;
0030 return s >> 16;
0031 }
0032
0033
0034
0035
0036
0037 static inline __sum16
0038 ip_fast_csum(const void *iph, unsigned int ihl)
0039 {
0040 const void *ptr = iph;
0041 unsigned int tmp, tmp2, sum;
0042
0043 __asm__(
0044 " ld.ab %0, [%3, 4] \n"
0045 " ld.ab %2, [%3, 4] \n"
0046 " sub %1, %4, 2 \n"
0047 " lsr.f lp_count, %1, 1 \n"
0048 " bcc 0f \n"
0049 " add.f %0, %0, %2 \n"
0050 " ld.ab %2, [%3, 4] \n"
0051 "0: lp 1f \n"
0052 " ld.ab %1, [%3, 4] \n"
0053 " adc.f %0, %0, %2 \n"
0054 " ld.ab %2, [%3, 4] \n"
0055 " adc.f %0, %0, %1 \n"
0056 "1: adc.f %0, %0, %2 \n"
0057 " add.cs %0,%0,1 \n"
0058 : "=&r"(sum), "=r"(tmp), "=&r"(tmp2), "+&r" (ptr)
0059 : "r"(ihl)
0060 : "cc", "lp_count", "memory");
0061
0062 return csum_fold(sum);
0063 }
0064
0065
0066
0067
0068
0069 static inline __wsum
0070 csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
0071 __u8 proto, __wsum sum)
0072 {
0073 __asm__ __volatile__(
0074 " add.f %0, %0, %1 \n"
0075 " adc.f %0, %0, %2 \n"
0076 " adc.f %0, %0, %3 \n"
0077 " adc.f %0, %0, %4 \n"
0078 " adc %0, %0, 0 \n"
0079 : "+&r"(sum)
0080 : "r"(saddr), "r"(daddr),
0081 #ifdef CONFIG_CPU_BIG_ENDIAN
0082 "r"(len),
0083 #else
0084 "r"(len << 8),
0085 #endif
0086 "r"(htons(proto))
0087 : "cc");
0088
0089 return sum;
0090 }
0091
0092 #define csum_fold csum_fold
0093 #define ip_fast_csum ip_fast_csum
0094 #define csum_tcpudp_nofold csum_tcpudp_nofold
0095
0096 #include <asm-generic/checksum.h>
0097
0098 #endif