Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Jonas Gorski and committed by
John Crispin
ce8f0d06 2da4c74d

+13 -10
+13 -10
arch/mips/bcm63xx/nvram.c
··· 11 11 #define pr_fmt(fmt) "bcm63xx_nvram: " fmt 12 12 13 13 #include <linux/init.h> 14 + #include <linux/crc32.h> 14 15 #include <linux/export.h> 15 16 #include <linux/kernel.h> 16 17 #include <linux/if_ether.h> ··· 41 40 int __init bcm63xx_nvram_init(void *addr) 42 41 { 43 42 unsigned int check_len; 44 - u8 *p; 45 - u32 val; 43 + u32 crc, expected_crc; 46 44 47 45 /* extract nvram data */ 48 46 memcpy(&nvram, addr, sizeof(nvram)); 49 47 50 48 /* check checksum before using data */ 51 - if (nvram.version <= 4) 52 - check_len = offsetof(struct bcm963xx_nvram, checksum_old); 53 - else 49 + if (nvram.version <= 4) { 50 + check_len = offsetof(struct bcm963xx_nvram, reserved3); 51 + expected_crc = nvram.checksum_old; 52 + nvram.checksum_old = 0; 53 + } else { 54 54 check_len = sizeof(nvram); 55 - val = 0; 56 - p = (u8 *)&nvram; 55 + expected_crc = nvram.checksum_high; 56 + nvram.checksum_high = 0; 57 + } 57 58 58 - while (check_len--) 59 - val += *p; 60 - if (val) 59 + crc = crc32_le(~0, (u8 *)&nvram, check_len); 60 + 61 + if (crc != expected_crc) 61 62 return -EINVAL; 62 63 63 64 return 0;