Use unsigned loads to avoid possible misscalculation of IP checksums. This
bug was instruced in
f761106cd728bcf65b7fe161b10221ee00cf7132 (lmo) /
ed99e2bc1dc5dc54eb5a019f4975562dbef20103 (kernel.org).
[Original fix by Atsushi. Improved instruction scheduling and fix for
unaligned unsigned load by me -- Ralf]
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
#ifdef USE_DOUBLE
#define LOAD ld
#ifdef USE_DOUBLE
#define LOAD ld
#define ADD daddu
#define NBYTES 8
#else
#define LOAD lw
#define ADD daddu
#define NBYTES 8
#else
#define LOAD lw
#define ADD addu
#define NBYTES 4
#define ADD addu
#define NBYTES 4
+#define ADDC32(sum,reg) \
+ .set push; \
+ .set noat; \
+ addu sum, reg; \
+ sltu v1, sum, reg; \
+ addu sum, v1; \
+ .set pop
+
#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
LOAD _t0, (offset + UNIT(0))(src); \
LOAD _t1, (offset + UNIT(1))(src); \
#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \
LOAD _t0, (offset + UNIT(0))(src); \
LOAD _t1, (offset + UNIT(1))(src); \
beqz t8, .Lqword_align
andi t8, src, 0x8
beqz t8, .Lqword_align
andi t8, src, 0x8
LONG_SUBU a1, a1, 0x4
ADDC(sum, t0)
PTR_ADDU src, src, 0x4
LONG_SUBU a1, a1, 0x4
ADDC(sum, t0)
PTR_ADDU src, src, 0x4
LONG_SRL t8, t8, 0x2
.Lend_words:
LONG_SRL t8, t8, 0x2
.Lend_words:
LONG_SUBU t8, t8, 0x1
ADDC(sum, t0)
.set reorder /* DADDI_WAR */
LONG_SUBU t8, t8, 0x1
ADDC(sum, t0)
.set reorder /* DADDI_WAR */
/* Still a full word to go */
ulw t1, (src)
PTR_ADDIU src, 4
/* Still a full word to go */
ulw t1, (src)
PTR_ADDIU src, 4
+#ifdef USE_DOUBLE
+ dsll t1, t1, 32 /* clear lower 32bit */
+#endif
ADDC(sum, t1)
1: move t1, zero
ADDC(sum, t1)
1: move t1, zero
1:
.set reorder
/* Add the passed partial csum. */
1:
.set reorder
/* Add the passed partial csum. */
jr ra
.set noreorder
END(csum_partial)
jr ra
.set noreorder
END(csum_partial)