From: wbx <wbx@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Tue, 29 Nov 2005 01:37:34 +0000 (+0000)
Subject: add new flash map driver, some minor system code cleanup
X-Git-Url: https://git.rohieb.name/openwrt.git/commitdiff_plain/aa14640dabf93ba68395cb1a0105abb3431b36d4

add new flash map driver, some minor system code cleanup

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@2564 3c298f89-4303-0410-b956-a3cf2f4a3e73
---

diff --git a/openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch b/openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch
index 8f4531576..923356f61 100644
--- a/openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch
+++ b/openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch
@@ -1,89 +1,6 @@
-diff -Nur linux-2.6.12.5/arch/mips/Kconfig linux-2.6.12.5-brcm/arch/mips/Kconfig
---- linux-2.6.12.5/arch/mips/Kconfig	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/Kconfig	2005-09-16 10:29:18.135597872 +0200
-@@ -40,6 +40,15 @@
- 	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
- 	 Olivetti M700-10 workstations.
- 
-+config BCM947XX
-+	bool "Support for BCM947xx based boards"
-+	select DMA_NONCOHERENT
-+	select HW_HAS_PCI
-+	select IRQ_CPU
-+	select CPU_LITTLE_ENDIAN
-+	help
-+	 Support for BCM947xx based boards
-+	 
- config ACER_PICA_61
- 	bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
- 	depends on MACH_JAZZ && EXPERIMENTAL
-@@ -974,7 +983,7 @@
- 
- config CPU_LITTLE_ENDIAN
- 	bool "Generate little endian code"
--	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
-+	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA || BCM947XX
- 	default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
- 	help
- 	  Some MIPS machines can be configured for either little or big endian
-diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefile
---- linux-2.6.12.5/arch/mips/Makefile	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/Makefile	2005-09-16 10:29:18.137597568 +0200
-@@ -79,7 +79,7 @@
- cflags-y			+= -I $(TOPDIR)/include/asm/gcc
- cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
- cflags-y			+= $(call cc-option, -finline-limit=100000)
--LDFLAGS_vmlinux			+= -G 0 -static -n
-+LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
- MODFLAGS			+= -mlong-calls
- 
- cflags-$(CONFIG_SB1XXX_CORELIS)	+= -mno-sched-prolog -fno-omit-frame-pointer
-@@ -170,6 +170,7 @@
- cflags-$(CONFIG_CPU_MIPS32)	+= \
- 			$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
- 			-Wa,--trap
-+cflags-$(CONFIG_CPU_MIPS32)	+= -Wa,--trap
- 
- cflags-$(CONFIG_CPU_MIPS64)	+= \
- 			$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
-@@ -618,6 +619,14 @@
- load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
- 
- #
-+# Broadcom BCM47XX boards
-+#
-+core-$(CONFIG_BCM947XX)		+= arch/mips/bcm947xx/ arch/mips/bcm947xx/broadcom/
-+cflags-$(CONFIG_BCM947XX)	+= -Iarch/mips/bcm947xx/include
-+load-$(CONFIG_BCM947XX)		:= 0xffffffff80001000
-+
-+
-+#
- # SNI RM200 PCI
- #
- core-$(CONFIG_SNI_RM200_PCI)	+= arch/mips/sni/
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile
---- linux-2.6.12.5/arch/mips/bcm947xx/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile	2005-09-16 10:29:18.149595744 +0200
-@@ -0,0 +1,6 @@
-+#
-+# Makefile for the BCM47xx specific kernel interface routines
-+# under Linux.
-+#
-+
-+obj-y := irq.o int-handler.o prom.o setup.o time.o
-diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile
---- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile	2005-09-16 10:29:18.149595744 +0200
-@@ -0,0 +1,6 @@
-+#
-+# Makefile for the BCM47xx specific kernel interface routines
-+# under Linux.
-+#
-+
-+obj-y   := sbutils.o linux_osl.o bcmsrom.o bcmutils.o sbmips.o sbpci.o hnddma.o
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c	2005-09-16 10:29:18.150595592 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmsrom.c	2005-11-07 01:12:51.811809000 +0100
 @@ -0,0 +1,685 @@
 +/*
 + *  Misc useful routines to access NIC SROM
@@ -772,7 +689,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c	2005-09-16 10:29:18.164593464 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/bcmutils.c	2005-11-07 01:12:51.815809250 +0100
 @@ -0,0 +1,691 @@
 +/*
 + * Misc useful OS-independent routines.
@@ -1467,7 +1384,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c	2005-09-16 10:29:18.165593312 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/hnddma.c	2005-11-07 01:12:51.815809250 +0100
 @@ -0,0 +1,763 @@
 +/*
 + * Generic Broadcom Home Networking Division (HND) DMA module.
@@ -2234,7 +2151,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brc
 +}
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c	2005-09-16 10:29:18.166593160 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/linux_osl.c	2005-11-07 01:12:51.815809250 +0100
 @@ -0,0 +1,420 @@
 +/*
 + * Linux OS Independent Layer
@@ -2509,156 +2426,1129 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-
 +#endif
 +}
 +
-+uint
-+osl_getcycles(void)
-+{
-+	uint cycles;
++uint
++osl_getcycles(void)
++{
++	uint cycles;
++
++#if defined(mips)
++	cycles = read_c0_count() * 2;
++#elif defined(__i386__)
++	rdtscl(cycles);
++#else
++	cycles = 0;
++#endif
++	return cycles;
++}
++
++void *
++osl_reg_map(uint32 pa, uint size)
++{
++	return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
++}
++
++void
++osl_reg_unmap(void *va)
++{
++	iounmap(va);
++}
++
++int
++osl_busprobe(uint32 *val, uint32 addr)
++{
++#ifdef mips
++	return get_dbe(*val, (uint32*)addr);
++#else
++	*val = readl(addr);
++	return 0;
++#endif
++}
++
++void*
++osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
++{
++	return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
++}
++
++void
++osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
++{
++	pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
++}
++
++uint
++osl_dma_map(void *dev, void *va, uint size, int direction)
++{
++	int dir;
++
++	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
++	return (pci_map_single(dev, va, size, dir));
++}
++
++void
++osl_dma_unmap(void *dev, uint pa, uint size, int direction)
++{
++	int dir;
++
++	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
++	pci_unmap_single(dev, (uint32)pa, size, dir);
++}
++
++void
++osl_delay(uint usec)
++{
++	udelay(usec);
++}
++
++uchar*
++osl_pktdata(void *drv, void *skb)
++{
++	return (((struct sk_buff*)skb)->data);
++}
++
++uint
++osl_pktlen(void *drv, void *skb)
++{
++	return (((struct sk_buff*)skb)->len);
++}
++
++void*
++osl_pktnext(void *drv, void *skb)
++{
++	return (((struct sk_buff*)skb)->next);
++}
++
++void
++osl_pktsetnext(void *skb, void *x)
++{
++	((struct sk_buff*)skb)->next = (struct sk_buff*)x;
++}
++
++void
++osl_pktsetlen(void *drv, void *skb, uint len)
++{
++	__skb_trim((struct sk_buff*)skb, len);
++}
++
++uchar*
++osl_pktpush(void *drv, void *skb, int bytes)
++{
++	return (skb_push((struct sk_buff*)skb, bytes));
++}
++
++uchar*
++osl_pktpull(void *drv, void *skb, int bytes)
++{
++	return (skb_pull((struct sk_buff*)skb, bytes));
++}
++
++void*
++osl_pktdup(void *drv, void *skb)
++{
++	return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
++}
++
++void*
++osl_pktcookie(void *skb)
++{
++	return ((void*)((struct sk_buff*)skb)->csum);
++}
++
++void
++osl_pktsetcookie(void *skb, void *x)
++{
++	((struct sk_buff*)skb)->csum = (uint)x;
++}
++
++void*
++osl_pktlink(void *skb)
++{
++	return (((struct sk_buff*)skb)->prev);
++}
++
++void
++osl_pktsetlink(void *skb, void *x)
++{
++	((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
++}
++
++#endif
+diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile
+--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/Makefile	2005-11-19 14:16:38.941631500 +0100
+@@ -0,0 +1,7 @@
++#
++# Makefile for the BCM47xx specific kernel interface routines
++# under Linux.
++#
++
++obj-y   := sbutils.o linux_osl.o bcmsrom.o bcmutils.o sbmips.o sbpci.o hnddma.o
++#obj-y   := nvram.o nvram_linux.o
+diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram.c
+--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram.c	2005-11-19 02:28:26.438059500 +0100
+@@ -0,0 +1,321 @@
++/*
++ * NVRAM variable manipulation (common)
++ *
++ * Copyright 2004, Broadcom Corporation
++ * All Rights Reserved.
++ * 
++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
++ *
++ * $Id$
++ */
++
++#include <typedefs.h>
++#include <osl.h>
++#include <bcmendian.h>
++#include <bcmnvram.h>
++#include <bcmutils.h>
++#include <sbsdram.h>
++
++extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value);
++extern void BCMINIT(_nvram_free)(struct nvram_tuple *t);
++extern int BCMINIT(_nvram_read)(void *buf);
++
++char * BCMINIT(_nvram_get)(const char *name);
++int BCMINIT(_nvram_set)(const char *name, const char *value);
++int BCMINIT(_nvram_unset)(const char *name);
++int BCMINIT(_nvram_getall)(char *buf, int count);
++int BCMINIT(_nvram_commit)(struct nvram_header *header);
++int BCMINIT(_nvram_init)(void);
++void BCMINIT(_nvram_exit)(void);
++
++static struct nvram_tuple * BCMINITDATA(nvram_hash)[257];
++static struct nvram_tuple * nvram_dead;
++
++/* Free all tuples. Should be locked. */
++static void  
++BCMINITFN(nvram_free)(void)
++{
++	uint i;
++	struct nvram_tuple *t, *next;
++
++	/* Free hash table */
++	for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
++		for (t = BCMINIT(nvram_hash)[i]; t; t = next) {
++			next = t->next;
++			BCMINIT(_nvram_free)(t);
++		}
++		BCMINIT(nvram_hash)[i] = NULL;
++	}
++
++	/* Free dead table */
++	for (t = nvram_dead; t; t = next) {
++		next = t->next;
++		BCMINIT(_nvram_free)(t);
++	}
++	nvram_dead = NULL;
++
++	/* Indicate to per-port code that all tuples have been freed */
++	BCMINIT(_nvram_free)(NULL);
++}
++
++/* String hash */
++static INLINE uint
++hash(const char *s)
++{
++	uint hash = 0;
++
++	while (*s)
++		hash = 31 * hash + *s++;
++
++	return hash;
++}
++
++/* (Re)initialize the hash table. Should be locked. */
++static int 
++BCMINITFN(nvram_rehash)(struct nvram_header *header)
++{
++	char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq;
++
++	/* (Re)initialize hash table */
++	BCMINIT(nvram_free)();
++
++	/* Parse and set "name=value\0 ... \0\0" */
++	name = (char *) &header[1];
++	end = (char *) header + NVRAM_SPACE - 2;
++	end[0] = end[1] = '\0';
++	for (; *name; name = value + strlen(value) + 1) {
++		if (!(eq = strchr(name, '=')))
++			break;
++		*eq = '\0';
++		value = eq + 1;
++		BCMINIT(_nvram_set)(name, value);
++		*eq = '=';
++	}
++
++	/* Set special SDRAM parameters */
++	if (!BCMINIT(_nvram_get)("sdram_init")) {
++		sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16));
++		BCMINIT(_nvram_set)("sdram_init", buf);
++	}
++	if (!BCMINIT(_nvram_get)("sdram_config")) {
++		sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff));
++		BCMINIT(_nvram_set)("sdram_config", buf);
++	}
++	if (!BCMINIT(_nvram_get)("sdram_refresh")) {
++		sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff));
++		BCMINIT(_nvram_set)("sdram_refresh", buf);
++	}
++	if (!BCMINIT(_nvram_get)("sdram_ncdl")) {
++		sprintf(buf, "0x%08X", header->config_ncdl);
++		BCMINIT(_nvram_set)("sdram_ncdl", buf);
++	}
++
++	return 0;
++}
++
++/* Get the value of an NVRAM variable. Should be locked. */
++char * 
++BCMINITFN(_nvram_get)(const char *name)
++{
++	uint i;
++	struct nvram_tuple *t;
++	char *value;
++
++	if (!name)
++		return NULL;
++
++	/* Hash the name */
++	i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
++
++	/* Find the associated tuple in the hash table */
++	for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next);
++
++	value = t ? t->value : NULL;
++
++	return value;
++}
++
++/* Get the value of an NVRAM variable. Should be locked. */
++int 
++BCMINITFN(_nvram_set)(const char *name, const char *value)
++{
++	uint i;
++	struct nvram_tuple *t, *u, **prev;
++
++	/* Hash the name */
++	i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
++
++	/* Find the associated tuple in the hash table */
++	for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
++
++	/* (Re)allocate tuple */
++	if (!(u = BCMINIT(_nvram_realloc)(t, name, value)))
++		return -12; /* -ENOMEM */
++
++	/* Value reallocated */
++	if (t && t == u)
++		return 0;
++
++	/* Move old tuple to the dead table */
++	if (t) {
++		*prev = t->next;
++		t->next = nvram_dead;
++		nvram_dead = t;
++	}
++
++	/* Add new tuple to the hash table */
++	u->next = BCMINIT(nvram_hash)[i];
++	BCMINIT(nvram_hash)[i] = u;
++
++	return 0;
++}
++
++/* Unset the value of an NVRAM variable. Should be locked. */
++int 
++BCMINITFN(_nvram_unset)(const char *name)
++{
++	uint i;
++	struct nvram_tuple *t, **prev;
++
++	if (!name)
++		return 0;
++
++	/* Hash the name */
++	i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash));
++
++	/* Find the associated tuple in the hash table */
++	for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev);
++
++	/* Move it to the dead table */
++	if (t) {
++		*prev = t->next;
++		t->next = nvram_dead;
++		nvram_dead = t;
++	}
++
++	return 0;
++}
++
++/* Get all NVRAM variables. Should be locked. */
++int 
++BCMINITFN(_nvram_getall)(char *buf, int count)
++{
++	uint i;
++	struct nvram_tuple *t;
++	int len = 0;
++
++	bzero(buf, count);
++
++	/* Write name=value\0 ... \0\0 */
++	for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
++		for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
++			if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1))
++				len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1;
++			else
++				break;
++		}
++	}
++
++	return 0;
++}
++
++/* Regenerate NVRAM. Should be locked. */
++int
++BCMINITFN(_nvram_commit)(struct nvram_header *header)
++{
++	char *init, *config, *refresh, *ncdl;
++	char *ptr, *end;
++	int i;
++	struct nvram_tuple *t;
++	struct nvram_header tmp;
++	uint8 crc;
++
++	/* Regenerate header */
++	header->magic = NVRAM_MAGIC;
++	header->crc_ver_init = (NVRAM_VERSION << 8);
++	if (!(init = BCMINIT(_nvram_get)("sdram_init")) ||
++	    !(config = BCMINIT(_nvram_get)("sdram_config")) ||
++	    !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) ||
++	    !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) {
++		header->crc_ver_init |= SDRAM_INIT << 16;
++		header->config_refresh = SDRAM_CONFIG;
++		header->config_refresh |= SDRAM_REFRESH << 16;
++		header->config_ncdl = 0;
++	} else {
++		header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16;
++		header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff;
++		header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16;
++		header->config_ncdl = bcm_strtoul(ncdl, NULL, 0);
++	}
++
++	/* Clear data area */
++	ptr = (char *) header + sizeof(struct nvram_header);
++	bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header));
++
++	/* Leave space for a double NUL at the end */
++	end = (char *) header + NVRAM_SPACE - 2;
++
++	/* Write out all tuples */
++	for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) {
++		for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) {
++			if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
++				break;
++			ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
++		}
++	}
++
++	/* End with a double NUL */
++	ptr += 2;
++
++	/* Set new length */
++	header->len = ROUNDUP(ptr - (char *) header, 4);
++
++	/* Little-endian CRC8 over the last 11 bytes of the header */
++	tmp.crc_ver_init = htol32(header->crc_ver_init);
++	tmp.config_refresh = htol32(header->config_refresh);
++	tmp.config_ncdl = htol32(header->config_ncdl);
++	crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE);
++
++	/* Continue CRC8 over data bytes */
++	crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc);
++
++	/* Set new CRC8 */
++	header->crc_ver_init |= crc;
++
++	/* Reinitialize hash table */
++	return BCMINIT(nvram_rehash)(header);
++}
++
++/* Initialize hash table. Should be locked. */
++int 
++BCMINITFN(_nvram_init)(void)
++{
++	struct nvram_header *header;
++	int ret;
++	void *osh;
++
++	/* get kernel osl handler */
++	osh = osl_attach(NULL);
++
++	if (!(header = (struct nvram_header *) MALLOC(osh, NVRAM_SPACE))) {
++		printf("nvram_init: out of memory, malloced %d bytes\n", MALLOCED(osh));
++		return -12; /* -ENOMEM */
++	}
++
++	if ((ret = BCMINIT(_nvram_read)(header)) == 0 &&
++	    header->magic == NVRAM_MAGIC)
++		BCMINIT(nvram_rehash)(header);
++
++	MFREE(osh, header, NVRAM_SPACE);
++	return ret;
++}
++
++/* Free hash table. Should be locked. */
++void 
++BCMINITFN(_nvram_exit)(void)
++{
++	BCMINIT(nvram_free)();
++}
+diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram_linux.c
+--- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/nvram_linux.c	2005-11-19 02:28:26.438059500 +0100
+@@ -0,0 +1,633 @@
++/*
++ * NVRAM variable manipulation (Linux kernel half)
++ *
++ * Copyright 2005, Broadcom Corporation
++ * All Rights Reserved.
++ * 
++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
++ *
++ * $Id$
++ */
++
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/slab.h>
++#include <linux/bootmem.h>
++#include <linux/wrapper.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
++#include <linux/mtd/mtd.h>
++#include <asm/addrspace.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#include <typedefs.h>
++#include <bcmendian.h>
++#include <bcmnvram.h>
++#include <bcmutils.h>
++#include <sbconfig.h>
++#include <sbchipc.h>
++#include <sbutils.h>
++#include <sbmips.h>
++#include <sflash.h>
++
++/* In BSS to minimize text size and page aligned so it can be mmap()-ed */
++static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE)));
++
++#ifdef MODULE
++
++#define early_nvram_get(name) nvram_get(name)
++
++#else /* !MODULE */
++
++/* Global SB handle */
++extern void *bcm947xx_sbh;
++extern spinlock_t bcm947xx_sbh_lock;
++
++/* Convenience */
++#define sbh bcm947xx_sbh
++#define sbh_lock bcm947xx_sbh_lock
++#define KB * 1024
++#define MB * 1024 * 1024
++
++/* Probe for NVRAM header */
++static void __init
++early_nvram_init(void)
++{
++	struct nvram_header *header;
++	chipcregs_t *cc;
++	struct sflash *info = NULL;
++	int i;
++	uint32 base, off, lim;
++	u32 *src, *dst;
++
++	if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) {
++		base = KSEG1ADDR(SB_FLASH2);
++		switch (readl(&cc->capabilities) & CAP_FLASH_MASK) {
++		case PFLASH:
++			lim = SB_FLASH2_SZ;
++			break;
++
++		case SFLASH_ST:
++		case SFLASH_AT:
++			if ((info = sflash_init(cc)) == NULL)
++				return;
++			lim = info->size;
++			break;
++
++		case FLASH_NONE:
++		default:
++			return;
++		}
++	} else {
++		/* extif assumed, Stop at 4 MB */
++		base = KSEG1ADDR(SB_FLASH1);
++		lim = SB_FLASH1_SZ;
++	}
++
++	off = FLASH_MIN;
++	while (off <= lim) {
++		/* Windowed flash access */
++		header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
++		if (header->magic == NVRAM_MAGIC)
++			goto found;
++		off <<= 1;
++	}
++
++	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
++	header = (struct nvram_header *) KSEG1ADDR(base + 4 KB);
++	if (header->magic == NVRAM_MAGIC)
++		goto found;
++	
++	header = (struct nvram_header *) KSEG1ADDR(base + 1 KB);
++	if (header->magic == NVRAM_MAGIC)
++		goto found;
++	
++	printk("early_nvram_init: NVRAM not found\n");
++	return;
++
++found:
++	src = (u32 *) header;
++	dst = (u32 *) nvram_buf;
++	for (i = 0; i < sizeof(struct nvram_header); i += 4)
++		*dst++ = *src++;
++	for (; i < header->len && i < NVRAM_SPACE; i += 4)
++		*dst++ = ltoh32(*src++);
++}
++
++/* Early (before mm or mtd) read-only access to NVRAM */
++static char * __init
++early_nvram_get(const char *name)
++{
++	char *var, *value, *end, *eq;
++
++	if (!name)
++		return NULL;
++
++	/* Too early? */
++	if (sbh == NULL)
++		return NULL;
++
++	if (!nvram_buf[0])
++		early_nvram_init();
++
++	/* Look for name=value and return value */
++	var = &nvram_buf[sizeof(struct nvram_header)];
++	end = nvram_buf + sizeof(nvram_buf) - 2;
++	end[0] = end[1] = '\0';
++	for (; *var; var = value + strlen(value) + 1) {
++		if (!(eq = strchr(var, '=')))
++			break;
++		value = eq + 1;
++		if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
++			return value;
++	}
++
++	return NULL;
++}
++
++#endif /* !MODULE */
++
++extern char * _nvram_get(const char *name);
++extern int _nvram_set(const char *name, const char *value);
++extern int _nvram_unset(const char *name);
++extern int _nvram_getall(char *buf, int count);
++extern int _nvram_commit(struct nvram_header *header);
++extern int _nvram_init(void);
++extern void _nvram_exit(void);
++
++/* Globals */
++static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED;
++static struct semaphore nvram_sem;
++static unsigned long nvram_offset = 0;
++static int nvram_major = -1;
++static devfs_handle_t nvram_handle = NULL;
++static struct mtd_info *nvram_mtd = NULL;
++
++int
++_nvram_read(char *buf)
++{
++	struct nvram_header *header = (struct nvram_header *) buf;
++	size_t len;
++
++	if (!nvram_mtd ||
++	    MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) ||
++	    len != NVRAM_SPACE ||
++	    header->magic != NVRAM_MAGIC) {
++		/* Maybe we can recover some data from early initialization */
++		memcpy(buf, nvram_buf, NVRAM_SPACE);
++	}
++
++	return 0;
++}
++
++struct nvram_tuple *
++_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value)
++{
++	if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE)
++		return NULL;
++
++	if (!t) {
++		if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC)))
++			return NULL;
++
++		/* Copy name */
++		t->name = (char *) &t[1];
++		strcpy(t->name, name);
++
++		t->value = NULL;
++	}
++
++	/* Copy value */
++	if (!t->value || strcmp(t->value, value)) {
++		t->value = &nvram_buf[nvram_offset];
++		strcpy(t->value, value);
++		nvram_offset += strlen(value) + 1;
++	}
++
++	return t;
++}
++
++void
++_nvram_free(struct nvram_tuple *t)
++{
++	if (!t)
++		nvram_offset = 0;
++	else
++		kfree(t);
++}
++
++int
++nvram_set(const char *name, const char *value)
++{
++	unsigned long flags;
++	int ret;
++	struct nvram_header *header;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++	if ((ret = _nvram_set(name, value))) {
++		/* Consolidate space and try again */
++		if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) {
++			if (_nvram_commit(header) == 0)
++				ret = _nvram_set(name, value);
++			kfree(header);
++		}
++	}
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return ret;
++}
++
++char *
++real_nvram_get(const char *name)
++{
++	unsigned long flags;
++	char *value;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++	value = _nvram_get(name);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return value;
++}
++
++char *
++nvram_get(const char *name)
++{
++	if (nvram_major >= 0)
++		return real_nvram_get(name);
++	else
++		return early_nvram_get(name);
++}
++
++int
++nvram_unset(const char *name)
++{
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++	ret = _nvram_unset(name);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return ret;
++}
++
++static void
++erase_callback(struct erase_info *done)
++{
++	wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
++	wake_up(wait_q);
++}
++
++int
++nvram_commit(void)
++{
++	char *buf;
++	size_t erasesize, len;
++	unsigned int i;
++	int ret;
++	struct nvram_header *header;
++	unsigned long flags;
++	u_int32_t offset;
++	DECLARE_WAITQUEUE(wait, current);
++	wait_queue_head_t wait_q;
++	struct erase_info erase;
++
++	if (!nvram_mtd) {
++		printk("nvram_commit: NVRAM not found\n");
++		return -ENODEV;
++	}
++
++	if (in_interrupt()) {
++		printk("nvram_commit: not committing in interrupt\n");
++		return -EINVAL;
++	}
++
++	/* Backup sector blocks to be erased */
++	erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize);
++	if (!(buf = kmalloc(erasesize, GFP_KERNEL))) {
++		printk("nvram_commit: out of memory\n");
++		return -ENOMEM;
++	}
++
++	down(&nvram_sem);
++
++	if ((i = erasesize - NVRAM_SPACE) > 0) {
++		offset = nvram_mtd->size - erasesize;
++		len = 0;
++		ret = MTD_READ(nvram_mtd, offset, i, &len, buf);
++		if (ret || len != i) {
++			printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i);
++			ret = -EIO;
++			goto done;
++		}
++		header = (struct nvram_header *)(buf + i);
++	} else {
++		offset = nvram_mtd->size - NVRAM_SPACE;
++		header = (struct nvram_header *)buf;
++	}
++
++	/* Regenerate NVRAM */
++	spin_lock_irqsave(&nvram_lock, flags);
++	ret = _nvram_commit(header);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++	if (ret)
++		goto done;
++
++	/* Erase sector blocks */
++	init_waitqueue_head(&wait_q);
++	for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) {
++		erase.mtd = nvram_mtd;
++		erase.addr = offset;
++		erase.len = nvram_mtd->erasesize;
++		erase.callback = erase_callback;
++		erase.priv = (u_long) &wait_q;
++
++		set_current_state(TASK_INTERRUPTIBLE);
++		add_wait_queue(&wait_q, &wait);
++
++		/* Unlock sector blocks */
++		if (nvram_mtd->unlock)
++			nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize);
++
++		if ((ret = MTD_ERASE(nvram_mtd, &erase))) {
++			set_current_state(TASK_RUNNING);
++			remove_wait_queue(&wait_q, &wait);
++			printk("nvram_commit: erase error\n");
++			goto done;
++		}
++
++		/* Wait for erase to finish */
++		schedule();
++		remove_wait_queue(&wait_q, &wait);
++	}
++
++	/* Write partition up to end of data area */
++	offset = nvram_mtd->size - erasesize;
++	i = erasesize - NVRAM_SPACE + header->len;
++	ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf);
++	if (ret || len != i) {
++		printk("nvram_commit: write error\n");
++		ret = -EIO;
++		goto done;
++	}
++
++	offset = nvram_mtd->size - erasesize;
++	ret = MTD_READ(nvram_mtd, offset, 4, &len, buf);
++
++ done:
++	up(&nvram_sem);
++	kfree(buf);
++	return ret;
++}
++
++int
++nvram_getall(char *buf, int count)
++{
++	unsigned long flags;
++	int ret;
++
++	spin_lock_irqsave(&nvram_lock, flags);
++	ret = _nvram_getall(buf, count);
++	spin_unlock_irqrestore(&nvram_lock, flags);
++
++	return ret;
++}
++
++EXPORT_SYMBOL(nvram_get);
++EXPORT_SYMBOL(nvram_getall);
++EXPORT_SYMBOL(nvram_set);
++EXPORT_SYMBOL(nvram_unset);
++EXPORT_SYMBOL(nvram_commit);
++
++/* User mode interface below */
++
++static ssize_t
++dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos)
++{
++	char tmp[100], *name = tmp, *value;
++	ssize_t ret;
++	unsigned long off;
++
++	if (count > sizeof(tmp)) {
++		if (!(name = kmalloc(count, GFP_KERNEL)))
++			return -ENOMEM;
++	}
++
++	if (copy_from_user(name, buf, count)) {
++		ret = -EFAULT;
++		goto done;
++	}
++
++	if (*name == '\0') {
++		/* Get all variables */
++		ret = nvram_getall(name, count);
++		if (ret == 0) {
++			if (copy_to_user(buf, name, count)) {
++				ret = -EFAULT;
++				goto done;
++			}
++			ret = count;
++		}
++	} else {
++		if (!(value = nvram_get(name))) {
++			ret = 0;
++			goto done;
++		}
++
++		/* Provide the offset into mmap() space */
++		off = (unsigned long) value - (unsigned long) nvram_buf;
++
++		if (put_user(off, (unsigned long *) buf)) {
++			ret = -EFAULT;
++			goto done;
++		}
++
++		ret = sizeof(unsigned long);
++	}
++
++	flush_cache_all();	
++ 
++done:
++	if (name != tmp)
++		kfree(name);
 +
-+#if defined(mips)
-+	cycles = read_c0_count() * 2;
-+#elif defined(__i386__)
-+	rdtscl(cycles);
-+#else
-+	cycles = 0;
-+#endif
-+	return cycles;
++	return ret;
 +}
 +
