11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * INET		An implementation of the TCP/IP protocol suite for the LINUX
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		operating system.  INET is implemented using the  BSD Socket
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		interface as the means of communication with the user level.
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		M32R specific IP/TCP/UDP checksumming routines
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *		(Some code taken from MIPS architecture)
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1994, 1995  Waldorf Electronics GmbH
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1998, 1999  Ralf Baechle
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001-2005  Hiroyuki Kondo, Hirokazu Takata
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h>
214e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <net/checksum.h>
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/byteorder.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy while checksumming, otherwise like csum_partial
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3085d20dee20f0958df1615e73698f6b0c525812f7Al Viro__wsum
3185d20dee20f0958df1615e73698f6b0c525812f7Al Virocsum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sum = csum_partial(src, len, sum);
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memcpy(dst, src, len);
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return sum;
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(csum_partial_copy_nocheck);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy from userspace and compute checksum.  If we catch an exception
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * then zero the rest of the buffer.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4485d20dee20f0958df1615e73698f6b0c525812f7Al Viro__wsum
4585d20dee20f0958df1615e73698f6b0c525812f7Al Virocsum_partial_copy_from_user (const void __user *src, void *dst,
4685d20dee20f0958df1615e73698f6b0c525812f7Al Viro			     int len, __wsum sum, int *err_ptr)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int missing;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	missing = copy_from_user(dst, src, len);
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (missing) {
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(dst + len - missing, 0, missing);
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*err_ptr = -EFAULT;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return csum_partial(dst, len-missing, sum);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(csum_partial_copy_from_user);
59eaaece266a78b8f56ade48fe23147b8b933364deAl ViroEXPORT_SYMBOL(csum_partial);
60