^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef _M68K_CHECKSUM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define _M68K_CHECKSUM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/in6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifdef CONFIG_GENERIC_CSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm-generic/checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * computes the checksum of a memory block at buff, length len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * and adds in "sum" (32-bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * returns a 32-bit number suitable for feeding into itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * or csum_tcpudp_magic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * this function must be called with even lengths, except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * for the last fragment, which may be odd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * it's best to have buff aligned on a 32-bit boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) __wsum csum_partial(const void *buff, int len, __wsum sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * the same as csum_partial, but copies from src while it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * checksums
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * here even more important to align src and dst on a 32-bit (or even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * better 64-bit) boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define _HAVE_ARCH_CSUM_AND_COPY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) extern __wsum csum_and_copy_from_user(const void __user *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) extern __wsum csum_partial_copy_nocheck(const void *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) void *dst, int len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This is a version of ip_fast_csum() optimized for IP headers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * which always checksum on 4 octet boundaries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned int sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) __asm__ ("subqw #1,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "1:\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) "movel %1@+,%3\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) "addxl %3,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "dbra %2,1b\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) "movel %0,%3\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "swap %3\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "addxw %3,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "clrw %3\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "addxw %3,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) : "0" (sum), "1" (iph), "2" (ihl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return (__force __sum16)~sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static inline __sum16 csum_fold(__wsum sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned int tmp = (__force u32)sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) __asm__("swap %1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) "addw %1, %0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) "clrw %1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) "addxw %1, %0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) : "=&d" (sum), "=&d" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) : "0" (sum), "1" (tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return (__force __sum16)~sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static inline __wsum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned short proto, __wsum sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __asm__ ("addl %2,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "addxl %3,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) "addxl %4,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) "clrl %1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) "addxl %1,%0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) : "=&d" (sum), "=d" (saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) : "g" (daddr), "1" (saddr), "d" (len + proto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) "0" (sum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * computes the checksum of the TCP/UDP pseudo-header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * returns a 16-bit checksum, already complemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline __sum16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned short proto, __wsum sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * this routine is used for miscellaneous IP-like checksums, mainly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * in icmp.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static inline __sum16 ip_compute_csum(const void *buff, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return csum_fold (csum_partial(buff, len, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define _HAVE_ARCH_IPV6_CSUM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static __inline__ __sum16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) __u32 len, __u8 proto, __wsum sum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) register unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __asm__("addl %2@,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) "movel %2@(4),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "movel %2@(8),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "movel %2@(12),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "movel %3@,%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) "movel %3@(4),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) "movel %3@(8),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "movel %3@(12),%1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) "addxl %1,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "addxl %4,%0\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "clrl %1\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "addxl %1,%0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) : "=&d" (sum), "=&d" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) : "a" (saddr), "a" (daddr), "d" (len + proto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "0" (sum));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return csum_fold(sum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #endif /* CONFIG_GENERIC_CSUM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #endif /* _M68K_CHECKSUM_H */