summaryrefslogtreecommitdiff
path: root/target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch')
-rw-r--r--target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch49
1 files changed, 49 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch b/target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch
new file mode 100644
index 0000000000..14d83394be
--- /dev/null
+++ b/target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch
@@ -0,0 +1,49 @@
+From fb1e2c8a1073297f4674ca90c7d533de5187d158 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <jogo@openwrt.org>
+Date: Sat, 9 Feb 2013 12:09:53 +0100
+Subject: [PATCH] MIPS: BCM63XX: handle huawei nvram layout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Huawei uses a custom nvram layout, extending it with additional 32
+byte field. This pushes also the checksum further, causing it to
+always fail the check.
+
+Add an additional crc check for handling this modified nvram layout
+based on the different size.
+
+Reported-by: Álvaro Fernández Rojas <noltari@gmail.com>
+Signed-off-by: Jonas Gorski <jogo@openwrt.org>
+---
+ arch/mips/bcm63xx/nvram.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/arch/mips/bcm63xx/nvram.c
++++ b/arch/mips/bcm63xx/nvram.c
+@@ -59,8 +59,24 @@ int __init bcm63xx_nvram_init(void *addr
+
+ crc = crc32_le(~0, (u8 *)&nvram, check_len);
+
+- if (crc != expected_crc)
++ if (crc != expected_crc) {
++ /* huawei uses a modified nvram that is 32 bytes longer */
++ if (nvram.version == 2 && !strncmp(nvram.name, "HW5", 3)) {
++ check_len += 32;
++
++ /* restore old value */
++ nvram.checksum_old = expected_crc;
++ expected_crc = *(u32 *)&nvram.reserved3[28];
++ /* zero the checksum field */
++ memset(&nvram.reserved3[28], 0, 4);
++
++ crc = crc32_le(~0, (u8 *)&nvram, check_len);
++
++ if (crc == expected_crc)
++ return 0;
++ }
+ return -EINVAL;
++ }
+
+ return 0;
+ }