backport flash-map driver and serial setup from 2.6 for netgear wgt634, split flash...
[openwrt.git] / target / linux / linux-2.6 / patches / brcm / 001-bcm947xx.patch
index 923356f..b945e43 100644 (file)
@@ -1,18 +1,76 @@
-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-11-07 01:12:51.811809000 +0100
-@@ -0,0 +1,685 @@
+diff -urN linux.old/arch/mips/Kconfig linux.dev/arch/mips/Kconfig
+--- linux.old/arch/mips/Kconfig        2005-12-15 13:26:49.758027500 +0100
++++ linux.dev/arch/mips/Kconfig        2005-12-15 12:57:27.889182500 +0100
+@@ -244,6 +244,17 @@
+        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 SYS_HAS_CPU_MIPS32_R1
++      select SYS_SUPPORTS_32BIT_KERNEL
++      select SYS_SUPPORTS_LITTLE_ENDIAN
++      help
++       Support for BCM947xx based boards
++
+ config LASAT
+       bool "Support for LASAT Networks platforms"
+       select DMA_NONCOHERENT
+diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile
+--- linux.old/arch/mips/Makefile       2005-12-15 13:26:49.766024000 +0100
++++ linux.dev/arch/mips/Makefile       2005-12-15 12:57:27.921168500 +0100
+@@ -689,6 +689,13 @@
+ load-$(CONFIG_SIBYTE_BIGSUR)  := 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 -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile
+--- linux.old/arch/mips/bcm947xx/Makefile      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/Makefile      2005-12-15 14:32:03.580639500 +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 pci.o
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/Makefile linux.dev/arch/mips/bcm947xx/broadcom/Makefile
+--- linux.old/arch/mips/bcm947xx/broadcom/Makefile     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/Makefile     2005-12-17 20:51:17.749271000 +0100
+@@ -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 sflash.o nvram.o cfe_env.o
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/bcmsrom.c linux.dev/arch/mips/bcm947xx/broadcom/bcmsrom.c
+--- linux.old/arch/mips/bcm947xx/broadcom/bcmsrom.c    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/bcmsrom.c    2005-12-17 01:21:23.007883000 +0100
+@@ -0,0 +1,481 @@
 +/*
-+ *  Misc useful routines to access NIC SROM
++ *  Misc useful routines to access NIC SROM/OTP .
 + *
-+ * 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: bcmsrom.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
++ * 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 <typedefs.h>
@@ -21,76 +79,66 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +#include <bcmsrom.h>
 +#include <bcmdevs.h>
 +#include <bcmendian.h>
-+#include <sbpcmcia.h>
 +#include <pcicfg.h>
++#include <sbutils.h>
 +
 +#include <proto/ethernet.h>   /* for sprom content groking */
 +
 +#define       VARS_MAX        4096    /* should be reduced */
 +
-+static int initvars_srom_pci(void *curmap, char **vars, int *count);
-+static int initvars_cis_pcmcia(void *osh, char **vars, int *count);
-+static int sprom_cmd_pcmcia(void *osh, uint8 cmd);
-+static int sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data);
-+static int sprom_write_pcmcia(void *osh, uint16 addr, uint16 data);
-+static int sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc);
++#define WRITE_ENABLE_DELAY    500     /* 500 ms after write enable/disable toggle */
++#define WRITE_WORD_DELAY      20      /* 20 ms between each word write */
++
++static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count);
++static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc);
++
++static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count);
 +
 +/*
-+ * Initialize the vars from the right source for this platform.
++ * Initialize local vars from the right source for this platform.
 + * Return 0 on success, nonzero on error.
 + */
 +int
-+srom_var_init(uint bus, void *curmap, void *osh, char **vars, int *count)
++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count)
 +{
-+      if (vars == NULL)
++      ASSERT(bustype == BUSTYPE(bustype));
++      if (vars == NULL || count == NULL)
 +              return (0);
 +
-+      switch (bus) {
-+      case SB_BUS:
-+              /* These two could be asserts ... */
-+              *vars = NULL;
-+              *count = 0;
-+              return(0);
++      switch (BUSTYPE(bustype)) {
 +
 +      case PCI_BUS:
 +              ASSERT(curmap); /* can not be NULL */
-+              return(initvars_srom_pci(curmap, vars, count));
-+
-+      case PCMCIA_BUS:
-+              return(initvars_cis_pcmcia(osh, vars, count));
-+
++              return initvars_srom_pci(sbh, curmap, vars, count);
 +
 +      default:
-+              ASSERT(0);
++              return 0;
 +      }
 +      return (-1);
 +}
 +
-+
 +/* support only 16-bit word read from srom */
 +int
-+srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf)
++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
 +{
 +      void *srom;
-+      uint i, off, nw;
++      uint off, nw;
++
++      ASSERT(bustype == BUSTYPE(bustype));
 +
 +      /* check input - 16-bit access only */
 +      if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
 +              return 1;
 +
-+      if (bus == PCI_BUS) {
++      off = byteoff / 2;
++      nw = nbytes / 2;
++
++      if (BUSTYPE(bustype) == PCI_BUS) {
 +              if (!curmap)
 +                      return 1;
-+              srom = (void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET);
-+              if (sprom_read_pci(srom, byteoff, buf, nbytes, FALSE))
++              srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET;
++              if (sprom_read_pci(srom, off, buf, nw, FALSE))
 +                      return 1;
-+      } else if (bus == PCMCIA_BUS) {
-+              off = byteoff / 2;
-+              nw = nbytes / 2;
-+              for (i = 0; i < nw; i++) {
-+                      if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i)))
-+                              return 1;
-+              }
 +      } else {
 +              return 1;
 +      }
@@ -100,7 +148,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +
 +/* support only 16-bit word write into srom */
 +int
-+srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf)
++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
 +{
 +      uint16 *srom;
 +      uint i, off, nw, crc_range;
@@ -108,23 +156,25 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +      uint8 crc;
 +      volatile uint32 val32;
 +
++      ASSERT(bustype == BUSTYPE(bustype));
++
 +      /* check input - 16-bit access only */
 +      if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
 +              return 1;
 +
-+      crc_range = ((bus == PCMCIA_BUS) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2;
++      crc_range = (((BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2;
 +
 +      /* if changes made inside crc cover range */
 +      if (byteoff < crc_range) {
 +              nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2;
 +              /* read data including entire first 64 words from srom */
-+              if (srom_read(bus, curmap, osh, 0, nw * 2, image))
++              if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
 +                      return 1;
 +              /* make changes */
 +              bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
 +              /* calculate crc */
 +              htol16_buf(image, crc_range);
-+              crc = ~crc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
++              crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
 +              ltoh16_buf(image, crc_range);
 +              image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
 +              p = image;
@@ -135,343 +185,160 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +              nw = nbytes / 2;
 +      }
 +
-+      if (bus == PCI_BUS) {
-+              srom = (uint16*)((uint)curmap + PCI_BAR0_SPROM_OFFSET);
++      if (BUSTYPE(bustype) == PCI_BUS) {
++              srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET);
 +              /* enable writes to the SPROM */
 +              val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
 +              val32 |= SPROM_WRITEEN;
 +              OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
-+              bcm_mdelay(500);
++              bcm_mdelay(WRITE_ENABLE_DELAY);
 +              /* write srom */
 +              for (i = 0; i < nw; i++) {
 +                      W_REG(&srom[off + i], p[i]);
-+                      bcm_mdelay(20);
++                      bcm_mdelay(WRITE_WORD_DELAY);
 +              }
 +              /* disable writes to the SPROM */
 +              OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN);
-+      } else if (bus == PCMCIA_BUS) {
-+              /* enable writes to the SPROM */
-+              if (sprom_cmd_pcmcia(osh, SROM_WEN))
-+                      return 1;
-+              bcm_mdelay(500);
-+              /* write srom */
-+              for (i = 0; i < nw; i++) {
-+                      sprom_write_pcmcia(osh, (uint16)(off + i), p[i]);
-+                      bcm_mdelay(20);
-+              }
-+              /* disable writes to the SPROM */
-+              if (sprom_cmd_pcmcia(osh, SROM_WDS))
-+                      return 1;
 +      } else {
 +              return 1;
 +      }
 +
-+      bcm_mdelay(500);
-+      return 0;
-+}
-+
-+
-+int
-+srom_parsecis(uint8 *cis, char **vars, int *count)
-+{
-+      char eabuf[32];
-+      char *vp, *base;
-+      uint8 tup, tlen, sromrev = 1;
-+      int i, j;
-+      uint varsize;
-+      bool ag_init = FALSE;
-+      uint16 w;
-+
-+      ASSERT(vars);
-+      ASSERT(count);
-+
-+      base = vp = MALLOC(VARS_MAX);
-+      ASSERT(vp);
-+
-+      i = 0;
-+      do {
-+              tup = cis[i++];
-+              tlen = cis[i++];
-+
-+              switch (tup) {
-+              case CISTPL_MANFID:
-+                      vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
-+                      vp++;
-+                      vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
-+                      vp++;
-+                      break;
-+
-+              case CISTPL_FUNCE:
-+                      if (cis[i] == LAN_NID) {
-+                              ASSERT(cis[i + 1] == ETHER_ADDR_LEN);
-+                              bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf);
-+                              vp += sprintf(vp, "il0macaddr=%s", eabuf);
-+                              vp++;
-+                      }
-+                      break;
-+
-+              case CISTPL_CFTABLE:
-+                      vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
-+                      vp++;
-+                      break;
-+
-+              case CISTPL_BRCM_HNBU:
-+                      switch (cis[i]) {
-+                      case HNBU_CHIPID:
-+                              vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]);
-+                              vp++;
-+                              vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]);
-+                              vp++;
-+                              if (tlen == 7) {
-+                                      vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]);
-+                                      vp++;
-+                              }
-+                              break;
-+
-+                      case HNBU_BOARDREV:
-+                              vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
-+                              vp++;
-+                              break;
-+
-+                      case HNBU_AA:
-+                              vp += sprintf(vp, "aa0=%d", cis[i + 1]);
-+                              vp++;
-+                              break;
-+
-+                      case HNBU_AG:
-+                              vp += sprintf(vp, "ag0=%d", cis[i + 1]);
-+                              vp++;
-+                              ag_init = TRUE;
-+                              break;
-+
-+                      case HNBU_CC:
-+                              vp += sprintf(vp, "cc=%d", cis[i + 1]);
-+                              vp++;
-+                              break;
-+
-+                      case HNBU_PAPARMS:
-+                              vp += sprintf(vp, "pa0maxpwr=%d", cis[i + tlen - 1]);
-+                              vp++;
-+                              if (tlen == 9) {
-+                                      /* New version */
-+                                      for (j = 0; j < 3; j++) {
-+                                              vp += sprintf(vp, "pa0b%d=%d", j,
-+                                                            (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]);
-+                                              vp++;
-+                                      }
-+                                      vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
-+                                      vp++;
-+                              }
-+                              break;
-+
-+                      case HNBU_OEM:
-+                              vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
-+                                      cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4],
-+                                      cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]);
-+                              vp++;
-+                              break;
-+                      case HNBU_BOARDFLAGS:
-+                              w = (cis[i + 2] << 8) + cis[i + 1];
-+                              if (w == 0xffff) w = 0;
-+                              vp += sprintf(vp, "boardflags=%d", w);
-+                              vp++;
-+                              break;
-+                      case HNBU_LED:
-+                              if (cis[i + 1] != 0xff) {
-+                                      vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]);
-+                                      vp++;
-+                              }
-+                              if (cis[i + 2] != 0xff) {
-+                                      vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]);
-+                                      vp++;
-+                              }
-+                              if (cis[i + 3] != 0xff) {
-+                                      vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]);
-+                                      vp++;
-+                              }
-+                              if (cis[i + 4] != 0xff) {
-+                                      vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]);
-+                                      vp++;
-+                              }
-+                              break;
-+                      }
-+                      break;
-+
-+              }
-+              i += tlen;
-+      } while (tup != 0xff);
-+
-+      /* Set the srom version */
-+      vp += sprintf(vp, "sromrev=%d", sromrev);
-+      vp++;
-+
-+      /* For now just set boardflags2 to zero */
-+      vp += sprintf(vp, "boardflags2=0");
-+      vp++;
-+
-+      /* if there is no antenna gain field, set default */
-+      if (ag_init == FALSE) {
-+              vp += sprintf(vp, "ag0=%d", 0xff);
-+              vp++;
-+      }
-+
-+      /* final nullbyte terminator */
-+      *vp++ = '\0';
-+      varsize = (uint)vp - (uint)base;
-+
-+      ASSERT(varsize < VARS_MAX);
-+
-+      if (varsize == VARS_MAX) {
-+              *vars = base;
-+      } else {
-+              vp = MALLOC(varsize);
-+              ASSERT(vp);
-+              bcopy(base, vp, varsize);
-+              MFREE(base, VARS_MAX);
-+              *vars = vp;
-+      }
-+      *count = varsize;
-+
-+      return (0);
-+}
-+
-+
-+/* set PCMCIA sprom command register */
-+static int
-+sprom_cmd_pcmcia(void *osh, uint8 cmd)
-+{
-+      uint8 status;
-+      uint wait_cnt = 1000;
-+
-+      /* write sprom command register */
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
-+
-+      /* wait status */
-+      while (wait_cnt--) {
-+              OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
-+              if (status & SROM_DONE)
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+/* read a word from the PCMCIA srom */
-+static int
-+sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data)
-+{
-+      uint8 addr_l, addr_h, data_l, data_h;
-+
-+      addr_l = (uint8)((addr * 2) & 0xff);
-+      addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
-+
-+      /* set address */
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
-+
-+      /* do read */
-+      if (sprom_cmd_pcmcia(osh, SROM_READ))
-+              return 1;
-+
-+      /* read data */
-+      OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
-+      OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
-+
-+      *data = (data_h << 8) | data_l;
++      bcm_mdelay(WRITE_ENABLE_DELAY);
 +      return 0;
 +}
 +
-+/* write a word to the PCMCIA srom */
-+static int
-+sprom_write_pcmcia(void *osh, uint16 addr, uint16 data)
-+{
-+      uint8 addr_l, addr_h, data_l, data_h;
-+
-+      addr_l = (uint8)((addr * 2) & 0xff);
-+      addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
-+      data_l = (uint8)(data & 0xff);
-+      data_h = (uint8)((data >> 8) & 0xff);
-+
-+      /* set address */
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
-+
-+      /* write data */
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
-+      OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
-+
-+      /* do write */
-+      return sprom_cmd_pcmcia(osh, SROM_WRITE);
-+}
 +
 +/*
 + * Read in and validate sprom.
 + * Return 0 on success, nonzero on error.
 + */
 +static int
-+sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc)
++sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc)
 +{
-+      int off, nw;
-+      uint8 chk8;
-+      int i;
-+
-+      off = byteoff / 2;
-+      nw = ROUNDUP(nbytes, 2) / 2;
++      int err = 0;
++      uint i;
 +
 +      /* read the sprom */
-+      for (i = 0; i < nw; i++)
-+              buf[i] = R_REG(&sprom[off + i]);
++      for (i = 0; i < nwords; i++)
++              buf[i] = R_REG(&sprom[wordoff + i]);
 +
 +      if (check_crc) {
 +              /* fixup the endianness so crc8 will pass */
-+              htol16_buf(buf, nw * 2);
-+              if ((chk8 = crc8((uchar*)buf, nbytes, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE)
-+                      return (1);
++              htol16_buf(buf, nwords * 2);
++              if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE)
++                      err = 1;
 +              /* now correct the endianness of the byte array */
-+              ltoh16_buf(buf, nw * 2);
++              ltoh16_buf(buf, nwords * 2);
 +      }
++      
++      return err;
++}     
 +
-+      return (0);
++/*
++* Create variable table from memory.
++* Return 0 on success, nonzero on error.
++*/
++static int
++initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count)
++{
++      int c = (int)(end - start);
++
++      /* do it only when there is more than just the null string */
++      if (c > 1) {
++              char *vp = MALLOC(osh, c);
++              ASSERT(vp);
++              if (!vp)
++                      return BCME_NOMEM;
++              bcopy(start, vp, c);
++              *vars = vp;
++              *count = c;
++      }
++      else {
++              *vars = NULL;
++              *count = 0;
++      }
++      
++      return 0;
 +}
 +
 +/*
 + * Initialize nonvolatile variable table from sprom.
 + * Return 0 on success, nonzero on error.
 + */
-+
 +static int
-+initvars_srom_pci(void *curmap, char **vars, int *count)
++initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count)
 +{
 +      uint16 w, b[64];
 +      uint8 sromrev;
 +      struct ether_addr ea;
 +      char eabuf[32];              
-+      int c, woff, i;
++      uint32 w32;
++      int woff, i;
 +      char *vp, *base;
++      osl_t *osh = sb_osh(sbh);
++      int err;
 +
-+      if (sprom_read_pci((void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof (b), TRUE))
-+              return (-1);
++      /*
++      * Apply CRC over SROM content regardless SROM is present or not,
++      * and use variable <devpath>sromrev's existance in flash to decide
++      * if we should return an error when CRC fails or read SROM variables
++      * from flash.
++      */
++      sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE);
 +
 +      /* top word of sprom contains version and crc8 */
 +      sromrev = b[63] & 0xff;
-+      if ((sromrev != 1) && (sromrev != 2)) {
++      /* bcm4401 sroms misprogrammed */
++      if (sromrev == 0x10)
++              sromrev = 1;
++      
++      /* srom version check */
++      if (sromrev > 3)
 +              return (-2);
-+      }
 +
 +      ASSERT(vars);
 +      ASSERT(count);
 +
-+      base = vp = MALLOC(VARS_MAX);
++      base = vp = MALLOC(osh, VARS_MAX);
 +      ASSERT(vp);
++      if (!vp)
++              return -2;
 +
 +      vp += sprintf(vp, "sromrev=%d", sromrev);
 +      vp++;
 +
-+      if (sromrev >= 2) {
-+              /* New section takes over the 4th hardware function space */
++      if (sromrev >= 3) {
++              /* New section takes over the 3th hardware function space */
++
++              /* Words 22+23 are 11a (mid) ofdm power offsets */
++              w32 = ((uint32)b[23] << 16) | b[22];
++              vp += sprintf(vp, "ofdmapo=%d", w32);
++              vp++;
++
++              /* Words 24+25 are 11a (low) ofdm power offsets */
++              w32 = ((uint32)b[25] << 16) | b[24];
++              vp += sprintf(vp, "ofdmalpo=%d", w32);
++              vp++;
++
++              /* Words 26+27 are 11a (high) ofdm power offsets */
++              w32 = ((uint32)b[27] << 16) | b[26];
++              vp += sprintf(vp, "ofdmahpo=%d", w32);
++              vp++;
++
++              /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/
++              w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8);
++              vp += sprintf(vp, "gpiotimerval=%d", w32);
++
++              /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/
++              w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) |  /* oncount*/
++                      ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */
++              vp += sprintf(vp, "gpiotimerval=%d", w32);
 +
-+              /* Word 28 is boardflags2 */
-+              vp += sprintf(vp, "boardflags2=%d", b[28]);
 +              vp++;
++      }
++
++      if (sromrev >= 2) {
++              /* New section takes over the 4th hardware function space */
 +
 +              /* Word 29 is max power 11a high/low */
 +              w = b[29];
@@ -622,9 +489,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +      vp++;
 +
 +      /* Word 57 is boardflags, if not programmed make it zero */
-+      w = b[57];
-+      if (w == 0xffff) w = 0;
-+      vp += sprintf(vp, "boardflags=%d", w);
++      w32 = (uint32)b[57];
++      if (w32 == 0xffff) w32 = 0;
++      if (sromrev > 1) {
++              /* Word 28 is the high bits of boardflags */
++              w32 |= (uint32)b[28] << 16;
++      }
++      vp += sprintf(vp, "boardflags=%d", w32);
 +      vp++;
 +
 +      /* Word 58 is antenna gain 0/1 */
@@ -643,72 +514,57 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmsrom.c linux-2.6.12.5-br
 +                            ((b[61] >> 8) & 0xff), (b[61] & 0xff),
 +                            ((b[62] >> 8) & 0xff), (b[62] & 0xff));
 +              vp++;
++      } else if (sromrev == 2) {
++              /* Word 60 OFDM tx power offset from CCK level */
++              /* OFDM Power Offset - opo */
++              vp += sprintf(vp, "opo=%d", b[60] & 0xff);
++              vp++;
++      } else {
++              /* Word 60: cck power offsets */
++              vp += sprintf(vp, "cckpo=%d", b[60]);
++              vp++;
++
++              /* Words 61+62: 11g ofdm power offsets */
++              w32 = ((uint32)b[62] << 16) | b[61];
++              vp += sprintf(vp, "ofdmgpo=%d", w32);
++              vp++;
 +      }
 +
 +      /* final nullbyte terminator */
 +      *vp++ = '\0';
 +
-+      c = vp - base;
-+      ASSERT(c <= VARS_MAX);
-+
-+      if (c == VARS_MAX) {
-+              *vars = base;
-+      } else {
-+              vp = MALLOC(c);
-+              ASSERT(vp);
-+              bcopy(base, vp, c);
-+              MFREE(base, VARS_MAX);
-+              *vars = vp;
-+      }
-+      *count = c;
-+
-+      return (0);
-+}
-+
-+/*
-+ * Read the cis and call parsecis to initialize the vars.
-+ * Return 0 on success, nonzero on error.
-+ */
-+static int
-+initvars_cis_pcmcia(void *osh, char **vars, int *count)
-+{
-+      uint8 *cis = NULL;
-+      int rc;
-+
-+      if ((cis = MALLOC(CIS_SIZE)) == NULL)
-+              return (-1);
-+
-+      OSL_PCMCIA_READ_ATTR(osh, 0, cis, CIS_SIZE);
-+
-+      rc = srom_parsecis(cis, vars, count);
-+
-+      MFREE(cis, CIS_SIZE);
-+
-+      return (rc);
++      ASSERT((vp - base) <= VARS_MAX);
++      
++      err = initvars_table(osh, base, vp, vars, count);
++      
++      MFREE(osh, base, VARS_MAX);
++      return err;
 +}
 +
-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-11-07 01:12:51.815809250 +0100
-@@ -0,0 +1,691 @@
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/bcmutils.c linux.dev/arch/mips/bcm947xx/broadcom/bcmutils.c
+--- linux.old/arch/mips/bcm947xx/broadcom/bcmutils.c   1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/bcmutils.c   2005-12-17 17:53:52.387365000 +0100
+@@ -0,0 +1,356 @@
 +/*
 + * Misc useful OS-independent routines.
 + *
-+ * 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: bcmutils.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
++ * 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 <typedefs.h>
 +#include <osl.h>
++#include <sbutils.h>
++#include <bcmnvram.h>
 +#include <bcmutils.h>
 +#include <bcmendian.h>
-+#include <bcmnvram.h>
++#include <bcmdevs.h>
 +
 +unsigned char bcm_ctype[] = {
 +      _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,                        /* 0-7 */
@@ -807,104 +663,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +      return (n);
 +}
 +
-+void
-+deadbeef(char *p, uint len)
++/* return pointer to location of substring 'needle' in 'haystack' */
++char*
++bcmstrstr(char *haystack, char *needle)
 +{
-+      static uchar meat[] = { 0xde, 0xad, 0xbe, 0xef };
++      int len, nlen;
++      int i;
 +
-+      while (len-- > 0) {
-+              *p = meat[((uint)p) & 3];
-+              p++;
-+      }
++      if ((haystack == NULL) || (needle == NULL))
++              return (haystack);
++
++      nlen = strlen(needle);
++      len = strlen(haystack) - nlen + 1;
++
++      for (i = 0; i < len; i++)
++              if (bcmp(needle, &haystack[i], nlen) == 0)
++                      return (&haystack[i]);
++      return (NULL);
 +}
 +
-+/* pretty hex print a contiguous buffer */
-+void
-+prhex(char *msg, uchar *buf, uint nbytes)
++char*
++bcmstrcat(char *dest, const char *src)
 +{
-+      char line[256];
-+      char* p;
-+      uint i;
++      strcpy(&dest[strlen(dest)], src);
++      return (dest);
++}
 +
-+      if (msg && (msg[0] != '\0'))
-+              printf("%s: ", msg);
 +
-+      p = line;
-+      for (i = 0; i < nbytes; i++) {
-+              if (i % 16 == 0) {
-+                      p += sprintf(p, "%04d: ", i);   /* line prefix */
-+              }
-+              p += sprintf(p, "%02x ", buf[i]);
-+              if (i % 16 == 15) {
-+                      printf("%s\n", line);           /* flush line */
-+                      p = line;
-+              }
-+      }
-+
-+      /* flush last partial line */
-+      if (p != line)
-+              printf("%s\n", line);
-+}
-+
-+/* pretty hex print a pkt buffer chain */
-+void
-+prpkt(char *msg, void *drv, void *p0)
-+{
-+      void *p;
-+
-+      if (msg && (msg[0] != '\0'))
-+              printf("%s: ", msg);
-+
-+      for (p = p0; p; p = PKTNEXT(drv, p))
-+              prhex(NULL, PKTDATA(drv, p), PKTLEN(drv, p));
-+}
-+
-+/* copy a pkt buffer chain into a buffer */
-+uint
-+pktcopy(void *drv, void *p, uint offset, int len, uchar *buf)
-+{
-+      uint n, ret = 0;
-+
-+      if (len < 0)
-+              len = 4096;     /* "infinite" */
-+
-+      /* skip 'offset' bytes */
-+      for (; p && offset; p = PKTNEXT(drv, p)) {
-+              if (offset < (uint)PKTLEN(drv, p))
-+                      break;
-+              offset -= PKTLEN(drv, p);
-+      }
-+
-+      if (!p)
-+              return 0;
-+
-+      /* copy the data */
-+      for (; p && len; p = PKTNEXT(drv, p)) {
-+              n = MIN((uint)PKTLEN(drv, p) - offset, (uint)len);
-+              bcopy(PKTDATA(drv, p) + offset, buf, n);
-+              buf += n;
-+              len -= n;
-+              ret += n;
-+              offset = 0;
-+      }
-+
-+      return ret;
-+}
-+
-+/* return total length of buffer chain */
-+uint
-+pkttotlen(void *drv, void *p)
-+{
-+      uint total;
-+
-+      total = 0;
-+      for (; p; p = PKTNEXT(drv, p))
-+              total += PKTLEN(drv, p);
-+      return (total);
-+}
-+
-+
-+uchar*
++char*
 +bcm_ether_ntoa(char *ea, char *buf)
 +{
 +      sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x",
@@ -928,123 +714,113 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +      return (i == 6);
 +}
 +
-+/* 
-+ * Traverse a string of 1-byte tag/1-byte length/variable-length value 
-+ * triples, returning a pointer to the substring whose first element 
-+ * matches tag.  Stop parsing when we see an element whose ID is greater
-+ * than the target key. 
-+ */
-+bcm_tlv_t *
-+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key)
++void
++bcm_mdelay(uint ms)
 +{
-+      bcm_tlv_t *elt;
-+      int totlen;
-+
-+      elt = (bcm_tlv_t*)buf;
-+      totlen = buflen;
-+
-+      /* find tagged parameter */
-+      while (totlen >= 2) {
-+              uint id = elt->id;
-+              int len = elt->len;
-+              
-+              /* Punt if we start seeing IDs > than target key */
-+              if (id > key)
-+                      return(NULL);
-+
-+              /* validate remaining totlen */
-+              if ((id == key) && (totlen >= (len + 2)))
-+                      return (elt);
++      uint i;
 +
-+              elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
-+              totlen -= (len + 2);
++      for (i = 0; i < ms; i++) {
++              OSL_DELAY(1000);
 +      }
-+      return NULL;
 +}
 +
-+
-+/* 
-+ * Traverse a string of 1-byte tag/1-byte length/variable-length value 
-+ * triples, returning a pointer to the substring whose first element 
-+ * matches tag
++/*
++ * Search the name=value vars for a specific one and return its value.
++ * Returns NULL if not found.
 + */
-+bcm_tlv_t *
-+bcm_parse_tlvs(void *buf, int buflen, uint key)
++char*
++getvar(char *vars, char *name)
 +{
-+      bcm_tlv_t *elt;
-+      int totlen;
-+
-+      elt = (bcm_tlv_t*)buf;
-+      totlen = buflen;
++      char *s;
++      int len;
 +
-+      /* find tagged parameter */
-+      while (totlen >= 2) {
-+              int len = elt->len;
++      len = strlen(name);
 +
-+              /* validate remaining totlen */
-+              if ((elt->id == key) && (totlen >= (len + 2)))
-+                      return (elt);
++      /* first look in vars[] */
++      for (s = vars; s && *s; ) {
++              if ((bcmp(s, name, len) == 0) && (s[len] == '='))
++                      return (&s[len+1]);
 +
-+              elt = (bcm_tlv_t*)((uint8*)elt + (len + 2));
-+              totlen -= (len + 2);
++              while (*s++)
++                      ;
 +      }
-+      
-+      return NULL;
++
++      /* then query nvram */
++      return (BCMINIT(nvram_get)(name));
 +}
 +
-+void
-+pktqinit(struct pktq *q, int maxlen)
++/*
++ * Search the vars for a specific one and return its value as
++ * an integer. Returns 0 if not found.
++ */
++int
++getintvar(char *vars, char *name)
 +{
-+      q->head = q->tail = NULL;
-+      q->maxlen = maxlen;
-+      q->len = 0;
++      char *val;
++
++      if ((val = getvar(vars, name)) == NULL)
++              return (0);
++
++      return (bcm_strtoul(val, NULL, 0));
 +}
 +
-+void
-+pktenq(struct pktq *q, void *p, bool lifo)
-+{
-+      ASSERT(PKTLINK(p) == NULL);
 +
-+      PKTSETLINK(p, NULL);
++/* Search for token in comma separated token-string */
++static int
++findmatch(char *string, char *name)
++{
++      uint len;
++      char *c;
 +
-+      if (q->tail == NULL) {
-+              ASSERT(q->head == NULL);
-+              q->head = q->tail = p;
-+      }
-+      else {
-+              ASSERT(q->head);
-+              ASSERT(PKTLINK(q->tail) == NULL);
-+              if (lifo) {
-+                      PKTSETLINK(p, q->head);
-+                      q->head = p;
-+              } else {
-+                      PKTSETLINK(q->tail, p);
-+                      q->tail = p;
-+              }
++      len = strlen(name);
++      while ((c = strchr(string, ',')) != NULL) {
++              if (len == (uint)(c - string) && !strncmp(string, name, len))
++                      return 1;
++              string = c + 1;
 +      }
-+      q->len++;
++
++      return (!strcmp(string, name));
 +}
 +
-+void*
-+pktdeq(struct pktq *q)
++/* Return gpio pin number assigned to the named pin */
++/*
++* Variable should be in format:
++*
++*     gpio<N>=pin_name,pin_name
++*
++* This format allows multiple features to share the gpio with mutual
++* understanding.
++*
++* 'def_pin' is returned if a specific gpio is not defined for the requested functionality 
++* and if def_pin is not used by others.
++*/
++uint
++getgpiopin(char *vars, char *pin_name, uint def_pin)
 +{
-+      void *p;
++      char name[] = "gpioXXXX";
++      char *val;
++      uint pin;
 +
-+      if ((p = q->head)) {
-+              ASSERT(q->tail);
-+              q->head = PKTLINK(p);
-+              PKTSETLINK(p, NULL);
-+              q->len--;
-+              if (q->head == NULL)
-+                      q->tail = NULL;
++      /* Go thru all possibilities till a match in pin name */
++      for (pin = 0; pin < GPIO_NUMPINS; pin ++) {
++              sprintf(name, "gpio%d", pin);
++              val = getvar(vars, name);
++              if (val && findmatch(val, pin_name))
++                      return pin;
 +      }
-+      else {
-+              ASSERT(q->tail == NULL);
++
++      if (def_pin != GPIO_PIN_NOTDEFINED) {
++              /* make sure the default pin is not used by someone else */
++              sprintf(name, "gpio%d", def_pin);
++              if (getvar(vars, name)) {
++                      def_pin =  GPIO_PIN_NOTDEFINED;
++              }
 +      }
 +
-+      return (p);
++      return def_pin;
 +}
 +
++
 +/*******************************************************************************
 + * crc8
 + *
@@ -1101,61 +877,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +    0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
 +};
 +
-+/*
-+ * Search the name=value vars for a specific one and return its value.
-+ * Returns NULL if not found.
-+ */
-+char*
-+getvar(char *vars, char *name)
-+{
-+      char *s;
-+      int len;
-+
-+      len = strlen(name);
-+
-+      /* first look in vars[] */
-+      for (s = vars; s && *s; ) {
-+              if ((bcmp(s, name, len) == 0) && (s[len] == '='))
-+                      return (&s[len+1]);
-+
-+              while (*s++)
-+                      ;
-+      }
-+
-+      /* then query nvram */
-+      return (nvram_get(name));
-+}
-+
-+/*
-+ * Search the vars for a specific one and return its value as
-+ * an integer. Returns 0 if not found.
-+ */
-+int
-+getintvar(char *vars, char *name)
-+{
-+      char *val;
-+
-+      if ((val = getvar(vars, name)) == NULL)
-+              return (0);
-+
-+      return (bcm_strtoul(val, NULL, 0));
-+}
-+
-+void
-+bcm_mdelay(uint ms)
-+{
-+      uint i;
-+
-+      for (i = 0; i < ms; i++) {
-+              OSL_DELAY(1000);
-+      }
-+}
-+
 +#define CRC_INNER_LOOP(n, c, x) \
 +    (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
 +
 +uint8
-+crc8(
++hndcrc8(
 +      uint8 *pdata,   /* pointer to array of data to process */
 +      uint  nbytes,   /* number of input data bytes to process */
 +      uint8 crc       /* either CRC8_INIT_VALUE or previous return value */
@@ -1169,226 +895,18 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/bcmutils.c linux-2.6.12.5-b
 +      return crc;
 +}
 +
-+/*******************************************************************************
-+ * crc16
-+ *
-+ * Computes a crc16 over the input data using the polynomial:
-+ *
-+ *       x^16 + x^12 +x^5 + 1
-+ *
-+ * The caller provides the initial value (either CRC16_INIT_VALUE
-+ * or the previous returned value) to allow for processing of 
-+ * discontiguous blocks of data.  When generating the CRC the
-+ * caller is responsible for complementing the final return value
-+ * and inserting it into the byte stream.  When checking, a final
-+ * return value of CRC16_GOOD_VALUE indicates a valid CRC.
-+ *
-+ * Reference: Dallas Semiconductor Application Note 27
-+ *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", 
-+ *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
-+ *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
-+ *
-+ ******************************************************************************/
-+
-+static uint16 crc16_table[256] = {
-+    0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
-+    0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
-+    0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
-+    0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
-+    0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
-+    0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
-+    0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
-+    0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
-+    0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
-+    0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
-+    0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
-+    0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
-+    0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
-+    0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
-+    0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
-+    0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
-+    0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
-+    0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
-+    0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
-+    0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
-+    0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
-+    0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
-+    0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
-+    0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
-+    0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
-+    0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
-+    0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
-+    0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
-+    0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
-+    0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
-+    0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
-+    0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
-+};
-+
-+uint16
-+crc16(
-+    uint8 *pdata,  /* pointer to array of data to process */
-+    uint nbytes, /* number of input data bytes to process */
-+    uint16 crc     /* either CRC16_INIT_VALUE or previous return value */
-+)
-+{
-+    while (nbytes-- > 0)
-+        CRC_INNER_LOOP(16, crc, *pdata++);
-+    return crc;
-+}
-+
-+static uint32 crc32_table[256] = {
-+    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
-+    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
-+    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
-+    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
-+    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
-+    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
-+    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
-+    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
-+    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
-+    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
-+    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
-+    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
-+    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
-+    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
-+    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
-+    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
-+    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
-+    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
-+    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
-+    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
-+    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
-+    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
-+    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
-+    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
-+    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
-+    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
-+    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
-+    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
-+    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
-+    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-+    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
-+    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
-+    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
-+    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
-+    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
-+    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
-+    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
-+    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
-+    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
-+    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
-+    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
-+    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
-+    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
-+    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
-+    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
-+    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
-+    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
-+    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-+    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
-+    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
-+    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
-+    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
-+    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
-+    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
-+    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
-+    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
-+    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
-+    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
-+    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
-+    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
-+    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
-+    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
-+    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
-+    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-+};
-+
-+uint32
-+crc32(
-+    uint8 *pdata,  /* pointer to array of data to process */
-+    uint   nbytes, /* number of input data bytes to process */
-+    uint32 crc     /* either CRC32_INIT_VALUE or previous return value */
-+)
-+{
-+    uint8 *pend;
-+#ifdef __mips__
-+    uint8 tmp[4];
-+    ulong *tptr = (ulong *)tmp;
-+
-+      /* in case the beginning of the buffer isn't aligned */
-+      pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc);
-+      nbytes -= (pend - pdata);
-+      while (pdata < pend)
-+              CRC_INNER_LOOP(32, crc, *pdata++);
-+
-+    /* handle bulk of data as 32-bit words */
-+    pend = pdata + (nbytes & 0xfffffffc);
-+    while (pdata < pend) {
-+      *tptr = *((ulong *)pdata)++;
-+        CRC_INNER_LOOP(32, crc, tmp[0]);
-+        CRC_INNER_LOOP(32, crc, tmp[1]);
-+        CRC_INNER_LOOP(32, crc, tmp[2]);
-+        CRC_INNER_LOOP(32, crc, tmp[3]);
-+    }
-+
-+    /* 1-3 bytes at end of buffer */
-+    pend = pdata + (nbytes & 0x03);
-+    while (pdata < pend)
-+        CRC_INNER_LOOP(32, crc, *pdata++);
-+#else
-+    pend = pdata + nbytes;
-+    while (pdata < pend)
-+        CRC_INNER_LOOP(32, crc, *pdata++);
-+#endif
-+       
-+    return crc;
-+}
-+
 +#ifdef notdef
 +#define CLEN  1499
 +#define CBUFSIZ       (CLEN+4)
 +#define CNBUFS                5
 +
-+void testcrc32(void)
-+{
-+      uint j,k,l;
-+      uint8 *buf;
-+      uint len[CNBUFS];
-+      uint32 crcr;
-+      uint32 crc32tv[CNBUFS] =
-+              {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110};
-+
-+      ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL);
-+
-+      /* step through all possible alignments */
-+      for (l=0;l<=4;l++) {
-+              for (j=0; j<CNBUFS; j++) {
-+                      len[j] = CLEN;
-+                      for (k=0; k<len[j]; k++)
-+                              *(buf + j*CBUFSIZ + (k+l)) = (j+k) & 0xff;
-+              }
-+
-+              for (j=0; j<CNBUFS; j++) {
-+                      crcr = crc32(buf + j*CBUFSIZ + l, len[j], CRC32_INIT_VALUE);
-+                      ASSERT(crcr == crc32tv[j]);
-+              }
-+      }
-+
-+      MFREE(buf, CBUFSIZ*CNBUFS);
-+      return;
-+}
 +#endif
-+
-+
-+
-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-11-07 01:12:51.815809250 +0100
-@@ -0,0 +1,763 @@
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/cfe_env.c linux.dev/arch/mips/bcm947xx/broadcom/cfe_env.c
+--- linux.old/arch/mips/bcm947xx/broadcom/cfe_env.c    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/cfe_env.c    2005-12-17 21:40:08.166726750 +0100
+@@ -0,0 +1,234 @@
 +/*
-+ * Generic Broadcom Home Networking Division (HND) DMA module.
-+ * This supports the following chips: BCM42xx, 44xx, 47xx .
++ * NVRAM variable manipulation (Linux kernel half)
 + *
 + * Copyright 2001-2003, Broadcom Corporation
 + * All Rights Reserved.
@@ -1398,765 +916,237 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/hnddma.c linux-2.6.12.5-brc
 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 + *
-+ * $Id: hnddma.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
++ * $Id$
 + */
 +
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
 +#include <typedefs.h>
 +#include <osl.h>
 +#include <bcmendian.h>
 +#include <bcmutils.h>
 +
-+struct dma_info;      /* forward declaration */
-+#define di_t struct dma_info
-+#include <hnddma.h>
-+
-+/* debug/trace */
-+#define       DMA_ERROR(args)
-+#define       DMA_TRACE(args)
-+
-+/* default dma message level(if input msg_level pointer is null in dma_attach()) */
-+static uint dma_msg_level = 0;
-+
-+#define       MAXNAMEL        8
-+#define       MAXDD           (DMAMAXRINGSZ / sizeof (dmadd_t))
-+
-+/* dma engine software state */
-+typedef struct dma_info {
-+      hnddma_t        hnddma;         /* exported structure */
-+      uint            *msg_level;     /* message level pointer */
-+
-+      char            name[MAXNAMEL]; /* callers name for diag msgs */
-+      void            *drv;           /* driver handle */
-+      void            *dev;           /* device handle */
-+      dmaregs_t       *regs;          /* dma engine registers */
-+
-+      dmadd_t         *txd;           /* pointer to chip-specific tx descriptor ring */
-+      uint            txin;           /* index of next descriptor to reclaim */
-+      uint            txout;          /* index of next descriptor to post */
-+      uint            txavail;        /* # free tx descriptors */
-+      void            *txp[MAXDD];    /* parallel array of pointers to packets */
-+      ulong           txdpa;          /* physical address of descriptor ring */
-+      uint            txdalign;       /* #bytes added to alloc'd mem to align txd */
-+
-+      dmadd_t         *rxd;           /* pointer to chip-specific rx descriptor ring */
-+      uint            rxin;           /* index of next descriptor to reclaim */
-+      uint            rxout;          /* index of next descriptor to post */
-+      void            *rxp[MAXDD];    /* parallel array of pointers to packets */
-+      ulong           rxdpa;          /* physical address of descriptor ring */
-+      uint            rxdalign;       /* #bytes added to alloc'd mem to align rxd */
-+
-+      /* tunables */
-+      uint            ntxd;           /* # tx descriptors */
-+      uint            nrxd;           /* # rx descriptors */
-+      uint            rxbufsize;      /* rx buffer size in bytes */
-+      uint            nrxpost;        /* # rx buffers to keep posted */
-+      uint            rxoffset;       /* rxcontrol offset */
-+      uint            ddoffset;       /* add to get dma address of descriptor ring */
-+      uint            dataoffset;     /* add to get dma address of data buffer */
-+} dma_info_t;
-+
-+/* descriptor bumping macros */
-+#define       NEXTTXD(i)      ((i + 1) & (di->ntxd - 1))
-+#define       PREVTXD(i)      ((i - 1) & (di->ntxd - 1))
-+#define       NEXTRXD(i)      ((i + 1) & (di->nrxd - 1))
-+#define       NTXDACTIVE(h, t)        ((t - h) & (di->ntxd - 1))
-+#define       NRXDACTIVE(h, t)        ((t - h) & (di->nrxd - 1))
-+
-+/* macros to convert between byte offsets and indexes */
-+#define       B2I(bytes)      ((bytes) / sizeof (dmadd_t))
-+#define       I2B(index)      ((index) * sizeof (dmadd_t))
++#define NVRAM_SIZE       (0x1ff0)
++static char _nvdata[NVRAM_SIZE] __initdata;
++static char _valuestr[256] __initdata;
 +
-+void*
-+dma_attach(void *drv, void *dev, char *name, dmaregs_t *regs, uint ntxd, uint nrxd,
-+      uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level)
-+{
-+      dma_info_t *di;
-+      void *va;
++/*
++ * TLV types.  These codes are used in the "type-length-value"
++ * encoding of the items stored in the NVRAM device (flash or EEPROM)
++ *
++ * The layout of the flash/nvram is as follows:
++ *
++ * <type> <length> <data ...> <type> <length> <data ...> <type_end>
++ *
++ * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
++ * The "length" field marks the length of the data section, not
++ * including the type and length fields.
++ *
++ * Environment variables are stored as follows:
++ *
++ * <type_env> <length> <flags> <name> = <value>
++ *
++ * If bit 0 (low bit) is set, the length is an 8-bit value.
++ * If bit 0 (low bit) is clear, the length is a 16-bit value
++ * 
++ * Bit 7 set indicates "user" TLVs.  In this case, bit 0 still
++ * indicates the size of the length field.  
++ *
++ * Flags are from the constants below:
++ *
++ */
++#define ENV_LENGTH_16BITS     0x00    /* for low bit */
++#define ENV_LENGTH_8BITS      0x01
 +
-+      ASSERT(ntxd <= MAXDD);
-+      ASSERT(nrxd <= MAXDD);
++#define ENV_TYPE_USER         0x80
 +
-+      /* allocate private info structure */
-+      if ((di = MALLOC(sizeof (dma_info_t))) == NULL)
-+              return (NULL);
-+      bzero((char*)di, sizeof (dma_info_t));
-+
-+      /* set message level */
-+      di->msg_level = msg_level ? msg_level : &dma_msg_level;
-+
-+      DMA_TRACE(("%s: dma_attach: drv 0x%x dev 0x%x regs 0x%x ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", name, (uint)drv, (uint)dev, (uint)regs, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, ddoffset, dataoffset));
-+
-+      /* make a private copy of our callers name */
-+      strncpy(di->name, name, MAXNAMEL);
-+      di->name[MAXNAMEL-1] = '\0';
-+
-+      di->drv = drv;
-+      di->dev = dev;
-+      di->regs = regs;
-+
-+      /* allocate transmit descriptor ring */
-+      if (ntxd) {
-+              if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->txdpa)) == NULL)
-+                      goto fail;
-+              di->txd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN);
-+              di->txdalign = ((uint)di->txd - (uint)va);
-+              di->txdpa = di->txdpa + di->txdalign;
-+              ASSERT(ISALIGNED(di->txd, DMARINGALIGN));
-+      }
-+
-+      /* allocate receive descriptor ring */
-+      if (nrxd) {
-+              if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->rxdpa)) == NULL)
-+                      goto fail;
-+              di->rxd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN);
-+              di->rxdalign = ((uint)di->rxd - (uint)va);
-+              di->rxdpa = di->rxdpa + di->rxdalign;
-+              ASSERT(ISALIGNED(di->rxd, DMARINGALIGN));
-+      }
-+
-+      /* save tunables */
-+      di->ntxd = ntxd;
-+      di->nrxd = nrxd;
-+      di->rxbufsize = rxbufsize;
-+      di->nrxpost = nrxpost;
-+      di->rxoffset = rxoffset;
-+      di->ddoffset = ddoffset;
-+      di->dataoffset = dataoffset;
-+
-+      return ((void*)di);
-+
-+fail:
-+      dma_detach((void*)di);
-+      return (NULL);
-+}
++#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
++#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
 +
-+/* may be called with core in reset */
-+void
-+dma_detach(dma_info_t *di)
-+{
-+      if (di == NULL)
-+              return;
++/*
++ * The actual TLV types we support
++ */
 +
-+      DMA_TRACE(("%s: dma_detach\n", di->name));
++#define ENV_TLV_TYPE_END      0x00    
++#define ENV_TLV_TYPE_ENV      ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
 +
-+      /* shouldn't be here if descriptors are unreclaimed */
-+      ASSERT(di->txin == di->txout);
-+      ASSERT(di->rxin == di->rxout);
++/*
++ * Environment variable flags 
++ */
 +
-+      /* free dma descriptor rings */
-+      if (di->txd)
-+              DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->txd - di->txdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->txdpa);
-+      if (di->rxd)
-+              DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->rxd - di->rxdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->rxdpa);
++#define ENV_FLG_NORMAL                0x00    /* normal read/write */
++#define ENV_FLG_BUILTIN               0x01    /* builtin - not stored in flash */
++#define ENV_FLG_READONLY      0x02    /* read-only - cannot be changed */
 +
-+      /* free our private info structure */
-+      MFREE((void*)di, sizeof (dma_info_t));
-+}
++#define ENV_FLG_MASK          0xFF    /* mask of attributes we keep */
++#define ENV_FLG_ADMIN         0x100   /* lets us internally override permissions */
 +
 +
-+void
-+dma_txreset(dma_info_t *di)
++/*  *********************************************************************
++    *  _nvram_read(buffer,offset,length)
++    *  
++    *  Read data from the NVRAM device
++    *  
++    *  Input parameters: 
++    *            buffer - destination buffer
++    *            offset - offset of data to read
++    *            length - number of bytes to read
++    *            
++    *  Return value:
++    *            number of bytes read, or <0 if error occured
++    ********************************************************************* */
++static int
++_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
 +{
-+      uint32 status;
++    int i;
++    if (offset > NVRAM_SIZE)
++      return -1; 
 +
-+      DMA_TRACE(("%s: dma_txreset\n", di->name));
-+
-+      /* suspend tx DMA first */
-+      W_REG(&di->regs->xmtcontrol, XC_SE);
-+      SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED &&
-+               status != XS_XS_IDLE &&
-+               status != XS_XS_STOPPED,
-+               10000);
++    for ( i = 0; i < length; i++) {
++      buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
++    }
++    return length;
++}
 +
-+      W_REG(&di->regs->xmtcontrol, 0);
-+      SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED,
-+               10000);
 +
-+      if (status != XS_XS_DISABLED) {
-+              DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name));
++static char*
++_strnchr(const char *dest,int c,size_t cnt)
++{
++      while (*dest && (cnt > 0)) {
++      if (*dest == c) return (char *) dest;
++      dest++;
++      cnt--;
 +      }
-+
-+      /* wait for the last transaction to complete */
-+      OSL_DELAY(300);
++      return NULL;
 +}
 +
-+void
-+dma_rxreset(dma_info_t *di)
-+{
-+      uint32 status;
 +
-+      DMA_TRACE(("%s: dma_rxreset\n", di->name));
 +
-+      W_REG(&di->regs->rcvcontrol, 0);
-+      SPINWAIT((status = (R_REG(&di->regs->rcvstatus) & RS_RS_MASK)) != RS_RS_DISABLED,
-+               10000);
++/*
++ * Core support API: Externally visible.
++ */
 +
-+      if (status != RS_RS_DISABLED) {
-+              DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name));
-+      }
-+}
++/*
++ * Get the value of an NVRAM variable
++ * @param     name    name of variable to get
++ * @return    value of variable or NULL if undefined
++ */
 +
-+void
-+dma_txinit(dma_info_t *di)
++char* 
++cfe_env_get(unsigned char *nv_buf, char* name)
 +{
-+      DMA_TRACE(("%s: dma_txinit\n", di->name));
-+
-+      di->txin = di->txout = 0;
-+      di->txavail = di->ntxd - 1;
++    int size;
++    unsigned char *buffer;
++    unsigned char *ptr;
++    unsigned char *envval;
++    unsigned int reclen;
++    unsigned int rectype;
++    int offset;
++    int flg;
++    
++    size = NVRAM_SIZE;
++    buffer = &_nvdata[0];
 +
-+      /* clear tx descriptor ring */
-+      BZERO_SM((void*)di->txd, (di->ntxd * sizeof (dmadd_t)));
-+
-+      W_REG(&di->regs->xmtcontrol, XC_XE);
-+      W_REG(&di->regs->xmtaddr, (di->txdpa + di->ddoffset));
-+}
++    ptr = buffer;
++    offset = 0;
 +
-+bool
-+dma_txenabled(dma_info_t *di)
-+{
-+      uint32 xc;
++    /* Read the record type and length */
++    if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
++      goto error;
++    }
++    
++    while ((*ptr != ENV_TLV_TYPE_END)  && (size > 1)) {
 +
-+      /* If the chip is dead, it is not enabled :-) */
-+      xc = R_REG(&di->regs->xmtcontrol);
-+      return ((xc != 0xffffffff) && (xc & XC_XE));
-+}
++      /* Adjust pointer for TLV type */
++      rectype = *(ptr);
++      offset++;
++      size--;
 +
-+void
-+dma_txsuspend(dma_info_t *di)
-+{
-+      DMA_TRACE(("%s: dma_txsuspend\n", di->name));
-+      OR_REG(&di->regs->xmtcontrol, XC_SE);
-+}
-+
-+void
-+dma_txresume(dma_info_t *di)
-+{
-+      DMA_TRACE(("%s: dma_txresume\n", di->name));
-+      AND_REG(&di->regs->xmtcontrol, ~XC_SE);
-+}
-+
-+bool
-+dma_txsuspended(dma_info_t *di)
-+{
-+      uint32 xc;
-+      uint32 xs;
-+
-+      xc = R_REG(&di->regs->xmtcontrol);
-+      if (xc & XC_SE) {
-+              xs = R_REG(&di->regs->xmtstatus);
-+              return ((xs & XS_XS_MASK) == XS_XS_IDLE);
-+      }
-+      return 0;
-+}
-+
-+bool
-+dma_txstopped(dma_info_t *di)
-+{
-+      return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_STOPPED);
-+}
-+
-+bool
-+dma_rxstopped(dma_info_t *di)
-+{
-+      return ((R_REG(&di->regs->rcvstatus) & RS_RS_MASK) == RS_RS_STOPPED);
-+}
-+
-+void
-+dma_fifoloopbackenable(dma_info_t *di)
-+{
-+      DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
-+      OR_REG(&di->regs->xmtcontrol, XC_LE);
-+}
-+
-+void
-+dma_rxinit(dma_info_t *di)
-+{
-+      DMA_TRACE(("%s: dma_rxinit\n", di->name));
-+
-+      di->rxin = di->rxout = 0;
-+
-+      /* clear rx descriptor ring */
-+      BZERO_SM((void*)di->rxd, (di->nrxd * sizeof (dmadd_t)));
-+
-+      dma_rxenable(di);
-+      W_REG(&di->regs->rcvaddr, (di->rxdpa + di->ddoffset));
-+}
-+
-+void
-+dma_rxenable(dma_info_t *di)
-+{
-+      DMA_TRACE(("%s: dma_rxenable\n", di->name));
-+      W_REG(&di->regs->rcvcontrol, ((di->rxoffset << RC_RO_SHIFT) | RC_RE));
-+}
-+
-+bool
-+dma_rxenabled(dma_info_t *di)
-+{
-+      uint32 rc;
-+
-+      rc = R_REG(&di->regs->rcvcontrol);
-+      return ((rc != 0xffffffff) && (rc & RC_RE));
-+}
-+
-+/*
-+ * The BCM47XX family supports full 32bit dma engine buffer addressing so
-+ * dma buffers can cross 4 Kbyte page boundaries.
-+ */
-+int
-+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+      void *p, *next;
-+      uchar *data;
-+      uint len;
-+      uint txout;
-+      uint32 ctrl;
-+      uint32 pa;
-+
-+      DMA_TRACE(("%s: dma_txfast\n", di->name));
-+
-+      txout = di->txout;
-+      ctrl = 0;
-+
-+      /*
-+       * Walk the chain of packet buffers
-+       * allocating and initializing transmit descriptor entries.
-+       */
-+      for (p = p0; p; p = next) {
-+              data = PKTDATA(di->drv, p);
-+              len = PKTLEN(di->drv, p);
-+              next = PKTNEXT(di->drv, p);
-+
-+              /* return nonzero if out of tx descriptors */
-+              if (NEXTTXD(txout) == di->txin)
-+                      goto outoftxd;
-+
-+              if (len == 0)
-+                      continue;
-+
-+              /* get physical address of buffer start */
-+              pa = (uint32) DMA_MAP(di->dev, data, len, DMA_TX, p);
-+
-+              /* build the descriptor control value */
-+              ctrl = len & CTRL_BC_MASK;
-+
-+              ctrl |= coreflags;
-+              
-+              if (p == p0)
-+                      ctrl |= CTRL_SOF;
-+              if (next == NULL)
-+                      ctrl |= (CTRL_IOC | CTRL_EOF);
-+              if (txout == (di->ntxd - 1))
-+                      ctrl |= CTRL_EOT;
-+
-+              /* init the tx descriptor */
-+              W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
-+              W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+              ASSERT(di->txp[txout] == NULL);
-+
-+              txout = NEXTTXD(txout);
-+      }
-+
-+      /* if last txd eof not set, fix it */
-+      if (!(ctrl & CTRL_EOF))
-+              W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
-+
-+      /* save the packet */
-+      di->txp[PREVTXD(txout)] = p0;
-+
-+      /* bump the tx descriptor index */
-+      di->txout = txout;
-+
-+      /* kick the chip */
-+      W_REG(&di->regs->xmtptr, I2B(txout));
-+
-+      /* tx flow control */
-+      di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+      return (0);
-+
-+outoftxd:
-+      DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name));
-+      PKTFREE(di->drv, p0, TRUE);
-+      di->txavail = 0;
-+      di->hnddma.txnobuf++;
-+      return (-1);
-+}
-+
-+#define       PAGESZ          4096
-+#define       PAGEBASE(x)     ((uint)(x) & ~4095)
-+
-+/*
-+ * Just like above except go through the extra effort of splitting
-+ * buffers that cross 4Kbyte boundaries into multiple tx descriptors.
-+ */
-+int
-+dma_tx(dma_info_t *di, void *p0, uint32 coreflags)
-+{
-+      void *p, *next;
-+      uchar *data;
-+      uint plen, len;
-+      uchar *page, *start, *end;
-+      uint txout;
-+      uint32 ctrl;
-+      uint32 pa;
-+
-+      DMA_TRACE(("%s: dma_tx\n", di->name));
-+
-+      txout = di->txout;
-+      ctrl = 0;
-+
-+      /*
-+       * Walk the chain of packet buffers
-+       * splitting those that cross 4 Kbyte boundaries
-+       * allocating and initializing transmit descriptor entries.
++      /* 
++       * Read the length.  It can be either 1 or 2 bytes
++       * depending on the code 
 +       */
-+      for (p = p0; p; p = next) {
-+              data = PKTDATA(di->drv, p);
-+              plen = PKTLEN(di->drv, p);
-+              next = PKTNEXT(di->drv, p);
-+
-+              if (plen == 0)
-+                      continue;
-+
-+              for (page = (uchar*)PAGEBASE(data);
-+                      page <= (uchar*)PAGEBASE(data + plen - 1);
-+                      page += PAGESZ) {
-+
-+                      /* return nonzero if out of tx descriptors */
-+                      if (NEXTTXD(txout) == di->txin)
-+                              goto outoftxd;
-+
-+                      start = (page == (uchar*)PAGEBASE(data))?  data: page;
-+                      end = (page == (uchar*)PAGEBASE(data + plen))?
-+                              (data + plen): (page + PAGESZ);
-+                      len = end - start;
-+
-+                      /* build the descriptor control value */
-+                      ctrl = len & CTRL_BC_MASK;
-+
-+                      ctrl |= coreflags;
-+
-+                      if ((p == p0) && (start == data))
-+                              ctrl |= CTRL_SOF;
-+                      if ((next == NULL) && (end == (data + plen)))
-+                              ctrl |= (CTRL_IOC | CTRL_EOF);
-+                      if (txout == (di->ntxd - 1))
-+                              ctrl |= CTRL_EOT;
-+
-+                      /* get physical address of buffer start */
-+                      pa = (uint32) DMA_MAP(di->dev, start, len, DMA_TX, p);
-+
-+                      /* init the tx descriptor */
-+                      W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl));
-+                      W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+                      ASSERT(di->txp[txout] == NULL);
-+
-+                      txout = NEXTTXD(txout);
-+              }
++      if (rectype & ENV_LENGTH_8BITS) {
++          /* Read the record type and length - 8 bits */
++          if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
++              goto error;
++          }
++          reclen = *(ptr);
++          size--;
++          offset++;
 +      }
-+
-+      /* if last txd eof not set, fix it */
-+      if (!(ctrl & CTRL_EOF))
-+              W_SM(&di->txd[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF));
-+
-+      /* save the packet */
-+      di->txp[PREVTXD(txout)] = p0;
-+
-+      /* bump the tx descriptor index */
-+      di->txout = txout;
-+
-+      /* kick the chip */
-+      W_REG(&di->regs->xmtptr, I2B(txout));
-+
-+      /* tx flow control */
-+      di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+      return (0);
-+
-+outoftxd:
-+      DMA_ERROR(("%s: dma_tx: out of txds\n", di->name));
-+      PKTFREE(di->drv, p0, TRUE);
-+      di->txavail = 0;
-+      di->hnddma.txnobuf++;
-+      return (-1);
-+}
-+
-+/* returns a pointer to the next frame received, or NULL if there are no more */
-+void*
-+dma_rx(dma_info_t *di)
-+{
-+      void *p;
-+      uint len;
-+      int skiplen = 0;
-+
-+      while ((p = dma_getnextrxp(di, FALSE))) {
-+              /* skip giant packets which span multiple rx descriptors */
-+              if (skiplen > 0) {
-+                      skiplen -= di->rxbufsize;
-+                      if (skiplen < 0)
-+                              skiplen = 0;
-+                      PKTFREE(di->drv, p, FALSE);
-+                      continue;
-+              }
-+
-+              len = ltoh16(*(uint16*)(PKTDATA(di->drv, p)));
-+              DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-+
-+              /* bad frame length check */
-+              if (len > (di->rxbufsize - di->rxoffset)) {
-+                      DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len));
-+                      if (len > 0)
-+                              skiplen = len - (di->rxbufsize - di->rxoffset);
-+                      PKTFREE(di->drv, p, FALSE);
-+                      di->hnddma.rxgiants++;
-+                      continue;
++      else {
++          /* Read the record type and length - 16 bits, MSB first */
++          if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
++              goto error;
++          }
++          reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
++          size -= 2;
++          offset += 2;
++      }
++
++      if (reclen > size)
++          break;      /* should not happen, bad NVRAM */
++
++      switch (rectype) {
++          case ENV_TLV_TYPE_ENV:
++              /* Read the TLV data */
++              if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
++                  goto error;
++              flg = *ptr++;
++              envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
++              if (envval) {
++                  *envval++ = '\0';
++                  memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
++                  _valuestr[(reclen-1)-(envval-ptr)] = '\0';
++#if 0                 
++                  printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
++#endif
++                  if(!strcmp(ptr, name)){
++                      return _valuestr;
++                  }
++                  if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
++                      return _valuestr;
 +              }
-+
-+              /* set actual length */
-+              PKTSETLEN(di->drv, p, (di->rxoffset + len));
-+
 +              break;
-+      }
-+
-+      return (p);
-+}
-+
-+/* post receive buffers */
-+void
-+dma_rxfill(dma_info_t *di)
-+{
-+      void *p;
-+      uint rxin, rxout;
-+      uint ctrl;
-+      uint n;
-+      uint i;
-+      uint32 pa;
-+      uint rxbufsize;
++              
++          default: 
++              /* Unknown TLV type, skip it. */
++              break;
++          }
 +
 +      /*
-+       * Determine how many receive buffers we're lacking
-+       * from the full complement, allocate, initialize,
-+       * and post them, then update the chip rx lastdscr.
++       * Advance to next TLV 
 +       */
++              
++      size -= (int)reclen;
++      offset += reclen;
 +
-+      rxin = di->rxin;
-+      rxout = di->rxout;
-+      rxbufsize = di->rxbufsize;
-+
-+      n = di->nrxpost - NRXDACTIVE(rxin, rxout);
-+
-+      DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
-+
-+      for (i = 0; i < n; i++) {
-+              if ((p = PKTGET(di->drv, rxbufsize, FALSE)) == NULL) {
-+                      DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name));
-+                      di->hnddma.rxnobuf++;
-+                      break;
-+              }
-+
-+              *(uint32*)(OSL_UNCACHED(PKTDATA(di->drv, p))) = 0;
-+
-+              pa = (uint32) DMA_MAP(di->dev, PKTDATA(di->drv, p), rxbufsize, DMA_RX, p);
-+              ASSERT(ISALIGNED(pa, 4));
-+
-+              /* save the free packet pointer */
-+              ASSERT(di->rxp[rxout] == NULL);
-+              di->rxp[rxout] = p;
-+
-+              /* prep the descriptor control value */
-+              ctrl = rxbufsize;
-+              if (rxout == (di->nrxd - 1))
-+                      ctrl |= CTRL_EOT;
-+
-+              /* init the rx descriptor */
-+              W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl));
-+              W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset));
-+
-+              rxout = NEXTRXD(rxout);
-+      }
-+
-+      di->rxout = rxout;
-+
-+      /* update the chip lastdscr pointer */
-+      W_REG(&di->regs->rcvptr, I2B(rxout));
-+}
-+
-+void
-+dma_txreclaim(dma_info_t *di, bool forceall)
-+{
-+      void *p;
-+
-+      DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : ""));
-+
-+      while ((p = dma_getnexttxp(di, forceall)))
-+              PKTFREE(di->drv, p, TRUE);
-+}
-+
-+/*
-+ * Reclaim next completed txd (txds if using chained buffers) and
-+ * return associated packet.
-+ * If 'force' is true, reclaim txd(s) and return associated packet
-+ * regardless of the value of the hardware "curr" pointer.
-+ */
-+void*
-+dma_getnexttxp(dma_info_t *di, bool forceall)
-+{
-+      uint start, end, i;
-+      void *txp;
-+
-+      DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : ""));
-+
-+      txp = NULL;
-+
-+      start = di->txin;
-+      if (forceall)
-+              end = di->txout;
-+      else
-+              end = B2I(R_REG(&di->regs->xmtstatus) & XS_CD_MASK);
-+
-+      if ((start == 0) && (end > di->txout))
-+              goto bogus;
-+
-+      for (i = start; i != end && !txp; i = NEXTTXD(i)) {
-+              DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->txd[i].addr)) - di->dataoffset),
-+                        (BUS_SWAP32(R_SM(&di->txd[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]);
-+              W_SM(&di->txd[i].addr, 0xdeadbeef);
-+              txp = di->txp[i];
-+              di->txp[i] = NULL;
-+      }
-+
-+      di->txin = i;
-+
-+      /* tx flow control */
-+      di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-+
-+      return (txp);
-+
-+bogus:
-+/*
-+      DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n",
-+              start, end, di->txout, forceall));
-+*/
-+      return (NULL);
-+}
-+
-+void
-+dma_rxreclaim(dma_info_t *di)
-+{
-+      void *p;
-+
-+      DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
-+
-+      while ((p = dma_getnextrxp(di, TRUE)))
-+              PKTFREE(di->drv, p, FALSE);
-+}
-+
-+void *
-+dma_getnextrxp(dma_info_t *di, bool forceall)
-+{
-+      uint i;
-+      void *rxp;
-+
-+      /* if forcing, dma engine must be disabled */
-+      ASSERT(!forceall || !dma_rxenabled(di));
-+
-+      i = di->rxin;
-+
-+      /* return if no packets posted */
-+      if (i == di->rxout)
-+              return (NULL);
-+
-+      /* ignore curr if forceall */
-+      if (!forceall && (i == B2I(R_REG(&di->regs->rcvstatus) & RS_CD_MASK)))
-+              return (NULL);
-+
-+      /* get the packet pointer that corresponds to the rx descriptor */
-+      rxp = di->rxp[i];
-+      ASSERT(rxp);
-+      di->rxp[i] = NULL;
-+
-+      /* clear this packet from the descriptor ring */
-+      DMA_UNMAP(di->dev, (BUS_SWAP32(R_SM(&di->rxd[i].addr)) - di->dataoffset),
-+                di->rxbufsize, DMA_RX, rxp);
-+      W_SM(&di->rxd[i].addr, 0xdeadbeef);
-+
-+      di->rxin = NEXTRXD(i);
-+
-+      return (rxp);
-+}
-+
-+char*
-+dma_dumptx(dma_info_t *di, char *buf)
-+{
-+      buf += sprintf(buf, "txd 0x%lx txdpa 0x%lx txp 0x%lx txin %d txout %d txavail %d\n",
-+              (ulong)di->txd, di->txdpa, (ulong)di->txp, di->txin, di->txout, di->txavail);
-+      buf += sprintf(buf, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n",
-+              R_REG(&di->regs->xmtcontrol),
-+              R_REG(&di->regs->xmtaddr),
-+              R_REG(&di->regs->xmtptr),
-+              R_REG(&di->regs->xmtstatus));
-+      return (buf);
-+}
-+
-+char*
-+dma_dumprx(dma_info_t *di, char *buf)
-+{
-+      buf += sprintf(buf, "rxd 0x%lx rxdpa 0x%lx rxp 0x%lx rxin %d rxout %d\n",
-+              (ulong)di->rxd, di->rxdpa, (ulong)di->rxp, di->rxin, di->rxout);
-+      buf += sprintf(buf, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n",
-+              R_REG(&di->regs->rcvcontrol),
-+              R_REG(&di->regs->rcvaddr),
-+              R_REG(&di->regs->rcvptr),
-+              R_REG(&di->regs->rcvstatus));
-+      return (buf);
-+}
-+
-+char*
-+dma_dump(dma_info_t *di, char *buf)
-+{
-+      buf = dma_dumptx(di, buf);
-+      buf = dma_dumprx(di, buf);
-+      return (buf);
-+}
-+
-+uint
-+dma_getvar(dma_info_t *di, char *name)
-+{
-+      if (!strcmp(name, "&txavail"))
-+              return ((uint) &di->txavail);
-+      else {
-+              ASSERT(0);
++      /* Read the next record type */
++      ptr = buffer;
++      if (_nvram_read(nv_buf, ptr,offset,1) != 1)
++          goto error;
 +      }
-+      return (0);
-+}
 +
-+void
-+dma_txblock(dma_info_t *di)
-+{
-+      di->txavail = 0;
-+}
++error:
++    return NULL;
 +
-+void
-+dma_txunblock(dma_info_t *di)
-+{
-+      di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
 +}
 +
-+uint
-+dma_txactive(dma_info_t *di)
-+{
-+      return (NTXDACTIVE(di->txin, di->txout));
-+}
-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-11-07 01:12:51.815809250 +0100
-@@ -0,0 +1,420 @@
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/linux_osl.c linux.dev/arch/mips/bcm947xx/broadcom/linux_osl.c
+--- linux.old/arch/mips/bcm947xx/broadcom/linux_osl.c  1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/linux_osl.c  2005-12-15 17:11:05.818041750 +0100
+@@ -0,0 +1,102 @@
 +/*
 + * Linux OS Independent Layer
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -2164,15 +1154,16 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-
 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 + *
-+ * $Id: linux_osl.c,v 1.2 2005/02/28 13:34:25 jolt Exp $
++ * $Id$
 + */
 +
 +#define LINUX_OSL
 +
 +#include <typedefs.h>
 +#include <bcmendian.h>
++#include <linux/module.h>
 +#include <linuxver.h>
-+#include <linux_osl.h>
++#include <osl.h>
 +#include <bcmutils.h>
 +#include <linux/delay.h>
 +#ifdef mips
@@ -2180,59 +1171,40 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-
 +#endif
 +#include <pcicfg.h>
 +
-+#define PCI_CFG_RETRY 10      
-+
-+void*
-+osl_pktget(void *drv, uint len, bool send)
-+{
-+      struct sk_buff *skb;
-+
-+      if ((skb = dev_alloc_skb(len)) == NULL)
-+              return (NULL);
-+
-+      skb_put(skb, len);
-+
-+      /* ensure the cookie field is cleared */ 
-+      PKTSETCOOKIE(skb, NULL);
-+
-+      return ((void*) skb);
-+}
-+
-+void
-+osl_pktfree(void *p)
-+{
-+      struct sk_buff *skb, *nskb;
-+
-+      skb = (struct sk_buff*) p;
-+
-+      /* perversion: we use skb->next to chain multi-skb packets */
-+      while (skb) {
-+              nskb = skb->next;
-+              skb->next = NULL;
-+              if (skb->destructor) {
-+                      /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */
-+                      dev_kfree_skb_any(skb);
-+              } else {
-+                      /* can free immediately (even in_irq()) if destructor does not exist */
-+                      dev_kfree_skb(skb);
-+              }
-+              skb = nskb;
-+      }
-+}
++#define PCI_CFG_RETRY                 10      
++
++#define OS_HANDLE_MAGIC               0x1234abcd
++#define BCM_MEM_FILENAME_LEN  24
++
++typedef struct bcm_mem_link {
++      struct bcm_mem_link *prev;
++      struct bcm_mem_link *next;
++      uint    size;
++      int     line;
++      char    file[BCM_MEM_FILENAME_LEN];
++} bcm_mem_link_t;
++
++struct os_handle {
++      uint magic;
++      void *pdev;
++      uint malloced;
++      uint failed;
++      bcm_mem_link_t *dbgmem_list;
++};
 +
 +uint32
-+osl_pci_read_config(void *loc, uint offset, uint size)
++osl_pci_read_config(osl_t *osh, uint offset, uint size)
 +{
-+      struct pci_dev *pdev;
 +      uint val;
 +      uint retry=PCI_CFG_RETRY;        
 +
++      ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
++
 +      /* only 4byte access supported */
 +      ASSERT(size == 4);
 +
-+      pdev = (struct pci_dev*)loc;
 +      do {
-+              pci_read_config_dword(pdev, offset, &val);
++              pci_read_config_dword(osh->pdev, offset, &val);
 +              if (val != 0xffffffff)
 +                      break;
 +      } while (retry--);
@@ -2242,356 +1214,45 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/linux_osl.c linux-2.6.12.5-
 +}
 +
 +void
-+osl_pci_write_config(void *loc, uint offset, uint size, uint val)
++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val)
 +{
-+      struct pci_dev *pdev;
 +      uint retry=PCI_CFG_RETRY;        
 +
++      ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC)));
++
 +      /* only 4byte access supported */
 +      ASSERT(size == 4);
 +
-+      pdev = (struct pci_dev*)loc;
-+
 +      do {
-+              pci_write_config_dword(pdev, offset, val);
++              pci_write_config_dword(osh->pdev, offset, val);
 +              if (offset!=PCI_BAR0_WIN)
 +                      break;
-+              if (osl_pci_read_config(loc,offset,size) == val) 
++              if (osl_pci_read_config(osh,offset,size) == val) 
 +                      break;
 +      } while (retry--);
 +
 +}
 +
 +void
-+osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size)
++osl_delay(uint usec)
 +{
-+      ASSERT(0);
++      uint d;
++
++      while (usec > 0) {
++              d = MIN(usec, 1000);
++              udelay(d);
++              usec -= d;
++      }
 +}
 +
-+void
-+osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size)
-+{
-+      ASSERT(0);
-+}
-+
-+void
-+osl_assert(char *exp, char *file, int line)
-+{
-+      char tempbuf[255];
-+
-+      sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line);
-+      panic(tempbuf);
-+}
-+
-+/*
-+ * BINOSL selects the slightly slower function-call-based binary compatible osl.
-+ */
-+#ifdef BINOSL
-+
-+int
-+osl_printf(const char *format, ...)
-+{
-+      va_list args;
-+      char buf[1024];
-+      int len;
-+
-+      /* sprintf into a local buffer because there *is* no "vprintk()".. */
-+      va_start(args, format);
-+      len = vsprintf(buf, format, args);
-+      va_end(args);
-+
-+      if (len > sizeof (buf)) {
-+              printk("osl_printf: buffer overrun\n");
-+              return (0);
-+      }
-+
-+      return (printk(buf));
-+}
-+
-+int
-+osl_sprintf(char *buf, const char *format, ...)
-+{
-+      va_list args;
-+      int rc;
-+
-+      va_start(args, format);
-+      rc = vsprintf(buf, format, args);
-+      va_end(args);
-+      return (rc);
-+}
-+
-+int
-+osl_strcmp(const char *s1, const char *s2)
-+{
-+      return (strcmp(s1, s2));
-+}
-+
-+int
-+osl_strncmp(const char *s1, const char *s2, uint n)
-+{
-+      return (strncmp(s1, s2, n));
-+}
-+
-+int
-+osl_strlen(char *s)
-+{
-+      return (strlen(s));
-+}
-+
-+char*
-+osl_strcpy(char *d, const char *s)
-+{
-+      return (strcpy(d, s));
-+}
-+
-+char*
-+osl_strncpy(char *d, const char *s, uint n)
-+{
-+      return (strncpy(d, s, n));
-+}
-+
-+void
-+bcopy(const void *src, void *dst, int len)
-+{
-+      memcpy(dst, src, len);
-+}
-+
-+int
-+bcmp(const void *b1, const void *b2, int len)
-+{
-+      return (memcmp(b1, b2, len));
-+}
-+
-+void
-+bzero(void *b, int len)
-+{
-+      memset(b, '\0', len);
-+}
-+
-+void*
-+osl_malloc(uint size)
-+{
-+      return (kmalloc(size, GFP_ATOMIC));
-+}
-+
-+void
-+osl_mfree(void *addr, uint size)
-+{
-+      kfree(addr);
-+}
-+
-+uint32
-+osl_readl(volatile uint32 *r)
-+{
-+      return (readl(r));
-+}
-+
-+uint16
-+osl_readw(volatile uint16 *r)
-+{
-+      return (readw(r));
-+}
-+
-+uint8
-+osl_readb(volatile uint8 *r)
-+{
-+      return (readb(r));
-+}
-+
-+void
-+osl_writel(uint32 v, volatile uint32 *r)
-+{
-+      writel(v, r);
-+}
-+
-+void
-+osl_writew(uint16 v, volatile uint16 *r)
-+{
-+      writew(v, r);
-+}
-+
-+void
-+osl_writeb(uint8 v, volatile uint8 *r)
-+{
-+      writeb(v, r);
-+}
-+
-+void *
-+osl_uncached(void *va)
-+{
-+#ifdef mips
-+      return ((void*)KSEG1ADDR(va));
-+#else
-+      return ((void*)va);
-+#endif
-+}
-+
-+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 @@
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/nvram.c linux.dev/arch/mips/bcm947xx/broadcom/nvram.c
+--- linux.old/arch/mips/bcm947xx/broadcom/nvram.c      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/nvram.c      2005-12-18 04:59:36.185204500 +0100
+@@ -0,0 +1,165 @@
 +/*
-+ * NVRAM variable manipulation (common)
++ * NVRAM variable manipulation (Linux kernel half)
 + *
-+ * Copyright 2004, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -2602,394 +1263,63 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram.c linux-2.6.12.5-brcm
 + * $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 <asm/bootinfo.h>
++#include <asm/addrspace.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
 +#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;
++#include <sbconfig.h>
++#include <sbchipc.h>
++#include <sbutils.h>
++#include <sbmips.h>
++#include <sflash.h>
 +
-+/* Free all tuples. Should be locked. */
-+static void  
-+BCMINITFN(nvram_free)(void)
-+{
-+      uint i;
-+      struct nvram_tuple *t, *next;
++/* 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)));
 +
-+      /* 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;
-+      }
++/* Global SB handle */
++extern void *sbh;
++extern spinlock_t bcm947xx_sbh_lock;
++static int cfe_env;
 +
-+      /* Free dead table */
-+      for (t = nvram_dead; t; t = next) {
-+              next = t->next;
-+              BCMINIT(_nvram_free)(t);
-+      }
-+      nvram_dead = NULL;
++extern char *cfe_env_get(char *nv_buf, const char *name);
++              
 +
-+      /* Indicate to per-port code that all tuples have been freed */
-+      BCMINIT(_nvram_free)(NULL);
-+}
++/* Convenience */
++#define sbh_lock bcm947xx_sbh_lock
++#define KB * 1024
++#define MB * 1024 * 1024
 +
-+/* String hash */
-+static INLINE uint
-+hash(const char *s)
++/* Probe for NVRAM header */
++static void __init
++early_nvram_init(void)
 +{
-+      uint hash = 0;
-+
-+      while (*s)
-+              hash = 31 * hash + *s++;
-+
-+      return hash;
-+}
++      struct nvram_header *header;
++      chipcregs_t *cc;
++      struct sflash *info = NULL;
++      int i;
++      uint32 base, off, lim;
++      u32 *src, *dst;
 +
-+/* (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;
++      cfe_env = 0;
++      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:
@@ -3008,6 +1338,21 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.12.
 +              lim = SB_FLASH1_SZ;
 +      }
 +
++      /* XXX: hack for supporting the CFE environment stuff on WGT634U */
++      src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000);
++      dst = (u32 *) nvram_buf;
++      if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) {
++              printk("early_nvram_init: WGT634U NVRAM found.\n");
++
++              for (i = 0; i < 0x1ff0; i++) {
++                      if (*src == 0xFFFFFFFF)
++                              break;
++                      *dst++ = *src++;
++              }
++              cfe_env = 1;
++              return;
++      }
++
 +      off = FLASH_MIN;
 +      while (off <= lim) {
 +              /* Windowed flash access */
@@ -3026,749 +1371,87 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/nvram_linux.c linux-2.6.12.
 +      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);
-+
-+      return ret;
-+}
-+
-+static ssize_t
-+dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-+{
-+      char tmp[100], *name = tmp, *value;
-+      ssize_t ret;
-+
-+      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)
-+{
-+      if (cmd != NVRAM_MAGIC)
-+              return -EINVAL;
-+      return nvram_commit();
-+}
-+
-+static int
-+dev_nvram_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+      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;
-+}
-+
-+static int
-+dev_nvram_open(struct inode *inode, struct file * file)
-+{
-+      MOD_INC_USE_COUNT;
-+      return 0;
-+}
-+
-+static int
-+dev_nvram_release(struct inode *inode, struct file * file)
-+{
-+      MOD_DEC_USE_COUNT;
-+      return 0;
-+}
-+
-+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 order = 0;
-+      struct page *page, *end;
-+
-+      if (nvram_handle)
-+              devfs_unregister(nvram_handle);
-+
-+      if (nvram_major >= 0)
-+              devfs_unregister_chrdev(nvram_major, "nvram");
-+
-+      if (nvram_mtd)
-+              put_mtd_device(nvram_mtd);
-+
-+      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);
-+
-+      _nvram_exit();
-+}
-+
-+static int __init
-+dev_nvram_init(void)
-+{
-+      int order = 0, ret = 0;
-+      struct page *page, *end;
-+      unsigned int i;
-+
-+      /* 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
-+
-+      /* Initialize hash table lock */
-+      spin_lock_init(&nvram_lock);
-+
-+      /* Initialize commit semaphore */
-+      init_MUTEX(&nvram_sem);
-+
-+      /* Register char device */
-+      if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) {
-+              ret = nvram_major;
-+              goto err;
-+      }
-+
-+      /* Initialize hash table */
-+      _nvram_init();
-+
-+      /* 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);
-+
-+      /* Set the SDRAM NCDL value into NVRAM if not already done */
-+      if (getintvar(NULL, "sdram_ncdl") == 0) {
-+              unsigned int ncdl;
-+              char buf[] = "0x00000000";
-+
-+              if ((ncdl = sb_memc_get_ncdl(sbh))) {
-+                      sprintf(buf, "0x%08x", ncdl);
-+                      nvram_set("sdram_ncdl", buf);
-+                      nvram_commit();
-+              }
-+      }
-+
-+      return 0;
-+
-+ err:
-+      dev_nvram_exit();
-+      return ret;
-+}
-+
-+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-11-07 01:12:51.819809500 +0100
-@@ -0,0 +1,950 @@
-+/*
-+ * BCM47XX Sonics SiliconBackplane MIPS core routines
-+ *
-+ * 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: sbmips.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
-+ */
-+
-+#include <typedefs.h>
-+#include <osl.h>
-+#include <sbutils.h>
-+#include <bcmdevs.h>
-+#include <bcmnvram.h>
-+#include <bcmutils.h>
-+#include <hndmips.h>
-+#include <sbconfig.h>
-+#include <sbextif.h>
-+#include <sbchipc.h>
-+#include <sbmemc.h>
-+
-+/*
-+ * Memory segments (32bit kernel mode addresses)
-+ */
-+#undef KUSEG
-+#undef KSEG0
-+#undef KSEG1
-+#undef KSEG2
-+#undef KSEG3
-+#define KUSEG         0x00000000
-+#define KSEG0         0x80000000
-+#define KSEG1         0xa0000000
-+#define KSEG2         0xc0000000
-+#define KSEG3         0xe0000000
-+
-+/*
-+ * Map an address to a certain kernel segment
-+ */
-+#undef KSEG0ADDR
-+#undef KSEG1ADDR
-+#undef KSEG2ADDR
-+#undef KSEG3ADDR
-+#define KSEG0ADDR(a)          (((a) & 0x1fffffff) | KSEG0)
-+#define KSEG1ADDR(a)          (((a) & 0x1fffffff) | KSEG1)
-+#define KSEG2ADDR(a)          (((a) & 0x1fffffff) | KSEG2)
-+#define KSEG3ADDR(a)          (((a) & 0x1fffffff) | KSEG3)
-+
-+/*
-+ * The following macros are especially useful for __asm__
-+ * inline assembler.
-+ */
-+#ifndef __STR
-+#define __STR(x) #x
-+#endif
-+#ifndef STR
-+#define STR(x) __STR(x)
-+#endif
-+
-+/*  *********************************************************************
-+    *  CP0 Registers 
-+    ********************************************************************* */
-+
-+#define C0_INX                0               /* CP0: TLB Index */
-+#define C0_RAND               1               /* CP0: TLB Random */
-+#define C0_TLBLO0     2               /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO      C0_TLBLO0       /* CP0: TLB EntryLo0 */
-+#define C0_TLBLO1     3               /* CP0: TLB EntryLo1 */
-+#define C0_CTEXT      4               /* CP0: Context */
-+#define C0_PGMASK     5               /* CP0: TLB PageMask */
-+#define C0_WIRED      6               /* CP0: TLB Wired */
-+#define C0_BADVADDR   8               /* CP0: Bad Virtual Address */
-+#define C0_COUNT      9               /* CP0: Count */
-+#define C0_TLBHI      10              /* CP0: TLB EntryHi */
-+#define C0_COMPARE    11              /* CP0: Compare */
-+#define C0_SR         12              /* CP0: Processor Status */
-+#define C0_STATUS     C0_SR           /* CP0: Processor Status */
-+#define C0_CAUSE      13              /* CP0: Exception Cause */
-+#define C0_EPC                14              /* CP0: Exception PC */
-+#define C0_PRID               15              /* CP0: Processor Revision Indentifier */
-+#define C0_CONFIG     16              /* CP0: Config */
-+#define C0_LLADDR     17              /* CP0: LLAddr */
-+#define C0_WATCHLO    18              /* CP0: WatchpointLo */
-+#define C0_WATCHHI    19              /* CP0: WatchpointHi */
-+#define C0_XCTEXT     20              /* CP0: XContext */
-+#define C0_DIAGNOSTIC 22              /* CP0: Diagnostic */
-+#define C0_BROADCOM   C0_DIAGNOSTIC   /* CP0: Broadcom Register */
-+#define C0_ECC                26              /* CP0: ECC */
-+#define C0_CACHEERR   27              /* CP0: CacheErr */
-+#define C0_TAGLO      28              /* CP0: TagLo */
-+#define C0_TAGHI      29              /* CP0: TagHi */
-+#define C0_ERREPC     30              /* CP0: ErrorEPC */
-+
-+/*
-+ * Macros to access the system control coprocessor
-+ */
-+
-+#define MFC0(source, sel)                                     \
-+({                                                            \
-+      int __res;                                              \
-+      __asm__ __volatile__(                                   \
-+      ".set\tnoreorder\n\t"                                   \
-+      ".set\tnoat\n\t"                                        \
-+      ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
-+      "move\t%0,$1\n\t"                                       \
-+      ".set\tat\n\t"                                          \
-+      ".set\treorder"                                         \
-+      :"=r" (__res)                                           \
-+      :                                                       \
-+      :"$1");                                                 \
-+      __res;                                                  \
-+})
++      return;
 +
-+#define MTC0(source, sel, value)                              \
-+do {                                                          \
-+      __asm__ __volatile__(                                   \
-+      ".set\tnoreorder\n\t"                                   \
-+      ".set\tnoat\n\t"                                        \
-+      "move\t$1,%z0\n\t"                                      \
-+      ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
-+      ".set\tat\n\t"                                          \
-+      ".set\treorder"                                         \
-+      :                                                       \
-+      :"Jr" (value)                                           \
-+      :"$1");                                                 \
-+} while (0)
++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++);
++}
 +
-+/*
-+ * R4x00 interrupt enable / cause bits
-+ */
-+#undef IE_SW0
-+#undef IE_SW1
-+#undef IE_IRQ0
-+#undef IE_IRQ1
-+#undef IE_IRQ2
-+#undef IE_IRQ3
-+#undef IE_IRQ4
-+#undef IE_IRQ5
-+#define IE_SW0                (1<< 8)
-+#define IE_SW1                (1<< 9)
-+#define IE_IRQ0               (1<<10)
-+#define IE_IRQ1               (1<<11)
-+#define IE_IRQ2               (1<<12)
-+#define IE_IRQ3               (1<<13)
-+#define IE_IRQ4               (1<<14)
-+#define IE_IRQ5               (1<<15)
++/* Early (before mm or mtd) read-only access to NVRAM */
++char * __init nvram_get(const char *name)
++{
++      char *var, *value, *end, *eq;
 +
-+/*
-+ * Bitfields in the R4xx0 cp0 status register
-+ */
-+#define ST0_IE                        0x00000001
-+#define ST0_EXL                       0x00000002
-+#define ST0_ERL                       0x00000004
-+#define ST0_KSU                       0x00000018
-+#  define KSU_USER            0x00000010
-+#  define KSU_SUPERVISOR      0x00000008
-+#  define KSU_KERNEL          0x00000000
-+#define ST0_UX                        0x00000020
-+#define ST0_SX                        0x00000040
-+#define ST0_KX                        0x00000080
-+#define ST0_DE                        0x00010000
-+#define ST0_CE                        0x00020000
++      if (!name)
++              return NULL;
 +
-+/*
-+ * Status register bits available in all MIPS CPUs.
-+ */
-+#define ST0_IM                        0x0000ff00
-+#define ST0_CH                        0x00040000
-+#define ST0_SR                        0x00100000
-+#define ST0_TS                        0x00200000
-+#define ST0_BEV                       0x00400000
-+#define ST0_RE                        0x02000000
-+#define ST0_FR                        0x04000000
-+#define ST0_CU                        0xf0000000
-+#define ST0_CU0                       0x10000000
-+#define ST0_CU1                       0x20000000
-+#define ST0_CU2                       0x40000000
-+#define ST0_CU3                       0x80000000
-+#define ST0_XX                        0x80000000      /* MIPS IV naming */
++      /* Too early? */
++      if (sbh == NULL)
++              return NULL;
 +
-+/*
-+ * Cache Operations
-+ */
++      if (!nvram_buf[0])
++              early_nvram_init();
 +
-+#ifndef Fill_I
-+#define Fill_I                        0x14
-+#endif
++      if (cfe_env)
++              return cfe_env_get(nvram_buf, name);
 +
-+#define cache_unroll(base,op)                 \
-+      __asm__ __volatile__("                  \
-+              .set noreorder;                 \
-+              .set mips3;                     \
-+              cache %1, (%0);                 \
-+              .set mips0;                     \
-+              .set reorder"                   \
-+              :                               \
-+              : "r" (base),                   \
-+                "i" (op));
++      /* 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;
++      }
 +
-+/* 
-+ * These are the UART port assignments, expressed as offsets from the base
-+ * register.  These assignments should hold for any serial port based on
-+ * a 8250, 16450, or 16550(A).
++      return NULL;
++}
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbmips.c linux.dev/arch/mips/bcm947xx/broadcom/sbmips.c
+--- linux.old/arch/mips/bcm947xx/broadcom/sbmips.c     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/sbmips.c     2005-12-15 16:46:31.122961250 +0100
+@@ -0,0 +1,1038 @@
++/*
++ * BCM47XX Sonics SiliconBackplane MIPS core routines
++ *
++ * 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$
 + */
 +
-+#define UART_MCR      4       /* Out: Modem Control Register */
-+#define UART_MSR      6       /* In:  Modem Status Register */
-+#define UART_MCR_LOOP 0x10    /* Enable loopback test mode */
++#include <typedefs.h>
++#include <osl.h>
++#include <sbutils.h>
++#include <bcmdevs.h>
++#include <bcmnvram.h>
++#include <bcmutils.h>
++#include <hndmips.h>
++#include <sbconfig.h>
++#include <sbextif.h>
++#include <sbchipc.h>
++#include <sbmemc.h>
++#include <mipsinc.h>
++#include <sbutils.h>
 +
-+/* 
++/*
 + * Returns TRUE if an external UART exists at the given base
 + * register.
 + */
 +static bool
-+serial_exists(uint8 *regs)
++BCMINITFN(serial_exists)(uint8 *regs)
 +{
 +      uint8 save_mcr, status1;
 +
@@ -3780,12 +1463,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      return (status1 == 0x90);
 +}
 +
-+/* 
++/*
 + * Initializes UART access. The callback function will be called once
 + * per found UART.
-+*/
++ */
 +void
-+sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift))
++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift))
 +{
 +      void *regs;
 +      ulong base;
@@ -3811,7 +1494,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              n = 2;
 +              for (i = 0; i < 2; i++) {
 +                      regs = (void *) REG_MAP(base + (i * 8), 8);
-+                      if (serial_exists(regs)) {
++                      if (BCMINIT(serial_exists)(regs)) {
 +                              /* Set GPIO 1 to be the external UART IRQ */
 +                              W_REG(&eir->gpiointmask, 2);
 +                              if (add)
@@ -3841,27 +1524,35 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +                                                R_REG(&cc->clockcontrol_n),
 +                                                R_REG(&cc->clockcontrol_m2));
 +                      div = 1;
-+              } else if (rev >= 3) {
-+                      /* Internal backplane clock */
-+                      baud_base = sb_clock_rate(pll,
-+                                                R_REG(&cc->clockcontrol_n),
-+                                                R_REG(&cc->clockcontrol_sb));
-+                      div = 2;        /* Minimum divisor */
-+                      W_REG(&cc->uart_clkdiv, div);
 +              } else {
-+                      /* Fixed internal backplane clock */
-+                      baud_base = 88000000;
-+                      div = 48;
-+              }
-+
-+              /* Clock source depends on strapping if UartClkOverride is unset */
-+              if ((rev > 0) && ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) {
-+                      if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
-+                              /* Internal divided backplane clock */
-+                              baud_base /= div;
++                      if (rev >= 11) {
++                              /* Fixed ALP clock */
++                              baud_base = 20000000;
++                              div = 1;
++                              /* Set the override bit so we don't divide it */
++                              W_REG(&cc->corecontrol, CC_UARTCLKO);
++                      } else if (rev >= 3) {
++                              /* Internal backplane clock */
++                              baud_base = sb_clock(sbh);
++                              div = 2;        /* Minimum divisor */
++                              W_REG(&cc->clkdiv,
++                                    ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div));
 +                      } else {
-+                              /* Assume external clock of 1.8432 MHz */
-+                              baud_base = 1843200;
++                              /* Fixed internal backplane clock */
++                              baud_base = 88000000;
++                              div = 48;
++                      }
++
++                      /* Clock source depends on strapping if UartClkOverride is unset */
++                      if ((rev > 0) &&
++                          ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) {
++                              if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
++                                      /* Internal divided backplane clock */
++                                      baud_base /= div;
++                              } else {
++                                      /* Assume external clock of 1.8432 MHz */
++                                      baud_base = 1843200;
++                              }
 +                      }
 +              }
 +
@@ -3880,9 +1571,90 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      }
 +}
 +
++/*
++ * Initialize jtag master and return handle for
++ * jtag_rwreg. Returns NULL on failure.
++ */
++void *
++sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap)
++{
++      void *regs;
++
++      if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) {
++              chipcregs_t *cc = (chipcregs_t *) regs;
++              uint32 tmp;
++
++              /*
++               * Determine jtagm availability from
++               * core revision and capabilities.
++               */
++              tmp = sb_corerev(sbh);
++              /*
++               * Corerev 10 has jtagm, but the only chip
++               * with it does not have a mips, and
++               * the layout of the jtagcmd register is
++               * different. We'll only accept >= 11.
++               */
++              if (tmp < 11)
++                      return (NULL);
++
++              tmp = R_REG(&cc->capabilities);
++              if ((tmp & CAP_JTAGP) == 0)
++                      return (NULL);
++
++              /* Set clock divider if requested */
++              if (clkd != 0) {
++                      tmp = R_REG(&cc->clkdiv);
++                      tmp = (tmp & ~CLKD_JTAG) |
++                              ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG);
++                      W_REG(&cc->clkdiv, tmp);
++              }
++
++              /* Enable jtagm */
++              tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0);
++              W_REG(&cc->jtagctrl, tmp);
++      }
++
++      return (regs);
++}
++
++void
++sb_jtagm_disable(void *h)
++{
++      chipcregs_t *cc = (chipcregs_t *)h;
++
++      W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN);
++}
++
++/*
++ * Read/write a jtag register. Assumes a target with
++ * 8 bit IR and 32 bit DR.
++ */
++#define       IRWIDTH         8
++#define       DRWIDTH         32
++uint32
++jtag_rwreg(void *h, uint32 ir, uint32 dr)
++{
++      chipcregs_t *cc = (chipcregs_t *) h;
++      uint32 tmp;
++
++      W_REG(&cc->jtagir, ir);
++      W_REG(&cc->jtagdr, dr);
++      tmp = JCMD_START | JCMD_ACC_IRDR |
++              ((IRWIDTH - 1) << JCMD_IRW_SHIFT) |
++              (DRWIDTH - 1);
++      W_REG(&cc->jtagcmd, tmp);
++      while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) {
++              /* OSL_DELAY(1); */
++      }
++
++      tmp = R_REG(&cc->jtagdr);
++      return (tmp);
++}
++
 +/* Returns the SB interrupt flag of the current core. */
 +uint32
-+sb_flag(void *sbh)
++sb_flag(sb_t *sbh)
 +{
 +      void *regs;
 +      sbconfig_t *sb;
@@ -3909,12 +1681,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      SBIPS_INT4_SHIFT
 +};
 +
-+/* 
++/*
 + * Returns the MIPS IRQ assignment of the current core. If unassigned,
 + * 0 is returned.
 + */
 +uint
-+sb_irq(void *sbh)
++sb_irq(sb_t *sbh)
 +{
 +      uint idx;
 +      void *regs;
@@ -3947,7 +1719,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +/* Clears the specified MIPS IRQ. */
 +static void
-+sb_clearirq(void *sbh, uint irq)
++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq)
 +{
 +      void *regs;
 +      sbconfig_t *sb;
@@ -3963,12 +1735,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              OR_REG(&sb->sbipsflag, sbips_int_mask[irq]);
 +}
 +
-+/* 
++/*
 + * Assigns the specified MIPS IRQ to the specified core. Shared MIPS
 + * IRQ 0 may be assigned more than once.
 + */
 +static void
-+sb_setirq(void *sbh, uint irq, uint coreid, uint coreunit)
++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit)
 +{
 +      void *regs;
 +      sbconfig_t *sb;
@@ -3991,14 +1763,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq];
 +              W_REG(&sb->sbipsflag, flag);
 +      }
-+}     
++}
 +
-+/* 
++/*
 + * Initializes clocks and interrupts. SB and NVRAM access must be
 + * initialized prior to calling.
 + */
 +void
-+sb_mips_init(void *sbh)
++BCMINITFN(sb_mips_init)(sb_t *sbh)
 +{
 +      ulong hz, ns, tmp;
 +      extifregs_t *eir;
@@ -4033,45 +1805,66 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              tmp = CEIL(10, ns) << FW_W3_SHIFT;      /* W3 = 10nS */
 +              tmp |= CEIL(10, ns) << FW_W1_SHIFT;     /* W1 = 10nS */
 +              tmp |= CEIL(120, ns);                   /* W0 = 120nS */
-+              W_REG(&cc->parallelflashwaitcnt, tmp);
++              
++              // Added by Chen-I for 5365
++              if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
++              {
++                      W_REG(&cc->flash_waitcount, tmp);
++                      W_REG(&cc->pcmcia_memwait, tmp);
++              }
++              else
++              {
++                      if (sb_corerev(sbh) < 9)
++                              W_REG(&cc->flash_waitcount, tmp);
 +
-+              W_REG(&cc->cs01memwaitcnt, tmp);
++                      if ((sb_corerev(sbh) < 9) ||
++                       ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) {
++                              W_REG(&cc->pcmcia_memwait, tmp);
++                      }
++              }
 +      }
 +
 +      /* Chip specific initialization */
-+      switch (sb_chip(sbh)) {
++      switch (BCMINIT(sb_chip)(sbh)) {
 +      case BCM4710_DEVICE_ID:
 +              /* Clear interrupt map */
 +              for (irq = 0; irq <= 4; irq++)
-+                      sb_clearirq(sbh, irq);
-+              sb_setirq(sbh, 0, SB_CODEC, 0);
-+              sb_setirq(sbh, 0, SB_EXTIF, 0);
-+              sb_setirq(sbh, 2, SB_ENET, 1);
-+              sb_setirq(sbh, 3, SB_ILINE20, 0);
-+              sb_setirq(sbh, 4, SB_PCI, 0);
++                      BCMINIT(sb_clearirq)(sbh, irq);
++              BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0);
++              BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0);
++              BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1);
++              BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0);
++              BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0);
 +              ASSERT(eir);
-+              value = nvram_get("et0phyaddr");
++              value = BCMINIT(nvram_get)("et0phyaddr");
 +              if (value && !strcmp(value, "31")) {
 +                      /* Enable internal UART */
 +                      W_REG(&eir->corecontrol, CC_UE);
 +                      /* Give USB its own interrupt */
-+                      sb_setirq(sbh, 1, SB_USB, 0);
++                      BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0);
 +              } else {
 +                      /* Disable internal UART */
 +                      W_REG(&eir->corecontrol, 0);
 +                      /* Give Ethernet its own interrupt */
-+                      sb_setirq(sbh, 1, SB_ENET, 0);
-+                      sb_setirq(sbh, 0, SB_USB, 0);
++                      BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0);
++                      BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0);
 +              }
 +              break;
-+      case BCM4310_DEVICE_ID:
-+              MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22));
++      case BCM5350_DEVICE_ID:
++              /* Clear interrupt map */
++              for (irq = 0; irq <= 4; irq++)
++                      BCMINIT(sb_clearirq)(sbh, irq);
++              BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0);
++              BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0);
++              BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0);
++              BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0);
++              BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0);
 +              break;
 +      }
 +}
 +
 +uint32
-+sb_mips_clock(void *sbh)
++BCMINITFN(sb_mips_clock)(sb_t *sbh)
 +{
 +      extifregs_t *eir;
 +      chipcregs_t *cc;
@@ -4090,18 +1883,35 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
 +              pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
 +              n = R_REG(&cc->clockcontrol_n);
-+              if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4))
++              if ((pll_type == PLL_TYPE2) ||
++                  (pll_type == PLL_TYPE4) ||
++                  (pll_type == PLL_TYPE6) ||
++                  (pll_type == PLL_TYPE7))
 +                      m = R_REG(&cc->clockcontrol_mips);
-+              else if (pll_type == PLL_TYPE3) {
++              else if (pll_type == PLL_TYPE5) {
 +                      rate = 200000000;
 +                      goto out;
++              }
++              else if (pll_type == PLL_TYPE3) {
++                      if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */
++                              rate = 200000000;
++                              goto out;
++                      } else
++                              m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */
 +              } else
 +                      m = R_REG(&cc->clockcontrol_sb);
 +      } else
 +              goto out;
 +
-+      /* calculate rate */
-+      rate = sb_clock_rate(pll_type, n, m);
++      // Added by Chen-I for 5365 
++      if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
++              rate = 100000000;
++      else
++              /* calculate rate */
++              rate = sb_clock_rate(pll_type, n, m);
++
++      if (pll_type == PLL_TYPE6)
++              rate = SB2MIPS_T6(rate);
 +
 +out:
 +      /* switch back to previous core */
@@ -4110,26 +1920,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      return rate;
 +}
 +
-+static void
-+icache_probe(int *size, int *lsize)
-+{
-+      uint32 config1;
-+      uint sets, ways;
-+
-+      config1 = MFC0(C0_CONFIG, 1);
-+
-+      /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
-+      if ((*lsize = ((config1 >> 19) & 7)))
-+              *lsize = 2 << *lsize;
-+      sets = 64 << ((config1 >> 22) & 7);
-+      ways = 1 + ((config1 >> 16) & 7);
-+      *size = *lsize * sets * ways;
-+}
-+
 +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
 +
 +static void
-+handler(void)
++BCMINITFN(handler)(void)
 +{
 +      /* Step 11 */
 +      __asm__ (
@@ -4139,7 +1933,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      /* Disable interrupts */
 +      /*      MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */
 +              "mfc0 $15, $12\n\t"
-+              "and $15, $15, -31746\n\t"
++      /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */
++              "li $14, -31746\n\t"
++              "and $15, $15, $14\n\t"
 +              "mtc0 $15, $12\n\t"
 +              "eret\n\t"
 +              "nop\n\t"
@@ -4150,7 +1946,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +/* The following MUST come right after handler() */
 +static void
-+afterhandler(void)
++BCMINITFN(afterhandler)(void)
 +{
 +}
 +
@@ -4158,22 +1954,24 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 + * Set the MIPS, backplane and PCI clocks as closely as possible.
 + */
 +bool
-+sb_mips_setclock(void *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock)
++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock)
 +{
 +      extifregs_t *eir = NULL;
 +      chipcregs_t *cc = NULL;
 +      mipsregs_t *mipsr = NULL;
-+      volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci;
-+      uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, new_ratio;
++      volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2;
++      uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg;
 +      uint32 pll_type, sync_mode;
++      uint ic_size, ic_lsize;
 +      uint idx, i;
-+      struct {
++      typedef struct {
 +              uint32 mipsclock;
 +              uint16 n;
 +              uint32 sb;
 +              uint32 pci33;
 +              uint32 pci25;
-+      } type1_table[] = {
++      } n3m_table_t;
++      static n3m_table_t BCMINITDATA(type1_table)[] = {
 +              {  96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /*  96.000 32.000 24.000 */
 +              { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */
 +              { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */
@@ -4197,56 +1995,91 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      };
 +      typedef struct {
 +              uint32 mipsclock;
++              uint16 n;
++              uint32 m2; /* that is the clockcontrol_m2 */
++      } type3_table_t;
++      static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */
++              { 150000000, 0x311, 0x4020005 },
++              { 200000000, 0x311, 0x4020003 },
++      };
++      typedef struct {
++              uint32 mipsclock;
 +              uint32 sbclock;
 +              uint16 n;
 +              uint32 sb;
 +              uint32 pci33;
 +              uint32 m2;
 +              uint32 m3;
-+              uint32 ratio;
++              uint32 ratio_cfg;
 +              uint32 ratio_parm;
 +      } n4m_table_t;
 +
-+      n4m_table_t type2_table[] = {
-+              { 180000000,  80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 180000000,  90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
-+              { 200000000, 100000000, 0x0303, 0x01000000, 0x01000600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
-+              { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
-+              { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
-+              { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
-+              { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
-+              { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 },
-+              { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 0x21, 0x0aaa0555 },
-+              { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
-+              { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 0x21, 0x0aaa0555 },
-+              { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 0x94, 0x012a0115 },
-+              { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 0x21, 0x0aaa0555 }
++      static n4m_table_t BCMINITDATA(type2_table)[] = {
++              { 180000000,  80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 180000000,  90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
++              { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 },
++              { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
++              { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
++              { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
++              { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
++              { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 },
++              { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 },
++              { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
++              { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 },
++              { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100,  8, 0x012a00a9 },
++              { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 }
++      };
++
++      static n4m_table_t BCMINITDATA(type4_table)[] = {
++              { 192000000,  96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
++              { 198000000,  99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
++              { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
++              { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
++              { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005,  8, 0x012a00a9 },
++              { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 },
++              { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 },
++              { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002,  9, 0x02520129 },
++              { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
++              { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 },
++              { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 },
++              { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
++              { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 },
++              { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002,  9, 0x02520129 },
++              { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 }
 +      };
 +
-+      n4m_table_t type4_table[] = {
-+              { 192000000,  96000000, 0x0702, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
-+              { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 0x21, 0x0aaa0555 },
-+              { 216000000, 108000000, 0x0211, 0x11020005, 0x11030303, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
-+              { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x11030305, 0x04000005, 0x94, 0x012a00a9 },
-+              { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 0x21, 0x0aaa0555 },
-+              { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 0x21, 0x0aaa0555 },
-+              { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
-+              { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 0x21, 0x0aaa0555 },
-+              { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
-+              { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
-+              { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 0x73, 0x254a14a9 },
-+              { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 0x52, 0x02520129 }
++      static n4m_table_t BCMINITDATA(type7_table)[] = {
++              { 183333333,  91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
++              { 187500000,  93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 },
++              { 196875000,  98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 },
++              { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 },
++              { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
++              { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
++              { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 },
++              { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 },
++              { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 },
++              { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 }
 +      };
-+      uint icache_size, ic_lsize;
++
 +      ulong start, end, dst;
 +      bool ret = FALSE;
 +
 +      /* get index of the current core */
 +      idx = sb_coreidx(sbh);
++      clockcontrol_m2 = NULL;
 +
 +      /* switch to extif or chipc core */
 +      if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) {
@@ -4254,18 +2087,31 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              clockcontrol_n = &eir->clockcontrol_n;
 +              clockcontrol_sb = &eir->clockcontrol_sb;
 +              clockcontrol_pci = &eir->clockcontrol_pci;
++              clockcontrol_m2 = &cc->clockcontrol_m2;
 +      } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
 +              pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
-+              clockcontrol_n = &cc->clockcontrol_n;
-+              clockcontrol_sb = &cc->clockcontrol_sb;
-+              clockcontrol_pci = &cc->clockcontrol_pci;
++              if (pll_type == PLL_TYPE6) {
++                      clockcontrol_n = NULL;
++                      clockcontrol_sb = NULL;
++                      clockcontrol_pci = NULL;
++              } else {
++                      clockcontrol_n = &cc->clockcontrol_n;
++                      clockcontrol_sb = &cc->clockcontrol_sb;
++                      clockcontrol_pci = &cc->clockcontrol_pci;
++                      clockcontrol_m2 = &cc->clockcontrol_m2;
++              }
 +      } else
 +              goto done;
 +
-+      /* Store the current clock register values */
-+      orig_n = R_REG(clockcontrol_n);
-+      orig_sb = R_REG(clockcontrol_sb);
-+      orig_pci = R_REG(clockcontrol_pci);
++      if (pll_type == PLL_TYPE6) {
++              /* Silence compilers */
++              orig_n = orig_sb = orig_pci = 0;
++      } else {
++              /* Store the current clock register values */
++              orig_n = R_REG(clockcontrol_n);
++              orig_sb = R_REG(clockcontrol_sb);
++              orig_pci = R_REG(clockcontrol_pci);
++      }
 +
 +      if (pll_type == PLL_TYPE1) {
 +              /* Keep the current PCI clock if not specified */
@@ -4275,10 +2121,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              }
 +
 +              /* Search for the closest MIPS clock less than or equal to a preferred value */
-+              for (i = 0; i < ARRAYSIZE(type1_table); i++) {
-+                      ASSERT(type1_table[i].mipsclock ==
-+                             sb_clock_rate(pll_type, type1_table[i].n, type1_table[i].sb));
-+                      if (type1_table[i].mipsclock > mipsclock)
++              for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) {
++                      ASSERT(BCMINIT(type1_table)[i].mipsclock ==
++                             sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb));
++                      if (BCMINIT(type1_table)[i].mipsclock > mipsclock)
 +                              break;
 +              }
 +              if (i == 0) {
@@ -4288,35 +2134,99 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +                      ret = TRUE;
 +                      i--;
 +              }
-+              ASSERT(type1_table[i].mipsclock <= mipsclock);
++              ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock);
 +
 +              /* No PLL change */
-+              if ((orig_n == type1_table[i].n) &&
-+                  (orig_sb == type1_table[i].sb) &&
-+                  (orig_pci == type1_table[i].pci33))
++              if ((orig_n == BCMINIT(type1_table)[i].n) &&
++                  (orig_sb == BCMINIT(type1_table)[i].sb) &&
++                  (orig_pci == BCMINIT(type1_table)[i].pci33))
 +                      goto done;
 +
 +              /* Set the PLL controls */
-+              W_REG(clockcontrol_n, type1_table[i].n);
-+              W_REG(clockcontrol_sb, type1_table[i].sb);
++              W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n);
++              W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb);
 +              if (pciclock == 25000000)
-+                      W_REG(clockcontrol_pci, type1_table[i].pci25);
++                      W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25);
 +              else
-+                      W_REG(clockcontrol_pci, type1_table[i].pci33);
++                      W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33);
++
++              /* Reset */
++              sb_watchdog(sbh, 1);
++
++              while (1);
++      } else if ((pll_type == PLL_TYPE3) &&
++                 (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) {
++              /* 5350 */
++              /* Search for the closest MIPS clock less than or equal to a preferred value */
++
++              for (i = 0; i < ARRAYSIZE(type3_table); i++) {
++                      if (type3_table[i].mipsclock > mipsclock)
++                              break;
++              }
++              if (i == 0) {
++                      ret = FALSE;
++                      goto done;
++              } else {
++                      ret = TRUE;
++                      i--;
++              }
++              ASSERT(type3_table[i].mipsclock <= mipsclock);
++
++              /* No PLL change */
++              orig_m2 = R_REG(&cc->clockcontrol_m2);
++              if ((orig_n == type3_table[i].n) &&
++                  (orig_m2 == type3_table[i].m2)) {
++                      goto done;
++              }
++
++              /* Set the PLL controls */
++              W_REG(clockcontrol_n, type3_table[i].n);
++              W_REG(clockcontrol_m2, type3_table[i].m2);
 +
 +              /* Reset */
 +              sb_watchdog(sbh, 1);
 +              while (1);
-+      } else if ((pll_type == PLL_TYPE2) || (pll_type == PLL_TYPE4)) {
-+              n4m_table_t *table = (pll_type == PLL_TYPE2) ? type2_table : type4_table;
-+              uint tabsz = (pll_type == PLL_TYPE2) ? ARRAYSIZE(type2_table) : ARRAYSIZE(type4_table);
++      } else if ((pll_type == PLL_TYPE2) ||
++                 (pll_type == PLL_TYPE4) ||
++                 (pll_type == PLL_TYPE6) ||
++                 (pll_type == PLL_TYPE7)) {
++              n4m_table_t *table = NULL, *te;
++              uint tabsz = 0;
 +
 +              ASSERT(cc);
 +
++              orig_mips = R_REG(&cc->clockcontrol_mips);
++
++              if (pll_type == PLL_TYPE6) {
++                      uint32 new_mips = 0;
++
++                      ret = TRUE;
++                      if (mipsclock <= SB2MIPS_T6(CC_T6_M1))
++                              new_mips = CC_T6_MMASK;
++
++                      if (orig_mips == new_mips)
++                              goto done;
++
++                      W_REG(&cc->clockcontrol_mips, new_mips);
++                      goto end_fill;
++              }
++
++              if (pll_type == PLL_TYPE2) {
++                      table = BCMINIT(type2_table);
++                      tabsz = ARRAYSIZE(BCMINIT(type2_table));
++              } else if (pll_type == PLL_TYPE4) {
++                      table = BCMINIT(type4_table);
++                      tabsz = ARRAYSIZE(BCMINIT(type4_table));
++              } else if (pll_type == PLL_TYPE7) {
++                      table = BCMINIT(type7_table);
++                      tabsz = ARRAYSIZE(BCMINIT(type7_table));
++              } else
++                      ASSERT("No table for plltype" == NULL);
++
 +              /* Store the current clock register values */
 +              orig_m2 = R_REG(&cc->clockcontrol_m2);
-+              orig_mips = R_REG(&cc->clockcontrol_mips);
 +              orig_ratio_parm = 0;
++              orig_ratio_cfg = 0;
 +
 +              /* Look up current ratio */
 +              for (i = 0; i < tabsz; i++) {
@@ -4326,6 +2236,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +                          (orig_m2 == table[i].m2) &&
 +                          (orig_mips == table[i].m3)) {
 +                              orig_ratio_parm = table[i].ratio_parm;
++                              orig_ratio_cfg = table[i].ratio_cfg;
 +                              break;
 +                      }
 +              }
@@ -4342,50 +2253,55 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +                      ret = FALSE;
 +                      goto done;
 +              } else {
++                      te = &table[i];
 +                      ret = TRUE;
 +              }
 +
 +              /* No PLL change */
-+              if ((orig_n == table[i].n) &&
-+                  (orig_sb == table[i].sb) &&
-+                  (orig_pci == table[i].pci33) &&
-+                  (orig_m2 == table[i].m2) &&
-+                  (orig_mips == table[i].m3))
++              if ((orig_n == te->n) &&
++                  (orig_sb == te->sb) &&
++                  (orig_pci == te->pci33) &&
++                  (orig_m2 == te->m2) &&
++                  (orig_mips == te->m3))
 +                      goto done;
 +
 +              /* Set the PLL controls */
-+              W_REG(clockcontrol_n, table[i].n);
-+              W_REG(clockcontrol_sb, table[i].sb);
-+              W_REG(clockcontrol_pci, table[i].pci33);
-+              W_REG(&cc->clockcontrol_m2, table[i].m2);
-+              W_REG(&cc->clockcontrol_mips, table[i].m3);
++              W_REG(clockcontrol_n, te->n);
++              W_REG(clockcontrol_sb, te->sb);
++              W_REG(clockcontrol_pci, te->pci33);
++              W_REG(&cc->clockcontrol_m2, te->m2);
++              W_REG(&cc->clockcontrol_mips, te->m3);
++
++              /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */
++              if ((pll_type == PLL_TYPE7) &&
++                  (te->sb != te->m2) &&
++                  (sb_clock_rate(pll_type, te->n, te->m2) == 120000000))
++                      W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100);
 +
 +              /* No ratio change */
-+              if (orig_ratio_parm == table[i].ratio_parm)
++              if (orig_ratio_parm == te->ratio_parm)
 +                      goto end_fill;
 +
-+              new_ratio = table[i].ratio_parm;
-+
-+              icache_probe(&icache_size, &ic_lsize);
++              icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize);
 +
 +              /* Preload the code into the cache */
 +              start = ((ulong) &&start_fill) & ~(ic_lsize - 1);
 +              end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1);
 +              while (start < end) {
-+                      cache_unroll(start, Fill_I);
++                      cache_op(start, Fill_I);
 +                      start += ic_lsize;
 +              }
 +
 +              /* Copy the handler */
-+              start = (ulong) &handler;
-+              end = (ulong) &afterhandler;
++              start = (ulong) &BCMINIT(handler);
++              end = (ulong) &BCMINIT(afterhandler);
 +              dst = KSEG1ADDR(0x180);
 +              for (i = 0; i < (end - start); i += 4)
 +                      *((ulong *)(dst + i)) = *((ulong *)(start + i));
-+              
++
 +              /* Preload handler into the cache one line at a time */
 +              for (i = 0; i < (end - start); i += 4)
-+                      cache_unroll(dst + i, Fill_I);
++                      cache_op(dst + i, Fill_I);
 +
 +              /* Clear BEV bit */
 +              MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV);
@@ -4401,8 +2317,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +      start_fill:
 +              /* step 1, set clock ratios */
-+              MTC0(C0_BROADCOM, 3, new_ratio);
-+              MTC0(C0_BROADCOM, 1, 8);
++              MTC0(C0_BROADCOM, 3, te->ratio_parm);
++              MTC0(C0_BROADCOM, 1, te->ratio_cfg);
 +
 +              /* step 2: program timer intr */
 +              W_REG(&mipsr->timer, 100);
@@ -4416,7 +2332,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +              MTC0(C0_BROADCOM, 2, 0x9);
 +
 +
-+              /* steps 5 & 6 */ 
++              /* steps 5 & 6 */
 +              __asm__ __volatile__ (
 +                      ".set\tmips3\n\t"
 +                      "wait\n\t"
@@ -4425,7 +2341,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +              /* step 7, clear cfg_active */
 +              MTC0(C0_BROADCOM, 2, 0);
-+              
++
 +              /* Additional Step: set back to orig sync mode */
 +              MTC0(C0_BROADCOM, 4, sync_mode);
 +
@@ -4454,10 +2370,49 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      return ret;
 +}
 +
-+
++/*
++ *  This also must be run from the cache on 47xx
++ *  so there are no mips core BIU ops in progress
++ *  when the PFC is enabled.
++ */
++
++static void
++BCMINITFN(_enable_pfc)(uint32 mode)
++{
++      /* write range */
++      *(volatile uint32 *)PFC_CR1 = 0xffff0000;
++
++      /* enable */
++      *(volatile uint32 *)PFC_CR0 = mode;
++}
++
++void
++BCMINITFN(enable_pfc)(uint32 mode)
++{
++      ulong start, end;
++      int i;
++
++      /* If auto then choose the correct mode for this
++         platform, currently we only ever select one mode */
++      if (mode == PFC_AUTO)
++              mode = PFC_INST;
++
++      /* enable prefetch cache if available */
++      if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) {
++              start = (ulong) &BCMINIT(_enable_pfc);
++              end = (ulong) &BCMINIT(enable_pfc);
++
++              /* Preload handler into the cache one line at a time */
++              for (i = 0; i < (end - start); i += 4)
++                      cache_op(start + i, Fill_I);
++
++              BCMINIT(_enable_pfc)(mode);
++      }
++}
++
 +/* returns the ncdl value to be programmed into sdram_ncdl for calibration */
 +uint32
-+sb_memc_get_ncdl(void *sbh)
++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh)
 +{
 +      sbmemcregs_t *memc;
 +      uint32 ret = 0;
@@ -4479,7 +2434,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +      dqsg = R_REG(&memc->dqsgatencdl);
 +
 +      rd &= MEMC_RDNCDLCOR_RD_MASK;
-+      wr &= MEMC_WRNCDLCOR_WR_MASK; 
++      wr &= MEMC_WRNCDLCOR_WR_MASK;
 +      dqsg &= MEMC_DQSGATENCDL_G_MASK;
 +
 +      if (config & MEMC_CONFIG_DDR) {
@@ -4500,14 +2455,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbmips.c linux-2.6.12.5-brc
 +
 +      return ret;
 +}
-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-11-07 01:12:51.819809500 +0100
-@@ -0,0 +1,530 @@
++
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbpci.c linux.dev/arch/mips/bcm947xx/broadcom/sbpci.c
+--- linux.old/arch/mips/bcm947xx/broadcom/sbpci.c      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/sbpci.c      2005-12-18 05:36:53.351735500 +0100
+@@ -0,0 +1,533 @@
 +/*
 + * Low-Level PCI and SB support for BCM47xx
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -4515,18 +2471,18 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 + *
-+ * $Id: sbpci.c,v 1.2 2005/02/28 13:34:25 jolt Exp $
++ * $Id$
 + */
 +
 +#include <typedefs.h>
 +#include <pcicfg.h>
 +#include <bcmdevs.h>
 +#include <sbconfig.h>
-+#include <sbpci.h>
 +#include <osl.h>
++#include <sbutils.h>
++#include <sbpci.h>
 +#include <bcmendian.h>
 +#include <bcmutils.h>
-+#include <sbutils.h>
 +#include <bcmnvram.h>
 +#include <hndmips.h>
 +
@@ -4545,6 +2501,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +/* CardBus mode */
 +static bool cardbus = FALSE;
 +
++/* Disable PCI host core */
++static bool pci_disabled = FALSE;
++
 +/*
 + * Functions for accessing external PCI configuration space
 + */
@@ -4553,7 +2512,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +#define PCI_SLOT_MAX 16
 +
 +static uint32
-+config_cmd(void *sbh, uint bus, uint dev, uint func, uint off)
++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off)
 +{
 +      uint coreidx;
 +      sbpciregs_t *regs;
@@ -4589,12 +2548,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 +
 +static int
-+extpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      uint32 addr, *reg = NULL, val;
 +      int ret = 0;
 +
-+      if (!(addr = config_cmd(sbh, bus, dev, func, off)) ||
++      if (pci_disabled ||
++          !(addr = config_cmd(sbh, bus, dev, func, off)) ||
 +          !(reg = (uint32 *) REG_MAP(addr, len)) ||
 +          BUSPROBE(val, reg))
 +              val = 0xffffffff;
@@ -4616,12 +2576,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 +
 +static int
-+extpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      uint32 addr, *reg = NULL, val;
 +      int ret = 0;
 +
-+      if (!(addr = config_cmd(sbh, bus, dev, func, off)) ||
++      if (pci_disabled ||
++          !(addr = config_cmd(sbh, bus, dev, func, off)) ||
 +          !(reg = (uint32 *) REG_MAP(addr, len)) ||
 +          BUSPROBE(val, reg))
 +              goto done;
@@ -4651,7 +2612,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 + */
 +
 +static int
-+sb_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      pci_config_regs *cfg;
 +
@@ -4660,7 +2621,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +      cfg = &sb_config_regs[dev];
 +
 +      ASSERT(ISALIGNED(off, len));
-+      ASSERT(ISALIGNED(buf, len));
++      ASSERT(ISALIGNED((uintptr)buf, len));
 +
 +      if (len == 4)
 +              *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off)));
@@ -4675,7 +2636,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 +
 +static int
-+sb_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      uint coreidx, n;
 +      void *regs;
@@ -4687,7 +2648,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +      cfg = &sb_config_regs[dev];
 +
 +      ASSERT(ISALIGNED(off, len));
-+      ASSERT(ISALIGNED(buf, len));
++      ASSERT(ISALIGNED((uintptr)buf, len));
 +
 +      /* Emulate BAR sizing */
 +      if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) &&
@@ -4699,12 +2660,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +                      n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT;
 +                      if (off == OFFSETOF(pci_config_regs, base[0]))
 +                              cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1);
-+                      /*else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1)
++#if 0
++                      else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1)
 +                              cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1);
 +                      else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2)
 +                              cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1);
 +                      else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3)
-+                              cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);*/
++                              cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1);
++#endif
 +              }
 +              sb_setcoreidx(sbh, coreidx);
 +              return 0;
@@ -4723,7 +2686,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 +
 +int
-+sbpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      if (bus == 0)
 +              return sb_read_config(sbh, bus, dev, func, off, buf, len);
@@ -4732,7 +2695,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +}
 +
 +int
-+sbpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
++sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len)
 +{
 +      if (bus == 0)
 +              return sb_write_config(sbh, bus, dev, func, off, buf, len);
@@ -4747,33 +2710,49 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +              pci_ban[pci_banned++] = core;
 +}
 +
-+int __init
-+sbpci_init(void *sbh)
++static int
++sbpci_init_pci(sb_t *sbh)
 +{
-+      uint chip, chiprev, chippkg, coreidx, host, i;
++      uint chip, chiprev, chippkg, host;
++      uint32 boardflags;
 +      sbpciregs_t *pci;
 +      sbconfig_t *sb;
-+      pci_config_regs *cfg;
-+      void *regs;
-+      char varname[8];
-+      uint wlidx = 0;
-+      uint16 vendor, core;
-+      uint8 class, subclass, progif;
 +      uint32 val;
-+      uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK };
-+      uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT };
 +
 +      chip = sb_chip(sbh);
 +      chiprev = sb_chiprev(sbh);
 +      chippkg = sb_chippkg(sbh);
-+      coreidx = sb_coreidx(sbh);
 +
-+      if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0)))
++      if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) {
++              printf("PCI: no core\n");
++              pci_disabled = TRUE;
 +              return -1;
++      }
 +      sb_core_reset(sbh, 0);
 +
-+      if (((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) ||
-+          ((chip == BCM4712_DEVICE_ID) && (chippkg == BCM4712SMALL_PKG_ID)))
++      boardflags = (uint32) getintvar(NULL, "boardflags");
++
++      if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0))
++              pci_disabled = TRUE;
++
++      /*
++       * The 200-pin BCM4712 package does not bond out PCI. Even when
++       * PCI is bonded out, some boards may leave the pins
++       * floating.
++       */
++      if (((chip == BCM4712_DEVICE_ID) &&
++           ((chippkg == BCM4712SMALL_PKG_ID) ||
++            (chippkg == BCM4712MID_PKG_ID))) ||
++          (boardflags & BFL_NOPCI))
++              pci_disabled = TRUE;
++
++      /*
++       * If the PCI core should not be touched (disabled, not bonded
++       * out, or pins floating), do not even attempt to access core
++       * registers. Otherwise, try to determine if it is in host
++       * mode.
++       */
++      if (pci_disabled)
 +              host = 0;
 +      else
 +              host = !BUSPROBE(val, &pci->control);
@@ -4790,7 +2769,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +              /* Reset the external PCI bus and enable the clock */
 +              W_REG(&pci->control, 0x5);              /* enable the tristate drivers */
 +              W_REG(&pci->control, 0xd);              /* enable the PCI clock */
-+              OSL_DELAY(100);                         /* delay 100 us */
++              OSL_DELAY(150);                         /* delay > 100 us */
 +              W_REG(&pci->control, 0xf);              /* deassert PCI reset */
 +              W_REG(&pci->arbcontrol, PCI_INT_ARB);   /* use internal arbiter */
 +              OSL_DELAY(1);                           /* delay 1 us */
@@ -4800,8 +2779,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +              if (cardbus) {
 +                      printf("PCI: Enabling CardBus\n");
 +                      /* GPIO 1 resets the CardBus device on bcm94710ap */
-+                      sb_gpioout(sbh, 1, 1);
-+                      sb_gpioouten(sbh, 1, 1);
++                      sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY);
++                      sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY);
 +                      W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400);
 +              }
 +
@@ -4819,6 +2798,29 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +              /* Enable PCI interrupts */
 +              W_REG(&pci->intmask, PCI_INTA);
 +      }
++      
++      return 0;
++}
++
++static int
++sbpci_init_cores(sb_t *sbh)
++{
++      uint chip, chiprev, chippkg, coreidx, i;
++      sbconfig_t *sb;
++      pci_config_regs *cfg;
++      void *regs;
++      char varname[8];
++      uint wlidx = 0;
++      uint16 vendor, core;
++      uint8 class, subclass, progif;
++      uint32 val;
++      uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK };
++      uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT };
++
++      chip = sb_chip(sbh);
++      chiprev = sb_chiprev(sbh);
++      chippkg = sb_chippkg(sbh);
++      coreidx = sb_coreidx(sbh);
 +
 +      /* Scan the SB bus */
 +      bzero(sb_config_regs, sizeof(sb_config_regs));
@@ -4871,9 +2873,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +                      subclass = PCI_MEMORY_RAM;
 +                      break;
 +              case SB_PCI:
++#if 0
 +                      class = PCI_CLASS_BRIDGE;
 +                      subclass = PCI_BRIDGE_PCI;
-+                      //break;
++                      break;
++#endif
 +              case SB_MIPS:
 +              case SB_MIPS33:
 +                      class = PCI_CLASS_CPU;
@@ -4906,6 +2910,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +                      subclass = PCI_CRYPT_NETWORK;
 +                      core = BCM47XX_IPSEC_ID;
 +                      break;
++              case SB_ROBO:
++                      class = PCI_CLASS_NET;
++                      subclass = PCI_NET_OTHER;
++                      core = BCM47XX_ROBO_ID;
++                      break;
 +              case SB_EXTIF:
 +              case SB_CC:
 +                      class = PCI_CLASS_MEMORY;
@@ -4943,9 +2952,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +              cfg->sub_class = subclass;
 +              cfg->base_class = class;
 +              cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0)));
-+              cfg->base[1] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch1)))*/;
-+              cfg->base[2] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch2)))*/;
-+              cfg->base[3] = 0/*htol32(sb_base(R_REG(&sb->sbadmatch3)))*/;
++              cfg->base[1] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch1)));
++              cfg->base[2] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch2)));
++              cfg->base[3] = 0;//htol32(sb_base(R_REG(&sb->sbadmatch3)));
 +              cfg->base[4] = 0;
 +              cfg->base[5] = 0;
 +              if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI)
@@ -4976,110 +2985,56 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbpci.c linux-2.6.12.5-brcm
 +      return 0;
 +}
 +
-+void
-+sbpci_check(void *sbh)
++int __init
++sbpci_init(sb_t *sbh)
 +{
-+      uint coreidx;
-+      sbpciregs_t *pci;
-+      uint32 sbtopci1;
-+      uint32 buf[64], *ptr, i;
-+      ulong pa;
-+      volatile uint j;
-+
-+      coreidx = sb_coreidx(sbh);
-+      pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0);
-+
-+      /* Clear the test array */
-+      pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL);
-+      ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
-+      memset(ptr, 0, sizeof(buf));
-+
-+      /* Point PCI window 1 to memory */
-+      sbtopci1 = R_REG(&pci->sbtopci1);
-+      W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK));
-+
-+      /* Fill the test array via PCI window 1 */
-+      ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf));
-+      for (i = 0; i < ARRAYSIZE(buf); i++) {
-+              for (j = 0; j < 2; j++);
-+              W_REG(&ptr[i], i);
-+      }
-+      REG_UNMAP(ptr);
-+
-+      /* Restore PCI window 1 */
-+      W_REG(&pci->sbtopci1, sbtopci1);
-+
-+      /* Check the test array */
-+      DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL);
-+      ptr = (uint32 *) OSL_UNCACHED(&buf[0]);
-+      for (i = 0; i < ARRAYSIZE(buf); i++) {
-+              if (ptr[i] != i)
-+                      break;
-+      }
-+
-+      /* Change the clock if the test fails */
-+      if (i < ARRAYSIZE(buf)) {
-+              uint32 req, cur;
-+
-+              cur = sb_clock(sbh);
-+              printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000);
-+              for (req = 104000000; req < 176000000; req += 4000000) {
-+                      printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000);
-+                      /* This will only reset if the clocks are valid and have changed */
-+                      sb_mips_setclock(sbh, req, 0, 0);
-+              }
-+              /* Should not reach here */
-+              ASSERT(0);
-+      }
-+
-+      sb_setcoreidx(sbh, coreidx);
++      sbpci_init_pci(sbh);
++      sbpci_init_cores(sbh);
++      return 0;
 +}
-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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,1895 @@
++
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/sbutils.c linux.dev/arch/mips/bcm947xx/broadcom/sbutils.c
+--- linux.old/arch/mips/bcm947xx/broadcom/sbutils.c    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/sbutils.c    2005-12-17 01:21:12.951254500 +0100
+@@ -0,0 +1,2370 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
 + * of the SiliconBackplane-based Broadcom chips.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * 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: sbutils.c,v 1.1 2005/02/28 13:33:32 jolt Exp $
++ * $Id$
 + */
 +
 +#include <typedefs.h>
 +#include <osl.h>
++#include <sbutils.h>
 +#include <bcmutils.h>
 +#include <bcmdevs.h>
 +#include <sbconfig.h>
 +#include <sbchipc.h>
 +#include <sbpci.h>
 +#include <pcicfg.h>
-+#include <sbpcmcia.h>
 +#include <sbextif.h>
-+#include <sbutils.h>
 +#include <bcmsrom.h>
 +
 +/* debug/trace */
 +#define       SB_ERROR(args)
 +
++
 +typedef uint32 (*sb_intrsoff_t)(void *intr_arg);
 +typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg);
++typedef bool (*sb_intrsenabled_t)(void *intr_arg);
 +
 +/* misc sb info needed by some of the routines */
 +typedef struct sb_info {
-+      uint    chip;                   /* chip number */
-+      uint    chiprev;                /* chip revision */
-+      uint    chippkg;                /* chip package option */
-+      uint    boardtype;              /* board type */
-+      uint    boardvendor;            /* board vendor id */
-+      uint    bus;                    /* what bus type we are going through */
++
++      struct sb_pub   sb;                     /* back plane public state(must be first field of sb_info */
 +
 +      void    *osh;                   /* osl os handle */
 +      void    *sdh;                   /* bcmsdh handle */
@@ -5089,14 +3044,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +      uint    curidx;                 /* current core index */
 +      uint    dev_coreid;             /* the core provides driver functions */
-+      uint    pciidx;                 /* pci core index */
-+      uint    pcirev;                 /* pci core rev */
-+
-+      uint    pcmciaidx;              /* pcmcia core index */
-+      uint    pcmciarev;              /* pcmcia core rev */
-+      bool    memseg;                 /* flag to toggle MEM_SEG register */
-+
-+      uint    ccrev;                  /* chipc core rev */
 +
 +      uint    gpioidx;                /* gpio control core index */
 +      uint    gpioid;                 /* gpio control coretype */
@@ -5107,32 +3054,49 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      void    *intr_arg;              /* interrupt callback function arg */
 +      sb_intrsoff_t           intrsoff_fn;            /* function turns chip interrupts off */
 +      sb_intrsrestore_t       intrsrestore_fn;        /* function restore chip interrupts */
++      sb_intrsenabled_t       intrsenabled_fn;        /* function to check if chip interrupts are enabled */
++
 +} sb_info_t;
 +
 +/* local prototypes */
-+static void* sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz);
-+static void sb_scan(sb_info_t *si);
-+static uint sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val);
-+static uint _sb_coreidx(void *sbh);
-+static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit);
-+static uint sb_pcidev2chip(uint pcidev);
-+static uint sb_chip2numcores(uint chip);
++static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
++      uint bustype, void *sdh, char **vars, int *varsz);
++static void BCMINIT(sb_scan)(sb_info_t *si);
++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val);
++static uint _sb_coreidx(sb_info_t *si);
++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit);
++static uint BCMINIT(sb_pcidev2chip)(uint pcidev);
++static uint BCMINIT(sb_chip2numcores)(uint chip);
++static int sb_pci_fixcfg(sb_info_t *si);
++
++/* delay needed between the mdio control/ mdiodata register data access */
++#define PR28829_DELAY() OSL_DELAY(10)
++
++
++/* global variable to indicate reservation/release of gpio's*/
++static uint32 sb_gpioreservation = 0;
 +
 +#define       SB_INFO(sbh)    (sb_info_t*)sbh
 +#define       SET_SBREG(sbh, r, mask, val)    W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val)))
-+#define       GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) \
-+                              && ISALIGNED((x), SB_CORE_SIZE))
-+#define       GOODREGS(regs)  (regs && ISALIGNED(regs, SB_CORE_SIZE))
-+#define       REGS2SB(va)     (sbconfig_t*) ((uint)(va) + SBCONFIGOFF)
++#define       GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE))
++#define       GOODREGS(regs)  ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE))
++#define       REGS2SB(va)     (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF)
 +#define       GOODIDX(idx)    (((uint)idx) < SB_MAXCORES)
 +#define       BADIDX          (SB_MAXCORES+1)
++#define       NOREV           -1
++
++#define PCI(si)               ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) 
++
++/* sonicsrev */
++#define       SONICS_2_2      (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
++#define       SONICS_2_3      (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
 +
 +#define       R_SBREG(sbh, sbr)       sb_read_sbreg((sbh), (sbr))
 +#define       W_SBREG(sbh, sbr, v)    sb_write_sbreg((sbh), (sbr), (v))
 +#define       AND_SBREG(sbh, sbr, v)  W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v)))
 +#define       OR_SBREG(sbh, sbr, v)   W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v)))
 +
-+/* 
++/*
 + * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/
 + * after core switching to avoid invalid register accesss inside ISR.
 + */
@@ -5143,173 +3107,98 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) {  \
 +              (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
 +
-+/* power control defines */
-+#define       PLL_DELAY       150                     /* 150us pll on delay */
-+#define       FREF_DELAY      15                      /* 15us fref change delay */
++/* dynamic clock control defines */
 +#define       LPOMINFREQ      25000                   /* low power oscillator min */
 +#define       LPOMAXFREQ      43000                   /* low power oscillator max */
-+#define       XTALMINFREQ     19800000                /* 20mhz - 1% */
-+#define       XTALMAXFREQ     20200000                /* 20mhz + 1% */
-+#define       PCIMINFREQ      25000000                /* 25mhz */
-+#define       PCIMAXFREQ      34000000                /* 33mhz + fudge */
++#define       XTALMINFREQ     19800000                /* 20 MHz - 1% */
++#define       XTALMAXFREQ     20200000                /* 20 MHz + 1% */
++#define       PCIMINFREQ      25000000                /* 25 MHz */
++#define       PCIMAXFREQ      34000000                /* 33 MHz + fudge */
 +
-+#define SCC_LOW2FAST_LIMIT    5000    /* turn on fast clock time, in unit of ms */
++#define       ILP_DIV_5MHZ    0                       /* ILP = 5 MHz */
++#define       ILP_DIV_1MHZ    4                       /* ILP = 1 MHz */
 +
++#define MIN_DUMPBUFLEN  32    /* debug */
 +
-+static uint32
-+sb_read_sbreg(void *sbh, volatile uint32 *sbr)
-+{
-+      sb_info_t *si;
-+      uint8 tmp;
-+      uint32 val, intr_val = 0;
-+
-+      si = SB_INFO(sbh);
++/* GPIO Based LED powersave defines */
++#define DEFAULT_GPIO_ONTIME   10
++#define DEFAULT_GPIO_OFFTIME  90
 +
-+      /* 
-+       * compact flash only has 11 bits address, while we needs 12 bits address.
-+       * MEM_SEG will be OR'd with other 11 bits address in hardware, 
-+       * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
-+       * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special
-+       */
-+      if(si->memseg) {
-+              INTR_OFF(si, intr_val);
-+              tmp = 1;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
-+              (uint32)sbr &= ~(1 << 11);      /* mask out bit 11*/
-+      }
++#define DEFAULT_GPIOTIMERVAL  ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
 +
-+      val = R_REG(sbr);
-+      
-+      if(si->memseg) {
-+              tmp = 0;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
-+              INTR_RESTORE(si, intr_val);
-+      }
++static uint32
++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr)
++{
++      uint32 val = R_REG(sbr);
 +
 +      return (val);
 +}
 +
 +static void
-+sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v)
++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v)
 +{
-+      sb_info_t *si;
-+      uint8 tmp;
-+      volatile uint32 dummy;
-+      uint32 intr_val = 0;
-+
-+      si = SB_INFO(sbh);
-+
-+      /* 
-+       * compact flash only has 11 bits address, while we needs 12 bits address.
-+       * MEM_SEG will be OR'd with other 11 bits address in hardware, 
-+       * so we program MEM_SEG with 12th bit when necessary(access sb regsiters).
-+       * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special 
-+       */
-+      if(si->memseg) {
-+              INTR_OFF(si, intr_val);
-+              tmp = 1;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
-+              (uint32)sbr &= ~(1 << 11);      /* mask out bit 11 */
-+      }
-+
-+      if ((si->bus == PCMCIA_BUS) || (si->bus == PCI_BUS)) {
-+#ifdef IL_BIGENDIAN
-+              dummy = R_REG(sbr);
-+              W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
-+              dummy = R_REG(sbr);
-+              W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
-+#else
-+              dummy = R_REG(sbr);
-+              W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff));
-+              dummy = R_REG(sbr);
-+              W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff));
-+#endif
-+      } else
-+              W_REG(sbr, v);
-+
-+      if(si->memseg) {
-+              tmp = 0;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1);
-+              INTR_RESTORE(si, intr_val);
-+      }
++      W_REG(sbr, v);
 +}
 +
-+/*
-+ * Allocate a sb handle.
-+ * devid - pci device id (used to determine chip#)
-+ * osh - opaque OS handle
-+ * regs - virtual address of initial core registers
-+ * bustype - pci/pcmcia/sb/sdio/etc
-+ * vars - pointer to a pointer area for "environment" variables
-+ * varsz - pointer to int to return the size of the vars
-+ */
-+void*
-+sb_attach(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz)
-+{
-+      sb_info_t *si;
-+
-+      /* alloc sb_info_t */
-+      if ((si = MALLOC(sizeof (sb_info_t))) == NULL) {
-+              SB_ERROR(("sb_attach: malloc failed!\n"));
-+              return (NULL);
-+      }
-+
-+      return (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz));
-+}
++/* Using sb_kattach depends on SB_BUS support, either implicit  */
++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */
++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS)
 +
 +/* global kernel resource */
 +static sb_info_t ksi;
 +
 +/* generic kernel variant of sb_attach() */
-+void*
-+sb_kattach()
++sb_t * 
++BCMINITFN(sb_kattach)()
 +{
 +      uint32 *regs;
-+      char *unused;
-+      int varsz;
 +
 +      if (ksi.curmap == NULL) {
 +              uint32 cid;
++
 +              regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE);
 +              cid = R_REG((uint32 *)regs);
-+              if ((cid == 0x08104712) || (cid == 0x08114712)) {
++              if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) &&
++                  ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) &&
++                  ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) {
 +                      uint32 *scc, val;
 +
-+                      scc = (uint32 *)((uint32)regs + OFFSETOF(chipcregs_t, slow_clk_ctl));
++                      scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl));
 +                      val = R_REG(scc);
 +                      SB_ERROR(("    initial scc = 0x%x\n", val));
 +                      val |= SCC_SS_XTAL;
 +                      W_REG(scc, val);
 +              }
 +
-+              sb_doattach(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs,
-+                          SB_BUS, NULL, &unused, &varsz);
++              if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs,
++                      SB_BUS, NULL, NULL, NULL) == NULL) {
++                      return NULL;
++              }
 +      }
 +
-+      return &ksi;
++      return (sb_t *)&ksi;
 +}
++#endif
 +
-+static void*
-+sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz)
++static sb_info_t  * 
++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs,
++      uint bustype, void *sdh, char **vars, int *varsz)
 +{
 +      uint origidx;
 +      chipcregs_t *cc;
++      sbconfig_t *sb;
 +      uint32 w;
 +
 +      ASSERT(GOODREGS(regs));
 +
 +      bzero((uchar*)si, sizeof (sb_info_t));
 +
-+      si->pciidx = si->gpioidx = BADIDX;
++      si->sb.buscoreidx = si->gpioidx = BADIDX;
 +
 +      si->osh = osh;
 +      si->curmap = regs;
 +      si->sdh = sdh;
 +
-+      /* 4317A0 PCMCIA is no longer supported */ 
-+      if ((bustype == PCMCIA_BUS) && (R_REG((uint32 *)regs) == 0x04104317))
-+              return NULL;
-+
 +      /* check to see if we are a sb core mimic'ing a pci core */
 +      if (bustype == PCI_BUS) {
 +              if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff)
@@ -5318,142 +3207,149 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +                      bustype = PCI_BUS;
 +      }
 +
-+      si->bus = bustype;
++      si->sb.bustype = bustype;
++      if (si->sb.bustype != BUSTYPE(si->sb.bustype)) {
++              SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n",
++                        si->sb.bustype, BUSTYPE(si->sb.bustype)));
++              return NULL;
++      }
 +
 +      /* kludge to enable the clock on the 4306 which lacks a slowclock */
-+      if (si->bus == PCI_BUS)
-+              sb_pwrctl_xtal((void*)si, XTAL|PLL, ON);
++      if (BUSTYPE(si->sb.bustype) == PCI_BUS)
++              sb_clkctl_xtal(&si->sb, XTAL|PLL, ON);
 +
-+      /* clear any previous epidiag-induced target abort */
-+      sb_taclear((void*)si);
++      if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
++              w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32));
++              if (!GOODCOREADDR(w))
++                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE);
++      }
 +
 +      /* initialize current core index value */
-+      si->curidx = _sb_coreidx((void*)si);
++      si->curidx = _sb_coreidx(si);
++
++      if (si->curidx == BADIDX) {
++              SB_ERROR(("sb_doattach: bad core index\n"));
++              return NULL;
++      }
++
++      /* get sonics backplane revision */
++      sb = REGS2SB(si->curmap);
++      si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
 +
 +      /* keep and reuse the initial register mapping */
 +      origidx = si->curidx;
-+      if (si->bus == SB_BUS)
++      if (BUSTYPE(si->sb.bustype) == SB_BUS)
 +              si->regs[origidx] = regs;
 +
-+      /* initialize the vars */
-+      if (srom_var_init(si->bus, si->curmap, osh, vars, varsz)) {
-+              SB_ERROR(("sb_attach: srom_var_init failed\n"));
-+              goto bad;
-+      }
-+      
-+      if (si->bus == PCMCIA_BUS) {
-+              w = getintvar(*vars, "regwindowsz");
-+              si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE;
-+      }
-+
 +      /* is core-0 a chipcommon core? */
 +      si->numcores = 1;
-+      cc = (chipcregs_t*) sb_setcoreidx((void*)si, 0);
-+      if (sb_coreid((void*)si) != SB_CC)
++      cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0);
++      if (sb_coreid(&si->sb) != SB_CC)
 +              cc = NULL;
 +
 +      /* determine chip id and rev */
 +      if (cc) {
 +              /* chip common core found! */
-+              si->chip = R_REG(&cc->chipid) & CID_ID_MASK;
-+              si->chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT;
-+              si->chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT;
++              si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK;
++              si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT;
++              si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT;
 +      } else {
-+              /* without chip common core, get devid for PCMCIA */
-+              if (si->bus == PCMCIA_BUS)
-+                      devid = getintvar(*vars, "devid");
-+
 +              /* no chip common core -- must convert device id to chip id */
-+              if ((si->chip = sb_pcidev2chip(devid)) == 0) {
-+                      SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid));
-+                      goto bad;
++              if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) {
++                      SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid));
++                      sb_setcoreidx(&si->sb, origidx);
++                      return NULL;
 +              }
-+
-+              /*
-+               * The chip revision number is hardwired into all
-+               * of the pci function config rev fields and is
-+               * independent from the individual core revision numbers.
-+               * For example, the "A0" silicon of each chip is chip rev 0.
-+               * For PCMCIA we get it from the CIS instead.
-+               */
-+              if (si->bus == PCMCIA_BUS) {
-+                      ASSERT(vars);
-+                      si->chiprev = getintvar(*vars, "chiprev");
-+              } else if (si->bus == PCI_BUS) {
-+                      w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32));
-+                      si->chiprev = w & 0xff;
-+              } else
-+                      si->chiprev = 0;
 +      }
 +
 +      /* get chipcommon rev */
-+      si->ccrev = cc? sb_corerev((void*)si) : 0;
-+      
++      si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV;
++
 +      /* determine numcores */
-+      if ((si->ccrev == 4) || (si->ccrev >= 6))
++      if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6)))
 +              si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT;
 +      else
-+              si->numcores = sb_chip2numcores(si->chip);
++              si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip);
 +
 +      /* return to original core */
-+      sb_setcoreidx((void*)si, origidx);
++      sb_setcoreidx(&si->sb, origidx);
 +
 +      /* sanity checks */
-+      ASSERT(si->chip);
-+      /* 4704A1 is chiprev 8 :-( */
-+      ASSERT((si->chiprev < 8) ||
-+             ((si->chip == BCM4704_DEVICE_ID) && ((si->chiprev == 8))));
++      ASSERT(si->sb.chip);
 +
 +      /* scan for cores */
-+      sb_scan(si);
++      BCMINIT(sb_scan)(si);
 +
-+      /* pci core is required */
-+      if (!GOODIDX(si->pciidx)) {
-+              SB_ERROR(("sb_attach: pci core not found\n"));
-+              goto bad;
++      /* fixup necessary chip/core configurations */
++      if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
++              if (sb_pci_fixcfg(si)) {
++                      SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n"));
++                      return NULL;
++              }
++      }
++      
++      /* srom_var_init() depends on sb_scan() info */
++      if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) {
++              SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n"));
++              return (NULL);
++      }
++      
++      if (cc == NULL) {
++              /*
++               * The chip revision number is hardwired into all
++               * of the pci function config rev fields and is
++               * independent from the individual core revision numbers.
++               * For example, the "A0" silicon of each chip is chip rev 0.
++               */
++              if (BUSTYPE(si->sb.bustype) == PCI_BUS) {
++                      w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32));
++                      si->sb.chiprev = w & 0xff;
++              } else
++                      si->sb.chiprev = 0;
 +      }
 +
 +      /* gpio control core is required */
 +      if (!GOODIDX(si->gpioidx)) {
-+              SB_ERROR(("sb_attach: gpio control core not found\n"));
-+              goto bad;
++              SB_ERROR(("sb_doattach: gpio control core not found\n"));
++              return NULL;
 +      }
 +
 +      /* get boardtype and boardrev */
-+      switch (si->bus) {
++      switch (BUSTYPE(si->sb.bustype)) {
 +      case PCI_BUS:
 +              /* do a pci config read to get subsystem id and subvendor id */
 +              w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32));
-+              si->boardvendor = w & 0xffff;
-+              si->boardtype = (w >> 16) & 0xffff;
-+              break;
-+
-+      case PCMCIA_BUS:
-+      case SDIO_BUS:
-+              si->boardvendor = getintvar(*vars, "manfid");
-+              si->boardtype = getintvar(*vars, "prodid");
++              si->sb.boardvendor = w & 0xffff;
++              si->sb.boardtype = (w >> 16) & 0xffff;
 +              break;
 +
 +      case SB_BUS:
-+              si->boardvendor = VENDOR_BROADCOM;
-+              si->boardtype = 0xffff;
++      case JTAG_BUS:
++              si->sb.boardvendor = VENDOR_BROADCOM;
++              if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0)
++                      si->sb.boardtype = 0xffff;
 +              break;
 +      }
 +
-+      if (si->boardtype == 0) {
-+              SB_ERROR(("sb_attach: unknown board type\n"));
-+              ASSERT(si->boardtype);
++      if (si->sb.boardtype == 0) {
++              SB_ERROR(("sb_doattach: unknown board type\n"));
++              ASSERT(si->sb.boardtype);
 +      }
 +
-+      return ((void*)si);
++      /* setup the GPIO based LED powersave register */
++      if (si->sb.ccrev >= 16) {
++              w = getintvar(*vars, "gpiotimerval");
++              if (!w)
++                      w = DEFAULT_GPIOTIMERVAL; 
++              sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w);
++      }
 +
-+bad:
-+      MFREE(si, sizeof (sb_info_t));
-+      return (NULL);
++
++      return (si);
 +}
 +
 +uint
-+sb_coreid(void *sbh)
++sb_coreid(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -5461,11 +3357,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      sb = REGS2SB(si->curmap);
 +
-+      return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
++      return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT);
 +}
 +
 +uint
-+sb_coreidx(void *sbh)
++sb_coreidx(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
@@ -5475,46 +3371,41 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* return current index of core */
 +static uint
-+_sb_coreidx(void *sbh)
++_sb_coreidx(sb_info_t *si)
 +{
-+      sb_info_t *si;
 +      sbconfig_t *sb;
 +      uint32 sbaddr = 0;
 +
-+      si = SB_INFO(sbh);
 +      ASSERT(si);
 +
-+      switch (si->bus) {
++      switch (BUSTYPE(si->sb.bustype)) {
 +      case SB_BUS:
 +              sb = REGS2SB(si->curmap);
-+              sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0));
++              sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0));
 +              break;
 +
 +      case PCI_BUS:
 +              sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32));
 +              break;
 +
-+      case PCMCIA_BUS: {
-+              uint8 tmp;
-+
-+              OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
-+              sbaddr  = (uint)tmp << 12;
-+              OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
-+              sbaddr |= (uint)tmp << 16;
-+              OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
-+              sbaddr |= (uint)tmp << 24;
++#ifdef BCMJTAG
++      case JTAG_BUS:
++              sbaddr = (uint32)si->curmap;
 +              break;
-+      }
++#endif        /* BCMJTAG */
++
 +      default:
 +              ASSERT(0);
 +      }
 +
-+      ASSERT(GOODCOREADDR(sbaddr));
-+      return ((sbaddr - SB_ENUM_BASE)/SB_CORE_SIZE);
++      if (!GOODCOREADDR(sbaddr))
++              return BADIDX;
++
++      return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE);
 +}
 +
 +uint
-+sb_corevendor(void *sbh)
++sb_corevendor(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -5522,26 +3413,37 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      sb = REGS2SB(si->curmap);
 +
-+      return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
++      return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT);
 +}
 +
 +uint
-+sb_corerev(void *sbh)
++sb_corerev(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
++      uint sbidh;
 +
 +      si = SB_INFO(sbh);
 +      sb = REGS2SB(si->curmap);
++      sbidh = R_SBREG(si, &(sb)->sbidhigh);
++
++      return (SBCOREREV(sbidh));
++}
++
++void *
++sb_osh(sb_t *sbh)
++{
++      sb_info_t *si;
 +
-+      return (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK);
++      si = SB_INFO(sbh);
++      return si->osh;
 +}
 +
 +#define       SBTML_ALLOW     (SBTML_PE | SBTML_FGC | SBTML_FL_MASK)
 +
 +/* set/clear sbtmstatelow core-specific flags */
 +uint32
-+sb_coreflags(void *sbh, uint32 mask, uint32 val)
++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -5555,17 +3457,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +      /* mask and set */
 +      if (mask || val) {
-+              w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val;
-+              W_SBREG(sbh, &sb->sbtmstatelow, w);
++              w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val;
++              W_SBREG(si, &sb->sbtmstatelow, w);
 +      }
 +
 +      /* return the new value */
-+      return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW);
++      return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW);
 +}
 +
 +/* set/clear sbtmstatehigh core-specific flags */
 +uint32
-+sb_coreflagshi(void *sbh, uint32 mask, uint32 val)
++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -5579,16 +3481,45 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +      /* mask and set */
 +      if (mask || val) {
-+              w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val;
-+              W_SBREG(sbh, &sb->sbtmstatehigh, w);
++              w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val;
++              W_SBREG(si, &sb->sbtmstatehigh, w);
 +      }
 +
 +      /* return the new value */
-+      return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK);
++      return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK);
++}
++
++/* caller needs to take care of core-specific bist hazards */
++int
++sb_corebist(sb_t *sbh, uint coreid, uint coreunit)
++{
++      uint32 sblo;
++      uint coreidx;
++      sb_info_t *si;
++      int result = 0;
++
++      si = SB_INFO(sbh);
++
++      coreidx = sb_findcoreidx(si, coreid, coreunit);
++      if (!GOODIDX(coreidx))
++              result = BCME_ERROR;
++      else {
++              sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0);
++              sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE));
++              
++              SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000);
++      
++              if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF)
++                      result = BCME_ERROR;
++
++              sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo);
++      }
++
++      return result;
 +}
 +
 +bool
-+sb_iscoreup(void *sbh)
++sb_iscoreup(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -5596,7 +3527,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      sb = REGS2SB(si->curmap);
 +
-+      return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK);
++      return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK);
 +}
 +
 +/*
@@ -5604,9 +3535,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 + * switch back to the original core, and return the new value.
 + */
 +static uint
-+sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val)
++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val)
 +{
-+      sb_info_t *si;
 +      uint origidx;
 +      uint32 *r;
 +      uint w;
@@ -5616,20 +3546,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      ASSERT(regoff < SB_CORE_SIZE);
 +      ASSERT((val & ~mask) == 0);
 +
-+      si = SB_INFO(sbh);
++      INTR_OFF(si, intr_val);
 +
 +      /* save current core index */
-+      origidx = sb_coreidx(sbh);
++      origidx = sb_coreidx(&si->sb);
 +
 +      /* switch core */
-+      INTR_OFF(si, intr_val);
-+      r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff);
++      r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff);
 +
 +      /* mask and set */
 +      if (mask || val) {
 +              if (regoff >= SBCONFIGOFF) {
-+                      w = (R_SBREG(sbh, r) & ~mask) | val;
-+                      W_SBREG(sbh, r, w);
++                      w = (R_SBREG(si, r) & ~mask) | val;
++                      W_SBREG(si, r, w);
 +              } else {
 +                      w = (R_REG(r) & ~mask) | val;
 +                      W_REG(r, w);
@@ -5637,50 +3566,78 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      }
 +
 +      /* readback */
-+      w = R_SBREG(sbh, r);
++      if (regoff >= SBCONFIGOFF)
++              w = R_SBREG(si, r);
++      else
++              w = R_REG(r);
 +
 +      /* restore core index */
 +      if (origidx != coreidx)
-+              sb_setcoreidx(sbh, origidx);
++              sb_setcoreidx(&si->sb, origidx);
 +
 +      INTR_RESTORE(si, intr_val);
 +      return (w);
 +}
 +
++#define DWORD_ALIGN(x)  (x & ~(0x03))
++#define BYTE_POS(x) (x & 0x3)
++#define WORD_POS(x) (x & 0x1)
++
++#define BYTE_SHIFT(x)  (8 * BYTE_POS(x))
++#define WORD_SHIFT(x)  (16 * WORD_POS(x))
++
++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF)
++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF)
++
++#define read_pci_cfg_byte(a) \
++      (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff)
++
++#define read_pci_cfg_write(a) \
++      (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff)
++
++
 +/* scan the sb enumerated space to identify all cores */
 +static void
-+sb_scan(sb_info_t *si)
++BCMINITFN(sb_scan)(sb_info_t *si)
 +{
-+      void *sbh;
 +      uint origidx;
 +      uint i;
++      bool pci;
++      uint pciidx;
++      uint pcirev;
++
 +
-+      sbh = (void*) si;
 +
 +      /* numcores should already be set */
 +      ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES));
 +
 +      /* save current core index */
-+      origidx = sb_coreidx(sbh);
++      origidx = sb_coreidx(&si->sb);
 +
-+      si->pciidx = si->gpioidx = BADIDX;
++      si->sb.buscorerev = NOREV;
++      si->sb.buscoreidx = BADIDX;
 +
-+      for (i = 0; i < si->numcores; i++) {
-+              sb_setcoreidx(sbh, i);
-+              si->coreid[i] = sb_coreid(sbh);
++      si->gpioidx = BADIDX;
 +
-+              if (si->coreid[i] == SB_CC)
-+                      si->ccrev = sb_corerev(sbh);
++      pci = FALSE;
++      pcirev = NOREV;
++      pciidx = BADIDX;
 +
-+              else if (si->coreid[i] == SB_PCI) {
-+                      si->pciidx = i;
-+                      si->pcirev = sb_corerev(sbh);
++      for (i = 0; i < si->numcores; i++) {
++              sb_setcoreidx(&si->sb, i);
++              si->coreid[i] = sb_coreid(&si->sb);
 +
-+              }else if (si->coreid[i] == SB_PCMCIA){
-+                      si->pcmciaidx = i;
-+                      si->pcmciarev = sb_corerev(sbh);
++              if (si->coreid[i] == SB_PCI) { 
++                      pciidx = i;
++                      pcirev = sb_corerev(&si->sb);
++                      pci = TRUE;
 +              }
 +      }
++      if (pci) {
++              si->sb.buscoretype = SB_PCI;
++              si->sb.buscorerev = pcirev; 
++              si->sb.buscoreidx = pciidx; 
++      }
 +
 +      /*
 +       * Find the gpio "controlling core" type and index.
@@ -5689,24 +3646,25 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +       * - else if there's a pci core (rev >= 2) - use that
 +       * - else there had better be an extif core (4710 only)
 +       */
-+      if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) {
-+              si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0);
++      if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) {
++              si->gpioidx = sb_findcoreidx(si, SB_CC, 0);
 +              si->gpioid = SB_CC;
-+      } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) {
-+              si->gpioidx = si->pciidx;
++      } else if (PCI(si) && (si->sb.buscorerev >= 2)) {
++              si->gpioidx = si->sb.buscoreidx;
 +              si->gpioid = SB_PCI;
-+      } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) {
-+              si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0);
++      } else if (sb_findcoreidx(si, SB_EXTIF, 0)) {
++              si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0);
 +              si->gpioid = SB_EXTIF;
-+      }
++      } else
++              ASSERT(si->gpioidx != BADIDX);
 +
 +      /* return to original core index */
-+      sb_setcoreidx(sbh, origidx);
++      sb_setcoreidx(&si->sb, origidx);
 +}
 +
 +/* may be called with core in reset */
 +void
-+sb_detach(void *sbh)
++sb_detach(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      uint idx;
@@ -5716,26 +3674,27 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      if (si == NULL)
 +              return;
 +
-+      if (si->bus == SB_BUS)
++      if (BUSTYPE(si->sb.bustype) == SB_BUS)
 +              for (idx = 0; idx < SB_MAXCORES; idx++)
 +                      if (si->regs[idx]) {
 +                              REG_UNMAP(si->regs[idx]);
 +                              si->regs[idx] = NULL;
 +                      }
 +
-+      MFREE(si, sizeof (sb_info_t));
++      if (si != &ksi)
++              MFREE(si->osh, si, sizeof (sb_info_t));
 +}
 +
 +/* use pci dev id to determine chip id for chips not having a chipcommon core */
 +static uint
-+sb_pcidev2chip(uint pcidev)
++BCMINITFN(sb_pcidev2chip)(uint pcidev)
 +{
 +      if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID))
 +              return (BCM4710_DEVICE_ID);
-+      if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID))
-+              return (BCM4610_DEVICE_ID);
 +      if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID))
 +              return (BCM4402_DEVICE_ID);
++      if (pcidev == BCM4401_ENET_ID)
++              return (BCM4402_DEVICE_ID);
 +      if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID))
 +              return (BCM4307_DEVICE_ID);
 +      if (pcidev == BCM4301_DEVICE_ID)
@@ -5746,23 +3705,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* convert chip number to number of i/o cores */
 +static uint
-+sb_chip2numcores(uint chip)
++BCMINITFN(sb_chip2numcores)(uint chip)
 +{
-+      if (chip == 0x4710)
++      if (chip == BCM4710_DEVICE_ID)
 +              return (9);
-+      if (chip == 0x4610)
-+              return (9);
-+      if (chip == 0x4402)
++      if (chip == BCM4402_DEVICE_ID)
 +              return (3);
-+      if ((chip == 0x4307) || (chip == 0x4301))
++      if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID))
 +              return (5);
-+      if (chip == 0x4310)
-+              return (8);
-+      if (chip == 0x4306)     /* < 4306c0 */
++      if (chip == BCM4306_DEVICE_ID)  /* < 4306c0 */
 +              return (6);
-+      if (chip == 0x4704)
++      if (chip == BCM4704_DEVICE_ID)
 +              return (9);
-+      if (chip == 0x5365)
++      if (chip == BCM5365_DEVICE_ID)
 +              return (7);
 +
 +      SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip));
@@ -5772,13 +3727,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* return index of coreid or BADIDX if not found */
 +static uint
-+sb_findcoreidx(void *sbh, uint coreid, uint coreunit)
++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit)
 +{
-+      sb_info_t *si;
 +      uint found;
 +      uint i;
 +
-+      si = SB_INFO(sbh);
 +      found = 0;
 +
 +      for (i = 0; i < si->numcores; i++)
@@ -5791,28 +3744,31 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      return (BADIDX);
 +}
 +
-+/* change logical "focus" to the indiciated core */
++/* 
++ * this function changes logical "focus" to the indiciated core, 
++ * must be called with interrupt off.
++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core
++ */
 +void*
-+sb_setcoreidx(void *sbh, uint coreidx)
++sb_setcoreidx(sb_t *sbh, uint coreidx)
 +{
 +      sb_info_t *si;
 +      uint32 sbaddr;
-+      uint8 tmp;
 +
 +      si = SB_INFO(sbh);
 +
 +      if (coreidx >= si->numcores)
 +              return (NULL);
-+
++      
 +      /*
 +       * If the user has provided an interrupt mask enabled function,
 +       * then assert interrupts are disabled before switching the core.
 +       */
-+      ASSERT((si->imf == NULL) || !(*si->imf)(si->imfarg));
++      ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg));
 +
 +      sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE);
 +
-+      switch (si->bus) {
++      switch (BUSTYPE(si->sb.bustype)) {
 +      case SB_BUS:
 +              /* map new one */
 +              if (!si->regs[coreidx]) {
@@ -5827,14 +3783,16 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr);
 +              break;
 +
-+      case PCMCIA_BUS:
-+              tmp = (sbaddr >> 12) & 0x0f;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1);
-+              tmp = (sbaddr >> 16) & 0xff;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1);
-+              tmp = (sbaddr >> 24) & 0xff;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1);
++#ifdef BCMJTAG
++      case JTAG_BUS:
++              /* map new one */
++              if (!si->regs[coreidx]) {
++                      si->regs[coreidx] = (void *)sbaddr;
++                      ASSERT(GOODREGS(si->regs[coreidx]));
++              }
++              si->curmap = si->regs[coreidx];
 +              break;
++#endif        /* BCMJTAG */
 +      }
 +
 +      si->curidx = coreidx;
@@ -5842,16 +3800,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      return (si->curmap);
 +}
 +
-+/* change logical "focus" to the indicated core */
++/* 
++ * this function changes logical "focus" to the indiciated core, 
++ * must be called with interrupt off.
++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core
++ */
 +void*
-+sb_setcore(void *sbh, uint coreid, uint coreunit)
++sb_setcore(sb_t *sbh, uint coreid, uint coreunit)
 +{
 +      sb_info_t *si;
 +      uint idx;
 +
 +      si = SB_INFO(sbh);
-+
-+      idx = sb_findcoreidx(sbh, coreid, coreunit);
++      idx = sb_findcoreidx(si, coreid, coreunit);
 +      if (!GOODIDX(idx))
 +              return (NULL);
 +
@@ -5860,125 +3821,145 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* return chip number */
 +uint
-+sb_chip(void *sbh)
++BCMINITFN(sb_chip)(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
 +      si = SB_INFO(sbh);
-+      return (si->chip);
++      return (si->sb.chip);
 +}
 +
 +/* return chip revision number */
 +uint
-+sb_chiprev(void *sbh)
++BCMINITFN(sb_chiprev)(sb_t *sbh)
++{
++      sb_info_t *si;
++
++      si = SB_INFO(sbh);
++      return (si->sb.chiprev);
++}
++
++/* return chip common revision number */
++uint
++BCMINITFN(sb_chipcrev)(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
 +      si = SB_INFO(sbh);
-+      return (si->chiprev);
++      return (si->sb.ccrev);
 +}
 +
 +/* return chip package option */
 +uint
-+sb_chippkg(void *sbh)
++BCMINITFN(sb_chippkg)(sb_t *sbh)
++{
++      sb_info_t *si;
++
++      si = SB_INFO(sbh);
++      return (si->sb.chippkg);
++}
++
++/* return PCI core rev. */
++uint
++BCMINITFN(sb_pcirev)(sb_t *sbh)
++{
++      sb_info_t *si;
++
++      si = SB_INFO(sbh);
++      return (si->sb.buscorerev);
++}
++
++bool
++BCMINITFN(sb_war16165)(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
 +      si = SB_INFO(sbh);
-+      return (si->chippkg);
++
++      return (PCI(si) && (si->sb.buscorerev <= 10));
 +}
 +
 +/* return board vendor id */
 +uint
-+sb_boardvendor(void *sbh)
++BCMINITFN(sb_boardvendor)(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
 +      si = SB_INFO(sbh);
-+      return (si->boardvendor);
++      return (si->sb.boardvendor);
 +}
 +
 +/* return boardtype */
 +uint
-+sb_boardtype(void *sbh)
++BCMINITFN(sb_boardtype)(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      char *var;
 +
 +      si = SB_INFO(sbh);
 +
-+      if (si->bus == SB_BUS && si->boardtype == 0xffff) {
++      if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) {
 +              /* boardtype format is a hex string */
-+              si->boardtype = getintvar(NULL, "boardtype");
++              si->sb.boardtype = getintvar(NULL, "boardtype");
 +
 +              /* backward compatibility for older boardtype string format */
-+              if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) {
++              if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) {
 +                      if (!strcmp(var, "bcm94710dev"))
-+                              si->boardtype = BCM94710D_BOARD;
++                              si->sb.boardtype = BCM94710D_BOARD;
 +                      else if (!strcmp(var, "bcm94710ap"))
-+                              si->boardtype = BCM94710AP_BOARD;
-+                      else if (!strcmp(var, "bcm94310u"))
-+                              si->boardtype = BCM94310U_BOARD;
-+                      else if (!strcmp(var, "bu4711"))
-+                              si->boardtype = BU4711_BOARD;
++                              si->sb.boardtype = BCM94710AP_BOARD;
 +                      else if (!strcmp(var, "bu4710"))
-+                              si->boardtype = BU4710_BOARD;
++                              si->sb.boardtype = BU4710_BOARD;
 +                      else if (!strcmp(var, "bcm94702mn"))
-+                              si->boardtype = BCM94702MN_BOARD;
++                              si->sb.boardtype = BCM94702MN_BOARD;
 +                      else if (!strcmp(var, "bcm94710r1"))
-+                              si->boardtype = BCM94710R1_BOARD;
++                              si->sb.boardtype = BCM94710R1_BOARD;
 +                      else if (!strcmp(var, "bcm94710r4"))
-+                              si->boardtype = BCM94710R4_BOARD;
++                              si->sb.boardtype = BCM94710R4_BOARD;
 +                      else if (!strcmp(var, "bcm94702cpci"))
-+                              si->boardtype = BCM94702CPCI_BOARD;
++                              si->sb.boardtype = BCM94702CPCI_BOARD;
 +                      else if (!strcmp(var, "bcm95380_rr"))
-+                              si->boardtype = BCM95380RR_BOARD; 
++                              si->sb.boardtype = BCM95380RR_BOARD;
 +              }
 +      }
 +
-+      return (si->boardtype);
++      return (si->sb.boardtype);
 +}
 +
-+/* return board bus style */
++/* return bus type of sbh device */
 +uint
-+sb_boardstyle(void *sbh)
++sb_bus(sb_t *sbh)
 +{
 +      sb_info_t *si;
-+      uint16 w;
 +
 +      si = SB_INFO(sbh);
++      return (si->sb.bustype);
++}
 +
-+      if (si->bus == PCMCIA_BUS)
-+              return (BOARDSTYLE_PCMCIA);
-+
-+      if (si->bus == SB_BUS)
-+              return (BOARDSTYLE_SOC);
-+
-+      /* bus is PCI */
-+
-+      if (OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CIS, sizeof (uint32)) != 0)
-+              return (BOARDSTYLE_CARDBUS);
++/* return bus core type */
++uint
++sb_buscoretype(sb_t *sbh)
++{
++      sb_info_t *si;
 +
-+      if ((srom_read(si->bus, si->curmap, si->osh, (SPROM_SIZE - 1) * 2, 2, &w) == 0) &&
-+          (w == 0x0313))
-+              return (BOARDSTYLE_CARDBUS);
++      si = SB_INFO(sbh);
 +
-+      return (BOARDSTYLE_PCI);
++      return (si->sb.buscoretype);
 +}
 +
-+/* return boolean if sbh device is in pci hostmode or client mode */
++/* return bus core revision */
 +uint
-+sb_bus(void *sbh)
++sb_buscorerev(sb_t *sbh)
 +{
 +      sb_info_t *si;
-+
 +      si = SB_INFO(sbh);
-+      return (si->bus);
++
++      return (si->sb.buscorerev);
 +}
 +
 +/* return list of found cores */
 +uint
-+sb_corelist(void *sbh, uint coreid[])
++sb_corelist(sb_t *sbh, uint coreid[])
 +{
 +      sb_info_t *si;
 +
@@ -5990,7 +3971,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* return current register mapping */
 +void *
-+sb_coreregs(void *sbh)
++sb_coreregs(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
@@ -6000,49 +3981,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      return (si->curmap);
 +}
 +
-+/* Check if a target abort has happened and clear it */
-+bool
-+sb_taclear(void *sbh)
-+{
-+      sb_info_t *si;
-+      bool rc = FALSE;
-+      sbconfig_t *sb;
-+
-+      si = SB_INFO(sbh);
-+      sb = REGS2SB(si->curmap);
-+
-+      if (si->bus == PCI_BUS) {
-+              uint32 stcmd;
-+
-+              stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd));
-+              rc = (stcmd & 0x08000000) != 0;
-+
-+              if (rc) {
-+                      /* Target abort bit is set, clear it */
-+                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD, sizeof(stcmd), stcmd);
-+              }
-+      } else if (si->bus == PCMCIA_BUS) {
-+              rc = FALSE;
-+      }
-+      else if (si->bus == SDIO_BUS) {
-+              /* due to 4317 A0 HW bug, sdio core wedged on target abort, 
-+                 just clear SBSErr bit blindly */
-+              if (0x0 != R_SBREG(sbh, &sb->sbtmerrlog)) {
-+                      SB_ERROR(("SDIO target abort, clean it"));
-+                      W_SBREG(sbh, &sb->sbtmstatehigh, 0);
-+              }
-+              rc = FALSE;
-+      }
-+
-+      return (rc);
-+}
 +
 +/* do buffered registers update */
 +void
-+sb_commit(void *sbh)
++sb_commit(sb_t *sbh)
 +{
 +      sb_info_t *si;
-+      sbpciregs_t *pciregs;
 +      uint origidx;
 +      uint intr_val = 0;
 +
@@ -6052,12 +3996,22 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      ASSERT(GOODIDX(origidx));
 +
 +      INTR_OFF(si, intr_val);
-+      /* switch over to pci core */
-+      pciregs = (sbpciregs_t*) sb_setcore(sbh, SB_PCI, 0);
 +
-+      /* do the buffer registers update */
-+      W_REG(&pciregs->bcastaddr, SB_COMMIT);
-+      W_REG(&pciregs->bcastdata, 0x0);
++      /* switch over to chipcommon core if there is one, else use pci */
++      if (si->sb.ccrev != NOREV) {
++              chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0);
++
++              /* do the buffer registers update */
++              W_REG(&ccregs->broadcastaddress, SB_COMMIT);
++              W_REG(&ccregs->broadcastdata, 0x0);
++      } else if (PCI(si)) {
++              sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0);
++
++              /* do the buffer registers update */
++              W_REG(&pciregs->bcastaddr, SB_COMMIT);
++              W_REG(&pciregs->bcastdata, 0x0);
++      } else
++              ASSERT(0);
 +
 +      /* restore core index */
 +      sb_setcoreidx(sbh, origidx);
@@ -6066,7 +4020,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* reset and re-enable a core */
 +void
-+sb_core_reset(void *sbh, uint32 bits)
++sb_core_reset(sb_t *sbh, uint32 bits)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -6086,69 +4040,135 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +       */
 +
 +      /* set reset while enabling the clock and forcing them on throughout the core */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits));
-+      dummy = R_SBREG(sbh, &sb->sbtmstatelow);
-+
-+      if (sb_coreid(sbh) == SB_ILINE100) {
-+              bcm_mdelay(50);
-+      } else {
-+              OSL_DELAY(1);
-+      }
++      W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits));
++      dummy = R_SBREG(si, &sb->sbtmstatelow);
++      OSL_DELAY(1);
 +
-+      if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) {
-+              W_SBREG(sbh, &sb->sbtmstatehigh, 0);
++      if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) {
++              W_SBREG(si, &sb->sbtmstatehigh, 0);
 +      }
-+      if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
-+              AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
++      if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) {
++              AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
 +      }
 +
 +      /* clear reset and allow it to propagate throughout the core */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
-+      dummy = R_SBREG(sbh, &sb->sbtmstatelow);
++      W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits));
++      dummy = R_SBREG(si, &sb->sbtmstatelow);
 +      OSL_DELAY(1);
 +
 +      /* leave clock enabled */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits));
-+      dummy = R_SBREG(sbh, &sb->sbtmstatelow);
++      W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits));
++      dummy = R_SBREG(si, &sb->sbtmstatelow);
 +      OSL_DELAY(1);
 +}
 +
 +void
-+sb_core_tofixup(void *sbh)
++sb_core_tofixup(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
 +
 +      si = SB_INFO(sbh);
 +
-+      if (si->pcirev >= 5)
++      if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || (PCI(si) && (si->sb.buscorerev >= 5)) )
 +              return;
 +
 +      ASSERT(GOODREGS(si->curmap));
 +      sb = REGS2SB(si->curmap);
 +
-+      if (si->bus == SB_BUS) {
-+              SET_SBREG(sbh, &sb->sbimconfiglow,
++      if (BUSTYPE(si->sb.bustype) == SB_BUS) {
++              SET_SBREG(si, &sb->sbimconfiglow,
 +                        SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
 +                        (0x5 << SBIMCL_RTO_SHIFT) | 0x3);
 +      } else {
 +              if (sb_coreid(sbh) == SB_PCI) {
-+                      SET_SBREG(sbh, &sb->sbimconfiglow,
++                      SET_SBREG(si, &sb->sbimconfiglow,
 +                                SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
 +                                (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
 +              } else {
-+                      SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
++                      SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0);
 +              }
 +      }
 +
 +      sb_commit(sbh);
 +}
 +
++/*
++ * Set the initiator timeout for the "master core".
++ * The master core is defined to be the core in control
++ * of the chip and so it issues accesses to non-memory
++ * locations (Because of dma *any* core can access memeory).
++ *
++ * The routine uses the bus to decide who is the master:
++ *    SB_BUS => mips
++ *    JTAG_BUS => chipc
++ *    PCI_BUS => pci
++ *
++ * This routine exists so callers can disable initiator
++ * timeouts so accesses to very slow devices like otp
++ * won't cause an abort. The routine allows arbitrary
++ * settings of the service and request timeouts, though.
++ *
++ * Returns the timeout state before changing it or -1
++ * on error.
++ */
++
++#define       TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK)
++
++uint32
++sb_set_initiator_to(sb_t *sbh, uint32 to)
++{
++      sb_info_t *si;
++      uint origidx, idx;
++      uint intr_val = 0;
++      uint32 tmp, ret = 0xffffffff;
++      sbconfig_t *sb;
++
++      si = SB_INFO(sbh);
++
++      if ((to & ~TO_MASK) != 0)
++              return ret;
++
++      /* Figure out the master core */
++      idx = BADIDX;
++      switch (BUSTYPE(si->sb.bustype)) {
++      case PCI_BUS:
++              idx = si->sb.buscoreidx; 
++              break;
++      case JTAG_BUS:
++              idx = SB_CC_IDX;
++              break;
++      case SB_BUS:
++              if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX)
++                      idx = sb_findcoreidx(si, SB_MIPS, 0);
++              break;
++      default:
++              ASSERT(0);
++      }
++      if (idx == BADIDX)
++              return ret;
++
++      INTR_OFF(si, intr_val);
++      origidx = sb_coreidx(sbh);
++
++      sb = REGS2SB(sb_setcoreidx(sbh, idx));
++
++      tmp = R_SBREG(si, &sb->sbimconfiglow);
++      ret = tmp & TO_MASK;
++      W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to);
++
++      sb_commit(sbh);
++      sb_setcoreidx(sbh, origidx);
++      INTR_RESTORE(si, intr_val);
++      return ret;
++}
++
 +void
-+sb_core_disable(void *sbh, uint32 bits)
++sb_core_disable(sb_t *sbh, uint32 bits)
 +{
 +      sb_info_t *si;
 +      volatile uint32 dummy;
++      uint32 rej;
 +      sbconfig_t *sb;
 +
 +      si = SB_INFO(sbh);
@@ -6156,83 +4176,72 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      ASSERT(GOODREGS(si->curmap));
 +      sb = REGS2SB(si->curmap);
 +
-+      /* must return if core is already in reset */
-+      if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET)
++      /* if core is already in reset, just return */
++      if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET)
 +              return;
 +
-+      /* put into reset and return if clocks are not enabled */
-+      if ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0)
-+              goto disable;
++      /* reject value changed between sonics 2.2 and 2.3 */
++      if (si->sb.sonicsrev == SONICS_2_2)
++              rej = (1 << SBTML_REJ_SHIFT);
++      else
++              rej = (2 << SBTML_REJ_SHIFT);
 +
-+      /* set the reject bit */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ));
++      /* if clocks are not enabled, put into reset and return */
++      if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0)
++              goto disable;
 +
-+      /* spin until reject is set */
-+      while ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_REJ) == 0)
-+              OSL_DELAY(1);
++      /* set target reject and spin until busy is clear (preserve core-specific bits) */
++      OR_SBREG(si, &sb->sbtmstatelow, rej);
++      dummy = R_SBREG(si, &sb->sbtmstatelow);
++      OSL_DELAY(1);
++      SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000);
 +
-+      /* spin until sbtmstatehigh.busy is clear */
-+      while (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY)
++      if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) {
++              OR_SBREG(si, &sb->sbimstate, SBIM_RJ);
++              dummy = R_SBREG(si, &sb->sbimstate);
 +              OSL_DELAY(1);
++              SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000);
++      }
 +
 +      /* set reset and reject while enabling the clocks */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET));
-+      dummy = R_SBREG(sbh, &sb->sbtmstatelow);
++      W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET));
++      dummy = R_SBREG(si, &sb->sbtmstatelow);
 +      OSL_DELAY(10);
 +
-+ disable:
++      /* don't forget to clear the initiator reject bit */
++      if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT)
++              AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ);
++
++disable:
 +      /* leave reset and reject asserted */
-+      W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET));
++      W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET));
 +      OSL_DELAY(1);
 +}
 +
++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */
 +void
-+sb_watchdog(void *sbh, uint ticks)
++sb_watchdog(sb_t *sbh, uint ticks)
 +{
 +      sb_info_t *si = SB_INFO(sbh);
 +
 +      /* instant NMI */
 +      switch (si->gpioid) {
 +      case SB_CC:
-+              sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
++              sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks);
 +              break;
 +      case SB_EXTIF:
-+              sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks);
++              sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks);
 +              break;
 +      }
 +}
 +
-+/* initialize the pcmcia core */
-+void
-+sb_pcmcia_init(void *sbh)
-+{
-+      sb_info_t *si;
-+      uint8 cor;
-+
-+      si = SB_INFO(sbh);
-+
-+      /* enable d11 mac interrupts */
-+      if (si->chip == BCM4301_DEVICE_ID) {
-+              /* Have to use FCR2 in 4301 */
-+              OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
-+              cor |= COR_IRQEN | COR_FUNEN;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1);
-+      } else {
-+              OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
-+              cor |= COR_IRQEN | COR_FUNEN;
-+              OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1);
-+      }
-+
-+}
-+
 +
 +/*
 + * Configure the pci core for pci client (NIC) action
-+ * and get appropriate dma offset value.
 + * coremask is the bitvec of cores by index to be enabled.
 + */
 +void
-+sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask)
++sb_pci_setup(sb_t *sbh, uint coremask)
 +{
 +      sb_info_t *si;
 +      sbconfig_t *sb;
@@ -6243,14 +4252,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +      si = SB_INFO(sbh);
 +
-+      if (dmaoffset)
-+              *dmaoffset = 0;
-+
 +      /* if not pci bus, we're done */
-+      if (si->bus != PCI_BUS)
++      if (BUSTYPE(si->sb.bustype) != PCI_BUS)
 +              return;
 +
-+      ASSERT(si->pciidx);
++      ASSERT(PCI(si));
++      ASSERT(si->sb.buscoreidx != BADIDX);
 +
 +      /* get current core index */
 +      idx = si->curidx;
@@ -6258,41 +4265,39 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      /* we interrupt on this backplane flag number */
 +      ASSERT(GOODREGS(si->curmap));
 +      sb = REGS2SB(si->curmap);
-+      sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
++      sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK;
 +
 +      /* switch over to pci core */
-+      pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx);
++      pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx);
 +      sb = REGS2SB(pciregs);
 +
 +      /*
 +       * Enable sb->pci interrupts.  Assume
 +       * PCI rev 2.3 support was added in pci core rev 6 and things changed..
 +       */
-+      if (si->pcirev < 6) {
-+              /* set sbintvec bit for our flag number */
-+              OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag));
-+      } else {
++      if ((PCI(si) && ((si->sb.buscorerev) >= 6))) {
 +              /* pci config write to set this core bit in PCIIntMask */
 +              w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32));
 +              w |= (coremask << PCI_SBIM_SHIFT);
 +              OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w);
++      } else {
++              /* set sbintvec bit for our flag number */
++              OR_SBREG(si, &sb->sbintvec, (1 << sbflag));
 +      }
 +
-+      /* enable prefetch and bursts for sonics-to-pci translation 2 */
-+      OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
-+
-+      if (si->pcirev < 5) {
-+              SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
-+                      (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
-+              sb_commit(sbh);
++      if (PCI(si)) {
++              OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST));
++              if (si->sb.buscorerev >= 11)
++                      OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
++              if (si->sb.buscorerev < 5) {
++                      SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK,
++                              (0x3 << SBIMCL_RTO_SHIFT) | 0x2);
++                      sb_commit(sbh);
++              }
 +      }
 +
 +      /* switch back to previous core */
 +      sb_setcoreidx(sbh, idx);
-+
-+      /* use large sb pci dma window */
-+      if (dmaoffset)
-+              *dmaoffset = SB_PCI_DMA;
 +}
 +
 +uint32
@@ -6345,7 +4350,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* return the core-type instantiation # of the current core */
 +uint
-+sb_coreunit(void *sbh)
++sb_coreunit(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      uint idx;
@@ -6392,7 +4397,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      n1 = n & CN_N1_MASK;
 +      n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT;
 +
-+      if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) {
++      if (pll_type == PLL_TYPE6) {
++              if (m & CC_T6_MMASK)
++                      return CC_T6_M1;
++              else
++                      return CC_T6_M0;
++      } else if ((pll_type == PLL_TYPE1) ||
++                 (pll_type == PLL_TYPE3) ||
++                 (pll_type == PLL_TYPE4) ||
++                 (pll_type == PLL_TYPE7)) {
 +              n1 = factor6(n1);
 +              n2 += CC_F5_BIAS;
 +      } else if (pll_type == PLL_TYPE2) {
@@ -6400,12 +4413,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              n2 += CC_T2_BIAS;
 +              ASSERT((n1 >= 2) && (n1 <= 7));
 +              ASSERT((n2 >= 5) && (n2 <= 23));
-+      } else if (pll_type == PLL_TYPE3) {
++      } else if (pll_type == PLL_TYPE5) {
 +              return (100000000);
 +      } else
-+              ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4));
-+
-+      clock = CC_CLOCK_BASE * n1 * n2;
++              ASSERT(0);
++      /* PLL types 3 and 7 use BASE2 (25Mhz) */
++      if ((pll_type == PLL_TYPE3) ||
++          (pll_type == PLL_TYPE7)) { 
++              clock =  CC_CLOCK_BASE2 * n1 * n2;
++      }
++      else 
++              clock = CC_CLOCK_BASE1 * n1 * n2;
 +
 +      if (clock == 0)
 +              return 0;
@@ -6415,9 +4433,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT;
 +      mc = (m & CC_MC_MASK) >> CC_MC_SHIFT;
 +
-+      if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) {
++      if ((pll_type == PLL_TYPE1) ||
++          (pll_type == PLL_TYPE3) ||
++          (pll_type == PLL_TYPE4) ||
++          (pll_type == PLL_TYPE7)) {
 +              m1 = factor6(m1);
-+              if (pll_type == PLL_TYPE1)
++              if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3))
 +                      m2 += CC_F5_BIAS;
 +              else
 +                      m2 = factor6(m2);
@@ -6454,7 +4475,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* returns the current speed the SB is running at */
 +uint32
-+sb_clock(void *sbh)
++sb_clock(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      extifregs_t *eir;
@@ -6477,14 +4498,35 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) {
 +              pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK;
 +              n = R_REG(&cc->clockcontrol_n);
-+              m = R_REG(&cc->clockcontrol_sb);
++              if (pll_type == PLL_TYPE6)
++                      m = R_REG(&cc->clockcontrol_mips);
++              else if (pll_type == PLL_TYPE3)
++              {
++                      // Added by Chen-I for 5365 
++                      if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)         
++                              m = R_REG(&cc->clockcontrol_sb);
++                      else
++                              m = R_REG(&cc->clockcontrol_m2);
++              }
++              else
++                      m = R_REG(&cc->clockcontrol_sb);
 +      } else {
 +              INTR_RESTORE(si, intr_val);
 +              return 0;
 +      }
 +
-+      /* calculate rate */
-+      rate = sb_clock_rate(pll_type, n, m);
++      // Added by Chen-I for 5365 
++      if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID)
++      {
++              rate = 100000000;
++      }
++      else
++      {       
++              /* calculate rate */
++              rate = sb_clock_rate(pll_type, n, m);
++              if (pll_type == PLL_TYPE3)
++                      rate = rate / 2;
++      }
 +
 +      /* switch back to previous core */
 +      sb_setcoreidx(sbh, idx);
@@ -6496,7 +4538,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* change logical "focus" to the gpio core for optimized access */
 +void*
-+sb_gpiosetcore(void *sbh)
++sb_gpiosetcore(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +
@@ -6507,7 +4549,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +/* mask&set gpiocontrol bits */
 +uint32
-+sb_gpiocontrol(void *sbh, uint32 mask, uint32 val)
++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6515,6 +4557,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      regoff = 0;
 +
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* gpios could be shared on router platforms */
++      if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
++              mask = priority ? (sb_gpioreservation & mask) :
++                      ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
++              val &= mask;
++      }
++
 +      switch (si->gpioid) {
 +      case SB_CC:
 +              regoff = OFFSETOF(chipcregs_t, gpiocontrol);
@@ -6528,12 +4579,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              return (0);
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
++      return (sb_corereg(si, si->gpioidx, regoff, mask, val));
 +}
 +
 +/* mask&set gpio output enable bits */
 +uint32
-+sb_gpioouten(void *sbh, uint32 mask, uint32 val)
++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6541,6 +4592,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      regoff = 0;
 +
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* gpios could be shared on router platforms */
++      if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
++              mask = priority ? (sb_gpioreservation & mask) :
++                      ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
++              val &= mask;
++      }
++
 +      switch (si->gpioid) {
 +      case SB_CC:
 +              regoff = OFFSETOF(chipcregs_t, gpioouten);
@@ -6555,12 +4615,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              break;
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
++      return (sb_corereg(si, si->gpioidx, regoff, mask, val));
 +}
 +
 +/* mask&set gpio output bits */
 +uint32
-+sb_gpioout(void *sbh, uint32 mask, uint32 val)
++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6568,6 +4628,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      regoff = 0;
 +
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* gpios could be shared on router platforms */
++      if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
++              mask = priority ? (sb_gpioreservation & mask) :
++                      ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
++              val &= mask;
++      }
++
 +      switch (si->gpioid) {
 +      case SB_CC:
 +              regoff = OFFSETOF(chipcregs_t, gpioout);
@@ -6582,12 +4651,78 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              break;
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
++      return (sb_corereg(si, si->gpioidx, regoff, mask, val));
++}
++
++/* reserve one gpio */
++uint32
++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
++{
++      sb_info_t *si;
++
++      si = SB_INFO(sbh);
++
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */
++      if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority))  {
++              ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
++              return -1;
++      }
++      /* make sure only one bit is set */
++      if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
++              ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
++              return -1;
++      }
++
++      /* already reserved */
++      if (sb_gpioreservation & gpio_bitmask)
++              return -1;
++      /* set reservation */
++      sb_gpioreservation |= gpio_bitmask;
++
++      return sb_gpioreservation;
++}
++
++/* release one gpio */
++/* 
++ * releasing the gpio doesn't change the current value on the GPIO last write value 
++ * persists till some one overwrites it
++*/
++
++uint32
++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority)
++{
++      sb_info_t *si;
++
++      si = SB_INFO(sbh);
++
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */
++      if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority))  {
++              ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority));
++              return -1;
++      }
++      /* make sure only one bit is set */
++      if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) {
++              ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1)));
++              return -1;
++      }
++      
++      /* already released */
++      if (!(sb_gpioreservation & gpio_bitmask))
++              return -1;
++
++      /* clear reservation */
++      sb_gpioreservation &= ~gpio_bitmask;
++
++      return sb_gpioreservation;
 +}
 +
 +/* return the current gpioin register value */
 +uint32
-+sb_gpioin(void *sbh)
++sb_gpioin(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6609,12 +4744,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              break;
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0));
++      return (sb_corereg(si, si->gpioidx, regoff, 0, 0));
 +}
 +
 +/* mask&set gpio interrupt polarity bits */
 +uint32
-+sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val)
++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6622,6 +4757,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      regoff = 0;
 +
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* gpios could be shared on router platforms */
++      if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
++              mask = priority ? (sb_gpioreservation & mask) :
++                      ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
++              val &= mask;
++      }
++
 +      switch (si->gpioid) {
 +      case SB_CC:
 +              regoff = OFFSETOF(chipcregs_t, gpiointpolarity);
@@ -6637,12 +4781,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              break;
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
++      return (sb_corereg(si, si->gpioidx, regoff, mask, val));
 +}
 +
 +/* mask&set gpio interrupt mask bits */
 +uint32
-+sb_gpiointmask(void *sbh, uint32 mask, uint32 val)
++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority)
 +{
 +      sb_info_t *si;
 +      uint regoff;
@@ -6650,6 +4794,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si = SB_INFO(sbh);
 +      regoff = 0;
 +
++      priority = GPIO_DRV_PRIORITY; /* compatibility hack */
++
++      /* gpios could be shared on router platforms */
++      if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) {
++              mask = priority ? (sb_gpioreservation & mask) :
++                      ((sb_gpioreservation | mask) & ~(sb_gpioreservation));
++              val &= mask;
++      }
++
 +      switch (si->gpioid) {
 +      case SB_CC:
 +              regoff = OFFSETOF(chipcregs_t, gpiointmask);
@@ -6665,71 +4818,180 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +              break;
 +      }
 +
-+      return (sb_corereg(sbh, si->gpioidx, regoff, mask, val));
++      return (sb_corereg(si, si->gpioidx, regoff, mask, val));
 +}
 +
++/* assign the gpio to an led */
++uint32
++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val)
++{
++      sb_info_t *si;
 +
-+/*
-+ * Return the slowclock min or max frequency.
-+ * Three sources of SLOW CLOCK:
-+ *    1. On Chip LPO         -     32khz or 160khz
-+ *    2. On Chip Xtal OSC    -     20mhz/4*(divider+1) 
-+ *    3. External PCI clock  -     66mhz/4*(divider+1)
-+ */
-+static uint
-+slowfreq(void *sbh, bool max)
++      si = SB_INFO(sbh);
++      if (si->sb.ccrev < 16)
++              return -1;
++
++      /* gpio led powersave reg */
++      return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val));
++}
++
++/* mask&set gpio timer val */
++uint32 
++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval)
 +{
 +      sb_info_t *si;
++      si = SB_INFO(sbh);
++
++      if (si->sb.ccrev < 16)
++              return -1;
++
++      return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval));
++}
++
++
++/* return the slow clock source - LPO, XTAL, or PCI */
++static uint
++sb_slowclk_src(sb_info_t *si)
++{
++      chipcregs_t *cc;
++
++
++      ASSERT(sb_coreid(&si->sb) == SB_CC);
++
++      if (si->sb.ccrev < 6) {
++              if ((BUSTYPE(si->sb.bustype) == PCI_BUS)
++                      && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS))
++                      return (SCC_SS_PCI);
++              else
++                      return (SCC_SS_XTAL);
++      } else if (si->sb.ccrev < 10) {
++              cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
++              return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK);
++      } else  /* Insta-clock */
++              return (SCC_SS_XTAL);
++}
++
++/* return the ILP (slowclock) min or max frequency */
++static uint
++sb_slowclk_freq(sb_info_t *si, bool max)
++{
 +      chipcregs_t *cc;
-+      uint32 v;
++      uint32 slowclk;
 +      uint div;
 +
-+      si = SB_INFO(sbh);
 +
-+      ASSERT(sb_coreid(sbh) == SB_CC);
++      ASSERT(sb_coreid(&si->sb) == SB_CC);
 +
-+      cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx);
++      cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx);
 +
-+      /* shouldn't be here unless we've established the chip has dynamic power control */
++      /* shouldn't be here unless we've established the chip has dynamic clk control */
 +      ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL);
 +
-+      if (si->ccrev < 6) {
-+              v = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
-+
-+              if (v & PCI_CFG_GPIO_SCS)
++      slowclk = sb_slowclk_src(si);
++      if (si->sb.ccrev < 6) {
++              if (slowclk == SCC_SS_PCI)
 +                      return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64));
 +              else
 +                      return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32));
-+      } else {
-+              v = R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
-+              div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1);
-+              if (v == SCC_SS_LPO)
++      } else if (si->sb.ccrev < 10) {
++              div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
++              if (slowclk == SCC_SS_LPO)
 +                      return (max? LPOMAXFREQ : LPOMINFREQ);
-+              else if (v == SCC_SS_XTAL)
++              else if (slowclk == SCC_SS_XTAL)
 +                      return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div));
-+              else if (v == SCC_SS_PCI)
++              else if (slowclk == SCC_SS_PCI)
 +                      return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div));
 +              else
 +                      ASSERT(0);
++      } else {
++              /* Chipc rev 10 is InstaClock */
++              div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
++              div = 4 * (div + 1);
++              return (max ? XTALMAXFREQ : (XTALMINFREQ/div));
++      }
++      return (0);
++}
++
++static void
++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs)
++{
++      chipcregs_t * cc;
++      uint slowmaxfreq, pll_delay, slowclk;
++      uint pll_on_delay, fref_sel_delay;
++
++      pll_delay = PLL_DELAY;
++
++      /* If the slow clock is not sourced by the xtal then add the xtal_on_delay
++       * since the xtal will also be powered down by dynamic clk control logic.
++       */
++      slowclk = sb_slowclk_src(si);
++      if (slowclk != SCC_SS_XTAL)
++              pll_delay += XTAL_ON_DELAY;
++
++      /* Starting with 4318 it is ILP that is used for the delays */
++      slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE);
++
++      pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
++      fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
++
++      cc = (chipcregs_t *)chipcregs;
++      W_REG(&cc->pll_on_delay, pll_on_delay);
++      W_REG(&cc->fref_sel_delay, fref_sel_delay);
++}
++
++int
++sb_pwrctl_slowclk(void *sbh, bool set, uint *div)
++{
++      sb_info_t *si;
++      uint origidx;
++      chipcregs_t *cc;
++      uint intr_val = 0;
++      uint err = 0;
++      
++      si = SB_INFO(sbh);
++
++      /* chipcommon cores prior to rev6 don't support slowclkcontrol */
++      if (si->sb.ccrev < 6)
++              return 1;
++
++      /* chipcommon cores rev10 are a whole new ball game */
++      if (si->sb.ccrev >= 10)
++              return 1;
++
++      if (set && ((*div % 4) || (*div < 4)))
++              return 2;
++      
++      INTR_OFF(si, intr_val);
++      origidx = si->curidx;
++      cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0);
++      ASSERT(cc != NULL);
++      
++      if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) {
++              err = 3;
++              goto done;
 +      }
-+      return (0);
++
++      if (set) {
++              SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT));
++              sb_clkctl_setdelay(sbh, (void *)cc);
++      } else
++              *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1);
++
++done:
++      sb_setcoreidx(sbh, origidx);
++      INTR_RESTORE(si, intr_val);
++      return err;
 +}
 +
 +/* initialize power control delay registers */
-+void
-+sb_pwrctl_init(void *sbh)
++void sb_clkctl_init(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      uint origidx;
 +      chipcregs_t *cc;
-+      uint slowmaxfreq;
-+      uint pll_on_delay, fref_sel_delay;
 +
 +      si = SB_INFO(sbh);
 +
-+      if (si->bus == SB_BUS)
-+              return;
-+
 +      origidx = si->curidx;
 +
 +      if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
@@ -6738,24 +5000,22 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
 +              goto done;
 +
-+      slowmaxfreq = slowfreq(sbh, TRUE);
-+      pll_on_delay = ((slowmaxfreq * PLL_DELAY) + 999999) / 1000000;
-+      fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
-+
-+      W_REG(&cc->pll_on_delay, pll_on_delay);
-+      W_REG(&cc->fref_sel_delay, fref_sel_delay);
-+
-+      /* 4317pc does not work with SlowClock less than 5Mhz */
-+      if (si->bus == PCMCIA_BUS)
-+              SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (0 << SCC_CD_SHF));
++      /* set all Instaclk chip ILP to 1 MHz */
++      if (si->sb.ccrev >= 10)
++              SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT));
++      
++      sb_clkctl_setdelay(si, (void *)cc);
 +
 +done:
 +      sb_setcoreidx(sbh, origidx);
 +}
-+
++void sb_pwrctl_init(sb_t *sbh)
++{
++sb_clkctl_init(sbh);
++}
 +/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
 +uint16
-+sb_pwrctl_fast_pwrup_delay(void *sbh)
++sb_clkctl_fast_pwrup_delay(sb_t *sbh)
 +{
 +      sb_info_t *si;
 +      uint origidx;
@@ -6768,9 +5028,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      fpdelay = 0;
 +      origidx = si->curidx;
 +
-+      if (si->bus == SB_BUS)
-+              goto done;
-+
 +      INTR_OFF(si, intr_val);
 +
 +      if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL)
@@ -6779,7 +5036,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL))
 +              goto done;
 +
-+      slowminfreq = slowfreq(sbh, FALSE);
++      slowminfreq = sb_slowclk_freq(si, FALSE);
 +      fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq;
 +
 +done:
@@ -6787,73 +5044,81 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      INTR_RESTORE(si, intr_val);
 +      return (fpdelay);
 +}
-+
++uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh)
++{
++return sb_clkctl_fast_pwrup_delay(sbh);
++}
 +/* turn primary xtal and/or pll off/on */
 +int
-+sb_pwrctl_xtal(void *sbh, uint what, bool on)
++sb_clkctl_xtal(sb_t *sbh, uint what, bool on)
 +{
 +      sb_info_t *si;
 +      uint32 in, out, outen;
 +
 +      si = SB_INFO(sbh);
 +
++      switch (BUSTYPE(si->sb.bustype)) {
++              case PCI_BUS:
 +
-+      if (si->bus == PCMCIA_BUS) {
-+              return (0);
-+      }
-+
-+      if (si->bus != PCI_BUS) 
-+              return (-1);
-+
-+      in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32));
-+      out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
-+      outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32));
-+
-+      /*
-+       * We can't actually read the state of the PLLPD so we infer it
-+       * by the value of XTAL_PU which *is* readable via gpioin.
-+       */
-+      if (on && (in & PCI_CFG_GPIO_XTAL))
-+              return (0);
++                      in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32));
++                      out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32));
++                      outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32));
 +
-+      if (what & XTAL)
-+              outen |= PCI_CFG_GPIO_XTAL;
-+      if (what & PLL)
-+              outen |= PCI_CFG_GPIO_PLL;
++                      /*
++                       * Avoid glitching the clock if GPRS is already using it.
++                       * We can't actually read the state of the PLLPD so we infer it
++                       * by the value of XTAL_PU which *is* readable via gpioin.
++                       */
++                      if (on && (in & PCI_CFG_GPIO_XTAL))
++                              return (0);
 +
-+      if (on) {
-+              /* turn primary xtal on */
-+              if (what & XTAL) {
-+                      out |= PCI_CFG_GPIO_XTAL;
++                      if (what & XTAL)
++                              outen |= PCI_CFG_GPIO_XTAL;
 +                      if (what & PLL)
-+                              out |= PCI_CFG_GPIO_PLL;
-+                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
-+                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
-+                      OSL_DELAY(200);
-+              }
++                              outen |= PCI_CFG_GPIO_PLL;
++
++                      if (on) {
++                              /* turn primary xtal on */
++                              if (what & XTAL) {
++                                      out |= PCI_CFG_GPIO_XTAL;
++                                      if (what & PLL)
++                                              out |= PCI_CFG_GPIO_PLL;
++                                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
++                                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
++                                      OSL_DELAY(XTAL_ON_DELAY);
++                              }
 +
-+              /* turn pll on */
-+              if (what & PLL) {
-+                      out &= ~PCI_CFG_GPIO_PLL;
-+                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
-+                      OSL_DELAY(2000);
-+              }
-+      } else {
-+              if (what & XTAL)
-+                      out &= ~PCI_CFG_GPIO_XTAL;
-+              if (what & PLL)
-+                      out |= PCI_CFG_GPIO_PLL;
-+              OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
-+              OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
++                              /* turn pll on */
++                              if (what & PLL) {
++                                      out &= ~PCI_CFG_GPIO_PLL;
++                                      OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
++                                      OSL_DELAY(2000);
++                              }
++                      } else {
++                              if (what & XTAL)
++                                      out &= ~PCI_CFG_GPIO_XTAL;
++                              if (what & PLL)
++                                      out |= PCI_CFG_GPIO_PLL;
++                              OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out);
++                              OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen);
++                      }
++
++              default:
++                      return (-1);
 +      }
 +
 +      return (0);
 +}
 +
-+/* set dynamic power control mode (forceslow, forcefast, dynamic) */
++int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on)
++{
++return sb_clkctl_xtal(sbh,what,on);
++}
++
++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */
 +/*   returns true if ignore pll off is set and false if it is not */
 +bool
-+sb_pwrctl_clk(void *sbh, uint mode)
++sb_clkctl_clk(sb_t *sbh, uint mode)
 +{
 +      sb_info_t *si;
 +      uint origidx;
@@ -6864,8 +5129,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +      si = SB_INFO(sbh);
 +
-+      /* chipcommon cores prior to rev6 don't support slowclkcontrol */
-+      if (si->ccrev < 6)
++      /* chipcommon cores prior to rev6 don't support dynamic clock control */
++      if (si->sb.ccrev < 6)
++              return (FALSE);
++
++      /* chipcommon cores rev10 are a whole new ball game */
++      if (si->sb.ccrev >= 10)
 +              return (FALSE);
 +
 +      INTR_OFF(si, intr_val);
@@ -6881,20 +5150,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      switch (mode) {
 +      case CLK_FAST:  /* force fast (pll) clock */
 +              /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
-+              sb_pwrctl_xtal(sbh, XTAL, ON);
++              sb_clkctl_xtal(&si->sb, XTAL, ON);
 +
 +              SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP);
 +              break;
 +
-+      case CLK_SLOW:  /* force slow clock */
-+              if ((si->bus == SDIO_BUS) || (si->bus == PCMCIA_BUS))
-+                      return (-1);
-+
-+              if (si->ccrev >= 6)
-+                      OR_REG(&cc->slow_clk_ctl, SCC_FS);
-+              break;
-+
-+      case CLK_DYNAMIC:       /* enable dynamic power control */
++      case CLK_DYNAMIC:       /* enable dynamic clock control */
 +              scc = R_REG(&cc->slow_clk_ctl);
 +              scc &= ~(SCC_FS | SCC_IP | SCC_XC);
 +              if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
@@ -6903,10 +5164,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +
 +              /* for dynamic control, we have to release our xtal_pu "force on" */
 +              if (scc & SCC_XC)
-+                      sb_pwrctl_xtal(sbh, XTAL, OFF);
++                      sb_clkctl_xtal(&si->sb, XTAL, OFF);
 +              break;
++
++      default:
++              ASSERT(0);
 +      }
-+      
++
 +      /* Is the h/w forcing the use of the fast clk */
 +      forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP);
 +
@@ -6916,9 +5180,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      return (forcefastclk);
 +}
 +
++bool sb_pwrctl_clk(sb_t *sbh, uint mode)
++{
++return sb_clkctl_clk(sbh, mode);
++}
 +/* register driver interrupt disabling and restoring callback functions */
 +void
-+sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intr_arg)
++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg)
 +{
 +      sb_info_t *si;
 +
@@ -6926,6 +5194,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/broadcom/sbutils.c linux-2.6.12.5-br
 +      si->intr_arg = intr_arg;
 +      si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn;
 +      si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn;
++      si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn;
 +      /* save current core id.  when this function called, the current core
 +       * must be the core which provides driver functions(il, et, wl, etc.)
 +       */
@@ -6933,115 +5202,608 @@ 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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,90 @@
-+/*
-+ * BCM4710 address space map and definitions
-+ * Think twice before adding to this file, this is not the kitchen sink
-+ * These definitions are not guaranteed for all 47xx chips, only the 4710
++void
++sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, 
++      uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif)
++{
++      uint vendor, core, unit;
++      uint chip, chippkg;
++      char varname[8];
++      uint8 class, subclass, progif;
++      
++      vendor = sb_corevendor(sbh);
++      core = sb_coreid(sbh);
++      unit = sb_coreunit(sbh);
++
++      chip = BCMINIT(sb_chip)(sbh);
++      chippkg = BCMINIT(sb_chippkg)(sbh);
++
++      progif = 0;
++      
++      /* Known vendor translations */
++      switch (vendor) {
++      case SB_VEND_BCM:
++              vendor = VENDOR_BROADCOM;
++              break;
++      }
++
++      /* Determine class based on known core codes */
++      switch (core) {
++      case SB_ILINE20:
++              class = PCI_CLASS_NET;
++              subclass = PCI_NET_ETHER;
++              core = BCM47XX_ILINE_ID;
++              break;
++      case SB_ENET:
++              class = PCI_CLASS_NET;
++              subclass = PCI_NET_ETHER;
++              core = BCM47XX_ENET_ID;
++              break;
++      case SB_SDRAM:
++      case SB_MEMC:
++              class = PCI_CLASS_MEMORY;
++              subclass = PCI_MEMORY_RAM;
++              break;
++      case SB_PCI:
++              class = PCI_CLASS_BRIDGE;
++              subclass = PCI_BRIDGE_PCI;
++              break;
++      case SB_MIPS:
++      case SB_MIPS33:
++              class = PCI_CLASS_CPU;
++              subclass = PCI_CPU_MIPS;
++              break;
++      case SB_CODEC:
++              class = PCI_CLASS_COMM;
++              subclass = PCI_COMM_MODEM;
++              core = BCM47XX_V90_ID;
++              break;
++      case SB_USB:
++              class = PCI_CLASS_SERIAL;
++              subclass = PCI_SERIAL_USB;
++              progif = 0x10; /* OHCI */
++              core = BCM47XX_USB_ID;
++              break;
++      case SB_USB11H:
++              class = PCI_CLASS_SERIAL;
++              subclass = PCI_SERIAL_USB;
++              progif = 0x10; /* OHCI */
++              core = BCM47XX_USBH_ID;
++              break;
++      case SB_USB11D:
++              class = PCI_CLASS_SERIAL;
++              subclass = PCI_SERIAL_USB;
++              core = BCM47XX_USBD_ID;
++              break;
++      case SB_IPSEC:
++              class = PCI_CLASS_CRYPT;
++              subclass = PCI_CRYPT_NETWORK;
++              core = BCM47XX_IPSEC_ID;
++              break;
++      case SB_ROBO:
++              class = PCI_CLASS_NET;
++              subclass = PCI_NET_OTHER;
++              core = BCM47XX_ROBO_ID;
++              break;
++      case SB_EXTIF:
++      case SB_CC:
++              class = PCI_CLASS_MEMORY;
++              subclass = PCI_MEMORY_FLASH;
++              break;
++      case SB_D11:
++              class = PCI_CLASS_NET;
++              subclass = PCI_NET_OTHER;
++              /* Let an nvram variable override this */
++              sprintf(varname, "wl%did", unit);
++              if ((core = getintvar(NULL, varname)) == 0) {
++                      if (chip == BCM4712_DEVICE_ID) {
++                              if (chippkg == BCM4712SMALL_PKG_ID)
++                                      core = BCM4306_D11G_ID;
++                              else
++                                      core = BCM4306_D11DUAL_ID;
++                      }
++              }
++              break;
++
++      default:
++              class = subclass = progif = 0xff;
++              break;
++      }
++
++      *pcivendor = (uint16)vendor;
++      *pcidevice = (uint16)core;
++      *pciclass = class;
++      *pcisubclass = subclass;
++      *pciprogif = progif;
++}
++
++/* Fix chip's configuration. The current core may be changed upon return */
++static int
++sb_pci_fixcfg(sb_info_t *si)
++{
++      uint origidx, pciidx;
++      sbpciregs_t *pciregs;
++      uint16 val16, *reg16;
++
++      ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS);
++
++      /* Fix PCI(e) SROM shadow area */
++      /* save the current index */
++      origidx = sb_coreidx(&si->sb);
++
++      if (si->sb.buscoretype == SB_PCI) {
++              pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0);
++              ASSERT(pciregs);
++              reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
++      }
++      else {
++              ASSERT(0);
++              return -1;
++      }
++      pciidx = sb_coreidx(&si->sb);
++      val16 = R_REG(reg16);
++      if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) {
++              val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK);
++              W_REG(reg16, val16);
++      }
++
++      /* restore the original index */
++      sb_setcoreidx(&si->sb, origidx);
++
++      return 0;
++}
++
++EXPORT_SYMBOL(sb_boardtype);
++EXPORT_SYMBOL(sb_boardvendor);
++EXPORT_SYMBOL(sb_gpiocontrol);
++EXPORT_SYMBOL(sb_gpioin);
++EXPORT_SYMBOL(sb_gpiointmask);
++EXPORT_SYMBOL(sb_gpiointpolarity);
++EXPORT_SYMBOL(sb_gpioled);
++EXPORT_SYMBOL(sb_gpioout);
++EXPORT_SYMBOL(sb_gpioouten);
++EXPORT_SYMBOL(sb_gpiorelease);
++EXPORT_SYMBOL(sb_gpioreserve);
++EXPORT_SYMBOL(sb_gpiosetcore);
++EXPORT_SYMBOL(sb_gpiotimerval);
++EXPORT_SYMBOL(sb_watchdog);
+diff -urN linux.old/arch/mips/bcm947xx/broadcom/sflash.c linux.dev/arch/mips/bcm947xx/broadcom/sflash.c
+--- linux.old/arch/mips/bcm947xx/broadcom/sflash.c     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/broadcom/sflash.c     2005-12-15 16:59:20.045933750 +0100
+@@ -0,0 +1,418 @@
++/*
++ * Broadcom SiliconBackplane chipcommon serial flash interface
++ *
++ * 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.      
 + *
-+ * 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$
 + */
 +
-+#ifndef _bcm4710_h_
-+#define _bcm4710_h_
++#include <osl.h>
++#include <typedefs.h>
++#include <sbconfig.h>
++#include <sbchipc.h>
++#include <mipsinc.h>
++#include <bcmutils.h>
++#include <bcmdevs.h>
++#include <sflash.h>
++
++/* Private global state */
++static struct sflash sflash;
 +
-+/* Address map */
-+#define BCM4710_SDRAM         0x00000000      /* Physical SDRAM */
-+#define BCM4710_PCI_MEM               0x08000000      /* Host Mode PCI memory access space (64 MB) */
-+#define BCM4710_PCI_CFG               0x0c000000      /* Host Mode PCI configuration space (64 MB) */
-+#define BCM4710_PCI_DMA               0x40000000      /* Client Mode PCI memory access space (1 GB) */
-+#define       BCM4710_SDRAM_SWAPPED   0x10000000      /* Byteswapped Physical SDRAM */
-+#define BCM4710_ENUM          0x18000000      /* Beginning of core enumeration space */
++/* Issue a serial flash command */
++static INLINE void
++sflash_cmd(chipcregs_t *cc, uint opcode)
++{
++      W_REG(&cc->flashcontrol, SFLASH_START | opcode);
++      while (R_REG(&cc->flashcontrol) & SFLASH_BUSY);
++}
 +
-+/* Core register space */
-+#define BCM4710_REG_SDRAM     0x18000000      /* SDRAM core registers */
-+#define BCM4710_REG_ILINE20   0x18001000      /* InsideLine20 core registers */
-+#define BCM4710_REG_EMAC0     0x18002000      /* Ethernet MAC 0 core registers */
-+#define BCM4710_REG_CODEC     0x18003000      /* Codec core registers */
-+#define BCM4710_REG_USB               0x18004000      /* USB core registers */
-+#define BCM4710_REG_PCI               0x18005000      /* PCI core registers */
-+#define BCM4710_REG_MIPS      0x18006000      /* MIPS core registers */
-+#define BCM4710_REG_EXTIF     0x18007000      /* External Interface core registers */
-+#define BCM4710_REG_EMAC1     0x18008000      /* Ethernet MAC 1 core registers */
-+
-+#define       BCM4710_EXTIF           0x1f000000      /* External Interface base address */
-+#define BCM4710_PCMCIA_MEM    0x1f000000      /* External Interface PCMCIA memory access */
-+#define BCM4710_PCMCIA_IO     0x1f100000      /* PCMCIA I/O access */
-+#define BCM4710_PCMCIA_CONF   0x1f200000      /* PCMCIA configuration */
-+#define BCM4710_PROG          0x1f800000      /* Programable interface */
-+#define BCM4710_FLASH         0x1fc00000      /* Flash */
-+
-+#define       BCM4710_EJTAG           0xff200000      /* MIPS EJTAG space (2M) */
-+
-+#define       BCM4710_UART            (BCM4710_REG_EXTIF + 0x00000300)
-+
-+#define       BCM4710_EUART           (BCM4710_EXTIF + 0x00800000)
-+#define       BCM4710_LED             (BCM4710_EXTIF + 0x00900000)
++/* Initialize serial flash access */
++struct sflash *
++sflash_init(chipcregs_t *cc)
++{
++      uint32 id, id2;
 +
-+#define       SBFLAG_PCI      0
-+#define       SBFLAG_ENET0    1
-+#define       SBFLAG_ILINE20  2
-+#define       SBFLAG_CODEC    3
-+#define       SBFLAG_USB      4
-+#define       SBFLAG_EXTIF    5
-+#define       SBFLAG_ENET1    6
++      bzero(&sflash, sizeof(sflash));
 +
-+#ifdef        CONFIG_HWSIM
-+#define       BCM4710_TRACE(trval)        do { *((int *)0xa0000f18) = (trval); } while (0)
-+#else
-+#define       BCM4710_TRACE(trval)
-+#endif
++      sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK;
++
++      switch (sflash.type) {
++      case SFLASH_ST:
++              /* Probe for ST chips */
++              sflash_cmd(cc, SFLASH_ST_DP);
++              sflash_cmd(cc, SFLASH_ST_RES);
++              id = R_REG(&cc->flashdata);
++              switch (id) {
++              case 0x11:
++                      /* ST M25P20 2 Mbit Serial Flash */
++                      sflash.blocksize = 64 * 1024;
++                      sflash.numblocks = 4;
++                      break;
++              case 0x12:
++                      /* ST M25P40 4 Mbit Serial Flash */
++                      sflash.blocksize = 64 * 1024;
++                      sflash.numblocks = 8;
++                      break;
++              case 0x13:
++                      /* ST M25P80 8 Mbit Serial Flash */
++                      sflash.blocksize = 64 * 1024;
++                      sflash.numblocks = 16;
++                      break;
++              case 0x14:
++                      /* ST M25P16 16 Mbit Serial Flash */
++                      sflash.blocksize = 64 * 1024;
++                      sflash.numblocks = 32;
++                      break;
++              case 0x15:
++                      /* ST M25P32 32 Mbit Serial Flash */
++                      sflash.blocksize = 64 * 1024;
++                      sflash.numblocks = 64;
++                      break;
++              case 0xbf:
++                      W_REG(&cc->flashaddress, 1);
++                      sflash_cmd(cc, SFLASH_ST_RES);
++                      id2 = R_REG(&cc->flashdata);
++                      if (id2 == 0x44) {
++                              /* SST M25VF80 4 Mbit Serial Flash */
++                              sflash.blocksize = 64 * 1024;
++                              sflash.numblocks = 8;
++                      }
++                      break;
++              }
++              break;
++
++      case SFLASH_AT:
++              /* Probe for Atmel chips */
++              sflash_cmd(cc, SFLASH_AT_STATUS);
++              id = R_REG(&cc->flashdata) & 0x3c;
++              switch (id) {
++              case 0xc:
++                      /* Atmel AT45DB011 1Mbit Serial Flash */
++                      sflash.blocksize = 256;
++                      sflash.numblocks = 512;
++                      break;
++              case 0x14:
++                      /* Atmel AT45DB021 2Mbit Serial Flash */
++                      sflash.blocksize = 256;
++                      sflash.numblocks = 1024;
++                      break;
++              case 0x1c:
++                      /* Atmel AT45DB041 4Mbit Serial Flash */
++                      sflash.blocksize = 256;
++                      sflash.numblocks = 2048;
++                      break;
++              case 0x24:
++                      /* Atmel AT45DB081 8Mbit Serial Flash */
++                      sflash.blocksize = 256;
++                      sflash.numblocks = 4096;
++                      break;
++              case 0x2c:
++                      /* Atmel AT45DB161 16Mbit Serial Flash */
++                      sflash.blocksize = 512;
++                      sflash.numblocks = 4096;
++                      break;
++              case 0x34:
++                      /* Atmel AT45DB321 32Mbit Serial Flash */
++                      sflash.blocksize = 512;
++                      sflash.numblocks = 8192;
++                      break;
++              case 0x3c:
++                      /* Atmel AT45DB642 64Mbit Serial Flash */
++                      sflash.blocksize = 1024;
++                      sflash.numblocks = 8192;
++                      break;
++              }
++              break;
++      }
 +
++      sflash.size = sflash.blocksize * sflash.numblocks;
++      return sflash.size ? &sflash : NULL;
++}
 +
-+/* BCM94702 CPCI -ExtIF used for LocalBus devs */
++/* Read len bytes starting at offset into buf. Returns number of bytes read. */
++int
++sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf)
++{
++      int cnt;
++      uint32 *from, *to;
 +
-+#define BCM94702_CPCI_RESET_ADDR       BCM4710_EXTIF
-+#define BCM94702_CPCI_BOARDID_ADDR    (BCM4710_EXTIF | 0x4000)
-+#define BCM94702_CPCI_DOC_ADDR        (BCM4710_EXTIF | 0x6000)
-+#define BCM94702_DOC_ADDR                BCM94702_CPCI_DOC_ADDR
-+#define BCM94702_CPCI_LED_ADDR        (BCM4710_EXTIF | 0xc000)
-+#define BCM94702_CPCI_NVRAM_ADDR      (BCM4710_EXTIF | 0xe000)
-+#define BCM94702_CPCI_NVRAM_SIZE         0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/
-+#define BCM94702_CPCI_TOD_REG_BASE       (BCM94702_CPCI_NVRAM_ADDR | 0x1ff0)
++      if (!len)
++              return 0;
 +
-+#define LED_REG(x)      \
-+ (*(volatile unsigned char *) (KSEG1ADDR(BCM94702_CPCI_LED_ADDR) + (x)))
++      if ((offset + len) > sflash.size)
++              return -22;
 +
-+/* 
-+ * Reset function implemented in PLD.  Read or write should trigger hard reset 
++      if ((len >= 4) && (offset & 3))
++              cnt = 4 - (offset & 3);
++      else if ((len >= 4) && ((uint32)buf & 3))
++              cnt = 4 - ((uint32)buf & 3);
++      else
++              cnt = len;
++
++      from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset);
++      to = (uint32 *)buf;
++
++      if (cnt < 4) {
++              bcopy(from, to, cnt);
++              return cnt;
++      }
++
++      while (cnt >= 4) {
++              *to++ = *from++;
++              cnt -= 4;
++      }
++
++      return (len - cnt);
++}
++
++/* Poll for command completion. Returns zero when complete. */
++int
++sflash_poll(chipcregs_t *cc, uint offset)
++{
++      if (offset >= sflash.size)
++              return -22;
++
++      switch (sflash.type) {
++      case SFLASH_ST:
++              /* Check for ST Write In Progress bit */
++              sflash_cmd(cc, SFLASH_ST_RDSR);
++              return R_REG(&cc->flashdata) & SFLASH_ST_WIP;
++      case SFLASH_AT:
++              /* Check for Atmel Ready bit */
++              sflash_cmd(cc, SFLASH_AT_STATUS);
++              return !(R_REG(&cc->flashdata) & SFLASH_AT_READY);
++      }
++
++      return 0;
++}
++
++/* Write len bytes starting at offset into buf. Returns number of bytes
++ * written. Caller should poll for completion.
 + */
-+#define SYS_HARD_RESET()   \
-+    { for (;;) \
-+     *( (volatile unsigned char *)\
-+      KSEG1ADDR(BCM94702_CPCI_RESET_ADDR) ) = 0x80; \
-+    }
++int
++sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
++{
++      struct sflash *sfl;
++      int ret = 0;
++      bool is4712b0;
++      uint32 page, byte, mask;
++
++      if (!len)
++              return 0;
++
++      if ((offset + len) > sflash.size)
++              return -22;
++
++      sfl = &sflash;
++      switch (sfl->type) {
++      case SFLASH_ST:
++              mask = R_REG(&cc->chipid);
++              is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) &&
++                          ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT)));
++              /* Enable writes */
++              sflash_cmd(cc, SFLASH_ST_WREN);
++              if (is4712b0) {
++                      mask = 1 << 14;
++                      W_REG(&cc->flashaddress, offset);
++                      W_REG(&cc->flashdata, *buf++);
++                      /* Set chip select */
++                      OR_REG(&cc->gpioout, mask);
++                      /* Issue a page program with the first byte */
++                      sflash_cmd(cc, SFLASH_ST_PP);
++                      ret = 1;
++                      offset++;
++                      len--;
++                      while (len > 0) {
++                              if ((offset & 255) == 0) {
++                                      /* Page boundary, drop cs and return */
++                                      AND_REG(&cc->gpioout, ~mask);
++                                      if (!sflash_poll(cc, offset)) {
++                                              /* Flash rejected command */
++                                              return -11;
++                                      }
++                                      return ret;
++                              } else {
++                                      /* Write single byte */
++                                      sflash_cmd(cc, *buf++);
++                              }
++                              ret++;
++                              offset++;
++                              len--;
++                      }
++                      /* All done, drop cs if needed */
++                      if ((offset & 255) != 1) {
++                              /* Drop cs */
++                              AND_REG(&cc->gpioout, ~mask);
++                              if (!sflash_poll(cc, offset)) {
++                                      /* Flash rejected command */
++                                      return -12;
++                              }
++                      }
++              } else {
++                      ret = 1;
++                      W_REG(&cc->flashaddress, offset);
++                      W_REG(&cc->flashdata, *buf);
++                      /* Page program */
++                      sflash_cmd(cc, SFLASH_ST_PP);
++              }
++              break;
++      case SFLASH_AT:
++              mask = sfl->blocksize - 1;
++              page = (offset & ~mask) << 1;
++              byte = offset & mask;
++              /* Read main memory page into buffer 1 */
++              if (byte || len < sfl->blocksize) {
++                      W_REG(&cc->flashaddress, page);
++                      sflash_cmd(cc, SFLASH_AT_BUF1_LOAD);
++                      /* 250 us for AT45DB321B */
++                      SPINWAIT(sflash_poll(cc, offset), 1000);
++                      ASSERT(!sflash_poll(cc, offset));
++              }
++              /* Write into buffer 1 */
++              for (ret = 0; ret < len && byte < sfl->blocksize; ret++) {
++                      W_REG(&cc->flashaddress, byte++);
++                      W_REG(&cc->flashdata, *buf++);
++                      sflash_cmd(cc, SFLASH_AT_BUF1_WRITE);
++              }
++              /* Write buffer 1 into main memory page */
++              W_REG(&cc->flashaddress, page);
++              sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM);
++              break;
++      }
++
++      return ret;
++}
++
++/* Erase a region. Returns number of bytes scheduled for erasure.
++ * Caller should poll for completion.
++ */
++int
++sflash_erase(chipcregs_t *cc, uint offset)
++{
++      struct sflash *sfl;
++
++      if (offset >= sflash.size)
++              return -22;
++
++      sfl = &sflash;
++      switch (sfl->type) {
++      case SFLASH_ST:
++              sflash_cmd(cc, SFLASH_ST_WREN);
++              W_REG(&cc->flashaddress, offset);
++              sflash_cmd(cc, SFLASH_ST_SE);
++              return sfl->blocksize;
++      case SFLASH_AT:
++              W_REG(&cc->flashaddress, offset << 1);
++              sflash_cmd(cc, SFLASH_AT_PAGE_ERASE);
++              return sfl->blocksize;
++      }
++
++      return 0;
++}
++
++/*
++ * writes the appropriate range of flash, a NULL buf simply erases
++ * the region of flash
++ */
++int
++sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf)
++{
++      struct sflash *sfl;
++      uchar *block = NULL, *cur_ptr, *blk_ptr;
++      uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder;
++      uint blk_offset, blk_len, copied;
++      int bytes, ret = 0;
++
++      /* Check address range */
++      if (len <= 0)
++              return 0;
++
++      sfl = &sflash;
++      if ((offset + len) > sfl->size)
++              return -1;
++
++      blocksize = sfl->blocksize;
++      mask = blocksize - 1;
++
++      /* Allocate a block of mem */
++      if (!(block = MALLOC(NULL, blocksize)))
++              return -1;
++
++      while (len) {
++              /* Align offset */
++              cur_offset = offset & ~mask;
++              cur_length = blocksize;
++              cur_ptr = block;
++
++              remainder = blocksize - (offset & mask);
++              if (len < remainder)
++                      cur_retlen = len;
++              else
++                      cur_retlen = remainder;
++
++              /* buf == NULL means erase only */
++              if (buf) {
++                      /* Copy existing data into holding block if necessary */
++                      if ((offset & mask)  || (len < blocksize)) {
++                              blk_offset = cur_offset;
++                              blk_len = cur_length;
++                              blk_ptr = cur_ptr;
++
++                              /* Copy entire block */
++                              while(blk_len) {
++                                      copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); 
++                                      blk_offset += copied;
++                                      blk_len -= copied;
++                                      blk_ptr += copied;
++                              }
++                      }
++
++                      /* Copy input data into holding block */
++                      memcpy(cur_ptr + (offset & mask), buf, cur_retlen);
++              }
++
++              /* Erase block */
++              if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0)
++                      goto done;
++              while (sflash_poll(cc, (uint) cur_offset));
++
++              /* buf == NULL means erase only */
++              if (!buf) {
++                      offset += cur_retlen;
++                      len -= cur_retlen;
++                      continue;
++              }
++
++              /* Write holding block */
++              while (cur_length > 0) {
++                      if ((bytes = sflash_write(cc,
++                                                (uint) cur_offset,
++                                                (uint) cur_length,
++                                                (uchar *) cur_ptr)) < 0) {
++                              ret = bytes;
++                              goto done;
++                      }
++                      while (sflash_poll(cc, (uint) cur_offset));
++                      cur_offset += bytes;
++                      cur_length -= bytes;
++                      cur_ptr += bytes;
++              }
++
++              offset += cur_retlen;
++              len -= cur_retlen;
++              buf += cur_retlen;
++      }
 +
-+#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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,238 @@
++      ret = len;
++done:
++      if (block)
++              MFREE(NULL, block, blocksize);
++      return ret;
++}
++
+diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h
+--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h     2005-12-15 15:25:24.905340500 +0100
+@@ -0,0 +1,391 @@
 +/*
 + * Broadcom device-specific manifest constants.
 + *
-+ * $Id$
-+ * Copyright 2001-2003, Broadcom Corporation   
++ * 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$
 + */
 +
 +#ifndef       _BCMDEVS_H
@@ -7083,6 +5845,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define       BCM47XX_USBH_ID         0x4716          /* 47xx usb host */
 +#define       BCM47XX_USBD_ID         0x4717          /* 47xx usb device */
 +#define       BCM47XX_IPSEC_ID        0x4718          /* 47xx ipsec */
++#define       BCM47XX_ROBO_ID         0x4719          /* 47xx/53xx roboswitch core */
++#define       BCM47XX_USB20H_ID       0x471a          /* 47xx usb 2.0 host */
++#define       BCM47XX_USB20D_ID       0x471b          /* 47xx usb 2.0 device */
 +
 +#define       BCM4710_DEVICE_ID       0x4710          /* 4710 primary function 0 */
 +
@@ -7096,6 +5861,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define       BCM4402_DEVICE_ID       0x4402          /* 4402 primary function 0 */
 +#define       BCM4402_ENET_ID         0x4402          /* 4402 enet */
 +#define       BCM4402_V90_ID          0x4403          /* 4402 v90 codec */
++#define       BCM4401_ENET_ID         0x170c          /* 4401b0 production enet cards */
 +
 +#define       BCM4301_DEVICE_ID       0x4301          /* 4301 primary function 0 */
 +#define       BCM4301_D11B_ID         0x4301          /* 4301 802.11b */
@@ -7124,19 +5890,68 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define       BCM4310_ENET_ID         0x4313          /* 4310 enet */
 +#define       BCM4310_USB_ID          0x4315          /* 4310 usb */
 +
++#define       BCMGPRS_UART_ID         0x4333          /* Uart id used by 4306/gprs card */
++#define       BCMGPRS2_UART_ID        0x4344          /* Uart id used by 4306/gprs card */
++
++
 +#define       BCM4704_DEVICE_ID       0x4704          /* 4704 chipcommon chipid */
 +#define       BCM4704_ENET_ID         0x4706          /* 4704 enet (Use 47XX_ENET_ID instead!) */
 +
 +#define       BCM4317_DEVICE_ID       0x4317          /* 4317 chip common chipid */
 +
++#define       BCM4318_DEVICE_ID       0x4318          /* 4318 chip common chipid */
++#define       BCM4318_D11G_ID         0x4318          /* 4318 801.11b/g id */
++#define       BCM4318_D11DUAL_ID      0x4319          /* 4318 801.11a/b/g id */
++#define BCM4318_JTAGM_ID      0x4331          /* 4318 jtagm device id */
++
++#define FPGA_JTAGM_ID         0x4330          /* ??? */
++
++/* Address map */
++#define BCM4710_SDRAM           0x00000000      /* Physical SDRAM */
++#define BCM4710_PCI_MEM         0x08000000      /* Host Mode PCI memory access space (64 MB) */
++#define BCM4710_PCI_CFG         0x0c000000      /* Host Mode PCI configuration space (64 MB) */
++#define BCM4710_PCI_DMA         0x40000000      /* Client Mode PCI memory access space (1 GB) */
++#define BCM4710_SDRAM_SWAPPED   0x10000000      /* Byteswapped Physical SDRAM */
++#define BCM4710_ENUM            0x18000000      /* Beginning of core enumeration space */
++
++/* Core register space */
++#define BCM4710_REG_SDRAM       0x18000000      /* SDRAM core registers */
++#define BCM4710_REG_ILINE20     0x18001000      /* InsideLine20 core registers */
++#define BCM4710_REG_EMAC0       0x18002000      /* Ethernet MAC 0 core registers */
++#define BCM4710_REG_CODEC       0x18003000      /* Codec core registers */
++#define BCM4710_REG_USB         0x18004000      /* USB core registers */
++#define BCM4710_REG_PCI         0x18005000      /* PCI core registers */
++#define BCM4710_REG_MIPS        0x18006000      /* MIPS core registers */
++#define BCM4710_REG_EXTIF       0x18007000      /* External Interface core registers */
++#define BCM4710_REG_EMAC1       0x18008000      /* Ethernet MAC 1 core registers */
++
++#define BCM4710_EXTIF           0x1f000000      /* External Interface base address */
++#define BCM4710_PCMCIA_MEM      0x1f000000      /* External Interface PCMCIA memory access */
++#define BCM4710_PCMCIA_IO       0x1f100000      /* PCMCIA I/O access */
++#define BCM4710_PCMCIA_CONF     0x1f200000      /* PCMCIA configuration */
++#define BCM4710_PROG            0x1f800000      /* Programable interface */
++#define BCM4710_FLASH           0x1fc00000      /* Flash */
++
++#define BCM4710_EJTAG           0xff200000      /* MIPS EJTAG space (2M) */
++
++#define BCM4710_UART            (BCM4710_REG_EXTIF + 0x00000300)
++
++#define BCM4710_EUART           (BCM4710_EXTIF + 0x00800000)
++#define BCM4710_LED             (BCM4710_EXTIF + 0x00900000)
++
 +#define       BCM4712_DEVICE_ID       0x4712          /* 4712 chipcommon chipid */
 +#define       BCM4712_MIPS_ID         0x4720          /* 4712 base devid */
++#define       BCM4712LARGE_PKG_ID     0               /* 340pin 4712 package id */
 +#define       BCM4712SMALL_PKG_ID     1               /* 200pin 4712 package id */
++#define       BCM4712MID_PKG_ID       2               /* 225pin 4712 package id */
 +
 +#define       SDIOH_FPGA_ID           0x4380          /* sdio host fpga */
 +
 +#define BCM5365_DEVICE_ID       0x5365          /* 5365 chipcommon chipid */
++#define       BCM5350_DEVICE_ID       0x5350          /* bcm5350 chipcommon chipid */
++#define       BCM5352_DEVICE_ID       0x5352          /* bcm5352 chipcommon chipid */
 +
++#define       BCM4320_DEVICE_ID       0x4320          /* bcm4320 chipcommon chipid */
 +
 +/* PCMCIA vendor Id's */
 +
@@ -7150,13 +5965,22 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define       BFL_BTCOEXIST           0x0001  /* This board implements Bluetooth coexistance */
 +#define       BFL_PACTRL              0x0002  /* This board has gpio 9 controlling the PA */
 +#define       BFL_AIRLINEMODE         0x0004  /* This board implements gpio13 radio disable indication */
-+#define       BFL_ENETSPI             0x0010  /* This board has ephy roboswitch spi */
++#define       BFL_ENETROBO            0x0010  /* This board has robo switch or core */
 +#define       BFL_CCKHIPWR            0x0040  /* Can do high-power CCK transmission */
 +#define       BFL_ENETADM             0x0080  /* This board has ADMtek switch */
-+#define       BFL_ENETVLAN            0x0100  /* This board can do vlan */
++#define       BFL_ENETVLAN            0x0100  /* This board has vlan capability */
++#define       BFL_AFTERBURNER         0x0200  /* This board supports Afterburner mode */
++#define BFL_NOPCI             0x0400  /* This board leaves PCI floating */
++#define BFL_FEM                       0x0800  /* This board supports the Front End Module */
++#define BFL_EXTLNA            0x1000  /* This board has an external LNA */
++#define BFL_HGPA              0x2000  /* This board has a high gain PA */
++#define       BFL_BTCMOD              0x4000  /* This board' BTCOEXIST is in the alternate gpios */
++#define       BFL_ALTIQ               0x8000  /* Alternate I/Q settings */
 +
 +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
 +#define BOARD_GPIO_HWRAD_B    0x010   /* bit 4 is HWRAD input on 4301 */
++#define       BOARD_GPIO_BTCMOD_IN    0x010   /* bit 4 is the alternate BT Coexistance Input */
++#define       BOARD_GPIO_BTCMOD_OUT   0x020   /* bit 5 is the alternate BT Coexistance Out */
 +#define       BOARD_GPIO_BTC_IN       0x080   /* bit 7 is BT Coexistance Input */
 +#define       BOARD_GPIO_BTC_OUT      0x100   /* bit 8 is BT Coexistance Out */
 +#define       BOARD_GPIO_PACTRL       0x200   /* bit 9 controls the PA on new 4306 boards */
@@ -7170,6 +5994,20 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define       PCI_BUS                 1       /* PCI target */
 +#define       PCMCIA_BUS              2       /* PCMCIA target */
 +#define SDIO_BUS              3       /* SDIO target */
++#define JTAG_BUS              4       /* JTAG */
++
++/* Allows optimization for single-bus support */
++#ifdef BCMBUSTYPE
++#define BUSTYPE(bus) (BCMBUSTYPE)
++#else
++#define BUSTYPE(bus) (bus)
++#endif
++
++/* power control defines */
++#define PLL_DELAY             150             /* us pll on delay */
++#define FREF_DELAY            200             /* us fref change delay */
++#define MIN_SLOW_CLK          32              /* us Slow clock period */
++#define       XTAL_ON_DELAY           1000            /* us crystal power-on delay */
 +
 +/* Reference Board Types */
 +
@@ -7260,30 +6098,109 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmdevs.h linux-2.6.12.5-brc
 +#define BCM94317SDIO_BOARD    0x0443
 +
 +#define BU4712_BOARD          0x0444
++#define       BU4712SD_BOARD          0x045d
++#define       BU4712L_BOARD           0x045f
 +
 +/* BCM4712 boards */
-+#define BCM94712AGR_BOARD     0x0445
-+#define BCM94712AP_BOARD      0x0446
++#define BCM94712AP_BOARD      0x0445
++#define BCM94712P_BOARD               0x0446
++
++/* BCM4318 boards */
++#define BU4318_BOARD          0x0447
++#define CB4318_BOARD          0x0448
++#define MPG4318_BOARD         0x0449
++#define MP4318_BOARD          0x044a
++#define SD4318_BOARD          0x044b
++
++/* BCM63XX boards */
++#define BCM96338_BOARD                0x6338
++#define BCM96345_BOARD                0x6345
++#define BCM96348_BOARD                0x6348
++
++/* Another mp4306 with SiGe */
++#define       BCM94306P_BOARD         0x044c
++
++/* CF-like 4317 modules */
++#define       BCM94317CF_BOARD        0x044d
++
++/* mp4303 */
++#define       BCM94303MP_BOARD        0x044e
++
++/* mpsgh4306 */
++#define       BCM94306MPSGH_BOARD     0x044f
++
++/* BRCM 4306 w/ Front End Modules */
++#define BCM94306MPM           0x0450
++#define BCM94306MPL           0x0453
++
++/* 4712agr */
++#define       BCM94712AGR_BOARD       0x0451
++
++/* The real CF 4317 board */
++#define       CFI4317_BOARD           0x0452
++
++/* pcmcia 4303 */
++#define       PC4303_BOARD            0x0454
++
++/* 5350K */
++#define       BCM95350K_BOARD         0x0455
++
++/* 5350R */
++#define       BCM95350R_BOARD         0x0456
 +
-+/* BCM4702 boards */
-+#define CT4702AP_BOARD                0x0447
++/* 4306mplna */
++#define       BCM94306MPLNA_BOARD     0x0457
++
++/* 4320 boards */
++#define       BU4320_BOARD            0x0458
++#define       BU4320S_BOARD           0x0459
++#define       BCM94320PH_BOARD        0x045a
++
++/* 4306mph */
++#define       BCM94306MPH_BOARD       0x045b
++
++/* 4306pciv */
++#define       BCM94306PCIV_BOARD      0x045c
++
++#define       BU4712SD_BOARD          0x045d
++
++#define       BCM94320PFLSH_BOARD     0x045e
++
++#define       BU4712L_BOARD           0x045f
++#define       BCM94712LGR_BOARD       0x0460
++#define       BCM94320R_BOARD         0x0461
++
++#define       BU5352_BOARD            0x0462
++
++#define       BCM94318MPGH_BOARD      0x0463
++
++
++#define       BCM95352GR_BOARD        0x0467
++
++/* bcm95351agr */
++#define       BCM95351AGR_BOARD       0x0470
++
++/* # of GPIO pins */
++#define GPIO_NUMPINS          16
 +
 +#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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,125 @@
-+/*******************************************************************************
-+ * $Id$
-+ * Copyright 2001-2003, Broadcom Corporation   
+diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h
+--- linux.old/arch/mips/bcm947xx/include/bcmendian.h   1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h   2005-12-15 15:25:47.146730500 +0100
+@@ -0,0 +1,152 @@
++/*
++ * local version of endian.h - byte order defines
++ *
++ * 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.   
-+ * local version of endian.h - byte order defines
-+ ******************************************************************************/
++ *
++ *  $Id$
++*/
 +
 +#ifndef _BCMENDIAN_H_
 +#define _BCMENDIAN_H_
@@ -7303,6 +6220,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-b
 +              (((uint32)(val) & (uint32)0x0000ff00UL) <<  8) | \
 +              (((uint32)(val) & (uint32)0x00ff0000UL) >>  8) | \
 +              (((uint32)(val) & (uint32)0xff000000UL) >> 24) ))
++              
++/* 2 Byte swap a 32 bit value */
++#define BCMSWAP32BY16(val) \
++      ((uint32)( \
++              (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \
++              (((uint32)(val) & (uint32)0xffff0000UL) >> 16) ))
++              
 +
 +static INLINE uint16
 +bcmswap16(uint16 val)
@@ -7316,6 +6240,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-b
 +      return BCMSWAP32(val);
 +}
 +
++static INLINE uint32
++bcmswap32by16(uint32 val)
++{
++      return BCMSWAP32BY16(val);
++}
++
 +/* buf        - start of buffer of shorts to swap */
 +/* len  - byte length of buffer */
 +static INLINE void
@@ -7397,382 +6327,35 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmendian.h linux-2.6.12.5-b
 +      return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3];
 +}
 +
-+#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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,229 @@
-+/*
-+ * Hardware-specific definitions for
-+ * Broadcom BCM47XX 10/100 Mbps Ethernet cores.
-+ *
-+ * 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$
-+ */
-+
-+#ifndef       _bcmenet_47xx_h_
-+#define       _bcmenet_47xx_h_
-+
-+#include <bcmdevs.h>
-+#include <hnddma.h>
-+
-+#define       BCMENET_NFILTERS        64              /* # ethernet address filter entries */
-+#define       BCMENET_MCHASHBASE      0x200           /* multicast hash filter base address */
-+#define       BCMENET_MCHASHSIZE      256             /* multicast hash filter size in bytes */
-+#define       BCMENET_MAX_DMA         4096            /* chip has 12 bits of DMA addressing */
-+
-+/* power management event wakeup pattern constants */
-+#define       BCMENET_NPMP            4               /* chip supports 4 wakeup patterns */
-+#define       BCMENET_PMPBASE         0x400           /* wakeup pattern base address */
-+#define       BCMENET_PMPSIZE         0x80            /* 128bytes each pattern */
-+#define       BCMENET_PMMBASE         0x600           /* wakeup mask base address */
-+#define       BCMENET_PMMSIZE         0x10            /* 128bits each mask */
-+
-+/* cpp contortions to concatenate w/arg prescan */
-+#ifndef PAD
-+#define       _PADLINE(line)  pad ## line
-+#define       _XSTR(line)     _PADLINE(line)
-+#define       PAD             _XSTR(__LINE__)
-+#endif        /* PAD */
-+
-+/* sometimes you just need the enet mib definitions */
-+#include <bcmenetmib.h>
-+
-+/*
-+ * Host Interface Registers
-+ */
-+typedef volatile struct _bcmenettregs {
-+      /* Device and Power Control */
-+      uint32  devcontrol;
-+      uint32  PAD[2];
-+      uint32  biststatus;
-+      uint32  wakeuplength;
-+      uint32  PAD[3];
-+      
-+      /* Interrupt Control */
-+      uint32  intstatus;
-+      uint32  intmask;
-+      uint32  gptimer;
-+      uint32  PAD[23];
-+
-+      /* Ethernet MAC Address Filtering Control */
-+      uint32  PAD[2];
-+      uint32  enetftaddr;
-+      uint32  enetftdata;
-+      uint32  PAD[2];
-+
-+      /* Ethernet MAC Control */
-+      uint32  emactxmaxburstlen;
-+      uint32  emacrxmaxburstlen;
-+      uint32  emaccontrol;
-+      uint32  emacflowcontrol;
-+
-+      uint32  PAD[20];
-+
-+      /* DMA Lazy Interrupt Control */
-+      uint32  intrecvlazy;
-+      uint32  PAD[63];
-+
-+      /* DMA engine */
-+      dmaregs_t       dmaregs;
-+      dmafifo_t       dmafifo;
-+      uint32  PAD[116];
-+
-+      /* EMAC Registers */
-+      uint32 rxconfig;
-+      uint32 rxmaxlength;
-+      uint32 txmaxlength;
-+      uint32 PAD;
-+      uint32 mdiocontrol;
-+      uint32 mdiodata;
-+      uint32 emacintmask;
-+      uint32 emacintstatus;
-+      uint32 camdatalo;
-+      uint32 camdatahi;
-+      uint32 camcontrol;
-+      uint32 enetcontrol;
-+      uint32 txcontrol;
-+      uint32 txwatermark;
-+      uint32 mibcontrol;
-+      uint32 PAD[49];
-+
-+      /* EMAC MIB counters */
-+      bcmenetmib_t    mib;
-+
-+      uint32  PAD[585];
-+
-+      /* Sonics SiliconBackplane config registers */
-+      sbconfig_t      sbconfig;
-+} bcmenetregs_t;
-+
-+/* device control */
-+#define       DC_PM           ((uint32)1 << 7)        /* pattern filtering enable */
-+#define       DC_IP           ((uint32)1 << 10)       /* internal ephy present (rev >= 1) */
-+#define       DC_ER           ((uint32)1 << 15)       /* ephy reset */
-+#define       DC_MP           ((uint32)1 << 16)       /* mii phy mode enable */
-+#define       DC_CO           ((uint32)1 << 17)       /* mii phy mode: enable clocks */
-+#define       DC_PA_MASK      0x7c0000                /* mii phy mode: mdc/mdio phy address */
-+#define       DC_PA_SHIFT     18
-+
-+/* wakeup length */
-+#define       WL_P0_MASK      0x7f                    /* pattern 0 */
-+#define       WL_D0           ((uint32)1 << 7)
-+#define       WL_P1_MASK      0x7f00                  /* pattern 1 */
-+#define       WL_P1_SHIFT     8
-+#define       WL_D1           ((uint32)1 << 15)
-+#define       WL_P2_MASK      0x7f0000                /* pattern 2 */
-+#define       WL_P2_SHIFT     16
-+#define       WL_D2           ((uint32)1 << 23)
-+#define       WL_P3_MASK      0x7f000000              /* pattern 3 */
-+#define       WL_P3_SHIFT     24
-+#define       WL_D3           ((uint32)1 << 31)
-+
-+/* intstatus and intmask */
-+#define       I_PME           ((uint32)1 << 6)        /* power management event */
-+#define       I_TO            ((uint32)1 << 7)        /* general purpose timeout */
-+#define       I_PC            ((uint32)1 << 10)       /* descriptor error */
-+#define       I_PD            ((uint32)1 << 11)       /* data error */
-+#define       I_DE            ((uint32)1 << 12)       /* descriptor protocol error */
-+#define       I_RU            ((uint32)1 << 13)       /* receive descriptor underflow */
-+#define       I_RO            ((uint32)1 << 14)       /* receive fifo overflow */
-+#define       I_XU            ((uint32)1 << 15)       /* transmit fifo underflow */
-+#define       I_RI            ((uint32)1 << 16)       /* receive interrupt */
-+#define       I_XI            ((uint32)1 << 24)       /* transmit interrupt */
-+#define       I_EM            ((uint32)1 << 26)       /* emac interrupt */
-+#define       I_MW            ((uint32)1 << 27)       /* mii write */
-+#define       I_MR            ((uint32)1 << 28)       /* mii read */
-+
-+/* emaccontrol */
-+#define       EMC_CG          ((uint32)1 << 0)        /* crc32 generation enable */
-+#define       EMC_EP          ((uint32)1 << 2)        /* onchip ephy: powerdown (rev >= 1) */
-+#define       EMC_ED          ((uint32)1 << 3)        /* onchip ephy: energy detected (rev >= 1) */
-+#define       EMC_LC_MASK     0xe0                    /* onchip ephy: led control (rev >= 1) */
-+#define       EMC_LC_SHIFT    5
-+
-+/* emacflowcontrol */
-+#define       EMF_RFH_MASK    0xff                    /* rx fifo hi water mark */
-+#define       EMF_PG          ((uint32)1 << 15)       /* enable pause frame generation */
-+
-+/* interrupt receive lazy */
-+#define       IRL_TO_MASK     0x00ffffff              /* timeout */
-+#define       IRL_FC_MASK     0xff000000              /* frame count */
-+#define       IRL_FC_SHIFT    24                      /* frame count */
-+
-+/* emac receive config */
-+#define       ERC_DB          ((uint32)1 << 0)        /* disable broadcast */
-+#define       ERC_AM          ((uint32)1 << 1)        /* accept all multicast */
-+#define       ERC_RDT         ((uint32)1 << 2)        /* receive disable while transmitting */
-+#define       ERC_PE          ((uint32)1 << 3)        /* promiscuous enable */
-+#define       ERC_LE          ((uint32)1 << 4)        /* loopback enable */
-+#define       ERC_FE          ((uint32)1 << 5)        /* enable flow control */
-+#define       ERC_UF          ((uint32)1 << 6)        /* accept unicast flow control frame */
-+#define       ERC_RF          ((uint32)1 << 7)        /* reject filter */
-+
-+/* emac mdio control */
-+#define       MC_MF_MASK      0x7f                    /* mdc frequency */
-+#define       MC_PE           ((uint32)1 << 7)        /* mii preamble enable */
-+
-+/* emac mdio data */
-+#define       MD_DATA_MASK    0xffff                  /* r/w data */
-+#define       MD_TA_MASK      0x30000                 /* turnaround value */
-+#define       MD_TA_SHIFT     16
-+#define       MD_TA_VALID     (2 << MD_TA_SHIFT)      /* valid ta */
-+#define       MD_RA_MASK      0x7c0000                /* register address */
-+#define       MD_RA_SHIFT     18
-+#define       MD_PMD_MASK     0xf800000               /* physical media device */
-+#define       MD_PMD_SHIFT    23
-+#define       MD_OP_MASK      0x30000000              /* opcode */
-+#define       MD_OP_SHIFT     28
-+#define       MD_OP_WRITE     (1 << MD_OP_SHIFT)      /* write op */
-+#define       MD_OP_READ      (2 << MD_OP_SHIFT)      /* read op */
-+#define       MD_SB_MASK      0xc0000000              /* start bits */
-+#define       MD_SB_SHIFT     30
-+#define       MD_SB_START     (0x1 << MD_SB_SHIFT)    /* start of frame */
-+
-+/* emac intstatus and intmask */
-+#define       EI_MII          ((uint32)1 << 0)        /* mii mdio interrupt */
-+#define       EI_MIB          ((uint32)1 << 1)        /* mib interrupt */
-+#define       EI_FLOW         ((uint32)1 << 2)        /* flow control interrupt */
-+
-+/* emac cam data high */
-+#define       CD_V            ((uint32)1 << 16)       /* valid bit */
-+
-+/* emac cam control */
-+#define       CC_CE           ((uint32)1 << 0)        /* cam enable */
-+#define       CC_MS           ((uint32)1 << 1)        /* mask select */
-+#define       CC_RD           ((uint32)1 << 2)        /* read */
-+#define       CC_WR           ((uint32)1 << 3)        /* write */
-+#define       CC_INDEX_MASK   0x3f0000                /* index */
-+#define       CC_INDEX_SHIFT  16
-+#define       CC_CB           ((uint32)1 << 31)       /* cam busy */
-+
-+/* emac ethernet control */
-+#define       EC_EE           ((uint32)1 << 0)        /* emac enable */
-+#define       EC_ED           ((uint32)1 << 1)        /* emac disable */
-+#define       EC_ES           ((uint32)1 << 2)        /* emac soft reset */
-+#define       EC_EP           ((uint32)1 << 3)        /* external phy select */
-+
-+/* emac transmit control */
-+#define       EXC_FD          ((uint32)1 << 0)        /* full duplex */
-+#define       EXC_FM          ((uint32)1 << 1)        /* flowmode */
-+#define       EXC_SB          ((uint32)1 << 2)        /* single backoff enable */
-+#define       EXC_SS          ((uint32)1 << 3)        /* small slottime */
-+
-+/* emac mib control */
-+#define       EMC_RZ          ((uint32)1 << 0)        /* autoclear on read */
-+
-+/* sometimes you just need the enet rxheader definitions */
-+#include <bcmenetrxh.h>
-+
-+#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-11-07 01:12:51.823809750 +0100
-@@ -0,0 +1,81 @@
-+/*
-+ * Hardware-specific MIB definition for
-+ * Broadcom Home Networking Division
-+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores.
-+ * 
-+ * 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$
-+ */
-+
-+#ifndef _bcmenetmib_h_
-+#define _bcmenetmib_h_
-+
-+/* cpp contortions to concatenate w/arg prescan */
-+#ifndef PAD
-+#define       _PADLINE(line)  pad ## line
-+#define       _XSTR(line)     _PADLINE(line)
-+#define       PAD             _XSTR(__LINE__)
-+#endif        /* PAD */
-+
-+/*
-+ * EMAC MIB Registers
-+ */
-+typedef volatile struct {
-+      uint32 tx_good_octets;
-+      uint32 tx_good_pkts;
-+      uint32 tx_octets;
-+      uint32 tx_pkts;
-+      uint32 tx_broadcast_pkts;
-+      uint32 tx_multicast_pkts;
-+      uint32 tx_len_64;
-+      uint32 tx_len_65_to_127;
-+      uint32 tx_len_128_to_255;
-+      uint32 tx_len_256_to_511;
-+      uint32 tx_len_512_to_1023;
-+      uint32 tx_len_1024_to_max;
-+      uint32 tx_jabber_pkts;
-+      uint32 tx_oversize_pkts;
-+      uint32 tx_fragment_pkts;
-+      uint32 tx_underruns;
-+      uint32 tx_total_cols;
-+      uint32 tx_single_cols;
-+      uint32 tx_multiple_cols;
-+      uint32 tx_excessive_cols;
-+      uint32 tx_late_cols;
-+      uint32 tx_defered;
-+      uint32 tx_carrier_lost;
-+      uint32 tx_pause_pkts;
-+      uint32 PAD[8];
-+
-+      uint32 rx_good_octets;
-+      uint32 rx_good_pkts;
-+      uint32 rx_octets;
-+      uint32 rx_pkts;
-+      uint32 rx_broadcast_pkts;
-+      uint32 rx_multicast_pkts;
-+      uint32 rx_len_64;
-+      uint32 rx_len_65_to_127;
-+      uint32 rx_len_128_to_255;
-+      uint32 rx_len_256_to_511;
-+      uint32 rx_len_512_to_1023;
-+      uint32 rx_len_1024_to_max;
-+      uint32 rx_jabber_pkts;
-+      uint32 rx_oversize_pkts;
-+      uint32 rx_fragment_pkts;
-+      uint32 rx_missed_pkts;
-+      uint32 rx_crc_align_errs;
-+      uint32 rx_undersize;
-+      uint32 rx_crc_errs;
-+      uint32 rx_align_errs;
-+      uint32 rx_symbol_errs;
-+      uint32 rx_pause_pkts;
-+      uint32 rx_nonpause_pkts;
-+} bcmenetmib_t;
-+
-+#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,43 @@
-+/*
-+ * Hardware-specific Receive Data Header for the
-+ * Broadcom Home Networking Division
-+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores.
-+ *
-+ * 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$
-+ */
++#define ltoh_ua(ptr) ( \
++      sizeof(*(ptr)) == sizeof(uint8) ?  *(uint8 *)ptr : \
++      sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \
++      (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \
++)
 +
-+#ifndef _bcmenetrxh_h_
-+#define       _bcmenetrxh_h_
++#define ntoh_ua(ptr) ( \
++      sizeof(*(ptr)) == sizeof(uint8) ?  *(uint8 *)ptr : \
++      sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \
++      (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \
++)
 +
-+/*
-+ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header
-+ * with every frame consisting of
-+ * 16bits of frame length, followed by
-+ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined.
-+ */
-+typedef volatile struct {
-+      uint16  len;
-+      uint16  flags;
-+      uint16  pad[12];
-+} bcmenetrxh_t;
-+
-+#define       RXHDR_LEN       28
-+
-+#define       RXF_L           ((uint16)1 << 11)       /* last buffer in a frame */
-+#define       RXF_MISS        ((uint16)1 << 7)        /* received due to promisc mode */
-+#define       RXF_BRDCAST     ((uint16)1 << 6)        /* dest is broadcast address */
-+#define       RXF_MULT        ((uint16)1 << 5)        /* dest is multicast address */
-+#define       RXF_LG          ((uint16)1 << 4)        /* frame length > rxmaxlength */
-+#define       RXF_NO          ((uint16)1 << 3)        /* odd number of nibbles */
-+#define       RXF_RXER        ((uint16)1 << 2)        /* receive symbol error */
-+#define       RXF_CRC         ((uint16)1 << 1)        /* crc error */
-+#define       RXF_OV          ((uint16)1 << 0)        /* fifo overflow */
-+
-+#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,131 @@
++#endif /* _BCMENDIAN_H_ */
+diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h
+--- linux.old/arch/mips/bcm947xx/include/bcmnvram.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h    2005-12-15 16:04:35.850827500 +0100
+@@ -0,0 +1,87 @@
 +/*
 + * NVRAM variable manipulation
 + *
-+ * $Copyright Open Broadcom Corporation$
++ * 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: bcmnvram.h,v 1.1.1.1 2004/01/21 03:50:44 gigis Exp $
++ * $Id$
 + */
 +
 +#ifndef _bcmnvram_h_
@@ -7785,8 +6368,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 +struct nvram_header {
 +      uint32 magic;
 +      uint32 len;
-+      uint32 crc_ver_init;    /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */
-+      uint32 config_refresh;  /* 0:15 config, 16:31 refresh */
++      uint32 crc_ver_init;    /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
++      uint32 config_refresh;  /* 0:15 sdram_config, 16:31 sdram_refresh */
 +      uint32 config_ncdl;     /* ncdl values for memc */
 +};
 +
@@ -7797,31 +6380,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 +};
 +
 +/*
-+ * Initialize NVRAM access. May be unnecessary or undefined on certain
-+ * platforms.
-+ */
-+extern int nvram_init(void *sbh);
-+
-+/*
-+ * Disable NVRAM access. May be unnecessary or undefined on certain
-+ * platforms.
-+ */
-+extern void nvram_exit(void);
-+
-+/*
 + * Get the value of an NVRAM variable. The pointer returned may be
 + * invalid after a set.
 + * @param     name    name of variable to get
 + * @return    value of variable or NULL if undefined
 + */
-+extern char * nvram_get(const char *name);
++extern char * __init nvram_get(const char *name);
 +
 +/* 
 + * Get the value of an NVRAM variable.
 + * @param     name    name of variable to get
 + * @return    value of variable or NUL if undefined
 + */
-+#define nvram_safe_get(name) (nvram_get(name) ? : "")
++#define nvram_safe_get(name) (BCMINIT(nvram_get)(name) ? : "")
 +
 +/*
 + * Match an NVRAM variable.
@@ -7830,9 +6401,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 + * @return    TRUE if variable is defined and its value is string equal
 + *            to match or FALSE otherwise
 + */
-+static INLINE int
++static inline int
 +nvram_match(char *name, char *match) {
-+      const char *value = nvram_get(name);
++      const char *value = BCMINIT(nvram_get)(name);
 +      return (value && !strcmp(value, match));
 +}
 +
@@ -7843,69 +6414,31 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmnvram.h linux-2.6.12.5-br
 + * @return    TRUE if variable is defined and its value is not string
 + *            equal to invmatch or FALSE otherwise
 + */
-+static INLINE int
++static inline int
 +nvram_invmatch(char *name, char *invmatch) {
-+      const char *value = nvram_get(name);
++      const char *value = BCMINIT(nvram_get)(name);
 +      return (value && strcmp(value, invmatch));
 +}
 +
-+/*
-+ * Set the value of an NVRAM variable. The name and value strings are
-+ * copied into private storage. Pointers to previously set values
-+ * may become invalid. The new value may be immediately
-+ * retrieved but will not be permanently stored until a commit.
-+ * @param     name    name of variable to set
-+ * @param     value   value of variable
-+ * @return    0 on success and errno on failure
-+ */
-+extern int nvram_set(const char *name, const char *value);
-+
-+/*
-+ * Unset an NVRAM variable. Pointers to previously set values
-+ * remain valid until a set.
-+ * @param     name    name of variable to unset
-+ * @return    0 on success and errno on failure
-+ * NOTE: use nvram_commit to commit this change to flash.
-+ */
-+extern int nvram_unset(const char *name);
-+
-+/*
-+ * Commit NVRAM variables to permanent storage. All pointers to values
-+ * may be invalid after a commit.
-+ * NVRAM values are undefined after a commit.
-+ * @return    0 on success and errno on failure
-+ */
-+extern int nvram_commit(void);
-+
-+/*
-+ * Get all NVRAM variables (format name=value\0 ... \0\0).
-+ * @param     buf     buffer to store variables
-+ * @param     count   size of buffer in bytes
-+ * @return    0 on success and errno on failure
-+ */
-+extern int nvram_getall(char *buf, int count);
-+
-+extern int kernel_write(unsigned char *buffer, int offset, int length);
-+
 +#endif /* _LANGUAGE_ASSEMBLY */
 +
 +#define NVRAM_MAGIC           0x48534C46      /* 'FLSH' */
 +#define NVRAM_VERSION         1
 +#define NVRAM_HEADER_SIZE     20
-+#define NVRAM_LOC_GAP         0x100000
-+#define NVRAM_SPACE           0x2000
-+#define NVRAM_FIRST_LOC               (0xbfd00000 - NVRAM_SPACE)
-+#define NVRAM_LAST_LOC                (0xc0000000 - NVRAM_SPACE)
++#define NVRAM_SPACE           0x8000
++
++#define NVRAM_MAX_VALUE_LEN 255
++#define NVRAM_MAX_PARAM_LEN 64
 +
 +#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,24 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h
+--- linux.old/arch/mips/bcm947xx/include/bcmsrom.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h     2005-12-15 15:34:32.919589250 +0100
+@@ -0,0 +1,23 @@
 +/*
-+ * Misc useful routines to access NIC srom
++ * Misc useful routines to access NIC local SROM/OTP .
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -7919,58 +6452,34 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmsrom.h linux-2.6.12.5-brc
 +#ifndef       _bcmsrom_h_
 +#define       _bcmsrom_h_
 +
-+extern int srom_var_init(uint bus, void *curmap, void *osh, char **vars, int *count);
++extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count);
++
++extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
++extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf);
 +
-+extern int srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf);
-+extern int srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf);
-+extern int srom_parsecis(uint8 *cis, char **vars, int *count);
-+         
 +#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,136 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h
+--- linux.old/arch/mips/bcm947xx/include/bcmutils.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h    2005-12-15 16:44:25.619117750 +0100
+@@ -0,0 +1,308 @@
 +/*
 + * Misc useful os-independent macros and functions.
 + *
-+ * 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.   
++ * 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$
 + */
 +
 +#ifndef       _bcmutils_h_
 +#define       _bcmutils_h_
 +
-+#ifndef MIN
-+#define       MIN(a, b)               (((a)<(b))?(a):(b))
-+#endif
-+
-+#ifndef MAX
-+#define       MAX(a, b)               (((a)>(b))?(a):(b))
-+#endif
-+
-+#define CEIL(x, y)            (((x) + ((y)-1)) / (y))
-+#define       ROUNDUP(x, y)           ((((ulong)(x)+((y)-1))/(y))*(y))
-+#define       ISALIGNED(a, x)         (((uint)(a) & ((x)-1)) == 0)
-+#define       ISPOWEROF2(x)           ((((x)-1)&(x))==0)
-+#define       OFFSETOF(type, member)  ((uint) &((type *)0)->member)
-+#define ARRAYSIZE(a)          (sizeof(a)/sizeof(a[0]))
-+
-+/* bit map related macros */
-+#ifndef setbit
-+#define       NBBY    8       /* 8 bits per byte */
-+#define       setbit(a,i)     ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
-+#define       clrbit(a,i)     ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
-+#define       isset(a,i)      ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
-+#define       isclr(a,i)      (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
-+#endif
-+
-+#define       NBITS(type)     (sizeof (type) * 8)
++/*** driver-only section ***/
++#include <osl.h>
 +
 +#define _BCM_U        0x01    /* upper */
 +#define _BCM_L        0x02    /* lower */
@@ -7981,6 +6490,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-br
 +#define _BCM_X        0x40    /* hex digit */
 +#define _BCM_SP       0x80    /* hard space (0x20) */
 +
++#define GPIO_PIN_NOTDEFINED   0x20 
++
 +extern unsigned char bcm_ctype[];
 +#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)])
 +
@@ -7996,40 +6507,157 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-br
 +#define bcm_isupper(c)        ((bcm_ismask(c)&(_BCM_U)) != 0)
 +#define bcm_isxdigit(c)       ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0)
 +
-+/*
-+ * Spin at most 'us' microseconds while 'exp' is true.
-+ * Caller should explicitly test 'exp' when this completes
-+ * and take appropriate error action if 'exp' is still true.
-+ */
-+#define SPINWAIT(exp, us) { \
-+      uint countdown = (us) + 9; \
-+      while ((exp) && (countdown >= 10)) {\
-+              OSL_DELAY(10); \
-+              countdown -= 10; \
-+      } \
-+}
++/*
++ * Spin at most 'us' microseconds while 'exp' is true.
++ * Caller should explicitly test 'exp' when this completes
++ * and take appropriate error action if 'exp' is still true.
++ */
++#define SPINWAIT(exp, us) { \
++      uint countdown = (us) + 9; \
++      while ((exp) && (countdown >= 10)) {\
++              OSL_DELAY(10); \
++              countdown -= 10; \
++      } \
++}
++
++/* generic osl packet queue */
++struct pktq {
++      void *head;     /* first packet to dequeue */
++      void *tail;     /* last packet to dequeue */
++      uint len;       /* number of queued packets */
++      uint maxlen;    /* maximum number of queued packets */
++      bool priority;  /* enqueue by packet priority */
++      uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */
++};
++#define DEFAULT_QLEN  128
++
++#define       pktq_len(q)     ((q)->len)
++#define       pktq_avail(q)   ((q)->maxlen - (q)->len)
++#define       pktq_head(q)    ((q)->head)
++#define       pktq_full(q)    ((q)->len >= (q)->maxlen)
++#define       _pktq_pri(q, pri)       ((q)->prio_map[pri])
++#define       pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0))
++
++/* externs */
++/* packet */
++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf);
++extern uint pkttotlen(osl_t *osh, void *);
++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]);
++extern void pktenq(struct pktq *q, void *p, bool lifo);
++extern void *pktdeq(struct pktq *q);
++extern void *pktdeqtail(struct pktq *q);
++/* string */
++extern uint bcm_atoi(char *s);
++extern uchar bcm_toupper(uchar c);
++extern ulong bcm_strtoul(char *cp, char **endp, uint base);
++extern char *bcmstrstr(char *haystack, char *needle);
++extern char *bcmstrcat(char *dest, const char *src);
++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen);
++/* ethernet address */
++extern char *bcm_ether_ntoa(char *ea, char *buf);
++extern int bcm_ether_atoe(char *p, char *ea);
++/* delay */
++extern void bcm_mdelay(uint ms);
++/* variable access */
++extern char *getvar(char *vars, char *name);
++extern int getintvar(char *vars, char *name);
++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin);
++#define       bcmlog(fmt, a1, a2)
++#define       bcmdumplog(buf, size)   *buf = '\0'
++#define       bcmdumplogent(buf, idx) -1
++
++/*** driver/apps-shared section ***/
++
++#define BCME_STRLEN           64
++#define VALID_BCMERROR(e)  ((e <= 0) && (e >= BCME_LAST))
++
++
++/* 
++ * error codes could be added but the defined ones shouldn't be changed/deleted 
++ * these error codes are exposed to the user code 
++ * when ever a new error code is added to this list 
++ * please update errorstring table with the related error string and 
++ * update osl files with os specific errorcode map   
++*/
++
++#define BCME_ERROR                    -1      /* Error generic */
++#define BCME_BADARG                   -2      /* Bad Argument */
++#define BCME_BADOPTION                        -3      /* Bad option */
++#define BCME_NOTUP                    -4      /* Not up */
++#define BCME_NOTDOWN                  -5      /* Not down */
++#define BCME_NOTAP                    -6      /* Not AP */
++#define BCME_NOTSTA                   -7      /* Not STA  */
++#define BCME_BADKEYIDX                        -8      /* BAD Key Index */
++#define BCME_RADIOOFF                         -9      /* Radio Off */
++#define BCME_NOTBANDLOCKED            -10     /* Not  bandlocked */
++#define BCME_NOCLK                    -11     /* No Clock*/
++#define BCME_BADRATESET                       -12     /* BAD RateSet*/
++#define BCME_BADBAND                  -13     /* BAD Band */
++#define BCME_BUFTOOSHORT              -14     /* Buffer too short */  
++#define BCME_BUFTOOLONG                       -15     /* Buffer too Long */   
++#define BCME_BUSY                     -16     /* Busy*/       
++#define BCME_NOTASSOCIATED            -17     /* Not associated*/
++#define BCME_BADSSIDLEN                       -18     /* BAD SSID Len */
++#define BCME_OUTOFRANGECHAN           -19     /* Out of Range Channel*/
++#define BCME_BADCHAN                  -20     /* BAD Channel */
++#define BCME_BADADDR                  -21     /* BAD Address*/
++#define BCME_NORESOURCE                       -22     /* No resources*/
++#define BCME_UNSUPPORTED              -23     /* Unsupported*/
++#define BCME_BADLEN                   -24     /* Bad Length*/
++#define BCME_NOTREADY                 -25     /* Not ready Yet*/
++#define BCME_EPERM                    -26     /* Not Permitted */
++#define BCME_NOMEM                    -27     /* No Memory */
++#define BCME_ASSOCIATED                       -28     /* Associated */
++#define BCME_RANGE                    -29     /* Range Error*/
++#define BCME_NOTFOUND                 -30     /* Not found */
++#define BCME_LAST                     BCME_NOTFOUND   
++
++#ifndef ABS
++#define       ABS(a)                  (((a)<0)?-(a):(a))
++#endif
++
++#ifndef MIN
++#define       MIN(a, b)               (((a)<(b))?(a):(b))
++#endif
++
++#ifndef MAX
++#define       MAX(a, b)               (((a)>(b))?(a):(b))
++#endif
 +
-+/* generic osl packet queue */
-+struct pktq {
-+      void *head;
-+      void *tail;
-+      uint  len;
-+      uint  maxlen; 
-+};
-+#define DEFAULT_QLEN  128
++#define CEIL(x, y)            (((x) + ((y)-1)) / (y))
++#define       ROUNDUP(x, y)           ((((x)+((y)-1))/(y))*(y))
++#define       ISALIGNED(a, x)         (((a) & ((x)-1)) == 0)
++#define       ISPOWEROF2(x)           ((((x)-1)&(x))==0)
++#define VALID_MASK(mask)      !((mask) & ((mask) + 1))
++#define       OFFSETOF(type, member)  ((uint)(uintptr)&((type *)0)->member)
++#define ARRAYSIZE(a)          (sizeof(a)/sizeof(a[0]))
 +
-+#define       pktq_len(q)             ((q)->len)
-+#define       pktq_avail(q)   ((q)->maxlen - (q)->len)
-+#define       pktq_head(q)    ((q)->head)
-+#define       pktq_full(q)    ((q)->len >= (q)->maxlen)
++/* bit map related macros */
++#ifndef setbit
++#define       NBBY    8       /* 8 bits per byte */
++#define       setbit(a,i)     (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY))
++#define       clrbit(a,i)     (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
++#define       isset(a,i)      (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY)))
++#define       isclr(a,i)      ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
++#endif
++
++#define       NBITS(type)     (sizeof(type) * 8)
++#define NBITVAL(bits) (1 << (bits))
++#define MAXBITVAL(bits)       ((1 << (bits)) - 1)
 +
 +/* crc defines */
 +#define CRC8_INIT_VALUE  0xff         /* Initial CRC8 checksum value */
 +#define CRC8_GOOD_VALUE  0x9f         /* Good final CRC8 checksum value */
 +#define CRC16_INIT_VALUE 0xffff               /* Initial CRC16 checksum value */
 +#define CRC16_GOOD_VALUE 0xf0b8               /* Good final CRC16 checksum value */
-+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
-+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
++#define CRC32_INIT_VALUE 0xffffffff   /* Initial CRC32 checksum value */
++#define CRC32_GOOD_VALUE 0xdebb20e3   /* Good final CRC32 checksum value */
++
++/* bcm_format_flags() bit description structure */
++typedef struct bcm_bit_desc {
++      uint32  bit;
++      char*   name;
++} bcm_bit_desc_t;
 +
 +/* tag_ID/length/value_buffer tuple */
 +typedef struct bcm_tlv {
@@ -8038,48 +6666,124 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bcmutils.h linux-2.6.12.5-br
 +      uint8   data[1];
 +} bcm_tlv_t;
 +
-+/* externs */
-+extern uint bcm_atoi(char *s);
-+extern uchar bcm_toupper(uchar c);
-+extern ulong bcm_strtoul(char *cp, char **endp, uint base);
-+extern void deadbeef(char *p, uint len);
-+extern void prhex(char *msg, uchar *buf, uint len);
-+extern void prpkt(char *msg, void *drv, void *p0);
-+extern uint pktcopy(void *drv, void *p, uint offset, int len, uchar *buf);
-+extern uint pkttotlen(void *drv, void *);
-+extern uchar *bcm_ether_ntoa(char *ea, char *buf);
-+extern int bcm_ether_atoe(char *p, char *ea);
-+extern void bcm_mdelay(uint ms);
-+extern char *getvar(char *vars, char *name);
-+extern int getintvar(char *vars, char *name);
++/* Check that bcm_tlv_t fits into the given buflen */
++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len))
++
++/* buffer length for ethernet address from bcm_ether_ntoa() */
++#define ETHER_ADDR_STR_LEN    18
++
++/* unaligned load and store macros */
++#ifdef IL_BIGENDIAN
++static INLINE uint32
++load32_ua(uint8 *a)
++{
++      return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]);
++}
++
++static INLINE void
++store32_ua(uint8 *a, uint32 v)
++{
++      a[0] = (v >> 24) & 0xff;
++      a[1] = (v >> 16) & 0xff;
++      a[2] = (v >> 8) & 0xff;
++      a[3] = v & 0xff;
++}
++
++static INLINE uint16
++load16_ua(uint8 *a)
++{
++      return ((a[0] << 8) | a[1]);
++}
++
++static INLINE void
++store16_ua(uint8 *a, uint16 v)
++{
++      a[0] = (v >> 8) & 0xff;
++      a[1] = v & 0xff;
++}
++
++#else
++
++static INLINE uint32
++load32_ua(uint8 *a)
++{
++      return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]);
++}
++
++static INLINE void
++store32_ua(uint8 *a, uint32 v)
++{
++      a[3] = (v >> 24) & 0xff;
++      a[2] = (v >> 16) & 0xff;
++      a[1] = (v >> 8) & 0xff;
++      a[0] = v & 0xff;
++}
++
++static INLINE uint16
++load16_ua(uint8 *a)
++{
++      return ((a[1] << 8) | a[0]);
++}
++
++static INLINE void
++store16_ua(uint8 *a, uint16 v)
++{
++      a[1] = (v >> 8) & 0xff;
++      a[0] = v & 0xff;
++}
++
++#endif
 +
-+extern uint8 crc8(uint8 *p, uint nbytes, uint8 crc);
-+extern uint16 crc16(uint8 *p, uint nbytes, uint16 crc);
-+extern uint32 crc32(uint8 *p, uint nbytes, uint32 crc);
++/* externs */
++/* crc */
++extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc);
++/* format/print */
++/* IE parsing */
++extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen);
 +extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key);
 +extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key);
-+extern void pktqinit(struct pktq *q, int maxlen);
-+extern void pktenq(struct pktq *q, void *p, bool lifo);
-+extern void *pktdeq(struct pktq *q);
 +
-+#define       bcmlog(fmt, a1, a2)
-+#define       bcmdumplog(buf, size)   *buf = '\0'
++/* bcmerror*/
++extern const char *bcmerrorstr(int bcmerror);
++
++/* multi-bool data type: set of bools, mbool is true if any is set */
++typedef uint32 mbool;
++#define mboolset(mb, bit)             (mb |= bit)             /* set one bool */
++#define mboolclr(mb, bit)             (mb &= ~bit)            /* clear one bool */
++#define mboolisset(mb, bit)           ((mb & bit) != 0)       /* TRUE if one bool is set */
++#define       mboolmaskset(mb, mask, val)     ((mb) = (((mb) & ~(mask)) | (val)))
++
++/* power conversion */
++extern uint16 bcm_qdbm_to_mw(uint8 qdbm);
++extern uint8 bcm_mw_to_qdbm(uint16 mw);
++
++/* generic datastruct to help dump routines */
++struct fielddesc {
++      char    *nameandfmt;
++      uint32  offset;
++      uint32  len;
++};
++
++typedef  uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset);
++extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize);
++
++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len);
 +
 +#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-11-07 01:12:51.827810000 +0100
+diff -urN linux.old/arch/mips/bcm947xx/include/bitfuncs.h linux.dev/arch/mips/bcm947xx/include/bitfuncs.h
+--- linux.old/arch/mips/bcm947xx/include/bitfuncs.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/bitfuncs.h    2005-12-15 15:34:40.268048500 +0100
 @@ -0,0 +1,85 @@
 +/*
 + * bit manipulation utility functions
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -8155,85 +6859,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/bitfuncs.h linux-2.6.12.5-br
 +#endif
 +
 +#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,69 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/flash.h linux.dev/arch/mips/bcm947xx/include/flash.h
+--- linux.old/arch/mips/bcm947xx/include/flash.h       1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/flash.h       2005-12-15 15:34:44.280299250 +0100
+@@ -0,0 +1,188 @@
 +/*
-+ * 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.h: Common definitions for flash access.
 + *
-+*/
-+
-+#ifndef _epivers_h_
-+#define _epivers_h_
-+
-+#ifdef        linux
-+#include <linux/config.h>
-+#endif
-+
-+/* Vendor Name, ASCII, 32 chars max */
-+#ifdef COMPANYNAME
-+#define       HPNA_VENDOR             COMPANYNAME
-+#else
-+#define       HPNA_VENDOR             "Broadcom Corporation"
-+#endif
-+
-+/* Driver Date, ASCII, 32 chars max */
-+#define HPNA_DRV_BUILD_DATE   __DATE__
-+
-+/* Hardware Manufacture Date, ASCII, 32 chars max */
-+#define HPNA_HW_MFG_DATE      "Not Specified"
-+
-+/* See documentation for Device Type values, 32 values max */
-+#ifndef       HPNA_DEV_TYPE
-+
-+#if   defined(CONFIG_BRCM_VJ)
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_DISPLAY }
-+
-+#elif defined(CONFIG_BCRM_93725)
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY }
-+
-+#else
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_PCINIC }
-+
-+#endif
-+
-+#endif        /* !HPNA_DEV_TYPE */
-+
-+
-+#define       EPI_MAJOR_VERSION       1
-+
-+#define       EPI_MINOR_VERSION       1
-+
-+#define       EPI_RC_NUMBER           2
-+
-+#define       EPI_INCREMENTAL_NUMBER  0
-+
-+#define       EPI_BUILD_NUMBER        0
-+
-+#define       EPI_VERSION             1,1,2,0
-+
-+#define       EPI_VERSION_NUM         0x01010200
-+
-+/* Driver Version String, ASCII, 32 chars max */
-+#define       EPI_VERSION_STR         "1.1.2.0"
-+#define       EPI_ROUTER_VERSION_STR  "1.1.2.0"
-+
-+#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,69 @@
-+/*
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -8242,149 +6875,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/epivers.h.in linux-2.6.12.5-
 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 + *
 + * $Id$
-+ *
-+*/
-+
-+#ifndef _epivers_h_
-+#define _epivers_h_
-+
-+#ifdef        linux
-+#include <linux/config.h>
-+#endif
-+
-+/* Vendor Name, ASCII, 32 chars max */
-+#ifdef COMPANYNAME
-+#define       HPNA_VENDOR             COMPANYNAME
-+#else
-+#define       HPNA_VENDOR             "Broadcom Corporation"
-+#endif
-+
-+/* Driver Date, ASCII, 32 chars max */
-+#define HPNA_DRV_BUILD_DATE   __DATE__
-+
-+/* Hardware Manufacture Date, ASCII, 32 chars max */
-+#define HPNA_HW_MFG_DATE      "Not Specified"
-+
-+/* See documentation for Device Type values, 32 values max */
-+#ifndef       HPNA_DEV_TYPE
-+
-+#if   defined(CONFIG_BRCM_VJ)
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_DISPLAY }
-+
-+#elif defined(CONFIG_BCRM_93725)
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY }
-+
-+#else
-+#define HPNA_DEV_TYPE         { CDCF_V0_DEVICE_PCINIC }
-+
-+#endif
-+
-+#endif        /* !HPNA_DEV_TYPE */
-+
-+
-+#define       EPI_MAJOR_VERSION       @EPI_MAJOR_VERSION@
-+
-+#define       EPI_MINOR_VERSION       @EPI_MINOR_VERSION@
-+
-+#define       EPI_RC_NUMBER           @EPI_RC_NUMBER@
-+
-+#define       EPI_INCREMENTAL_NUMBER  @EPI_INCREMENTAL_NUMBER@
-+
-+#define       EPI_BUILD_NUMBER        @EPI_BUILD_NUMBER@
-+
-+#define       EPI_VERSION             @EPI_VERSION@
-+
-+#define       EPI_VERSION_NUM         @EPI_VERSION_NUM@
-+
-+/* Driver Version String, ASCII, 32 chars max */
-+#define       EPI_VERSION_STR         "@EPI_VERSION_STR@"
-+#define       EPI_ROUTER_VERSION_STR  "@EPI_ROUTER_VERSION_STR@"
-+
-+#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,60 @@
-+/*
-+ * Driver-specific socket ioctls
-+ * used by BSD, Linux, and PSOS
-+ * Broadcom BCM44XX 10/100Mbps Ethernet Device Driver
-+ *
-+ * 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$
-+ */
-+
-+#ifndef _etsockio_h_
-+#define _etsockio_h_
-+
-+/* THESE MUST BE CONTIGUOUS AND CONSISTENT WITH VALUES IN ETC.H */
-+
-+
-+#if defined(linux)
-+#define SIOCSETCUP            (SIOCDEVPRIVATE + 0)
-+#define SIOCSETCDOWN          (SIOCDEVPRIVATE + 1)
-+#define SIOCSETCLOOP          (SIOCDEVPRIVATE + 2)
-+#define SIOCGETCDUMP          (SIOCDEVPRIVATE + 3)
-+#define SIOCSETCSETMSGLEVEL   (SIOCDEVPRIVATE + 4)
-+#define SIOCSETCPROMISC               (SIOCDEVPRIVATE + 5)
-+#define SIOCSETCTXDOWN                (SIOCDEVPRIVATE + 6)    /* obsolete */
-+#define SIOCSETCSPEED         (SIOCDEVPRIVATE + 7)
-+#define SIOCTXGEN             (SIOCDEVPRIVATE + 8)
-+#define SIOCGETCPHYRD         (SIOCDEVPRIVATE + 9)
-+#define SIOCSETCPHYWR         (SIOCDEVPRIVATE + 10)
-+#define SIOCPERF                  (SIOCDEVPRIVATE + 11)
-+#define SIOCPERFDMA               (SIOCDEVPRIVATE + 12)
-+
-+#else /* !linux */
-+
-+#define SIOCSETCUP            _IOWR('e', 130 + 0, struct ifreq)
-+#define SIOCSETCDOWN          _IOWR('e', 130 + 1, struct ifreq)
-+#define SIOCSETCLOOP          _IOWR('e', 130 + 2, struct ifreq)
-+#define SIOCGETCDUMP          _IOWR('e', 130 + 3, struct ifreq)
-+#define SIOCSETCSETMSGLEVEL   _IOWR('e', 130 + 4, struct ifreq)
-+#define SIOCSETCPROMISC               _IOWR('e', 130 + 5, struct ifreq)
-+#define SIOCSETCTXDOWN                _IOWR('e', 130 + 6, struct ifreq)       /* obsolete */
-+#define SIOCSETCSPEED         _IOWR('e', 130 + 7, struct ifreq)
-+#define SIOCTXGEN             _IOWR('e', 130 + 8, struct ifreq)
-+
-+#endif
-+
-+/* arg to SIOCTXGEN */
-+struct txg {
-+      uint32 num;             /* number of frames to send */
-+      uint32 delay;           /* delay in microseconds between sending each */
-+      uint32 size;            /* size of ether frame to send */
-+      uchar buf[1514];        /* starting ether frame data */
-+};
-+
-+#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-11-07 01:12:51.827810000 +0100
-@@ -0,0 +1,184 @@
-+/*
-+ * flash.h: Common definitions for flash access.
-+ *
-+ * 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$
 + */
 +
 +/* Types of flashes we know about */
-+typedef enum _flash_type {OLD, BSC, SCS, AMD, SST} flash_type_t;
++typedef enum _flash_type {OLD, BSC, SCS, AMD, SST, SFLASH} flash_type_t;
 +
 +/* Commands to write/erase the flases */
 +typedef struct _flash_cmds{
@@ -8427,13 +6921,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +
 +
 +#ifdef        DECLARE_FLASHES
++flash_cmds_t sflash_cmd_t = 
++      { SFLASH,       0,      0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00,   0x00 };
 +
 +flash_cmds_t flash_cmds[] = {
-+/*      type  needu   preera  eraseb  erasech write   wbuf    clcsr   rdcsr   rdid    confrm  read */
-+      { BSC,  0,      0x00,   0x20,   0x00,   0x40,   0x00,   0x50,   0x70,   0x90,   0xd0,   0xff },
-+      { SCS,  0,      0x00,   0x20,   0x00,   0x40,   0xe8,   0x50,   0x70,   0x90,   0xd0,   0xff },
-+      { AMD,  1,      0x80,   0x30,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
-+      { SST,  1,      0x80,   0x50,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
++/*      type          needu   preera  eraseb  erasech write   wbuf    clcsr   rdcsr   rdid    confrm  read */
++      { BSC,          0,      0x00,   0x20,   0x00,   0x40,   0x00,   0x50,   0x70,   0x90,   0xd0,   0xff },
++      { SCS,          0,      0x00,   0x20,   0x00,   0x40,   0xe8,   0x50,   0x70,   0x90,   0xd0,   0xff },
++      { AMD,          1,      0x80,   0x30,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
++      { SST,          1,      0x80,   0x50,   0x10,   0xa0,   0x00,   0x00,   0x00,   0x90,   0x00,   0xf0 },
 +      { 0 }
 +};
 +
@@ -8502,6 +6998,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +};
 +
 +
++flash_desc_t sflash_desc =  
++      { 0, 0, 0, 0,   SFLASH, 0, 0,  0, 0,  0, NULL,    "SFLASH" };
 +
 +flash_desc_t flashes[] = {
 +      { 0x00b0, 0x00d0, 0x0200000, 2, SCS, 0x10000, 32,  0, 31,  0, NULL,    "Intel 28F160S3/5 1Mx16" },
@@ -8530,7 +7028,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +      { 0x0001, 0x2249, 0x0200000, 2, AMD, 0x10000, 32,  1, 31,  4, amd4112, "AMD 29lv160DB 1Mx16 BotB" },
 +      { 0x0001, 0x22f6, 0x0400000, 2, AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" },
 +      { 0x0001, 0x22f9, 0x0400000, 2, AMD, 0x10000, 64,  1, 63,  8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" },
-+      { 0x0001, 0x2201, 0x0400000, 2, AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" },
++      { 0x0001, 0x227e, 0x0400000, 2, AMD, 0x10000, 64,  0, 62,  8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" },
 +      { 0x0001, 0x2200, 0x0400000, 2, AMD, 0x10000, 64,  1, 63,  8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" },
 +      { 0x0020, 0x22CA, 0x0400000, 2, AMD, 0x10000, 64,  0, 62,  4, amd4112, "ST 29w320DT 2Mx16 TopB" },
 +      { 0x0020, 0x22CB, 0x0400000, 2, AMD, 0x10000, 64,  1, 63,  4, amd2114, "ST 29w320DB 2Mx16 BotB" },
@@ -8553,238 +7051,46 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/flash.h linux-2.6.12.5-brcm/
 +extern flash_desc_t flashes[];
 +
 +#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-11-07 01:12:51.831810250 +0100
-@@ -0,0 +1,34 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/flashutl.h linux.dev/arch/mips/bcm947xx/include/flashutl.h
+--- linux.old/arch/mips/bcm947xx/include/flashutl.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/flashutl.h    2005-12-15 15:34:48.160541750 +0100
+@@ -0,0 +1,27 @@
 +/*
 + * BCM47XX FLASH driver interface
 + *
-+ * 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.   
++ * 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$
 + */
 +
 +#ifndef _flashutl_h_
 +#define _flashutl_h_
 +
-+#define FLASH_BASE      0xbfc00000            /* BCM4710 */
 +
-+int   flash_init(void* base_addr, char *flash_str);
-+int   flash_erase(void);
-+int   flash_eraseblk(unsigned long off);
-+int   flash_write(unsigned long off, uint16 *src, uint nbytes);
-+unsigned long flash_block_base(unsigned long off);
-+unsigned long flash_block_lim(unsigned long off);
-+int FlashWriteRange(unsigned short* dst, unsigned short* src, unsigned int numbytes);
++#ifndef _LANGUAGE_ASSEMBLY
 +
++int   sysFlashInit(char *flash_str);
++int sysFlashRead(uint off, uchar *dst, uint bytes);
++int sysFlashWrite(uint off, uchar *src, uint bytes);
 +void nvWrite(unsigned short *data, unsigned int len);
 +
-+/* Global vars */
-+extern char*          flashutl_base;
-+extern flash_desc_t*  flashutl_desc;
-+extern flash_cmds_t*  flashutl_cmd;
++#endif        /* _LANGUAGE_ASSEMBLY */
 +
 +#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-11-07 01:12:51.831810250 +0100
-@@ -0,0 +1,181 @@
-+/*
-+ * Generic Broadcom Home Networking Division (HND) DMA engine definitions.
-+ * This supports the following chips: BCM42xx, 44xx, 47xx .
-+ *
-+ * $Id$
-+ * 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.   
-+ */
-+
-+#ifndef       _hnddma_h_
-+#define       _hnddma_h_
-+
-+/*
-+ * Each DMA processor consists of a transmit channel and a receive channel.
-+ */
-+typedef volatile struct {
-+      /* transmit channel */
-+      uint32  xmtcontrol;                     /* enable, et al */
-+      uint32  xmtaddr;                        /* descriptor ring base address (4K aligned) */
-+      uint32  xmtptr;                         /* last descriptor posted to chip */
-+      uint32  xmtstatus;                      /* current active descriptor, et al */
-+
-+      /* receive channel */
-+      uint32  rcvcontrol;                     /* enable, et al */
-+      uint32  rcvaddr;                        /* descriptor ring base address (4K aligned) */
-+      uint32  rcvptr;                         /* last descriptor posted to chip */
-+      uint32  rcvstatus;                      /* current active descriptor, et al */
-+} dmaregs_t;
-+
-+typedef volatile struct {
-+      /* diag access */
-+      uint32  fifoaddr;                       /* diag address */
-+      uint32  fifodatalow;                    /* low 32bits of data */
-+      uint32  fifodatahigh;                   /* high 32bits of data */
-+      uint32  pad;                            /* reserved */
-+} dmafifo_t;
-+
-+/* transmit channel control */
-+#define       XC_XE           ((uint32)1 << 0)        /* transmit enable */
-+#define       XC_SE           ((uint32)1 << 1)        /* transmit suspend request */
-+#define       XC_LE           ((uint32)1 << 2)        /* loopback enable */
-+#define       XC_FL           ((uint32)1 << 4)        /* flush request */
-+
-+/* transmit descriptor table pointer */
-+#define       XP_LD_MASK      0xfff                   /* last valid descriptor */
-+
-+/* transmit channel status */
-+#define       XS_CD_MASK      0x0fff                  /* current descriptor pointer */
-+#define       XS_XS_MASK      0xf000                  /* transmit state */
-+#define       XS_XS_SHIFT     12
-+#define       XS_XS_DISABLED  0x0000                  /* disabled */
-+#define       XS_XS_ACTIVE    0x1000                  /* active */
-+#define       XS_XS_IDLE      0x2000                  /* idle wait */
-+#define       XS_XS_STOPPED   0x3000                  /* stopped */
-+#define       XS_XS_SUSP      0x4000                  /* suspend pending */
-+#define       XS_XE_MASK      0xf0000                 /* transmit errors */
-+#define       XS_XE_SHIFT     16
-+#define       XS_XE_NOERR     0x00000                 /* no error */
-+#define       XS_XE_DPE       0x10000                 /* descriptor protocol error */
-+#define       XS_XE_DFU       0x20000                 /* data fifo underrun */
-+#define       XS_XE_BEBR      0x30000                 /* bus error on buffer read */
-+#define       XS_XE_BEDA      0x40000                 /* bus error on descriptor access */
-+#define       XS_FL           ((uint32)1 << 20)       /* flushed */
-+
-+/* receive channel control */
-+#define       RC_RE           ((uint32)1 << 0)        /* receive enable */
-+#define       RC_RO_MASK      0xfe                    /* receive frame offset */
-+#define       RC_RO_SHIFT     1
-+#define       RC_FM           ((uint32)1 << 8)        /* direct fifo receive (pio) mode */
-+
-+/* receive descriptor table pointer */
-+#define       RP_LD_MASK      0xfff                   /* last valid descriptor */
-+
-+/* receive channel status */
-+#define       RS_CD_MASK      0x0fff                  /* current descriptor pointer */
-+#define       RS_RS_MASK      0xf000                  /* receive state */
-+#define       RS_RS_SHIFT     12
-+#define       RS_RS_DISABLED  0x0000                  /* disabled */
-+#define       RS_RS_ACTIVE    0x1000                  /* active */
-+#define       RS_RS_IDLE      0x2000                  /* idle wait */
-+#define       RS_RS_STOPPED   0x3000                  /* reserved */
-+#define       RS_RE_MASK      0xf0000                 /* receive errors */
-+#define       RS_RE_SHIFT     16
-+#define       RS_RE_NOERR     0x00000                 /* no error */
-+#define       RS_RE_DPE       0x10000                 /* descriptor protocol error */
-+#define       RS_RE_DFO       0x20000                 /* data fifo overflow */
-+#define       RS_RE_BEBW      0x30000                 /* bus error on buffer write */
-+#define       RS_RE_BEDA      0x40000                 /* bus error on descriptor access */
-+
-+/* fifoaddr */
-+#define       FA_OFF_MASK     0xffff                  /* offset */
-+#define       FA_SEL_MASK     0xf0000                 /* select */
-+#define       FA_SEL_SHIFT    16
-+#define       FA_SEL_XDD      0x00000                 /* transmit dma data */
-+#define       FA_SEL_XDP      0x10000                 /* transmit dma pointers */
-+#define       FA_SEL_RDD      0x40000                 /* receive dma data */
-+#define       FA_SEL_RDP      0x50000                 /* receive dma pointers */
-+#define       FA_SEL_XFD      0x80000                 /* transmit fifo data */
-+#define       FA_SEL_XFP      0x90000                 /* transmit fifo pointers */
-+#define       FA_SEL_RFD      0xc0000                 /* receive fifo data */
-+#define       FA_SEL_RFP      0xd0000                 /* receive fifo pointers */
-+
-+/*
-+ * DMA Descriptor
-+ * Descriptors are only read by the hardware, never written back.
-+ */
-+typedef volatile struct {
-+      uint32  ctrl;           /* misc control bits & bufcount */
-+      uint32  addr;           /* data buffer address */
-+} dmadd_t;
-+
-+/*
-+ * Each descriptor ring must be 4096byte aligned
-+ * and fit within a single 4096byte page.
-+ */
-+#define       DMAMAXRINGSZ    4096
-+#define       DMARINGALIGN    4096
-+
-+/* control flags */
-+#define       CTRL_BC_MASK    0x1fff                  /* buffer byte count */
-+#define       CTRL_EOT        ((uint32)1 << 28)       /* end of descriptor table */
-+#define       CTRL_IOC        ((uint32)1 << 29)       /* interrupt on completion */
-+#define       CTRL_EOF        ((uint32)1 << 30)       /* end of frame */
-+#define       CTRL_SOF        ((uint32)1 << 31)       /* start of frame */
-+
-+/* control flags in the range [27:20] are core-specific and not defined here */
-+#define       CTRL_CORE_MASK  0x0ff00000
-+
-+/* export structure */
-+typedef volatile struct {
-+      /* rx error counters */
-+      uint            rxgiants;       /* rx giant frames */
-+      uint            rxnobuf;        /* rx out of dma descriptors */
-+      /* tx error counters */
-+      uint            txnobuf;        /* tx out of dma descriptors */
-+} hnddma_t;
-+
-+#ifndef di_t
-+#define       di_t    void
-+#endif
-+
-+/* externs */
-+extern void *dma_attach(void *drv, void *dev, char *name, dmaregs_t *dmaregs,
-+      uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset,
-+      uint ddoffset, uint dataoffset, uint *msg_level);
-+extern void dma_detach(di_t *di);
-+extern void dma_txreset(di_t *di);
-+extern void dma_rxreset(di_t *di);
-+extern void dma_txinit(di_t *di);
-+extern bool dma_txenabled(di_t *di);
-+extern void dma_rxinit(di_t *di);
-+extern void dma_rxenable(di_t *di);
-+extern bool dma_rxenabled(di_t *di);
-+extern void dma_txsuspend(di_t *di);
-+extern void dma_txresume(di_t *di);
-+extern bool dma_txsuspended(di_t *di);
-+extern bool dma_txstopped(di_t *di);
-+extern bool dma_rxstopped(di_t *di);
-+extern int dma_txfast(di_t *di, void *p, uint32 coreflags);
-+extern int dma_tx(di_t *di, void *p, uint32 coreflags);
-+extern void dma_fifoloopbackenable(di_t *di);
-+extern void *dma_rx(di_t *di);
-+extern void dma_rxfill(di_t *di);
-+extern void dma_txreclaim(di_t *di, bool forceall);
-+extern void dma_rxreclaim(di_t *di);
-+extern char *dma_dump(di_t *di, char *buf);
-+extern char *dma_dumptx(di_t *di, char *buf);
-+extern char *dma_dumprx(di_t *di, char *buf);
-+extern uint dma_getvar(di_t *di, char *name);
-+extern void *dma_getnexttxp(di_t *di, bool forceall);
-+extern void *dma_getnextrxp(di_t *di, bool forceall);
-+extern void dma_txblock(di_t *di);
-+extern void dma_txunblock(di_t *di);
-+extern uint dma_txactive(di_t *di);
-+
-+#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-11-07 01:12:51.831810250 +0100
+diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h
+--- linux.old/arch/mips/bcm947xx/include/hndmips.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h     2005-12-15 15:34:53.396869000 +0100
 @@ -0,0 +1,16 @@
 +/*
 + * Alternate include file for HND sbmips.h since CFE also ships with
 + * a sbmips.h.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -8796,14 +7102,14 @@ 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-11-07 01:12:51.831810250 +0100
-@@ -0,0 +1,313 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/bcm947xx/include/linux_osl.h
+--- linux.old/arch/mips/bcm947xx/include/linux_osl.h   1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h   2005-12-15 17:23:39.225126750 +0100
+@@ -0,0 +1,331 @@
 +/*
 + * Linux OS Independent Layer
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -8823,30 +7129,73 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#include <linuxver.h>
 +
 +/* assert and panic */
++#ifdef __GNUC__
++#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
++#if GCC_VERSION > 30100
 +#define       ASSERT(exp)             do {} while (0)
++#else
++/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/
++#define       ASSERT(exp)             
++#endif
++#endif
 +
-+/* PCMCIA attribute space access macros */
-+#define       OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \
-+      osl_pcmcia_read_attr((osh), (offset), (buf), (size))
-+#define       OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \
-+      osl_pcmcia_write_attr((osh), (offset), (buf), (size))
-+extern void osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size);
-+extern void osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int size);
++/* microsecond delay */
++#define       OSL_DELAY(usec)         osl_delay(usec)
++extern void osl_delay(uint usec);
 +
 +/* PCI configuration space access macros */
-+#define       OSL_PCI_READ_CONFIG(loc, offset, size) \
-+      osl_pci_read_config((loc), (offset), (size))
-+#define       OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \
-+      osl_pci_write_config((loc), (offset), (size), (val))
-+extern uint32 osl_pci_read_config(void *loc, uint size, uint offset);
-+extern void osl_pci_write_config(void *loc, uint offset, uint size, uint val);
++#define       OSL_PCI_READ_CONFIG(osh, offset, size) \
++      osl_pci_read_config((osh), (offset), (size))
++#define       OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \
++      osl_pci_write_config((osh), (offset), (size), (val))
++extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset);
++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val);
++
++/* PCI device bus # and slot # */
++#define OSL_PCI_BUS(osh)      osl_pci_bus(osh)
++#define OSL_PCI_SLOT(osh)     osl_pci_slot(osh)
++extern uint osl_pci_bus(osl_t *osh);
++extern uint osl_pci_slot(osl_t *osh);
 +
 +/* OSL initialization */
-+#define osl_init()            do {} while (0)
++extern osl_t *osl_attach(void *pdev);
++extern void osl_detach(osl_t *osh);
 +
 +/* host/bus architecture-specific byte swap */
 +#define BUS_SWAP32(v)         (v)
 +
++/* general purpose memory allocation */
++
++#define       MALLOC(osh, size)       kmalloc(size, GFP_ATOMIC)
++#define       MFREE(osh, addr, size)  kfree(addr);
++
++#define       MALLOC_FAILED(osh)      osl_malloc_failed((osh))
++
++extern void *osl_malloc(osl_t *osh, uint size);
++extern void osl_mfree(osl_t *osh, void *addr, uint size);
++extern uint osl_malloced(osl_t *osh);
++extern uint osl_malloc_failed(osl_t *osh);
++
++/* allocate/free shared (dma-able) consistent memory */
++#define       DMA_CONSISTENT_ALIGN    PAGE_SIZE
++#define       DMA_ALLOC_CONSISTENT(osh, size, pap) \
++      osl_dma_alloc_consistent((osh), (size), (pap))
++#define       DMA_FREE_CONSISTENT(osh, va, size, pa) \
++      osl_dma_free_consistent((osh), (void*)(va), (size), (pa))
++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap);
++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa);
++
++/* map/unmap direction */
++#define       DMA_TX  1
++#define       DMA_RX  2
++
++/* register access macros */
++#if defined(BCMJTAG)
++#include <bcmjtag.h>
++#define       R_REG(r)        bcmjtag_read(NULL, (uint32)(r), sizeof (*(r)))
++#define       W_REG(r, v)     bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r)))
++#endif
++
 +/*
 + * BINOSL selects the slightly slower function-call-based binary compatible osl.
 + * Macros expand to calls to functions defined in linux_osl.c .
@@ -8859,22 +7208,39 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#include <linux/string.h>
 +
 +/* register access macros */
++#if !defined(BCMJTAG)
++#ifndef IL_BIGENDIAN   
++#define R_REG(r) ( \
++      sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \
++      sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \
++      readl((volatile uint32*)(r)) \
++)
++#define W_REG(r, v) do { \
++      switch (sizeof(*(r))) { \
++      case sizeof(uint8):     writeb((uint8)(v), (volatile uint8*)(r)); break; \
++      case sizeof(uint16):    writew((uint16)(v), (volatile uint16*)(r)); break; \
++      case sizeof(uint32):    writel((uint32)(v), (volatile uint32*)(r)); break; \
++      } \
++} while (0)
++#else /* IL_BIGENDIAN */
 +#define R_REG(r) ({ \
 +      __typeof(*(r)) __osl_v; \
 +      switch (sizeof(*(r))) { \
-+      case sizeof(uint8):     __osl_v = readb((volatile uint8*)(r)); break; \
-+      case sizeof(uint16):    __osl_v = readw((volatile uint16*)(r)); break; \
++      case sizeof(uint8):     __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \
++      case sizeof(uint16):    __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \
 +      case sizeof(uint32):    __osl_v = readl((volatile uint32*)(r)); break; \
 +      } \
 +      __osl_v; \
 +})
 +#define W_REG(r, v) do { \
 +      switch (sizeof(*(r))) { \
-+      case sizeof(uint8):     writeb((uint8)(v), (volatile uint8*)(r)); break; \
-+      case sizeof(uint16):    writew((uint16)(v), (volatile uint16*)(r)); break; \
++      case sizeof(uint8):     writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \
++      case sizeof(uint16):    writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \
 +      case sizeof(uint32):    writel((uint32)(v), (volatile uint32*)(r)); break; \
 +      } \
 +} while (0)
++#endif
++#endif
 +
 +#define       AND_REG(r, v)           W_REG((r), R_REG(r) & (v))
 +#define       OR_REG(r, v)            W_REG((r), R_REG(r) | (v))
@@ -8884,10 +7250,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#define       bcmp(b1, b2, len)       memcmp((b1), (b2), (len))
 +#define       bzero(b, len)           memset((b), '\0', (len))
 +
-+/* general purpose memory allocation */
-+#define       MALLOC(size)            kmalloc((size), GFP_ATOMIC)
-+#define       MFREE(addr, size)       kfree((addr))
-+
 +/* uncached virtual address */
 +#ifdef mips
 +#define OSL_UNCACHED(va)      KSEG1ADDR((va))
@@ -8921,52 +7283,31 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +#define       REG_MAP(pa, size)       ioremap_nocache((unsigned long)(pa), (unsigned long)(size))
 +#define       REG_UNMAP(va)           iounmap((void *)(va))
 +
-+/* allocate/free shared (dma-able) consistent (uncached) memory */
-+#define       DMA_ALLOC_CONSISTENT(dev, size, pap) \
-+      pci_alloc_consistent((dev), (size), (dma_addr_t*)(pap))
-+#define       DMA_FREE_CONSISTENT(dev, va, size, pa) \
-+      pci_free_consistent((dev), (size), (va), (dma_addr_t)(pa))
-+
-+/* map/unmap direction */
-+#define       DMA_TX                  PCI_DMA_TODEVICE
-+#define       DMA_RX                  PCI_DMA_FROMDEVICE
-+
-+/* map/unmap shared (dma-able) memory */
-+#define       DMA_MAP(dev, va, size, direction, p) \
-+      pci_map_single((dev), (va), (size), (direction))
-+#define       DMA_UNMAP(dev, pa, size, direction, p) \
-+      pci_unmap_single((dev), (dma_addr_t)(pa), (size), (direction))
-+
-+/* microsecond delay */
-+#define       OSL_DELAY(usec)         udelay(usec)
-+#include <linux/delay.h>
-+#define OSL_SLEEP(usec) set_current_state(TASK_INTERRUPTIBLE); \
-+                        schedule_timeout((usec*HZ)/1000000);
-+#define OSL_IN_INTERRUPT() in_interrupt()
-+
 +/* shared (dma-able) memory access macros */
 +#define       R_SM(r)                 *(r)
 +#define       W_SM(r, v)              (*(r) = (v))
 +#define       BZERO_SM(r, len)        memset((r), '\0', (len))
 +
 +/* packet primitives */
-+#define       PKTGET(drv, len, send)          osl_pktget((drv), (len), (send))
-+#define       PKTFREE(drv, skb, send)         osl_pktfree((skb))
-+#define       PKTDATA(drv, skb)               (((struct sk_buff*)(skb))->data)
-+#define       PKTLEN(drv, skb)                (((struct sk_buff*)(skb))->len)
-+#define PKTHEADROOM(drv, skb)         (PKTDATA(drv,skb)-(((struct sk_buff*)(skb))->head))
-+#define PKTTAILROOM(drv, skb)         ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
-+#define       PKTNEXT(drv, skb)               (((struct sk_buff*)(skb))->next)
++#define       PKTGET(osh, len, send)          osl_pktget((osh), (len), (send))
++#define       PKTFREE(osh, skb, send)         osl_pktfree((skb))
++#define       PKTDATA(osh, skb)               (((struct sk_buff*)(skb))->data)
++#define       PKTLEN(osh, skb)                (((struct sk_buff*)(skb))->len)
++#define PKTHEADROOM(osh, skb)         (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head))
++#define PKTTAILROOM(osh, skb)         ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail))
++#define       PKTNEXT(osh, skb)               (((struct sk_buff*)(skb))->next)
 +#define       PKTSETNEXT(skb, x)              (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x))
-+#define       PKTSETLEN(drv, skb, len)        __skb_trim((struct sk_buff*)(skb), (len))
-+#define       PKTPUSH(drv, skb, bytes)        skb_push((struct sk_buff*)(skb), (bytes))
-+#define       PKTPULL(drv, skb, bytes)        skb_pull((struct sk_buff*)(skb), (bytes))
-+#define       PKTDUP(drv, skb)                skb_clone((struct sk_buff*)(skb), GFP_ATOMIC)
++#define       PKTSETLEN(osh, skb, len)        __skb_trim((struct sk_buff*)(skb), (len))
++#define       PKTPUSH(osh, skb, bytes)        skb_push((struct sk_buff*)(skb), (bytes))
++#define       PKTPULL(osh, skb, bytes)        skb_pull((struct sk_buff*)(skb), (bytes))
++#define       PKTDUP(osh, skb)                skb_clone((struct sk_buff*)(skb), GFP_ATOMIC)
 +#define       PKTCOOKIE(skb)                  ((void*)((struct sk_buff*)(skb))->csum)
 +#define       PKTSETCOOKIE(skb, x)            (((struct sk_buff*)(skb))->csum = (uint)(x))
 +#define       PKTLINK(skb)                    (((struct sk_buff*)(skb))->prev)
 +#define       PKTSETLINK(skb, x)              (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x))
-+extern void *osl_pktget(void *drv, uint len, bool send);
++#define       PKTPRIO(skb)                    (((struct sk_buff*)(skb))->priority)
++#define       PKTSETPRIO(skb, x)              (((struct sk_buff*)(skb))->priority = (x))
++extern void *osl_pktget(osl_t *osh, uint len, bool send);
 +extern void osl_pktfree(void *skb);
 +
 +#else /* BINOSL */                                    
@@ -8992,20 +7333,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +extern int osl_sprintf(char *buf, const char *format, ...);
 +extern int osl_strcmp(const char *s1, const char *s2);
 +extern int osl_strncmp(const char *s1, const char *s2, uint n);
-+extern int osl_strlen(char *s);
++extern int osl_strlen(const char *s);
 +extern char* osl_strcpy(char *d, const char *s);
 +extern char* osl_strncpy(char *d, const char *s, uint n);
 +
 +/* register access macros */
-+#define R_REG(r) ({ \
-+      __typeof(*(r)) __osl_v; \
-+      switch (sizeof(*(r))) { \
-+      case sizeof(uint8):     __osl_v = osl_readb((volatile uint8*)(r)); break; \
-+      case sizeof(uint16):    __osl_v = osl_readw((volatile uint16*)(r)); break; \
-+      case sizeof(uint32):    __osl_v = osl_readl((volatile uint32*)(r)); break; \
-+      } \
-+      __osl_v; \
-+})
++#if !defined(BCMJTAG)
++#define R_REG(r) ( \
++      sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \
++      sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \
++      osl_readl((volatile uint32*)(r)) \
++)
 +#define W_REG(r, v) do { \
 +      switch (sizeof(*(r))) { \
 +      case sizeof(uint8):     osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \
@@ -9013,6 +7351,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +      case sizeof(uint32):    osl_writel((uint32)(v), (volatile uint32*)(r)); break; \
 +      } \
 +} while (0)
++#endif
++
 +#define       AND_REG(r, v)           W_REG((r), R_REG(r) & (v))
 +#define       OR_REG(r, v)            W_REG((r), R_REG(r) | (v))
 +extern uint8 osl_readb(volatile uint8 *r);
@@ -9027,12 +7367,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +extern int bcmp(const void *b1, const void *b2, int len);
 +extern void bzero(void *b, int len);
 +
-+/* general purpose memory allocation */
-+#define       MALLOC(size)            osl_malloc((size))
-+#define       MFREE(addr, size)       osl_mfree((char*)(addr), (size))
-+extern void *osl_malloc(uint size);
-+extern void osl_mfree(void *addr, uint size);
-+
 +/* uncached virtual address */
 +#define OSL_UNCACHED(va)      osl_uncached((va))
 +extern void *osl_uncached(void *va);
@@ -9051,83 +7385,74 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linux_osl.h linux-2.6.12.5-b
 +extern void *osl_reg_map(uint32 pa, uint size);
 +extern void osl_reg_unmap(void *va);
 +
-+/* allocate/free shared (dma-able) consistent (uncached) memory */
-+#define       DMA_ALLOC_CONSISTENT(dev, size, pap) \
-+      osl_dma_alloc_consistent((dev), (size), (pap))
-+#define       DMA_FREE_CONSISTENT(dev, va, size, pa) \
-+      osl_dma_free_consistent((dev), (void*)(va), (size), (pa))
-+extern void *osl_dma_alloc_consistent(void *dev, uint size, ulong *pap);
-+extern void osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa);
-+
-+/* map/unmap direction */
-+#define       DMA_TX  1
-+#define       DMA_RX  2
-+
-+/* map/unmap shared (dma-able) memory */
-+#define       DMA_MAP(dev, va, size, direction, p) \
-+      osl_dma_map((dev), (va), (size), (direction))
-+#define       DMA_UNMAP(dev, pa, size, direction, p) \
-+      osl_dma_unmap((dev), (pa), (size), (direction))
-+extern uint osl_dma_map(void *dev, void *va, uint size, int direction);
-+extern void osl_dma_unmap(void *dev, uint pa, uint size, int direction);
-+
-+/* microsecond delay */
-+#define       OSL_DELAY(usec)         osl_delay((usec))
-+extern void osl_delay(uint usec);
-+
 +/* shared (dma-able) memory access macros */
 +#define       R_SM(r)                 *(r)
 +#define       W_SM(r, v)              (*(r) = (v))
 +#define       BZERO_SM(r, len)        bzero((r), (len))
 +
 +/* packet primitives */
-+#define       PKTGET(drv, len, send)          osl_pktget((drv), (len), (send))
-+#define       PKTFREE(drv, skb, send)         osl_pktfree((skb))
-+#define       PKTDATA(drv, skb)               osl_pktdata((drv), (skb))
-+#define       PKTLEN(drv, skb)                osl_pktlen((drv), (skb))
-+#define       PKTNEXT(drv, skb)               osl_pktnext((drv), (skb))
++#define       PKTGET(osh, len, send)          osl_pktget((osh), (len), (send))
++#define       PKTFREE(osh, skb, send)         osl_pktfree((skb))
++#define       PKTDATA(osh, skb)               osl_pktdata((osh), (skb))
++#define       PKTLEN(osh, skb)                osl_pktlen((osh), (skb))
++#define PKTHEADROOM(osh, skb)         osl_pktheadroom((osh), (skb))
++#define PKTTAILROOM(osh, skb)         osl_pkttailroom((osh), (skb))
++#define       PKTNEXT(osh, skb)               osl_pktnext((osh), (skb))
 +#define       PKTSETNEXT(skb, x)              osl_pktsetnext((skb), (x))
-+#define       PKTSETLEN(drv, skb, len)        osl_pktsetlen((drv), (skb), (len))
-+#define       PKTPUSH(drv, skb, bytes)        osl_pktpush((drv), (skb), (bytes))
-+#define       PKTPULL(drv, skb, bytes)        osl_pktpull((drv), (skb), (bytes))
-+#define       PKTDUP(drv, skb)                osl_pktdup((drv), (skb))
++#define       PKTSETLEN(osh, skb, len)        osl_pktsetlen((osh), (skb), (len))
++#define       PKTPUSH(osh, skb, bytes)        osl_pktpush((osh), (skb), (bytes))
++#define       PKTPULL(osh, skb, bytes)        osl_pktpull((osh), (skb), (bytes))
++#define       PKTDUP(osh, skb)                osl_pktdup((osh), (skb))
 +#define       PKTCOOKIE(skb)                  osl_pktcookie((skb))
 +#define       PKTSETCOOKIE(skb, x)            osl_pktsetcookie((skb), (x))
 +#define       PKTLINK(skb)                    osl_pktlink((skb))
 +#define       PKTSETLINK(skb, x)              osl_pktsetlink((skb), (x))
-+extern void *osl_pktget(void *drv, uint len, bool send);
++#define       PKTPRIO(skb)                    osl_pktprio((skb))
++#define       PKTSETPRIO(skb, x)              osl_pktsetprio((skb), (x))
++extern void *osl_pktget(osl_t *osh, uint len, bool send);
 +extern void osl_pktfree(void *skb);
-+extern uchar *osl_pktdata(void *drv, void *skb);
-+extern uint osl_pktlen(void *drv, void *skb);
-+extern void *osl_pktnext(void *drv, void *skb);
++extern uchar *osl_pktdata(osl_t *osh, void *skb);
++extern uint osl_pktlen(osl_t *osh, void *skb);
++extern uint osl_pktheadroom(osl_t *osh, void *skb);
++extern uint osl_pkttailroom(osl_t *osh, void *skb);
++extern void *osl_pktnext(osl_t *osh, void *skb);
 +extern void osl_pktsetnext(void *skb, void *x);
-+extern void osl_pktsetlen(void *drv, void *skb, uint len);
-+extern uchar *osl_pktpush(void *drv, void *skb, int bytes);
-+extern uchar *osl_pktpull(void *drv, void *skb, int bytes);
-+extern void *osl_pktdup(void *drv, void *skb);
++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len);
++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes);
++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes);
++extern void *osl_pktdup(osl_t *osh, void *skb);
 +extern void *osl_pktcookie(void *skb);
 +extern void osl_pktsetcookie(void *skb, void *x);
 +extern void *osl_pktlink(void *skb);
 +extern void osl_pktsetlink(void *skb, void *x);
++extern uint osl_pktprio(void *skb);
++extern void osl_pktsetprio(void *skb, uint x);
 +
 +#endif        /* BINOSL */
 +
++#define OSL_ERROR(bcmerror)   osl_error(bcmerror)
++extern int osl_error(int bcmerror);
++
++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */
++#define       PKTBUFSZ        2048
++
 +#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-11-07 01:12:51.831810250 +0100
-@@ -0,0 +1,326 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h
+--- linux.old/arch/mips/bcm947xx/include/linuxver.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h    2005-12-15 16:02:45.467929000 +0100
+@@ -0,0 +1,389 @@
 +/*
 + * Linux-specific abstractions to gain some independence from linux kernel versions.
-+ * Pave over some 2.2 versus 2.4 kernel differences.
++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences.
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -9150,6 +7475,16 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +#include <linux/modversions.h>
 +#endif
 +
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
++#include <linux/moduleparam.h>
++#endif
++
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) 
++#define module_param(_name_, _type_, _perm_)  MODULE_PARM(_name_, "i")        
++#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_))
++#endif
++
 +/* linux/malloc.h is deprecated, use linux/slab.h instead. */
 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9))
 +#include <linux/malloc.h>
@@ -9159,7 +7494,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +
 +#include <linux/types.h>
 +#include <linux/init.h>
-+#include <linux/module.h>
 +#include <linux/mm.h>
 +#include <linux/string.h>
 +#include <linux/pci.h>
@@ -9167,6 +7501,36 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +#include <linux/netdevice.h>
 +#include <asm/io.h>
 +
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41))
++#include <linux/workqueue.h>
++#else
++#include <linux/tqueue.h>
++#ifndef work_struct
++#define work_struct tq_struct
++#endif
++#ifndef INIT_WORK
++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data))
++#endif
++#ifndef schedule_work
++#define schedule_work(_work) schedule_task((_work))
++#endif
++#ifndef flush_scheduled_work
++#define flush_scheduled_work() flush_scheduled_tasks()
++#endif
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
++/* Some distributions have their own 2.6.x compatibility layers */
++#ifndef IRQ_NONE
++typedef void irqreturn_t;
++#define IRQ_NONE
++#define IRQ_HANDLED
++#define IRQ_RETVAL(x)
++#endif
++#else
++typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs);
++#endif
++
 +#ifndef __exit
 +#define __exit
 +#endif
@@ -9384,163 +7748,679 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/linuxver.h linux-2.6.12.5-br
 +      } while (0)
 +
 +/*
-+ * Emit code to initialise all of a tq_struct
++ * Emit code to initialise all of a tq_struct
++ */
++#define INIT_TQUEUE(_tq, _routine, _data)                     \
++      do {                                                    \
++              INIT_LIST_HEAD(&(_tq)->list);                   \
++              (_tq)->sync = 0;                                \
++              PREPARE_TQUEUE((_tq), (_routine), (_data));     \
++      } while (0)
++
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6))
++
++/* Power management related routines */
++
++static inline int
++pci_save_state(struct pci_dev *dev, u32 *buffer)
++{
++      int i;
++      if (buffer) {
++              for (i = 0; i < 16; i++)
++                      pci_read_config_dword(dev, i * 4,&buffer[i]);
++      }
++      return 0;
++}
++
++static inline int 
++pci_restore_state(struct pci_dev *dev, u32 *buffer)
++{
++      int i;
++
++      if (buffer) {
++              for (i = 0; i < 16; i++)
++                      pci_write_config_dword(dev,i * 4, buffer[i]);
++      }
++      /*
++       * otherwise, write the context information we know from bootup.
++       * This works around a problem where warm-booting from Windows
++       * combined with a D3(hot)->D0 transition causes PCI config
++       * header data to be forgotten.
++       */     
++      else {
++              for (i = 0; i < 6; i ++)
++                      pci_write_config_dword(dev,
++                                             PCI_BASE_ADDRESS_0 + (i * 4),
++                                             pci_resource_start(dev, i));
++              pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
++      }
++      return 0;
++}
++
++#endif /* PCI power management */
++
++/* Old cp0 access macros deprecated in 2.4.19 */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19))
++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
++#endif
++
++/* Module refcount handled internally in 2.6.x */
++#ifndef SET_MODULE_OWNER
++#define SET_MODULE_OWNER(dev)         do {} while (0)
++#define OLD_MOD_INC_USE_COUNT         MOD_INC_USE_COUNT
++#define OLD_MOD_DEC_USE_COUNT         MOD_DEC_USE_COUNT
++#else
++#define OLD_MOD_INC_USE_COUNT         do {} while (0)
++#define OLD_MOD_DEC_USE_COUNT         do {} while (0)
++#endif
++
++#ifndef SET_NETDEV_DEV
++#define SET_NETDEV_DEV(net, pdev)     do {} while (0)
++#endif
++
++#ifndef HAVE_FREE_NETDEV
++#define free_netdev(dev)              kfree(dev)
++#endif
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
++/* struct packet_type redefined in 2.6.x */
++#define af_packet_priv                        data
++#endif
++
++#endif /* _linuxver_h_ */
+diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h
+--- linux.old/arch/mips/bcm947xx/include/mipsinc.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h     2005-12-15 16:47:29.886633750 +0100
+@@ -0,0 +1,552 @@
++/*
++ * HND Run Time Environment for standalone MIPS programs.
++ *
++ * 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$
++ */
++
++#ifndef       _MISPINC_H
++#define _MISPINC_H
++
++
++/* MIPS defines */
++
++#ifdef        _LANGUAGE_ASSEMBLY
++
++/*
++ * Symbolic register names for 32 bit ABI
++ */
++#define zero  $0      /* wired zero */
++#define AT    $1      /* assembler temp - uppercase because of ".set at" */
++#define v0    $2      /* return value */
++#define v1    $3
++#define a0    $4      /* argument registers */
++#define a1    $5
++#define a2    $6
++#define a3    $7
++#define t0    $8      /* caller saved */
++#define t1    $9
++#define t2    $10
++#define t3    $11
++#define t4    $12
++#define t5    $13
++#define t6    $14
++#define t7    $15
++#define s0    $16     /* callee saved */
++#define s1    $17
++#define s2    $18
++#define s3    $19
++#define s4    $20
++#define s5    $21
++#define s6    $22
++#define s7    $23
++#define t8    $24     /* caller saved */
++#define t9    $25
++#define jp    $25     /* PIC jump register */
++#define k0    $26     /* kernel scratch */
++#define k1    $27
++#define gp    $28     /* global pointer */
++#define sp    $29     /* stack pointer */
++#define fp    $30     /* frame pointer */
++#define s8    $30     /* same like fp! */
++#define ra    $31     /* return address */
++
++
++/*
++ * CP0 Registers 
++ */
++
++#define C0_INX                $0
++#define C0_RAND               $1
++#define C0_TLBLO0     $2
++#define C0_TLBLO      C0_TLBLO0
++#define C0_TLBLO1     $3
++#define C0_CTEXT      $4
++#define C0_PGMASK     $5
++#define C0_WIRED      $6
++#define C0_BADVADDR   $8
++#define C0_COUNT      $9
++#define C0_TLBHI      $10
++#define C0_COMPARE    $11
++#define C0_SR         $12
++#define C0_STATUS     C0_SR
++#define C0_CAUSE      $13
++#define C0_EPC                $14
++#define C0_PRID               $15
++#define C0_CONFIG     $16
++#define C0_LLADDR     $17
++#define C0_WATCHLO    $18
++#define C0_WATCHHI    $19
++#define C0_XCTEXT     $20
++#define C0_DIAGNOSTIC $22
++#define C0_BROADCOM   C0_DIAGNOSTIC
++#define       C0_PERFORMANCE  $25
++#define C0_ECC                $26
++#define C0_CACHEERR   $27
++#define C0_TAGLO      $28
++#define C0_TAGHI      $29
++#define C0_ERREPC     $30
++#define C0_DESAVE     $31
++
++/*
++ * LEAF - declare leaf routine
++ */
++#define LEAF(symbol)                          \
++              .globl  symbol;                 \
++              .align  2;                      \
++              .type   symbol,@function;       \
++              .ent    symbol,0;               \
++symbol:               .frame  sp,0,ra
++
++/*
++ * END - mark end of function
++ */
++#define END(function)                         \
++              .end    function;               \
++              .size   function,.-function
++
++#define _ULCAST_
++
++#else
++
++/*
++ * The following macros are especially useful for __asm__
++ * inline assembler.
++ */
++#ifndef __STR
++#define __STR(x) #x
++#endif
++#ifndef STR
++#define STR(x) __STR(x)
++#endif
++
++#define _ULCAST_ (unsigned long)
++
++
++/*
++ * CP0 Registers 
++ */
++
++#define C0_INX                0               /* CP0: TLB Index */
++#define C0_RAND               1               /* CP0: TLB Random */
++#define C0_TLBLO0     2               /* CP0: TLB EntryLo0 */
++#define C0_TLBLO      C0_TLBLO0       /* CP0: TLB EntryLo0 */
++#define C0_TLBLO1     3               /* CP0: TLB EntryLo1 */
++#define C0_CTEXT      4               /* CP0: Context */
++#define C0_PGMASK     5               /* CP0: TLB PageMask */
++#define C0_WIRED      6               /* CP0: TLB Wired */
++#define C0_BADVADDR   8               /* CP0: Bad Virtual Address */
++#define C0_COUNT      9               /* CP0: Count */
++#define C0_TLBHI      10              /* CP0: TLB EntryHi */
++#define C0_COMPARE    11              /* CP0: Compare */
++#define C0_SR         12              /* CP0: Processor Status */
++#define C0_STATUS     C0_SR           /* CP0: Processor Status */
++#define C0_CAUSE      13              /* CP0: Exception Cause */
++#define C0_EPC                14              /* CP0: Exception PC */
++#define C0_PRID               15              /* CP0: Processor Revision Indentifier */
++#define C0_CONFIG     16              /* CP0: Config */
++#define C0_LLADDR     17              /* CP0: LLAddr */
++#define C0_WATCHLO    18              /* CP0: WatchpointLo */
++#define C0_WATCHHI    19              /* CP0: WatchpointHi */
++#define C0_XCTEXT     20              /* CP0: XContext */
++#define C0_DIAGNOSTIC 22              /* CP0: Diagnostic */
++#define C0_BROADCOM   C0_DIAGNOSTIC   /* CP0: Broadcom Register */
++#define       C0_PERFORMANCE  25              /* CP0: Performance Counter/Control Registers */
++#define C0_ECC                26              /* CP0: ECC */
++#define C0_CACHEERR   27              /* CP0: CacheErr */
++#define C0_TAGLO      28              /* CP0: TagLo */
++#define C0_TAGHI      29              /* CP0: TagHi */
++#define C0_ERREPC     30              /* CP0: ErrorEPC */
++#define C0_DESAVE     31              /* CP0: DebugSave */
++
++#endif        /* _LANGUAGE_ASSEMBLY */
++
++/*
++ * Memory segments (32bit kernel mode addresses)
++ */
++#undef KUSEG
++#undef KSEG0
++#undef KSEG1
++#undef KSEG2
++#undef KSEG3
++#define KUSEG         0x00000000
++#define KSEG0         0x80000000
++#define KSEG1         0xa0000000
++#define KSEG2         0xc0000000
++#define KSEG3         0xe0000000
++#define PHYSADDR_MASK 0x1fffffff
++
++/*
++ * Map an address to a certain kernel segment
++ */
++#undef PHYSADDR
++#undef KSEG0ADDR
++#undef KSEG1ADDR
++#undef KSEG2ADDR
++#undef KSEG3ADDR
++
++#define PHYSADDR(a)   (_ULCAST_(a) & PHYSADDR_MASK)
++#define KSEG0ADDR(a)  ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0)
++#define KSEG1ADDR(a)  ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1)
++#define KSEG2ADDR(a)  ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2)
++#define KSEG3ADDR(a)  ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3)
++
++
++#ifndef       Index_Invalidate_I
++/*
++ * Cache Operations
++ */
++#define Index_Invalidate_I    0x00
++#define Index_Writeback_Inv_D 0x01
++#define Index_Invalidate_SI   0x02
++#define Index_Writeback_Inv_SD        0x03
++#define Index_Load_Tag_I      0x04
++#define Index_Load_Tag_D      0x05
++#define Index_Load_Tag_SI     0x06
++#define Index_Load_Tag_SD     0x07
++#define Index_Store_Tag_I     0x08
++#define Index_Store_Tag_D     0x09
++#define Index_Store_Tag_SI    0x0A
++#define Index_Store_Tag_SD    0x0B
++#define Create_Dirty_Excl_D   0x0d
++#define Create_Dirty_Excl_SD  0x0f
++#define Hit_Invalidate_I      0x10
++#define Hit_Invalidate_D      0x11
++#define Hit_Invalidate_SI     0x12
++#define Hit_Invalidate_SD     0x13
++#define Fill_I                        0x14
++#define Hit_Writeback_Inv_D   0x15
++                                      /* 0x16 is unused */
++#define Hit_Writeback_Inv_SD  0x17
++#define R5K_Page_Invalidate_S 0x17
++#define Hit_Writeback_I               0x18
++#define Hit_Writeback_D               0x19
++                                      /* 0x1a is unused */
++#define Hit_Writeback_SD      0x1b
++                                      /* 0x1c is unused */
++                                      /* 0x1e is unused */
++#define Hit_Set_Virtual_SI    0x1e
++#define Hit_Set_Virtual_SD    0x1f
++#endif
++
++
++/*
++ * R4x00 interrupt enable / cause bits
 + */
-+#define INIT_TQUEUE(_tq, _routine, _data)                     \
-+      do {                                                    \
-+              INIT_LIST_HEAD(&(_tq)->list);                   \
-+              (_tq)->sync = 0;                                \
-+              PREPARE_TQUEUE((_tq), (_routine), (_data));     \
-+      } while (0)
++#define IE_SW0                        (_ULCAST_(1) <<  8)
++#define IE_SW1                        (_ULCAST_(1) <<  9)
++#define IE_IRQ0                       (_ULCAST_(1) << 10)
++#define IE_IRQ1                       (_ULCAST_(1) << 11)
++#define IE_IRQ2                       (_ULCAST_(1) << 12)
++#define IE_IRQ3                       (_ULCAST_(1) << 13)
++#define IE_IRQ4                       (_ULCAST_(1) << 14)
++#define IE_IRQ5                       (_ULCAST_(1) << 15)
 +
++#ifndef       ST0_UM
++/*
++ * Bitfields in the mips32 cp0 status register
++ */
++#define ST0_IE                        0x00000001
++#define ST0_EXL                       0x00000002
++#define ST0_ERL                       0x00000004
++#define ST0_UM                        0x00000010
++#define ST0_SWINT0            0x00000100
++#define ST0_SWINT1            0x00000200
++#define ST0_HWINT0            0x00000400
++#define ST0_HWINT1            0x00000800
++#define ST0_HWINT2            0x00001000
++#define ST0_HWINT3            0x00002000
++#define ST0_HWINT4            0x00004000
++#define ST0_HWINT5            0x00008000
++#define ST0_IM                        0x0000ff00
++#define ST0_NMI                       0x00080000
++#define ST0_SR                        0x00100000
++#define ST0_TS                        0x00200000
++#define ST0_BEV                       0x00400000
++#define ST0_RE                        0x02000000
++#define ST0_RP                        0x08000000
++#define ST0_CU                        0xf0000000
++#define ST0_CU0                       0x10000000
++#define ST0_CU1                       0x20000000
++#define ST0_CU2                       0x40000000
++#define ST0_CU3                       0x80000000
 +#endif
 +
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6))
 +
-+/* Power management related routines */
++/*
++ * Bitfields in the mips32 cp0 cause register
++ */
++#define C_EXC                 0x0000007c
++#define C_EXC_SHIFT           2
++#define C_INT                 0x0000ff00
++#define C_INT_SHIFT           8
++#define C_SW0                 (_ULCAST_(1) <<  8)
++#define C_SW1                 (_ULCAST_(1) <<  9)
++#define C_IRQ0                        (_ULCAST_(1) << 10)
++#define C_IRQ1                        (_ULCAST_(1) << 11)
++#define C_IRQ2                        (_ULCAST_(1) << 12)
++#define C_IRQ3                        (_ULCAST_(1) << 13)
++#define C_IRQ4                        (_ULCAST_(1) << 14)
++#define C_IRQ5                        (_ULCAST_(1) << 15)
++#define C_WP                  0x00400000
++#define C_IV                  0x00800000
++#define C_CE                  0x30000000
++#define C_CE_SHIFT            28
++#define C_BD                  0x80000000
++
++/* Values in C_EXC */
++#define EXC_INT                       0
++#define EXC_TLBM              1
++#define EXC_TLBL              2
++#define EXC_TLBS              3
++#define EXC_AEL                       4
++#define EXC_AES                       5
++#define EXC_IBE                       6
++#define EXC_DBE                       7
++#define EXC_SYS                       8
++#define EXC_BPT                       9
++#define EXC_RI                        10
++#define EXC_CU                        11
++#define EXC_OV                        12
++#define EXC_TR                        13
++#define EXC_WATCH             23
++#define EXC_MCHK              24
++
++
++/*
++ * Bits in the cp0 config register.
++ */
++#define CONF_CM_CACHABLE_NO_WA                0
++#define CONF_CM_CACHABLE_WA           1
++#define CONF_CM_UNCACHED              2
++#define CONF_CM_CACHABLE_NONCOHERENT  3
++#define CONF_CM_CACHABLE_CE           4
++#define CONF_CM_CACHABLE_COW          5
++#define CONF_CM_CACHABLE_CUW          6
++#define CONF_CM_CACHABLE_ACCELERATED  7
++#define CONF_CM_CMASK                 7
++#define CONF_CU                               (_ULCAST_(1) <<  3)
++#define CONF_DB                               (_ULCAST_(1) <<  4)
++#define CONF_IB                               (_ULCAST_(1) <<  5)
++#define CONF_SE                               (_ULCAST_(1) << 12)
++#define CONF_SC                               (_ULCAST_(1) << 17)
++#define CONF_AC                               (_ULCAST_(1) << 23)
++#define CONF_HALT                     (_ULCAST_(1) << 25)
++
++
++/*
++ * Bits in the cp0 config register select 1.
++ */
++#define CONF1_FP              0x00000001      /* FPU present */
++#define CONF1_EP              0x00000002      /* EJTAG present */
++#define CONF1_CA              0x00000004      /* mips16 implemented */
++#define CONF1_WR              0x00000008      /* Watch registers present */
++#define CONF1_PC              0x00000010      /* Performance counters present */
++#define CONF1_DA_SHIFT                7               /* D$ associativity */
++#define CONF1_DA_MASK         0x00000380
++#define CONF1_DA_BASE         1
++#define CONF1_DL_SHIFT                10              /* D$ line size */
++#define CONF1_DL_MASK         0x00001c00
++#define CONF1_DL_BASE         2
++#define CONF1_DS_SHIFT                13              /* D$ sets/way */
++#define CONF1_DS_MASK         0x0000e000
++#define CONF1_DS_BASE         64
++#define CONF1_IA_SHIFT                16              /* I$ associativity */
++#define CONF1_IA_MASK         0x00070000
++#define CONF1_IA_BASE         1
++#define CONF1_IL_SHIFT                19              /* I$ line size */
++#define CONF1_IL_MASK         0x00380000
++#define CONF1_IL_BASE         2
++#define CONF1_IS_SHIFT                22              /* Instruction cache sets/way */
++#define CONF1_IS_MASK         0x01c00000
++#define CONF1_IS_BASE         64
++#define CONF1_MS_MASK         0x7e000000      /* Number of tlb entries */
++#define CONF1_MS_SHIFT                25
++
++/* PRID register */
++#define PRID_COPT_MASK                0xff000000
++#define PRID_COMP_MASK                0x00ff0000
++#define PRID_IMP_MASK         0x0000ff00
++#define PRID_REV_MASK         0x000000ff
++
++#define PRID_COMP_LEGACY      0x000000
++#define PRID_COMP_MIPS                0x010000
++#define PRID_COMP_BROADCOM    0x020000
++#define PRID_COMP_ALCHEMY     0x030000
++#define PRID_COMP_SIBYTE      0x040000
++#define PRID_IMP_BCM4710      0x4000
++#define PRID_IMP_BCM3302      0x9000
++#define PRID_IMP_BCM3303      0x9100
++
++#define PRID_IMP_UNKNOWN      0xff00
++
++#define BCM330X(id) \
++      (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \
++      || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
++
++/* Bits in C0_BROADCOM */
++#define BRCM_PFC_AVAIL                0x20000000      /* PFC is available */
++#define BRCM_DC_ENABLE                0x40000000      /* Enable Data $ */
++#define BRCM_IC_ENABLE                0x80000000      /* Enable Instruction $ */
++#define BRCM_PFC_ENABLE               0x00400000      /* Obsolete? Enable PFC (at least on 4310) */
++
++/* PreFetch Cache aka Read Ahead Cache */
++
++#define PFC_CR0                       0xff400000      /* control reg 0 */
++#define PFC_CR1                       0xff400004      /* control reg 1 */
++
++/* PFC operations */
++#define PFC_I                 0x00000001      /* Enable PFC use for instructions */
++#define PFC_D                 0x00000002      /* Enable PFC use for data */
++#define PFC_PFI                       0x00000004      /* Enable seq. prefetch for instructions */
++#define PFC_PFD                       0x00000008      /* Enable seq. prefetch for data */
++#define PFC_CINV              0x00000010      /* Enable selective (i/d) cacheop flushing */
++#define PFC_NCH                       0x00000020      /* Disable flushing based on cacheops */
++#define PFC_DPF                       0x00000040      /* Enable directional prefetching */
++#define PFC_FLUSH             0x00000100      /* Flush the PFC */
++#define PFC_BRR                       0x40000000      /* Bus error indication */
++#define PFC_PWR                       0x80000000      /* Disable power saving (clock gating) */
++
++/* Handy defaults */
++#define PFC_DISABLED          0
++#define PFC_AUTO                      0xffffffff      /* auto select the default mode */
++#define PFC_INST              (PFC_I | PFC_PFI | PFC_CINV)
++#define PFC_INST_NOPF         (PFC_I | PFC_CINV)
++#define PFC_DATA              (PFC_D | PFC_PFD | PFC_CINV)
++#define PFC_DATA_NOPF         (PFC_D | PFC_CINV)
++#define PFC_I_AND_D           (PFC_INST | PFC_DATA)
++#define PFC_I_AND_D_NOPF      (PFC_INST_NOPF | PFC_DATA_NOPF)
 +
-+static inline int
-+pci_save_state(struct pci_dev *dev, u32 *buffer)
-+{
-+      int i;
-+      if (buffer) {
-+              for (i = 0; i < 16; i++)
-+                      pci_read_config_dword(dev, i * 4,&buffer[i]);
-+      }
-+      return 0;
-+}
 +
-+static inline int 
-+pci_restore_state(struct pci_dev *dev, u32 *buffer)
-+{
-+      int i;
++/* 
++ * These are the UART port assignments, expressed as offsets from the base
++ * register.  These assignments should hold for any serial port based on
++ * a 8250, 16450, or 16550(A).
++ */
 +
-+      if (buffer) {
-+              for (i = 0; i < 16; i++)
-+                      pci_write_config_dword(dev,i * 4, buffer[i]);
-+      }
-+      /*
-+       * otherwise, write the context information we know from bootup.
-+       * This works around a problem where warm-booting from Windows
-+       * combined with a D3(hot)->D0 transition causes PCI config
-+       * header data to be forgotten.
-+       */     
-+      else {
-+              for (i = 0; i < 6; i ++)
-+                      pci_write_config_dword(dev,
-+                                             PCI_BASE_ADDRESS_0 + (i * 4),
-+                                             pci_resource_start(dev, i));
-+              pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-+      }
-+      return 0;
-+}
++#define UART_RX               0       /* In:  Receive buffer (DLAB=0) */
++#define UART_TX               0       /* Out: Transmit buffer (DLAB=0) */
++#define UART_DLL      0       /* Out: Divisor Latch Low (DLAB=1) */
++#define UART_DLM      1       /* Out: Divisor Latch High (DLAB=1) */
++#define UART_LCR      3       /* Out: Line Control Register */
++#define UART_MCR      4       /* Out: Modem Control Register */
++#define UART_LSR      5       /* In:  Line Status Register */
++#define UART_MSR      6       /* In:  Modem Status Register */
++#define UART_SCR      7       /* I/O: Scratch Register */
++#define UART_LCR_DLAB 0x80    /* Divisor latch access bit */
++#define UART_LCR_WLEN8        0x03    /* Wordlength: 8 bits */
++#define UART_MCR_LOOP 0x10    /* Enable loopback test mode */
++#define UART_LSR_THRE 0x20    /* Transmit-hold-register empty */
++#define UART_LSR_RXRDY        0x01    /* Receiver ready */
 +
-+#endif /* PCI power management */
 +
-+/* Old cp0 access macros deprecated in 2.4.19 */
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19))
-+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT)
-+#endif
++#ifndef       _LANGUAGE_ASSEMBLY
 +
-+#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-11-07 01:12:51.831810250 +0100
-@@ -0,0 +1,62 @@
 +/*
-+ * Broadcom Home Gateway Reference Design
-+ * Ports Web Page Configuration Support Routines
-+ *
-+ * 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$
++ * Macros to access the system control coprocessor
 + */
 +
-+#ifndef _nvports_h_
-+#define _nvports_h_
-+
-+#define uint32 unsigned long
-+#define uint16 unsigned short
-+#define uint unsigned int
-+#define uint8 unsigned char
-+#define uint64 unsigned long long
-+
-+enum FORCE_PORT {
-+      FORCE_OFF,
-+      FORCE_10H,
-+      FORCE_10F,
-+      FORCE_100H,
-+      FORCE_100F,
-+      FORCE_DOWN,
-+      POWER_OFF
-+};
-+
-+typedef struct _PORT_ATTRIBS
-+{
-+      uint    autoneg;
-+      uint    force;
-+      uint    native; 
-+} PORT_ATTRIBS;
++#define MFC0(source, sel)                                     \
++({                                                            \
++      int __res;                                              \
++      __asm__ __volatile__(                                   \
++      ".set\tnoreorder\n\t"                                   \
++      ".set\tnoat\n\t"                                        \
++      ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \
++      "move\t%0,$1\n\t"                                       \
++      ".set\tat\n\t"                                          \
++      ".set\treorder"                                         \
++      :"=r" (__res)                                           \
++      :                                                       \
++      :"$1");                                                 \
++      __res;                                                  \
++})
 +
-+extern uint
-+nvExistsPortAttrib(char *attrib, uint portno);
++#define MTC0(source, sel, value)                              \
++do {                                                          \
++      __asm__ __volatile__(                                   \
++      ".set\tnoreorder\n\t"                                   \
++      ".set\tnoat\n\t"                                        \
++      "move\t$1,%z0\n\t"                                      \
++      ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \
++      ".set\tat\n\t"                                          \
++      ".set\treorder"                                         \
++      :                                                       \
++      :"jr" (value)                                           \
++      :"$1");                                                 \
++} while (0)
 +
-+extern int
-+nvExistsAnyForcePortAttrib(uint portno);
++#define get_c0_count()                                                \
++({                                                            \
++      int __res;                                              \
++      __asm__ __volatile__(                                   \
++      ".set\tnoreorder\n\t"                                   \
++      ".set\tnoat\n\t"                                        \
++      "mfc0\t%0,$9\n\t"                                       \
++      ".set\tat\n\t"                                          \
++      ".set\treorder"                                         \
++      :"=r" (__res));                                         \
++      __res;                                                  \
++})
 +
-+extern void
-+nvSetPortAttrib(char *attrib, uint portno);
++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize)
++{
++      uint lsz, sets, ways;
 +
-+extern void
-+nvUnsetPortAttrib(char *attrib, uint portno);
++      /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
++      if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT)))
++              lsz = CONF1_IL_BASE << lsz;
++      sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT);
++      ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT);
++      *size = lsz * sets * ways;
++      *lsize = lsz;
++}
 +
-+extern void
-+nvUnsetAllForcePortAttrib(uint portno);
++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize)
++{
++      uint lsz, sets, ways;
 +
-+extern PORT_ATTRIBS
-+nvGetSwitchPortAttribs(uint portno);
++      /* Data Cache Size = Associativity * Line Size * Sets Per Way */
++      if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT)))
++              lsz = CONF1_DL_BASE << lsz;
++      sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT);
++      ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT);
++      *size = lsz * sets * ways;
++      *lsize = lsz;
++}
 +
-+#endif /* _nvports_h_ */
++#define cache_op(base, op)                    \
++      __asm__ __volatile__("                  \
++              .set noreorder;                 \
++              .set mips3;                     \
++              cache %1, (%0);                 \
++              .set mips0;                     \
++              .set reorder"                   \
++              :                               \
++              : "r" (base),                   \
++                "i" (op));
 +
++#define cache_unroll4(base, delta, op)                \
++      __asm__ __volatile__("                  \
++              .set noreorder;                 \
++              .set mips3;                     \
++              cache %1,0(%0);                 \
++              cache %1,delta(%0);             \
++              cache %1,(2 * delta)(%0);       \
++              cache %1,(3 * delta)(%0);       \
++              .set mips0;                     \
++              .set reorder"                   \
++              :                               \
++              : "r" (base),                   \
++                "i" (op));
 +
++#endif /* !_LANGUAGE_ASSEMBLY */
 +
-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-11-07 01:12:51.835810500 +0100
-@@ -0,0 +1,38 @@
++#endif        /* _MISPINC_H */
+diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h
+--- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2005-12-15 15:35:08.321801750 +0100
+@@ -0,0 +1,42 @@
 +/*
-+ * OS Independent Layer
++ * OS Abstraction Layer
 + * 
-+ * 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.   
++ * 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$
 + */
 +
 +#ifndef _osl_h_
 +#define _osl_h_
 +
-+#ifdef V2_HAL
-+#include <v2hal_osl.h>
-+#elif defined(linux)
++/* osl handle type forward declaration */
++typedef struct os_handle osl_t;
++
++#if defined(linux)
 +#include <linux_osl.h>
-+#elif PMON
-+#include <pmon_osl.h>
 +#elif defined(NDIS)
 +#include <ndis_osl.h>
 +#elif defined(_CFE_)
 +#include <cfe_osl.h>
-+#elif defined(MACOS9)
-+#include <macos9_osl.h>
++#elif defined(_HNDRTE_)
++#include <hndrte_osl.h>
++#elif defined(_MINOSL_)
++#include <min_osl.h>
++#elif PMON
++#include <pmon_osl.h>
 +#elif defined(MACOSX)
 +#include <macosx_osl.h>
 +#else
@@ -9549,16 +8429,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/osl.h linux-2.6.12.5-brcm/ar
 +
 +/* handy */
 +#define       SET_REG(r, mask, val)   W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
++#define       MAXPRIO         7       /* 0-7 */
 +
 +#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-11-07 01:12:51.835810500 +0100
-@@ -0,0 +1,362 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h
+--- linux.old/arch/mips/bcm947xx/include/pcicfg.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h      2005-12-15 15:36:31.719013750 +0100
+@@ -0,0 +1,398 @@
 +/*
 + * pcicfg.h: PCI configuration  constants and structures.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -9596,7 +8477,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define       PCICFG_BUS_SHIFT        16      /* Bus shift */
 +#define       PCICFG_SLOT_SHIFT       11      /* Slot shift */
 +#define       PCICFG_FUN_SHIFT        8       /* Function shift */
-+#define       PCICFG_OFF_SHIFT        0       /* Bus shift */
++#define       PCICFG_OFF_SHIFT        0       /* Register shift */
 +
 +#define       PCICFG_BUS_MASK         0xff    /* Bus mask */
 +#define       PCICFG_SLOT_MASK        0x1f    /* Slot mask */
@@ -9614,7 +8495,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define       PCI_CONFIG_FUN(a)       (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK)
 +#define       PCI_CONFIG_OFF(a)       (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK)
 +
-+
 +/* The actual config space */
 +
 +#define       PCI_BAR_MAX             6
@@ -9623,6 +8503,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +
 +#define       PCR_RSVDA_MAX           2
 +
++/* pci config status reg has a bit to indicate that capability ptr is present*/
++
++#define PCI_CAPPTR_PRESENT    0x0010
++
 +typedef struct _pci_config_regs {
 +    unsigned short    vendor;
 +    unsigned short    device;
@@ -9678,6 +8562,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define       PCI_CFG_SVID            0x2c
 +#define       PCI_CFG_SSID            0x2e
 +#define       PCI_CFG_ROMBAR          0x30
++#define PCI_CFG_CAPPTR                0x34
 +#define       PCI_CFG_INT             0x3c
 +#define       PCI_CFG_PIN             0x3d
 +#define       PCI_CFG_MINGNT          0x3e
@@ -9886,7 +8771,32 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +    unsigned char     dev_dep[192];
 +} ppb_config_regs;
 +
-+/* Eveything below is BRCM HND proprietary */
++
++/* PCI CAPABILITY DEFINES */
++#define PCI_CAP_POWERMGMTCAP_ID               0x01
++#define PCI_CAP_MSICAP_ID             0x05
++
++/* Data structure to define the Message Signalled Interrupt facility 
++ * Valid for PCI and PCIE configurations */
++typedef struct _pciconfig_cap_msi {
++      unsigned char capID;
++      unsigned char nextptr;
++      unsigned short msgctrl;
++      unsigned int msgaddr;
++} pciconfig_cap_msi;
++
++/* Data structure to define the Power managment facility
++ * Valid for PCI and PCIE configurations */
++typedef struct _pciconfig_cap_pwrmgmt {
++      unsigned char capID;
++      unsigned char nextptr;
++      unsigned short pme_cap;
++      unsigned short  pme_sts_ctrl; 
++      unsigned char  pme_bridge_ext;
++      unsigned char  data;
++} pciconfig_cap_pwrmgmt;
++
++/* Everything below is BRCM HND proprietary */
 +
 +#define       PCI_BAR0_WIN            0x80    /* backplane addres space accessed by BAR0 */
 +#define       PCI_BAR1_WIN            0x84    /* backplane addres space accessed by BAR1 */
@@ -9904,9 +8814,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define       PCI_BAR0_SPROM_OFFSET   (4 * 1024)      /* bar0 + 4K accesses external sprom */
 +#define       PCI_BAR0_PCIREGS_OFFSET (6 * 1024)      /* bar0 + 6K accesses pci core registers */
 +
++/* PCI_INT_STATUS */
++#define       PCI_SBIM_STATUS_SERR    0x4     /* backplane SBErr interrupt status */
++
 +/* PCI_INT_MASK */
 +#define       PCI_SBIM_SHIFT          8       /* backplane core interrupt mask bits offset */
 +#define       PCI_SBIM_MASK           0xff00  /* backplane core interrupt mask */
++#define       PCI_SBIM_MASK_SERR      0x4     /* backplane SBErr interrupt mask */
 +
 +/* PCI_SPROM_CONTROL */
 +#define       SPROM_BLANK             0x04    /* indicating a blank sprom */
@@ -9916,693 +8830,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/pcicfg.h linux-2.6.12.5-brcm
 +#define       SPROM_SIZE              256     /* sprom size in 16-bit */
 +#define SPROM_CRC_RANGE               64      /* crc cover range in 16-bit */
 +
-+#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-11-07 01:12:51.835810500 +0100
-@@ -0,0 +1,679 @@
-+/*
-+ * 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.   
-+ *
-+ * Fundamental types and constants relating to 802.11 
-+ *
-+ * $Id$
-+ */
-+
-+#ifndef _802_11_H_
-+#define _802_11_H_
-+
-+#ifndef _TYPEDEFS_H_
-+#include <typedefs.h>
-+#endif
-+
-+#ifndef _NET_ETHERNET_H_
-+#include <proto/ethernet.h>
-+#endif
-+
-+/* enable structure packing */
-+#if !defined(__GNUC__)
-+#pragma pack(1)
-+#endif
-+
-+/* some platforms require stronger medicine */
-+#if defined(__GNUC__)
-+#define       PACKED  __attribute__((packed))
-+#else
-+#define       PACKED
-+#endif
-+
-+
-+#define DOT11_TU_TO_US                        1024    /* 802.11 Time Unit is 1024 microseconds */
-+
-+/* Generic 802.11 frame constants */
-+#define DOT11_A3_HDR_LEN              24
-+#define DOT11_A4_HDR_LEN              30
-+#define DOT11_MAC_HDR_LEN             DOT11_A3_HDR_LEN
-+#define DOT11_FCS_LEN                 4
-+#define DOT11_ICV_LEN                 4
-+#define DOT11_ICV_AES_LEN             8
-+
-+
-+#define DOT11_KEY_INDEX_SHIFT         6
-+#define DOT11_IV_LEN                  4
-+#define DOT11_IV_TKIP_LEN             8
-+#define DOT11_IV_AES_OCB_LEN          4
-+#define DOT11_IV_AES_CCM_LEN          8
-+
-+#define DOT11_MAX_MPDU_BODY_LEN               2312
-+#define DOT11_MAX_MPDU_LEN            2346    /* body len + A4 hdr + FCS */
-+#define DOT11_MAX_SSID_LEN            32
-+
-+/* dot11RTSThreshold */
-+#define DOT11_DEFAULT_RTS_LEN         2347
-+#define DOT11_MAX_RTS_LEN             2347
-+
-+/* dot11FragmentationThreshold */
-+#define DOT11_MIN_FRAG_LEN            256
-+#define DOT11_MAX_FRAG_LEN            2346    /* Max frag is also limited by aMPDUMaxLength of the attached PHY */
-+#define DOT11_DEFAULT_FRAG_LEN                2346
-+
-+/* dot11BeaconPeriod */
-+#define DOT11_MIN_BEACON_PERIOD               1
-+#define DOT11_MAX_BEACON_PERIOD               0xFFFF
-+
-+/* dot11DTIMPeriod */
-+#define DOT11_MIN_DTIM_PERIOD         1
-+#define DOT11_MAX_DTIM_PERIOD         0xFF
-+
-+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */
-+#define DOT11_LLC_SNAP_HDR_LEN        8
-+#define DOT11_OUI_LEN                 3
-+struct dot11_llc_snap_header {
-+      uint8   dsap;                           /* always 0xAA */
-+      uint8   ssap;                           /* always 0xAA */
-+      uint8   ctl;                            /* always 0x03 */
-+      uint8   oui[DOT11_OUI_LEN];             /* RFC1042: 0x00 0x00 0x00
-+                                                 Bridge-Tunnel: 0x00 0x00 0xF8 */
-+      uint16  type;                           /* ethertype */
-+} PACKED;
-+
-+/* RFC1042 header used by 802.11 per 802.1H */
-+#define RFC1042_HDR_LEN                       (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN)
-+
-+/* Generic 802.11 MAC header */
-+/*
-+ * N.B.: This struct reflects the full 4 address 802.11 MAC header.
-+ *             The fields are defined such that the shorter 1, 2, and 3
-+ *             address headers just use the first k fields.
-+ */
-+struct dot11_header {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       a1;             /* address 1 */
-+      struct ether_addr       a2;             /* address 2 */
-+      struct ether_addr       a3;             /* address 3 */
-+      uint16                  seq;            /* sequence control */
-+      struct ether_addr       a4;             /* address 4 */
-+} PACKED;
-+
-+/* Control frames */
-+
-+struct dot11_rts_frame {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       ra;             /* receiver address */
-+      struct ether_addr       ta;             /* transmitter address */
-+} PACKED;
-+#define       DOT11_RTS_LEN           16
-+
-+struct dot11_cts_frame {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       ra;             /* receiver address */
-+} PACKED;
-+#define       DOT11_CTS_LEN           10
-+
-+struct dot11_ack_frame {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       ra;             /* receiver address */
-+} PACKED;
-+#define       DOT11_ACK_LEN           10
-+
-+struct dot11_ps_poll_frame {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* AID */
-+      struct ether_addr       bssid;          /* receiver address, STA in AP */
-+      struct ether_addr       ta;             /* transmitter address */
-+} PACKED;
-+#define       DOT11_PS_POLL_LEN       16
-+
-+struct dot11_cf_end_frame {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       ra;             /* receiver address */
-+      struct ether_addr       bssid;          /* transmitter address, STA in AP */
-+} PACKED;
-+#define       DOT11_CS_END_LEN        16
-+
-+/* Management frame header */
-+struct dot11_management_header {
-+      uint16                  fc;             /* frame control */
-+      uint16                  durid;          /* duration/ID */
-+      struct ether_addr       da;             /* receiver address */
-+      struct ether_addr       sa;             /* transmitter address */
-+      struct ether_addr       bssid;          /* BSS ID */
-+      uint16                  seq;            /* sequence control */
-+} PACKED;
-+#define       DOT11_MGMT_HDR_LEN      24
-+
-+/* Management frame payloads */
-+
-+struct dot11_bcn_prb {
-+      uint32                  timestamp[2];
-+      uint16                  beacon_interval;
-+      uint16                  capability;
-+} PACKED;
-+#define       DOT11_BCN_PRB_LEN       12
-+
-+struct dot11_auth {
-+      uint16                  alg;            /* algorithm */
-+      uint16                  seq;            /* sequence control */
-+      uint16                  status;         /* status code */
-+} PACKED;
-+#define DOT11_AUTH_FIXED_LEN  6               /* length of auth frame without challenge info elt */
-+
-+struct dot11_assoc_req {
-+      uint16                  capability;     /* capability information */
-+      uint16                  listen;         /* listen interval */
-+} PACKED;
-+
-+struct dot11_assoc_resp {
-+      uint16                  capability;     /* capability information */
-+      uint16                  status;         /* status code */
-+      uint16                  aid;            /* association ID */
-+} PACKED;
-+
-+struct dot11_action_measure {
-+      uint8   category;
-+      uint8   action;
-+      uint8   token;
-+      uint8   data[1];
-+} PACKED;
-+#define DOT11_ACTION_MEASURE_LEN      3
-+
-+/**************
-+  802.11h related definitions.
-+**************/
-+typedef struct {
-+      uint8 id;
-+      uint8 len;
-+      uint8 power;
-+} dot11_power_cnst_t;
-+
-+typedef struct {
-+      uint8 min;
-+      uint8 max;
-+} dot11_power_cap_t;
-+
-+typedef struct {
-+      uint8 id;
-+      uint8 len;
-+      uint8 tx_pwr;
-+      uint8 margin;
-+} dot11_tpc_rep_t;
-+#define DOT11_MNG_IE_TPC_REPORT_LEN   2       /* length of IE data, not including 2 byte header */
-+
-+typedef struct {
-+      uint8 id;
-+      uint8 len;
-+      uint8 first_channel;
-+      uint8 num_channels;
-+} dot11_supp_channels_t;
-+
-+struct dot11_channel_switch {
-+      uint8 id;
-+      uint8 len;
-+      uint8 mode;
-+      uint8 channel;
-+      uint8 count;
-+}  PACKED;
-+typedef struct dot11_channel_switch dot11_channel_switch_t;
-+
-+/* 802.11h Measurement Request/Report IEs */
-+/* Measurement Type field */
-+#define DOT11_MEASURE_TYPE_BASIC      0
-+#define DOT11_MEASURE_TYPE_CCA                1
-+#define DOT11_MEASURE_TYPE_RPI                2
-+
-+/* Measurement Mode field */
-+
-+/* Measurement Request Modes */
-+#define DOT11_MEASURE_MODE_ENABLE     (1<<1)
-+#define DOT11_MEASURE_MODE_REQUEST    (1<<2)
-+#define DOT11_MEASURE_MODE_REPORT     (1<<3)
-+/* Measurement Report Modes */
-+#define DOT11_MEASURE_MODE_LATE       (1<<0)
-+#define DOT11_MEASURE_MODE_INCAPABLE  (1<<1)
-+#define DOT11_MEASURE_MODE_REFUSED    (1<<2)
-+/* Basic Measurement Map bits */
-+#define DOT11_MEASURE_BASIC_MAP_BSS   ((uint8)(1<<0))
-+#define DOT11_MEASURE_BASIC_MAP_OFDM  ((uint8)(1<<1))
-+#define DOT11_MEASURE_BASIC_MAP_UKNOWN        ((uint8)(1<<2))
-+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3))
-+#define DOT11_MEASURE_BASIC_MAP_UNMEAS        ((uint8)(1<<4))
-+
-+typedef struct {
-+      uint8 id;
-+      uint8 len;
-+      uint8 token;
-+      uint8 mode;
-+      uint8 type;
-+      uint8 channel;
-+      uint8 start_time[8];
-+      uint16 duration;
-+} dot11_meas_req_t;
-+#define DOT11_MNG_IE_MREQ_LEN 14
-+/* length of Measure Request IE data not including variable len */
-+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3
-+
-+struct dot11_meas_rep {
-+      uint8 id;
-+      uint8 len;
-+      uint8 token;
-+      uint8 mode;
-+      uint8 type;
-+      union 
-+      {
-+              struct {
-+                      uint8 channel;
-+                      uint8 start_time[8];
-+                      uint16 duration;
-+                      uint8 map;
-+              } PACKED basic;
-+              uint8 data[1];
-+      } PACKED rep;
-+} PACKED;
-+typedef struct dot11_meas_rep dot11_meas_rep_t;
-+
-+/* length of Measure Report IE data not including variable len */
-+#define DOT11_MNG_IE_MREP_FIXED_LEN   3
-+
-+struct dot11_meas_rep_basic {
-+      uint8 channel;
-+      uint8 start_time[8];
-+      uint16 duration;
-+      uint8 map;
-+} PACKED;
-+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t;
-+#define DOT11_MEASURE_BASIC_REP_LEN   12
-+
-+struct dot11_quiet {
-+      uint8 id;
-+      uint8 len;
-+      uint8 count;    /* TBTTs until beacon interval in quiet starts */
-+      uint8 period;   /* Beacon intervals between periodic quiet periods ? */
-+      uint16 duration;/* Length of quiet period, in TU's */
-+      uint16 offset;  /* TU's offset from TBTT in Count field */
-+} PACKED;
-+typedef struct dot11_quiet dot11_quiet_t;
-+
-+typedef struct {
-+      uint8 channel;
-+      uint8 map;
-+} chan_map_tuple_t;
++/* PCI_CFG_CMD_STAT */
++#define PCI_CFG_CMD_STAT_TA   0x08000000      /* target abort status */
 +
-+typedef struct {
-+      uint8 id;
-+      uint8 len;
-+      uint8 eaddr[ETHER_ADDR_LEN];
-+      uint8 interval;
-+      chan_map_tuple_t map[1];
-+} dot11_ibss_dfs_t;
-+
-+
-+/* Macro to take a pointer to a beacon or probe response
-+ * header and return the char* pointer to the SSID info element
-+ */
-+#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN)
-+
-+/* Authentication frame payload constants */
-+#define DOT11_OPEN_SYSTEM     0
-+#define DOT11_SHARED_KEY      1
-+#define DOT11_CHALLENGE_LEN   128
-+
-+/* Frame control macros */
-+#define FC_PVER_MASK          0x3
-+#define FC_PVER_SHIFT         0
-+#define FC_TYPE_MASK          0xC
-+#define FC_TYPE_SHIFT         2
-+#define FC_SUBTYPE_MASK               0xF0
-+#define FC_SUBTYPE_SHIFT      4
-+#define FC_TODS                       0x100
-+#define FC_TODS_SHIFT         8
-+#define FC_FROMDS             0x200
-+#define FC_FROMDS_SHIFT               9
-+#define FC_MOREFRAG           0x400
-+#define FC_MOREFRAG_SHIFT     10
-+#define FC_RETRY              0x800
-+#define FC_RETRY_SHIFT                11
-+#define FC_PM                 0x1000
-+#define FC_PM_SHIFT           12
-+#define FC_MOREDATA           0x2000
-+#define FC_MOREDATA_SHIFT     13
-+#define FC_WEP                        0x4000
-+#define FC_WEP_SHIFT          14
-+#define FC_ORDER              0x8000
-+#define FC_ORDER_SHIFT                15
-+
-+/* sequence control macros */
-+#define SEQNUM_SHIFT          4
-+#define FRAGNUM_MASK          0xF
-+
-+/* Frame Control type/subtype defs */
-+
-+/* FC Types */
-+#define FC_TYPE_MNG           0
-+#define FC_TYPE_CTL           1
-+#define FC_TYPE_DATA          2
-+
-+/* Management Subtypes */
-+#define FC_SUBTYPE_ASSOC_REQ          0
-+#define FC_SUBTYPE_ASSOC_RESP         1
-+#define FC_SUBTYPE_REASSOC_REQ                2
-+#define FC_SUBTYPE_REASSOC_RESP               3
-+#define FC_SUBTYPE_PROBE_REQ          4
-+#define FC_SUBTYPE_PROBE_RESP         5
-+#define FC_SUBTYPE_BEACON             8
-+#define FC_SUBTYPE_ATIM                       9
-+#define FC_SUBTYPE_DISASSOC           10
-+#define FC_SUBTYPE_AUTH                       11
-+#define FC_SUBTYPE_DEAUTH             12
-+#define FC_SUBTYPE_ACTION             13
-+
-+/* Control Subtypes */
-+#define FC_SUBTYPE_PS_POLL            10
-+#define FC_SUBTYPE_RTS                        11
-+#define FC_SUBTYPE_CTS                        12
-+#define FC_SUBTYPE_ACK                        13
-+#define FC_SUBTYPE_CF_END             14
-+#define FC_SUBTYPE_CF_END_ACK         15
-+
-+/* Data Subtypes */
-+#define FC_SUBTYPE_DATA                       0
-+#define FC_SUBTYPE_DATA_CF_ACK                1
-+#define FC_SUBTYPE_DATA_CF_POLL               2
-+#define FC_SUBTYPE_DATA_CF_ACK_POLL   3
-+#define FC_SUBTYPE_NULL                       4
-+#define FC_SUBTYPE_CF_ACK             5
-+#define FC_SUBTYPE_CF_POLL            6
-+#define FC_SUBTYPE_CF_ACK_POLL                7
-+
-+/* type-subtype combos */
-+#define FC_KIND_MASK          (FC_TYPE_MASK | FC_SUBTYPE_MASK)
-+
-+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT))
-+
-+#define FC_ASSOC_REQ  FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ)
-+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP)
-+#define FC_REASSOC_REQ        FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ)
-+#define FC_REASSOC_RESP       FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP)
-+#define FC_PROBE_REQ  FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ)
-+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP)
-+#define FC_BEACON     FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON)
-+#define FC_DISASSOC   FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC)
-+#define FC_AUTH               FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH)
-+#define FC_DEAUTH     FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH)
-+#define FC_ACTION     FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION)
-+
-+#define FC_PS_POLL    FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL)
-+#define FC_RTS                FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS)
-+#define FC_CTS                FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS)
-+#define FC_ACK                FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK)
-+#define FC_CF_END     FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END)
-+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK)
-+
-+#define FC_DATA               FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA)
-+#define FC_NULL_DATA  FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL)
-+#define FC_DATA_CF_ACK        FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK)
-+
-+/* Management Frames */
-+
-+/* Management Frame Constants */
-+
-+/* Fixed fields */
-+#define DOT11_MNG_AUTH_ALGO_LEN               2
-+#define DOT11_MNG_AUTH_SEQ_LEN                2
-+#define DOT11_MNG_BEACON_INT_LEN      2
-+#define DOT11_MNG_CAP_LEN             2
-+#define DOT11_MNG_AP_ADDR_LEN         6
-+#define DOT11_MNG_LISTEN_INT_LEN      2
-+#define DOT11_MNG_REASON_LEN          2
-+#define DOT11_MNG_AID_LEN             2
-+#define DOT11_MNG_STATUS_LEN          2
-+#define DOT11_MNG_TIMESTAMP_LEN               8
-+
-+/* DUR/ID field in assoc resp is 0xc000 | AID */
-+#define DOT11_AID_MASK                        0x3fff
-+
-+/* Reason Codes */
-+#define DOT11_RC_RESERVED                     0
-+#define DOT11_RC_UNSPECIFIED                  1       /* Unspecified reason */
-+#define DOT11_RC_AUTH_INVAL                   2       /* Previous authentication no longer valid */
-+#define DOT11_RC_DEAUTH_LEAVING                       3       /* Deauthenticated because sending station is
-+                                                         leaving (or has left) IBSS or ESS */
-+#define DOT11_RC_INACTIVITY                   4       /* Disassociated due to inactivity */
-+#define DOT11_RC_BUSY                         5       /* Disassociated because AP is unable to handle
-+                                                         all currently associated stations */
-+#define DOT11_RC_INVAL_CLASS_2                        6       /* Class 2 frame received from
-+                                                         nonauthenticated station */
-+#define DOT11_RC_INVAL_CLASS_3                        7       /* Class 3 frame received from
-+                                                         nonassociated station */
-+#define DOT11_RC_DISASSOC_LEAVING             8       /* Disassociated because sending station is
-+                                                         leaving (or has left) BSS */
-+#define DOT11_RC_NOT_AUTH                     9       /* Station requesting (re)association is
-+                                                         not authenticated with responding station */
-+#define DOT11_RC_MAX                          23      /* Reason codes > 23 are reserved */
-+
-+/* Status Codes */
-+#define DOT11_STATUS_SUCCESS                  0       /* Successful */
-+#define DOT11_STATUS_FAILURE                  1       /* Unspecified failure */
-+#define DOT11_STATUS_CAP_MISMATCH             10      /* Cannot support all requested capabilities
-+                                                         in the Capability Information field */
-+#define DOT11_STATUS_REASSOC_FAIL             11      /* Reassociation denied due to inability to
-+                                                         confirm that association exists */
-+#define DOT11_STATUS_ASSOC_FAIL                       12      /* Association denied due to reason outside
-+                                                         the scope of this standard */
-+#define DOT11_STATUS_AUTH_MISMATCH            13      /* Responding station does not support the
-+                                                         specified authentication algorithm */
-+#define DOT11_STATUS_AUTH_SEQ                 14      /* Received an Authentication frame with
-+                                                         authentication transaction sequence number
-+                                                         out of expected sequence */
-+#define DOT11_STATUS_AUTH_CHALLENGE_FAIL      15      /* Authentication rejected because of challenge failure */
-+#define DOT11_STATUS_AUTH_TIMEOUT             16      /* Authentication rejected due to timeout waiting
-+                                                         for next frame in sequence */
-+#define DOT11_STATUS_ASSOC_BUSY_FAIL          17      /* Association denied because AP is unable to
-+                                                         handle additional associated stations */
-+#define DOT11_STATUS_ASSOC_RATE_MISMATCH      18      /* Association denied due to requesting station
-+                                                         not supporting all of the data rates in the
-+                                                         BSSBasicRateSet parameter */
-+#define DOT11_STATUS_ASSOC_SHORT_REQUIRED     19      /* Association denied due to requesting station
-+                                                         not supporting the Short Preamble option */
-+#define DOT11_STATUS_ASSOC_PBCC_REQUIRED      20      /* Association denied due to requesting station
-+                                                         not supporting the PBCC Modulation option */
-+#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED   21      /* Association denied due to requesting station
-+                                                         not supporting the Channel Agility option */
-+#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED  22      /* Association denied because Spectrum Management 
-+                                                         capability is required. */
-+#define DOT11_STATUS_ASSOC_BAD_POWER_CAP      23      /* Association denied because the info in the 
-+                                                         Power Cap element is unacceptable. */
-+#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS   24      /* Association denied because the info in the 
-+                                                         Supported Channel element is unacceptable */
-+#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25      /* Association denied due to requesting station
-+                                                         not supporting the Short Slot Time option */
-+#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED    26      /* Association denied due to requesting station
-+                                                         not supporting the ER-PBCC Modulation option */
-+#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED   27      /* Association denied due to requesting station
-+                                                         not supporting the DSS-OFDM option */
-+
-+/* Info Elts, length of INFORMATION portion of Info Elts */
-+#define DOT11_MNG_DS_PARAM_LEN                        1
-+#define DOT11_MNG_IBSS_PARAM_LEN              2
-+
-+/* TIM Info element has 3 bytes fixed info in INFORMATION field,
-+ * followed by 1 to 251 bytes of Partial Virtual Bitmap */
-+#define DOT11_MNG_TIM_FIXED_LEN                       3
-+#define DOT11_MNG_TIM_DTIM_COUNT              0
-+#define DOT11_MNG_TIM_DTIM_PERIOD             1
-+#define DOT11_MNG_TIM_BITMAP_CTL              2
-+#define DOT11_MNG_TIM_PVB                     3
-+
-+/* TLV defines */
-+#define TLV_TAG_OFF           0
-+#define TLV_LEN_OFF           1
-+#define TLV_HDR_LEN           2
-+#define TLV_BODY_OFF          2
-+
-+/* Management Frame Information Element IDs */
-+#define DOT11_MNG_SSID_ID                     0
-+#define DOT11_MNG_RATES_ID                    1
-+#define DOT11_MNG_FH_PARMS_ID                 2
-+#define DOT11_MNG_DS_PARMS_ID                 3
-+#define DOT11_MNG_CF_PARMS_ID                 4
-+#define DOT11_MNG_TIM_ID                      5
-+#define DOT11_MNG_IBSS_PARMS_ID                       6
-+#define DOT11_MNG_COUNTRY_ID                  7
-+#define DOT11_MNG_HOPPING_PARMS_ID            8
-+#define DOT11_MNG_HOPPING_TABLE_ID            9
-+#define DOT11_MNG_REQUEST_ID                  10
-+#define DOT11_MNG_CHALLENGE_ID                        16
-+#define DOT11_MNG_PWR_CONSTRAINT_ID           32    /* 11H PowerConstraint    */
-+#define DOT11_MNG_PWR_CAP_ID                  33    /* 11H PowerCapability    */
-+#define DOT11_MNG_TPC_REQUEST_ID              34    /* 11H TPC Request        */
-+#define DOT11_MNG_TPC_REPORT_ID                       35    /* 11H TPC Report         */
-+#define DOT11_MNG_SUPP_CHANNELS_ID            36    /* 11H Supported Channels */
-+#define DOT11_MNG_CHANNEL_SWITCH_ID           37    /* 11H ChannelSwitch Announcement*/
-+#define DOT11_MNG_MEASURE_REQUEST_ID          38    /* 11H MeasurementRequest */
-+#define DOT11_MNG_MEASURE_REPORT_ID           39    /* 11H MeasurementReport  */
-+#define DOT11_MNG_QUIET_ID                    40    /* 11H Quiet              */
-+#define DOT11_MNG_IBSS_DFS_ID                 41    /* 11H IBSS_DFS           */
-+#define DOT11_MNG_ERP_ID                      42
-+#define DOT11_MNG_NONERP_ID                   47
-+#define DOT11_MNG_EXT_RATES_ID                        50
-+#define DOT11_MNG_WPA_ID                      221
-+#define DOT11_MNG_PROPR_ID                    221
-+
-+/* ERP info element bit values */
-+#define DOT11_MNG_ERP_LEN                     1       /* ERP is currently 1 byte long */
-+#define DOT11_MNG_NONERP_PRESENT              0x01    /* NonERP (802.11b) STAs are present in the BSS */
-+#define DOT11_MNG_USE_PROTECTION              0x02    /* Use protection mechanisms for ERP-OFDM frames */
-+#define DOT11_MNG_BARKER_PREAMBLE             0x04    /* Short Preambles: 0 == allowed, 1 == not allowed */
-+
-+/* Capability Information Field */
-+#define DOT11_CAP_ESS                         0x0001
-+#define DOT11_CAP_IBSS                                0x0002
-+#define DOT11_CAP_POLLABLE                    0x0004
-+#define DOT11_CAP_POLL_RQ                     0x0008
-+#define DOT11_CAP_PRIVACY                     0x0010
-+#define DOT11_CAP_SHORT                               0x0020
-+#define DOT11_CAP_PBCC                                0x0040
-+#define DOT11_CAP_AGILITY                     0x0080
-+#define DOT11_CAP_SPECTRUM                    0x0100
-+#define DOT11_CAP_SHORTSLOT                   0x0400
-+#define DOT11_CAP_CCK_OFDM                    0x2000
-+
-+/* Action Frame Constants */
-+#define DOT11_ACTION_CAT_ERR_MASK     0x10
-+#define DOT11_ACTION_CAT_SPECT_MNG    0x00
-+
-+#define DOT11_ACTION_ID_M_REQ         0
-+#define DOT11_ACTION_ID_M_REP         1
-+#define DOT11_ACTION_ID_TPC_REQ               2
-+#define DOT11_ACTION_ID_TPC_REP               3
-+#define DOT11_ACTION_ID_CHANNEL_SWITCH        4
-+
-+/* MLME Enumerations */
-+#define DOT11_BSSTYPE_INFRASTRUCTURE          0
-+#define DOT11_BSSTYPE_INDEPENDENT             1
-+#define DOT11_BSSTYPE_ANY                     2
-+#define DOT11_SCANTYPE_ACTIVE                 0
-+#define DOT11_SCANTYPE_PASSIVE                        1
-+
-+/* 802.11 A PHY constants */
-+#define APHY_SLOT_TIME                9
-+#define APHY_SIFS_TIME                16
-+#define APHY_DIFS_TIME                (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME))
-+#define APHY_PREAMBLE_TIME    16
-+#define APHY_SIGNAL_TIME      4
-+#define APHY_SYMBOL_TIME      4
-+#define APHY_SERVICE_NBITS    16
-+#define APHY_TAIL_NBITS               6
-+#define       APHY_CWMIN              15
-+
-+/* 802.11 B PHY constants */
-+#define BPHY_SLOT_TIME                20
-+#define BPHY_SIFS_TIME                10
-+#define BPHY_DIFS_TIME                50
-+#define BPHY_PLCP_TIME                192
-+#define BPHY_PLCP_SHORT_TIME  96
-+#define       BPHY_CWMIN              31
-+
-+/* 802.11 G constants */
-+#define DOT11_OFDM_SIGNAL_EXTENSION   6
-+
-+#define PHY_CWMAX             1023
-+
-+#define       DOT11_MAXNUMFRAGS       16      /* max # fragments per MSDU */
-+
-+/* dot11Counters Table - 802.11 spec., Annex D */
-+typedef struct d11cnt {
-+      uint32          txfrag;         /* dot11TransmittedFragmentCount */
-+      uint32          txmulti;        /* dot11MulticastTransmittedFrameCount */
-+      uint32          txfail;         /* dot11FailedCount */
-+      uint32          txretry;        /* dot11RetryCount */
-+      uint32          txretrie;       /* dot11MultipleRetryCount */
-+      uint32          rxdup;          /* dot11FrameduplicateCount */
-+      uint32          txrts;          /* dot11RTSSuccessCount */
-+      uint32          txnocts;        /* dot11RTSFailureCount */
-+      uint32          txnoack;        /* dot11ACKFailureCount */
-+      uint32          rxfrag;         /* dot11ReceivedFragmentCount */
-+      uint32          rxmulti;        /* dot11MulticastReceivedFrameCount */
-+      uint32          rxcrc;          /* dot11FCSErrorCount */
-+      uint32          txfrmsnt;       /* dot11TransmittedFrameCount */
-+      uint32          rxundec;        /* dot11WEPUndecryptableCount */
-+} d11cnt_t;
-+
-+/* BRCM OUI */
-+#define BRCM_OUI              "\x00\x10\x18"
-+
-+/* WPA definitions */
-+#define WPA_VERSION           1
-+#define WPA_OUI                       "\x00\x50\xF2"
-+
-+#define WPA_OUI_LEN   3
-+
-+/* WPA authentication modes */
-+#define WPA_AUTH_NONE         0       /* None */
-+#define WPA_AUTH_UNSPECIFIED  1       /* Unspecified authentication over 802.1X: default for WPA */
-+#define WPA_AUTH_PSK          2       /* Pre-shared Key over 802.1X */
-+#define WPA_AUTH_DISABLED     255     /* Legacy (i.e., non-WPA) */
-+                               
-+#define IS_WPA_AUTH(auth)     ((auth) == WPA_AUTH_NONE || \
-+                               (auth) == WPA_AUTH_UNSPECIFIED || \
-+                               (auth) == WPA_AUTH_PSK)
-+
-+
-+/* Key related defines */
-+#define DOT11_MAX_KEY_SIZE    32      /* max size of any key */
-+#define DOT11_MAX_IV_SIZE     16      /* max size of any IV */
-+#define DOT11_EXT_IV_FLAG     (1<<5)  /* flag to indicate IV is > 4 bytes */
-+
-+#define WEP1_KEY_SIZE         5       /* max size of any WEP key */
-+#define WEP1_KEY_HEX_SIZE     10      /* size of WEP key in hex. */
-+#define WEP128_KEY_SIZE               13      /* max size of any WEP key */
-+#define WEP128_KEY_HEX_SIZE   26      /* size of WEP key in hex. */
-+#define TKIP_MIC_SIZE         8       /* size of TKIP MIC */
-+#define TKIP_EOM_SIZE         7       /* max size of TKIP EOM */
-+#define TKIP_EOM_FLAG         0x5a    /* TKIP EOM flag byte */
-+#define TKIP_KEY_SIZE         32      /* size of any TKIP key */
-+#define TKIP_MIC_AUTH_TX      16      /* offset to Authenticator MIC TX key */
-+#define TKIP_MIC_AUTH_RX      24      /* offset to Authenticator MIC RX key */
-+#define TKIP_MIC_SUP_RX               16      /* offset to Supplicant MIC RX key */
-+#define TKIP_MIC_SUP_TX               24      /* offset to Supplicant MIC TX key */
-+#define AES_KEY_SIZE          16      /* size of AES key */
-+
-+#undef PACKED
-+#if !defined(__GNUC__)
-+#pragma pack()
 +#endif
-+
-+#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-11-07 01:12:51.835810500 +0100
+diff -urN linux.old/arch/mips/bcm947xx/include/proto/ethernet.h linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h
+--- linux.old/arch/mips/bcm947xx/include/proto/ethernet.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h      2005-12-15 12:57:27.869191250 +0100
 @@ -0,0 +1,145 @@
 +/*******************************************************************************
 + * $Id$
@@ -10744,87 +8978,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.6.1
 +                          ((uint8 *)(ea))[2] |                \
 +                          ((uint8 *)(ea))[3] |                \
 +                          ((uint8 *)(ea))[4] |                \
-+                          ((uint8 *)(ea))[5]) == 0)
-+
-+#undef PACKED
-+
-+#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-11-07 01:12:51.835810500 +0100
-@@ -0,0 +1,69 @@
-+/*******************************************************************************
-+ * $Id$
-+ * 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.   
-+ * crc.h - a function to compute crc for iLine10 headers
-+ ******************************************************************************/
-+
-+#ifndef _RTS_CRC_H_
-+#define _RTS_CRC_H_ 1
-+
-+#include "typedefs.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+
-+#define CRC8_INIT_VALUE  0xff       /* Initial CRC8 checksum value */
-+#define CRC8_GOOD_VALUE  0x9f       /* Good final CRC8 checksum value */
-+#define HCS_GOOD_VALUE   0x39       /* Good final header checksum value */
-+
-+#define CRC16_INIT_VALUE 0xffff     /* Initial CRC16 checksum value */
-+#define CRC16_GOOD_VALUE 0xf0b8     /* Good final CRC16 checksum value */
-+
-+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */
-+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */
-+
-+void   hcs(uint8 *, uint);
-+uint8  crc8(uint8 *, uint, uint8);
-+uint16 crc16(uint8 *, uint, uint16);
-+uint32 crc32(uint8 *, uint, uint32);
-+
-+/* macros for common usage */
-+
-+#define APPEND_CRC8(pbytes, nbytes)                           \
-+do {                                                          \
-+    uint8 tmp = crc8(pbytes, nbytes, CRC8_INIT_VALUE) ^ 0xff; \
-+    (pbytes)[(nbytes)] = tmp;                                 \
-+    (nbytes) += 1;                                            \
-+} while (0)
-+
-+#define APPEND_CRC16(pbytes, nbytes)                               \
-+do {                                                               \
-+    uint16 tmp = crc16(pbytes, nbytes, CRC16_INIT_VALUE) ^ 0xffff; \
-+    (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff;                    \
-+    (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff;                    \
-+    (nbytes) += 2;                                                 \
-+} while (0)
-+
-+#define APPEND_CRC32(pbytes, nbytes)                                   \
-+do {                                                                   \
-+    uint32 tmp = crc32(pbytes, nbytes, CRC32_INIT_VALUE) ^ 0xffffffff; \
-+    (pbytes)[(nbytes) + 0] = (tmp >>  0) & 0xff;                       \
-+    (pbytes)[(nbytes) + 1] = (tmp >>  8) & 0xff;                       \
-+    (pbytes)[(nbytes) + 2] = (tmp >> 16) & 0xff;                       \
-+    (pbytes)[(nbytes) + 3] = (tmp >> 24) & 0xff;                       \
-+    (nbytes) += 4;                                                     \
-+} while (0)
++                          ((uint8 *)(ea))[5]) == 0)
 +
-+#ifdef __cplusplus
-+}
-+#endif
++#undef PACKED
 +
-+#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-11-07 01:12:51.835810500 +0100
++#endif /* _NET_ETHERNET_H_ */
+diff -urN linux.old/arch/mips/bcm947xx/include/s5.h linux.dev/arch/mips/bcm947xx/include/s5.h
+--- linux.old/arch/mips/bcm947xx/include/s5.h  1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/s5.h  2005-12-15 12:57:27.869191250 +0100
 @@ -0,0 +1,103 @@
 +#ifndef _S5_H_
 +#define _S5_H_
@@ -10929,10 +9090,10 @@ 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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,281 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h
+--- linux.old/arch/mips/bcm947xx/include/sbchipc.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h     2005-12-15 15:35:20.458560250 +0100
+@@ -0,0 +1,440 @@
 +/*
 + * SiliconBackplane Chipcommon core hardware definitions.
 + *
@@ -10940,7 +9101,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 + * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
 + * gpio interface, extbus, and support for serial and parallel flashes.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * $Id$
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -10948,13 +9110,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 + *
-+ * $Id$
 + */
 +
 +#ifndef       _SBCHIPC_H
 +#define       _SBCHIPC_H
 +
 +
++#ifndef _LANGUAGE_ASSEMBLY
++
 +/* cpp contortions to concatenate w/arg prescan */
 +#ifndef PAD
 +#define       _PADLINE(line)  pad ## line
@@ -10966,12 +9129,25 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +      uint32  chipid;                 /* 0x0 */
 +      uint32  capabilities;
 +      uint32  corecontrol;            /* corerev >= 1 */
-+      uint32  PAD[5];
++      uint32  bist;
++
++      /* OTP */
++      uint32  otpstatus;              /* 0x10, corerev >= 10 */
++      uint32  otpcontrol;
++      uint32  otpprog;
++      uint32  PAD;
 +
 +      /* Interrupt control */
 +      uint32  intstatus;              /* 0x20 */
 +      uint32  intmask;
-+      uint32  PAD[6];
++      uint32  chipcontrol;            /* 0x28, rev >= 11 */
++      uint32  chipstatus;             /* 0x2c, rev >= 11 */
++
++      /* Jtag Master */
++      uint32  jtagcmd;                /* 0x30, rev >= 10 */
++      uint32  jtagir;
++      uint32  jtagdr;
++      uint32  jtagctrl;
 +
 +      /* serial flash interface registers */
 +      uint32  flashcontrol;           /* 0x40 */
@@ -10980,7 +9156,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +      uint32  PAD[1];
 +
 +      /* Silicon backplane configuration broadcast control */
-+      uint32  broadcastaddress;
++      uint32  broadcastaddress;       /* 0x50 */
 +      uint32  broadcastdata;
 +      uint32  PAD[2];
 +
@@ -10995,7 +9171,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +
 +      /* Watchdog timer */
 +      uint32  watchdog;               /* 0x80 */
-+      uint32  PAD[3];
++      uint32  PAD[1];
++
++      /*GPIO based LED powersave registers corerev >= 16*/
++      uint32  gpiotimerval;           /*0x88 */
++      uint32  gpiotimeroutmask;
 +
 +      /* clock control */
 +      uint32  clockcontrol_n;         /* 0x90 */
@@ -11003,28 +9183,33 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +      uint32  clockcontrol_pci;       /* aka m1 */
 +      uint32  clockcontrol_m2;        /* mii/uart/mipsref */
 +      uint32  clockcontrol_mips;      /* aka m3 */
-+      uint32  uart_clkdiv;            /* corerev >= 3 */
++      uint32  clkdiv;                 /* corerev >= 3 */
 +      uint32  PAD[2];
 +
 +      /* pll delay registers (corerev >= 4) */
 +      uint32  pll_on_delay;           /* 0xb0 */
 +      uint32  fref_sel_delay;
-+      uint32  slow_clk_ctl;
-+      uint32  PAD[17];
++      uint32  slow_clk_ctl;           /* 5 < corerev < 10 */
++      uint32  PAD[1];
++
++      /* Instaclock registers (corerev >= 10) */
++      uint32  system_clk_ctl;         /* 0xc0 */
++      uint32  clkstatestretch;
++      uint32  PAD[14];
 +
 +      /* ExtBus control registers (corerev >= 3) */
-+      uint32  cs01config;             /* 0x100 */
-+      uint32  cs01memwaitcnt;
-+      uint32  cs01attrwaitcnt;
-+      uint32  cs01iowaitcnt;
-+      uint32  cs23config;
-+      uint32  cs23memwaitcnt;
-+      uint32  cs23attrwaitcnt;
-+      uint32  cs23iowaitcnt;
-+      uint32  cs4config;
-+      uint32  cs4waitcnt;
-+      uint32  parallelflashconfig;
-+      uint32  parallelflashwaitcnt;
++      uint32  pcmcia_config;          /* 0x100 */
++      uint32  pcmcia_memwait;
++      uint32  pcmcia_attrwait;
++      uint32  pcmcia_iowait;
++      uint32  ide_config;
++      uint32  ide_memwait;
++      uint32  ide_attrwait;
++      uint32  ide_iowait;
++      uint32  prog_config;
++      uint32  prog_waitcount;
++      uint32  flash_config;
++      uint32  flash_waitcount;
 +      uint32  PAD[116];
 +
 +      /* uarts */
@@ -11048,6 +9233,24 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +      uint8   uart1scratch;
 +} chipcregs_t;
 +
++#endif /* _LANGUAGE_ASSEMBLY */
++
++#define       CC_CHIPID               0
++#define       CC_CAPABILITIES         4
++#define       CC_JTAGCMD              0x30
++#define       CC_JTAGIR               0x34
++#define       CC_JTAGDR               0x38
++#define       CC_JTAGCTRL             0x3c
++#define       CC_WATCHDOG             0x80
++#define       CC_CLKC_N               0x90
++#define       CC_CLKC_M0              0x94
++#define       CC_CLKC_M1              0x98
++#define       CC_CLKC_M2              0x9c
++#define       CC_CLKC_M3              0xa0
++#define       CC_CLKDIV               0xa4
++#define       CC_SYS_CLK_CTL          0xc0
++#define       CC_OTP                  0x800
++
 +/* chipid */
 +#define       CID_ID_MASK             0x0000ffff              /* Chip Id mask */
 +#define       CID_REV_MASK            0x000f0000              /* Chip Revision mask */
@@ -11067,6 +9270,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define       CAP_FLASH_MASK          0x00000700              /* Type of flash */
 +#define       CAP_PLL_MASK            0x00038000              /* Type of PLL */
 +#define CAP_PWR_CTL           0x00040000              /* Power control */
++#define CAP_OTPSIZE           0x00380000              /* OTP Size (0 = none) */
++#define CAP_OTPSIZE_SHIFT     19                      /* OTP Size shift */
++#define CAP_OTPSIZE_BASE      5                       /* OTP Size base */
++#define CAP_JTAGP             0x00400000              /* JTAG Master Present */
++#define CAP_ROM                       0x00800000              /* Internal boot rom active */
 +
 +/* PLL type */
 +#define PLL_NONE              0x00000000
@@ -11074,13 +9282,81 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define PLL_TYPE2             0x00020000              /* 48Mhz, 4 dividers */
 +#define PLL_TYPE3             0x00030000              /* 25Mhz, 2 dividers */
 +#define PLL_TYPE4             0x00008000              /* 48Mhz, 4 dividers */
++#define PLL_TYPE5             0x00018000              /* 25Mhz, 4 dividers */
++#define PLL_TYPE6             0x00028000              /* 100/200 or 120/240 only */
++#define PLL_TYPE7             0x00038000              /* 25Mhz, 4 dividers */
 +
 +/* corecontrol */
 +#define CC_UARTCLKO           0x00000001              /* Drive UART with internal clock */
 +#define       CC_SE                   0x00000002              /* sync clk out enable (corerev >= 3) */
 +
++/* Fields in the otpstatus register */
++#define       OTPS_PROGFAIL           0x80000000
++#define       OTPS_PROTECT            0x00000007
++#define       OTPS_HW_PROTECT         0x00000001
++#define       OTPS_SW_PROTECT         0x00000002
++#define       OTPS_CID_PROTECT        0x00000004
++
++/* Fields in the otpcontrol register */
++#define       OTPC_RECWAIT            0xff000000
++#define       OTPC_PROGWAIT           0x00ffff00
++#define       OTPC_PRW_SHIFT          8
++#define       OTPC_MAXFAIL            0x00000038
++#define       OTPC_VSEL               0x00000006
++#define       OTPC_SELVL              0x00000001
++
++/* Fields in otpprog */
++#define       OTPP_COL_MASK           0x000000ff
++#define       OTPP_ROW_MASK           0x0000ff00
++#define       OTPP_ROW_SHIFT          8
++#define       OTPP_READERR            0x10000000
++#define       OTPP_VALUE              0x20000000
++#define       OTPP_VALUE_SHIFT                29
++#define       OTPP_READ               0x40000000
++#define       OTPP_START              0x80000000
++#define       OTPP_BUSY               0x80000000
++
++/* jtagcmd */
++#define JCMD_START            0x80000000
++#define JCMD_BUSY             0x80000000
++#define JCMD_PAUSE            0x40000000
++#define JCMD0_ACC_MASK                0x0000f000
++#define JCMD0_ACC_IRDR                0x00000000
++#define JCMD0_ACC_DR          0x00001000
++#define JCMD0_ACC_IR          0x00002000
++#define JCMD0_ACC_RESET               0x00003000
++#define JCMD0_ACC_IRPDR               0x00004000
++#define JCMD0_ACC_PDR         0x00005000
++#define JCMD0_IRW_MASK                0x00000f00
++#define JCMD_ACC_MASK         0x000f0000              /* Changes for corerev 11 */
++#define JCMD_ACC_IRDR         0x00000000
++#define JCMD_ACC_DR           0x00010000
++#define JCMD_ACC_IR           0x00020000
++#define JCMD_ACC_RESET                0x00030000
++#define JCMD_ACC_IRPDR                0x00040000
++#define JCMD_ACC_PDR          0x00050000
++#define JCMD_IRW_MASK         0x00001f00
++#define JCMD_IRW_SHIFT                8
++#define JCMD_DRW_MASK         0x0000003f
++
++/* jtagctrl */
++#define JCTRL_FORCE_CLK               4                       /* Force clock */
++#define JCTRL_EXT_EN          2                       /* Enable external targets */
++#define JCTRL_EN              1                       /* Enable Jtag master */
++
++/* Fields in clkdiv */
++#define       CLKD_SFLASH             0x0f000000
++#define       CLKD_SFLASH_SHIFT       24
++#define       CLKD_OTP                0x000f0000
++#define       CLKD_OTP_SHIFT          16
++#define       CLKD_JTAG               0x00000f00
++#define       CLKD_JTAG_SHIFT         8               
++#define       CLKD_UART               0x000000ff
++
 +/* intstatus/intmask */
++#define       CI_GPIO                 0x00000001              /* gpio intr */
 +#define       CI_EI                   0x00000002              /* ro: ext intr pin (corerev >= 3) */
++#define       CI_WDRESET              0x80000000              /* watchdog reset occurred */
 +
 +/* slow_clk_ctl */
 +#define SCC_SS_MASK           0x00000007              /* slow clock source mask */
@@ -11093,13 +9369,27 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define SCC_IP                        0x00001000              /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
 +#define SCC_XC                        0x00002000              /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
 +#define SCC_XP                        0x00004000              /* XtalPU (RO), 1/0: crystal running/disabled */
-+#define SCC_CD_MASK           0xffff0000              /* ClockDivider mask, SlowClk = 1/(4+divisor) * crystal/PCI clock */
-+#define SCC_CD_SHF            16                      /* CLockDivider shift */
++#define SCC_CD_MASK           0xffff0000              /* ClockDivider (SlowClk = 1/(4+divisor)) */
++#define SCC_CD_SHIFT          16
++
++/* system_clk_ctl */
++#define       SYCC_IE                 0x00000001              /* ILPen: Enable Idle Low Power */
++#define       SYCC_AE                 0x00000002              /* ALPen: Enable Active Low Power */
++#define       SYCC_FP                 0x00000004              /* ForcePLLOn */
++#define       SYCC_AR                 0x00000008              /* Force ALP (or HT if ALPen is not set */
++#define       SYCC_HR                 0x00000010              /* Force HT */
++#define SYCC_CD_MASK          0xffff0000              /* ClkDiv  (ILP = 1/(4+divisor)) */
++#define SYCC_CD_SHIFT         16
++
++/* gpiotimerval*/
++#define GPIO_ONTIME_SHIFT     16
 +
 +/* clockcontrol_n */
 +#define       CN_N1_MASK              0x3f                    /* n1 control */
 +#define       CN_N2_MASK              0x3f00                  /* n2 control */
 +#define       CN_N2_SHIFT             8
++#define       CN_PLLC_MASK            0xf0000                 /* pll control */
++#define       CN_PLLC_SHIFT           16
 +
 +/* clockcontrol_sb/pci/uart */
 +#define       CC_M1_MASK              0x3f                    /* m1 control */
@@ -11110,12 +9400,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define       CC_MC_MASK              0x1f000000              /* mux control */
 +#define       CC_MC_SHIFT             24
 +
-+/* N3M Clock control values for 125Mhz */
-+#define       CC_125_N                0x0802                  /* Default values for bcm4310 */
-+#define       CC_125_M                0x04020009
-+#define       CC_125_M25              0x11090009
-+#define       CC_125_M33              0x11090005
-+
 +/* N3M Clock control magic field values */
 +#define       CC_F6_2                 0x02                    /* A factor of 2 in */
 +#define       CC_F6_3                 0x03                    /* 6-bit fields like */
@@ -11140,8 +9424,19 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define       CC_T2MC_M2BYP           2
 +#define       CC_T2MC_M3BYP           4
 +
++/* Type 6 Clock control magic field values */
++#define       CC_T6_MMASK             1                       /* bits of interest in m */
++#define       CC_T6_M0                120000000               /* sb clock for m = 0 */
++#define       CC_T6_M1                100000000               /* sb clock for m = 1 */
++#define       SB2MIPS_T6(sb)          (2 * (sb))
++
 +/* Common clock base */
-+#define       CC_CLOCK_BASE           24000000                /* Half the clock freq */
++#define       CC_CLOCK_BASE1          24000000                /* Half the clock freq */
++#define CC_CLOCK_BASE2                12500000                /* Alternate crystal on some PLL's */
++
++/* Clock control values for 200Mhz in 5350 */
++#define       CLKC_5350_N             0x0311
++#define       CLKC_5350_M             0x04020009
 +
 +/* Flash types in the chipcommon capabilities register */
 +#define FLASH_NONE            0x000           /* No flash */
@@ -11213,21 +9508,46 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbchipc.h linux-2.6.12.5-brc
 +#define SFLASH_AT_ID_MASK                     0x38
 +#define SFLASH_AT_ID_SHIFT                    3
 +
++/* OTP regions */
++#define       OTP_HW_REGION   OTPS_HW_PROTECT
++#define       OTP_SW_REGION   OTPS_SW_PROTECT
++#define       OTP_CID_REGION  OTPS_CID_PROTECT
++
++/* OTP regions (Byte offsets from otp size) */
++#define       OTP_SWLIM_OFF   (-8)
++#define       OTP_CIDBASE_OFF 0
++#define       OTP_CIDLIM_OFF  8
++
++/* Predefined OTP words (Word offset from otp size) */
++#define       OTP_BOUNDARY_OFF (-4)
++#define       OTP_HWSIGN_OFF  (-3)
++#define       OTP_SWSIGN_OFF  (-2)
++#define       OTP_CIDSIGN_OFF (-1)
++
++#define       OTP_CID_OFF     0
++#define       OTP_PKG_OFF     1
++#define       OTP_FID_OFF     2
++#define       OTP_RSV_OFF     3
++#define       OTP_LIM_OFF     4
++
++#define       OTP_SIGNATURE   0x578a
++#define       OTP_MAGIC       0x4e56
++
 +#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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,296 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h
+--- linux.old/arch/mips/bcm947xx/include/sbconfig.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h    2005-12-15 15:35:24.538815250 +0100
+@@ -0,0 +1,342 @@
 +/*
 + * Broadcom SiliconBackplane hardware register definitions.
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -11246,16 +9566,27 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 + * All regions may not exist on all chips.
 + */
 +#define SB_SDRAM_BASE         0x00000000      /* Physical SDRAM */
-+#define SB_PCI_MEM            0x08000000      /* Host Mode PCI memory access space (64 MB) */
-+#define SB_PCI_CFG            0x0c000000      /* Host Mode PCI configuration space (64 MB) */
++#define SB_PCI_MEM            0x08000000      /* Host Mode sb2pcitranslation0 (64 MB) */
++#define SB_PCI_CFG            0x0c000000      /* Host Mode sb2pcitranslation1 (64 MB) */
 +#define       SB_SDRAM_SWAPPED        0x10000000      /* Byteswapped Physical SDRAM */
 +#define SB_ENUM_BASE          0x18000000      /* Enumeration space base */
 +#define       SB_ENUM_LIM             0x18010000      /* Enumeration space limit */
++
++#define       SB_FLASH2               0x1c000000      /* Flash Region 2 (region 1 shadowed here) */
++#define       SB_FLASH2_SZ            0x02000000      /* Size of Flash Region 2 */
++
 +#define       SB_EXTIF_BASE           0x1f000000      /* External Interface region base address */
-+#define SB_PCI_DMA            0x40000000      /* Client Mode PCI memory access space (1 GB) */
++#define       SB_FLASH1               0x1fc00000      /* Flash Region 1 */
++#define       SB_FLASH1_SZ            0x00400000      /* Size of Flash Region 1 */
++
++#define SB_PCI_DMA            0x40000000      /* Client Mode sb2pcitranslation2 (1 GB) */
++#define SB_PCI_DMA_SZ         0x40000000      /* Client Mode sb2pcitranslation2 size in bytes */
++#define SB_PCIE_DMA_L32               0x00000000      /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
++#define SB_PCIE_DMA_H32               0x80000000      /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
 +#define       SB_EUART                (SB_EXTIF_BASE + 0x00800000)
 +#define       SB_LED                  (SB_EXTIF_BASE + 0x00900000)
 +
++
 +/* enumeration space related defs */
 +#define SB_CORE_SIZE          0x1000          /* each core gets 4Kbytes for registers */
 +#define       SB_MAXCORES             ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE)
@@ -11268,8 +9599,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +/*
 + * Sonics Configuration Space Registers.
 + */
-+#ifdef _LANGUAGE_ASSEMBLY
-+
 +#define SBIPSFLAG             0x08
 +#define SBTPSFLAG             0x18
 +#define       SBTMERRLOGA             0x48            /* sonics >= 2.3 */
@@ -11294,8 +9623,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define SBIDLOW                       0xf8
 +#define SBIDHIGH              0xfc
 +
-+
-+#else
++#ifndef _LANGUAGE_ASSEMBLY
 +
 +typedef volatile struct _sbconfig {
 +      uint32  PAD[2];
@@ -11373,7 +9701,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +
 +/* sbtmstatelow */
 +#define       SBTML_RESET             0x1             /* reset */
-+#define       SBTML_REJ               0x2             /* reject */
++#define       SBTML_REJ_MASK          0x6             /* reject */
++#define       SBTML_REJ_SHIFT         1
 +#define       SBTML_CLK               0x10000         /* clock enable */
 +#define       SBTML_FGC               0x20000         /* force gated clocks on */
 +#define       SBTML_FL_MASK           0x3ffc0000      /* core-specific flags */
@@ -11386,10 +9715,12 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define       SBTMH_BUSY              0x4             /* busy */
 +#define       SBTMH_TO                0x00000020      /* timeout (sonics >= 2.3) */
 +#define       SBTMH_FL_MASK           0x1fff0000      /* core-specific flags */
++#define SBTMH_DMA64           0x10000000      /* supports DMA with 64-bit addresses */
 +#define       SBTMH_GCR               0x20000000      /* gated clock request */
 +#define       SBTMH_BISTF             0x40000000      /* bist failed */
 +#define       SBTMH_BISTD             0x80000000      /* bist done */
 +
++
 +/* sbbwa0 */
 +#define       SBBWA_TAB0_MASK         0xffff          /* lookup table 0 */
 +#define       SBBWA_TAB1_MASK         0xffff          /* lookup table 1 */
@@ -11477,10 +9808,16 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define       SBIDL_IP_SHIFT          24
 +#define       SBIDL_RV_MASK           0xf0000000      /* sonics backplane revision code */
 +#define       SBIDL_RV_SHIFT          28
++#define       SBIDL_RV_2_2            0x00000000      /* version 2.2 or earlier */
++#define       SBIDL_RV_2_3            0x10000000      /* version 2.3 */
 +
 +/* sbidhigh */
-+#define       SBIDH_RC_MASK           0xf             /* revision code*/
-+#define       SBIDH_CC_MASK           0xfff0          /* core code */
++#define       SBIDH_RC_MASK           0x000f          /* revision code */
++#define       SBIDH_RCE_MASK          0x7000          /* revision code extension field */
++#define       SBIDH_RCE_SHIFT         8
++#define       SBCOREREV(sbidh) \
++      ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK))
++#define       SBIDH_CC_MASK           0x8ff0          /* core code */
 +#define       SBIDH_CC_SHIFT          4
 +#define       SBIDH_VC_MASK           0xffff0000      /* vendor code */
 +#define       SBIDH_VC_SHIFT          16
@@ -11499,9 +9836,11 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define       SB_ENET                 0x806           /* enet mac core */
 +#define       SB_CODEC                0x807           /* v90 codec core */
 +#define       SB_USB                  0x808           /* usb 1.1 host/device core */
++#define       SB_ADSL                 0x809           /* ADSL core */
 +#define       SB_ILINE100             0x80a           /* iline100 core */
 +#define       SB_IPSEC                0x80b           /* ipsec core */
 +#define       SB_PCMCIA               0x80d           /* pcmcia core */
++#define       SB_SOCRAM               0x80e           /* internal memory core */
 +#define       SB_MEMC                 0x80f           /* memc sdram core */
 +#define       SB_EXTIF                0x811           /* external interface core */
 +#define       SB_D11                  0x812           /* 802.11 MAC core */
@@ -11509,14 +9848,41 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbconfig.h linux-2.6.12.5-br
 +#define       SB_USB11H               0x817           /* usb 1.1 host core */
 +#define       SB_USB11D               0x818           /* usb 1.1 device core */
 +#define       SB_USB20H               0x819           /* usb 2.0 host core */
-+#define       SB_USB20D               0x81A           /* usb 2.0 device core */
-+#define       SB_SDIOH                0x81B           /* sdio host core */
-+#define SB_ROBO                 0x81C           /* robo switch core */
++#define       SB_USB20D               0x81a           /* usb 2.0 device core */
++#define       SB_SDIOH                0x81b           /* sdio host core */
++#define       SB_ROBO                 0x81c           /* roboswitch core */
++#define       SB_ATA100               0x81d           /* parallel ATA core */
++#define       SB_SATAXOR              0x81e           /* serial ATA & XOR DMA core */
++#define       SB_GIGETH               0x81f           /* gigabit ethernet core */
++#define       SB_PCIE                 0x820           /* pci express core */
++#define       SB_SRAMC                0x822           /* SRAM controller core */
++#define       SB_MINIMAC              0x823           /* MINI MAC/phy core */
++
++#define       SB_CC_IDX               0               /* chipc, when present, is always core 0 */
++
++/* Not really related to Silicon Backplane, but a couple of software
++ * conventions for the use the flash space:
++ */
++
++/* Minumum amount of flash we support */
++#define FLASH_MIN             0x00020000      /* Minimum flash size */
++
++/* A boot/binary may have an embedded block that describes its size  */
++#define       BISZ_OFFSET             0x3e0           /* At this offset into the binary */
++#define       BISZ_MAGIC              0x4249535a      /* Marked with this value: 'BISZ' */
++#define       BISZ_MAGIC_IDX          0               /* Word 0: magic */
++#define       BISZ_TXTST_IDX          1               /*      1: text start */
++#define       BISZ_TXTEND_IDX         2               /*      2: text start */
++#define       BISZ_DATAST_IDX         3               /*      3: text start */
++#define       BISZ_DATAEND_IDX        4               /*      4: text start */
++#define       BISZ_BSSST_IDX          5               /*      5: text start */
++#define       BISZ_BSSEND_IDX         6               /*      6: text start */
++#define BISZ_SIZE             7               /* descriptor size in 32-bit intergers */
 +
 +#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-11-07 01:12:51.839810750 +0100
+diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h
+--- linux.old/arch/mips/bcm947xx/include/sbextif.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h     2005-12-15 16:48:55.651993750 +0100
 @@ -0,0 +1,242 @@
 +/*
 + * Hardware-specific External Interface I/O core definitions
@@ -11532,13 +9898,13 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brc
 + * The external interface core also contains 2 on-chip 16550 UARTs, clock
 + * frequency control, a watchdog interrupt timer, and a GPIO interface.
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -11760,20 +10126,21 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbextif.h linux-2.6.12.5-brc
 +#define       CC_CLOCK_BASE   24000000        /* Half the clock freq. in the 4710 */
 +
 +#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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,144 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h
+--- linux.old/arch/mips/bcm947xx/include/sbmemc.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h      2005-12-15 15:35:31.567254500 +0100
+@@ -0,0 +1,148 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions.
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -11839,7 +10206,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm
 +
 +/* For sdr: */
 +#define MEMC_SD_CONFIG_INIT   0x00048000
-+#define MEMC_SD_DRAMTIM_INIT  0x000754da
++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8
++#define MEMC_SD_DRAMTIM3_INIT 0x000754da
 +#define MEMC_SD_RDNCDLCOR_INIT        0x00000000
 +#define MEMC_SD_WRNCDLCOR_INIT        0x49351200
 +#define MEMC_SD1_WRNCDLCOR_INIT       0x14500200      /* For corerev 1 (4712) */
@@ -11862,8 +10230,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm
 +
 +/* For ddr: */
 +#define MEMC_CONFIG_INIT      0x00048000
-+#define MEMC_DRAMTIM_INIT     0x000754d9
++#define MEMC_DRAMTIM2_INIT    0x000754d8
++#define MEMC_DRAMTIM25_INIT   0x000754d9
 +#define MEMC_RDNCDLCOR_INIT   0x00000000
++#define MEMC_RDNCDLCOR_SIMINIT        0xf6f6f6f6      /* For hdl sim */
 +#define MEMC_WRNCDLCOR_INIT   0x49351200
 +#define MEMC_1_WRNCDLCOR_INIT 0x14500200
 +#define MEMC_DQSGATENCDL_INIT 0x00030000
@@ -11908,10 +10278,10 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmemc.h linux-2.6.12.5-brcm
 +#define MEMC_CONFIG_DDR               0x00000001
 +
 +#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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,56 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm947xx/include/sbmips.h
+--- linux.old/arch/mips/bcm947xx/include/sbmips.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbmips.h      2005-12-15 16:46:57.616617000 +0100
+@@ -0,0 +1,62 @@
 +/*
 + * Broadcom SiliconBackplane MIPS definitions
 + *
@@ -11921,7 +10291,7 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm
 + * interface. The core revision is stored in the SB ID register in SB
 + * configuration space.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -11935,6 +10305,8 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm
 +#ifndef       _SBMIPS_H
 +#define       _SBMIPS_H
 +
++#include <mipsinc.h>
++
 +#ifndef _LANGUAGE_ASSEMBLY
 +
 +/* cpp contortions to concatenate w/arg prescan */
@@ -11954,35 +10326,39 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbmips.h linux-2.6.12.5-brcm
 +      uint32  timer;
 +} mipsregs_t;
 +
-+extern uint32 sb_flag(void *sbh);
-+extern uint sb_irq(void *sbh);
++extern uint32 sb_flag(sb_t *sbh);
++extern uint sb_irq(sb_t *sbh);
 +
-+extern void sb_serial_init(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift));
++extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift));
 +
-+extern void sb_mips_init(void *sbh);
-+extern uint32 sb_mips_clock(void *sbh);
-+extern bool sb_mips_setclock(void *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock);
++extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap);
++extern void sb_jtagm_disable(void *h);
++extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr);
++extern void BCMINIT(sb_mips_init)(sb_t *sbh);
++extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh);
++extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock);
++extern void BCMINIT(enable_pfc)(uint32 mode);
++extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh);
 +
-+extern uint32 sb_memc_get_ncdl(void *sbh);
 +
 +#endif /* _LANGUAGE_ASSEMBLY */
 +
 +#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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,113 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h
+--- linux.old/arch/mips/bcm947xx/include/sbpci.h       1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h       2005-12-15 15:35:36.795581250 +0100
+@@ -0,0 +1,122 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions.
 + *
 + * $Id$
-+ * 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.   
++ * 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.      
 + */
 +
 +#ifndef       _SBPCI_H
@@ -12065,8 +10441,17 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/
 +#define SBTOPCI_IO    1
 +#define SBTOPCI_CFG0  2
 +#define SBTOPCI_CFG1  3
-+#define       SBTOPCI_PREF    0x4     /* prefetch enable */
-+#define       SBTOPCI_BURST   0x8     /* burst enable */
++#define       SBTOPCI_PREF    0x4             /* prefetch enable */
++#define       SBTOPCI_BURST   0x8             /* burst enable */
++#define       SBTOPCI_RC_MASK         0x30    /* read command (>= rev11) */
++#define       SBTOPCI_RC_READ         0x00    /* memory read */
++#define       SBTOPCI_RC_READLINE     0x10    /* memory read line */
++#define       SBTOPCI_RC_READMULTI    0x20    /* memory read multiple */
++
++/* PCI core index in SROM shadow area */
++#define SRSH_PI_OFFSET        0       /* first word */
++#define SRSH_PI_MASK  0xf000  /* bit 15:12 */
++#define SRSH_PI_SHIFT 12      /* bit 15:12 */
 +
 +/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */
 +#define cap_list      rsvd_a[0]
@@ -12076,164 +10461,29 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbpci.h linux-2.6.12.5-brcm/
 +
 +#ifndef _LANGUAGE_ASSEMBLY
 +
-+extern int sbpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
-+extern int sbpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len);
 +extern void sbpci_ban(uint16 core);
-+extern int sbpci_init(void *sbh);
-+extern void sbpci_check(void *sbh);
++extern int sbpci_init(sb_t *sbh);
++extern void sbpci_check(sb_t *sbh);
 +
 +#endif /* !_LANGUAGE_ASSEMBLY */
 +
 +#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-11-07 01:12:51.839810750 +0100
-@@ -0,0 +1,131 @@
-+/*
-+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions.
-+ *
-+ * $Id$
-+ * 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.   
-+ */
-+
-+#ifndef       _SBPCMCIA_H
-+#define       _SBPCMCIA_H
-+
-+
-+/* All the addresses that are offsets in attribute space are divided
-+ * by two to account for the fact that odd bytes are invalid in
-+ * attribute space and our read/write routines make the space appear
-+ * as if they didn't exist. Still we want to show the original numbers
-+ * as documented in the hnd_pcmcia core manual.
-+ */
-+
-+/* PCMCIA Function Configuration Registers */
-+#define       PCMCIA_FCR              (0x700 / 2)
-+
-+#define       FCR0_OFF                0
-+#define       FCR1_OFF                (0x40 / 2)
-+#define       FCR2_OFF                (0x80 / 2)
-+#define       FCR3_OFF                (0xc0 / 2)
-+
-+#define       PCMCIA_FCR0             (0x700 / 2)
-+#define       PCMCIA_FCR1             (0x740 / 2)
-+#define       PCMCIA_FCR2             (0x780 / 2)
-+#define       PCMCIA_FCR3             (0x7c0 / 2)
-+
-+/* Standard PCMCIA FCR registers */
-+
-+#define       PCMCIA_COR              0
-+
-+#define       COR_RST                 0x80
-+#define       COR_LEV                 0x40
-+#define       COR_IRQEN               0x04
-+#define       COR_BLREN               0x01
-+#define       COR_FUNEN               0x01
-+
-+
-+#define       PCICIA_FCSR             (2 / 2)
-+#define       PCICIA_PRR              (4 / 2)
-+#define       PCICIA_SCR              (6 / 2)
-+#define       PCICIA_ESR              (8 / 2)
-+
-+
-+#define PCM_MEMOFF            0x0000
-+#define F0_MEMOFF             0x1000
-+#define F1_MEMOFF             0x2000
-+#define F2_MEMOFF             0x3000
-+#define F3_MEMOFF             0x4000
-+
-+/* Memory base in the function fcr's */
-+#define MEM_ADDR0             (0x728 / 2)
-+#define MEM_ADDR1             (0x72a / 2)
-+#define MEM_ADDR2             (0x72c / 2)
-+
-+/* PCMCIA base plus Srom access in fcr0: */
-+#define PCMCIA_ADDR0          (0x072e / 2)
-+#define PCMCIA_ADDR1          (0x0730 / 2)
-+#define PCMCIA_ADDR2          (0x0732 / 2)
-+
-+#define MEM_SEG                       (0x0734 / 2)
-+#define SROM_CS                       (0x0736 / 2)
-+#define SROM_DATAL            (0x0738 / 2)
-+#define SROM_DATAH            (0x073a / 2)
-+#define SROM_ADDRL            (0x073c / 2)
-+#define SROM_ADDRH            (0x073e / 2)
-+
-+/*  Values for srom_cs: */
-+#define SROM_IDLE             0
-+#define SROM_WRITE            1
-+#define SROM_READ             2
-+#define SROM_WEN              4
-+#define SROM_WDS              7
-+#define SROM_DONE             8
-+
-+/* CIS stuff */
-+
-+/* The CIS stops where the FCRs start */
-+#define       CIS_SIZE                PCMCIA_FCR
-+
-+/* Standard tuples we know about */
-+
-+#define       CISTPL_MANFID           0x20            /* Manufacturer and device id */
-+#define       CISTPL_FUNCE            0x22            /* Function extensions */
-+#define       CISTPL_CFTABLE          0x1b            /* Config table entry */
-+
-+/* Function extensions for LANs */
-+
-+#define       LAN_TECH                1               /* Technology type */
-+#define       LAN_SPEED               2               /* Raw bit rate */
-+#define       LAN_MEDIA               3               /* Transmission media */
-+#define       LAN_NID                 4               /* Node identification (aka MAC addr) */
-+#define       LAN_CONN                5               /* Connector standard */
-+
-+
-+/* CFTable */
-+#define CFTABLE_REGWIN_2K     0x08            /* 2k reg windows size */
-+#define CFTABLE_REGWIN_4K     0x10            /* 4k reg windows size */
-+#define CFTABLE_REGWIN_8K     0x20            /* 8k reg windows size */
-+
-+/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll
-+ * take one for HNBU, and use "extensions" (a la FUNCE) within it.
-+ */
-+
-+#define       CISTPL_BRCM_HNBU        0x80
-+
-+/* Subtypes of BRCM_HNBU: */
-+
-+#define       HNBU_CHIPID             0x01            /* Six bytes with PCI vendor &
-+                                               * device id and chiprev
-+                                               */
-+#define       HNBU_BOARDREV           0x02            /* Two bytes board revision */
-+#define       HNBU_PAPARMS            0x03            /* Eleven bytes PA parameters */
-+#define       HNBU_OEM                0x04            /* Eight bytes OEM data */
-+#define       HNBU_CC                 0x05            /* Default country code */
-+#define       HNBU_AA                 0x06            /* Antennas available */
-+#define       HNBU_AG                 0x07            /* Antenna gain */
-+#define HNBU_BOARDFLAGS               0x08            /* board flags */
-+#define HNBU_LED              0x09            /* LED set */
-+
-+#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-11-07 01:12:51.843811000 +0100
+diff -urN linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h
+--- linux.old/arch/mips/bcm947xx/include/sbsdram.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h     2005-12-15 15:35:40.175792500 +0100
 @@ -0,0 +1,75 @@
 +/*
 + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions.
 + *
-+ * 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.   
++ * 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$
 + */
 +
@@ -12299,15 +10549,15 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbsdram.h linux-2.6.12.5-brc
 +#define MEM8MX16X2    0xc29   /* 32 MB */
 +
 +#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-11-07 01:12:51.843811000 +0100
-@@ -0,0 +1,90 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h
+--- linux.old/arch/mips/bcm947xx/include/sbutils.h     1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h     2005-12-15 16:00:47.404550500 +0100
+@@ -0,0 +1,136 @@
 +/*
 + * Misc utility routines for accessing chip-specific features
 + * of Broadcom HNBU SiliconBackplane-based chips.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -12321,11 +10571,28 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brc
 +#ifndef       _sbutils_h_
 +#define       _sbutils_h_
 +
-+/* Board styles (bustype) */
-+#define       BOARDSTYLE_SOC          0               /* Silicon Backplane */
-+#define       BOARDSTYLE_PCI          1               /* PCI/MiniPCI board */
-+#define       BOARDSTYLE_PCMCIA       2               /* PCMCIA board */
-+#define       BOARDSTYLE_CARDBUS      3               /* Cardbus board */
++/* 
++ * Datastructure to export all chip specific common variables 
++ * public (read-only) portion of sbutils handle returned by 
++ * sb_attach()/sb_kattach()
++*/
++
++struct sb_pub {
++
++      uint    bustype;                /* SB_BUS, PCI_BUS  */
++      uint    buscoretype;            /* SB_PCI, SB_PCMCIA, SB_PCIE*/
++      uint    buscorerev;             /* buscore rev */
++      uint    buscoreidx;             /* buscore index */
++      int     ccrev;                  /* chip common core rev */
++      uint    boardtype;              /* board type */
++      uint    boardvendor;            /* board vendor */
++      uint    chip;                   /* chip number */
++      uint    chiprev;                /* chip revision */
++      uint    chippkg;                /* chip package option */
++      uint    sonicsrev;              /* sonics backplane rev */
++};
++
++typedef const struct sb_pub  sb_t;
 +
 +/*
 + * Many of the routines below take an 'sbh' handle as their first arg.
@@ -12336,71 +10603,140 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/sbutils.h linux-2.6.12.5-brc
 + */
 +
 +/* exported externs */
-+extern void *sb_attach(uint pcidev, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz);
-+extern void *sb_kattach(void);
-+extern void sb_detach(void *sbh);
-+extern uint sb_chip(void *sbh);
-+extern uint sb_chiprev(void *sbh);
-+extern uint sb_chippkg(void *sbh);
-+extern uint sb_boardvendor(void *sbh);
-+extern uint sb_boardtype(void *sbh);
-+extern uint sb_boardstyle(void *sbh);
-+extern uint sb_bus(void *sbh);
-+extern uint sb_corelist(void *sbh, uint coreid[]);
-+extern uint sb_coreid(void *sbh);
-+extern uint sb_coreidx(void *sbh);
-+extern uint sb_coreunit(void *sbh);
-+extern uint sb_corevendor(void *sbh);
-+extern uint sb_corerev(void *sbh);
-+extern void *sb_coreregs(void *sbh);
-+extern uint32 sb_coreflags(void *sbh, uint32 mask, uint32 val);
-+extern uint32 sb_coreflagshi(void *sbh, uint32 mask, uint32 val);
-+extern bool sb_iscoreup(void *sbh);
-+extern void *sb_setcoreidx(void *sbh, uint coreidx);
-+extern void *sb_setcore(void *sbh, uint coreid, uint coreunit);
-+extern void sb_commit(void *sbh);
++extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz);
++extern sb_t * BCMINIT(sb_kattach)(void);
++extern void sb_detach(sb_t *sbh);
++extern uint BCMINIT(sb_chip)(sb_t *sbh);
++extern uint BCMINIT(sb_chiprev)(sb_t *sbh);
++extern uint BCMINIT(sb_chipcrev)(sb_t *sbh);
++extern uint BCMINIT(sb_chippkg)(sb_t *sbh);
++extern uint BCMINIT(sb_pcirev)(sb_t *sbh);
++extern bool BCMINIT(sb_war16165)(sb_t *sbh);
++extern uint BCMINIT(sb_boardvendor)(sb_t *sbh);
++extern uint BCMINIT(sb_boardtype)(sb_t *sbh);
++extern uint sb_bus(sb_t *sbh);
++extern uint sb_buscoretype(sb_t *sbh);
++extern uint sb_buscorerev(sb_t *sbh);
++extern uint sb_corelist(sb_t *sbh, uint coreid[]);
++extern uint sb_coreid(sb_t *sbh);
++extern uint sb_coreidx(sb_t *sbh);
++extern uint sb_coreunit(sb_t *sbh);
++extern uint sb_corevendor(sb_t *sbh);
++extern uint sb_corerev(sb_t *sbh);
++extern void *sb_osh(sb_t *sbh);
++extern void *sb_coreregs(sb_t *sbh);
++extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val);
++extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val);
++extern bool sb_iscoreup(sb_t *sbh);
++extern void *sb_setcoreidx(sb_t *sbh, uint coreidx);
++extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit);
++extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit);
++extern void sb_commit(sb_t *sbh);
 +extern uint32 sb_base(uint32 admatch);
 +extern uint32 sb_size(uint32 admatch);
-+extern void sb_core_reset(void *sbh, uint32 bits);
-+extern void sb_core_tofixup(void *sbh);
-+extern void sb_core_disable(void *sbh, uint32 bits);
++extern void sb_core_reset(sb_t *sbh, uint32 bits);
++extern void sb_core_tofixup(sb_t *sbh);
++extern void sb_core_disable(sb_t *sbh, uint32 bits);
 +extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m);
-+extern uint32 sb_clock(void *sbh);
-+extern void sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask);
-+extern void sb_pcmcia_init(void *sbh);
-+extern void sb_watchdog(void *sbh, uint ticks);
-+extern void *sb_gpiosetcore(void *sbh);
-+extern uint32 sb_gpiocontrol(void *sbh, uint32 mask, uint32 val);
-+extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val);
-+extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val);
-+extern uint32 sb_gpioin(void *sbh);
-+extern uint32 sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val);
-+extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val);
-+extern bool sb_taclear(void *sbh);
-+extern void sb_pwrctl_init(void *sbh);
-+extern uint16 sb_pwrctl_fast_pwrup_delay(void *sbh);
-+extern bool sb_pwrctl_clk(void *sbh, uint mode);
-+extern int sb_pwrctl_xtal(void *sbh, uint what, bool on);
-+extern void sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intr_arg);
-+
-+/* pwrctl xtal what flags */
++extern uint32 sb_clock(sb_t *sbh);
++extern void sb_pci_setup(sb_t *sbh, uint coremask);
++extern void sb_watchdog(sb_t *sbh, uint ticks);
++extern void *sb_gpiosetcore(sb_t *sbh);
++extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
++extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
++extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
++extern uint32 sb_gpioin(sb_t *sbh);
++extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
++extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority);
++extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val);
++extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority);
++extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority);
++
++extern void sb_clkctl_init(sb_t *sbh);
++extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh);
++extern bool sb_clkctl_clk(sb_t *sbh, uint mode);
++extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on);
++extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn,
++      void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg);
++extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to);
++extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, 
++      uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif);
++extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val);
++
++
++
++/*
++* Build device path. Path size must be >= SB_DEVPATH_BUFSZ.
++* The returned path is NULL terminated and has trailing '/'.
++* Return 0 on success, nonzero otherwise.
++*/
++extern int sb_devpath(sb_t *sbh, char *path, int size);
++
++/* clkctl xtal what flags */
 +#define       XTAL            0x1                     /* primary crystal oscillator (2050) */
 +#define       PLL             0x2                     /* main chip pll */
 +
-+/* pwrctl clk mode */
++/* clkctl clk mode */
 +#define       CLK_FAST        0                       /* force fast (pll) clock */
-+#define       CLK_SLOW        1                       /* force slow clock */
-+#define       CLK_DYNAMIC     2                       /* enable dynamic power control */
++#define       CLK_DYNAMIC     2                       /* enable dynamic clock control */
++
++
++/* GPIO usage priorities */
++#define GPIO_DRV_PRIORITY     0
++#define GPIO_APP_PRIORITY     1
++
++/* device path */
++#define SB_DEVPATH_BUFSZ      16      /* min buffer size in bytes */
 +
 +#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-11-07 01:12:51.843811000 +0100
-@@ -0,0 +1,31 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h
+--- linux.old/arch/mips/bcm947xx/include/sflash.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/sflash.h      2005-12-15 16:49:23.001703000 +0100
+@@ -0,0 +1,36 @@
++/*
++ * Broadcom SiliconBackplane chipcommon serial flash interface
++ *
++ * 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$
++ */
++
++#ifndef _sflash_h_
++#define _sflash_h_
++
++#include <typedefs.h>
++#include <sbchipc.h>
++
++struct sflash {
++      uint blocksize;         /* Block size */
++      uint numblocks;         /* Number of blocks */
++      uint32 type;            /* Type */
++      uint size;              /* Total size in bytes */
++};
++
++/* Utility functions */
++extern int sflash_poll(chipcregs_t *cc, uint offset);
++extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf);
++extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
++extern int sflash_erase(chipcregs_t *cc, uint offset);
++extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf);
++extern struct sflash * sflash_init(chipcregs_t *cc);
++
++#endif /* _sflash_h_ */
+diff -urN linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h
+--- linux.old/arch/mips/bcm947xx/include/trxhdr.h      1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h      2005-12-15 15:35:49.220357750 +0100
+@@ -0,0 +1,33 @@
 +/*
 + * TRX image file header format.
 + *
-+ * Copyright 2001-2003, Broadcom Corporation
++ * Copyright 2005, Broadcom Corporation
 + * All Rights Reserved.
 + * 
 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
@@ -12417,880 +10753,352 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/include/trxhdr.h linux-2.6.12.5-brcm
 +#define TRX_VERSION   1
 +#define TRX_MAX_LEN   0x3A0000
 +#define TRX_NO_HEADER 1               /* Do not write TRX header */   
++#define TRX_GZ_FILES  0x2     /* Contains up to TRX_MAX_OFFSET individual gzip files */
++#define TRX_MAX_OFFSET        3
 +
 +struct trx_header {
 +      uint32 magic;           /* "HDR0" */
 +      uint32 len;             /* Length of file including header */
 +      uint32 crc32;           /* 32-bit CRC from flag_version to end of file */
 +      uint32 flag_version;    /* 0:15 flags, 16:31 version */
-+      uint32 offsets[3];      /* Offsets of partitions from start of header */
++      uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */
 +};
 +
 +/* Compatibility */
 +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-11-07 01:12:51.843811000 +0100
-@@ -0,0 +1,162 @@
+diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h
+--- linux.old/arch/mips/bcm947xx/include/typedefs.h    1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h    2005-12-15 15:35:52.436558750 +0100
+@@ -0,0 +1,326 @@
 +/*
-+ * 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.   
++ * 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$
 + */
 +
 +#ifndef _TYPEDEFS_H_
 +#define _TYPEDEFS_H_
 +
-+/*----------------------- define TRUE, FALSE, NULL, bool ----------------*/
-+#ifdef __cplusplus
 +
-+#ifndef FALSE
-+#define FALSE false
-+#endif
-+#ifndef TRUE
-+#define TRUE  true
-+#endif
++/* Define 'SITE_TYPEDEFS' in the compile to include a site specific
++ * typedef file "site_typedefs.h".
++ *
++ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs"
++ * section of this file makes inferences about the compile environment
++ * based on defined symbols and possibly compiler pragmas.
++ *
++ * Following these two sections is the "Default Typedefs"
++ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is
++ * defined. This section has a default set of typedefs and a few
++ * proprocessor symbols (TRUE, FALSE, NULL, ...).
++ */
 +
-+#else /* !__cplusplus */
++#ifdef SITE_TYPEDEFS
 +
-+#if defined(_WIN32)
++/*******************************************************************************
++ * Site Specific Typedefs
++ *******************************************************************************/
 +
-+typedef       unsigned char   bool;
++#include "site_typedefs.h"
 +
 +#else
 +
-+#if defined(MACOSX) && defined(KERNEL)
-+#include <IOKit/IOTypes.h>
-+#else
-+typedef       int     bool;
-+#endif
++/*******************************************************************************
++ * Inferred Typedefs
++ *******************************************************************************/
 +
-+#endif
++/* Infer the compile environment based on preprocessor symbols and pramas.
++ * Override type definitions as needed, and include configuration dependent
++ * header files to define types.
++ */
++
++#ifdef __cplusplus
 +
++#define TYPEDEF_BOOL
 +#ifndef FALSE
-+#define FALSE 0
++#define FALSE false
 +#endif
 +#ifndef TRUE
-+#define TRUE  1
-+
-+#ifndef NULL
-+#define       NULL 0
-+#endif
-+
++#define TRUE  true
 +#endif
 +
-+#endif /* __cplusplus */
-+
-+#ifndef OFF
-+#define       OFF     0
-+#endif
++#else /* ! __cplusplus */
 +
-+#ifndef ON
-+#define       ON      1
-+#endif
++#if defined(_WIN32)
 +
-+/*----------------------- define uchar, ushort, uint, ulong ----------------*/
++#define TYPEDEF_BOOL
++typedef       unsigned char   bool;                   /* consistent w/BOOL */
 +
-+typedef unsigned char uchar;
++#endif /* _WIN32 */
 +
-+#if defined(_WIN32) || defined(PMON) || defined(__MRC__) || defined(V2_HAL) || defined(_CFE_)
++#endif        /* ! __cplusplus */
 +
-+#ifndef V2_HAL
-+typedef unsigned short        ushort;
++/* use the Windows ULONG_PTR type when compiling for 64 bit */
++#if defined(_WIN64)
++#include <basetsd.h>
++#define TYPEDEF_UINTPTR
++typedef ULONG_PTR     uintptr;
 +#endif
 +
-+typedef unsigned int  uint;
-+typedef unsigned long ulong;
-+
-+#else
-+
-+/* pick up ushort & uint from standard types.h */
-+#if defined(linux) && defined(__KERNEL__)
-+#include <linux/types.h>      /* sys/types.h and linux/types.h are oil and water */
-+#else
-+#include <sys/types.h>        
-+#if !defined(TARGETENV_sun4) && !defined(linux)
-+typedef unsigned long ulong;
-+#endif /* TARGETENV_sun4 */
-+#endif
-+#if defined(PMON)
-+typedef unsigned int  uint;
-+typedef unsigned long long       uint64;
++#ifdef _HNDRTE_
++typedef long unsigned int size_t;
 +#endif
 +
-+#endif /* WIN32 || PMON || .. */
-+
-+/*----------------------- define [u]int8/16/32/64 --------------------------*/
-+
-+
-+#ifdef V2_HAL
-+#include <bcmos.h>
-+#else
-+typedef signed char   int8;
-+typedef signed short  int16;
-+typedef signed int    int32;
-+
-+typedef unsigned char uint8;
-+typedef unsigned short        uint16;
-+typedef unsigned int  uint32;
-+#endif        /* V2_HAL */
-+
-+typedef float         float32;
-+typedef double                float64;
-+
-+/*
-+ * abstracted floating point type allows for compile time selection of
-+ * single or double precision arithmetic.  Compiling with -DFLOAT32
-+ * selects single precision; the default is double precision.
-+ */
-+
-+#if defined(FLOAT32)
-+typedef float32 float_t;
-+#else /* default to double precision floating point */
-+typedef float64 float_t;
-+#endif /* FLOAT32 */
-+
 +#ifdef _MSC_VER           /* Microsoft C */
++#define TYPEDEF_INT64
++#define TYPEDEF_UINT64
 +typedef signed __int64        int64;
 +typedef unsigned __int64 uint64;
++#endif
++
++#if defined(MACOSX) && defined(KERNEL)
++#define TYPEDEF_BOOL
++#endif
++
++
++#if defined(linux)
++#define TYPEDEF_UINT
++#define TYPEDEF_USHORT
++#define TYPEDEF_ULONG
++#endif
 +
-+#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
-+/* gcc understands signed/unsigned 64 bit types, but complains in ANSI mode */
-+typedef signed long long int64;
-+typedef unsigned long long uint64;
++#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_)
++#define TYPEDEF_UINT
++#define TYPEDEF_USHORT
++#endif
 +
-+#elif defined(__ICL) && !defined(__STDC__)
-+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode */
-+typedef unsigned long long uint64;
 +
-+#endif /* _MSC_VER */
++/* Do not support the (u)int64 types with strict ansi for GNU C */
++#if defined(__GNUC__) && defined(__STRICT_ANSI__)
++#define TYPEDEF_INT64
++#define TYPEDEF_UINT64
++#endif
 +
++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode
++ * for singned or unsigned */
++#if defined(__ICL)
 +
-+/*----------------------- define PTRSZ, INLINE --------------------------*/
++#define TYPEDEF_INT64
 +
-+#define       PTRSZ   sizeof (char*)
++#if defined(__STDC__)
++#define TYPEDEF_UINT64
++#endif
 +
-+#ifndef INLINE
++#endif /* __ICL */
 +
-+#ifdef _MSC_VER
 +
-+#define INLINE __inline
++#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_)
 +
-+#elif __GNUC__
++/* pick up ushort & uint from standard types.h */
++#if defined(linux) && defined(__KERNEL__)
 +
-+#define INLINE __inline__
++#include <linux/types.h>      /* sys/types.h and linux/types.h are oil and water */
 +
 +#else
 +
-+#define INLINE
++#include <sys/types.h>        
 +
-+#endif /* _MSC_VER */
++#endif
 +
-+#endif /* INLINE */
++#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_  && !_MINOSL_ */
 +
-+#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-11-07 01:12:51.843811000 +0100
-@@ -0,0 +1,690 @@
-+/*
-+ * Custom OID/ioctl definitions for
-+ * Broadcom 802.11abg Networking Device Driver
-+ *
-+ * Definitions subject to change without notice.
-+ *
-+ * 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$
-+ */
++#if defined(MACOSX) && defined(KERNEL)
++#include <IOKit/IOTypes.h>
++#endif
 +
-+#ifndef _wlioctl_h_
-+#define       _wlioctl_h_
 +
-+#include <typedefs.h>
-+#include <proto/ethernet.h>
-+#include <proto/802.11.h>
++/* use the default typedefs in the next section of this file */
++#define USE_TYPEDEF_DEFAULTS
 +
-+#if defined(__GNUC__)
-+#define       PACKED  __attribute__((packed))
-+#else
-+#define       PACKED
++#endif /* SITE_TYPEDEFS */
++
++
++/*******************************************************************************
++ * Default Typedefs
++ *******************************************************************************/
++
++#ifdef USE_TYPEDEF_DEFAULTS
++#undef USE_TYPEDEF_DEFAULTS
++
++#ifndef TYPEDEF_BOOL
++typedef       /*@abstract@*/ unsigned char    bool;
 +#endif
 +
-+/*
-+ * Per-bss information structure.
-+ */
++/*----------------------- define uchar, ushort, uint, ulong ------------------*/
 +
-+#define WL_NUMRATES           255     /* max # of rates in a rateset */
-+
-+typedef struct wl_rateset {
-+      uint32  count;                  /* # rates in this set */
-+      uint8   rates[WL_NUMRATES];     /* rates in 500kbps units w/hi bit set if basic */
-+} wl_rateset_t;
-+
-+#define       WL_LEGACY_BSS_INFO_VERSION      106     /* an older supported version of wl_bss_info struct */
-+#define       WL_BSS_INFO_VERSION             107     /* current version of wl_bss_info struct */
-+
-+typedef struct wl_bss_info106 {
-+      uint            version;        /* version field */
-+      struct ether_addr BSSID;
-+      uint8           SSID_len;
-+      uint8           SSID[32];
-+      uint8           Privacy;        /* 0=No WEP, 1=Use WEP */
-+      int16           RSSI;           /* receive signal strength (in dBm) */
-+      uint16          beacon_period;  /* units are Kusec */
-+      uint16          atim_window;    /* units are Kusec */
-+      uint8           channel;        /* Channel no. */
-+      int8            infra;          /* 0=IBSS, 1=infrastructure, 2=unknown */
-+      struct {
-+              uint    count;          /* # rates in this set */
-+              uint8   rates[12];      /* rates in 500kbps units w/hi bit set if basic */
-+      } rateset;                      /* supported rates */
-+        uint8           dtim_period;    /* DTIM period */
-+      int8            phy_noise;      /* noise right after tx (in dBm) */
-+      uint16          capability;     /* Capability information */
-+      struct dot11_bcn_prb *prb;      /* probe response frame (ioctl na) */
-+      uint16          prb_len;        /* probe response frame length (ioctl na) */
-+      struct {
-+              uint8 supported;        /* wpa supported */
-+              uint8 multicast;        /* multicast cipher */
-+              uint8 ucount;           /* count of unicast ciphers */
-+              uint8 unicast[4];       /* unicast ciphers */
-+              uint8 acount;           /* count of auth modes */
-+              uint8 auth[4];          /* Authentication modes */
-+      } wpa;
-+} wl_bss_info106_t;
-+
-+typedef struct wl_bss_info {
-+      uint32          version;        /* version field */
-+      uint32          length;         /* byte length of data in this record, starting at version and including IEs */
-+      struct ether_addr BSSID;
-+      uint16          beacon_period;  /* units are Kusec */
-+      uint16          capability;     /* Capability information */
-+      uint8           SSID_len;
-+      uint8           SSID[32];
-+      struct {
-+              uint    count;          /* # rates in this set */
-+              uint8   rates[16];      /* rates in 500kbps units w/hi bit set if basic */
-+      } rateset;                      /* supported rates */
-+      uint8           channel;        /* Channel no. */
-+      uint16          atim_window;    /* units are Kusec */
-+        uint8           dtim_period;    /* DTIM period */
-+      int16           RSSI;           /* receive signal strength (in dBm) */
-+      int8            phy_noise;      /* noise (in dBm) */
-+      uint32          ie_length;      /* byte length of Information Elements */
-+      /* variable length Information Elements */
-+} wl_bss_info_t;
-+
-+typedef struct wl_scan_results {
-+      uint32 buflen;
-+      uint32 version;
-+      uint32 count;
-+      wl_bss_info_t bss_info[1];
-+} wl_scan_results_t;
-+/* size of wl_scan_results not including variable length array */
-+#define WL_SCAN_RESULTS_FIXED_SIZE 12
-+
-+/* uint32 list */
-+typedef struct wl_uint32_list {
-+      /* in - # of elements, out - # of entries */
-+      uint32 count;
-+      /* variable length uint32 list */
-+      uint32 element[1];
-+} wl_uint32_list_t;
-+
-+typedef struct wlc_ssid {
-+      uint32          SSID_len;
-+      uchar           SSID[32];
-+} wlc_ssid_t;
-+
-+#define WLC_CNTRY_BUF_SZ        4       /* Country string is 3 bytes + NULL */
-+
-+typedef struct wl_channels_in_country {
-+      uint32 buflen;
-+      uint32 band;
-+      char country_abbrev[WLC_CNTRY_BUF_SZ];
-+      uint32 count;
-+      uint32 channel[1];
-+} wl_channels_in_country_t;
-+
-+typedef struct wl_country_list {
-+      uint32 buflen;
-+      uint32 band_set;
-+      uint32 band;
-+      uint32 count;
-+      char country_abbrev[1];
-+} wl_country_list_t;
++#ifndef TYPEDEF_UCHAR
++typedef unsigned char uchar;
++#endif
 +
++#ifndef TYPEDEF_USHORT
++typedef unsigned short        ushort;
++#endif
 +
-+/*
-+* Maximum # of keys that wl driver supports in S/W. Keys supported 
-+* in H/W is less than or equal to WSEC_MAX_KEYS.
-+*/
-+#define WSEC_MAX_KEYS         54      /* Max # of keys (50 + 4 default keys) */
-+#define WSEC_MAX_DEFAULT_KEYS 4       /* # of default keys */
++#ifndef TYPEDEF_UINT
++typedef unsigned int  uint;
++#endif
 +
-+/*
-+* Remove these two defines if access to crypto/tkhash.h 
-+* is unconditionally permitted.
-+*/
-+#define TKHASH_P1_KEY_SIZE    10      /* size of TKHash Phase1 output, in bytes */
-+#define TKHASH_P2_KEY_SIZE    16      /* size of TKHash Phase2 output */
-+
-+/* Enumerate crypto algorithms */
-+#define       CRYPTO_ALGO_OFF                 0
-+#define       CRYPTO_ALGO_WEP1                1
-+#define       CRYPTO_ALGO_TKIP                2
-+#define       CRYPTO_ALGO_WEP128              3
-+#define CRYPTO_ALGO_AES_CCM           4
-+#define CRYPTO_ALGO_AES_OCB_MSDU      5
-+#define CRYPTO_ALGO_AES_OCB_MPDU      6
-+#define CRYPTO_ALGO_NALG              7
-+
-+/* For use with wlc_wep_key.flags */
-+#define WSEC_PRIMARY_KEY      (1 << 1)        /* Indicates this key is the primary (ie tx) key */
-+#define WSEC_TKIP_ERROR               (1 << 2)        /* Provoke deliberate MIC error */
-+#define WSEC_REPLAY_ERROR     (1 << 3)        /* Provoke deliberate replay */
-+
-+#define WSEC_GEN_MIC_ERROR    0x0001
-+#define WSEC_GEN_REPLAY               0x0002
-+
-+typedef struct tkip_info {
-+      uint16          phase1[TKHASH_P1_KEY_SIZE/sizeof(uint16)];      /* tkhash phase1 result */
-+      uint8           phase2[TKHASH_P2_KEY_SIZE];     /* tkhash phase2 result */
-+      uint32          micl;
-+      uint32          micr;
-+} tkip_info_t;
-+
-+typedef struct wsec_iv {
-+      uint32          hi;     /* upper 32 bits of IV */
-+      uint16          lo;     /* lower 16 bits of IV */
-+} wsec_iv_t;
-+
-+typedef struct wsec_key {
-+      uint32          index;          /* key index */
-+      uint32          len;            /* key length */
-+      uint8           data[DOT11_MAX_KEY_SIZE];       /* key data */
-+      tkip_info_t     tkip_tx;        /* tkip transmit state */
-+      tkip_info_t     tkip_rx;        /* tkip receive state */
-+      uint32          algo;           /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
-+      uint32          flags;          /* misc flags */
-+      uint32          algo_hw;        /* cache for hw register*/
-+      uint32          aes_mode;       /* cache for hw register*/
-+      int             iv_len;         /* IV length */         
-+      int             iv_initialized; /* has IV been initialized already? */          
-+      int             icv_len;        /* ICV length */
-+      wsec_iv_t       rxiv;           /* Rx IV */
-+      wsec_iv_t       txiv;           /* Tx IV */
-+      struct ether_addr ea;           /* per station */
-+} wsec_key_t;
-+
-+/* wireless security bitvec */
-+#define WEP_ENABLED           1
-+#define TKIP_ENABLED          2
-+#define AES_ENABLED           4
-+#define WSEC_SWFLAG           8
-+
-+#define WSEC_SW(wsec)         ((wsec) & WSEC_SWFLAG)
-+#define WSEC_HW(wsec)         (!WSEC_SW(wsec))
-+#define WSEC_WEP_ENABLED(wsec)        ((wsec) & WEP_ENABLED)
-+#define WSEC_TKIP_ENABLED(wsec)       ((wsec) & TKIP_ENABLED)
-+#define WSEC_AES_ENABLED(wsec)        ((wsec) & AES_ENABLED)
-+#define WSEC_ENABLED(wsec)    ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
-+
-+/* wireless authentication bit vector */
-+#define WPA_ENABLED   1
-+#define PSK_ENABLED   2
-+
-+#define WAUTH_WPA_ENABLED(wauth)      ((wauth) & WPA_ENABLED)
-+#define WAUTH_PSK_ENABLED(wauth)      ((wauth) & PSK_ENABLED)
-+#define WAUTH_ENABLED(wauth)          ((wauth) & (WPA_ENABLED | PSK_ENABLED))
-+
-+/* group/mcast cipher */
-+#define WPA_MCAST_CIPHER(wsec)        (((wsec) & TKIP_ENABLED) ? WPA_CIPHER_TKIP : \
-+                              ((wsec) & AES_ENABLED) ? WPA_CIPHER_AES_CCM : \
-+                              WPA_CIPHER_NONE)
-+
-+typedef struct wl_led_info {
-+      uint32          index;          /* led index */
-+      uint32          behavior;
-+      bool            activehi;
-+} wl_led_info_t;
++#ifndef TYPEDEF_ULONG
++typedef unsigned long ulong;
++#endif
 +
-+/*
-+ * definitions for driver messages passed from WL to NAS.
-+ */
-+/* Use this to recognize wpa and 802.1x driver messages. */
-+static const uint8 wl_wpa_snap_template[] =
-+      { 0xaa, 0xaa, 0x03, 0x00, 0x90, 0x4c };
-+
-+#define WL_WPA_MSG_IFNAME_MAX 16
-+
-+/* WPA driver message */
-+typedef struct wl_wpa_header {
-+      struct ether_header eth;
-+      struct dot11_llc_snap_header snap;
-+      uint8 version;
-+      uint8 type;
-+      /* version 2 additions */
-+      char ifname[WL_WPA_MSG_IFNAME_MAX];
-+      /* version specific data */
-+      /* uint8 data[1]; */
-+} wl_wpa_header_t PACKED;
-+
-+#define WL_WPA_HEADER_LEN     (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX)
-+
-+/* WPA driver message ethertype - private between wlc and nas */
-+#define WL_WPA_ETHER_TYPE     0x9999
-+
-+/* WPA driver message current version */
-+#define WL_WPA_MSG_VERSION    2
-+
-+/* Type field values for the 802.2 driver messages for WPA. */
-+#define WLC_ASSOC_MSG         1
-+#define WLC_DISASSOC_MSG      2
-+#define WLC_PTK_MIC_MSG               3
-+#define WLC_GTK_MIC_MSG               4
-+
-+/* 802.1x driver message */
-+typedef struct wl_eapol_header {
-+      struct ether_header eth;
-+      struct dot11_llc_snap_header snap;
-+      uint8 version;
-+      uint8 reserved;
-+      char ifname[WL_WPA_MSG_IFNAME_MAX];
-+      /* version specific data */
-+      /* uint8 802_1x_msg[1]; */
-+} wl_eapol_header_t PACKED;
-+
-+#define WL_EAPOL_HEADER_LEN   (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX)
-+
-+/* 802.1x driver message ethertype - private between wlc and nas */
-+#define WL_EAPOL_ETHER_TYPE   0x999A
-+
-+/* 802.1x driver message current version */
-+#define WL_EAPOL_MSG_VERSION  1
-+
-+/* srom read/write struct passed through ioctl */
-+typedef struct {
-+      uint   byteoff;         /* byte offset */
-+      uint   nbytes;          /* number of bytes */
-+      uint16 buf[1];
-+} srom_rw_t;
++/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/
 +
-+/* R_REG and W_REG struct passed through ioctl */
-+typedef struct {
-+      uint32  byteoff;        /* byte offset of the field in d11regs_t */
-+      uint32  val;            /* read/write value of the field */
-+      uint32  size;           /* sizeof the field */
-+} rw_reg_t;
++#ifndef TYPEDEF_UINT8
++typedef unsigned char uint8;
++#endif
 +
-+/* Structure used by GET/SET_ATTEN ioctls */
-+typedef struct {
-+      uint16  auto_ctrl;      /* 1: Automatic control, 0: overriden */
-+      uint16  bb;             /* Baseband attenuation */
-+      uint16  radio;          /* Radio attenuation */
-+      uint16  txctl1;         /* Radio TX_CTL1 value */
-+} atten_t;
++#ifndef TYPEDEF_UINT16
++typedef unsigned short        uint16;
++#endif
 +
-+/* Used to get specific STA parameters */ 
-+typedef struct {
-+      uint32  val;
-+      struct ether_addr ea;
-+} scb_val_t;
-+
-+/* callback registration data types */
-+
-+typedef struct _mac_event_params {
-+      uint msg;
-+      struct ether_addr *addr;
-+      uint result;
-+      uint status; 
-+      uint auth_type;
-+} mac_event_params_t;
-+
-+typedef struct _mic_error_params {
-+      struct ether_addr *ea;
-+      bool group;
-+      bool flush_txq;
-+} mic_error_params_t;
-+
-+typedef enum _wl_callback {
-+      WL_MAC_EVENT_CALLBACK = 0,
-+      WL_LINK_UP_CALLBACK,
-+      WL_LINK_DOWN_CALLBACK,
-+      WL_MIC_ERROR_CALLBACK,
-+      WL_LAST_CALLBACK
-+} wl_callback_t;
-+
-+typedef struct _callback {
-+      void (*fn)(void *, void *);
-+      void *context;
-+} callback_t;
-+
-+typedef struct _scan_callback {
-+      void (*fn)(void *);
-+      void *context;
-+} scan_callback_t;
-+
-+/* used to register an arbitrary callback via the IOCTL interface */
-+typedef struct _set_callback {
-+      int index;
-+      callback_t callback;
-+} set_callback_t;
++#ifndef TYPEDEF_UINT32
++typedef unsigned int  uint32;
++#endif
 +
-+/*
-+ * Country locale determines which channels are available to us.
-+ */
-+typedef enum _wlc_locale {
-+      WLC_WW = 0,     /* Worldwide */
-+      WLC_THA,        /* Thailand */
-+      WLC_ISR,        /* Israel */
-+      WLC_JDN,        /* Jordan */
-+      WLC_PRC,        /* China */
-+      WLC_JPN,        /* Japan */
-+      WLC_FCC,        /* USA */
-+      WLC_EUR,        /* Europe */
-+      WLC_USL,        /* US Low Band only */
-+      WLC_JPH,        /* Japan High Band only */
-+      WLC_ALL,        /* All the channels in this band */
-+      WLC_11D,        /* Represents locale recieved by 11d beacons */
-+      WLC_LAST_LOCALE,
-+      WLC_UNDEFINED_LOCALE = 0xf
-+} wlc_locale_t;
-+
-+/* channel encoding */
-+typedef struct channel_info {
-+      int hw_channel;
-+      int target_channel;
-+      int scan_channel;
-+} channel_info_t;
-+
-+/* For ioctls that take a list of MAC addresses */
-+struct maclist {
-+      uint count;                     /* number of MAC addresses */
-+      struct ether_addr ea[1];        /* variable length array of MAC addresses */
-+};
++#ifndef TYPEDEF_UINT64
++typedef unsigned long long uint64;
++#endif
 +
-+/* get pkt count struct passed through ioctl */
-+typedef struct get_pktcnt {
-+      uint rx_good_pkt;
-+      uint rx_bad_pkt;
-+      uint tx_good_pkt;
-+      uint tx_bad_pkt;
-+} get_pktcnt_t;
-+
-+/* Linux network driver ioctl encoding */
-+typedef struct wl_ioctl {
-+      int cmd;        /* common ioctl definition */
-+      void *buf;      /* pointer to user buffer */
-+      int len;        /* length of user buffer */
-+} wl_ioctl_t;
++#ifndef TYPEDEF_UINTPTR
++typedef unsigned int  uintptr;
++#endif
 +
-+/* 
-+ * Structure for passing hardware and software 
-+ * revision info up from the driver. 
-+ */
-+typedef struct wlc_rev_info {
-+      uint            vendorid;       /* PCI vendor id */
-+      uint            deviceid;       /* device id of chip */
-+      uint            radiorev;       /* radio revision */
-+      uint            chiprev;        /* chip revision */
-+      uint            corerev;        /* core revision */
-+      uint            boardid;        /* board identifier (usu. PCI sub-device id) */
-+      uint            boardvendor;    /* board vendor (usu. PCI sub-vendor id) */
-+      uint            boardrev;       /* board revision */
-+      uint            driverrev;      /* driver version */
-+      uint            ucoderev;       /* microcode version */
-+      uint            bus;            /* bus type */
-+      uint        chipnum;    /* chip number */
-+} wlc_rev_info_t;
-+
-+/* check this magic number */
-+#define WLC_IOCTL_MAGIC               0x14e46c77
-+
-+/* bump this number if you change the ioctl interface */
-+#define WLC_IOCTL_VERSION     1
-+
-+/* maximum length buffer required */
-+#define WLC_IOCTL_MAXLEN      8192
-+
-+/* common ioctl definitions */
-+#define WLC_GET_MAGIC                         0
-+#define WLC_GET_VERSION                               1
-+#define WLC_UP                                        2
-+#define WLC_DOWN                              3
-+#define WLC_DUMP                              6
-+#define WLC_GET_MSGLEVEL                      7
-+#define WLC_SET_MSGLEVEL                      8
-+#define WLC_GET_PROMISC                               9
-+#define WLC_SET_PROMISC                               10
-+#define WLC_GET_RATE                          12
-+#define WLC_SET_RATE                          13
-+#define WLC_GET_INSTANCE                      14
-+#define WLC_GET_FRAG                          15
-+#define WLC_SET_FRAG                          16
-+#define WLC_GET_RTS                           17
-+#define WLC_SET_RTS                           18
-+#define WLC_GET_INFRA                         19
-+#define WLC_SET_INFRA                         20
-+#define WLC_GET_AUTH                          21
-+#define WLC_SET_AUTH                          22
-+#define WLC_GET_BSSID                         23
-+#define WLC_SET_BSSID                         24
-+#define WLC_GET_SSID                          25
-+#define WLC_SET_SSID                          26
-+#define WLC_RESTART                           27
-+#define WLC_GET_CHANNEL                               29
-+#define WLC_SET_CHANNEL                               30
-+#define WLC_GET_SRL                           31
-+#define WLC_SET_SRL                           32
-+#define WLC_GET_LRL                           33
-+#define WLC_SET_LRL                           34
-+#define WLC_GET_PLCPHDR                               35
-+#define WLC_SET_PLCPHDR                               36
-+#define WLC_GET_RADIO                         37
-+#define WLC_SET_RADIO                         38
-+#define WLC_GET_PHYTYPE                               39
-+#define WLC_GET_WEP                           42
-+#define WLC_SET_WEP                           43
-+#define WLC_GET_KEY                           44
-+#define WLC_SET_KEY                           45
-+#define WLC_SCAN                              50
-+#define WLC_SCAN_RESULTS                      51
-+#define WLC_DISASSOC                          52
-+#define WLC_REASSOC                           53
-+#define WLC_GET_ROAM_TRIGGER                  54
-+#define WLC_SET_ROAM_TRIGGER                  55
-+#define WLC_GET_TXANT                         61
-+#define WLC_SET_TXANT                         62
-+#define WLC_GET_ANTDIV                                63
-+#define WLC_SET_ANTDIV                                64
-+#define WLC_GET_TXPWR                         65
-+#define WLC_SET_TXPWR                         66
-+#define WLC_GET_CLOSED                                67
-+#define WLC_SET_CLOSED                                68
-+#define WLC_GET_MACLIST                               69
-+#define WLC_SET_MACLIST                               70
-+#define WLC_GET_RATESET                               71
-+#define WLC_SET_RATESET                               72
-+#define WLC_GET_LOCALE                                73
-+#define WLC_SET_LOCALE                                74
-+#define WLC_GET_BCNPRD                                75
-+#define WLC_SET_BCNPRD                                76
-+#define WLC_GET_DTIMPRD                               77
-+#define WLC_SET_DTIMPRD                               78
-+#define WLC_GET_SROM                          79
-+#define WLC_SET_SROM                          80
-+#define WLC_GET_WEP_RESTRICT                  81
-+#define WLC_SET_WEP_RESTRICT                  82
-+#define WLC_GET_COUNTRY                               83
-+#define WLC_SET_COUNTRY                               84
-+#define WLC_GET_REVINFO                               98
-+#define WLC_GET_MACMODE                               105
-+#define WLC_SET_MACMODE                               106
-+#define WLC_GET_GMODE                         109
-+#define WLC_SET_GMODE                         110
-+#define WLC_GET_CURR_RATESET                  114     /* current rateset */
-+#define WLC_GET_SCANSUPPRESS                  115
-+#define WLC_SET_SCANSUPPRESS                  116
-+#define WLC_GET_AP                            117
-+#define WLC_SET_AP                            118
-+#define WLC_GET_EAP_RESTRICT                  119
-+#define WLC_SET_EAP_RESTRICT                  120
-+#define WLC_GET_WDSLIST                               123
-+#define WLC_SET_WDSLIST                               124
-+#define WLC_GET_RSSI                          127
-+#define WLC_GET_WSEC                          133
-+#define WLC_SET_WSEC                          134
-+#define WLC_GET_BSS_INFO                      136
-+#define WLC_GET_LAZYWDS                               138
-+#define WLC_SET_LAZYWDS                               139
-+#define WLC_GET_BANDLIST                      140
-+#define WLC_GET_BAND                          141
-+#define WLC_SET_BAND                          142
-+#define WLC_GET_SHORTSLOT                     144
-+#define WLC_GET_SHORTSLOT_OVERRIDE            145
-+#define WLC_SET_SHORTSLOT_OVERRIDE            146
-+#define WLC_GET_SHORTSLOT_RESTRICT            147
-+#define WLC_SET_SHORTSLOT_RESTRICT            148
-+#define WLC_GET_GMODE_PROTECTION              149
-+#define WLC_GET_GMODE_PROTECTION_OVERRIDE     150
-+#define WLC_SET_GMODE_PROTECTION_OVERRIDE     151
-+#define WLC_UPGRADE                           152
-+#define WLC_GET_ASSOCLIST                     159
-+#define WLC_GET_CLK                           160
-+#define WLC_SET_CLK                           161
-+#define WLC_GET_UP                            162
-+#define WLC_OUT                                       163
-+#define WLC_GET_WPA_AUTH                      164
-+#define WLC_SET_WPA_AUTH                      165
-+#define WLC_GET_GMODE_PROTECTION_CONTROL      178
-+#define WLC_SET_GMODE_PROTECTION_CONTROL      179
-+#define WLC_GET_PHYLIST                               180
-+#define WLC_GET_GMODE_PROTECTION_CTS          198
-+#define WLC_SET_GMODE_PROTECTION_CTS          199
-+#define WLC_GET_PIOMODE                               203
-+#define WLC_SET_PIOMODE                               204
-+#define WLC_SET_LED                           209
-+#define WLC_GET_LED                           210
-+#define WLC_GET_CHANNEL_SEL                   215
-+#define WLC_START_CHANNEL_SEL                 216
-+#define WLC_GET_VALID_CHANNELS                        217
-+#define WLC_GET_FAKEFRAG                      218
-+#define WLC_SET_FAKEFRAG                      219
-+#define WLC_GET_WET                           230
-+#define WLC_SET_WET                           231
-+#define WLC_GET_KEY_PRIMARY                   235
-+#define WLC_SET_KEY_PRIMARY                   236
-+#define WLC_SCAN_WITH_CALLBACK                        240
-+#define WLC_SET_CS_SCAN_TIMER                 248
-+#define WLC_GET_CS_SCAN_TIMER                 249
-+#define WLC_CURRENT_PWR                               256
-+#define WLC_GET_CHANNELS_IN_COUNTRY           260
-+#define WLC_GET_COUNTRY_LIST                  261
-+#define WLC_NVRAM_GET                         264
-+#define WLC_NVRAM_SET                         265
-+#define WLC_LAST                              271     /* bump after adding */
++#ifndef TYPEDEF_INT8
++typedef signed char   int8;
++#endif
 +
-+/*
-+ * Minor kludge alert:
-+ * Duplicate a few definitions that irelay requires from epiioctl.h here
-+ * so caller doesn't have to include this file and epiioctl.h .
-+ * If this grows any more, it would be time to move these irelay-specific
-+ * definitions out of the epiioctl.h and into a separate driver common file.
-+ */
-+#ifndef EPICTRL_COOKIE
-+#define EPICTRL_COOKIE                0xABADCEDE
++#ifndef TYPEDEF_INT16
++typedef signed short  int16;
 +#endif
 +
-+/* vx wlc ioctl's offset */
-+#define CMN_IOCTL_OFF 0x180
++#ifndef TYPEDEF_INT32
++typedef signed int    int32;
++#endif
 +
-+/*
-+ * custom OID support
-+ *
-+ * 0xFF - implementation specific OID
-+ * 0xE4 - first byte of Broadcom PCI vendor ID
-+ * 0x14 - second byte of Broadcom PCI vendor ID
-+ * 0xXX - the custom OID number
-+ */
++#ifndef TYPEDEF_INT64
++typedef signed long long int64;
++#endif
++
++/*----------------------- define float32/64, float_t -----------------------*/
 +
-+/* begin 0x1f values beyond the start of the ET driver range. */
-+#define WL_OID_BASE           0xFFE41420
++#ifndef TYPEDEF_FLOAT32
++typedef float         float32;
++#endif
 +
-+/* NDIS overrides */
-+#define OID_WL_GETINSTANCE    (WL_OID_BASE + WLC_GET_INSTANCE)
++#ifndef TYPEDEF_FLOAT64
++typedef double                float64;
++#endif
 +
-+#define WL_DECRYPT_STATUS_SUCCESS     1
-+#define WL_DECRYPT_STATUS_FAILURE     2
-+#define WL_DECRYPT_STATUS_UNKNOWN     3
++/*
++ * abstracted floating point type allows for compile time selection of
++ * single or double precision arithmetic.  Compiling with -DFLOAT32
++ * selects single precision; the default is double precision.
++ */
 +
-+/* allows user-mode app to poll the status of USB image upgrade */
-+#define WLC_UPGRADE_SUCCESS                   0
-+#define WLC_UPGRADE_PENDING                   1
++#ifndef TYPEDEF_FLOAT_T
 +
-+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */
-+#define WL_RADIO_SW_DISABLE   (1<<0)
-+#define WL_RADIO_HW_DISABLE   (1<<1)
++#if defined(FLOAT32)
++typedef float32 float_t;
++#else /* default to double precision floating point */
++typedef float64 float_t;
++#endif
 +
-+/* Override bit for WLC_SET_TXPWR.  if set, ignore other level limits */
-+#define WL_TXPWR_OVERRIDE     (1<<31)
++#endif /* TYPEDEF_FLOAT_T */
 +
++/*----------------------- define macro values -----------------------------*/
 +
-+/* Bus types */
-+#define WL_SB_BUS     0       /* Silicon Backplane */
-+#define WL_PCI_BUS    1       /* PCI target */
-+#define WL_PCMCIA_BUS 2       /* PCMCIA target */
++#ifndef FALSE
++#define FALSE 0
++#endif
 +
-+/* band types */
-+#define       WLC_BAND_AUTO           0       /* auto-select */
-+#define       WLC_BAND_A              1       /* "a" band (5   Ghz) */
-+#define       WLC_BAND_B              2       /* "b" band (2.4 Ghz) */
++#ifndef TRUE
++#define TRUE  1
++#endif
 +
-+/* MAC list modes */
-+#define WLC_MACMODE_DISABLED  0       /* MAC list disabled */
-+#define WLC_MACMODE_DENY      1       /* Deny specified (i.e. allow unspecified) */
-+#define WLC_MACMODE_ALLOW     2       /* Allow specified (i.e. deny unspecified) */   
++#ifndef NULL
++#define       NULL    0
++#endif
 +
-+/* 
-+ *
-+ */
-+#define GMODE_LEGACY_B                0
-+#define GMODE_AUTO            1
-+#define GMODE_ONLY            2
-+#define GMODE_B_DEFERRED      3
-+#define GMODE_PERFORMANCE     4
-+#define GMODE_LRS             5
-+#define GMODE_MAX             6
++#ifndef OFF
++#define       OFF     0
++#endif
 +
-+/* values for PLCPHdr_override */
-+#define WLC_PLCP_AUTO -1
-+#define WLC_PLCP_SHORT        0
-+#define WLC_PLCP_LONG 1
++#ifndef ON
++#define       ON      1
++#endif
 +
-+/* values for g_protection_override */
-+#define WLC_G_PROTECTION_AUTO -1
-+#define WLC_G_PROTECTION_OFF  0
-+#define WLC_G_PROTECTION_ON   1
++#define       AUTO    (-1)
 +
-+/* values for g_protection_control */
-+#define WLC_G_PROTECTION_CTL_OFF      0
-+#define WLC_G_PROTECTION_CTL_LOCAL    1
-+#define WLC_G_PROTECTION_CTL_OVERLAP  2
++/* Reclaiming text and data :
++   The following macros specify special linker sections that can be reclaimed
++   after a system is considered 'up'.
++ */ 
++#if defined(__GNUC__) && defined(BCMRECLAIM)
++extern bool   bcmreclaimed;
++#define BCMINITDATA(_data)    __attribute__ ((__section__ (".dataini." #_data))) _data##_ini          
++#define BCMINITFN(_fn)                __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini
++#define BCMINIT(_id)          _id##_ini
++#else 
++#define BCMINITDATA(_data)    _data           
++#define BCMINITFN(_fn)                _fn
++#define BCMINIT(_id)          _id
++#define bcmreclaimed          0
++#endif
 +
++/*----------------------- define PTRSZ, INLINE ----------------------------*/
 +
++#ifndef PTRSZ
++#define       PTRSZ   sizeof (char*)
++#endif
 +
++#ifndef INLINE
 +
++#ifdef _MSC_VER
 +
++#define INLINE __inline
 +
-+/* max # of leds supported by GPIO (gpio pin# == led index#) */
-+#define       WL_LED_NUMGPIO          16      /* gpio 0-15 */
++#elif __GNUC__
 +
-+/* led per-pin behaviors */
-+#define       WL_LED_OFF              0               /* always off */
-+#define       WL_LED_ON               1               /* always on */
-+#define       WL_LED_ACTIVITY         2               /* activity */
-+#define       WL_LED_RADIO            3               /* radio enabled */
-+#define       WL_LED_ARADIO           4               /* 5  Ghz radio enabled */
-+#define       WL_LED_BRADIO           5               /* 2.4Ghz radio enabled */
-+#define       WL_LED_BGMODE           6               /* on if gmode, off if bmode */
-+#define       WL_LED_WI1              7               
-+#define       WL_LED_WI2              8               
-+#define       WL_LED_WI3              9               
-+#define       WL_LED_ASSOC            10              /* associated state indicator */
-+#define       WL_LED_INACTIVE         11              /* null behavior (clears default behavior) */
-+#define       WL_LED_NUMBEHAVIOR      12
++#define INLINE __inline__
 +
-+/* led behavior numeric value format */
-+#define       WL_LED_BEH_MASK         0x7f            /* behavior mask */
-+#define       WL_LED_AL_MASK          0x80            /* activelow (polarity) bit */
++#else
 +
++#define INLINE
 +
-+/* rate check */
-+#define WL_RATE_OFDM(r)               (((r) & 0x7f) == 12 || ((r) & 0x7f) == 18 || \
-+                               ((r) & 0x7f) == 24 || ((r) & 0x7f) == 36 || \
-+                               ((r) & 0x7f) == 48 || ((r) & 0x7f) == 72 || \
-+                               ((r) & 0x7f) == 96 || ((r) & 0x7f) == 108)
++#endif /* _MSC_VER */
 +
++#endif /* INLINE */
 +
-+#undef PACKED
++#undef TYPEDEF_BOOL
++#undef TYPEDEF_UCHAR
++#undef TYPEDEF_USHORT
++#undef TYPEDEF_UINT
++#undef TYPEDEF_ULONG
++#undef TYPEDEF_UINT8
++#undef TYPEDEF_UINT16
++#undef TYPEDEF_UINT32
++#undef TYPEDEF_UINT64
++#undef TYPEDEF_UINTPTR
++#undef TYPEDEF_INT8
++#undef TYPEDEF_INT16
++#undef TYPEDEF_INT32
++#undef TYPEDEF_INT64
++#undef TYPEDEF_FLOAT32
++#undef TYPEDEF_FLOAT64
++#undef TYPEDEF_FLOAT_T
++
++#endif /* USE_TYPEDEF_DEFAULTS */
 +
-+#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-11-07 01:12:51.843811000 +0100
++#endif /* _TYPEDEFS_H_ */
+diff -urN linux.old/arch/mips/bcm947xx/int-handler.S linux.dev/arch/mips/bcm947xx/int-handler.S
+--- linux.old/arch/mips/bcm947xx/int-handler.S 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/int-handler.S 2005-12-15 12:57:27.877187750 +0100
 @@ -0,0 +1,48 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13340,9 +11148,9 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/int-handler.S linux-2.6.12.5-brcm/ar
 +      nop
 +              
 +      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-11-19 02:16:15.531125500 +0100
+diff -urN linux.old/arch/mips/bcm947xx/irq.c linux.dev/arch/mips/bcm947xx/irq.c
+--- linux.old/arch/mips/bcm947xx/irq.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/irq.c 2005-12-15 12:57:27.877187750 +0100
 @@ -0,0 +1,67 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13368,62 +11176,271 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/irq.c linux-2.6.12.5-brcm/arch/mips/
 + *  675 Mass Ave, Cambridge, MA 02139, USA.
 + */
 +
-+#include <linux/config.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/irq.h>
-+#include <linux/module.h>
-+#include <linux/smp.h>
-+#include <linux/types.h>
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/module.h>
++#include <linux/smp.h>
++#include <linux/types.h>
++
++#include <asm/cpu.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/irq_cpu.h>
++
++extern asmlinkage void bcm47xx_irq_handler(void);
++
++void bcm47xx_irq_dispatch(struct pt_regs *regs)
++{
++      u32 cause;
++
++      cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
++
++      clear_c0_status(cause);
++
++      if (cause & CAUSEF_IP7)
++              do_IRQ(7, regs);
++      if (cause & CAUSEF_IP2)
++              do_IRQ(2, regs);
++      if (cause & CAUSEF_IP3)
++              do_IRQ(3, regs);
++      if (cause & CAUSEF_IP4)
++              do_IRQ(4, regs);
++      if (cause & CAUSEF_IP5)
++              do_IRQ(5, regs);
++      if (cause & CAUSEF_IP6)
++              do_IRQ(6, regs);
++}
++
++void __init arch_init_irq(void)
++{
++      set_except_vector(0, bcm47xx_irq_handler);
++      mips_cpu_irq_init(0);
++}
+diff -urN linux.old/arch/mips/bcm947xx/pci.c linux.dev/arch/mips/bcm947xx/pci.c
+--- linux.old/arch/mips/bcm947xx/pci.c 1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/pci.c 2005-12-18 07:01:36.731635000 +0100
+@@ -0,0 +1,215 @@
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/types.h>
++
++#include <asm/cpu.h>
++#include <asm/io.h>
++
++#include <typedefs.h>
++#include <osl.h>
++#include <sbutils.h>
++#include <sbmips.h>
++#include <sbconfig.h>
++#include <sbpci.h>
++#include <bcmdevs.h>
++#include <pcicfg.h>
++
++extern sb_t *sbh;
++extern spinlock_t sbh_lock;
++
++
++static int
++sb_pci_read_config(struct pci_bus *bus, unsigned int devfn,
++                              int reg, int size, u32 *val)
++{
++      int ret;
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
++      ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++
++      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
++}
++
++static int
++sb_pci_write_config(struct pci_bus *bus, unsigned int devfn,
++                              int reg, int size, u32 val)
++{
++      int ret;
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
++      ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++
++      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
++}
++
++
++static struct pci_ops sb_pci_ops = {
++      .read   = sb_pci_read_config,
++      .write  = sb_pci_write_config,
++};
++
++static struct resource sb_pci_mem_resource = {
++      .name   = "SB PCI Memory resources",
++      .start  = SB_ENUM_BASE,
++      .end    = SB_ENUM_LIM - 1,
++      .flags  = IORESOURCE_MEM,
++};
++
++static struct resource sb_pci_io_resource = {
++      .name   = "SB PCI I/O resources",
++      .start  = 0x000,
++      .end    = 0x0FF,
++      .flags  = IORESOURCE_IO,
++};
++
++static struct pci_controller bcm47xx_sb_pci_controller = {
++      .pci_ops        = &sb_pci_ops,
++      .mem_resource   = &sb_pci_mem_resource,
++      .io_resource    = &sb_pci_io_resource,
++};
++
++static struct resource ext_pci_mem_resource = {
++      .name   = "Ext PCI Memory resources",
++      .start  = 0x40000000,
++      .end    = 0x7fffffff,
++      .flags  = IORESOURCE_MEM,
++};
++
++static struct resource ext_pci_io_resource = {
++      .name   = "Ext PCI I/O resources",
++      .start  = 0x100,
++      .end    = 0x1FF,
++      .flags  = IORESOURCE_IO,
++};
++
++static struct pci_controller bcm47xx_ext_pci_controller = {
++      .pci_ops        = &sb_pci_ops,
++      .io_resource    = &ext_pci_io_resource,
++      .mem_resource   = &ext_pci_mem_resource,
++      .mem_offset             = 0x24000000,
++};
 +
-+#include <asm/cpu.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/irq_cpu.h>
++void bcm47xx_pci_init(void)
++{
++      unsigned long flags;
++      
++      spin_lock_irqsave(&sbh_lock, flags);
++      sbpci_init(sbh);
++      spin_unlock_irqrestore(&sbh_lock, flags);
 +
-+extern asmlinkage void bcm47xx_irq_handler(void);
++      set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
 +
-+void bcm47xx_irq_dispatch(struct pt_regs *regs)
++      register_pci_controller(&bcm47xx_sb_pci_controller);
++      register_pci_controller(&bcm47xx_ext_pci_controller);
++}
++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 +{
-+      u32 cause;
++      u8 irq;
++      
++      if (dev->bus->number == 1)
++              return 2;
 +
-+      cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
++      pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
++      return irq + 2;
++}
 +
-+      clear_c0_status(cause);
++u32 pci_iobase = 0x100;
++u32 pci_membase = SB_PCI_DMA;
 +
-+      if (cause & CAUSEF_IP7)
-+              do_IRQ(7, regs);
-+      if (cause & CAUSEF_IP2)
-+              do_IRQ(2, regs);
-+      if (cause & CAUSEF_IP3)
-+              do_IRQ(3, regs);
-+      if (cause & CAUSEF_IP4)
-+              do_IRQ(4, regs);
-+      if (cause & CAUSEF_IP5)
-+              do_IRQ(5, regs);
-+      if (cause & CAUSEF_IP6)
-+              do_IRQ(6, regs);
++static void bcm47xx_fixup_device(struct pci_dev *d)
++{
++      struct resource *res;
++      int pos, size;
++      u32 *base;
++
++      if (d->bus->number == 0)
++              return;
++      
++      printk("PCI: Fixing up device %s\n", pci_name(d));
++
++      /* Fix up resource bases */
++      for (pos = 0; pos < 6; pos++) {
++              res = &d->resource[pos];
++              base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
++              if (res->end) {
++                      size = res->end - res->start + 1;
++                      if (*base & (size - 1))
++                              *base = (*base + size) & ~(size - 1);
++                      res->start = *base;
++                      res->end = res->start + size - 1;
++                      *base += size;
++                      pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
++              }
++              /* Fix up PCI bridge BAR0 only */
++              if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
++                      break;
++      }
++      /* Fix up interrupt lines */
++      if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
++              d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
++      pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
 +}
 +
-+void __init arch_init_irq(void)
++
++static void bcm47xx_fixup_bridge(struct pci_dev *dev)
 +{
-+      set_except_vector(0, bcm47xx_irq_handler);
-+      mips_cpu_irq_init(0);
++      if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
++              return;
++      
++      printk("PCI: fixing up bridge\n");
++
++      /* Enable PCI bridge bus mastering and memory space */
++      pci_set_master(dev);
++      pcibios_enable_device(dev, ~0);
++      
++      /* Enable PCI bridge BAR1 prefetch and burst */
++      pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
++}
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++      uint coreidx;
++      unsigned long flags;
++      
++      bcm47xx_fixup_device(dev);
++
++      /* These cores come out of reset enabled */
++      if ((dev->bus->number != 0) ||
++              (dev->device == SB_MIPS) ||
++              (dev->device == SB_MIPS33) ||
++              (dev->device == SB_EXTIF) ||
++              (dev->device == SB_CC))
++              return 0;
++
++      /* Do a core reset */
++      spin_lock_irqsave(&sbh_lock, flags);
++      coreidx = sb_coreidx(sbh);
++      if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
++              /* 
++               * The USB core requires a special bit to be set during core
++               * reset to enable host (OHCI) mode. Resetting the SB core in
++               * pcibios_enable_device() is a hack for compatibility with
++               * vanilla usb-ohci so that it does not have to know about
++               * SB. A driver that wants to use the USB core in device mode
++               * should know about SB and should reset the bit back to 0
++               * after calling pcibios_enable_device().
++               */
++              sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
++              sb_core_reset(sbh, 1 << 29);
++      } else {
++              sb_core_reset(sbh, 0);
++      }
++      sb_setcoreidx(sbh, coreidx);
++      spin_unlock_irqrestore(&sbh_lock, flags);
++      
++      return 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-11-07 01:12:51.847811250 +0100
++DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
+diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c
+--- linux.old/arch/mips/bcm947xx/prom.c        1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/prom.c        2005-12-15 12:57:27.877187750 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13484,13 +11501,14 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/prom.c linux-2.6.12.5-brcm/arch/mips
 +{
 +      return 0;
 +}
-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-11-29 01:23:30.667381000 +0100
-@@ -0,0 +1,112 @@
+diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c
+--- linux.old/arch/mips/bcm947xx/setup.c       1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/setup.c       2005-12-18 06:34:52.106215250 +0100
+@@ -0,0 +1,157 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
 + *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
++ *  Copyright (C) 2005 Felix Fietkau <nbd@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
@@ -13524,22 +11542,57 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +#include <asm/reboot.h>
 +
 +#include <typedefs.h>
++#include <osl.h>
 +#include <sbutils.h>
 +#include <sbmips.h>
 +#include <sbpci.h>
 +#include <sbconfig.h>
 +#include <bcmdevs.h>
++#include <bcmutils.h>
++#include <bcmnvram.h>
 +
++extern void bcm47xx_pci_init(void);
 +extern void bcm47xx_time_init(void);
 +extern void bcm47xx_timer_setup(struct irqaction *irq);
 +void *sbh;
++spinlock_t sbh_lock = SPIN_LOCK_UNLOCKED;
++int boardflags;
 +
 +static int ser_line = 0;
 +
++typedef struct {
++      void *regs;
++      uint irq;
++      uint baud_base;
++      uint reg_shift;
++} serial_port;
++
++static serial_port ports[4];
++static int num_ports = 0;
++
 +static void
 +serial_add(void *regs, uint irq, uint baud_base, uint reg_shift)
 +{
++      ports[num_ports].regs = regs;
++      ports[num_ports].irq = irq;
++      ports[num_ports].baud_base = baud_base;
++      ports[num_ports].reg_shift = reg_shift;
++      num_ports++;
++}
++
++static void
++do_serial_add(serial_port *port)
++{
++      void *regs;
++      uint irq;
++      uint baud_base;
++      uint reg_shift;
 +      struct uart_port s;
++      
++      regs = port->regs;
++      irq = port->irq;
++      baud_base = port->baud_base;
++      reg_shift = port->reg_shift;
 +
 +      memset(&s, 0, sizeof(s));
 +
@@ -13556,12 +11609,6 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +      }
 +}
 +
-+void *nvram_get(char *foo)
-+{
-+      return NULL;
-+}
-+
-+
 +static void bcm47xx_machine_restart(char *command)
 +{
 +      printk("Please stand by while rebooting the system...\n");
@@ -13580,29 +11627,44 @@ diff -Nur linux-2.6.12.5/arch/mips/bcm947xx/setup.c linux-2.6.12.5-brcm/arch/mip
 +      while (1);
 +}
 +
-+static int __init bcm47xx_init(void)
++void __init plat_setup(void)
 +{
-+
-+      sbh = sb_kattach();
++      char *s;
++      int i;
++      
++      sbh = (void *) sb_kattach();
 +      sb_mips_init(sbh);
-+      sbpci_init(sbh);
 +
-+      sb_serial_init(sbh, serial_add);
++      bcm47xx_pci_init();
 +
++      sb_serial_init(sbh, serial_add);
++      boardflags = getintvar(NULL, "boardflags");
++
++      /* reverse serial ports if the nvram variable kernel_args starts with console=ttyS1 */
++      s = nvram_get("kernel_args");
++      if (!s) s = "";
++      if (!strncmp(s, "console=ttyS1", 13)) {
++              for (i = num_ports; i; i--)
++                      do_serial_add(&ports[i - 1]);
++      } else {
++              for (i = 0; i < num_ports; i++)
++                      do_serial_add(&ports[i]);
++      }
++      
 +      _machine_restart = bcm47xx_machine_restart;
 +      _machine_halt = bcm47xx_machine_halt;
 +      _machine_power_off = bcm47xx_machine_halt;
 +      
 +      board_time_init = bcm47xx_time_init;
 +      board_timer_setup = bcm47xx_timer_setup;
-+      
-+      return 0;
 +}
 +
-+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-11-07 01:12:51.847811250 +0100
++EXPORT_SYMBOL(sbh);
++EXPORT_SYMBOL(sbh_lock);
++EXPORT_SYMBOL(boardflags);
+diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c
+--- linux.old/arch/mips/bcm947xx/time.c        1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/bcm947xx/time.c        2005-12-15 12:57:27.877187750 +0100
 @@ -0,0 +1,59 @@
 +/*
 + *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
@@ -13663,41 +11725,13 @@ 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-11-07 01:12:51.847811250 +0100
-@@ -555,6 +555,28 @@
-       }
+diff -urN linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c
+--- linux.old/arch/mips/kernel/cpu-probe.c     2005-12-15 13:26:49.766024000 +0100
++++ linux.dev/arch/mips/kernel/cpu-probe.c     2005-12-15 12:57:27.901177250 +0100
+@@ -656,6 +656,28 @@
  }
  
 +static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
 +{
 +      decode_config1(c);
@@ -13706,13 +11740,13 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/m
 +                      c->cputype = CPU_BCM3302;
 +                      c->isa_level = MIPS_CPU_ISA_M32;
 +                      c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-+                                      MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
++                                      MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
 +              break;
 +              case PRID_IMP_BCM4710:
 +                      c->cputype = CPU_BCM4710;
 +                      c->isa_level = MIPS_CPU_ISA_M32;
 +                      c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
-+                                      MIPS_CPU_4KTLB | MIPS_CPU_COUNTER;
++                                      MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
 +              break;
 +      default:
 +              c->cputype = CPU_UNKNOWN;
@@ -13723,21 +11757,20 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/cpu-probe.c linux-2.6.12.5-brcm/arch/m
  __init void cpu_probe(void)
  {
        struct cpuinfo_mips *c = &current_cpu_data;
-@@ -577,7 +599,9 @@
+@@ -678,6 +700,9 @@
        case PRID_COMP_SIBYTE:
                cpu_probe_sibyte(c);
                break;
--
 +      case PRID_COMP_BROADCOM:
 +              cpu_probe_broadcom(c);
 +              break;
        case PRID_COMP_SANDCRAFT:
                cpu_probe_sandcraft(c);
                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-11-07 01:12:51.847811250 +0100
-@@ -122,6 +122,14 @@
+diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S
+--- linux.old/arch/mips/kernel/head.S  2005-12-15 13:26:49.766024000 +0100
++++ linux.dev/arch/mips/kernel/head.S  2005-12-15 12:57:27.901177250 +0100
+@@ -107,6 +107,14 @@
  #endif
        .endm
  
@@ -13752,59 +11785,22 @@ diff -Nur linux-2.6.12.5/arch/mips/kernel/head.S linux-2.6.12.5-brcm/arch/mips/k
        /*
         * Reserved space for exception handlers.
         * 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-11-07 01:12:51.847811250 +0100
-@@ -75,7 +75,9 @@
-       [CPU_VR4133]    "NEC VR4133",
-       [CPU_VR4181]    "NEC VR4181",
-       [CPU_VR4181A]   "NEC VR4181A",
--      [CPU_SR71000]   "Sandcraft SR71000"
-+      [CPU_SR71000]   "Sandcraft SR71000",
-+      [CPU_BCM3302]   "Broadcom BCM3302",
-+      [CPU_BCM4710]   "Broadcom BCM4710"
+diff -urN linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c
+--- linux.old/arch/mips/kernel/proc.c  2005-12-15 13:26:49.766024000 +0100
++++ linux.dev/arch/mips/kernel/proc.c  2005-12-15 12:57:27.921168500 +0100
+@@ -82,6 +82,8 @@
+       [CPU_VR4181]    = "NEC VR4181",
+       [CPU_VR4181A]   = "NEC VR4181A",
+       [CPU_SR71000]   = "Sandcraft SR71000",
++      [CPU_BCM3302]   = "Broadcom BCM3302",
++      [CPU_BCM4710]   = "Broadcom BCM4710",
+       [CPU_PR4450]    = "Philips PR4450",
  };
  
-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-11-07 01:12:51.851811500 +0100
-@@ -851,6 +851,8 @@
+diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c
+--- linux.old/arch/mips/mm/tlbex.c     2005-12-15 13:26:49.794011750 +0100
++++ linux.dev/arch/mips/mm/tlbex.c     2005-12-15 12:57:27.945158000 +0100
+@@ -858,6 +858,8 @@
        case CPU_4KSC:
        case CPU_20KC:
        case CPU_25KF:
@@ -13813,174 +11809,10 @@ 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/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-11-07 01:12:51.851811500 +0100
-@@ -0,0 +1,23 @@
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+
-+/* Do platform specific device initialization at pci_enable_device() time */
-+int pcibios_plat_dev_init(struct pci_dev *dev)
-+{
-+      return 0;
-+}
-+
-+int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+      u8 irq;
-+      
-+      if (dev->bus->number == 1)
-+              return 2;
-+
-+      pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
-+      return irq + 2;
-+}
-+
-+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-11-07 01:12:51.851811500 +0100
-@@ -0,0 +1,44 @@
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/types.h>
-+#include <asm/pci.h>
-+
-+#include <typedefs.h>
-+#include <sbpci.h>
-+
-+extern void *sbh;
-+//extern spinlock_t bcm47xx_sbh_lock;
-+
-+static int
-+sb_pci_read_config(struct pci_bus *bus, unsigned int devfn,
-+                   int reg, int size, u32 *val)
-+{
-+      //unsigned long flags;
-+      int ret;
-+
-+
-+      //spin_lock_irqsave(&sbh_lock, flags);
-+      ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
-+      //spin_unlock_irqrestore(&sbh_lock, flags);
-+
-+      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int
-+sb_pci_write_config(struct pci_bus *bus, unsigned int devfn,
-+                    int reg, int size, u32 val)
-+{
-+//    unsigned long flags;
-+      int ret;
-+
-+//    spin_lock_irqsave(&sbh_lock, flags);
-+      ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
-+//    spin_unlock_irqrestore(&sbh_lock, flags);
-+      return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-+}
-+
-+struct pci_ops sb_pci_ops = {
-+      .read = sb_pci_read_config,
-+      .write = sb_pci_write_config,
-+};
-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-11-07 01:12:51.851811500 +0100
-@@ -0,0 +1,61 @@
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/types.h>
-+
-+#include <asm/cpu.h>
-+#include <asm/io.h>
-+
-+#include <typedefs.h>
-+#include <sbconfig.h>
-+
-+extern struct pci_ops sb_pci_ops;
-+
-+static struct resource sb_pci_mem_resource = {
-+      .name   = "SB PCI Memory resources",
-+      .start  = SB_ENUM_BASE,
-+      .end    = SB_ENUM_LIM - 1,
-+      .flags  = IORESOURCE_MEM,
-+};
-+
-+static struct resource sb_pci_io_resource = {
-+      .name   = "SB PCI I/O resources",
-+      .start  = 0x100,
-+      .end    = 0x1FF,
-+      .flags  = IORESOURCE_IO,
-+};
-+
-+static struct pci_controller bcm47xx_sb_pci_controller = {
-+      .pci_ops        = &sb_pci_ops,
-+      .mem_resource   = &sb_pci_mem_resource,
-+      .io_resource    = &sb_pci_io_resource,
-+};
-+
-+static struct resource ext_pci_mem_resource = {
-+      .name   = "Ext PCI Memory resources",
-+      .start  = SB_PCI_DMA,
-+//    .end    = 0x7FFFFFFF,
-+      .end    = 0x40FFFFFF,
-+      .flags  = IORESOURCE_MEM,
-+};
-+
-+static struct resource ext_pci_io_resource = {
-+      .name   = "Ext PCI I/O resources",
-+      .start  = 0x200,
-+      .end    = 0x2FF,
-+      .flags  = IORESOURCE_IO,
-+};
-+
-+static struct pci_controller bcm47xx_ext_pci_controller = {
-+      .pci_ops        = &sb_pci_ops,
-+      .mem_resource   = &ext_pci_mem_resource,
-+      .io_resource    = &ext_pci_io_resource,
-+};
-+
-+static int __init bcm47xx_pci_init(void)
-+{
-+      register_pci_controller(&bcm47xx_sb_pci_controller);
-+      register_pci_controller(&bcm47xx_ext_pci_controller);
-+      return 0;
-+}
-+
-+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-11-07 01:12:51.851811500 +0100
-@@ -238,7 +238,8 @@
-               if (dev->resource[i].flags & IORESOURCE_IO)
-                       offset = hose->io_offset;
-               else if (dev->resource[i].flags & IORESOURCE_MEM)
--                      offset = hose->mem_offset;
-+                      offset = 0x26000000;
-+              //      offset = hose->mem_offset;
-               dev->resource[i].start += offset;
-               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-11-07 01:12:51.851811500 +0100
-@@ -213,6 +213,12 @@
+diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h
+--- linux.old/include/asm-mips/bootinfo.h      2005-12-15 13:26:49.818001250 +0100
++++ linux.dev/include/asm-mips/bootinfo.h      2005-12-15 12:57:27.969147500 +0100
+@@ -218,6 +218,12 @@
  #define MACH_GROUP_TITAN       22     /* PMC-Sierra Titan             */
  #define  MACH_TITAN_YOSEMITE  1       /* PMC-Sierra Yosemite          */
  
@@ -13993,10 +11825,10 @@ diff -Nur linux-2.6.12.5/include/asm-mips/bootinfo.h linux-2.6.12.5-brcm/include
  #define CL_SIZE                       COMMAND_LINE_SIZE
  
  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-11-07 01:12:51.851811500 +0100
-@@ -87,6 +87,13 @@
+diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h
+--- linux.old/include/asm-mips/cpu.h   2005-12-15 13:26:49.818001250 +0100
++++ linux.dev/include/asm-mips/cpu.h   2005-12-15 12:57:27.969147500 +0100
+@@ -102,6 +102,13 @@
  #define PRID_IMP_SR71000        0x0400
  
  /*
@@ -14010,42 +11842,20 @@ diff -Nur linux-2.6.12.5/include/asm-mips/cpu.h linux-2.6.12.5-brcm/include/asm-
   * Definitions for 7:0 on legacy processors
   */
  
-@@ -177,7 +184,9 @@
- #define CPU_VR4133            56
- #define CPU_AU1550            57
- #define CPU_24K                       58
--#define CPU_LAST              58
-+#define CPU_BCM3302           59
-+#define CPU_BCM4710           60
-+#define CPU_LAST              60
+@@ -196,7 +203,9 @@
+ #define CPU_34K                       60
+ #define CPU_PR4450            61
+ #define CPU_SB1A              62
+-#define CPU_LAST              62
++#define CPU_BCM3302           63
++#define CPU_BCM4710           64
++#define CPU_LAST              64
  
  /*
   * 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-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)
- #define read_c0_config3()     __read_32bit_c0_register($16, 3)
-+#define read_c0_config4()     __read_32bit_c0_register($16, 4)
-+#define read_c0_config5()     __read_32bit_c0_register($16, 5)
-+#define read_c0_config6()     __read_32bit_c0_register($16, 6)
-+#define read_c0_config7()     __read_32bit_c0_register($16, 7)
- #define write_c0_config(val)  __write_32bit_c0_register($16, 0, val)
- #define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
- #define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
- #define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
-+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
-+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
-+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
-+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
- /*
-  * 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-11-07 01:12:51.855811750 +0100
+diff -urN linux.old/include/linux/init.h linux.dev/include/linux/init.h
+--- linux.old/include/linux/init.h     2005-12-15 13:26:49.818001250 +0100
++++ linux.dev/include/linux/init.h     2005-12-15 12:57:27.973145750 +0100
 @@ -86,6 +86,8 @@
        static initcall_t __initcall_##fn __attribute_used__ \
        __attribute__((__section__(".initcall" level ".init"))) = fn
@@ -14055,10 +11865,10 @@ diff -Nur linux-2.6.12.5/include/linux/init.h linux-2.6.12.5-brcm/include/linux/
  #define core_initcall(fn)             __define_initcall("1",fn)
  #define postcore_initcall(fn)         __define_initcall("2",fn)
  #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-11-07 01:12:51.855811750 +0100
-@@ -2110,6 +2110,7 @@
+diff -urN linux.old/include/linux/pci_ids.h linux.dev/include/linux/pci_ids.h
+--- linux.old/include/linux/pci_ids.h  2005-12-15 13:26:49.818001250 +0100
++++ linux.dev/include/linux/pci_ids.h  2005-12-15 12:57:27.977144000 +0100
+@@ -1835,6 +1835,7 @@
  #define PCI_DEVICE_ID_TIGON3_5901_2   0x170e
  #define PCI_DEVICE_ID_BCM4401         0x4401
  #define PCI_DEVICE_ID_BCM4401B0               0x4402
This page took 0.511538 seconds and 4 git commands to generate.