summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm63xx/patches-3.8/119-MIPS-BCM63XX-handle-huawei-nvram-layout.patch
blob: 14d83394be6665b848a373ed4aa4059e0608790b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;
 }