1633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 2633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This file is subject to the terms and conditions of the GNU General Public 3633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * License. See the file "COPYING" in the main directory of this archive 4633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * for more details. 5633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 6633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle 7633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 1999 Silicon Graphics, Inc. 8633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 2001 Thiemo Seufer. 9633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copyright (C) 2002 Maciej W. Rozycki 10633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 11633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifndef _ASM_CHECKSUM_H 12633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define _ASM_CHECKSUM_H 13633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 14633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <linux/in6.h> 15633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 16633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#include <asm/uaccess.h> 17633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 18633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 19633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * computes the checksum of a memory block at buff, length len, 20633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * and adds in "sum" (32-bit) 21633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 22633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * returns a 32-bit number suitable for feeding into itself 23633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * or csum_tcpudp_magic 24633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 25633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * this function must be called with even lengths, except 26633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * for the last fragment, which may be odd 27633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 28633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * it's best to have buff aligned on a 32-bit boundary 29633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 30633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham__wsum csum_partial(const void *buff, int len, __wsum sum); 31633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 32633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham__wsum __csum_partial_copy_user(const void *src, void *dst, 33633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int len, __wsum sum, int *err_ptr); 34633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 35633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 36633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * this is a new version of the above that records errors it finds in *errp, 37633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * but continues and zeros the rest of the buffer. 38633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 39633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline 40633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len, 41633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __wsum sum, int *err_ptr) 42633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 43633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham might_sleep(); 44633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return __csum_partial_copy_user((__force void *)src, dst, 45633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham len, sum, err_ptr); 46633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 47633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 48633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 49633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Copy and checksum to user 50633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 51633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define HAVE_CSUM_COPY_USER 52633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline 53633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, 54633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __wsum sum, int *err_ptr) 55633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 56633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham might_sleep(); 57633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (access_ok(VERIFY_WRITE, dst, len)) 58633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return __csum_partial_copy_user(src, (__force void *)dst, 59633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham len, sum, err_ptr); 60633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham if (len) 61633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham *err_ptr = -EFAULT; 62633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 63633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return (__force __wsum)-1; /* invalid checksum */ 64633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 65633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 66633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 67633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * the same as csum_partial, but copies from user space (but on MIPS 68633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * we have just one address space, so this is identical to the above) 69633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 70633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham__wsum csum_partial_copy_nocheck(const void *src, void *dst, 71633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int len, __wsum sum); 72633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 73633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 74633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Fold a partial checksum without adding pseudo headers 75633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 76633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline __sum16 csum_fold(__wsum sum) 77633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 78633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__( 79633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push # csum_fold\n" 80633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noat \n" 81633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sll $1, %0, 16 \n" 82633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 83633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, $1 \n" 84633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " srl %0, %0, 16 \n" 85633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 86633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " xori %0, 0xffff \n" 87633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop" 88633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=r" (sum) 89633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "0" (sum)); 90633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 91633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return (__force __sum16)sum; 92633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 93633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 94633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 95633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * This is a version of ip_compute_csum() optimized for IP headers, 96633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * which always checksum on 4 octet boundaries. 97633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * 98633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by 99633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * Arnt Gulbrandsen. 100633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 101633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) 102633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 103633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const unsigned int *word = iph; 104633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const unsigned int *stop = word + ihl; 105633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned int csum; 106633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham int carry; 107633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 108633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum = word[0]; 109633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += word[1]; 110633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham carry = (csum < word[1]); 111633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += carry; 112633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 113633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += word[2]; 114633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham carry = (csum < word[2]); 115633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += carry; 116633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 117633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += word[3]; 118633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham carry = (csum < word[3]); 119633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += carry; 120633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 121633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham word += 4; 122633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham do { 123633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += *word; 124633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham carry = (csum < *word); 125633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham csum += carry; 126633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham word++; 127633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham } while (word != stop); 128633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 129633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return csum_fold(csum); 130633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 131633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 132633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline __wsum csum_tcpudp_nofold(__be32 saddr, 133633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __be32 daddr, unsigned short len, unsigned short proto, 134633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __wsum sum) 135633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 136633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__( 137633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push # csum_tcpudp_nofold\n" 138633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noat \n" 139633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_32BIT 140633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %2 \n" 141633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %2 \n" 142633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 143633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 144633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %3 \n" 145633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %3 \n" 146633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 147633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 148633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %4 \n" 149633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %4 \n" 150633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 151633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 152633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef CONFIG_64BIT 153633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " daddu %0, %2 \n" 154633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " daddu %0, %3 \n" 155633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " daddu %0, %4 \n" 156633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " dsll32 $1, %0, 0 \n" 157633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " daddu %0, $1 \n" 158633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " dsra32 %0, %0, 0 \n" 159633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 160633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop" 161633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=r" (sum) 162633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "0" ((__force unsigned long)daddr), 163633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "r" ((__force unsigned long)saddr), 164633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#ifdef __MIPSEL__ 165633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "r" ((proto + len) << 8), 166633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#else 167633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "r" (proto + len), 168633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif 169633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "r" ((__force unsigned long)sum)); 170633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 171633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return sum; 172633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 173633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 174633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 175633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * computes the checksum of the TCP/UDP pseudo-header 176633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * returns a 16-bit checksum, already complemented 177633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 178633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, 179633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short len, 180633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham unsigned short proto, 181633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __wsum sum) 182633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 183633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); 184633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 185633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 186633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham/* 187633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * this routine is used for miscellaneous IP-like checksums, mainly 188633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham * in icmp.c 189633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham */ 190633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic inline __sum16 ip_compute_csum(const void *buff, int len) 191633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 192633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return csum_fold(csum_partial(buff, len, 0)); 193633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 194633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 195633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#define _HAVE_ARCH_IPV6_CSUM 196633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandhamstatic __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, 197633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham const struct in6_addr *daddr, 198633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __u32 len, unsigned short proto, 199633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __wsum sum) 200633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham{ 201633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham __asm__( 202633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set push # csum_ipv6_magic\n" 203633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noreorder \n" 204633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set noat \n" 205633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %5 # proto (long in network byte order)\n" 206633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %5 \n" 207633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 208633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 209633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %6 # csum\n" 210633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %6 \n" 211633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 0(%2) # four words source address\n" 212633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 213633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 214633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 215633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 216633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 4(%2) \n" 217633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 218633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 219633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 220633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 221633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 8(%2) \n" 222633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 223633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 224633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 225633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 226633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 12(%2) \n" 227633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 228633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 229633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 230633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 231633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 0(%3) \n" 232633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 233633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 234633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 235633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 236633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 4(%3) \n" 237633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 238633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 239633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 240633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 241633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 8(%3) \n" 242633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 243633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 244633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 245633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 246633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " lw %1, 12(%3) \n" 247633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 \n" 248633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, %1 \n" 249633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " sltu $1, %0, %1 \n" 250633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 251633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " addu %0, $1 # Add final carry\n" 252633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham " .set pop" 253633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "=r" (sum), "=r" (proto) 254633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham : "r" (saddr), "r" (daddr), 255633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); 256633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 257633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham return csum_fold(sum); 258633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham} 259633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham 260633c3473533ad9f2cca069b22cc5d95cd4e3510bRaghu Gandham#endif /* _ASM_CHECKSUM_H */ 261