Path: blob/master/arch/powerpc/include/asm/checksum.h
15117 views
#ifndef _ASM_POWERPC_CHECKSUM_H1#define _ASM_POWERPC_CHECKSUM_H2#ifdef __KERNEL__34/*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License7* as published by the Free Software Foundation; either version8* 2 of the License, or (at your option) any later version.9*/1011/*12* This is a version of ip_compute_csum() optimized for IP headers,13* which always checksum on 4 octet boundaries. ihl is the number14* of 32-bit words and is always >= 5.15*/16extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);1718/*19* computes the checksum of the TCP/UDP pseudo-header20* returns a 16-bit checksum, already complemented21*/22extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,23unsigned short len,24unsigned short proto,25__wsum sum);2627/*28* computes the checksum of a memory block at buff, length len,29* and adds in "sum" (32-bit)30*31* returns a 32-bit number suitable for feeding into itself32* or csum_tcpudp_magic33*34* this function must be called with even lengths, except35* for the last fragment, which may be odd36*37* it's best to have buff aligned on a 32-bit boundary38*/39extern __wsum csum_partial(const void *buff, int len, __wsum sum);4041/*42* Computes the checksum of a memory block at src, length len,43* and adds in "sum" (32-bit), while copying the block to dst.44* If an access exception occurs on src or dst, it stores -EFAULT45* to *src_err or *dst_err respectively (if that pointer is not46* NULL), and, for an error on src, zeroes the rest of dst.47*48* Like csum_partial, this must be called with even lengths,49* except for the last fragment.50*/51extern __wsum csum_partial_copy_generic(const void *src, void *dst,52int len, __wsum sum,53int *src_err, int *dst_err);5455#ifdef __powerpc64__56#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER57extern __wsum csum_and_copy_from_user(const void __user *src, void *dst,58int len, __wsum sum, int *err_ptr);59#define HAVE_CSUM_COPY_USER60extern __wsum csum_and_copy_to_user(const void *src, void __user *dst,61int len, __wsum sum, int *err_ptr);62#else63/*64* the same as csum_partial, but copies from src to dst while it65* checksums.66*/67#define csum_partial_copy_from_user(src, dst, len, sum, errp) \68csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL)69#endif7071#define csum_partial_copy_nocheck(src, dst, len, sum) \72csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL)737475/*76* turns a 32-bit partial checksum (e.g. from csum_partial) into a77* 1's complement 16-bit checksum.78*/79static inline __sum16 csum_fold(__wsum sum)80{81unsigned int tmp;8283/* swap the two 16-bit halves of sum */84__asm__("rlwinm %0,%1,16,0,31" : "=r" (tmp) : "r" (sum));85/* if there is a carry from adding the two 16-bit halves,86it will carry from the lower half into the upper half,87giving us the correct sum in the upper half. */88return (__force __sum16)(~((__force u32)sum + tmp) >> 16);89}9091/*92* this routine is used for miscellaneous IP-like checksums, mainly93* in icmp.c94*/95static inline __sum16 ip_compute_csum(const void *buff, int len)96{97return csum_fold(csum_partial(buff, len, 0));98}99100static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,101unsigned short len,102unsigned short proto,103__wsum sum)104{105#ifdef __powerpc64__106unsigned long s = (__force u32)sum;107108s += (__force u32)saddr;109s += (__force u32)daddr;110s += proto + len;111s += (s >> 32);112return (__force __wsum) s;113#else114__asm__("\n\115addc %0,%0,%1 \n\116adde %0,%0,%2 \n\117adde %0,%0,%3 \n\118addze %0,%0 \n\119"120: "=r" (sum)121: "r" (daddr), "r"(saddr), "r"(proto + len), "0"(sum));122return sum;123#endif124}125#endif /* __KERNEL__ */126#endif127128129