blob: b04475d76f3c39a34e7ae00ab082c59fa8e1c7db [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
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090068 .align 5
69LEAF(csum_partial)
70 move sum, zero
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090071 move t7, zero
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090072
73 sltiu t8, a1, 0x8
74 bnez t8, small_csumcpy /* < 8 bytes to copy */
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090075 move t2, a1
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090076
Atsushi Nemoto773ff782006-12-08 01:04:45 +090077 andi t7, src, 0x1 /* odd buffer? */
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090078
79hword_align:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090080 beqz t7, word_align
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090081 andi t8, src, 0x2
82
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090083 lbu t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090084 LONG_SUBU a1, a1, 0x1
85#ifdef __MIPSEL__
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090086 sll t0, t0, 8
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090087#endif
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090088 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090089 PTR_ADDU src, src, 0x1
90 andi t8, src, 0x2
91
92word_align:
93 beqz t8, dword_align
94 sltiu t8, a1, 56
95
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090096 lhu t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090097 LONG_SUBU a1, a1, 0x2
Atsushi Nemoto52ffe762006-12-08 01:04:31 +090098 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +090099 sltiu t8, a1, 56
100 PTR_ADDU src, src, 0x2
101
102dword_align:
103 bnez t8, do_end_words
104 move t8, a1
105
106 andi t8, src, 0x4
107 beqz t8, qword_align
108 andi t8, src, 0x8
109
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900110 lw t0, 0x00(src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900111 LONG_SUBU a1, a1, 0x4
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900112 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900113 PTR_ADDU src, src, 0x4
114 andi t8, src, 0x8
115
116qword_align:
117 beqz t8, oword_align
118 andi t8, src, 0x10
119
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900120 lw t0, 0x00(src)
121 lw t1, 0x04(src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900122 LONG_SUBU a1, a1, 0x8
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900123 ADDC(sum, t0)
124 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900125 PTR_ADDU src, src, 0x8
126 andi t8, src, 0x10
127
128oword_align:
129 beqz t8, begin_movement
130 LONG_SRL t8, a1, 0x7
131
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900132 lw t3, 0x08(src)
133 lw t4, 0x0c(src)
134 lw t0, 0x00(src)
135 lw t1, 0x04(src)
136 ADDC(sum, t3)
137 ADDC(sum, t4)
138 ADDC(sum, t0)
139 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900140 LONG_SUBU a1, a1, 0x10
141 PTR_ADDU src, src, 0x10
142 LONG_SRL t8, a1, 0x7
143
144begin_movement:
145 beqz t8, 1f
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900146 andi t2, a1, 0x40
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900147
148move_128bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900149 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
150 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
151 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
152 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900153 LONG_SUBU t8, t8, 0x01
154 bnez t8, move_128bytes
155 PTR_ADDU src, src, 0x80
156
1571:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900158 beqz t2, 1f
159 andi t2, a1, 0x20
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900160
161move_64bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900162 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
163 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900164 PTR_ADDU src, src, 0x40
165
1661:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900167 beqz t2, do_end_words
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900168 andi t8, a1, 0x1c
169
170move_32bytes:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900171 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900172 andi t8, a1, 0x1c
173 PTR_ADDU src, src, 0x20
174
175do_end_words:
Atsushi Nemoto773ff782006-12-08 01:04:45 +0900176 beqz t8, small_csumcpy
177 andi t2, a1, 0x3
178 LONG_SRL t8, t8, 0x2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900179
180end_words:
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900181 lw t0, (src)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900182 LONG_SUBU t8, t8, 0x1
Atsushi Nemoto52ffe762006-12-08 01:04:31 +0900183 ADDC(sum, t0)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900184 bnez t8, end_words
185 PTR_ADDU src, src, 0x4
186
Atsushi Nemoto773ff782006-12-08 01:04:45 +0900187/* unknown src alignment and < 8 bytes to go */
188small_csumcpy:
189 move a1, t2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900190
Atsushi Nemoto773ff782006-12-08 01:04:45 +0900191 andi t0, a1, 4
192 beqz t0, 1f
193 andi t0, a1, 2
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900194
Atsushi Nemoto773ff782006-12-08 01:04:45 +0900195 /* Still a full word to go */
196 ulw t1, (src)
197 PTR_ADDIU src, 4
198 ADDC(sum, t1)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900199
Atsushi Nemoto773ff782006-12-08 01:04:45 +09002001: move t1, zero
201 beqz t0, 1f
202 andi t0, a1, 1
203
204 /* Still a halfword to go */
205 ulhu t1, (src)
206 PTR_ADDIU src, 2
207
2081: beqz t0, 1f
209 sll t1, t1, 16
210
211 lbu t2, (src)
212 nop
213
214#ifdef __MIPSEB__
215 sll t2, t2, 8
216#endif
217 or t1, t2
218
2191: ADDC(sum, t1)
220
221 /* fold checksum */
222 sll v1, sum, 16
223 addu sum, v1
224 sltu v1, sum, v1
225 srl sum, sum, 16
226 addu sum, v1
227
228 /* odd buffer alignment? */
229 beqz t7, 1f
230 nop
231 sll v1, sum, 8
232 srl sum, sum, 8
233 or sum, v1
234 andi sum, 0xffff
2351:
236 .set reorder
237 /* Add the passed partial csum. */
238 ADDC(sum, a2)
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900239 jr ra
Atsushi Nemoto773ff782006-12-08 01:04:45 +0900240 .set noreorder
Atsushi Nemoto0bcdda02006-12-04 00:42:59 +0900241 END(csum_partial)