-+void *
-+osl_reg_map(uint32 pa, uint size)
++static ssize_t
++dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
 +{
-+	return (ioremap_nocache((unsigned long)pa, (unsigned long)size));
-+}
++	char tmp[100], *name = tmp, *value;
++	ssize_t ret;
 +
-+void
-+osl_reg_unmap(void *va)
++	if (count > sizeof(tmp)) {
++		if (!(name = kmalloc(count, GFP_KERNEL)))
++			return -ENOMEM;
++	}
++
++	if (copy_from_user(name, buf, count)) {
++		ret = -EFAULT;
++		goto done;
++	}
++
++	value = name;
++	name = strsep(&value, "=");
++	if (value)
++		ret = nvram_set(name, value) ? : count;
++	else
++		ret = nvram_unset(name) ? : count;
++
++ done:
++	if (name != tmp)
++		kfree(name);
++
++	return ret;
++}	
++
++static int
++dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 +{
-+	iounmap(va);
++	if (cmd != NVRAM_MAGIC)
++		return -EINVAL;
++	return nvram_commit();
 +}
 +
-+int
-+osl_busprobe(uint32 *val, uint32 addr)
++static int
++dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
 +{
-+#ifdef mips
-+	return get_dbe(*val, (uint32*)addr);
-+#else
-+	*val = readl(addr);
++	unsigned long offset = virt_to_phys(nvram_buf);
++
++	if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
++			     vma->vm_page_prot))
++		return -EAGAIN;
++
 +	return 0;
