blob: 3bffdbb1c1f90f2dc33f4b94ab7b622cabbd93f4 [file] [log] [blame]
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +09001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Quick'n'dirty IP checksum ...
7 *
8 * Copyright (C) 1998, 1999 Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 */
11#include <asm/asm.h>
12#include <asm/regdef.h>
13
14#ifdef CONFIG_64BIT
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090015/*
16 * As we are sharing code base with the mips32 tree (which use the o32 ABI
17 * register definitions). We need to redefine the register definitions from
18 * the n64 ABI register naming to the o32 ABI register naming.
19 */
20#undef t0
21#undef t1
22#undef t2
23#undef t3
24#define t0 $8
25#define t1 $9
26#define t2 $10
27#define t3 $11
28#define t4 $12
29#define t5 $13
30#define t6 $14
31#define t7 $15
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090032#endif
33
34#define ADDC(sum,reg) \
35 addu sum, reg; \
36 sltu v1, sum, reg; \
37 addu sum, v1
38
39#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
40 lw _t0, (offset + 0x00)(src); \
41 lw _t1, (offset + 0x04)(src); \
42 lw _t2, (offset + 0x08)(src); \
43 lw _t3, (offset + 0x0c)(src); \
44 ADDC(sum, _t0); \
45 ADDC(sum, _t1); \
46 ADDC(sum, _t2); \
47 ADDC(sum, _t3); \
48 lw _t0, (offset + 0x10)(src); \
49 lw _t1, (offset + 0x14)(src); \
50 lw _t2, (offset + 0x18)(src); \
51 lw _t3, (offset + 0x1c)(src); \
52 ADDC(sum, _t0); \
53 ADDC(sum, _t1); \
54 ADDC(sum, _t2); \
55 ADDC(sum, _t3); \
56
57/*
58 * a0: source address
59 * a1: length of the area to checksum
60 * a2: partial checksum
61 */
62
63#define src a0
64#define sum v0
65
66 .text
67 .set noreorder
68
69/* unknown src alignment and < 8 bytes to go */
70small_csumcpy:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090071 move a1, t2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090072
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090073 andi t0, a1, 4
74 beqz t0, 1f
75 andi t0, a1, 2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090076
77 /* Still a full word to go */
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090078 ulw t1, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090079 PTR_ADDIU src, 4
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090080 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090081
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900821: move t1, zero
83 beqz t0, 1f
84 andi t0, a1, 1
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090085
86 /* Still a halfword to go */
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090087 ulhu t1, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090088 PTR_ADDIU src, 2
89
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900901: beqz t0, 1f
91 sll t1, t1, 16
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090092
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090093 lbu t2, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090094 nop
95
96#ifdef __MIPSEB__
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090097 sll t2, t2, 8
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090098#endif
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090099 or t1, t2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900100
Atsushi Nemoto52ffe762006-12-08 01:04:31 +09001011: ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900102
103 /* fold checksum */
104 sll v1, sum, 16
105 addu sum, v1
106 sltu v1, sum, v1
107 srl sum, sum, 16
108 addu sum, v1
109
110 /* odd buffer alignment? */
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900111 beqz t7, 1f
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900112 nop
113 sll v1, sum, 8
114 srl sum, sum, 8
115 or sum, v1
116 andi sum, 0xffff
1171:
118 .set reorder
119 /* Add the passed partial csum. */
120 ADDC(sum, a2)
121 jr ra
122 .set noreorder
123
124/* ------------------------------------------------------------------------- */
125
126 .align 5
127LEAF(csum_partial)
128 move sum, zero
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900129 move t7, zero
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900130
131 sltiu t8, a1, 0x8
132 bnez t8, small_csumcpy /* < 8 bytes to copy */
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900133 move t2, a1
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900134
135 beqz a1, out
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900136 andi t7, src, 0x1 /* odd buffer? */
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900137
138hword_align:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900139 beqz t7, word_align
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900140 andi t8, src, 0x2
141
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900142 lbu t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900143 LONG_SUBU a1, a1, 0x1
144#ifdef __MIPSEL__
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900145 sll t0, t0, 8
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900146#endif
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900147 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900148 PTR_ADDU src, src, 0x1
149 andi t8, src, 0x2
150
151word_align:
152 beqz t8, dword_align
153 sltiu t8, a1, 56
154
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900155 lhu t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900156 LONG_SUBU a1, a1, 0x2
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900157 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900158 sltiu t8, a1, 56
159 PTR_ADDU src, src, 0x2
160
161dword_align:
162 bnez t8, do_end_words
163 move t8, a1
164
165 andi t8, src, 0x4
166 beqz t8, qword_align
167 andi t8, src, 0x8
168
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900169 lw t0, 0x00(src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900170 LONG_SUBU a1, a1, 0x4
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900171 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900172 PTR_ADDU src, src, 0x4
173 andi t8, src, 0x8
174
175qword_align:
176 beqz t8, oword_align
177 andi t8, src, 0x10
178
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900179 lw t0, 0x00(src)
180 lw t1, 0x04(src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900181 LONG_SUBU a1, a1, 0x8
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900182 ADDC(sum, t0)
183 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900184 PTR_ADDU src, src, 0x8
185 andi t8, src, 0x10
186
187oword_align:
188 beqz t8, begin_movement
189 LONG_SRL t8, a1, 0x7
190
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900191 lw t3, 0x08(src)
192 lw t4, 0x0c(src)
193 lw t0, 0x00(src)
194 lw t1, 0x04(src)
195 ADDC(sum, t3)
196 ADDC(sum, t4)
197 ADDC(sum, t0)
198 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900199 LONG_SUBU a1, a1, 0x10
200 PTR_ADDU src, src, 0x10
201 LONG_SRL t8, a1, 0x7
202
203begin_movement:
204 beqz t8, 1f
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900205 andi t2, a1, 0x40
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900206
207move_128bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900208 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
209 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
210 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
211 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900212 LONG_SUBU t8, t8, 0x01
213 bnez t8, move_128bytes
214 PTR_ADDU src, src, 0x80
215
2161:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900217 beqz t2, 1f
218 andi t2, a1, 0x20
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900219
220move_64bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900221 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
222 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900223 PTR_ADDU src, src, 0x40
224
2251:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900226 beqz t2, do_end_words
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900227 andi t8, a1, 0x1c
228
229move_32bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900230 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900231 andi t8, a1, 0x1c
232 PTR_ADDU src, src, 0x20
233
234do_end_words:
235 beqz t8, maybe_end_cruft
236 LONG_SRL t8, t8, 0x2
237
238end_words:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900239 lw t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900240 LONG_SUBU t8, t8, 0x1
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900241 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900242 bnez t8, end_words
243 PTR_ADDU src, src, 0x4
244
245maybe_end_cruft:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900246 andi t2, a1, 0x3
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900247
248small_memcpy:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900249 j small_csumcpy; move a1, t2 /* XXX ??? */
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900250 beqz t2, out
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900251 move a1, t2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900252
253end_bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900254 lb t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900255 LONG_SUBU a1, a1, 0x1
256 bnez a2, end_bytes
257 PTR_ADDU src, src, 0x1
258
259out:
260 jr ra
261 move v0, sum
262 END(csum_partial)