/*
 * arch/sh64/lib/c-checksum.c
 *
 * This file contains network checksum routines that are better done
 * in an architecture-specific manner due to speed..
 */

#undef DEBUG

#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>

static inline unsigned short from64to16(unsigned long long x)
{
	/* add up 32-bit words for 33 bits */
	x = (x & 0xffffffff) + (x >> 32);
	/* add up 16-bit and 17-bit words for 17+c bits */
	x = (x & 0xffff) + (x >> 16);
	/* add up 16-bit and 2-bit for 16+c bit */
	x = (x & 0xffff) + (x >> 16);
	/* add up carry.. */
	x = (x & 0xffff) + (x >> 16);
	return x;
}

static inline unsigned short foldto16(unsigned long x)
{
	/* add up 16-bit for 17 bits */
	x = (x & 0xffff) + (x >> 16);
	/* add up carry.. */
	x = (x & 0xffff) + (x >> 16);
	return x;
}

static inline unsigned short myfoldto16(unsigned long long x)
{
	/* Fold down to 32-bits so we don't loose in the typedef-less
	   network stack.  */
	/* 64 to 33 */
	x = (x & 0xffffffff) + (x >> 32);
	/* 33 to 32 */
	x = (x & 0xffffffff) + (x >> 32);

	/* add up 16-bit for 17 bits */
	x = (x & 0xffff) + (x >> 16);
	/* add up carry.. */
	x = (x & 0xffff) + (x >> 16);
	return x;
}

#define odd(x) ((x)&1)
#define U16(x) ntohs(x)

static unsigned long do_csum(const unsigned char *buff, int len)
{
	int odd, count;
	unsigned long result = 0;

	pr_debug("do_csum buff %p, len %d (0x%x)\n", buff, len, len);
#ifdef DEBUG
	for (i = 0; i < len; i++) {
		if ((i % 26) == 0)
			printk("\n");
		printk("%02X ", buff[i]);
	}
#endif

	if (len <= 0)
		goto out;

	odd = 1 & (unsigned long) buff;
	if (odd) {
		result = *buff << 8;
		len--;
		buff++;
	}
	count = len >> 1;	/* nr of 16-bit words.. */
	if (count) {
		if (2 & (unsigned long) buff) {
			result += *(unsigned short *) buff;
			count--;
			len -= 2;
			buff += 2;
		}
		count >>= 1;	/* nr of 32-bit words.. */
		if (count) {
			unsigned long carry = 0;
			do {
				unsigned long w = *(unsigned long *) buff;
				buff += 4;
				count--;
				result += carry;
				result += w;
				carry = (w > result);
			} while (count);
			result += carry;
			result = (result & 0xffff) + (result >> 16);
		}
		if (len & 2) {
			result += *(unsigned short *) buff;
			buff += 2;
		}
	}
	if (len & 1)
		result += *buff;
	result = foldto16(result);
	if (odd)
		result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);

	pr_debug("\nCHECKSUM is 0x%x\n", result);

      out:
	return result;
}

/* computes the checksum of a memory block at buff, length len,
   and adds in "sum" (32-bit)  */
unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum)
{
	unsigned long long result = do_csum(buff, len);

	/* add in old sum, and carry.. */
	result += sum;
	/* 32+c bits -> 32 bits */
	result = (result & 0xffffffff) + (result >> 32);

	pr_debug("csum_partial, buff %p len %d sum 0x%x result=0x%016Lx\n",
		buff, len, sum, result);

	return result;
}

/* Copy while checksumming, otherwise like csum_partial.  */
unsigned int
csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
{
	sum = csum_partial(src, len, sum);
	memcpy(dst, src, len);

	return sum;
}

/* Copy from userspace and compute checksum.  If we catch an exception
   then zero the rest of the buffer.  */
unsigned int
csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len,
			    unsigned int sum, int *err_ptr)
{
	int missing;

	pr_debug
	    ("csum_partial_copy_from_user src %p, dest %p, len %d, sum %08x, err_ptr %p\n",
	     src, dst, len, sum, err_ptr);
	missing = copy_from_user(dst, src, len);
	pr_debug("  access_ok %d\n", __access_ok((unsigned long) src, len));
	pr_debug("  missing %d\n", missing);
	if (missing) {
		memset(dst + len - missing, 0, missing);
		*err_ptr = -EFAULT;
	}

	return csum_partial(dst, len, sum);
}

/* Copy to userspace and compute checksum.  */
unsigned int
csum_partial_copy_to_user(const unsigned char *src, unsigned char *dst, int len,
			  unsigned int sum, int *err_ptr)
{
	sum = csum_partial(src, len, sum);

	if (copy_to_user(dst, src, len))
		*err_ptr = -EFAULT;

	return sum;
}

/*
 *	This is a version of ip_compute_csum() optimized for IP headers,
 *	which always checksum on 4 octet boundaries.
 */
unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
{
	pr_debug("ip_fast_csum %p,%d\n", iph, ihl);

	return ~do_csum(iph, ihl * 4);
}

unsigned int csum_tcpudp_nofold(unsigned long saddr,
				unsigned long daddr,
				unsigned short len,
				unsigned short proto, unsigned int sum)
{
	unsigned long long result;

	pr_debug("ntohs(0x%x)=0x%x\n", 0xdead, ntohs(0xdead));
	pr_debug("htons(0x%x)=0x%x\n", 0xdead, htons(0xdead));

	result = ((unsigned long long) saddr +
		  (unsigned long long) daddr +
		  (unsigned long long) sum +
		  ((unsigned long long) ntohs(len) << 16) +
		  ((unsigned long long) proto << 8));

	/* Fold down to 32-bits so we don't loose in the typedef-less
	   network stack.  */
	/* 64 to 33 */
	result = (result & 0xffffffff) + (result >> 32);
	/* 33 to 32 */
	result = (result & 0xffffffff) + (result >> 32);

	pr_debug("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n",
		__FUNCTION__, saddr, daddr, len, proto, sum, result);

	return result;
}

// Post SIM:
unsigned int
csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum)
{
	//  unsigned dummy;
	pr_debug("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst,
		len);

	return csum_partial_copy(src, dst, len, sum);
}
