aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2011-10-18 01:49:19 -0400
committerGreg Ungerer <gerg@uclinux.org>2011-12-24 06:47:57 -0500
commit7f73bafc4630a450ebe8b021efa14781ffd992b1 (patch)
tree81d6448d479d48e5c93f6a444a6e5431a63aff4a /arch
parent479badc364b52774d77264aaf81f4d4b375a4a97 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68k/Kconfig3
-rw-r--r--arch/m68k/Kconfig.cpu2
-rw-r--r--arch/m68k/include/asm/checksum.h31
-rw-r--r--arch/m68k/lib/Makefile8
-rw-r--r--arch/m68k/lib/checksum.c (renamed from arch/m68k/lib/checksum_mm.c)0
-rw-r--r--arch/m68k/lib/checksum_no.c156
6 files changed, 16 insertions, 184 deletions
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 2914b036d76e..2fe2d633fe08 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -40,6 +40,9 @@ config GENERIC_CALIBRATE_DELAY
40config GENERIC_IOMAP 40config GENERIC_IOMAP
41 def_bool MMU 41 def_bool MMU
42 42
43config GENERIC_CSUM
44 bool
45
43config TIME_LOW_RES 46config TIME_LOW_RES
44 bool 47 bool
45 default y 48 default y
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu
index 9af9e68c303b..17d37ed57f3c 100644
--- a/arch/m68k/Kconfig.cpu
+++ b/arch/m68k/Kconfig.cpu
@@ -3,6 +3,7 @@ comment "Processor Type"
3config M68000 3config M68000
4 bool 4 bool
5 select CPU_HAS_NO_BITFIELDS 5 select CPU_HAS_NO_BITFIELDS
6 select GENERIC_CSUM
6 help 7 help
7 The Freescale (was Motorola) 68000 CPU is the first generation of 8 The Freescale (was Motorola) 68000 CPU is the first generation of
8 the well known M68K family of processors. The CPU core as well as 9 the well known M68K family of processors. The CPU core as well as
@@ -23,6 +24,7 @@ config COLDFIRE
23 select GENERIC_GPIO 24 select GENERIC_GPIO
24 select ARCH_REQUIRE_GPIOLIB 25 select ARCH_REQUIRE_GPIOLIB
25 select CPU_HAS_NO_BITFIELDS 26 select CPU_HAS_NO_BITFIELDS
27 select GENERIC_CSUM
26 help 28 help
27 The Freescale ColdFire family of processors is a modern derivitive 29 The Freescale ColdFire family of processors is a modern derivitive
28 of the 68000 processor family. They are mainly targeted at embedded 30 of the 68000 processor family. They are mainly targeted at embedded
diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h
index ec514485c8b6..2f88d867c711 100644
--- a/arch/m68k/include/asm/checksum.h
+++ b/arch/m68k/include/asm/checksum.h
@@ -3,6 +3,10 @@
3 3
4#include <linux/in6.h> 4#include <linux/in6.h>
5 5
6#ifdef CONFIG_GENERIC_CSUM
7#include <asm-generic/checksum.h>
8#else
9
6/* 10/*
7 * computes the checksum of a memory block at buff, length len, 11 * computes the checksum of a memory block at buff, length len,
8 * and adds in "sum" (32-bit) 12 * and adds in "sum" (32-bit)
@@ -34,30 +38,6 @@ extern __wsum csum_partial_copy_nocheck(const void *src,
34 void *dst, int len, 38 void *dst, int len,
35 __wsum sum); 39 __wsum sum);
36 40
37
38#ifdef CONFIG_COLDFIRE
39
40/*
41 * The ColdFire cores don't support all the 68k instructions used
42 * in the optimized checksum code below. So it reverts back to using
43 * more standard C coded checksums. The fast checksum code is
44 * significantly larger than the optimized version, so it is not
45 * inlined here.
46 */
47__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
48
49static inline __sum16 csum_fold(__wsum sum)
50{
51 unsigned int tmp = (__force u32)sum;
52
53 tmp = (tmp & 0xffff) + (tmp >> 16);
54 tmp = (tmp & 0xffff) + (tmp >> 16);
55
56 return (__force __sum16)~tmp;
57}
58
59#else
60
61/* 41/*
62 * This is a version of ip_fast_csum() optimized for IP headers, 42 * This is a version of ip_fast_csum() optimized for IP headers,
63 * which always checksum on 4 octet boundaries. 43 * which always checksum on 4 octet boundaries.
@@ -97,8 +77,6 @@ static inline __sum16 csum_fold(__wsum sum)
97 return (__force __sum16)~sum; 77 return (__force __sum16)~sum;
98} 78}
99 79
100#endif /* CONFIG_COLDFIRE */
101
102static inline __wsum 80static inline __wsum
103csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, 81csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
104 unsigned short proto, __wsum sum) 82 unsigned short proto, __wsum sum)
@@ -167,4 +145,5 @@ csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
167 return csum_fold(sum); 145 return csum_fold(sum);
168} 146}
169 147
148#endif /* CONFIG_GENERIC_CSUM */
170#endif /* _M68K_CHECKSUM_H */ 149#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index 1a1bd9067e90..b3b40e4ed339 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -7,8 +7,12 @@ lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
7 memcpy.o memset.o memmove.o 7 memcpy.o memset.o memmove.o
8 8
9ifdef CONFIG_MMU 9ifdef CONFIG_MMU
10lib-y += string.o uaccess.o checksum_mm.o 10lib-y += string.o uaccess.o
11else 11else
12lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o checksum_no.o 12lib-y += mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o
13endif
14
15ifndef CONFIG_GENERIC_CSUM
16lib-y += checksum.o
13endif 17endif
14 18
diff --git a/arch/m68k/lib/checksum_mm.c b/arch/m68k/lib/checksum.c
index 6216f12a756b..6216f12a756b 100644
--- a/arch/m68k/lib/checksum_mm.c
+++ b/arch/m68k/lib/checksum.c
diff --git a/arch/m68k/lib/checksum_no.c b/arch/m68k/lib/checksum_no.c
deleted file mode 100644
index e4c6354da765..000000000000
--- a/arch/m68k/lib/checksum_no.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * IP/TCP/UDP checksumming routines
7 *
8 * Authors: Jorge Cwik, <jorge@laser.satlink.net>
9 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
10 * Tom May, <ftom@netcom.com>
11 * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de>
12 * Lots of code moved from tcp.c and ip.c; see those files
13 * for more names.
14 *
15 * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
16 * Fixed some nasty bugs, causing some horrible crashes.
17 * A: At some points, the sum (%0) was used as
18 * length-counter instead of the length counter
19 * (%1). Thanks to Roman Hodek for pointing this out.
20 * B: GCC seems to mess up if one uses too many
21 * data-registers to hold input values and one tries to
22 * specify d0 and d1 as scratch registers. Letting gcc choose these
23 * registers itself solves the problem.
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version
28 * 2 of the License, or (at your option) any later version.
29 */
30
31/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
32 of the assembly has to go. */
33
34#include <linux/module.h>
35#include <net/checksum.h>
36
37static inline unsigned short from32to16(unsigned long x)
38{
39 /* add up 16-bit and 16-bit for 16+c bit */
40 x = (x & 0xffff) + (x >> 16);
41 /* add up carry.. */
42 x = (x & 0xffff) + (x >> 16);
43 return x;
44}
45
46static unsigned long do_csum(const unsigned char * buff, int len)
47{
48 int odd, count;
49 unsigned long result = 0;
50
51 if (len <= 0)
52 goto out;
53 odd = 1 & (unsigned long) buff;
54 if (odd) {
55 result = *buff;
56 len--;
57 buff++;
58 }
59 count = len >> 1; /* nr of 16-bit words.. */
60 if (count) {
61 if (2 & (unsigned long) buff) {
62 result += *(unsigned short *) buff;
63 count--;
64 len -= 2;
65 buff += 2;
66 }
67 count >>= 1; /* nr of 32-bit words.. */
68 if (count) {
69 unsigned long carry = 0;
70 do {
71 unsigned long w = *(unsigned long *) buff;
72 count--;
73 buff += 4;
74 result += carry;
75 result += w;
76 carry = (w > result);
77 } while (count);
78 result += carry;
79 result = (result & 0xffff) + (result >> 16);
80 }
81 if (len & 2) {
82 result += *(unsigned short *) buff;
83 buff += 2;
84 }
85 }
86 if (len & 1)
87 result += (*buff << 8);
88 result = from32to16(result);
89 if (odd)
90 result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
91out:
92 return result;
93}
94
95#ifdef CONFIG_COLDFIRE
96/*
97 * This is a version of ip_compute_csum() optimized for IP headers,
98 * which always checksum on 4 octet boundaries.
99 */
100__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
101{
102 return (__force __sum16)~do_csum(iph,ihl*4);
103}
104EXPORT_SYMBOL(ip_fast_csum);
105#endif
106
107/*
108 * computes the checksum of a memory block at buff, length len,
109 * and adds in "sum" (32-bit)
110 *
111 * returns a 32-bit number suitable for feeding into itself
112 * or csum_tcpudp_magic
113 *
114 * this function must be called with even lengths, except
115 * for the last fragment, which may be odd
116 *
117 * it's best to have buff aligned on a 32-bit boundary
118 */
119__wsum csum_partial(const void *buff, int len, __wsum sum)
120{
121 unsigned int result = do_csum(buff, len);
122
123 /* add in old sum, and carry.. */
124 result += (__force u32)sum;
125 if ((__force u32)sum > result)
126 result += 1;
127 return (__force __wsum)result;
128}
129
130EXPORT_SYMBOL(csum_partial);
131
132/*
133 * copy from fs while checksumming, otherwise like csum_partial
134 */
135
136__wsum
137csum_partial_copy_from_user(const void __user *src, void *dst,
138 int len, __wsum sum, int *csum_err)
139{
140 if (csum_err) *csum_err = 0;
141 memcpy(dst, (__force const void *)src, len);
142 return csum_partial(dst, len, sum);
143}
144EXPORT_SYMBOL(csum_partial_copy_from_user);
145
146/*
147 * copy from ds while checksumming, otherwise like csum_partial
148 */
149
150__wsum
151csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
152{
153 memcpy(dst, src, len);
154 return csum_partial(dst, len, sum);
155}
156EXPORT_SYMBOL(csum_partial_copy_nocheck);