-+#endif
 +}
 +
-+void*
-+osl_dma_alloc_consistent(void *dev, uint size, ulong *pap)
++static int
++dev_nvram_open(struct inode *inode, struct file * file)
 +{
-+	return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap));
++	MOD_INC_USE_COUNT;
++	return 0;
 +}
 +
-+void
-+osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa)
++static int
++dev_nvram_release(struct inode *inode, struct file * file)
 +{
-+	pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa);
++	MOD_DEC_USE_COUNT;
++	return 0;
 +}
 +
-+uint
-+osl_dma_map(void *dev, void *va, uint size, int direction)
++static struct file_operations dev_nvram_fops = {
++	owner:		THIS_MODULE,
++	open:		dev_nvram_open,
++	release:	dev_nvram_release,
++	read:		dev_nvram_read,
++	write:		dev_nvram_write,
++	ioctl:		dev_nvram_ioctl,
++	mmap:		dev_nvram_mmap,
++};
++
++static void
++dev_nvram_exit(void)
 +{
-+	int dir;
++	int order = 0;
++	struct page *page, *end;
 +
-+	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+	return (pci_map_single(dev, va, size, dir));
-+}
++	if (nvram_handle)
++		devfs_unregister(nvram_handle);
 +
-+void
-+osl_dma_unmap(void *dev, uint pa, uint size, int direction)
-+{
-+	int dir;
++	if (nvram_major >= 0)
++		devfs_unregister_chrdev(nvram_major, "nvram");
 +
-+	dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE;
-+	pci_unmap_single(dev, (uint32)pa, size, dir);
-+}
++	if (nvram_mtd)
++		put_mtd_device(nvram_mtd);
 +
