Skip to contentSkip to conversation

MIPS: Add NVRAM support for bcm47xx devices

PATCH New Waldemar Brodkorb 1 participant 1 message Jun 8, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 MIPS: Add NVRAM support for bcm47xx devices

When trying to netboot a Linksys WRT54GS WLAN router, the bootup fails, because of following error message:

...

[    0.424000] b44: b44.c:v2.0
[    0.424000] b44: Invalid MAC address found in EEPROM
[    0.432000] b44 ssb0:1: Problem fetching invariants of chip,aborting
[    0.436000] b44: probe of ssb0:1 failed with error -22

...

The router uses a CFE bootloader, but most of the needed environment variables for network card initialization, are not available from CFE via printenv and even though not via cfe_getenv().
The required environment variables are saved in a special partition in flash memory. The attached patch implement nvram_getenv and enables bootup via NFS root on my router.

Most of the patch is extracted from the OpenWrt subversion repository and stripped down and cleaned up to just fix this issue.

---
 arch/mips/bcm47xx/Makefile                 |    2 +-
 arch/mips/bcm47xx/nvram.c                  |  100 ++++++++++++++++++++++++++++
 arch/mips/bcm47xx/setup.c                  |   39 ++++++++----
 arch/mips/include/asm/mach-bcm47xx/nvram.h |   34 ++++++++++
 4 files changed, 162 insertions(+), 13 deletions(-)
 create mode 100644 arch/mips/bcm47xx/nvram.c
 create mode 100644 arch/mips/include/asm/mach-bcm47xx/nvram.h
arch/mips/bcm47xx/Makefile +1 -1
index 35294b1..7465e8a 100644
@@ -3,4 +3,4 @@
 # under Linux.
 #
 
-obj-y := gpio.o irq.o prom.o serial.o setup.o time.o wgt634u.o
+obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
arch/mips/bcm47xx/nvram.c new file +100 -0

100 lines not on this page · raw message

arch/mips/bcm47xx/setup.c +27 -12
index d442e11..b1aee33 100644
@@ -1,8 +1,8 @@
 /*
  *  Copyright (C) 2004 Florian Schirmer <[email protected]>
- *  Copyright (C) 2005 Waldemar Brodkorb <[email protected]>
  *  Copyright (C) 2006 Felix Fietkau <[email protected]>
  *  Copyright (C) 2006 Michael Buesch <[email protected]>
+ *  Copyright (C) 2010 Waldemar Brodkorb <[email protected]>
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -33,6 +33,7 @@
 #include <asm/time.h>
 #include <bcm47xx.h>
 #include <asm/fw/cfe/cfe_api.h>
+#include <asm/mach-bcm47xx/nvram.h>
 
 struct ssb_bus ssb_bcm47xx;
 EXPORT_SYMBOL(ssb_bcm47xx);
@@ -81,28 +82,42 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
 	/* Fill boardinfo structure */
 	memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo));
 
-	if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0)
+	if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0)
 		iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-	if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0)
+	if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("boardtype", buf, sizeof(buf)) >= 0)
 		iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0);
-	if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0)
+	if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
 		iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 
 	/* Fill sprom structure */
 	memset(&(iv->sprom), 0, sizeof(struct ssb_sprom));
 	iv->sprom.revision = 3;
 
-	if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+	if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
 		str2eaddr(buf, iv->sprom.et0mac);
-	if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+
+	if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
 		str2eaddr(buf, iv->sprom.et1mac);
-	if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
-		iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 10);
-	if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
-		iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 10);
-	if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
+
+	if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0)
+		iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0);
+
+	if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0)
+		iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0);
+
+	if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0)
 		iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10);
-	if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
+
+	if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 ||
+	    nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0)
 		iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10);
 
 	return 0;
arch/mips/include/asm/mach-bcm47xx/nvram.h new file +34 -0
new file mode 100644
index 0000000..b8b5fe8
@@ -0,0 +1,34 @@
+/*
+ *  Copyright (C) 2005, Broadcom Corporation
+ *  Copyright (C) 2006, Felix Fietkau <[email protected]>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef __NVRAM_H
+#define __NVRAM_H
+
+struct nvram_header {
+	u32 magic;
+	u32 len;
+	u32 crc_ver_init;	/* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+	u32 config_refresh;	/* 0:15 sdram_config, 16:31 sdram_refresh */
+	u32 config_ncdl;	/* ncdl values for memc */
+};
+
+#define NVRAM_HEADER		0x48534C46	/* 'FLSH' */
+#define NVRAM_VERSION		1
+#define NVRAM_HEADER_SIZE	20
+#define NVRAM_SPACE		0x8000
+
+#define FLASH_MIN		0x00020000	/* Minimum flash size */
+
+#define NVRAM_MAX_VALUE_LEN 255
+#define NVRAM_MAX_PARAM_LEN 64
+
+int nvram_getenv(char *name, char *val, size_t val_len);
+
+#endif
Signature · 1 line
1.7.0.4