mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
m68k: simpler m68k and ColdFire CPU's can use generic csum code
We have two implementations of the IP checksuming code for the m68k arch. One uses the more advanced instructions available in 68020 and above processors, the other uses the simpler instructions available on the original 68000 processors and the modern ColdFire processors. This simpler code is pretty much the same as the generic lib implementation of the IP csum functions. So lets just switch over to using that. That means we can completely remove the checksum_no.c file, and only have the local fast code used for the more complex 68k CPU family members. Signed-off-by: Greg Ungerer <gerg@uclinux.org>
This commit is contained in:
parent
479badc364
commit
7f73bafc46
@ -40,6 +40,9 @@ config GENERIC_CALIBRATE_DELAY
|
||||
config GENERIC_IOMAP
|
||||
def_bool MMU
|
||||
|
||||
config GENERIC_CSUM
|
||||
bool
|
||||
|
||||
config TIME_LOW_RES
|
||||
bool
|
||||
default y
|
||||
|
@ -3,6 +3,7 @@ comment "Processor Type"
|
||||
config M68000
|
||||
bool
|
||||
select CPU_HAS_NO_BITFIELDS
|
||||
select GENERIC_CSUM
|
||||
help
|
||||
The Freescale (was Motorola) 68000 CPU is the first generation of
|
||||
the well known M68K family of processors. The CPU core as well as
|
||||
@ -23,6 +24,7 @@ config COLDFIRE
|
||||
select GENERIC_GPIO
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select CPU_HAS_NO_BITFIELDS
|
||||
select GENERIC_CSUM
|
||||
help
|
||||
The Freescale ColdFire family of processors is a modern derivitive
|
||||
of the 68000 processor family. They are mainly targeted at embedded
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
#include <linux/in6.h>
|
||||
|
||||
#ifdef CONFIG_GENERIC_CSUM
|
||||
#include <asm-generic/checksum.h>
|
||||
#else
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
@ -34,30 +38,6 @@ extern __wsum csum_partial_copy_nocheck(const void *src,
|
||||
void *dst, int len,
|
||||
__wsum sum);
|
||||
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
|
||||
/*
|
||||
* The ColdFire cores don't support all the 68k instructions used
|
||||
* in the optimized checksum code below. So it reverts back to using
|
||||
* more standard C coded checksums. The fast checksum code is
|
||||
* significantly larger than the optimized version, so it is not
|
||||
* inlined here.
|
||||
*/
|
||||
__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
|
||||
|
||||
static inline __sum16 csum_fold(__wsum sum)
|
||||
{
|
||||
unsigned int tmp = (__force u32)sum;
|
||||
|
||||
tmp = (tmp & 0xffff) + (tmp >> 16);
|
||||
tmp = (tmp & 0xffff) + (tmp >> 16);
|
||||
|
||||
return (__force __sum16)~tmp;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* This is a version of ip_fast_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
@ -97,8 +77,6 @@ static inline __sum16 csum_fold(__wsum sum)
|
||||
return (__force __sum16)~sum;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_COLDFIRE */
|
||||
|
||||
static inline __wsum
|
||||
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
|
||||
unsigned short proto, __wsum sum)
|
||||
@ -167,4 +145,5 @@ csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
|
||||
return csum_fold(sum);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_GENERIC_CSUM */
|
||||
#endif /* _M68K_CHECKSUM_H */
|
||||
|
@ -7,8 +7,12 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
memcpy.o memset.o memmove.o
|
||||
|
||||
ifdef CONFIG_MMU
|
||||
lib-y += string.o uaccess.o checksum_mm.o
|
||||
lib-y += string.o uaccess.o
|
||||
else
|
||||
lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o checksum_no.o
|
||||
lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o
|
||||
endif
|
||||
|
||||
ifndef CONFIG_GENERIC_CSUM
|
||||
lib-y += checksum.o
|
||||
endif
|
||||
|
||||
|
@ -1,156 +0,0 @@
|
||||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* IP/TCP/UDP checksumming routines
|
||||
*
|
||||
* Authors: Jorge Cwik, <jorge@laser.satlink.net>
|
||||
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
|
||||
* Tom May, <ftom@netcom.com>
|
||||
* Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
|
||||
* Lots of code moved from tcp.c and ip.c; see those files
|
||||
* for more names.
|
||||
*
|
||||
* 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
|
||||
* Fixed some nasty bugs, causing some horrible crashes.
|
||||
* A: At some points, the sum (%0) was used as
|
||||
* length-counter instead of the length counter
|
||||
* (%1). Thanks to Roman Hodek for pointing this out.
|
||||
* B: GCC seems to mess up if one uses too many
|
||||
* data-registers to hold input values and one tries to
|
||||
* specify d0 and d1 as scratch registers. Letting gcc choose these
|
||||
* registers itself solves the problem.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
|
||||
of the assembly has to go. */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
static inline unsigned short from32to16(unsigned long x)
|
||||
{
|
||||
/* add up 16-bit and 16-bit for 16+c bit */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned long do_csum(const unsigned char * buff, int len)
|
||||
{
|
||||
int odd, count;
|
||||
unsigned long result = 0;
|
||||
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
odd = 1 & (unsigned long) buff;
|
||||
if (odd) {
|
||||
result = *buff;
|
||||
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;
|
||||
count--;
|
||||
buff += 4;
|
||||
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 << 8);
|
||||
result = from32to16(result);
|
||||
if (odd)
|
||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
return (__force __sum16)~do_csum(iph,ihl*4);
|
||||
}
|
||||
EXPORT_SYMBOL(ip_fast_csum);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
__wsum csum_partial(const void *buff, int len, __wsum sum)
|
||||
{
|
||||
unsigned int result = do_csum(buff, len);
|
||||
|
||||
/* add in old sum, and carry.. */
|
||||
result += (__force u32)sum;
|
||||
if ((__force u32)sum > result)
|
||||
result += 1;
|
||||
return (__force __wsum)result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
|
||||
/*
|
||||
* copy from fs while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum sum, int *csum_err)
|
||||
{
|
||||
if (csum_err) *csum_err = 0;
|
||||
memcpy(dst, (__force const void *)src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
/*
|
||||
* copy from ds while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
Loading…
Reference in New Issue
Block a user