-+void
-+osl_delay(uint usec)
-+{
-+	udelay(usec);
-+}
++	while ((PAGE_SIZE << order) < NVRAM_SPACE)
++		order++;
++	end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
++	for (page = virt_to_page(nvram_buf); page <= end; page++)
++		mem_map_unreserve(page);
 +
-+uchar*
-+osl_pktdata(void *drv, void *skb)
-+{
-+	return (((struct sk_buff*)skb)->data);
++	_nvram_exit();
 +}
 +
-+uint
-+osl_pktlen(void *drv, void *skb)
++static int __init
++dev_nvram_init(void)
 +{
-+	return (((struct sk_buff*)skb)->len);
-+}
++	int order = 0, ret = 0;
++	struct page *page, *end;
++	unsigned int i;
 +
-+void*
-+osl_pktnext(void *drv, void *skb)
-+{
-+	return (((struct sk_buff*)skb)->next);
-+}
++	/* Allocate and reserve memory to mmap() */
++	while ((PAGE_SIZE << order) < NVRAM_SPACE)
++		order++;
++	end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1);
++	for (page = virt_to_page(nvram_buf); page <= end; page++)
++		mem_map_reserve(page);
++
++#ifdef CONFIG_MTD
++	/* Find associated MTD device */
++	for (i = 0; i < MAX_MTD_DEVICES; i++) {
++		nvram_mtd = get_mtd_device(NULL, i);
++		if (nvram_mtd) {
++			if (!strcmp(nvram_mtd->name, "nvram") &&
++			    nvram_mtd->size >= NVRAM_SPACE)
++				break;
++			put_mtd_device(nvram_mtd);
++		}
++	}
++	if (i >= MAX_MTD_DEVICES)
++		nvram_mtd = NULL;
++#endif
 +
-+void
-+osl_pktsetnext(void *skb, void *x)
-+{
-+	((struct sk_buff*)skb)->next = (struct sk_buff*)x;
-+}
++	/* Initialize hash table lock */
++	spin_lock_init(&nvram_lock);
 +
-+void
-+osl_pktsetlen(void *drv, void *skb, uint len)
-+{
-+	__skb_trim((struct sk_buff*)skb, len);
-+}
++	/* Initialize commit semaphore */
++	init_MUTEX(&nvram_sem);
 +
-+uchar*
-+osl_pktpush(void *drv, void *skb, int bytes)
-+{
-+	return (skb_push((struct sk_buff*)skb, bytes));
-+}
++	/* Register char device */
++	if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
++		ret = nvram_major;
++		goto err;
++	}
 +
-+uchar*
-+osl_pktpull(void *drv, void *skb, int bytes)
-+{
-+	return (skb_pull((struct sk_buff*)skb, bytes));
-+}
++	/* Initialize hash table */
++	_nvram_init();
 +
-+void*
-+osl_pktdup(void *drv, void *skb)
-+{
-+	return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC));
-+}
++	/* Create /dev/nvram handle */
++	nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0,
++				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL);
 +
-+void*
-+osl_pktcookie(void *skb)
-+{
-+	return ((void*)((struct sk_buff*)skb)->csum);
-+}
++	/* Set the SDRAM NCDL value into NVRAM if not already done */
++	if (getintvar(NULL, "sdram_ncdl") == 0) {
++		unsigned int ncdl;
++		char buf[] = "0x00000000";
 +
-+void
-+osl_pktsetcookie(void *skb, void *x)
-+{
-+	((struct sk_buff*)skb)->csum = (uint)x;
-+}
++		if ((ncdl = sb_memc_get_ncdl(sbh))) {
++			sprintf(buf, "0x%08x", ncdl);
++			nvram_set("sdram_ncdl", buf);
++			nvram_commit();
++		}
++	}
 +
-+void*
-+osl_pktlink(void *skb)
-+{
-+	return (((struct sk_buff*)skb)->prev);
-+}
++	return 0;
 +
-+void
-+osl_pktsetlink(void *skb, void *x)
-+{
-+	((struct sk_buff*)skb)->prev = (struct sk_buff*)x;
++ err:
++	dev_nvram_exit();
++	return ret;
 +}
 +
-+#endif
++module_init(dev_nvram_init);
++module_exit(dev_nvram_exit);
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c	2005-09-16 10:29:18.168592856 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbmips.c	2005-11-07 01:12:51.819809500 +0100
 @@ -0,0 +1,950 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane MIPS core routines
@@ -3612,7 +4502,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +}
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c	2005-09-16 10:29:18.169592704 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbpci.c	2005-11-07 01:12:51.819809500 +0100
 @@ -0,0 +1,530 @@
 +/*
 + * Low-Level PCI and SB support for BCM47xx
@@ -4146,7 +5036,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c	2005-09-16 10:29:18.172592248 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/broadcom/sbutils.c	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,1895 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
@@ -6045,7 +6935,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h	2005-09-16 10:29:18.172592248 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcm4710.h	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,90 @@
 +/*
 + * BCM4710 address space map and definitions
@@ -6139,7 +7029,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcm4710.h linux-2.6.12.5-brc
 +#endif /* _bcm4710_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h	2005-09-16 10:29:18.173592096 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmdevs.h	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,238 @@
 +/*
 + * Broadcom device-specific manifest constants.
@@ -6381,7 +7271,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#endif /* _BCMDEVS_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h	2005-09-16 10:29:18.173592096 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmendian.h	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,125 @@
 +/*******************************************************************************
 + * $Id$
@@ -6510,7 +7400,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-b
 +#endif /* _BCMENDIAN_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h	2005-09-16 10:29:18.174591944 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,229 @@
 +/*
 + * Hardware-specific definitions for
@@ -6743,7 +7633,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.6.12.5
 +#endif	/* _bcmenet_47xx_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h	2005-09-16 10:29:18.174591944 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetmib.h	2005-11-07 01:12:51.823809750 +0100
 @@ -0,0 +1,81 @@
 +/*
 + * Hardware-specific MIB definition for
@@ -6828,7 +7718,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.6.12.5-
 +#endif	/* _bcmenetmib_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h	2005-09-16 10:29:18.183590576 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,43 @@
 +/*
 + * Hardware-specific Receive Data Header for the
@@ -6875,7 +7765,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.6.12.5-
 +#endif	/* _bcmenetrxh_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h	2005-09-16 10:29:18.184590424 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmnvram.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,131 @@
 +/*
 + * NVRAM variable manipulation
@@ -7010,7 +7900,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 +#endif /* _bcmnvram_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h	2005-09-16 10:29:18.184590424 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmsrom.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,24 @@
 +/*
 + * Misc useful routines to access NIC srom
@@ -7038,7 +7928,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brc
 +#endif	/* _bcmsrom_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h	2005-09-16 10:29:18.184590424 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bcmutils.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,136 @@
 +/*
 + * Misc useful os-independent macros and functions.
@@ -7178,7 +8068,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-br
 +#endif	/* _bcmutils_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h	2005-09-16 10:29:18.185590272 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/bitfuncs.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,85 @@
 +/*
 + * bit manipulation utility functions
@@ -7267,7 +8157,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-br
 +#endif /* _BITFUNCS_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h	2005-09-16 10:29:18.185590272 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,69 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation
@@ -7340,7 +8230,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h linux-2.6.12.5-brc
 +#endif /* _epivers_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in	2005-09-16 10:29:18.186590120 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/epivers.h.in	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,69 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation
@@ -7413,7 +8303,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-
 +#endif /* _epivers_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h	2005-09-16 10:29:18.186590120 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/etsockio.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,60 @@
 +/*
 + * Driver-specific socket ioctls
@@ -7477,7 +8367,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/etsockio.h linux-2.6.12.5-br
 +#endif
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h	2005-09-16 10:29:18.187589968 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flash.h	2005-11-07 01:12:51.827810000 +0100
 @@ -0,0 +1,184 @@
 +/*
 + * flash.h: Common definitions for flash access.
@@ -7665,7 +8555,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +#endif
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h	2005-09-16 10:29:18.187589968 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/flashutl.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,34 @@
 +/*
 + * BCM47XX FLASH driver interface
@@ -7703,7 +8593,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flashutl.h linux-2.6.12.5-br
 +#endif /* _flashutl_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h	2005-09-16 10:29:18.188589816 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hnddma.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,181 @@
 +/*
 + * Generic Broadcom Home Networking Division (HND) DMA engine definitions.
@@ -7888,7 +8778,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hnddma.h linux-2.6.12.5-brcm
 +#endif	/* _hnddma_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h	2005-09-16 10:29:18.188589816 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/hndmips.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,16 @@
 +/*
 + * Alternate include file for HND sbmips.h since CFE also ships with
@@ -7908,7 +8798,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/hndmips.h linux-2.6.12.5-brc
 +#include "sbmips.h"
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h	2005-09-16 10:29:18.190589512 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linux_osl.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,313 @@
 +/*
 + * Linux OS Independent Layer
@@ -8225,7 +9115,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#endif	/* _linux_osl_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h	2005-09-16 10:29:18.191589360 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/linuxver.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,326 @@
 +/*
 + * Linux-specific abstractions to gain some independence from linux kernel versions.
@@ -8555,7 +9445,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +#endif /* _linuxver_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h	2005-09-16 10:29:18.191589360 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/nvports.h	2005-11-07 01:12:51.831810250 +0100
 @@ -0,0 +1,62 @@
 +/*
 + * Broadcom Home Gateway Reference Design
@@ -8621,7 +9511,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/nvports.h linux-2.6.12.5-brc
 +
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h	2005-09-16 10:29:18.192589208 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/osl.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,38 @@
 +/*
 + * OS Independent Layer
@@ -8663,7 +9553,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/ar
 +#endif	/* _osl_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h	2005-09-16 10:29:18.192589208 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/pcicfg.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,362 @@
 +/*
 + * pcicfg.h: PCI configuration  constants and structures.
@@ -9029,7 +9919,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#endif
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h	2005-09-16 10:29:18.204587384 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/802.11.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,679 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation   
@@ -9712,7 +10602,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/802.11.h linux-2.6.12.
 +#endif /* _802_11_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h	2005-09-16 10:29:18.205587232 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/proto/ethernet.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,145 @@
 +/*******************************************************************************
 + * $Id$
@@ -9861,7 +10751,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.1
 +#endif /* _NET_ETHERNET_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h	2005-09-16 10:29:18.205587232 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/rts/crc.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,69 @@
 +/*******************************************************************************
 + * $Id$
@@ -9934,7 +10824,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/rts/crc.h linux-2.6.12.5-brc
 +#endif /* _RTS_CRC_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h	2005-09-16 10:29:18.206587080 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/s5.h	2005-11-07 01:12:51.835810500 +0100
 @@ -0,0 +1,103 @@
 +#ifndef _S5_H_
 +#define _S5_H_
@@ -10041,7 +10931,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/s5.h linux-2.6.12.5-brcm/arc
 +#endif /*!_S5_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h	2005-09-16 10:29:18.207586928 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbchipc.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,281 @@
 +/*
 + * SiliconBackplane Chipcommon core hardware definitions.
@@ -10326,7 +11216,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#endif	/* _SBCHIPC_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h	2005-09-16 10:29:18.207586928 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbconfig.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,296 @@
 +/*
 + * Broadcom SiliconBackplane hardware register definitions.
@@ -10626,7 +11516,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#endif	/* _SBCONFIG_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h	2005-09-16 10:29:18.208586776 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbextif.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,242 @@
 +/*
 + * Hardware-specific External Interface I/O core definitions
@@ -10872,7 +11762,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brc
 +#endif	/* _SBEXTIF_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h	2005-09-16 10:29:18.209586624 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmemc.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,144 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
@@ -11020,7 +11910,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm
 +#endif	/* _SBMEMC_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h	2005-09-16 10:29:18.209586624 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbmips.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,56 @@
 +/*
 + * Broadcom SiliconBackplane MIPS definitions
@@ -11080,7 +11970,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm
 +#endif	/* _SBMIPS_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h	2005-09-16 10:29:18.209586624 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpci.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,113 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
@@ -11197,7 +12087,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/
 +#endif	/* _SBPCI_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h	2005-09-16 10:29:18.210586472 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbpcmcia.h	2005-11-07 01:12:51.839810750 +0100
 @@ -0,0 +1,131 @@
 +/*
 + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
@@ -11332,7 +12222,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.6.12.5-br
 +#endif	/* _SBPCMCIA_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h	2005-09-16 10:29:18.210586472 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbsdram.h	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,75 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
@@ -11411,7 +12301,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brc
 +#endif	/* _SBSDRAM_H */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h	2005-09-16 10:29:18.211586320 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/sbutils.h	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,90 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
