1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _PARISC_CHECKSUM_H 3 #define _PARISC_CHECKSUM_H 4 5 #include <linux/in6.h> 6 7 #define csum_tcpudp_nofold csum_tcpudp_nofold 8 static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, 9 __u32 len, __u8 proto, 10 __wsum sum) 11 { 12 __asm__( 13 " add %1, %0, %0\n" 14 " addc %2, %0, %0\n" 15 " addc %3, %0, %0\n" 16 " addc %%r0, %0, %0\n" 17 : "=r" (sum) 18 : "r" (daddr), "r"(saddr), "r"(proto+len), "0"(sum)); 19 return sum; 20 } 21 22 #include <asm-generic/checksum.h> 23 24 #define _HAVE_ARCH_IPV6_CSUM 25 static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 26 const struct in6_addr *daddr, 27 __u32 len, __u8 proto, 28 __wsum sum) 29 { 30 unsigned long t0, t1, t2, t3; 31 32 len += proto; /* add 16-bit proto + len */ 33 34 __asm__ __volatile__ ( 35 36 #if BITS_PER_LONG > 32 37 38 /* 39 ** We can execute two loads and two adds per cycle on PA 8000. 40 ** But add insn's get serialized waiting for the carry bit. 41 ** Try to keep 4 registers with "live" values ahead of the ALU. 42 */ 43 44 " depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */ 45 " ldd,ma 8(%1), %4\n" /* get 1st saddr word */ 46 " ldd,ma 8(%2), %5\n" /* get 1st daddr word */ 47 " add %4, %0, %0\n" 48 " ldd,ma 8(%1), %6\n" /* 2nd saddr */ 49 " ldd,ma 8(%2), %7\n" /* 2nd daddr */ 50 " add,dc %5, %0, %0\n" 51 " add,dc %6, %0, %0\n" 52 " add,dc %7, %0, %0\n" 53 " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */ 54 " extrd,u %0, 31, 32, %4\n"/* copy upper half down */ 55 " depdi 0, 31, 32, %0\n"/* clear upper half */ 56 " add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */ 57 " addc 0, %0, %0\n" /* add final carry */ 58 59 #else 60 61 /* 62 ** For PA 1.x, the insn order doesn't matter as much. 63 ** Insn stream is serialized on the carry bit here too. 64 ** result from the previous operation (eg r0 + x) 65 */ 66 " ldw,ma 4(%1), %4\n" /* get 1st saddr word */ 67 " ldw,ma 4(%2), %5\n" /* get 1st daddr word */ 68 " add %4, %0, %0\n" 69 " ldw,ma 4(%1), %6\n" /* 2nd saddr */ 70 " addc %5, %0, %0\n" 71 " ldw,ma 4(%2), %7\n" /* 2nd daddr */ 72 " addc %6, %0, %0\n" 73 " ldw,ma 4(%1), %4\n" /* 3rd saddr */ 74 " addc %7, %0, %0\n" 75 " ldw,ma 4(%2), %5\n" /* 3rd daddr */ 76 " addc %4, %0, %0\n" 77 " ldw,ma 4(%1), %6\n" /* 4th saddr */ 78 " addc %5, %0, %0\n" 79 " ldw,ma 4(%2), %7\n" /* 4th daddr */ 80 " addc %6, %0, %0\n" 81 " addc %7, %0, %0\n" 82 " addc %3, %0, %0\n" /* fold in proto+len */ 83 " addc 0, %0, %0\n" /* add carry */ 84 85 #endif 86 : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len), 87 "=r" (t0), "=r" (t1), "=r" (t2), "=r" (t3) 88 : "0" (sum), "1" (saddr), "2" (daddr), "3" (len) 89 : "memory"); 90 return csum_fold(sum); 91 } 92 93 #endif 94 95