| 193 |
193 |
}
|
| 194 |
194 |
|
| 195 |
195 |
#define _HAVE_ARCH_IPV6_CSUM
|
|
196 |
static __inline__ __sum16 csum_ipv6_unaligned_magic(struct in6_addr *saddr,
|
|
197 |
struct in6_addr *daddr,
|
|
198 |
__u32 len, unsigned short proto,
|
|
199 |
__wsum sum);
|
|
200 |
|
| 196 |
201 |
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
|
| 197 |
202 |
const struct in6_addr *daddr,
|
| 198 |
203 |
__u32 len, unsigned short proto,
|
| 199 |
204 |
__wsum sum)
|
| 200 |
205 |
{
|
|
206 |
if ((((__u32) saddr) | ((__u32) daddr)) & 3) {
|
|
207 |
/* Unaligned to word boundaries... */
|
|
208 |
return csum_ipv6_unaligned_magic(saddr, daddr, len, proto, sum);
|
|
209 |
}
|
| 201 |
210 |
__asm__(
|
| 202 |
211 |
" .set push # csum_ipv6_magic\n"
|
| 203 |
212 |
" .set noreorder \n"
|
| ... | ... | |
| 257 |
266 |
return csum_fold(sum);
|
| 258 |
267 |
}
|
| 259 |
268 |
|
|
269 |
static __inline__ __sum16 csum_ipv6_unaligned_magic(struct in6_addr *saddr,
|
|
270 |
struct in6_addr *daddr,
|
|
271 |
__u32 len, unsigned short proto,
|
|
272 |
__wsum sum)
|
|
273 |
{
|
|
274 |
__asm__(
|
|
275 |
" .set push # csum_ipv6_magic\n"
|
|
276 |
" .set noreorder \n"
|
|
277 |
" .set noat \n"
|
|
278 |
" addu %0, %5 # proto (long in network byte order)\n"
|
|
279 |
" sltu $1, %0, %5 \n"
|
|
280 |
" addu %0, $1 \n"
|
|
281 |
|
|
282 |
" addu %0, %6 # csum\n"
|
|
283 |
" sltu $1, %0, %6 \n"
|
|
284 |
" andi %12, %2, 3 # calc offset for saddr\n"
|
|
285 |
" sub %2, %2, %12 # align pointer\n"
|
|
286 |
" sll %12, %12, 8 # calc shift left amount\n"
|
|
287 |
" lui %13, 32 # calc shift right amount\n"
|
|
288 |
" srl %13, 16 \n"
|
|
289 |
" subi %13, %13, %12 \n"
|
|
290 |
" lw %1, 0(%2) # four words source address\n"
|
|
291 |
" lw %14, 4(%2) # and next word\n"
|
|
292 |
" sllv %1, %1, %12 # shift word1 left\n"
|
|
293 |
" srlv %14, %14, %13 # shift word2 right\n"
|
|
294 |
" or %1, %1, %14 # or together\n"
|
|
295 |
" addu %0, $1 \n"
|
|
296 |
" addu %0, %1 \n"
|
|
297 |
" sltu $1, %0, %1 \n"
|
|
298 |
|
|
299 |
" lw %1, 4(%2) \n"
|
|
300 |
" lw %14, 8(%2) \n"
|
|
301 |
" sllv %1, %1, %12 \n"
|
|
302 |
" srlv %14, %14, %13 \n"
|
|
303 |
" or %1, %1, %14 \n"
|
|
304 |
" addu %0, $1 \n"
|
|
305 |
" addu %0, %1 \n"
|
|
306 |
" sltu $1, %0, %1 \n"
|
|
307 |
|
|
308 |
" lw %1, 8(%2) \n"
|
|
309 |
" lw %14, 12(%2) \n"
|
|
310 |
" sllv %1, %1, %12 \n"
|
|
311 |
" srlv %14, %14, %13 \n"
|
|
312 |
" or %1, %1, %14 \n"
|
|
313 |
" addu %0, $1 \n"
|
|
314 |
" addu %0, %1 \n"
|
|
315 |
" sltu $1, %0, %1 \n"
|
|
316 |
|
|
317 |
" lw %1, 12(%2) \n"
|
|
318 |
" lw %14, 16(%2) \n"
|
|
319 |
" sllv %1, %1, %12 \n"
|
|
320 |
" srlv %14, %14, %13 \n"
|
|
321 |
" or %1, %1, %14 \n"
|
|
322 |
" addu %0, $1 \n"
|
|
323 |
" addu %0, %1 \n"
|
|
324 |
" sltu $1, %0, %1 \n"
|
|
325 |
|
|
326 |
" srl %12, %12, 8 # Undo damage to saddr\n"
|
|
327 |
" addu %2, %2, %12 \n"
|
|
328 |
|
|
329 |
" andi %12, %3, 3 # calc offset for daddr\n"
|
|
330 |
" sub %3, %3, %12 # align pointer\n"
|
|
331 |
" sll %12, %12, 8 # calc shift left amount\n"
|
|
332 |
" lui %13, 32 # calc shift right amount\n"
|
|
333 |
" srl %13, 16 \n"
|
|
334 |
" subi %13, %13, %12 \n"
|
|
335 |
" lw %1, 0(%3) # four words source address\n"
|
|
336 |
" lw %14, 4(%3) # and next word\n"
|
|
337 |
" sllv %1, %1, %12 # shift word1 left\n"
|
|
338 |
" srlv %14, %14, %13 # shift word2 right\n"
|
|
339 |
" or %1, %1, %14 # or together\n"
|
|
340 |
" addu %0, $1 \n"
|
|
341 |
" addu %0, %1 \n"
|
|
342 |
" sltu $1, %0, %1 \n"
|
|
343 |
|
|
344 |
" lw %1, 4(%3) \n"
|
|
345 |
" lw %14, 8(%3) \n"
|
|
346 |
" sllv %1, %1, %12 \n"
|
|
347 |
" srlv %14, %14, %13 \n"
|
|
348 |
" or %1, %1, %14 \n"
|
|
349 |
" addu %0, $1 \n"
|
|
350 |
" addu %0, %1 \n"
|
|
351 |
" sltu $1, %0, %1 \n"
|
|
352 |
|
|
353 |
" lw %1, 8(%3) \n"
|
|
354 |
" lw %14, 12(%3) \n"
|
|
355 |
" sllv %1, %1, %12 \n"
|
|
356 |
" srlv %14, %14, %13 \n"
|
|
357 |
" or %1, %1, %14 \n"
|
|
358 |
" addu %0, $1 \n"
|
|
359 |
" addu %0, %1 \n"
|
|
360 |
" sltu $1, %0, %1 \n"
|
|
361 |
|
|
362 |
" lw %1, 12(%3) \n"
|
|
363 |
" lw %14, 16(%3) \n"
|
|
364 |
" sllv %1, %1, %12 \n"
|
|
365 |
" srlv %14, %14, %13 \n"
|
|
366 |
" or %1, %1, %14 \n"
|
|
367 |
" addu %0, $1 \n"
|
|
368 |
" addu %0, %1 \n"
|
|
369 |
" sltu $1, %0, %1 \n"
|
|
370 |
|
|
371 |
" srl %12, %12, 8 # Undo damage to daddr\n"
|
|
372 |
" addu %3, %3, %12 \n"
|
|
373 |
|
|
374 |
" addu %0, $1 # Add final carry\n"
|
|
375 |
" set pop"
|
|
376 |
: "=r" (sum), "=r" (proto)
|
|
377 |
: "r" (saddr), "r" (daddr),
|
|
378 |
"" (htonl(len)), "1" (htonl(proto)), "r" (sum)
|
|
379 |
: "%12", "%13", "%14");
|
|
380 |
|
|
381 |
return csum_fold(sum);
|
|
382 |
}
|
|
383 |
|
| 260 |
384 |
#endif /* _ASM_CHECKSUM_H */
|