@@ -11505,7 +12395,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brc
 +#endif	/* _sbutils_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h	2005-09-16 10:29:18.211586320 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/trxhdr.h	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,31 @@
 +/*
 + * TRX image file header format.
@@ -11540,7 +12430,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm
 +typedef struct trx_header TRXHDR, *PTRXHDR;
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h	2005-09-16 10:29:18.212586168 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/typedefs.h	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,162 @@
 +/*
 + * Copyright 2001-2003, Broadcom Corporation   
@@ -11706,7 +12596,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/typedefs.h linux-2.6.12.5-br
 +#endif /* _TYPEDEFS_H_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h
 --- linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h	2005-09-16 10:29:18.213586016 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/include/wlioctl.h	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,690 @@
 +/*
 + * Custom OID/ioctl definitions for
@@ -12400,7 +13290,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/wlioctl.h linux-2.6.12.5-brc
 +#endif /* _wlioctl_h_ */
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S
 --- linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S	2005-09-16 10:29:18.213586016 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/int-handler.S	2005-11-07 01:12:51.843811000 +0100
 @@ -0,0 +1,48 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -12452,8 +13342,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/ar
 +	END(bcm47xx_irq_handler)
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/irq.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c	2005-09-16 10:29:18.214585864 +0200
-@@ -0,0 +1,68 @@
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/irq.c	2005-11-19 02:16:15.531125500 +0100
+@@ -0,0 +1,67 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
 + *
@@ -12491,7 +13381,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/
 +#include <asm/io.h>
 +#include <asm/irq.h>
 +#include <asm/irq_cpu.h>
-+#include <asm/gdb-stub.h>
 +
 +extern asmlinkage void bcm47xx_irq_handler(void);
 +
@@ -12522,9 +13411,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/
 +	set_except_vector(0, bcm47xx_irq_handler);
 +	mips_cpu_irq_init(0);
 +}
+diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/Makefile linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile
+--- linux-2.6.12.5/arch/mips/bcm947xx/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/Makefile	2005-11-07 01:12:51.811809000 +0100
+@@ -0,0 +1,6 @@
++#
++# Makefile for the BCM47xx specific kernel interface routines
++# under Linux.
++#
++
++obj-y := irq.o int-handler.o prom.o setup.o time.o
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/prom.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c	2005-09-16 10:29:18.214585864 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/prom.c	2005-11-07 01:12:51.847811250 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -12587,10 +13486,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips
 +}
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/setup.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c	2005-09-16 10:29:18.215585712 +0200
-@@ -0,0 +1,127 @@
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/setup.c	2005-11-29 01:23:30.667381000 +0100
+@@ -0,0 +1,112 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
++ *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
 + *
 + *  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
@@ -12619,6 +13519,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +#include <linux/serial.h>
 +#include <linux/serial_core.h>
 +#include <linux/serial_reg.h>
++#include <asm/bootinfo.h>
 +#include <asm/time.h>
 +#include <asm/reboot.h>
 +
@@ -12629,24 +13530,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +#include <sbconfig.h>
 +#include <bcmdevs.h>
 +
-+#if 1
-+
-+#define SER_PORT1(reg)	(*((volatile unsigned char *)(0xb8000400+reg)))
-+
-+int putDebugChar(char c)
-+{
-+	while (!(SER_PORT1(UART_LSR) & UART_LSR_THRE));
-+	SER_PORT1(UART_TX) = c;
-+	
-+	return 1;
-+}
-+
-+char getDebugChar(void)
-+{
-+	while (!(SER_PORT1(UART_LSR) & 1));
-+	return SER_PORT1(UART_RX);
-+}
-+
++extern void bcm47xx_time_init(void);
++extern void bcm47xx_timer_setup(struct irqaction *irq);
++void *sbh;
 +
 +static int ser_line = 0;
 +
@@ -12669,20 +13555,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +		printk(KERN_ERR "Serial setup failed!\n");
 +	}
 +}
-+#endif
-+
-+extern void bcm47xx_time_init(void);
-+extern void bcm47xx_timer_setup(struct irqaction *irq);
 +
 +void *nvram_get(char *foo)
 +{
 +	return NULL;
 +}
 +
-+void *sbh;
 +
 +static void bcm47xx_machine_restart(char *command)
 +{
++	printk("Please stand by while rebooting the system...\n");
++	 
 +	/* Set the watchdog timer to reset immediately */
 +	local_irq_disable();
 +	sb_watchdog(sbh, 1);
@@ -12703,6 +13586,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +	sbh = sb_kattach();
 +	sb_mips_init(sbh);
 +	sbpci_init(sbh);
++
 +	sb_serial_init(sbh, serial_add);
 +
 +	_machine_restart = bcm47xx_machine_restart;
@@ -12718,7 +13602,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +early_initcall(bcm47xx_init);
 diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/time.c linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c
 --- linux-2.6.12.5/arch/mips/bcm947xx/time.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c	2005-09-16 10:29:18.215585712 +0200
++++ linux-2.6.12.5-brcm/arch/mips/bcm947xx/time.c	2005-11-07 01:12:51.847811250 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -12779,9 +13663,37 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/time.c linux-2.6.12.5-brcm/arch/mips
 +	/* Enable the timer interrupt */
 +	setup_irq(7, irq);
 +}
+diff -Nur linux-2.6.12.5/arch/mips/Kconfig linux-2.6.12.5-brcm/arch/mips/Kconfig
+--- linux-2.6.12.5/arch/mips/Kconfig	2005-08-15 02:20:18.000000000 +0200
++++ linux-2.6.12.5-brcm/arch/mips/Kconfig	2005-11-07 01:12:51.811809000 +0100
+@@ -40,6 +40,15 @@
+ 	 Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
+ 	 Olivetti M700-10 workstations.
+ 
++config BCM947XX
++	bool "Support for BCM947xx based boards"
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select CPU_LITTLE_ENDIAN
++	help
++	 Support for BCM947xx based boards
++	 
+ config ACER_PICA_61
+ 	bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)"
+ 	depends on MACH_JAZZ && EXPERIMENTAL
+@@ -974,7 +983,7 @@
+ 
+ config CPU_LITTLE_ENDIAN
+ 	bool "Generate little endian code"
+-	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA
++	default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || MACH_DECSTATION || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || SOC_AU1X00 || NEC_OSPREY || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA || BCM947XX
+ 	default n if MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927
+ 	help
+ 	  Some MIPS machines can be configured for either little or big endian
 diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/mips/kernel/cpu-probe.c
 --- linux-2.6.12.5/arch/mips/kernel/cpu-probe.c	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/cpu-probe.c	2005-09-16 10:29:18.243581456 +0200
++++ linux-2.6.12.5-brcm/arch/mips/kernel/cpu-probe.c	2005-11-07 01:12:51.847811250 +0100
 @@ -555,6 +555,28 @@
  	}
  }
@@ -12824,7 +13736,7 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/m
  		break;
 diff -Nur linux-2.6.12.5/arch/mips/kernel/head.S linux-2.6.12.5-brcm/arch/mips/kernel/head.S
 --- linux-2.6.12.5/arch/mips/kernel/head.S	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/head.S	2005-09-16 10:29:18.244581304 +0200
++++ linux-2.6.12.5-brcm/arch/mips/kernel/head.S	2005-11-07 01:12:51.847811250 +0100
 @@ -122,6 +122,14 @@
  #endif
  	.endm
@@ -12842,7 +13754,7 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/head.S linux-2.6.12.5-brcm/arch/mips/k
  	 * Necessary for machines which link their kernels at KSEG0.
 diff -Nur linux-2.6.12.5/arch/mips/kernel/proc.c linux-2.6.12.5-brcm/arch/mips/kernel/proc.c
 --- linux-2.6.12.5/arch/mips/kernel/proc.c	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/kernel/proc.c	2005-09-16 10:29:18.250580392 +0200
++++ linux-2.6.12.5-brcm/arch/mips/kernel/proc.c	2005-11-07 01:12:51.847811250 +0100
 @@ -75,7 +75,9 @@
  	[CPU_VR4133]	"NEC VR4133",
  	[CPU_VR4181]	"NEC VR4181",
@@ -12854,9 +13766,44 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/proc.c linux-2.6.12.5-brcm/arch/mips/k
  };
  
  
