| .. | .. |
|---|
| 13 | 13 | #define _S390_CHECKSUM_H |
|---|
| 14 | 14 | |
|---|
| 15 | 15 | #include <linux/uaccess.h> |
|---|
| 16 | +#include <linux/in6.h> |
|---|
| 16 | 17 | |
|---|
| 17 | 18 | /* |
|---|
| 18 | | - * computes the checksum of a memory block at buff, length len, |
|---|
| 19 | | - * and adds in "sum" (32-bit) |
|---|
| 19 | + * Computes the checksum of a memory block at buff, length len, |
|---|
| 20 | + * and adds in "sum" (32-bit). |
|---|
| 20 | 21 | * |
|---|
| 21 | | - * returns a 32-bit number suitable for feeding into itself |
|---|
| 22 | | - * or csum_tcpudp_magic |
|---|
| 22 | + * Returns a 32-bit number suitable for feeding into itself |
|---|
| 23 | + * or csum_tcpudp_magic. |
|---|
| 23 | 24 | * |
|---|
| 24 | | - * this function must be called with even lengths, except |
|---|
| 25 | | - * for the last fragment, which may be odd |
|---|
| 25 | + * This function must be called with even lengths, except |
|---|
| 26 | + * for the last fragment, which may be odd. |
|---|
| 26 | 27 | * |
|---|
| 27 | | - * it's best to have buff aligned on a 32-bit boundary |
|---|
| 28 | + * It's best to have buff aligned on a 32-bit boundary. |
|---|
| 28 | 29 | */ |
|---|
| 29 | | -static inline __wsum |
|---|
| 30 | | -csum_partial(const void *buff, int len, __wsum sum) |
|---|
| 30 | +static inline __wsum csum_partial(const void *buff, int len, __wsum sum) |
|---|
| 31 | 31 | { |
|---|
| 32 | 32 | register unsigned long reg2 asm("2") = (unsigned long) buff; |
|---|
| 33 | 33 | register unsigned long reg3 asm("3") = (unsigned long) len; |
|---|
| .. | .. |
|---|
| 40 | 40 | } |
|---|
| 41 | 41 | |
|---|
| 42 | 42 | /* |
|---|
| 43 | | - * the same as csum_partial_copy, but copies from user space. |
|---|
| 44 | | - * |
|---|
| 45 | | - * here even more important to align src and dst on a 32-bit (or even |
|---|
| 46 | | - * better 64-bit) boundary |
|---|
| 47 | | - * |
|---|
| 48 | | - * Copy from userspace and compute checksum. |
|---|
| 49 | | - */ |
|---|
| 50 | | -static inline __wsum |
|---|
| 51 | | -csum_partial_copy_from_user(const void __user *src, void *dst, |
|---|
| 52 | | - int len, __wsum sum, |
|---|
| 53 | | - int *err_ptr) |
|---|
| 54 | | -{ |
|---|
| 55 | | - if (unlikely(copy_from_user(dst, src, len))) |
|---|
| 56 | | - *err_ptr = -EFAULT; |
|---|
| 57 | | - return csum_partial(dst, len, sum); |
|---|
| 58 | | -} |
|---|
| 59 | | - |
|---|
| 60 | | - |
|---|
| 61 | | -static inline __wsum |
|---|
| 62 | | -csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) |
|---|
| 63 | | -{ |
|---|
| 64 | | - memcpy(dst,src,len); |
|---|
| 65 | | - return csum_partial(dst, len, sum); |
|---|
| 66 | | -} |
|---|
| 67 | | - |
|---|
| 68 | | -/* |
|---|
| 69 | | - * Fold a partial checksum without adding pseudo headers |
|---|
| 43 | + * Fold a partial checksum without adding pseudo headers. |
|---|
| 70 | 44 | */ |
|---|
| 71 | 45 | static inline __sum16 csum_fold(__wsum sum) |
|---|
| 72 | 46 | { |
|---|
| 73 | 47 | u32 csum = (__force u32) sum; |
|---|
| 74 | 48 | |
|---|
| 75 | | - csum += (csum >> 16) + (csum << 16); |
|---|
| 49 | + csum += (csum >> 16) | (csum << 16); |
|---|
| 76 | 50 | csum >>= 16; |
|---|
| 77 | 51 | return (__force __sum16) ~csum; |
|---|
| 78 | 52 | } |
|---|
| 79 | 53 | |
|---|
| 80 | 54 | /* |
|---|
| 81 | | - * This is a version of ip_compute_csum() optimized for IP headers, |
|---|
| 82 | | - * which always checksum on 4 octet boundaries. |
|---|
| 83 | | - * |
|---|
| 55 | + * This is a version of ip_compute_csum() optimized for IP headers, |
|---|
| 56 | + * which always checksums on 4 octet boundaries. |
|---|
| 84 | 57 | */ |
|---|
| 85 | 58 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) |
|---|
| 86 | 59 | { |
|---|
| 87 | | - return csum_fold(csum_partial(iph, ihl*4, 0)); |
|---|
| 60 | + __u64 csum = 0; |
|---|
| 61 | + __u32 *ptr = (u32 *)iph; |
|---|
| 62 | + |
|---|
| 63 | + csum += *ptr++; |
|---|
| 64 | + csum += *ptr++; |
|---|
| 65 | + csum += *ptr++; |
|---|
| 66 | + csum += *ptr++; |
|---|
| 67 | + ihl -= 4; |
|---|
| 68 | + while (ihl--) |
|---|
| 69 | + csum += *ptr++; |
|---|
| 70 | + csum += (csum >> 32) | (csum << 32); |
|---|
| 71 | + return csum_fold((__force __wsum)(csum >> 32)); |
|---|
| 88 | 72 | } |
|---|
| 89 | 73 | |
|---|
| 90 | 74 | /* |
|---|
| 91 | | - * computes the checksum of the TCP/UDP pseudo-header |
|---|
| 92 | | - * returns a 32-bit checksum |
|---|
| 75 | + * Computes the checksum of the TCP/UDP pseudo-header. |
|---|
| 76 | + * Returns a 32-bit checksum. |
|---|
| 93 | 77 | */ |
|---|
| 94 | | -static inline __wsum |
|---|
| 95 | | -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, |
|---|
| 96 | | - __wsum sum) |
|---|
| 78 | +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, |
|---|
| 79 | + __u8 proto, __wsum sum) |
|---|
| 97 | 80 | { |
|---|
| 98 | | - __u32 csum = (__force __u32)sum; |
|---|
| 81 | + __u64 csum = (__force __u64)sum; |
|---|
| 99 | 82 | |
|---|
| 100 | 83 | csum += (__force __u32)saddr; |
|---|
| 101 | | - if (csum < (__force __u32)saddr) |
|---|
| 102 | | - csum++; |
|---|
| 103 | | - |
|---|
| 104 | 84 | csum += (__force __u32)daddr; |
|---|
| 105 | | - if (csum < (__force __u32)daddr) |
|---|
| 106 | | - csum++; |
|---|
| 107 | | - |
|---|
| 108 | | - csum += len + proto; |
|---|
| 109 | | - if (csum < len + proto) |
|---|
| 110 | | - csum++; |
|---|
| 111 | | - |
|---|
| 112 | | - return (__force __wsum)csum; |
|---|
| 85 | + csum += len; |
|---|
| 86 | + csum += proto; |
|---|
| 87 | + csum += (csum >> 32) | (csum << 32); |
|---|
| 88 | + return (__force __wsum)(csum >> 32); |
|---|
| 113 | 89 | } |
|---|
| 114 | 90 | |
|---|
| 115 | 91 | /* |
|---|
| 116 | | - * computes the checksum of the TCP/UDP pseudo-header |
|---|
| 117 | | - * returns a 16-bit checksum, already complemented |
|---|
| 92 | + * Computes the checksum of the TCP/UDP pseudo-header. |
|---|
| 93 | + * Returns a 16-bit checksum, already complemented. |
|---|
| 118 | 94 | */ |
|---|
| 119 | | - |
|---|
| 120 | | -static inline __sum16 |
|---|
| 121 | | -csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, |
|---|
| 122 | | - __wsum sum) |
|---|
| 95 | +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, |
|---|
| 96 | + __u8 proto, __wsum sum) |
|---|
| 123 | 97 | { |
|---|
| 124 | | - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); |
|---|
| 98 | + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); |
|---|
| 125 | 99 | } |
|---|
| 126 | 100 | |
|---|
| 127 | 101 | /* |
|---|
| 128 | | - * this routine is used for miscellaneous IP-like checksums, mainly |
|---|
| 129 | | - * in icmp.c |
|---|
| 102 | + * Used for miscellaneous IP-like checksums, mainly icmp. |
|---|
| 130 | 103 | */ |
|---|
| 131 | | - |
|---|
| 132 | 104 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
|---|
| 133 | 105 | { |
|---|
| 134 | 106 | return csum_fold(csum_partial(buff, len, 0)); |
|---|
| 135 | 107 | } |
|---|
| 136 | 108 | |
|---|
| 109 | +#define _HAVE_ARCH_IPV6_CSUM |
|---|
| 110 | +static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, |
|---|
| 111 | + const struct in6_addr *daddr, |
|---|
| 112 | + __u32 len, __u8 proto, __wsum csum) |
|---|
| 113 | +{ |
|---|
| 114 | + __u64 sum = (__force __u64)csum; |
|---|
| 115 | + |
|---|
| 116 | + sum += (__force __u32)saddr->s6_addr32[0]; |
|---|
| 117 | + sum += (__force __u32)saddr->s6_addr32[1]; |
|---|
| 118 | + sum += (__force __u32)saddr->s6_addr32[2]; |
|---|
| 119 | + sum += (__force __u32)saddr->s6_addr32[3]; |
|---|
| 120 | + sum += (__force __u32)daddr->s6_addr32[0]; |
|---|
| 121 | + sum += (__force __u32)daddr->s6_addr32[1]; |
|---|
| 122 | + sum += (__force __u32)daddr->s6_addr32[2]; |
|---|
| 123 | + sum += (__force __u32)daddr->s6_addr32[3]; |
|---|
| 124 | + sum += len; |
|---|
| 125 | + sum += proto; |
|---|
| 126 | + sum += (sum >> 32) | (sum << 32); |
|---|
| 127 | + return csum_fold((__force __wsum)(sum >> 32)); |
|---|
| 128 | +} |
|---|
| 129 | + |
|---|
| 137 | 130 | #endif /* _S390_CHECKSUM_H */ |
|---|
| 138 | | - |
|---|
| 139 | | - |
|---|