add new flash map driver, some minor system code cleanup
authorWaldemar Brodkorb <mail@waldemar-brodkorb.de>
Tue, 29 Nov 2005 01:37:34 +0000 (01:37 +0000)
committerWaldemar Brodkorb <mail@waldemar-brodkorb.de>
Tue, 29 Nov 2005 01:37:34 +0000 (01:37 +0000)
SVN-Revision: 2564

openwrt/target/linux/linux-2.6/patches/brcm/001-bcm947xx.patch
openwrt/target/linux/linux-2.6/patches/brcm/002-flash-map.patch [new file with mode: 0644]
openwrt/target/linux/linux-2.6/patches/brcm/003-flash-map.patch [deleted file]

index 8f45315766ecabd18cd411ce2df189579bae4bbf..923356f616444edd24224c71c2e085e6150118c9 100644 (file)
@@ -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 (file)
index 0000000..406255b
--- /dev/null
@@ -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 (file)
index 6067579..0000000
+++ /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);