+diff -Nur linux-2.6.12.5/arch/mips/Makefile linux-2.6.12.5-brcm/arch/mips/Makefile
+--- linux-2.6.12.5/arch/mips/Makefile	2005-08-15 02:20:18.000000000 +0200
++++ linux-2.6.12.5-brcm/arch/mips/Makefile	2005-11-07 01:12:51.811809000 +0100
+@@ -79,7 +79,7 @@
+ cflags-y			+= -I $(TOPDIR)/include/asm/gcc
+ cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+ cflags-y			+= $(call cc-option, -finline-limit=100000)
+-LDFLAGS_vmlinux			+= -G 0 -static -n
++LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
+ MODFLAGS			+= -mlong-calls
+ 
+ cflags-$(CONFIG_SB1XXX_CORELIS)	+= -mno-sched-prolog -fno-omit-frame-pointer
+@@ -170,6 +170,7 @@
+ cflags-$(CONFIG_CPU_MIPS32)	+= \
+ 			$(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
+ 			-Wa,--trap
++cflags-$(CONFIG_CPU_MIPS32)	+= -Wa,--trap
+ 
+ cflags-$(CONFIG_CPU_MIPS64)	+= \
+ 			$(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
+@@ -618,6 +619,14 @@
+ load-$(CONFIG_SIBYTE_SWARM)	:= 0xffffffff80100000
+ 
+ #
++# Broadcom BCM47XX boards
++#
++core-$(CONFIG_BCM947XX)		+= arch/mips/bcm947xx/ arch/mips/bcm947xx/broadcom/
++cflags-$(CONFIG_BCM947XX)	+= -Iarch/mips/bcm947xx/include
++load-$(CONFIG_BCM947XX)		:= 0xffffffff80001000
++
++
++#
+ # SNI RM200 PCI
+ #
+ core-$(CONFIG_SNI_RM200_PCI)	+= arch/mips/sni/
 diff -Nur linux-2.6.12.5/arch/mips/mm/tlbex.c linux-2.6.12.5-brcm/arch/mips/mm/tlbex.c
 --- linux-2.6.12.5/arch/mips/mm/tlbex.c	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/mm/tlbex.c	2005-09-16 10:29:18.273576896 +0200
++++ linux-2.6.12.5-brcm/arch/mips/mm/tlbex.c	2005-11-07 01:12:51.851811500 +0100
 @@ -851,6 +851,8 @@
  	case CPU_4KSC:
  	case CPU_20KC:
@@ -12866,20 +13813,9 @@ diff -Nur linux-2.6.12.5/arch/mips/mm/tlbex.c linux-2.6.12.5-brcm/arch/mips/mm/t
  		tlbw(p);
  		break;
  
-diff -Nur linux-2.6.12.5/arch/mips/pci/Makefile linux-2.6.12.5-brcm/arch/mips/pci/Makefile
---- linux-2.6.12.5/arch/mips/pci/Makefile	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/pci/Makefile	2005-09-16 10:29:18.311571120 +0200
-@@ -18,6 +18,7 @@
- obj-$(CONFIG_MIPS_TX3927)	+= ops-jmr3927.o
- obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
- obj-$(CONFIG_NEC_CMBVR4133)	+= fixup-vr4133.o
-+obj-$(CONFIG_BCM947XX)		+= ops-sb.o fixup-bcm47xx.o pci-bcm47xx.o
- 
- #
- # These are still pretty much in the old state, watch, go blind.
 diff -Nur linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c linux-2.6.12.5-brcm/arch/mips/pci/fixup-bcm47xx.c
 --- linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/fixup-bcm47xx.c	2005-09-16 10:29:18.312570968 +0200
++++ linux-2.6.12.5-brcm/arch/mips/pci/fixup-bcm47xx.c	2005-11-07 01:12:51.851811500 +0100
 @@ -0,0 +1,23 @@
 +#include <linux/init.h>
 +#include <linux/pci.h>
@@ -12904,9 +13840,20 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/fixup-bcm47xx.c linux-2.6.12.5-brcm/arch/
 +struct pci_fixup pcibios_fixups[] __initdata = {
 +	{ 0 }
 +};
+diff -Nur linux-2.6.12.5/arch/mips/pci/Makefile linux-2.6.12.5-brcm/arch/mips/pci/Makefile
+--- linux-2.6.12.5/arch/mips/pci/Makefile	2005-08-15 02:20:18.000000000 +0200
++++ linux-2.6.12.5-brcm/arch/mips/pci/Makefile	2005-11-07 01:12:51.851811500 +0100
+@@ -18,6 +18,7 @@
+ obj-$(CONFIG_MIPS_TX3927)	+= ops-jmr3927.o
+ obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
+ obj-$(CONFIG_NEC_CMBVR4133)	+= fixup-vr4133.o
++obj-$(CONFIG_BCM947XX)		+= ops-sb.o fixup-bcm47xx.o pci-bcm47xx.o
+ 
+ #
+ # These are still pretty much in the old state, watch, go blind.
 diff -Nur linux-2.6.12.5/arch/mips/pci/ops-sb.c linux-2.6.12.5-brcm/arch/mips/pci/ops-sb.c
 --- linux-2.6.12.5/arch/mips/pci/ops-sb.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/ops-sb.c	2005-09-16 10:29:18.312570968 +0200
++++ linux-2.6.12.5-brcm/arch/mips/pci/ops-sb.c	2005-11-07 01:12:51.851811500 +0100
 @@ -0,0 +1,44 @@
 +#include <linux/kernel.h>
 +#include <linux/init.h>
@@ -12954,7 +13901,7 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/ops-sb.c linux-2.6.12.5-brcm/arch/mips/pc
 +};
 diff -Nur linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c linux-2.6.12.5-brcm/arch/mips/pci/pci-bcm47xx.c
 --- linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-brcm/arch/mips/pci/pci-bcm47xx.c	2005-09-16 10:29:18.313570816 +0200
++++ linux-2.6.12.5-brcm/arch/mips/pci/pci-bcm47xx.c	2005-11-07 01:12:51.851811500 +0100
 @@ -0,0 +1,61 @@
 +#include <linux/init.h>
 +#include <linux/pci.h>
@@ -13019,7 +13966,7 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/pci-bcm47xx.c linux-2.6.12.5-brcm/arch/mi
 +early_initcall(bcm47xx_pci_init);
 diff -Nur linux-2.6.12.5/arch/mips/pci/pci.c linux-2.6.12.5-brcm/arch/mips/pci/pci.c
 --- linux-2.6.12.5/arch/mips/pci/pci.c	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/arch/mips/pci/pci.c	2005-09-16 10:29:18.327568688 +0200
++++ linux-2.6.12.5-brcm/arch/mips/pci/pci.c	2005-11-07 01:12:51.851811500 +0100
 @@ -238,7 +238,8 @@
  		if (dev->resource[i].flags & IORESOURCE_IO)
  			offset = hose->io_offset;
@@ -13032,7 +13979,7 @@ diff -Nur linux-2.6.12.5/arch/mips/pci/pci.c linux-2.6.12.5-brcm/arch/mips/pci/p
  		dev->resource[i].end += offset;
 diff -Nur linux-2.6.12.5/include/asm-mips/bootinfo.h linux-2.6.12.5-brcm/include/asm-mips/bootinfo.h
 --- linux-2.6.12.5/include/asm-mips/bootinfo.h	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/bootinfo.h	2005-09-16 10:29:18.415555312 +0200
++++ linux-2.6.12.5-brcm/include/asm-mips/bootinfo.h	2005-11-07 01:12:51.851811500 +0100
 @@ -213,6 +213,12 @@
  #define MACH_GROUP_TITAN       22	/* PMC-Sierra Titan		*/
  #define  MACH_TITAN_YOSEMITE	1	/* PMC-Sierra Yosemite		*/
@@ -13048,7 +13995,7 @@ diff -Nur linux-2.6.12.5/include/asm-mips/bootinfo.h linux-2.6.12.5-brcm/include
  const char *get_system_type(void);
 diff -Nur linux-2.6.12.5/include/asm-mips/cpu.h linux-2.6.12.5-brcm/include/asm-mips/cpu.h
 --- linux-2.6.12.5/include/asm-mips/cpu.h	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/cpu.h	2005-09-16 10:29:18.416555160 +0200
++++ linux-2.6.12.5-brcm/include/asm-mips/cpu.h	2005-11-07 01:12:51.851811500 +0100
 @@ -87,6 +87,13 @@
  #define PRID_IMP_SR71000        0x0400
  
@@ -13076,7 +14023,7 @@ diff -Nur linux-2.6.12.5/include/asm-mips/cpu.h linux-2.6.12.5-brcm/include/asm-
   * ISA Level encodings
 diff -Nur linux-2.6.12.5/include/asm-mips/mipsregs.h linux-2.6.12.5-brcm/include/asm-mips/mipsregs.h
 --- linux-2.6.12.5/include/asm-mips/mipsregs.h	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/asm-mips/mipsregs.h	2005-09-16 10:29:18.426553640 +0200
++++ linux-2.6.12.5-brcm/include/asm-mips/mipsregs.h	2005-11-07 01:12:51.855811750 +0100
 @@ -790,10 +790,18 @@
  #define read_c0_config1()	__read_32bit_c0_register($16, 1)
  #define read_c0_config2()	__read_32bit_c0_register($16, 2)
@@ -13098,7 +14045,7 @@ diff -Nur linux-2.6.12.5/include/asm-mips/mipsregs.h linux-2.6.12.5-brcm/include
   * The WatchLo register.  There may be upto 8 of them.
 diff -Nur linux-2.6.12.5/include/linux/init.h linux-2.6.12.5-brcm/include/linux/init.h
 --- linux-2.6.12.5/include/linux/init.h	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/linux/init.h	2005-09-16 10:29:18.426553640 +0200
++++ linux-2.6.12.5-brcm/include/linux/init.h	2005-11-07 01:12:51.855811750 +0100
 @@ -86,6 +86,8 @@
  	static initcall_t __initcall_##fn __attribute_used__ \
  	__attribute__((__section__(".initcall" level ".init"))) = fn
@@ -13110,7 +14057,7 @@ diff -Nur linux-2.6.12.5/include/linux/init.h linux-2.6.12.5-brcm/include/linux/
  #define arch_initcall(fn)		__define_initcall("3",fn)
 diff -Nur linux-2.6.12.5/include/linux/pci_ids.h linux-2.6.12.5-brcm/include/linux/pci_ids.h
 --- linux-2.6.12.5/include/linux/pci_ids.h	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-brcm/include/linux/pci_ids.h	2005-09-16 10:29:18.429553184 +0200
++++ linux-2.6.12.5-brcm/include/linux/pci_ids.h	2005-11-07 01:12:51.855811750 +0100
 @@ -2110,6 +2110,7 @@
  #define PCI_DEVICE_ID_TIGON3_5901_2	0x170e
  #define PCI_DEVICE_ID_BCM4401		0x4401
diff --git a/openwrt/target/linux/linux-2.6/patches/brcm/002-flash-map.patch b/openwrt/target/linux/linux-2.6/patches/brcm/002-flash-map.patch
new file mode 100644
index 000000000..406255b64
--- /dev/null
+++ b/openwrt/target/linux/linux-2.6/patches/brcm/002-flash-map.patch
@@ -0,0 +1,360 @@
+diff -Nur linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c
+--- linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c	2005-11-06 20:36:42.553198500 +0100
+@@ -0,0 +1,329 @@
++/*
++ *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
++ *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
++ *
++ *  original functions for finding root filesystem from Mike Baker 
++ *
++ *  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.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  You should have received a copy of the  GNU General Public License along
++ *  with this program; if not, write  to the Free Software Foundation, Inc.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ * 
++ *  Copyright 2001-2003, Broadcom Corporation
++ *  All Rights Reserved.
++ * 
++ *  THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
++ *  KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
++ *  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
++ *  FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
++ *
++ *  $Id: bcm47xx-flash.c,v 1.1 2004/10/21 07:18:31 jolt Exp $
++ *
++ *  Flash mapping for BCM947XX boards
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <asm/io.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++#include <linux/mtd/partitions.h>
++#include <linux/config.h>
++#include <typedefs.h>
++#include <bcmutils.h>
++#include <bcmnvram.h>
++#include <trxhdr.h>
++
++
++#ifdef CONFIG_MTD_PARTITIONS
++extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
++#endif
++
++#define WINDOW_ADDR 0x1c000000
++#define WINDOW_SIZE (0x400000*2)
++#define BUSWIDTH 2
++
++static struct mtd_info *bcm947xx_mtd;
++
++static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
++{
++#define MIPS_MEMCPY_ALIGN 4
++	map_word ret;
++	ssize_t transfer;
++	ssize_t done = 0;
++	if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) {
++		done = len & ~(MIPS_MEMCPY_ALIGN - 1);
++		memcpy_fromio(to, map->virt + from, done);
++	}
++	while (done < len) {
++		ret = map->read(map, from + done);
++		transfer = len - done;
++		if (transfer > map->bankwidth)
++			transfer = map->bankwidth;
++		memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer);
++		done += transfer;
++	}
++}
++
++static struct map_info bcm947xx_map = {
++	name: "Physically mapped flash",
++	size: WINDOW_SIZE,
++	bankwidth: BUSWIDTH,
++	phys: WINDOW_ADDR,
++};
++
++#ifdef CONFIG_MTD_PARTITIONS
++
++static struct mtd_partition bcm947xx_parts[] = {
++	{ name: "cfe",	offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
++	{ name: "linux", offset: 0, size: 0, },
++	{ name: "rootfs", offset: 0, size: 0, },
++	{ name: "nvram", offset: 0, size: 0, },
++	{ name: "OpenWrt", offset: 0, size: 0, },
++	{ name: NULL, },
++};
++
++static int __init
++find_cfe_size(struct mtd_info *mtd, size_t size)
++{
++	struct trx_header *trx;
++	unsigned char buf[512];
++	int off;
++	size_t len;
++	int cfe_size_flag;
++
++	trx = (struct trx_header *) buf;
++
++	cfe_size_flag=0;
++
++	for (off = (256*1024); off < size; off += mtd->erasesize) {
++		memset(buf, 0xe5, sizeof(buf));
++
++		/*
++		 * Read into buffer 
++		 */
++		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
++		    len != sizeof(buf))
++			continue;
++
++		/* found a TRX header */
++		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
++			goto done;
++		}
++		cfe_size_flag += 1;
++	}
++
++	printk(KERN_NOTICE
++	       "%s: Couldn't find bootloader size\n",
++	       mtd->name);
++	return -1;
++
++ done:
++	printk(KERN_NOTICE "bootloader size flag: %d\n", cfe_size_flag);
++	return cfe_size_flag;
++
++}
++
++static int __init
++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
++{
++	struct trx_header *trx;
++	unsigned char buf[512];
++	int off;
++	size_t len;
++
++	trx = (struct trx_header *) buf;
++
++	for (off = (256*1024); off < size; off += mtd->erasesize) {
++		memset(buf, 0xe5, sizeof(buf));
++
++		/*
++		 * Read into buffer 
++		 */
++		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
++		    len != sizeof(buf))
++			continue;
++
++		/* found a TRX header */
++		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
++			part->offset = le32_to_cpu(trx->offsets[2]) ? : 
++				le32_to_cpu(trx->offsets[1]);
++			part->size = le32_to_cpu(trx->len); 
++
++			part->size -= part->offset;
++			part->offset += off;
++
++			goto done;
++		}
++	}
++
++	printk(KERN_NOTICE
++	       "%s: Couldn't find root filesystem\n",
++	       mtd->name);
++	return -1;
++
++ done:
++	return part->size;
++}
++
++struct mtd_partition * __init
++init_mtd_partitions(struct mtd_info *mtd, size_t size)
++{
++
++	int cfe_size_flag;
++
++	cfe_size_flag = find_cfe_size(mtd,size); 
++
++	/* if cfe_size_flag=0, cfe size is 256 kb, else 384 kb */
++
++	/* boot loader */
++	bcm947xx_parts[0].offset = 0;
++	if (cfe_size_flag == 0) {
++		bcm947xx_parts[0].size	 = 1024*256;
++	} else {
++		/* netgear wgt634u has 384 kb bootloader */
++		bcm947xx_parts[0].size   = 1024*384;
++	}
++
++	/* nvram */
++	if (cfe_size_flag == 0) {
++		bcm947xx_parts[3].offset = size - mtd->erasesize;
++		bcm947xx_parts[3].size   = mtd->erasesize;
++	} else {
++		/* nvram (old 128kb config partition on netgear wgt634u) */
++		bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
++		bcm947xx_parts[3].size   = 1024*128;
++	}
++
++	/* linux (kernel and rootfs) */
++	if (cfe_size_flag == 0) {
++		bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
++		bcm947xx_parts[1].size   = bcm947xx_parts[3].offset - 
++			bcm947xx_parts[1].offset;
++	} else {
++		/* do not count the elf loader, which is on one sector */
++		bcm947xx_parts[1].offset = bcm947xx_parts[0].size + 
++			bcm947xx_parts[3].size + mtd->erasesize;
++		bcm947xx_parts[1].size   = size - 
++			bcm947xx_parts[0].size - 
++			(2*bcm947xx_parts[3].size) - 
++			mtd->erasesize;
++	}
++
++	/* find and size rootfs */
++	if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
++		/* entirely jffs2 */
++		bcm947xx_parts[4].name = NULL;
++		if (cfe_size_flag == 0) {
++			bcm947xx_parts[2].size = bcm947xx_parts[3].offset - 
++				bcm947xx_parts[2].offset;
++		} else {
++			bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - 
++				bcm947xx_parts[3].size; 
++		}
++	} else {
++		/* legacy setup */
++		/* calculate leftover flash, and assign it to the jffs2 partition */
++		if (cfe_size_flag == 0) {
++			bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + 
++				bcm947xx_parts[2].size;
++			bcm947xx_parts[4].size = bcm947xx_parts[3].offset - 
++				bcm947xx_parts[4].offset;
++		} else {
++			bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + 
++				bcm947xx_parts[2].size;
++			if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
++				bcm947xx_parts[4].offset += mtd->erasesize - 
++					(bcm947xx_parts[4].offset % mtd->erasesize);
++			}
++			bcm947xx_parts[4].size = size - bcm947xx_parts[3].size - 
++				bcm947xx_parts[4].offset;
++		}
++	}
++
++	return bcm947xx_parts;
++}
++
++EXPORT_SYMBOL(init_mtd_partitions);
++#endif
++
++int __init init_bcm947xx_map(void)
++{
++	size_t size;
++	int ret = 0;
++#ifdef CONFIG_MTD_PARTITIONS
++	struct mtd_partition *parts;
++	int i;
++#endif
++
++	bcm947xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
++
++	if (!bcm947xx_map.virt) {
++		printk("Failed to ioremap\n");
++		return -EIO;
++	}
++	simple_map_init(&bcm947xx_map);
++	
++	bcm947xx_map.copy_from = bcm947xx_map_copy_from;
++	
++	if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
++		printk("Failed to do_map_probe\n");
++		iounmap((void *)bcm947xx_map.virt);
++		return -ENXIO;
++	}
++
++	bcm947xx_mtd->owner = THIS_MODULE;
++
++	size = bcm947xx_mtd->size;
++
++	printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", bcm947xx_mtd->size, WINDOW_ADDR);
++
++#ifdef CONFIG_MTD_PARTITIONS
++	parts = init_mtd_partitions(bcm947xx_mtd, size);
++	for (i = 0; parts[i].name; i++);
++	ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
++	if (ret) {
++		printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
++		goto fail;
++	}
++#endif
++
++	return 0;
++
++ fail:
++	if (bcm947xx_mtd)
++		map_destroy(bcm947xx_mtd);
++	if (bcm947xx_map.map_priv_1)
++		iounmap((void *) bcm947xx_map.map_priv_1);
++	bcm947xx_map.map_priv_1 = 0;
++	return ret;
++}
++
++void __exit cleanup_bcm947xx_map(void)
++{
++#ifdef CONFIG_MTD_PARTITIONS
++	del_mtd_partitions(bcm947xx_mtd);
++#endif
++	map_destroy(bcm947xx_mtd);
++	iounmap((void *)bcm947xx_map.virt);
++}
++
++module_init(init_bcm947xx_map);
++module_exit(cleanup_bcm947xx_map);
+diff -Nur linux-2.6.12.5/drivers/mtd/maps/Kconfig linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig
+--- linux-2.6.12.5/drivers/mtd/maps/Kconfig	2005-08-15 02:20:18.000000000 +0200
++++ linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig	2005-09-16 22:27:36.000000000 +0200
+@@ -357,6 +357,12 @@
+ 	  Mapping for the Flaga digital module. If you don't have one, ignore
+ 	  this setting.
+ 
++config MTD_BCM47XX
++	tristate "BCM47xx flash device"
++	depends on MIPS && MTD_CFI && BCM947XX
++	help
++	  Support for the flash chips on the BCM947xx board.
++	  
+ config MTD_BEECH
+ 	tristate "CFI Flash device mapped on IBM 405LP Beech"
+ 	depends on MTD_CFI && PPC32 && 40x && BEECH
+diff -Nur linux-2.6.12.5/drivers/mtd/maps/Makefile linux-2.6.12.5-flash/drivers/mtd/maps/Makefile
+--- linux-2.6.12.5/drivers/mtd/maps/Makefile	2005-08-15 02:20:18.000000000 +0200
++++ linux-2.6.12.5-flash/drivers/mtd/maps/Makefile	2005-09-16 22:27:01.000000000 +0200
+@@ -31,6 +31,7 @@
+ obj-$(CONFIG_MTD_PCMCIA)	+= pcmciamtd.o
+ obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
+ obj-$(CONFIG_MTD_TQM8XXL)	+= tqm8xxl.o
++obj-$(CONFIG_MTD_BCM47XX)	+= bcm47xx-flash.o
+ obj-$(CONFIG_MTD_SA1100)	+= sa1100-flash.o
+ obj-$(CONFIG_MTD_IPAQ)		+= ipaq-flash.o
+ obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o
diff --git a/openwrt/target/linux/linux-2.6/patches/brcm/003-flash-map.patch b/openwrt/target/linux/linux-2.6/patches/brcm/003-flash-map.patch
deleted file mode 100644
index 60675792a..000000000
--- a/openwrt/target/linux/linux-2.6/patches/brcm/003-flash-map.patch
+++ /dev/null
@@ -1,280 +0,0 @@
-diff -Nur linux-2.6.12.5/drivers/mtd/maps/Kconfig linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig
---- linux-2.6.12.5/drivers/mtd/maps/Kconfig	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-flash/drivers/mtd/maps/Kconfig	2005-09-16 22:27:36.513533784 +0200
-@@ -357,6 +357,12 @@
- 	  Mapping for the Flaga digital module. If you don't have one, ignore
- 	  this setting.
- 
-+config MTD_BCM47XX
-+	tristate "BCM47xx flash device"
-+	depends on MIPS && MTD_CFI && BCM947XX
-+	help
-+	  Support for the flash chips on the BCM947xx board.
-+	  
- config MTD_BEECH
- 	tristate "CFI Flash device mapped on IBM 405LP Beech"
- 	depends on MTD_CFI && PPC32 && 40x && BEECH
-diff -Nur linux-2.6.12.5/drivers/mtd/maps/Makefile linux-2.6.12.5-flash/drivers/mtd/maps/Makefile
---- linux-2.6.12.5/drivers/mtd/maps/Makefile	2005-08-15 02:20:18.000000000 +0200
-+++ linux-2.6.12.5-flash/drivers/mtd/maps/Makefile	2005-09-16 22:27:01.110915800 +0200
-@@ -31,6 +31,7 @@
- obj-$(CONFIG_MTD_PCMCIA)	+= pcmciamtd.o
- obj-$(CONFIG_MTD_RPXLITE)	+= rpxlite.o
- obj-$(CONFIG_MTD_TQM8XXL)	+= tqm8xxl.o
-+obj-$(CONFIG_MTD_BCM47XX)	+= bcm47xx-flash.o
- obj-$(CONFIG_MTD_SA1100)	+= sa1100-flash.o
- obj-$(CONFIG_MTD_IPAQ)		+= ipaq-flash.o
- obj-$(CONFIG_MTD_SBC_GXX)	+= sbc_gxx.o
-diff -Nur linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c
---- linux-2.6.12.5/drivers/mtd/maps/bcm47xx-flash.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.6.12.5-flash/drivers/mtd/maps/bcm47xx-flash.c	2005-09-16 22:26:41.470901536 +0200
-@@ -0,0 +1,249 @@
-+/*
-+ *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
-+ *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
-+ *
-+ *  original functions for finding root filesystem from Mike Baker 
-+ *
-+ *  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.
-+ *
-+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
-+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
-+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
-+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
-+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
-+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
-+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ *  You should have received a copy of the  GNU General Public License along
-+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
-+ *  675 Mass Ave, Cambridge, MA 02139, USA.
-+ * 
-+ *  Copyright 2001-2003, Broadcom Corporation
-+ *  All Rights Reserved.
-+ * 
-+ *  THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
-+ *  KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
-+ *  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
-+ *  FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
-+ *
-+ *  $Id$
-+ *
-+ *  Flash mapping for BCM947XX boards
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/config.h>
-+#include <typedefs.h>
-+#include <bcmutils.h>
-+#include <bcmnvram.h>
-+#include <trxhdr.h>
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+extern struct mtd_partition * init_mtd_partitions(struct mtd_info *mtd, size_t size);
-+#endif
-+
-+#define CFE_SIZE 1024*384
-+#define NVRAM_SIZE 1024*128
-+
-+#define WINDOW_ADDR 0x1c000000
-+#define WINDOW_SIZE (0x400000*2)
-+#define BUSWIDTH 2
-+
-+static struct mtd_info *bcm947xx_mtd;
-+
-+static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+#define MIPS_MEMCPY_ALIGN 4
-+	map_word ret;
-+	ssize_t transfer;
-+	ssize_t done = 0;
-+	if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) {
-+		done = len & ~(MIPS_MEMCPY_ALIGN - 1);
-+		memcpy_fromio(to, map->virt + from, done);
-+	}
-+	while (done < len) {
-+		ret = map->read(map, from + done);
-+		transfer = len - done;
-+		if (transfer > map->bankwidth)
-+			transfer = map->bankwidth;
-+		memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer);
-+		done += transfer;
-+	}
-+}
-+
-+static struct map_info bcm947xx_map = {
-+	name: "Physically mapped flash",
-+	size: WINDOW_SIZE,
-+	bankwidth: BUSWIDTH,
-+	phys: WINDOW_ADDR,
-+};
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+
-+static struct mtd_partition bcm947xx_parts[] = {
-+	{ name: "cfe",	offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
-+	{ name: "linux", offset: 0, size: 0, },
-+	{ name: "rootfs", offset: 0, size: 0, },
-+	{ name: "nvram", offset: 0, size: 0, },
-+	{ name: "OpenWrt", offset: 0, size: 0, },
-+	{ name: NULL, },
-+};
-+
-+static int __init
-+find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
-+{
-+	struct trx_header *trx;
-+	unsigned char buf[512];
-+	int off;
-+	size_t len;
-+
-+	trx = (struct trx_header *) buf;
-+
-+	for (off = (256*1024); off < size; off += mtd->erasesize) {
-+		memset(buf, 0xe5, sizeof(buf));
-+
-+		/*
-+		 * Read into buffer 
-+		 */
-+		if (MTD_READ(mtd, off, sizeof(buf), &len, buf) ||
-+		    len != sizeof(buf))
-+			continue;
-+
-+		/* found a TRX header */
-+		if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
-+			part->offset = le32_to_cpu(trx->offsets[2]) ? : 
-+				le32_to_cpu(trx->offsets[1]);
-+			part->size = le32_to_cpu(trx->len); 
-+
-+			part->size -= part->offset;
-+			part->offset += off;
-+
-+			goto done;
-+		}
-+	}
-+
-+	printk(KERN_NOTICE
-+	       "%s: Couldn't find root filesystem\n",
-+	       mtd->name);
-+	return -1;
-+
-+ done:
-+		return part->size;
-+}
-+
-+struct mtd_partition * __init
-+init_mtd_partitions(struct mtd_info *mtd, size_t size)
-+{
-+
-+	/* boot loader */
-+	bcm947xx_parts[0].offset = 0;
-+	bcm947xx_parts[0].size	 = CFE_SIZE;
-+
-+	/* nvram (old config partition) */
-+	bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
-+	bcm947xx_parts[3].size   = NVRAM_SIZE;
-+
-+	/* Size linux (kernel and rootfs) */
-+	/* do not count the elf loader, which is on one sector */
-+	bcm947xx_parts[1].offset = bcm947xx_parts[0].size + bcm947xx_parts[3].size + mtd->erasesize;
-+	bcm947xx_parts[1].size   = size - NVRAM_SIZE - bcm947xx_parts[0].size - 
-+		bcm947xx_parts[3].size - mtd->erasesize;
-+
-+	/* Find and size rootfs */
-+	if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
-+		/* entirely jffs2 */
-+		bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset - NVRAM_SIZE; 
-+		bcm947xx_parts[4].name = NULL;
-+	} else {
-+		/* legacy setup */
-+		/* calculate leftover flash, and assign it to the jffs2 partition */
-+		bcm947xx_parts[4].offset = bcm947xx_parts[2].offset + bcm947xx_parts[2].size;
-+		if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
-+			bcm947xx_parts[4].offset += mtd->erasesize - 
-+				(bcm947xx_parts[4].offset % mtd->erasesize);
-+		}
-+		bcm947xx_parts[4].size = size - NVRAM_SIZE - bcm947xx_parts[4].offset;
-+	}
-+
-+	return bcm947xx_parts;
-+}
-+
-+EXPORT_SYMBOL(init_mtd_partitions);
-+#endif
-+
-+int __init init_bcm947xx_map(void)
-+{
-+	size_t size;
-+	int ret = 0;
-+#ifdef CONFIG_MTD_PARTITIONS
-+	struct mtd_partition *parts;
-+	int i;
-+#endif
-+
-+	bcm947xx_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+
-+	if (!bcm947xx_map.virt) {
-+		printk("Failed to ioremap\n");
-+		return -EIO;
-+	}
-+	simple_map_init(&bcm947xx_map);
-+	
-+	bcm947xx_map.copy_from = bcm947xx_map_copy_from;
-+	
-+	if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
-+		printk("Failed to do_map_probe\n");
-+		iounmap((void *)bcm947xx_map.virt);
-+		return -ENXIO;
-+	}
-+
-+	bcm947xx_mtd->owner = THIS_MODULE;
-+
-+	size = bcm947xx_mtd->size;
-+
-+	printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", bcm947xx_mtd->size, WINDOW_ADDR);
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+	parts = init_mtd_partitions(bcm947xx_mtd, size);
-+	for (i = 0; parts[i].name; i++);
-+	ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
-+	if (ret) {
-+		printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
-+		goto fail;
-+	}
-+#endif
-+
-+	return 0;
-+
-+ fail:
-+	if (bcm947xx_mtd)
-+		map_destroy(bcm947xx_mtd);
-+	if (bcm947xx_map.map_priv_1)
-+		iounmap((void *) bcm947xx_map.map_priv_1);
-+	bcm947xx_map.map_priv_1 = 0;
-+	return ret;
-+}
-+
-+void __exit cleanup_bcm947xx_map(void)
-+{
-+#ifdef CONFIG_MTD_PARTITIONS
-+	del_mtd_partitions(bcm947xx_mtd);
-+#endif
-+	map_destroy(bcm947xx_mtd);
-+	iounmap((void *)bcm947xx_map.virt);
-+}
-+
-+module_init(init_bcm947xx_map);
-+module_exit(cleanup_bcm947xx_map);