diff options
author | Jonas Gorski <jonas.gorski@gmail.com> | 2012-11-11 07:22:34 -0500 |
---|---|---|
committer | John Crispin <blogic@openwrt.org> | 2012-12-12 12:57:49 -0500 |
commit | ce8f0d0607bcad3ec0e8599be80353204427093e (patch) | |
tree | 9d5547b44b31086b498ac83045e3b3dc847836a2 /arch/mips | |
parent | 2da4c74dc3711275e82856e62884c99f7a45f541 (diff) |
MIPS: BCM63XX: fix nvram checksum calculation
The current checksum calculation code does nothing except checking that
the first byte of nvram is 0 without actually checking the checksum.
Implement the correct checksum calculation by calculating the crc32 with
the checksum field set to 0.
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Patchwork: http://patchwork.linux-mips.org/patch/4540
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/bcm63xx/nvram.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index b57a10db7c98..620611680839 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #define pr_fmt(fmt) "bcm63xx_nvram: " fmt | 11 | #define pr_fmt(fmt) "bcm63xx_nvram: " fmt |
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/crc32.h> | ||
14 | #include <linux/export.h> | 15 | #include <linux/export.h> |
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
16 | #include <linux/if_ether.h> | 17 | #include <linux/if_ether.h> |
@@ -40,23 +41,25 @@ static int mac_addr_used; | |||
40 | int __init bcm63xx_nvram_init(void *addr) | 41 | int __init bcm63xx_nvram_init(void *addr) |
41 | { | 42 | { |
42 | unsigned int check_len; | 43 | unsigned int check_len; |
43 | u8 *p; | 44 | u32 crc, expected_crc; |
44 | u32 val; | ||
45 | 45 | ||
46 | /* extract nvram data */ | 46 | /* extract nvram data */ |
47 | memcpy(&nvram, addr, sizeof(nvram)); | 47 | memcpy(&nvram, addr, sizeof(nvram)); |
48 | 48 | ||
49 | /* check checksum before using data */ | 49 | /* check checksum before using data */ |
50 | if (nvram.version <= 4) | 50 | if (nvram.version <= 4) { |
51 | check_len = offsetof(struct bcm963xx_nvram, checksum_old); | 51 | check_len = offsetof(struct bcm963xx_nvram, reserved3); |
52 | else | 52 | expected_crc = nvram.checksum_old; |
53 | nvram.checksum_old = 0; | ||
54 | } else { | ||
53 | check_len = sizeof(nvram); | 55 | check_len = sizeof(nvram); |
54 | val = 0; | 56 | expected_crc = nvram.checksum_high; |
55 | p = (u8 *)&nvram; | 57 | nvram.checksum_high = 0; |
58 | } | ||
59 | |||
60 | crc = crc32_le(~0, (u8 *)&nvram, check_len); | ||
56 | 61 | ||
57 | while (check_len--) | 62 | if (crc != expected_crc) |
58 | val += *p; | ||
59 | if (val) | ||
60 | return -EINVAL; | 63 | return -EINVAL; |
61 | 64 | ||
62 | return 0; | 65 | return 0; |