Messages in this thread | | | From | Mike Frysinger <> | Date | Fri, 19 Jun 2009 09:12:12 -0400 | Subject | Re: [PATCH 05/17] Blackfin: convert to generic checksum code |
| |
On Fri, Jun 19, 2009 at 08:33, Arnd Bergmann wrote: > On Friday 19 June 2009, Mike Frysinger wrote: >> On Fri, Jun 19, 2009 at 05:05, Arnd Bergmann wrote: >> > x86 and blackfin are both little-endian, so your variant is correct >> > there. They add the 0x01 to the low byte of the 16-bit word, while >> > on big-endian machines, you have to add it to the high byte. >> >> can we think of enough simple examples to through together an optional >> boot-time self test ? > > sounds like a good idea.
how about the attached
> lib/checksum.c: Fix another endianess bug
hrm, still not quite :/
the attached test code shows failures in every case -mike /* * Networking checksum self checks. * * Licensed under the GPL-2. */
#define pr_fmt(fmt) "csum-selftest: " fmt
#include <linux/kernel.h> #include <net/checksum.h>
extern unsigned short do_csum(const unsigned char *buff, int len);
struct do_csum_data { unsigned short ret; unsigned char *buf; int len; }; #define DO_CSUM_DATA(_num, _ret) \ { \ .ret = _ret, \ .buf = do_csum_data##_num, \ .len = ARRAY_SIZE(do_csum_data##_num), \ } static unsigned char __initdata do_csum_data1[] = { 0x20, }; static unsigned char __initdata do_csum_data2[] = { 0x0d, 0x0a, }; static unsigned char __initdata do_csum_data3[] = { 0xff, 0xfb, 0x01, }; static unsigned char __initdata do_csum_data5[] = { 0x67, 0x72, 0x5d, 0x0d, 0x00, }; static unsigned char __initdata do_csum_data7[] = { 0x20, 0x20, 0x20, 0x35, 0x37, 0x20, 0x20, }; static unsigned char __initdata do_csum_data255[] = { 0x20, 0x34, 0x34, 0x34, 0x20, 0x53, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x30, 0x35, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0x34, 0x20, 0x53, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x69, 0x6e, 0x65, 0x74, 0x64, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x30, 0x36, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0x33, 0x36, 0x20, 0x53, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x64, 0x20, 0x2d, 0x6e, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x30, 0x37, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x34, 0x33, 0x32, 0x20, 0x52, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x73, 0x62, 0x69, 0x6e, 0x2f, 0x6b, 0x6c, 0x6f, 0x67, 0x64, 0x20, 0x2d, 0x6e, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x30, 0x38, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x33, 0x32, 0x20, 0x53, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x64, 0x6f, 0x67, 0x64, 0x20, 0x2d, 0x66, 0x20, 0x2d, 0x73, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x30, 0x39, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x35, 0x36, 0x20, 0x52, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x74, 0x65, 0x6c, 0x6e, 0x65, 0x74, 0x64, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x31, 0x31, 0x30, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; static struct do_csum_data __initdata do_csum_data[] = { DO_CSUM_DATA(1, 0x0020), DO_CSUM_DATA(2, 0xfc00), DO_CSUM_DATA(3, 0x0a0d), DO_CSUM_DATA(5, 0x7fc4), DO_CSUM_DATA(7, 0x7597), DO_CSUM_DATA(255, 0x4f96), };
static int __init do_csum_selftest(void) { int i, ret; unsigned short tret;
ret = 0; for (i = 0; i < ARRAY_SIZE(do_csum_data); ++i) { tret = do_csum(do_csum_data[i].buf, do_csum_data[i].len); if (tret != do_csum_data[i].ret) { pr_err("%s: test %i: %#x != %#x: FAIL\n", __func__, i, tret, do_csum_data[i].ret); ret = 1; } }
return ret; }
static int __init csum_selftest_init(void) { int ret = do_csum_selftest();
if (!ret) pr_info("all tests passed!\n");
return 0; } module_init(csum_selftest_init);
| |