Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6:
  SLUB: Fix early boot GFP_DMA allocations
  SLUB: Don't print out OOM warning for __GFP_NOFAIL
  SLUB: fix build when !SLUB_DEBUG
  SLUB: Out-of-memory diagnostics
  slab: document kzfree() zeroing behavior
  slab: fix generic PAGE_POISONING conflict with SLAB_RED_ZONE
  slob: use PG_slab for identifying SLOB pages
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 3120f8d..229d7b7 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -187,7 +187,7 @@
 write_begin:		no	locks the page		yes
 write_end:		no	yes, unlocks		yes
 perform_write:		no	n/a			yes
-bmap:			yes
+bmap:			no
 invalidatepage:		no	yes
 releasepage:		no	yes
 direct_IO:		no
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 25f3b0a..b29f028 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -618,6 +618,8 @@
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_HAS_CPU_CAVIUM_OCTEON
 	select SWAP_IO_SPACE
+	select HW_HAS_PCI
+	select ARCH_SUPPORTS_MSI
 	help
 	  This option supports all of the Octeon reference boards from Cavium
 	  Networks. It builds a kernel that dynamically determines the Octeon
@@ -851,6 +853,11 @@
 config SYS_SUPPORTS_LITTLE_ENDIAN
 	bool
 
+config SYS_SUPPORTS_HUGETLBFS
+	bool
+	depends on CPU_SUPPORTS_HUGEPAGES && 64BIT
+	default y
+
 config IRQ_CPU
 	bool
 
@@ -1055,6 +1062,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  Choose this option to build a kernel for release 1 or later of the
 	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
@@ -1074,6 +1082,7 @@
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  Choose this option to build a kernel for release 2 or later of the
 	  MIPS64 architecture.  Many modern embedded systems with a 64-bit
@@ -1160,6 +1169,7 @@
 	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
 	  instruction set.
@@ -1245,6 +1255,7 @@
 	select WEAK_ORDERING
 	select WEAK_REORDERING_BEYOND_LLSC
 	select CPU_SUPPORTS_HIGHMEM
+	select CPU_SUPPORTS_HUGEPAGES
 	help
 	  The Cavium Octeon processor is a highly integrated chip containing
 	  many ethernet hardware widgets for networking tasks. The processor
@@ -1364,6 +1375,8 @@
 	bool
 config CPU_SUPPORTS_64BIT_KERNEL
 	bool
+config CPU_SUPPORTS_HUGEPAGES
+	bool
 
 #
 # Set to y for ptrace access to watch registers.
@@ -2121,6 +2134,10 @@
 
 menu "Power management options"
 
+config ARCH_HIBERNATION_POSSIBLE
+	def_bool y
+	depends on !SMP
+
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
 	depends on !SMP
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index c4cae9e..807572a 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -167,7 +167,6 @@
 libs-$(CONFIG_CFE)		+= arch/mips/fw/cfe/
 libs-$(CONFIG_SNIPROM)		+= arch/mips/fw/sni/
 libs-y				+= arch/mips/fw/lib/
-libs-$(CONFIG_SIBYTE_CFE)	+= arch/mips/sibyte/cfe/
 
 #
 # Board-dependent options and extra files
@@ -184,7 +183,6 @@
 # Common Alchemy Au1x00 stuff
 #
 core-$(CONFIG_SOC_AU1X00)	+= arch/mips/alchemy/common/
-cflags-$(CONFIG_SOC_AU1X00)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00
 
 #
 # AMD Alchemy Pb1000 eval board
@@ -282,6 +280,10 @@
 libs-$(CONFIG_MIPS_XXS1500)	+= arch/mips/alchemy/xxs1500/
 load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000
 
+# must be last for Alchemy systems for GPIO to work properly
+cflags-$(CONFIG_SOC_AU1X00)	+= -I$(srctree)/arch/mips/include/asm/mach-au1x00
+
+
 #
 # Cobalt Server
 #
@@ -675,6 +677,9 @@
 
 drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
 
+# suspend and hibernation support
+drivers-$(CONFIG_PM)	+= arch/mips/power/
+
 ifdef CONFIG_LASAT
 rom.bin rom.sw: vmlinux
 	$(Q)$(MAKE) $(build)=arch/mips/lasat/image $@
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index 8128aeb..00b498e 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -1,3 +1,14 @@
+# au1000-style gpio
+config ALCHEMY_GPIO_AU1000
+	bool
+
+# select this in your board config if you don't want to use the gpio
+# namespace as documented in the manuals.  In this case however you need
+# to create the necessary gpio_* functions in your board code/headers!
+# see arch/mips/include/asm/mach-au1x00/gpio.h   for more information.
+config ALCHEMY_GPIO_INDIRECT
+	def_bool n
+
 choice
 	prompt "Machine type"
 	depends on MACH_ALCHEMY
@@ -108,22 +119,27 @@
 config SOC_AU1000
 	bool
 	select SOC_AU1X00
+	select ALCHEMY_GPIO_AU1000
 
 config SOC_AU1100
 	bool
 	select SOC_AU1X00
+	select ALCHEMY_GPIO_AU1000
 
 config SOC_AU1500
 	bool
 	select SOC_AU1X00
+	select ALCHEMY_GPIO_AU1000
 
 config SOC_AU1550
 	bool
 	select SOC_AU1X00
+	select ALCHEMY_GPIO_AU1000
 
 config SOC_AU1200
 	bool
 	select SOC_AU1X00
+	select ALCHEMY_GPIO_AU1000
 
 config SOC_AU1X00
 	bool
@@ -134,4 +150,5 @@
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_APM_EMULATION
-	select ARCH_REQUIRE_GPIOLIB
+	select GENERIC_GPIO
+	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index d50d476..b67fb51 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -7,7 +7,14 @@
 
 obj-y += prom.o irq.o puts.o time.o reset.o \
 	clocks.o platform.o power.o setup.o \
-	sleeper.o dma.o dbdma.o gpio.o
+	sleeper.o dma.o dbdma.o
+
+# optional gpiolib support
+ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
+ ifeq ($(CONFIG_GPIOLIB),y)
+  obj-$(CONFIG_ALCHEMY_GPIO_AU1000) += gpiolib-au1000.o
+ endif
+endif
 
 obj-$(CONFIG_PCI)		+= pci.o
 
diff --git a/arch/mips/alchemy/common/gpio.c b/arch/mips/alchemy/common/gpio.c
deleted file mode 100644
index 91a9c44..0000000
--- a/arch/mips/alchemy/common/gpio.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
- *  	Architecture specific GPIO support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
- *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
- *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Notes :
- * 	au1000 SoC have only one GPIO line : GPIO1
- * 	others have a second one : GPIO2
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/gpio.h>
-
-struct au1000_gpio_chip {
-	struct gpio_chip	chip;
-	void __iomem		*regbase;
-};
-
-#if !defined(CONFIG_SOC_AU1000)
-static int au1000_gpio2_get(struct gpio_chip *chip, unsigned offset)
-{
-	u32 mask = 1 << offset;
-	struct au1000_gpio_chip *gpch;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-	return readl(gpch->regbase + AU1000_GPIO2_ST) & mask;
-}
-
-static void au1000_gpio2_set(struct gpio_chip *chip,
-				unsigned offset, int value)
-{
-	u32 mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
-	struct au1000_gpio_chip *gpch;
-	unsigned long flags;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-
-	local_irq_save(flags);
-	writel(mask, gpch->regbase + AU1000_GPIO2_OUT);
-	local_irq_restore(flags);
-}
-
-static int au1000_gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	u32 mask = 1 << offset;
-	u32 tmp;
-	struct au1000_gpio_chip *gpch;
-	unsigned long flags;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-
-	local_irq_save(flags);
-	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
-	tmp &= ~mask;
-	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-static int au1000_gpio2_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	u32 mask = 1 << offset;
-	u32 out_mask = ((GPIO2_OUT_EN_MASK << offset) | (!!value << offset));
-	u32 tmp;
-	struct au1000_gpio_chip *gpch;
-	unsigned long flags;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-
-	local_irq_save(flags);
-	tmp = readl(gpch->regbase + AU1000_GPIO2_DIR);
-	tmp |= mask;
-	writel(tmp, gpch->regbase + AU1000_GPIO2_DIR);
-	writel(out_mask, gpch->regbase + AU1000_GPIO2_OUT);
-	local_irq_restore(flags);
-
-	return 0;
-}
-#endif /* !defined(CONFIG_SOC_AU1000) */
-
-static int au1000_gpio1_get(struct gpio_chip *chip, unsigned offset)
-{
-	u32 mask = 1 << offset;
-	struct au1000_gpio_chip *gpch;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-	return readl(gpch->regbase + AU1000_GPIO1_ST) & mask;
-}
-
-static void au1000_gpio1_set(struct gpio_chip *chip,
-				unsigned offset, int value)
-{
-	u32 mask = 1 << offset;
-	u32 reg_offset;
-	struct au1000_gpio_chip *gpch;
-	unsigned long flags;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-
-	if (value)
-		reg_offset = AU1000_GPIO1_OUT;
-	else
-		reg_offset = AU1000_GPIO1_CLR;
-
-	local_irq_save(flags);
-	writel(mask, gpch->regbase + reg_offset);
-	local_irq_restore(flags);
-}
-
-static int au1000_gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
-{
-	u32 mask = 1 << offset;
-	struct au1000_gpio_chip *gpch;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-	writel(mask, gpch->regbase + AU1000_GPIO1_ST);
-
-	return 0;
-}
-
-static int au1000_gpio1_direction_output(struct gpio_chip *chip,
-					unsigned offset, int value)
-{
-	u32 mask = 1 << offset;
-	struct au1000_gpio_chip *gpch;
-
-	gpch = container_of(chip, struct au1000_gpio_chip, chip);
-
-	writel(mask, gpch->regbase + AU1000_GPIO1_TRI_OUT);
-	au1000_gpio1_set(chip, offset, value);
-
-	return 0;
-}
-
-struct au1000_gpio_chip au1000_gpio_chip[] = {
-	[0] = {
-		.regbase			= (void __iomem *)SYS_BASE,
-		.chip = {
-			.label			= "au1000-gpio1",
-			.direction_input	= au1000_gpio1_direction_input,
-			.direction_output	= au1000_gpio1_direction_output,
-			.get			= au1000_gpio1_get,
-			.set			= au1000_gpio1_set,
-			.base			= 0,
-			.ngpio			= 32,
-		},
-	},
-#if !defined(CONFIG_SOC_AU1000)
-	[1] = {
-		.regbase                        = (void __iomem *)GPIO2_BASE,
-		.chip = {
-			.label                  = "au1000-gpio2",
-			.direction_input        = au1000_gpio2_direction_input,
-			.direction_output       = au1000_gpio2_direction_output,
-			.get                    = au1000_gpio2_get,
-			.set                    = au1000_gpio2_set,
-			.base                   = AU1XXX_GPIO_BASE,
-			.ngpio                  = 32,
-		},
-	},
-#endif
-};
-
-static int __init au1000_gpio_init(void)
-{
-	gpiochip_add(&au1000_gpio_chip[0].chip);
-#if !defined(CONFIG_SOC_AU1000)
-	gpiochip_add(&au1000_gpio_chip[1].chip);
-#endif
-
-	return 0;
-}
-arch_initcall(au1000_gpio_init);
-
diff --git a/arch/mips/alchemy/common/gpiolib-au1000.c b/arch/mips/alchemy/common/gpiolib-au1000.c
new file mode 100644
index 0000000..1bfa91f
--- /dev/null
+++ b/arch/mips/alchemy/common/gpiolib-au1000.c
@@ -0,0 +1,130 @@
+/*
+ *  Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
+ *  	GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0.
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Notes :
+ * 	au1000 SoC have only one GPIO block : GPIO1
+ * 	Au1100, Au15x0, Au12x0 have a second one : GPIO2
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/gpio.h>
+
+#if !defined(CONFIG_SOC_AU1000)
+static int gpio2_get(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE);
+}
+
+static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value);
+}
+
+static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE);
+}
+
+static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset,
+				  int value)
+{
+	return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE,
+						value);
+}
+
+static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE);
+}
+#endif /* !defined(CONFIG_SOC_AU1000) */
+
+static int gpio1_get(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE);
+}
+
+static void gpio1_set(struct gpio_chip *chip,
+				unsigned offset, int value)
+{
+	alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value);
+}
+
+static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE);
+}
+
+static int gpio1_direction_output(struct gpio_chip *chip,
+					unsigned offset, int value)
+{
+	return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE,
+					     value);
+}
+
+static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE);
+}
+
+struct gpio_chip alchemy_gpio_chip[] = {
+	[0] = {
+		.label			= "alchemy-gpio1",
+		.direction_input	= gpio1_direction_input,
+		.direction_output	= gpio1_direction_output,
+		.get			= gpio1_get,
+		.set			= gpio1_set,
+		.to_irq			= gpio1_to_irq,
+		.base			= ALCHEMY_GPIO1_BASE,
+		.ngpio			= ALCHEMY_GPIO1_NUM,
+	},
+#if !defined(CONFIG_SOC_AU1000)
+	[1] = {
+		.label                  = "alchemy-gpio2",
+		.direction_input        = gpio2_direction_input,
+		.direction_output       = gpio2_direction_output,
+		.get                    = gpio2_get,
+		.set                    = gpio2_set,
+		.to_irq			= gpio2_to_irq,
+		.base                   = ALCHEMY_GPIO2_BASE,
+		.ngpio                  = ALCHEMY_GPIO2_NUM,
+	},
+#endif
+};
+
+static int __init alchemy_gpiolib_init(void)
+{
+	gpiochip_add(&alchemy_gpio_chip[0]);
+#if !defined(CONFIG_SOC_AU1000)
+	gpiochip_add(&alchemy_gpio_chip[1]);
+#endif
+
+	return 0;
+}
+arch_initcall(alchemy_gpiolib_init);
diff --git a/arch/mips/alchemy/common/reset.c b/arch/mips/alchemy/common/reset.c
index 0191c93..4791011 100644
--- a/arch/mips/alchemy/common/reset.c
+++ b/arch/mips/alchemy/common/reset.c
@@ -27,8 +27,9 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <asm/cacheflush.h>
+#include <linux/gpio.h>
 
+#include <asm/cacheflush.h>
 #include <asm/mach-au1x00/au1000.h>
 
 void au1000_restart(char *command)
@@ -161,7 +162,7 @@
 #else
 	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
 #ifdef CONFIG_MIPS_MIRAGE
-	au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
+	gpio_direction_output(210, 1);
 #endif
 #ifdef CONFIG_MIPS_DB1200
 	au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C);
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index a75ffbf..de30d8e 100644
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -27,6 +27,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/gpio.h>
 #include <linux/init.h>
 
 #include <asm/mach-au1x00/au1000.h>
@@ -94,12 +95,12 @@
 #endif
 	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
 
-#ifdef CONFIG_MIPS_MIRAGE
 	/* Enable GPIO[31:0] inputs */
-	au_writel(0, SYS_PININPUTEN);
+	alchemy_gpio1_input_enable();
 
-	/* GPIO[20] is output, tristate the other input primary GPIOs */
-	au_writel(~(1 << 20), SYS_TRIOUTCLR);
+#ifdef CONFIG_MIPS_MIRAGE
+	/* GPIO[20] is output */
+	alchemy_gpio_direction_output(20, 0);
 
 	/* Set GPIO[210:208] instead of SSI_0 */
 	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
@@ -118,8 +119,7 @@
 	 * Enable speaker amplifier.  This should
 	 * be part of the audio driver.
 	 */
-	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
-	au_writel(0x02000200, GPIO2_OUTPUT);
+	alchemy_gpio_direction_output(209, 1);
 #endif
 
 	au_sync();
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
index aed2fde..cd27354 100644
--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -24,6 +24,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/mach-au1x00/au1000.h>
@@ -130,8 +131,11 @@
 	pin_func |= SYS_PF_USB;
 
 	au_writel(pin_func, SYS_PINFUNC);
-	au_writel(0x2800, SYS_TRIOUTCLR);
-	au_writel(0x0030, SYS_OUTPUTCLR);
+
+	alchemy_gpio_direction_input(11);
+	alchemy_gpio_direction_input(13);
+	alchemy_gpio_direction_output(4, 0);
+	alchemy_gpio_direction_output(5, 0);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 	/* Make GPIO 15 an input (for interrupt line) */
@@ -140,7 +144,7 @@
 	pin_func |= SYS_PF_I2S;
 	au_writel(pin_func, SYS_PINFUNC);
 
-	au_writel(0x8000, SYS_TRIOUTCLR);
+	alchemy_gpio_direction_input(15);
 
 	static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
 	au_writel(static_cfg0, MEM_STCFG0);
diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
index 4df57fa..6126308 100644
--- a/arch/mips/alchemy/devboards/pb1100/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
@@ -23,6 +23,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -88,7 +89,7 @@
 
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
-	au_writel(0, SYS_PININPUTEN);
+	alchemy_gpio1_input_enable();
 	udelay(100);
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
index fed3b09..d7a5656 100644
--- a/arch/mips/alchemy/devboards/pb1500/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
@@ -23,8 +23,9 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
 
 #include <asm/mach-au1x00/au1000.h>
@@ -90,11 +91,12 @@
 	au_writel(0, SYS_PINSTATERD);
 	udelay(100);
 
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-
 	/* GPIO201 is input for PCMCIA card detect */
 	/* GPIO203 is input for PCMCIA interrupt request */
-	au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR);
+	alchemy_gpio_direction_input(201);
+	alchemy_gpio_direction_input(203);
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 
 	/* Zero and disable FREQ2 */
 	sys_freqctrl = au_readl(SYS_FREQCTRL0);
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c
index d5eb9c3..632f986 100644
--- a/arch/mips/alchemy/devboards/pm.c
+++ b/arch/mips/alchemy/devboards/pm.c
@@ -9,6 +9,7 @@
 #include <linux/suspend.h>
 #include <linux/sysfs.h>
 #include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/gpio.h>
 
 /*
  * Generic suspend userspace interface for Alchemy development boards.
@@ -26,7 +27,7 @@
 static int db1x_pm_enter(suspend_state_t state)
 {
 	/* enable GPIO based wakeup */
-	au_writel(1, SYS_PININPUTEN);
+	alchemy_gpio1_input_enable();
 
 	/* clear and setup wake cause and source */
 	au_writel(0, SYS_WAKEMSK);
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
index 8ed1ae1..cc32c69 100644
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -28,6 +28,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/gpio.h>
 #include <linux/init.h>
 
 #include <asm/mach-au1x00/au1000.h>
@@ -55,10 +56,11 @@
 	}
 #endif
 
+	alchemy_gpio2_enable();
+
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
 	/* Enable USB power switch */
-	au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
-	au_writel(0x100000, GPIO2_OUTPUT);
+	alchemy_gpio_direction_output(204, 0);
 #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
 
 #ifdef CONFIG_PCI
@@ -74,14 +76,14 @@
 
 	/* Initialize GPIO */
 	au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
-	au_writel(0x00000001, SYS_OUTPUTCLR); /* set M66EN (PCI 66MHz) to OFF */
-	au_writel(0x00000008, SYS_OUTPUTSET); /* set PCI CLKRUN# to OFF */
-	au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
-	au_writel(0x00000020, SYS_OUTPUTCLR); /* set eth PHY TX_ER to OFF */
+	alchemy_gpio_direction_output(0, 0);	/* Disable M66EN (PCI 66MHz) */
+	alchemy_gpio_direction_output(3, 1);	/* Disable PCI CLKRUN# */
+	alchemy_gpio_direction_output(1, 1);	/* Enable EXT_IO3 */
+	alchemy_gpio_direction_output(5, 0);	/* Disable eth PHY TX_ER */
 
 	/* Enable LED and set it to green */
-	au_writel(au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR);
-	au_writel(0x18000800, GPIO2_OUTPUT);
+	alchemy_gpio_direction_output(211, 1);	/* green on */
+	alchemy_gpio_direction_output(212, 0);	/* red off */
 
 	board_pci_idsel = mtx1_pci_idsel;
 
@@ -101,10 +103,10 @@
 
 	if (assert && devsel != 0)
 		/* Suppress signal to Cardbus */
-		au_writel(0x00000002, SYS_OUTPUTCLR); /* set EXT_IO3 OFF */
+		gpio_set_value(1, 0);	/* set EXT_IO3 OFF */
 	else
-		au_writel(0x00000002, SYS_OUTPUTSET); /* set EXT_IO3 ON */
+		gpio_set_value(1, 1);	/* set EXT_IO3 ON */
+
 	au_sync_udelay(1);
 	return 1;
 }
-
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
index a2634fa..4de2d48 100644
--- a/arch/mips/alchemy/xxs1500/board_setup.c
+++ b/arch/mips/alchemy/xxs1500/board_setup.c
@@ -23,6 +23,7 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
@@ -50,6 +51,9 @@
 	}
 #endif
 
+	alchemy_gpio1_input_enable();
+	alchemy_gpio2_enable();
+
 	/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
 	pin_func  = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
 	pin_func |= SYS_PF_UR3;
@@ -65,20 +69,19 @@
 	au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
 
 #ifdef CONFIG_PCMCIA_XXS1500
-	/* Setup PCMCIA signals */
-	au_writel(0, SYS_PININPUTEN);
-
 	/* GPIO 0, 1, and 4 are inputs */
-	au_writel(1 | (1 << 1) | (1 << 4), SYS_TRIOUTCLR);
+	alchemy_gpio_direction_input(0);
+	alchemy_gpio_direction_input(1);
+	alchemy_gpio_direction_input(4);
 
-	/* Enable GPIO2 if not already enabled */
-	au_writel(1, GPIO2_ENABLE);
 	/* GPIO2 208/9/10/11 are inputs */
-	au_writel((1 << 8) | (1 << 9) | (1 << 10) | (1 << 11), GPIO2_DIR);
+	alchemy_gpio_direction_input(208);
+	alchemy_gpio_direction_input(209);
+	alchemy_gpio_direction_input(210);
+	alchemy_gpio_direction_input(211);
 
 	/* Turn off power */
-	au_writel((au_readl(GPIO2_PINSTATE) & ~(1 << 14)) | (1 << 30),
-		  GPIO2_OUTPUT);
+	alchemy_gpio_direction_output(214, 0);
 #endif
 
 #ifdef CONFIG_PCI
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index d6903c3..7c0528b 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -14,5 +14,9 @@
 obj-y += octeon-memcpy.o
 
 obj-$(CONFIG_SMP)                     += smp.o
+obj-$(CONFIG_PCI)                     += pci-common.o
+obj-$(CONFIG_PCI)                     += pci.o
+obj-$(CONFIG_PCI)                     += pcie.o
+obj-$(CONFIG_PCI_MSI)                 += msi.o
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 01b1ef9..627c162 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -13,20 +13,327 @@
  */
 #include <linux/types.h>
 #include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+
+#include <linux/cache.h>
+#include <linux/io.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
 
 #include <dma-coherence.h>
 
+#ifdef CONFIG_PCI
+#include "pci-common.h"
+#endif
+
+#define BAR2_PCI_ADDRESS 0x8000000000ul
+
+struct bar1_index_state {
+	int16_t ref_count;	/* Number of PCI mappings using this index */
+	uint16_t address_bits;	/* Upper bits of physical address. This is
+				   shifted 22 bits */
+};
+
+#ifdef CONFIG_PCI
+static DEFINE_SPINLOCK(bar1_lock);
+static struct bar1_index_state bar1_state[32];
+#endif
+
 dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
 {
+#ifndef CONFIG_PCI
 	/* Without PCI/PCIe this function can be called for Octeon internal
 	   devices such as USB. These devices all support 64bit addressing */
 	mb();
 	return virt_to_phys(ptr);
+#else
+	unsigned long flags;
+	uint64_t dma_mask;
+	int64_t start_index;
+	dma_addr_t result = -1;
+	uint64_t physical = virt_to_phys(ptr);
+	int64_t index;
+
+	mb();
+	/*
+	 * Use the DMA masks to determine the allowed memory
+	 * region. For us it doesn't limit the actual memory, just the
+	 * address visible over PCI.  Devices with limits need to use
+	 * lower indexed Bar1 entries.
+	 */
+	if (dev) {
+		dma_mask = dev->coherent_dma_mask;
+		if (dev->dma_mask)
+			dma_mask = *dev->dma_mask;
+	} else {
+		dma_mask = 0xfffffffful;
+	}
+
+	/*
+	 * Platform devices, such as the internal USB, skip all
+	 * translation and use Octeon physical addresses directly.
+	 */
+	if (!dev || dev->bus == &platform_bus_type)
+		return physical;
+
+	switch (octeon_dma_bar_type) {
+	case OCTEON_DMA_BAR_TYPE_PCIE:
+		if (unlikely(physical < (16ul << 10)))
+			panic("dma_map_single: Not allowed to map first 16KB."
+			      " It interferes with BAR0 special area\n");
+		else if ((physical + size >= (256ul << 20)) &&
+			 (physical < (512ul << 20)))
+			panic("dma_map_single: Not allowed to map bootbus\n");
+		else if ((physical + size >= 0x400000000ull) &&
+			 physical < 0x410000000ull)
+			panic("dma_map_single: "
+			      "Attempt to map illegal memory address 0x%llx\n",
+			      physical);
+		else if (physical >= 0x420000000ull)
+			panic("dma_map_single: "
+			      "Attempt to map illegal memory address 0x%llx\n",
+			      physical);
+		else if ((physical + size >=
+			  (4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20))
+			 && physical < (4ull<<30))
+			pr_warning("dma_map_single: Warning: "
+				   "Mapping memory address that might "
+				   "conflict with devices 0x%llx-0x%llx\n",
+				   physical, physical+size-1);
+		/* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */
+		if ((physical >= 0x410000000ull) && physical < 0x420000000ull)
+			result = physical - 0x400000000ull;
+		else
+			result = physical;
+		if (((result+size-1) & dma_mask) != result+size-1)
+			panic("dma_map_single: Attempt to map address "
+			      "0x%llx-0x%llx, which can't be accessed "
+			      "according to the dma mask 0x%llx\n",
+			      physical, physical+size-1, dma_mask);
+		goto done;
+
+	case OCTEON_DMA_BAR_TYPE_BIG:
+#ifdef CONFIG_64BIT
+		/* If the device supports 64bit addressing, then use BAR2 */
+		if (dma_mask > BAR2_PCI_ADDRESS) {
+			result = physical + BAR2_PCI_ADDRESS;
+			goto done;
+		}
+#endif
+		if (unlikely(physical < (4ul << 10))) {
+			panic("dma_map_single: Not allowed to map first 4KB. "
+			      "It interferes with BAR0 special area\n");
+		} else if (physical < (256ul << 20)) {
+			if (unlikely(physical + size > (256ul << 20)))
+				panic("dma_map_single: Requested memory spans "
+				      "Bar0 0:256MB and bootbus\n");
+			result = physical;
+			goto done;
+		} else if (unlikely(physical < (512ul << 20))) {
+			panic("dma_map_single: Not allowed to map bootbus\n");
+		} else if (physical < (2ul << 30)) {
+			if (unlikely(physical + size > (2ul << 30)))
+				panic("dma_map_single: Requested memory spans "
+				      "Bar0 512MB:2GB and BAR1\n");
+			result = physical;
+			goto done;
+		} else if (physical < (2ul << 30) + (128 << 20)) {
+			/* Fall through */
+		} else if (physical <
+			   (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)) {
+			if (unlikely
+			    (physical + size >
+			     (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20)))
+				panic("dma_map_single: Requested memory "
+				      "extends past Bar1 (4GB-%luMB)\n",
+				      OCTEON_PCI_BAR1_HOLE_SIZE);
+			result = physical;
+			goto done;
+		} else if ((physical >= 0x410000000ull) &&
+			   (physical < 0x420000000ull)) {
+			if (unlikely(physical + size > 0x420000000ull))
+				panic("dma_map_single: Requested memory spans "
+				      "non existant memory\n");
+			/* BAR0 fixed mapping 256MB:512MB ->
+			 * 16GB+256MB:16GB+512MB */
+			result = physical - 0x400000000ull;
+			goto done;
+		} else {
+			/* Continued below switch statement */
+		}
+		break;
+
+	case OCTEON_DMA_BAR_TYPE_SMALL:
+#ifdef CONFIG_64BIT
+		/* If the device supports 64bit addressing, then use BAR2 */
+		if (dma_mask > BAR2_PCI_ADDRESS) {
+			result = physical + BAR2_PCI_ADDRESS;
+			goto done;
+		}
+#endif
+		/* Continued below switch statement */
+		break;
+
+	default:
+		panic("dma_map_single: Invalid octeon_dma_bar_type\n");
+	}
+
+	/* Don't allow mapping to span multiple Bar entries. The hardware guys
+	   won't guarantee that DMA across boards work */
+	if (unlikely((physical >> 22) != ((physical + size - 1) >> 22)))
+		panic("dma_map_single: "
+		      "Requested memory spans more than one Bar1 entry\n");
+
+	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+		start_index = 31;
+	else if (unlikely(dma_mask < (1ul << 27)))
+		start_index = (dma_mask >> 22);
+	else
+		start_index = 31;
+
+	/* Only one processor can access the Bar register at once */
+	spin_lock_irqsave(&bar1_lock, flags);
+
+	/* Look through Bar1 for existing mapping that will work */
+	for (index = start_index; index >= 0; index--) {
+		if ((bar1_state[index].address_bits == physical >> 22) &&
+		    (bar1_state[index].ref_count)) {
+			/* An existing mapping will work, use it */
+			bar1_state[index].ref_count++;
+			if (unlikely(bar1_state[index].ref_count < 0))
+				panic("dma_map_single: "
+				      "Bar1[%d] reference count overflowed\n",
+				      (int) index);
+			result = (index << 22) | (physical & ((1 << 22) - 1));
+			/* Large BAR1 is offset at 2GB */
+			if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+				result += 2ul << 30;
+			goto done_unlock;
+		}
+	}
+
+	/* No existing mappings, look for a free entry */
+	for (index = start_index; index >= 0; index--) {
+		if (unlikely(bar1_state[index].ref_count == 0)) {
+			union cvmx_pci_bar1_indexx bar1_index;
+			/* We have a free entry, use it */
+			bar1_state[index].ref_count = 1;
+			bar1_state[index].address_bits = physical >> 22;
+			bar1_index.u32 = 0;
+			/* Address bits[35:22] sent to L2C */
+			bar1_index.s.addr_idx = physical >> 22;
+			/* Don't put PCI accesses in L2. */
+			bar1_index.s.ca = 1;
+			/* Endian Swap Mode */
+			bar1_index.s.end_swp = 1;
+			/* Set '1' when the selected address range is valid. */
+			bar1_index.s.addr_v = 1;
+			octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index),
+					   bar1_index.u32);
+			/* An existing mapping will work, use it */
+			result = (index << 22) | (physical & ((1 << 22) - 1));
+			/* Large BAR1 is offset at 2GB */
+			if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG)
+				result += 2ul << 30;
+			goto done_unlock;
+		}
+	}
+
+	pr_err("dma_map_single: "
+	       "Can't find empty BAR1 index for physical mapping 0x%llx\n",
+	       (unsigned long long) physical);
+
+done_unlock:
+	spin_unlock_irqrestore(&bar1_lock, flags);
+done:
+	pr_debug("dma_map_single 0x%llx->0x%llx\n", physical, result);
+	return result;
+#endif
 }
 
 void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
 {
-	/* Without PCI/PCIe this function can be called for Octeon internal
-	 * devices such as USB. These devices all support 64bit addressing */
+#ifndef CONFIG_PCI
+	/*
+	 * Without PCI/PCIe this function can be called for Octeon internal
+	 * devices such as USB. These devices all support 64bit addressing.
+	 */
 	return;
+#else
+	unsigned long flags;
+	uint64_t index;
+
+	/*
+	 * Platform devices, such as the internal USB, skip all
+	 * translation and use Octeon physical addresses directly.
+	 */
+	if (dev->bus == &platform_bus_type)
+		return;
+
+	switch (octeon_dma_bar_type) {
+	case OCTEON_DMA_BAR_TYPE_PCIE:
+		/* Nothing to do, all mappings are static */
+		goto done;
+
+	case OCTEON_DMA_BAR_TYPE_BIG:
+#ifdef CONFIG_64BIT
+		/* Nothing to do for addresses using BAR2 */
+		if (dma_addr >= BAR2_PCI_ADDRESS)
+			goto done;
+#endif
+		if (unlikely(dma_addr < (4ul << 10)))
+			panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
+			      dma_addr);
+		else if (dma_addr < (2ul << 30))
+			/* Nothing to do for addresses using BAR0 */
+			goto done;
+		else if (dma_addr < (2ul << 30) + (128ul << 20))
+			/* Need to unmap, fall through */
+			index = (dma_addr - (2ul << 30)) >> 22;
+		else if (dma_addr <
+			 (4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20))
+			goto done;	/* Nothing to do for the rest of BAR1 */
+		else
+			panic("dma_unmap_single: Unexpect DMA address 0x%llx\n",
+			      dma_addr);
+		/* Continued below switch statement */
+		break;
+
+	case OCTEON_DMA_BAR_TYPE_SMALL:
+#ifdef CONFIG_64BIT
+		/* Nothing to do for addresses using BAR2 */
+		if (dma_addr >= BAR2_PCI_ADDRESS)
+			goto done;
+#endif
+		index = dma_addr >> 22;
+		/* Continued below switch statement */
+		break;
+
+	default:
+		panic("dma_unmap_single: Invalid octeon_dma_bar_type\n");
+	}
+
+	if (unlikely(index > 31))
+		panic("dma_unmap_single: "
+		      "Attempt to unmap an invalid address (0x%llx)\n",
+		      dma_addr);
+
+	spin_lock_irqsave(&bar1_lock, flags);
+	bar1_state[index].ref_count--;
+	if (bar1_state[index].ref_count == 0)
+		octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+	else if (unlikely(bar1_state[index].ref_count < 0))
+		panic("dma_unmap_single: Bar1[%u] reference count < 0\n",
+		      (int) index);
+	spin_unlock_irqrestore(&bar1_lock, flags);
+done:
+	pr_debug("dma_unmap_single 0x%llx\n", dma_addr);
+	return;
+#endif
 }
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
index 80d6cb2..2fd66db 100644
--- a/arch/mips/cavium-octeon/executive/Makefile
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -11,3 +11,4 @@
 
 obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
 
+obj-$(CONFIG_PCI) += cvmx-helper-errata.o cvmx-helper-jtag.o
diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
index 4f5a08b..25666da 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
@@ -31,6 +31,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 #include <asm/octeon/cvmx.h>
 #include <asm/octeon/cvmx-spinlock.h>
@@ -97,6 +98,33 @@
 	return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
 }
 
+void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+				     uint64_t max_addr, uint64_t align,
+				     char *name)
+{
+	int64_t addr;
+
+	addr = cvmx_bootmem_phy_named_block_alloc(size, min_addr, max_addr,
+						  align, name, 0);
+	if (addr >= 0)
+		return cvmx_phys_to_ptr(addr);
+	else
+		return NULL;
+}
+
+void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+				       char *name)
+{
+    return cvmx_bootmem_alloc_named_range(size, address, address + size,
+					  0, name);
+}
+
+void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment, char *name)
+{
+    return cvmx_bootmem_alloc_named_range(size, 0, 0, alignment, name);
+}
+EXPORT_SYMBOL(cvmx_bootmem_alloc_named);
+
 int cvmx_bootmem_free_named(char *name)
 {
 	return cvmx_bootmem_phy_named_block_free(name, 0);
@@ -106,6 +134,7 @@
 {
 	return cvmx_bootmem_phy_named_block_find(name, 0);
 }
+EXPORT_SYMBOL(cvmx_bootmem_find_named_block);
 
 void cvmx_bootmem_lock(void)
 {
@@ -584,3 +613,78 @@
 	cvmx_bootmem_unlock();
 	return named_block_ptr != NULL;	/* 0 on failure, 1 on success */
 }
+
+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
+					   uint64_t max_addr,
+					   uint64_t alignment,
+					   char *name,
+					   uint32_t flags)
+{
+	int64_t addr_allocated;
+	struct cvmx_bootmem_named_block_desc *named_block_desc_ptr;
+
+#ifdef DEBUG
+	cvmx_dprintf("cvmx_bootmem_phy_named_block_alloc: size: 0x%llx, min: "
+		     "0x%llx, max: 0x%llx, align: 0x%llx, name: %s\n",
+		     (unsigned long long)size,
+		     (unsigned long long)min_addr,
+		     (unsigned long long)max_addr,
+		     (unsigned long long)alignment,
+		     name);
+#endif
+	if (cvmx_bootmem_desc->major_version != 3) {
+		cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
+			     "%d.%d at addr: %p\n",
+			     (int)cvmx_bootmem_desc->major_version,
+			     (int)cvmx_bootmem_desc->minor_version,
+			     cvmx_bootmem_desc);
+		return -1;
+	}
+
+	/*
+	 * Take lock here, as name lookup/block alloc/name add need to
+	 * be atomic.
+	 */
+	if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+		cvmx_spinlock_lock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+
+	/* Get pointer to first available named block descriptor */
+	named_block_desc_ptr =
+		cvmx_bootmem_phy_named_block_find(NULL,
+						  flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
+
+	/*
+	 * Check to see if name already in use, return error if name
+	 * not available or no more room for blocks.
+	 */
+	if (cvmx_bootmem_phy_named_block_find(name,
+					      flags | CVMX_BOOTMEM_FLAG_NO_LOCKING) || !named_block_desc_ptr) {
+		if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+			cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+		return -1;
+	}
+
+
+	/*
+	 * Round size up to mult of minimum alignment bytes We need
+	 * the actual size allocated to allow for blocks to be
+	 * coallesced when they are freed.  The alloc routine does the
+	 * same rounding up on all allocations.
+	 */
+	size = __ALIGN_MASK(size, (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1));
+
+	addr_allocated = cvmx_bootmem_phy_alloc(size, min_addr, max_addr,
+						alignment,
+						flags | CVMX_BOOTMEM_FLAG_NO_LOCKING);
+	if (addr_allocated >= 0) {
+		named_block_desc_ptr->base_addr = addr_allocated;
+		named_block_desc_ptr->size = size;
+		strncpy(named_block_desc_ptr->name, name,
+			cvmx_bootmem_desc->named_block_name_len);
+		named_block_desc_ptr->name[cvmx_bootmem_desc->named_block_name_len - 1] = 0;
+	}
+
+	if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+		cvmx_spinlock_unlock((cvmx_spinlock_t *)&(cvmx_bootmem_desc->lock));
+	return addr_allocated;
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
new file mode 100644
index 0000000..868659e
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-errata.c
@@ -0,0 +1,73 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Fixes and workaround for Octeon chip errata. This file
+ * contains functions called by cvmx-helper to workaround known
+ * chip errata. For the most part, code doesn't need to call
+ * these functions directly.
+ *
+ */
+#include <linux/module.h>
+
+#include <asm/octeon/octeon.h>
+
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+/**
+ * Due to errata G-720, the 2nd order CDR circuit on CN52XX pass
+ * 1 doesn't work properly. The following code disables 2nd order
+ * CDR for the specified QLM.
+ *
+ * @qlm:    QLM to disable 2nd order CDR for.
+ */
+void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm)
+{
+	int lane;
+	cvmx_helper_qlm_jtag_init();
+	/* We need to load all four lanes of the QLM, a total of 1072 bits */
+	for (lane = 0; lane < 4; lane++) {
+		/*
+		 * Each lane has 268 bits. We need to set
+		 * cfg_cdr_incx<67:64> = 3 and cfg_cdr_secord<77> =
+		 * 1. All other bits are zero. Bits go in LSB first,
+		 * so start off with the zeros for bits <63:0>.
+		 */
+		cvmx_helper_qlm_jtag_shift_zeros(qlm, 63 - 0 + 1);
+		/* cfg_cdr_incx<67:64>=3 */
+		cvmx_helper_qlm_jtag_shift(qlm, 67 - 64 + 1, 3);
+		/* Zeros for bits <76:68> */
+		cvmx_helper_qlm_jtag_shift_zeros(qlm, 76 - 68 + 1);
+		/* cfg_cdr_secord<77>=1 */
+		cvmx_helper_qlm_jtag_shift(qlm, 77 - 77 + 1, 1);
+		/* Zeros for bits <267:78> */
+		cvmx_helper_qlm_jtag_shift_zeros(qlm, 267 - 78 + 1);
+	}
+	cvmx_helper_qlm_jtag_update(qlm);
+}
+EXPORT_SYMBOL(__cvmx_helper_errata_qlm_disable_2nd_order_cdr);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
new file mode 100644
index 0000000..c1c5489
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-jtag.c
@@ -0,0 +1,144 @@
+
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Helper utilities for qlm_jtag.
+ *
+ */
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-helper-jtag.h>
+
+
+/**
+ * Initialize the internal QLM JTAG logic to allow programming
+ * of the JTAG chain by the cvmx_helper_qlm_jtag_*() functions.
+ * These functions should only be used at the direction of Cavium
+ * Networks. Programming incorrect values into the JTAG chain
+ * can cause chip damage.
+ */
+void cvmx_helper_qlm_jtag_init(void)
+{
+	union cvmx_ciu_qlm_jtgc jtgc;
+	uint32_t clock_div = 0;
+	uint32_t divisor = cvmx_sysinfo_get()->cpu_clock_hz / (25 * 1000000);
+	divisor = (divisor - 1) >> 2;
+	/* Convert the divisor into a power of 2 shift */
+	while (divisor) {
+		clock_div++;
+		divisor = divisor >> 1;
+	}
+
+	/*
+	 * Clock divider for QLM JTAG operations.  eclk is divided by
+	 * 2^(CLK_DIV + 2)
+	 */
+	jtgc.u64 = 0;
+	jtgc.s.clk_div = clock_div;
+	jtgc.s.mux_sel = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+		jtgc.s.bypass = 0x3;
+	else
+		jtgc.s.bypass = 0xf;
+	cvmx_write_csr(CVMX_CIU_QLM_JTGC, jtgc.u64);
+	cvmx_read_csr(CVMX_CIU_QLM_JTGC);
+}
+
+/**
+ * Write up to 32bits into the QLM jtag chain. Bits are shifted
+ * into the MSB and out the LSB, so you should shift in the low
+ * order bits followed by the high order bits. The JTAG chain is
+ * 4 * 268 bits long, or 1072.
+ *
+ * @qlm:    QLM to shift value into
+ * @bits:   Number of bits to shift in (1-32).
+ * @data:   Data to shift in. Bit 0 enters the chain first, followed by
+ *               bit 1, etc.
+ *
+ * Returns The low order bits of the JTAG chain that shifted out of the
+ *         circle.
+ */
+uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data)
+{
+	union cvmx_ciu_qlm_jtgd jtgd;
+	jtgd.u64 = 0;
+	jtgd.s.shift = 1;
+	jtgd.s.shft_cnt = bits - 1;
+	jtgd.s.shft_reg = data;
+	if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+		jtgd.s.select = 1 << qlm;
+	cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+	do {
+		jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+	} while (jtgd.s.shift);
+	return jtgd.s.shft_reg >> (32 - bits);
+}
+
+/**
+ * Shift long sequences of zeros into the QLM JTAG chain. It is
+ * common to need to shift more than 32 bits of zeros into the
+ * chain. This function is a convience wrapper around
+ * cvmx_helper_qlm_jtag_shift() to shift more than 32 bits of
+ * zeros at a time.
+ *
+ * @qlm:    QLM to shift zeros into
+ * @bits:
+ */
+void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits)
+{
+	while (bits > 0) {
+		int n = bits;
+		if (n > 32)
+			n = 32;
+		cvmx_helper_qlm_jtag_shift(qlm, n, 0);
+		bits -= n;
+	}
+}
+
+/**
+ * Program the QLM JTAG chain into all lanes of the QLM. You must
+ * have already shifted in 268*4, or 1072 bits into the JTAG
+ * chain. Updating invalid values can possibly cause chip damage.
+ *
+ * @qlm:    QLM to program
+ */
+void cvmx_helper_qlm_jtag_update(int qlm)
+{
+	union cvmx_ciu_qlm_jtgd jtgd;
+
+	/* Update the new data */
+	jtgd.u64 = 0;
+	jtgd.s.update = 1;
+	if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+		jtgd.s.select = 1 << qlm;
+	cvmx_write_csr(CVMX_CIU_QLM_JTGD, jtgd.u64);
+	do {
+		jtgd.u64 = cvmx_read_csr(CVMX_CIU_QLM_JTGD);
+	} while (jtgd.s.update);
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
index 48123707..e583889 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
@@ -29,6 +29,7 @@
  * This module provides system/board/application information obtained
  * by the bootloader.
  */
+#include <linux/module.h>
 
 #include <asm/octeon/cvmx.h>
 #include <asm/octeon/cvmx-spinlock.h>
@@ -69,6 +70,7 @@
 {
 	return &(state.sysinfo);
 }
+EXPORT_SYMBOL(cvmx_sysinfo_get);
 
 /**
  * This function is used in non-simple executive environments (such as
diff --git a/arch/mips/cavium-octeon/msi.c b/arch/mips/cavium-octeon/msi.c
new file mode 100644
index 0000000..964b03b
--- /dev/null
+++ b/arch/mips/cavium-octeon/msi.c
@@ -0,0 +1,288 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/msi.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+
+#include "pci-common.h"
+
+/*
+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
+ * in use.
+ */
+static uint64_t msi_free_irq_bitmask;
+
+/*
+ * Each bit in msi_multiple_irq_bitmask tells that the device using
+ * this bit in msi_free_irq_bitmask is also using the next bit. This
+ * is used so we can disable all of the MSI interrupts when a device
+ * uses multiple.
+ */
+static uint64_t msi_multiple_irq_bitmask;
+
+/*
+ * This lock controls updates to msi_free_irq_bitmask and
+ * msi_multiple_irq_bitmask.
+ */
+static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
+
+
+/**
+ * Called when a driver request MSI interrupts instead of the
+ * legacy INT A-D. This routine will allocate multiple interrupts
+ * for MSI devices that support them. A device can override this by
+ * programming the MSI control bits [6:4] before calling
+ * pci_enable_msi().
+ *
+ * @param dev    Device requesting MSI interrupts
+ * @param desc   MSI descriptor
+ *
+ * Returns 0 on success.
+ */
+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+	struct msi_msg msg;
+	uint16_t control;
+	int configured_private_bits;
+	int request_private_bits;
+	int irq;
+	int irq_step;
+	uint64_t search_mask;
+
+	/*
+	 * Read the MSI config to figure out how many IRQs this device
+	 * wants.  Most devices only want 1, which will give
+	 * configured_private_bits and request_private_bits equal 0.
+	 */
+	pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+			     &control);
+
+	/*
+	 * If the number of private bits has been configured then use
+	 * that value instead of the requested number. This gives the
+	 * driver the chance to override the number of interrupts
+	 * before calling pci_enable_msi().
+	 */
+	configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
+	if (configured_private_bits == 0) {
+		/* Nothing is configured, so use the hardware requested size */
+		request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
+	} else {
+		/*
+		 * Use the number of configured bits, assuming the
+		 * driver wanted to override the hardware request
+		 * value.
+		 */
+		request_private_bits = configured_private_bits;
+	}
+
+	/*
+	 * The PCI 2.3 spec mandates that there are at most 32
+	 * interrupts. If this device asks for more, only give it one.
+	 */
+	if (request_private_bits > 5)
+		request_private_bits = 0;
+
+try_only_one:
+	/*
+	 * The IRQs have to be aligned on a power of two based on the
+	 * number being requested.
+	 */
+	irq_step = 1 << request_private_bits;
+
+	/* Mask with one bit for each IRQ */
+	search_mask = (1 << irq_step) - 1;
+
+	/*
+	 * We're going to search msi_free_irq_bitmask_lock for zero
+	 * bits. This represents an MSI interrupt number that isn't in
+	 * use.
+	 */
+	spin_lock(&msi_free_irq_bitmask_lock);
+	for (irq = 0; irq < 64; irq += irq_step) {
+		if ((msi_free_irq_bitmask & (search_mask << irq)) == 0) {
+			msi_free_irq_bitmask |= search_mask << irq;
+			msi_multiple_irq_bitmask |= (search_mask >> 1) << irq;
+			break;
+		}
+	}
+	spin_unlock(&msi_free_irq_bitmask_lock);
+
+	/* Make sure the search for available interrupts didn't fail */
+	if (irq >= 64) {
+		if (request_private_bits) {
+			pr_err("arch_setup_msi_irq: Unable to find %d free "
+			       "interrupts, trying just one",
+			       1 << request_private_bits);
+			request_private_bits = 0;
+			goto try_only_one;
+		} else
+			panic("arch_setup_msi_irq: Unable to find a free MSI "
+			      "interrupt");
+	}
+
+	/* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
+	irq += OCTEON_IRQ_MSI_BIT0;
+
+	switch (octeon_dma_bar_type) {
+	case OCTEON_DMA_BAR_TYPE_SMALL:
+		/* When not using big bar, Bar 0 is based at 128MB */
+		msg.address_lo =
+			((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff;
+		msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32;
+	case OCTEON_DMA_BAR_TYPE_BIG:
+		/* When using big bar, Bar 0 is based at 0 */
+		msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff;
+		msg.address_hi = (0 + CVMX_PCI_MSI_RCV) >> 32;
+		break;
+	case OCTEON_DMA_BAR_TYPE_PCIE:
+		/* When using PCIe, Bar 0 is based at 0 */
+		/* FIXME CVMX_NPEI_MSI_RCV* other than 0? */
+		msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff;
+		msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32;
+		break;
+	default:
+		panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type\n");
+	}
+	msg.data = irq - OCTEON_IRQ_MSI_BIT0;
+
+	/* Update the number of IRQs the device has available to it */
+	control &= ~PCI_MSI_FLAGS_QSIZE;
+	control |= request_private_bits << 4;
+	pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
+			      control);
+
+	set_irq_msi(irq, desc);
+	write_msi_msg(irq, &msg);
+	return 0;
+}
+
+
+/**
+ * Called when a device no longer needs its MSI interrupts. All
+ * MSI interrupts for the device are freed.
+ *
+ * @irq:    The devices first irq number. There may be multple in sequence.
+ */
+void arch_teardown_msi_irq(unsigned int irq)
+{
+	int number_irqs;
+	uint64_t bitmask;
+
+	if ((irq < OCTEON_IRQ_MSI_BIT0) || (irq > OCTEON_IRQ_MSI_BIT63))
+		panic("arch_teardown_msi_irq: Attempted to teardown illegal "
+		      "MSI interrupt (%d)", irq);
+	irq -= OCTEON_IRQ_MSI_BIT0;
+
+	/*
+	 * Count the number of IRQs we need to free by looking at the
+	 * msi_multiple_irq_bitmask. Each bit set means that the next
+	 * IRQ is also owned by this device.
+	 */
+	number_irqs = 0;
+	while ((irq+number_irqs < 64) &&
+	       (msi_multiple_irq_bitmask & (1ull << (irq + number_irqs))))
+		number_irqs++;
+	number_irqs++;
+	/* Mask with one bit for each IRQ */
+	bitmask = (1 << number_irqs) - 1;
+	/* Shift the mask to the correct bit location */
+	bitmask <<= irq;
+	if ((msi_free_irq_bitmask & bitmask) != bitmask)
+		panic("arch_teardown_msi_irq: Attempted to teardown MSI "
+		      "interrupt (%d) not in use", irq);
+
+	/* Checks are done, update the in use bitmask */
+	spin_lock(&msi_free_irq_bitmask_lock);
+	msi_free_irq_bitmask &= ~bitmask;
+	msi_multiple_irq_bitmask &= ~bitmask;
+	spin_unlock(&msi_free_irq_bitmask_lock);
+}
+
+
+/**
+ * Called by the interrupt handling code when an MSI interrupt
+ * occurs.
+ *
+ * @param cpl
+ * @param dev_id
+ *
+ * @return
+ */
+static irqreturn_t octeon_msi_interrupt(int cpl, void *dev_id)
+{
+	uint64_t msi_bits;
+	int irq;
+
+	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE)
+		msi_bits = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_RCV0);
+	else
+		msi_bits = cvmx_read_csr(CVMX_NPI_NPI_MSI_RCV);
+	irq = fls64(msi_bits);
+	if (irq) {
+		irq += OCTEON_IRQ_MSI_BIT0 - 1;
+		if (irq_desc[irq].action) {
+			do_IRQ(irq);
+			return IRQ_HANDLED;
+		} else {
+			pr_err("Spurious MSI interrupt %d\n", irq);
+			if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+				/* These chips have PCIe */
+				cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
+					       1ull << (irq -
+							OCTEON_IRQ_MSI_BIT0));
+			} else {
+				/* These chips have PCI */
+				cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
+					       1ull << (irq -
+							OCTEON_IRQ_MSI_BIT0));
+			}
+		}
+	}
+	return IRQ_NONE;
+}
+
+
+/**
+ * Initializes the MSI interrupt handling code
+ *
+ * @return
+ */
+int octeon_msi_initialize(void)
+{
+	int r;
+	if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+		r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
+				IRQF_SHARED,
+				"MSI[0:63]", octeon_msi_interrupt);
+	} else if (octeon_is_pci_host()) {
+		r = request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt,
+				IRQF_SHARED,
+				"MSI[0:15]", octeon_msi_interrupt);
+		r += request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt,
+				 IRQF_SHARED,
+				 "MSI[16:31]", octeon_msi_interrupt);
+		r += request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt,
+				 IRQF_SHARED,
+				 "MSI[32:47]", octeon_msi_interrupt);
+		r += request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt,
+				 IRQF_SHARED,
+				 "MSI[48:63]", octeon_msi_interrupt);
+	}
+	return 0;
+}
+
+subsys_initcall(octeon_msi_initialize);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index d3a0c81..8dfa009 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -10,6 +10,8 @@
 #include <linux/hardirq.h>
 
 #include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-npi-defs.h>
 
 DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
 DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
diff --git a/arch/mips/cavium-octeon/pci-common.c b/arch/mips/cavium-octeon/pci-common.c
new file mode 100644
index 0000000..cd029f8
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci-common.c
@@ -0,0 +1,137 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include "pci-common.h"
+
+typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
+enum octeon_dma_bar_type octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_INVALID;
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @param dev    The Linux PCI device structure for the device to map
+ * @param slot   The slot number for this device on __BUS 0__. Linux
+ *               enumerates through all the bridges and figures out the
+ *               slot on Bus 0 where this device eventually hooks to.
+ * @param pin    The PCI interrupt pin read from the device, then swizzled
+ *               as it goes through each bridge.
+ * @return Interrupt number for the device
+ */
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (octeon_pcibios_map_irq)
+		return octeon_pcibios_map_irq(dev, slot, pin);
+	else
+		panic("octeon_pcibios_map_irq doesn't point to a "
+		      "pcibios_map_irq() function");
+}
+
+
+/**
+ * Called to perform platform specific PCI setup
+ *
+ * @param dev
+ * @return
+ */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	uint16_t config;
+	uint32_t dconfig;
+	int pos;
+	/*
+	 * Force the Cache line setting to 64 bytes. The standard
+	 * Linux bus scan doesn't seem to set it. Octeon really has
+	 * 128 byte lines, but Intel bridges get really upset if you
+	 * try and set values above 64 bytes. Value is specified in
+	 * 32bit words.
+	 */
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
+	/* Set latency timers for all devices */
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
+
+	/* Enable reporting System errors and parity errors on all devices */
+	/* Enable parity checking and error reporting */
+	pci_read_config_word(dev, PCI_COMMAND, &config);
+	config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	pci_write_config_word(dev, PCI_COMMAND, config);
+
+	if (dev->subordinate) {
+		/* Set latency timers on sub bridges */
+		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
+		/* More bridge error detection */
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
+		config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
+		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
+	}
+
+	/* Enable the PCIe normal error reporting */
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (pos) {
+		/* Update Device Control */
+		pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
+		/* Correctable Error Reporting */
+		config |= PCI_EXP_DEVCTL_CERE;
+		/* Non-Fatal Error Reporting */
+		config |= PCI_EXP_DEVCTL_NFERE;
+		/* Fatal Error Reporting */
+		config |= PCI_EXP_DEVCTL_FERE;
+		/* Unsupported Request */
+		config |= PCI_EXP_DEVCTL_URRE;
+		pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
+	}
+
+	/* Find the Advanced Error Reporting capability */
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (pos) {
+		/* Clear Uncorrectable Error Status */
+		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+				      &dconfig);
+		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
+				       dconfig);
+		/* Enable reporting of all uncorrectable errors */
+		/* Uncorrectable Error Mask - turned on bits disable errors */
+		pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
+		/*
+		 * Leave severity at HW default. This only controls if
+		 * errors are reported as uncorrectable or
+		 * correctable, not if the error is reported.
+		 */
+		/* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
+		/* Clear Correctable Error Status */
+		pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
+		pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
+		/* Enable reporting of all correctable errors */
+		/* Correctable Error Mask - turned on bits disable errors */
+		pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
+		/* Advanced Error Capabilities */
+		pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
+		/* ECRC Generation Enable */
+		if (config & PCI_ERR_CAP_ECRC_GENC)
+			config |= PCI_ERR_CAP_ECRC_GENE;
+		/* ECRC Check Enable */
+		if (config & PCI_ERR_CAP_ECRC_CHKC)
+			config |= PCI_ERR_CAP_ECRC_CHKE;
+		pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
+		/* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
+		/* Report all errors to the root complex */
+		pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
+				       PCI_ERR_ROOT_CMD_COR_EN |
+				       PCI_ERR_ROOT_CMD_NONFATAL_EN |
+				       PCI_ERR_ROOT_CMD_FATAL_EN);
+		/* Clear the Root status register */
+		pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
+		pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
+	}
+
+	return 0;
+}
diff --git a/arch/mips/cavium-octeon/pci-common.h b/arch/mips/cavium-octeon/pci-common.h
new file mode 100644
index 0000000..74ae799
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci-common.h
@@ -0,0 +1,39 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#ifndef __OCTEON_PCI_COMMON_H__
+#define __OCTEON_PCI_COMMON_H__
+
+#include <linux/pci.h>
+
+/* Some PCI cards require delays when accessing config space. */
+#define PCI_CONFIG_SPACE_DELAY 10000
+
+/* pcibios_map_irq() is defined inside pci-common.c. All it does is call the
+   Octeon specific version pointed to by this variable. This function needs to
+   change for PCI or PCIe based hosts */
+extern typeof(pcibios_map_irq) *octeon_pcibios_map_irq;
+
+/* The following defines are only used when octeon_dma_bar_type =
+   OCTEON_DMA_BAR_TYPE_BIG */
+#define OCTEON_PCI_BAR1_HOLE_BITS 5
+#define OCTEON_PCI_BAR1_HOLE_SIZE (1ul<<(OCTEON_PCI_BAR1_HOLE_BITS+3))
+
+enum octeon_dma_bar_type {
+	OCTEON_DMA_BAR_TYPE_INVALID,
+	OCTEON_DMA_BAR_TYPE_SMALL,
+	OCTEON_DMA_BAR_TYPE_BIG,
+	OCTEON_DMA_BAR_TYPE_PCIE
+};
+
+/**
+ * This is a variable to tell the DMA mapping system in dma-octeon.c
+ * how to map PCI DMA addresses.
+ */
+extern enum octeon_dma_bar_type octeon_dma_bar_type;
+
+#endif
diff --git a/arch/mips/cavium-octeon/pci.c b/arch/mips/cavium-octeon/pci.c
new file mode 100644
index 0000000..67c0ff5
--- /dev/null
+++ b/arch/mips/cavium-octeon/pci.c
@@ -0,0 +1,568 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include <asm/octeon/cvmx-pci-defs.h>
+
+#include "pci-common.h"
+
+#define USE_OCTEON_INTERNAL_ARBITER
+
+/*
+ * Octeon's PCI controller uses did=3, subdid=2 for PCI IO
+ * addresses. Use PCI endian swapping 1 so no address swapping is
+ * necessary. The Linux io routines will endian swap the data.
+ */
+#define OCTEON_PCI_IOSPACE_BASE     0x80011a0400000000ull
+#define OCTEON_PCI_IOSPACE_SIZE     (1ull<<32)
+
+/* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */
+#define OCTEON_PCI_MEMSPACE_OFFSET  (0x00011b0000000000ull)
+
+/**
+ * This is the bit decoding used for the Octeon PCI controller addresses
+ */
+union octeon_pci_address {
+	uint64_t u64;
+	struct {
+		uint64_t upper:2;
+		uint64_t reserved:13;
+		uint64_t io:1;
+		uint64_t did:5;
+		uint64_t subdid:3;
+		uint64_t reserved2:4;
+		uint64_t endian_swap:2;
+		uint64_t reserved3:10;
+		uint64_t bus:8;
+		uint64_t dev:5;
+		uint64_t func:3;
+		uint64_t reg:8;
+	} s;
+};
+
+/**
+ * Return the mapping of PCI device number to IRQ line. Each
+ * character in the return string represents the interrupt
+ * line for the device at that position. Device 1 maps to the
+ * first character, etc. The characters A-D are used for PCI
+ * interrupts.
+ *
+ * Returns PCI interrupt mapping
+ */
+const char *octeon_get_pci_interrupts(void)
+{
+	/*
+	 * Returning an empty string causes the interrupts to be
+	 * routed based on the PCI specification. From the PCI spec:
+	 *
+	 * INTA# of Device Number 0 is connected to IRQW on the system
+	 * board.  (Device Number has no significance regarding being
+	 * located on the system board or in a connector.) INTA# of
+	 * Device Number 1 is connected to IRQX on the system
+	 * board. INTA# of Device Number 2 is connected to IRQY on the
+	 * system board. INTA# of Device Number 3 is connected to IRQZ
+	 * on the system board. The table below describes how each
+	 * agent's INTx# lines are connected to the system board
+	 * interrupt lines. The following equation can be used to
+	 * determine to which INTx# signal on the system board a given
+	 * device's INTx# line(s) is connected.
+	 *
+	 * MB = (D + I) MOD 4 MB = System board Interrupt (IRQW = 0,
+	 * IRQX = 1, IRQY = 2, and IRQZ = 3) D = Device Number I =
+	 * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and
+	 * INTD# = 3)
+	 */
+	switch (octeon_bootinfo->board_type) {
+	case CVMX_BOARD_TYPE_NAO38:
+		/* This is really the NAC38 */
+		return "AAAAADABAAAAAAAAAAAAAAAAAAAAAAAA";
+	case CVMX_BOARD_TYPE_THUNDER:
+		return "";
+	case CVMX_BOARD_TYPE_EBH3000:
+		return "";
+	case CVMX_BOARD_TYPE_EBH3100:
+	case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+		return "AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+	case CVMX_BOARD_TYPE_BBGW_REF:
+		return "AABCD";
+	default:
+		return "";
+	}
+}
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @dev:    The Linux PCI device structure for the device to map
+ * @slot:   The slot number for this device on __BUS 0__. Linux
+ *               enumerates through all the bridges and figures out the
+ *               slot on Bus 0 where this device eventually hooks to.
+ * @pin:    The PCI interrupt pin read from the device, then swizzled
+ *               as it goes through each bridge.
+ * Returns Interrupt number for the device
+ */
+int __init octeon_pci_pcibios_map_irq(const struct pci_dev *dev,
+				      u8 slot, u8 pin)
+{
+	int irq_num;
+	const char *interrupts;
+	int dev_num;
+
+	/* Get the board specific interrupt mapping */
+	interrupts = octeon_get_pci_interrupts();
+
+	dev_num = dev->devfn >> 3;
+	if (dev_num < strlen(interrupts))
+		irq_num = ((interrupts[dev_num] - 'A' + pin - 1) & 3) +
+			OCTEON_IRQ_PCI_INT0;
+	else
+		irq_num = ((slot + pin - 3) & 3) + OCTEON_IRQ_PCI_INT0;
+	return irq_num;
+}
+
+
+/**
+ * Read a value from configuration space
+ *
+ */
+static int octeon_read_config(struct pci_bus *bus, unsigned int devfn,
+			      int reg, int size, u32 *val)
+{
+	union octeon_pci_address pci_addr;
+
+	pci_addr.u64 = 0;
+	pci_addr.s.upper = 2;
+	pci_addr.s.io = 1;
+	pci_addr.s.did = 3;
+	pci_addr.s.subdid = 1;
+	pci_addr.s.endian_swap = 1;
+	pci_addr.s.bus = bus->number;
+	pci_addr.s.dev = devfn >> 3;
+	pci_addr.s.func = devfn & 0x7;
+	pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+	udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+	switch (size) {
+	case 4:
+		*val = le32_to_cpu(cvmx_read64_uint32(pci_addr.u64));
+		return PCIBIOS_SUCCESSFUL;
+	case 2:
+		*val = le16_to_cpu(cvmx_read64_uint16(pci_addr.u64));
+		return PCIBIOS_SUCCESSFUL;
+	case 1:
+		*val = cvmx_read64_uint8(pci_addr.u64);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+/**
+ * Write a value to PCI configuration space
+ *
+ * @bus:
+ * @devfn:
+ * @reg:
+ * @size:
+ * @val:
+ * Returns
+ */
+static int octeon_write_config(struct pci_bus *bus, unsigned int devfn,
+			       int reg, int size, u32 val)
+{
+	union octeon_pci_address pci_addr;
+
+	pci_addr.u64 = 0;
+	pci_addr.s.upper = 2;
+	pci_addr.s.io = 1;
+	pci_addr.s.did = 3;
+	pci_addr.s.subdid = 1;
+	pci_addr.s.endian_swap = 1;
+	pci_addr.s.bus = bus->number;
+	pci_addr.s.dev = devfn >> 3;
+	pci_addr.s.func = devfn & 0x7;
+	pci_addr.s.reg = reg;
+
+#if PCI_CONFIG_SPACE_DELAY
+	udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+	switch (size) {
+	case 4:
+		cvmx_write64_uint32(pci_addr.u64, cpu_to_le32(val));
+		return PCIBIOS_SUCCESSFUL;
+	case 2:
+		cvmx_write64_uint16(pci_addr.u64, cpu_to_le16(val));
+		return PCIBIOS_SUCCESSFUL;
+	case 1:
+		cvmx_write64_uint8(pci_addr.u64, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+
+static struct pci_ops octeon_pci_ops = {
+	octeon_read_config,
+	octeon_write_config,
+};
+
+static struct resource octeon_pci_mem_resource = {
+	.start = 0,
+	.end = 0,
+	.name = "Octeon PCI MEM",
+	.flags = IORESOURCE_MEM,
+};
+
+/*
+ * PCI ports must be above 16KB so the ISA bus filtering in the PCI-X to PCI
+ * bridge
+ */
+static struct resource octeon_pci_io_resource = {
+	.start = 0x4000,
+	.end = OCTEON_PCI_IOSPACE_SIZE - 1,
+	.name = "Octeon PCI IO",
+	.flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pci_controller = {
+	.pci_ops = &octeon_pci_ops,
+	.mem_resource = &octeon_pci_mem_resource,
+	.mem_offset = OCTEON_PCI_MEMSPACE_OFFSET,
+	.io_resource = &octeon_pci_io_resource,
+	.io_offset = 0,
+	.io_map_base = OCTEON_PCI_IOSPACE_BASE,
+};
+
+
+/**
+ * Low level initialize the Octeon PCI controller
+ *
+ * Returns
+ */
+static void octeon_pci_initialize(void)
+{
+	union cvmx_pci_cfg01 cfg01;
+	union cvmx_npi_ctl_status ctl_status;
+	union cvmx_pci_ctl_status_2 ctl_status_2;
+	union cvmx_pci_cfg19 cfg19;
+	union cvmx_pci_cfg16 cfg16;
+	union cvmx_pci_cfg22 cfg22;
+	union cvmx_pci_cfg56 cfg56;
+
+	/* Reset the PCI Bus */
+	cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x1);
+	cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+	udelay(2000);		/* Hold PCI reset for 2 ms */
+
+	ctl_status.u64 = 0;	/* cvmx_read_csr(CVMX_NPI_CTL_STATUS); */
+	ctl_status.s.max_word = 1;
+	ctl_status.s.timer = 1;
+	cvmx_write_csr(CVMX_NPI_CTL_STATUS, ctl_status.u64);
+
+	/* Deassert PCI reset and advertize PCX Host Mode Device Capability
+	   (64b) */
+	cvmx_write_csr(CVMX_CIU_SOFT_PRST, 0x4);
+	cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+
+	udelay(2000);		/* Wait 2 ms after deasserting PCI reset */
+
+	ctl_status_2.u32 = 0;
+	ctl_status_2.s.tsr_hwm = 1;	/* Initializes to 0.  Must be set
+					   before any PCI reads. */
+	ctl_status_2.s.bar2pres = 1;	/* Enable BAR2 */
+	ctl_status_2.s.bar2_enb = 1;
+	ctl_status_2.s.bar2_cax = 1;	/* Don't use L2 */
+	ctl_status_2.s.bar2_esx = 1;
+	ctl_status_2.s.pmo_amod = 1;	/* Round robin priority */
+	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+		/* BAR1 hole */
+		ctl_status_2.s.bb1_hole = OCTEON_PCI_BAR1_HOLE_BITS;
+		ctl_status_2.s.bb1_siz = 1;  /* BAR1 is 2GB */
+		ctl_status_2.s.bb_ca = 1;    /* Don't use L2 with big bars */
+		ctl_status_2.s.bb_es = 1;    /* Big bar in byte swap mode */
+		ctl_status_2.s.bb1 = 1;      /* BAR1 is big */
+		ctl_status_2.s.bb0 = 1;      /* BAR0 is big */
+	}
+
+	octeon_npi_write32(CVMX_NPI_PCI_CTL_STATUS_2, ctl_status_2.u32);
+	udelay(2000);		/* Wait 2 ms before doing PCI reads */
+
+	ctl_status_2.u32 = octeon_npi_read32(CVMX_NPI_PCI_CTL_STATUS_2);
+	pr_notice("PCI Status: %s %s-bit\n",
+		  ctl_status_2.s.ap_pcix ? "PCI-X" : "PCI",
+		  ctl_status_2.s.ap_64ad ? "64" : "32");
+
+	if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		union cvmx_pci_cnt_reg cnt_reg_start;
+		union cvmx_pci_cnt_reg cnt_reg_end;
+		unsigned long cycles, pci_clock;
+
+		cnt_reg_start.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+		cycles = read_c0_cvmcount();
+		udelay(1000);
+		cnt_reg_end.u64 = cvmx_read_csr(CVMX_NPI_PCI_CNT_REG);
+		cycles = read_c0_cvmcount() - cycles;
+		pci_clock = (cnt_reg_end.s.pcicnt - cnt_reg_start.s.pcicnt) /
+			    (cycles / (mips_hpt_frequency / 1000000));
+		pr_notice("PCI Clock: %lu MHz\n", pci_clock);
+	}
+
+	/*
+	 * TDOMC must be set to one in PCI mode. TDOMC should be set to 4
+	 * in PCI-X mode to allow four oustanding splits. Otherwise,
+	 * should not change from its reset value. Don't write PCI_CFG19
+	 * in PCI mode (0x82000001 reset value), write it to 0x82000004
+	 * after PCI-X mode is known. MRBCI,MDWE,MDRE -> must be zero.
+	 * MRBCM -> must be one.
+	 */
+	if (ctl_status_2.s.ap_pcix) {
+		cfg19.u32 = 0;
+		/*
+		 * Target Delayed/Split request outstanding maximum
+		 * count. [1..31] and 0=32.  NOTE: If the user
+		 * programs these bits beyond the Designed Maximum
+		 * outstanding count, then the designed maximum table
+		 * depth will be used instead.  No additional
+		 * Deferred/Split transactions will be accepted if
+		 * this outstanding maximum count is
+		 * reached. Furthermore, no additional deferred/split
+		 * transactions will be accepted if the I/O delay/ I/O
+		 * Split Request outstanding maximum is reached.
+		 */
+		cfg19.s.tdomc = 4;
+		/*
+		 * Master Deferred Read Request Outstanding Max Count
+		 * (PCI only).  CR4C[26:24] Max SAC cycles MAX DAC
+		 * cycles 000 8 4 001 1 0 010 2 1 011 3 1 100 4 2 101
+		 * 5 2 110 6 3 111 7 3 For example, if these bits are
+		 * programmed to 100, the core can support 2 DAC
+		 * cycles, 4 SAC cycles or a combination of 1 DAC and
+		 * 2 SAC cycles. NOTE: For the PCI-X maximum
+		 * outstanding split transactions, refer to
+		 * CRE0[22:20].
+		 */
+		cfg19.s.mdrrmc = 2;
+		/*
+		 * Master Request (Memory Read) Byte Count/Byte Enable
+		 * select. 0 = Byte Enables valid. In PCI mode, a
+		 * burst transaction cannot be performed using Memory
+		 * Read command=4?h6. 1 = DWORD Byte Count valid
+		 * (default). In PCI Mode, the memory read byte
+		 * enables are automatically generated by the
+		 * core. Note: N3 Master Request transaction sizes are
+		 * always determined through the
+		 * am_attr[<35:32>|<7:0>] field.
+		 */
+		cfg19.s.mrbcm = 1;
+		octeon_npi_write32(CVMX_NPI_PCI_CFG19, cfg19.u32);
+	}
+
+
+	cfg01.u32 = 0;
+	cfg01.s.msae = 1;	/* Memory Space Access Enable */
+	cfg01.s.me = 1;		/* Master Enable */
+	cfg01.s.pee = 1;	/* PERR# Enable */
+	cfg01.s.see = 1;	/* System Error Enable */
+	cfg01.s.fbbe = 1;	/* Fast Back to Back Transaction Enable */
+
+	octeon_npi_write32(CVMX_NPI_PCI_CFG01, cfg01.u32);
+
+#ifdef USE_OCTEON_INTERNAL_ARBITER
+	/*
+	 * When OCTEON is a PCI host, most systems will use OCTEON's
+	 * internal arbiter, so must enable it before any PCI/PCI-X
+	 * traffic can occur.
+	 */
+	{
+		union cvmx_npi_pci_int_arb_cfg pci_int_arb_cfg;
+
+		pci_int_arb_cfg.u64 = 0;
+		pci_int_arb_cfg.s.en = 1;	/* Internal arbiter enable */
+		cvmx_write_csr(CVMX_NPI_PCI_INT_ARB_CFG, pci_int_arb_cfg.u64);
+	}
+#endif				/* USE_OCTEON_INTERNAL_ARBITER */
+
+	/*
+	 * Preferrably written to 1 to set MLTD. [RDSATI,TRTAE,
+	 * TWTAE,TMAE,DPPMR -> must be zero. TILT -> must not be set to
+	 * 1..7.
+	 */
+	cfg16.u32 = 0;
+	cfg16.s.mltd = 1;	/* Master Latency Timer Disable */
+	octeon_npi_write32(CVMX_NPI_PCI_CFG16, cfg16.u32);
+
+	/*
+	 * Should be written to 0x4ff00. MTTV -> must be zero.
+	 * FLUSH -> must be 1. MRV -> should be 0xFF.
+	 */
+	cfg22.u32 = 0;
+	/* Master Retry Value [1..255] and 0=infinite */
+	cfg22.s.mrv = 0xff;
+	/*
+	 * AM_DO_FLUSH_I control NOTE: This bit MUST BE ONE for proper
+	 * N3K operation.
+	 */
+	cfg22.s.flush = 1;
+	octeon_npi_write32(CVMX_NPI_PCI_CFG22, cfg22.u32);
+
+	/*
+	 * MOST Indicates the maximum number of outstanding splits (in -1
+	 * notation) when OCTEON is in PCI-X mode.  PCI-X performance is
+	 * affected by the MOST selection.  Should generally be written
+	 * with one of 0x3be807, 0x2be807, 0x1be807, or 0x0be807,
+	 * depending on the desired MOST of 3, 2, 1, or 0, respectively.
+	 */
+	cfg56.u32 = 0;
+	cfg56.s.pxcid = 7;	/* RO - PCI-X Capability ID */
+	cfg56.s.ncp = 0xe8;	/* RO - Next Capability Pointer */
+	cfg56.s.dpere = 1;	/* Data Parity Error Recovery Enable */
+	cfg56.s.roe = 1;	/* Relaxed Ordering Enable */
+	cfg56.s.mmbc = 1;	/* Maximum Memory Byte Count
+				   [0=512B,1=1024B,2=2048B,3=4096B] */
+	cfg56.s.most = 3;	/* Maximum outstanding Split transactions [0=1
+				   .. 7=32] */
+
+	octeon_npi_write32(CVMX_NPI_PCI_CFG56, cfg56.u32);
+
+	/*
+	 * Affects PCI performance when OCTEON services reads to its
+	 * BAR1/BAR2. Refer to Section 10.6.1.  The recommended values are
+	 * 0x22, 0x33, and 0x33 for PCI_READ_CMD_6, PCI_READ_CMD_C, and
+	 * PCI_READ_CMD_E, respectively. Unfortunately due to errata DDR-700,
+	 * these values need to be changed so they won't possibly prefetch off
+	 * of the end of memory if PCI is DMAing a buffer at the end of
+	 * memory. Note that these values differ from their reset values.
+	 */
+	octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_6, 0x21);
+	octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_C, 0x31);
+	octeon_npi_write32(CVMX_NPI_PCI_READ_CMD_E, 0x31);
+}
+
+
+/**
+ * Initialize the Octeon PCI controller
+ *
+ * Returns
+ */
+static int __init octeon_pci_setup(void)
+{
+	union cvmx_npi_mem_access_subidx mem_access;
+	int index;
+
+	/* Only these chips have PCI */
+	if (octeon_has_feature(OCTEON_FEATURE_PCIE))
+		return 0;
+
+	/* Point pcibios_map_irq() to the PCI version of it */
+	octeon_pcibios_map_irq = octeon_pci_pcibios_map_irq;
+
+	/* Only use the big bars on chips that support it */
+	if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+	    OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
+	    OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+		octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_SMALL;
+	else
+		octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_BIG;
+
+	/* PCI I/O and PCI MEM values */
+	set_io_port_base(OCTEON_PCI_IOSPACE_BASE);
+	ioport_resource.start = 0;
+	ioport_resource.end = OCTEON_PCI_IOSPACE_SIZE - 1;
+	if (!octeon_is_pci_host()) {
+		pr_notice("Not in host mode, PCI Controller not initialized\n");
+		return 0;
+	}
+
+	pr_notice("%s Octeon big bar support\n",
+		  (octeon_dma_bar_type ==
+		  OCTEON_DMA_BAR_TYPE_BIG) ? "Enabling" : "Disabling");
+
+	octeon_pci_initialize();
+
+	mem_access.u64 = 0;
+	mem_access.s.esr = 1;	/* Endian-Swap on read. */
+	mem_access.s.esw = 1;	/* Endian-Swap on write. */
+	mem_access.s.nsr = 0;	/* No-Snoop on read. */
+	mem_access.s.nsw = 0;	/* No-Snoop on write. */
+	mem_access.s.ror = 0;	/* Relax Read on read. */
+	mem_access.s.row = 0;	/* Relax Order on write. */
+	mem_access.s.ba = 0;	/* PCI Address bits [63:36]. */
+	cvmx_write_csr(CVMX_NPI_MEM_ACCESS_SUBID3, mem_access.u64);
+
+	/*
+	 * Remap the Octeon BAR 2 above all 32 bit devices
+	 * (0x8000000000ul).  This is done here so it is remapped
+	 * before the readl()'s below. We don't want BAR2 overlapping
+	 * with BAR0/BAR1 during these reads.
+	 */
+	octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0);
+	octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80);
+
+	/* Disable the BAR1 movable mappings */
+	for (index = 0; index < 32; index++)
+		octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0);
+
+	if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) {
+		/* Remap the Octeon BAR 0 to 0-2GB */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG04, 0);
+		octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+		/*
+		 * Remap the Octeon BAR 1 to map 2GB-4GB (minus the
+		 * BAR 1 hole).
+		 */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30);
+		octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+		/* Devices go after BAR1 */
+		octeon_pci_mem_resource.start =
+			OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) -
+			(OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+		octeon_pci_mem_resource.end =
+			octeon_pci_mem_resource.start + (1ul << 30);
+	} else {
+		/* Remap the Octeon BAR 0 to map 128MB-(128MB+4KB) */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG04, 128ul << 20);
+		octeon_npi_write32(CVMX_NPI_PCI_CFG05, 0);
+
+		/* Remap the Octeon BAR 1 to map 0-128MB */
+		octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0);
+		octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0);
+
+		/* Devices go after BAR0 */
+		octeon_pci_mem_resource.start =
+			OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) +
+			(4ul << 10);
+		octeon_pci_mem_resource.end =
+			octeon_pci_mem_resource.start + (1ul << 30);
+	}
+
+	register_pci_controller(&octeon_pci_controller);
+
+	/*
+	 * Clear any errors that might be pending from before the bus
+	 * was setup properly.
+	 */
+	cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1);
+	return 0;
+}
+
+arch_initcall(octeon_pci_setup);
diff --git a/arch/mips/cavium-octeon/pcie.c b/arch/mips/cavium-octeon/pcie.c
new file mode 100644
index 0000000..49d1408
--- /dev/null
+++ b/arch/mips/cavium-octeon/pcie.c
@@ -0,0 +1,1370 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2007, 2008 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pciercx-defs.h>
+#include <asm/octeon/cvmx-pescx-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-helper-errata.h>
+
+#include "pci-common.h"
+
+union cvmx_pcie_address {
+	uint64_t u64;
+	struct {
+		uint64_t upper:2;	/* Normally 2 for XKPHYS */
+		uint64_t reserved_49_61:13;	/* Must be zero */
+		uint64_t io:1;	/* 1 for IO space access */
+		uint64_t did:5;	/* PCIe DID = 3 */
+		uint64_t subdid:3;	/* PCIe SubDID = 1 */
+		uint64_t reserved_36_39:4;	/* Must be zero */
+		uint64_t es:2;	/* Endian swap = 1 */
+		uint64_t port:2;	/* PCIe port 0,1 */
+		uint64_t reserved_29_31:3;	/* Must be zero */
+		/*
+		 * Selects the type of the configuration request (0 = type 0,
+		 * 1 = type 1).
+		 */
+		uint64_t ty:1;
+		/* Target bus number sent in the ID in the request. */
+		uint64_t bus:8;
+		/*
+		 * Target device number sent in the ID in the
+		 * request. Note that Dev must be zero for type 0
+		 * configuration requests.
+		 */
+		uint64_t dev:5;
+		/* Target function number sent in the ID in the request. */
+		uint64_t func:3;
+		/*
+		 * Selects a register in the configuration space of
+		 * the target.
+		 */
+		uint64_t reg:12;
+	} config;
+	struct {
+		uint64_t upper:2;	/* Normally 2 for XKPHYS */
+		uint64_t reserved_49_61:13;	/* Must be zero */
+		uint64_t io:1;	/* 1 for IO space access */
+		uint64_t did:5;	/* PCIe DID = 3 */
+		uint64_t subdid:3;	/* PCIe SubDID = 2 */
+		uint64_t reserved_36_39:4;	/* Must be zero */
+		uint64_t es:2;	/* Endian swap = 1 */
+		uint64_t port:2;	/* PCIe port 0,1 */
+		uint64_t address:32;	/* PCIe IO address */
+	} io;
+	struct {
+		uint64_t upper:2;	/* Normally 2 for XKPHYS */
+		uint64_t reserved_49_61:13;	/* Must be zero */
+		uint64_t io:1;	/* 1 for IO space access */
+		uint64_t did:5;	/* PCIe DID = 3 */
+		uint64_t subdid:3;	/* PCIe SubDID = 3-6 */
+		uint64_t reserved_36_39:4;	/* Must be zero */
+		uint64_t address:36;	/* PCIe Mem address */
+	} mem;
+};
+
+/**
+ * Return the Core virtual base address for PCIe IO access. IOs are
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_io_base_address(int pcie_port)
+{
+	union cvmx_pcie_address pcie_addr;
+	pcie_addr.u64 = 0;
+	pcie_addr.io.upper = 0;
+	pcie_addr.io.io = 1;
+	pcie_addr.io.did = 3;
+	pcie_addr.io.subdid = 2;
+	pcie_addr.io.es = 1;
+	pcie_addr.io.port = pcie_port;
+	return pcie_addr.u64;
+}
+
+/**
+ * Size of the IO address region returned at address
+ * cvmx_pcie_get_io_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the IO window
+ */
+static inline uint64_t cvmx_pcie_get_io_size(int pcie_port)
+{
+	return 1ull << 32;
+}
+
+/**
+ * Return the Core virtual base address for PCIe MEM access. Memory is
+ * read/written as an offset from this address.
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns 64bit Octeon IO base address for read/write
+ */
+static inline uint64_t cvmx_pcie_get_mem_base_address(int pcie_port)
+{
+	union cvmx_pcie_address pcie_addr;
+	pcie_addr.u64 = 0;
+	pcie_addr.mem.upper = 0;
+	pcie_addr.mem.io = 1;
+	pcie_addr.mem.did = 3;
+	pcie_addr.mem.subdid = 3 + pcie_port;
+	return pcie_addr.u64;
+}
+
+/**
+ * Size of the Mem address region returned at address
+ * cvmx_pcie_get_mem_base_address()
+ *
+ * @pcie_port: PCIe port the IO is for
+ *
+ * Returns Size of the Mem window
+ */
+static inline uint64_t cvmx_pcie_get_mem_size(int pcie_port)
+{
+	return 1ull << 36;
+}
+
+/**
+ * Read a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port:  PCIe port to read from
+ * @cfg_offset: Address to read
+ *
+ * Returns Value read
+ */
+static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
+{
+	union cvmx_pescx_cfg_rd pescx_cfg_rd;
+	pescx_cfg_rd.u64 = 0;
+	pescx_cfg_rd.s.addr = cfg_offset;
+	cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
+	pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
+	return pescx_cfg_rd.s.data;
+}
+
+/**
+ * Write a PCIe config space register indirectly. This is used for
+ * registers of the form PCIEEP_CFG??? and PCIERC?_CFG???.
+ *
+ * @pcie_port:  PCIe port to write to
+ * @cfg_offset: Address to write
+ * @val:        Value to write
+ */
+static void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset,
+				 uint32_t val)
+{
+	union cvmx_pescx_cfg_wr pescx_cfg_wr;
+	pescx_cfg_wr.u64 = 0;
+	pescx_cfg_wr.s.addr = cfg_offset;
+	pescx_cfg_wr.s.data = val;
+	cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
+}
+
+/**
+ * Build a PCIe config space request address for a device
+ *
+ * @pcie_port: PCIe port to access
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ *
+ * Returns 64bit Octeon IO address
+ */
+static inline uint64_t __cvmx_pcie_build_config_addr(int pcie_port, int bus,
+						     int dev, int fn, int reg)
+{
+	union cvmx_pcie_address pcie_addr;
+	union cvmx_pciercx_cfg006 pciercx_cfg006;
+
+	pciercx_cfg006.u32 =
+	    cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
+	if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
+		return 0;
+
+	pcie_addr.u64 = 0;
+	pcie_addr.config.upper = 2;
+	pcie_addr.config.io = 1;
+	pcie_addr.config.did = 3;
+	pcie_addr.config.subdid = 1;
+	pcie_addr.config.es = 1;
+	pcie_addr.config.port = pcie_port;
+	pcie_addr.config.ty = (bus > pciercx_cfg006.s.pbnum);
+	pcie_addr.config.bus = bus;
+	pcie_addr.config.dev = dev;
+	pcie_addr.config.func = fn;
+	pcie_addr.config.reg = reg;
+	return pcie_addr.u64;
+}
+
+/**
+ * Read 8bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ *
+ * Returns Result of the read
+ */
+static uint8_t cvmx_pcie_config_read8(int pcie_port, int bus, int dev,
+				      int fn, int reg)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		return cvmx_read64_uint8(address);
+	else
+		return 0xff;
+}
+
+/**
+ * Read 16bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ *
+ * Returns Result of the read
+ */
+static uint16_t cvmx_pcie_config_read16(int pcie_port, int bus, int dev,
+					int fn, int reg)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		return le16_to_cpu(cvmx_read64_uint16(address));
+	else
+		return 0xffff;
+}
+
+/**
+ * Read 32bits from a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ *
+ * Returns Result of the read
+ */
+static uint32_t cvmx_pcie_config_read32(int pcie_port, int bus, int dev,
+					int fn, int reg)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		return le32_to_cpu(cvmx_read64_uint32(address));
+	else
+		return 0xffffffff;
+}
+
+/**
+ * Write 8bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ * @val:       Value to write
+ */
+static void cvmx_pcie_config_write8(int pcie_port, int bus, int dev, int fn,
+				    int reg, uint8_t val)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		cvmx_write64_uint8(address, val);
+}
+
+/**
+ * Write 16bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ * @val:       Value to write
+ */
+static void cvmx_pcie_config_write16(int pcie_port, int bus, int dev, int fn,
+				     int reg, uint16_t val)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		cvmx_write64_uint16(address, cpu_to_le16(val));
+}
+
+/**
+ * Write 32bits to a Device's config space
+ *
+ * @pcie_port: PCIe port the device is on
+ * @bus:       Sub bus
+ * @dev:       Device ID
+ * @fn:        Device sub function
+ * @reg:       Register to access
+ * @val:       Value to write
+ */
+static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn,
+				     int reg, uint32_t val)
+{
+	uint64_t address =
+	    __cvmx_pcie_build_config_addr(pcie_port, bus, dev, fn, reg);
+	if (address)
+		cvmx_write64_uint32(address, cpu_to_le32(val));
+}
+
+/**
+ * Initialize the RC config space CSRs
+ *
+ * @pcie_port: PCIe port to initialize
+ */
+static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
+{
+	union cvmx_pciercx_cfg030 pciercx_cfg030;
+	union cvmx_npei_ctl_status2 npei_ctl_status2;
+	union cvmx_pciercx_cfg070 pciercx_cfg070;
+	union cvmx_pciercx_cfg001 pciercx_cfg001;
+	union cvmx_pciercx_cfg032 pciercx_cfg032;
+	union cvmx_pciercx_cfg006 pciercx_cfg006;
+	union cvmx_pciercx_cfg008 pciercx_cfg008;
+	union cvmx_pciercx_cfg009 pciercx_cfg009;
+	union cvmx_pciercx_cfg010 pciercx_cfg010;
+	union cvmx_pciercx_cfg011 pciercx_cfg011;
+	union cvmx_pciercx_cfg035 pciercx_cfg035;
+	union cvmx_pciercx_cfg075 pciercx_cfg075;
+	union cvmx_pciercx_cfg034 pciercx_cfg034;
+
+	/* Max Payload Size (PCIE*_CFG030[MPS]) */
+	/* Max Read Request Size (PCIE*_CFG030[MRRS]) */
+	/* Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] */
+	/* Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) */
+	pciercx_cfg030.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port));
+	/*
+	 * Max payload size = 128 bytes for best Octeon DMA
+	 * performance.
+	 */
+	pciercx_cfg030.s.mps = 0;
+	/*
+	 * Max read request size = 128 bytes for best Octeon DMA
+	 * performance.
+	 */
+	pciercx_cfg030.s.mrrs = 0;
+	/* Enable relaxed ordering. */
+	pciercx_cfg030.s.ro_en = 1;
+	/* Enable no snoop. */
+	pciercx_cfg030.s.ns_en = 1;
+	/* Correctable error reporting enable. */
+	pciercx_cfg030.s.ce_en = 1;
+	/* Non-fatal error reporting enable. */
+	pciercx_cfg030.s.nfe_en = 1;
+	/* Fatal error reporting enable. */
+	pciercx_cfg030.s.fe_en = 1;
+	/* Unsupported request reporting enable. */
+	pciercx_cfg030.s.ur_en = 1;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port),
+			     pciercx_cfg030.u32);
+
+	/*
+	 * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match
+	 * PCIE*_CFG030[MPS]
+	 *
+	 * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not
+	 * exceed PCIE*_CFG030[MRRS].
+	 */
+	npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2);
+	/* Max payload size = 128 bytes for best Octeon DMA performance */
+	npei_ctl_status2.s.mps = 0;
+	/* Max read request size = 128 bytes for best Octeon DMA performance */
+	npei_ctl_status2.s.mrrs = 0;
+	cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
+
+	/* ECRC Generation (PCIE*_CFG070[GE,CE]) */
+	pciercx_cfg070.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port));
+	pciercx_cfg070.s.ge = 1;	/* ECRC generation enable. */
+	pciercx_cfg070.s.ce = 1;	/* ECRC check enable. */
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port),
+			     pciercx_cfg070.u32);
+
+	/*
+	 * Access Enables (PCIE*_CFG001[MSAE,ME]) ME and MSAE should
+	 * always be set.
+	 *
+	 * Interrupt Disable (PCIE*_CFG001[I_DIS]) System Error
+	 * Message Enable (PCIE*_CFG001[SEE])
+	 */
+	pciercx_cfg001.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port));
+	pciercx_cfg001.s.msae = 1;	/* Memory space enable. */
+	pciercx_cfg001.s.me = 1;	/* Bus master enable. */
+	pciercx_cfg001.s.i_dis = 1;	/* INTx assertion disable. */
+	pciercx_cfg001.s.see = 1;	/* SERR# enable */
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port),
+			pciercx_cfg001.u32);
+
+	/* Advanced Error Recovery Message Enables */
+	/* (PCIE*_CFG066,PCIE*_CFG067,PCIE*_CFG069) */
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG066(pcie_port), 0);
+	/* Use CVMX_PCIERCX_CFG067 hardware default */
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG069(pcie_port), 0);
+
+	/* Active State Power Management (PCIE*_CFG032[ASLPC]) */
+	pciercx_cfg032.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+	pciercx_cfg032.s.aslpc = 0;	/* Active state Link PM control. */
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port),
+			     pciercx_cfg032.u32);
+
+	/* Entrance Latencies (PCIE*_CFG451[L0EL,L1EL]) */
+
+	/*
+	 * Link Width Mode (PCIERCn_CFG452[LME]) - Set during
+	 * cvmx_pcie_rc_initialize_link()
+	 *
+	 * Primary Bus Number (PCIERCn_CFG006[PBNUM])
+	 *
+	 * We set the primary bus number to 1 so IDT bridges are
+	 * happy. They don't like zero.
+	 */
+	pciercx_cfg006.u32 = 0;
+	pciercx_cfg006.s.pbnum = 1;
+	pciercx_cfg006.s.sbnum = 1;
+	pciercx_cfg006.s.subbnum = 1;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port),
+			     pciercx_cfg006.u32);
+
+	/*
+	 * Memory-mapped I/O BAR (PCIERCn_CFG008)
+	 * Most applications should disable the memory-mapped I/O BAR by
+	 * setting PCIERCn_CFG008[ML_ADDR] < PCIERCn_CFG008[MB_ADDR]
+	 */
+	pciercx_cfg008.u32 = 0;
+	pciercx_cfg008.s.mb_addr = 0x100;
+	pciercx_cfg008.s.ml_addr = 0;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port),
+			     pciercx_cfg008.u32);
+
+	/*
+	 * Prefetchable BAR (PCIERCn_CFG009,PCIERCn_CFG010,PCIERCn_CFG011)
+	 * Most applications should disable the prefetchable BAR by setting
+	 * PCIERCn_CFG011[UMEM_LIMIT],PCIERCn_CFG009[LMEM_LIMIT] <
+	 * PCIERCn_CFG010[UMEM_BASE],PCIERCn_CFG009[LMEM_BASE]
+	 */
+	pciercx_cfg009.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port));
+	pciercx_cfg010.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port));
+	pciercx_cfg011.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port));
+	pciercx_cfg009.s.lmem_base = 0x100;
+	pciercx_cfg009.s.lmem_limit = 0;
+	pciercx_cfg010.s.umem_base = 0x100;
+	pciercx_cfg011.s.umem_limit = 0;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port),
+			     pciercx_cfg009.u32);
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port),
+			     pciercx_cfg010.u32);
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port),
+			     pciercx_cfg011.u32);
+
+	/*
+	 * System Error Interrupt Enables (PCIERCn_CFG035[SECEE,SEFEE,SENFEE])
+	 * PME Interrupt Enables (PCIERCn_CFG035[PMEIE])
+	 */
+	pciercx_cfg035.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port));
+	/* System error on correctable error enable. */
+	pciercx_cfg035.s.secee = 1;
+	/* System error on fatal error enable. */
+	pciercx_cfg035.s.sefee = 1;
+	/* System error on non-fatal error enable. */
+	pciercx_cfg035.s.senfee = 1;
+	/* PME interrupt enable. */
+	pciercx_cfg035.s.pmeie = 1;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port),
+			     pciercx_cfg035.u32);
+
+	/*
+	 * Advanced Error Recovery Interrupt Enables
+	 * (PCIERCn_CFG075[CERE,NFERE,FERE])
+	 */
+	pciercx_cfg075.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port));
+	/* Correctable error reporting enable. */
+	pciercx_cfg075.s.cere = 1;
+	/* Non-fatal error reporting enable. */
+	pciercx_cfg075.s.nfere = 1;
+	/* Fatal error reporting enable. */
+	pciercx_cfg075.s.fere = 1;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port),
+			     pciercx_cfg075.u32);
+
+	/* HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN],
+	 * PCIERCn_CFG034[DLLS_EN,CCINT_EN])
+	 */
+	pciercx_cfg034.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port));
+	/* Hot-plug interrupt enable. */
+	pciercx_cfg034.s.hpint_en = 1;
+	/* Data Link Layer state changed enable */
+	pciercx_cfg034.s.dlls_en = 1;
+	/* Command completed interrupt enable. */
+	pciercx_cfg034.s.ccint_en = 1;
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port),
+			     pciercx_cfg034.u32);
+}
+
+/**
+ * Initialize a host mode PCIe link. This function takes a PCIe
+ * port from reset to a link up state. Software can then begin
+ * configuring the rest of the link.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int __cvmx_pcie_rc_initialize_link(int pcie_port)
+{
+	uint64_t start_cycle;
+	union cvmx_pescx_ctl_status pescx_ctl_status;
+	union cvmx_pciercx_cfg452 pciercx_cfg452;
+	union cvmx_pciercx_cfg032 pciercx_cfg032;
+	union cvmx_pciercx_cfg448 pciercx_cfg448;
+
+	/* Set the lane width */
+	pciercx_cfg452.u32 =
+	    cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
+	pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+	if (pescx_ctl_status.s.qlm_cfg == 0) {
+		/* We're in 8 lane (56XX) or 4 lane (54XX) mode */
+		pciercx_cfg452.s.lme = 0xf;
+	} else {
+		/* We're in 4 lane (56XX) or 2 lane (52XX) mode */
+		pciercx_cfg452.s.lme = 0x7;
+	}
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port),
+			     pciercx_cfg452.u32);
+
+	/*
+	 * CN52XX pass 1.x has an errata where length mismatches on UR
+	 * responses can cause bus errors on 64bit memory
+	 * reads. Turning off length error checking fixes this.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+		union cvmx_pciercx_cfg455 pciercx_cfg455;
+		pciercx_cfg455.u32 =
+		    cvmx_pcie_cfgx_read(pcie_port,
+					CVMX_PCIERCX_CFG455(pcie_port));
+		pciercx_cfg455.s.m_cpl_len_err = 1;
+		cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port),
+				     pciercx_cfg455.u32);
+	}
+
+	/* Lane swap needs to be manually enabled for CN52XX */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) {
+		pescx_ctl_status.s.lane_swp = 1;
+		cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port),
+			       pescx_ctl_status.u64);
+	}
+
+	/* Bring up the link */
+	pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
+	pescx_ctl_status.s.lnk_enb = 1;
+	cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
+
+	/*
+	 * CN52XX pass 1.0: Due to a bug in 2nd order CDR, it needs to
+	 * be disabled.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
+		__cvmx_helper_errata_qlm_disable_2nd_order_cdr(0);
+
+	/* Wait for the link to come up */
+	cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port);
+	start_cycle = cvmx_get_cycle();
+	do {
+		if (cvmx_get_cycle() - start_cycle >
+		    2 * cvmx_sysinfo_get()->cpu_clock_hz) {
+			cvmx_dprintf("PCIe: Port %d link timeout\n",
+				     pcie_port);
+			return -1;
+		}
+		cvmx_wait(10000);
+		pciercx_cfg032.u32 =
+		    cvmx_pcie_cfgx_read(pcie_port,
+					CVMX_PCIERCX_CFG032(pcie_port));
+	} while (pciercx_cfg032.s.dlla == 0);
+
+	/* Display the link status */
+	cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port,
+		     pciercx_cfg032.s.nlw);
+
+	/*
+	 * Update the Replay Time Limit. Empirically, some PCIe
+	 * devices take a little longer to respond than expected under
+	 * load. As a workaround for this we configure the Replay Time
+	 * Limit to the value expected for a 512 byte MPS instead of
+	 * our actual 256 byte MPS. The numbers below are directly
+	 * from the PCIe spec table 3-4.
+	 */
+	pciercx_cfg448.u32 =
+	    cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
+	switch (pciercx_cfg032.s.nlw) {
+	case 1:		/* 1 lane */
+		pciercx_cfg448.s.rtl = 1677;
+		break;
+	case 2:		/* 2 lanes */
+		pciercx_cfg448.s.rtl = 867;
+		break;
+	case 4:		/* 4 lanes */
+		pciercx_cfg448.s.rtl = 462;
+		break;
+	case 8:		/* 8 lanes */
+		pciercx_cfg448.s.rtl = 258;
+		break;
+	}
+	cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port),
+			     pciercx_cfg448.u32);
+
+	return 0;
+}
+
+/**
+ * Initialize a PCIe port for use in host(RC) mode. It doesn't
+ * enumerate the bus.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int cvmx_pcie_rc_initialize(int pcie_port)
+{
+	int i;
+	union cvmx_ciu_soft_prst ciu_soft_prst;
+	union cvmx_pescx_bist_status pescx_bist_status;
+	union cvmx_pescx_bist_status2 pescx_bist_status2;
+	union cvmx_npei_ctl_status npei_ctl_status;
+	union cvmx_npei_mem_access_ctl npei_mem_access_ctl;
+	union cvmx_npei_mem_access_subidx mem_access_subid;
+	union cvmx_npei_dbg_data npei_dbg_data;
+	union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+
+	/*
+	 * Make sure we aren't trying to setup a target mode interface
+	 * in host mode.
+	 */
+	npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+	if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) {
+		cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called "
+			     "on port0, but port0 is not in host mode\n");
+		return -1;
+	}
+
+	/*
+	 * Make sure a CN52XX isn't trying to bring up port 1 when it
+	 * is disabled.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+		if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) {
+			cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() "
+				     "called on port1, but port1 is "
+				     "disabled\n");
+			return -1;
+		}
+	}
+
+	/*
+	 * PCIe switch arbitration mode. '0' == fixed priority NPEI,
+	 * PCIe0, then PCIe1. '1' == round robin.
+	 */
+	npei_ctl_status.s.arb = 1;
+	/* Allow up to 0x20 config retries */
+	npei_ctl_status.s.cfg_rtry = 0x20;
+	/*
+	 * CN52XX pass1.x has an errata where P0_NTAGS and P1_NTAGS
+	 * don't reset.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+		npei_ctl_status.s.p0_ntags = 0x20;
+		npei_ctl_status.s.p1_ntags = 0x20;
+	}
+	cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS, npei_ctl_status.u64);
+
+	/* Bring the PCIe out of reset */
+	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) {
+		/*
+		 * The EBH5200 board swapped the PCIe reset lines on
+		 * the board. As a workaround for this bug, we bring
+		 * both PCIe ports out of reset at the same time
+		 * instead of on separate calls. So for port 0, we
+		 * bring both out of reset and do nothing on port 1.
+		 */
+		if (pcie_port == 0) {
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+			/*
+			 * After a chip reset the PCIe will also be in
+			 * reset. If it isn't, most likely someone is
+			 * trying to init it again without a proper
+			 * PCIe reset.
+			 */
+			if (ciu_soft_prst.s.soft_prst == 0) {
+				/* Reset the ports */
+				ciu_soft_prst.s.soft_prst = 1;
+				cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+					       ciu_soft_prst.u64);
+				ciu_soft_prst.u64 =
+				    cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+				ciu_soft_prst.s.soft_prst = 1;
+				cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+					       ciu_soft_prst.u64);
+				/* Wait until pcie resets the ports. */
+				udelay(2000);
+			}
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+			ciu_soft_prst.s.soft_prst = 0;
+			cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+			ciu_soft_prst.s.soft_prst = 0;
+			cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+		}
+	} else {
+		/*
+		 * The normal case: The PCIe ports are completely
+		 * separate and can be brought out of reset
+		 * independently.
+		 */
+		if (pcie_port)
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+		else
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+		/*
+		 * After a chip reset the PCIe will also be in
+		 * reset. If it isn't, most likely someone is trying
+		 * to init it again without a proper PCIe reset.
+		 */
+		if (ciu_soft_prst.s.soft_prst == 0) {
+			/* Reset the port */
+			ciu_soft_prst.s.soft_prst = 1;
+			if (pcie_port)
+				cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
+					       ciu_soft_prst.u64);
+			else
+				cvmx_write_csr(CVMX_CIU_SOFT_PRST,
+					       ciu_soft_prst.u64);
+			/* Wait until pcie resets the ports. */
+			udelay(2000);
+		}
+		if (pcie_port) {
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+			ciu_soft_prst.s.soft_prst = 0;
+			cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+		} else {
+			ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+			ciu_soft_prst.s.soft_prst = 0;
+			cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+		}
+	}
+
+	/*
+	 * Wait for PCIe reset to complete. Due to errata PCIE-700, we
+	 * don't poll PESCX_CTL_STATUS2[PCIERST], but simply wait a
+	 * fixed number of cycles.
+	 */
+	cvmx_wait(400000);
+
+	/* PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of CN56XX and
+	   CN52XX, so we only probe it on newer chips */
+	if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+	    && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+		/* Clear PCLK_RUN so we can check if the clock is running */
+		pescx_ctl_status2.u64 =
+		    cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+		pescx_ctl_status2.s.pclk_run = 1;
+		cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port),
+			       pescx_ctl_status2.u64);
+		/*
+		 * Now that we cleared PCLK_RUN, wait for it to be set
+		 * again telling us the clock is running.
+		 */
+		if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port),
+					  union cvmx_pescx_ctl_status2,
+					  pclk_run, ==, 1, 10000)) {
+			cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n",
+				     pcie_port);
+			return -1;
+		}
+	}
+
+	/*
+	 * Check and make sure PCIe came out of reset. If it doesn't
+	 * the board probably hasn't wired the clocks up and the
+	 * interface should be skipped.
+	 */
+	pescx_ctl_status2.u64 =
+	    cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+	if (pescx_ctl_status2.s.pcierst) {
+		cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n",
+			     pcie_port);
+		return -1;
+	}
+
+	/*
+	 * Check BIST2 status. If any bits are set skip this interface. This
+	 * is an attempt to catch PCIE-813 on pass 1 parts.
+	 */
+	pescx_bist_status2.u64 =
+	    cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
+	if (pescx_bist_status2.u64) {
+		cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this "
+			     "port isn't hooked up, skipping.\n",
+			     pcie_port);
+		return -1;
+	}
+
+	/* Check BIST status */
+	pescx_bist_status.u64 =
+	    cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
+	if (pescx_bist_status.u64)
+		cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n",
+			     pcie_port, CAST64(pescx_bist_status.u64));
+
+	/* Initialize the config space CSRs */
+	__cvmx_pcie_rc_initialize_config_space(pcie_port);
+
+	/* Bring the link up */
+	if (__cvmx_pcie_rc_initialize_link(pcie_port)) {
+		cvmx_dprintf
+		    ("PCIe: ERROR: cvmx_pcie_rc_initialize_link() failed\n");
+		return -1;
+	}
+
+	/* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
+	npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL);
+	/* Allow 16 words to combine */
+	npei_mem_access_ctl.s.max_word = 0;
+	/* Wait up to 127 cycles for more data */
+	npei_mem_access_ctl.s.timer = 127;
+	cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64);
+
+	/* Setup Mem access SubDIDs */
+	mem_access_subid.u64 = 0;
+	/* Port the request is sent to. */
+	mem_access_subid.s.port = pcie_port;
+	/* Due to an errata on pass 1 chips, no merging is allowed. */
+	mem_access_subid.s.nmerge = 1;
+	/* Endian-swap for Reads. */
+	mem_access_subid.s.esr = 1;
+	/* Endian-swap for Writes. */
+	mem_access_subid.s.esw = 1;
+	/* No Snoop for Reads. */
+	mem_access_subid.s.nsr = 1;
+	/* No Snoop for Writes. */
+	mem_access_subid.s.nsw = 1;
+	/* Disable Relaxed Ordering for Reads. */
+	mem_access_subid.s.ror = 0;
+	/* Disable Relaxed Ordering for Writes. */
+	mem_access_subid.s.row = 0;
+	/* PCIe Adddress Bits <63:34>. */
+	mem_access_subid.s.ba = 0;
+
+	/*
+	 * Setup mem access 12-15 for port 0, 16-19 for port 1,
+	 * supplying 36 bits of address space.
+	 */
+	for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
+		cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i),
+			       mem_access_subid.u64);
+		/* Set each SUBID to extend the addressable range */
+		mem_access_subid.s.ba += 1;
+	}
+
+	/*
+	 * Disable the peer to peer forwarding register. This must be
+	 * setup by the OS after it enumerates the bus and assigns
+	 * addresses to the PCIe busses.
+	 */
+	for (i = 0; i < 4; i++) {
+		cvmx_write_csr(CVMX_PESCX_P2P_BARX_START(i, pcie_port), -1);
+		cvmx_write_csr(CVMX_PESCX_P2P_BARX_END(i, pcie_port), -1);
+	}
+
+	/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
+	cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
+
+	/*
+	 * Disable Octeon's BAR1. It isn't needed in RC mode since
+	 * BAR2 maps all of memory. BAR2 also maps 256MB-512MB into
+	 * the 2nd 256MB of memory.
+	 */
+	cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), -1);
+
+	/*
+	 * Set Octeon's BAR2 to decode 0-2^39. Bar0 and Bar1 take
+	 * precedence where they overlap. It also overlaps with the
+	 * device addresses, so make sure the peer to peer forwarding
+	 * is set right.
+	 */
+	cvmx_write_csr(CVMX_PESCX_P2N_BAR2_START(pcie_port), 0);
+
+	/*
+	 * Setup BAR2 attributes
+	 *
+	 * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
+	 * - PTLP_RO,CTLP_RO should normally be set (except for debug).
+	 * - WAIT_COM=0 will likely work for all applications.
+	 *
+	 * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]).
+	 */
+	if (pcie_port) {
+		union cvmx_npei_ctl_port1 npei_ctl_port;
+		npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT1);
+		npei_ctl_port.s.bar2_enb = 1;
+		npei_ctl_port.s.bar2_esx = 1;
+		npei_ctl_port.s.bar2_cax = 0;
+		npei_ctl_port.s.ptlp_ro = 1;
+		npei_ctl_port.s.ctlp_ro = 1;
+		npei_ctl_port.s.wait_com = 0;
+		npei_ctl_port.s.waitl_com = 0;
+		cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT1, npei_ctl_port.u64);
+	} else {
+		union cvmx_npei_ctl_port0 npei_ctl_port;
+		npei_ctl_port.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_PORT0);
+		npei_ctl_port.s.bar2_enb = 1;
+		npei_ctl_port.s.bar2_esx = 1;
+		npei_ctl_port.s.bar2_cax = 0;
+		npei_ctl_port.s.ptlp_ro = 1;
+		npei_ctl_port.s.ctlp_ro = 1;
+		npei_ctl_port.s.wait_com = 0;
+		npei_ctl_port.s.waitl_com = 0;
+		cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64);
+	}
+	return 0;
+}
+
+
+/* Above was cvmx-pcie.c, below original pcie.c */
+
+
+/**
+ * Map a PCI device to the appropriate interrupt line
+ *
+ * @param dev    The Linux PCI device structure for the device to map
+ * @param slot   The slot number for this device on __BUS 0__. Linux
+ *               enumerates through all the bridges and figures out the
+ *               slot on Bus 0 where this device eventually hooks to.
+ * @param pin    The PCI interrupt pin read from the device, then swizzled
+ *               as it goes through each bridge.
+ * @return Interrupt number for the device
+ */
+int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev,
+				       u8 slot, u8 pin)
+{
+	/*
+	 * The EBH5600 board with the PCI to PCIe bridge mistakenly
+	 * wires the first slot for both device id 2 and interrupt
+	 * A. According to the PCI spec, device id 2 should be C. The
+	 * following kludge attempts to fix this.
+	 */
+	if (strstr(octeon_board_type_string(), "EBH5600") &&
+	    dev->bus && dev->bus->parent) {
+		/*
+		 * Iterate all the way up the device chain and find
+		 * the root bus.
+		 */
+		while (dev->bus && dev->bus->parent)
+			dev = to_pci_dev(dev->bus->bridge);
+		/* If the root bus is number 0 and the PEX 8114 is the
+		 * root, assume we are behind the miswired bus. We
+		 * need to correct the swizzle level by two. Yuck.
+		 */
+		if ((dev->bus->number == 0) &&
+		    (dev->vendor == 0x10b5) && (dev->device == 0x8114)) {
+			/*
+			 * The pin field is one based, not zero. We
+			 * need to swizzle it by minus two.
+			 */
+			pin = ((pin - 3) & 3) + 1;
+		}
+	}
+	/*
+	 * The -1 is because pin starts with one, not zero. It might
+	 * be that this equation needs to include the slot number, but
+	 * I don't have hardware to check that against.
+	 */
+	return pin - 1 + OCTEON_IRQ_PCI_INT0;
+}
+
+/**
+ * Read a value from configuration space
+ *
+ * @param bus
+ * @param devfn
+ * @param reg
+ * @param size
+ * @param val
+ * @return
+ */
+static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
+					  unsigned int devfn, int reg, int size,
+					  u32 *val)
+{
+	union octeon_cvmemctl cvmmemctl;
+	union octeon_cvmemctl cvmmemctl_save;
+	int bus_number = bus->number;
+
+	/*
+	 * We need to force the bus number to be zero on the root
+	 * bus. Linux numbers the 2nd root bus to start after all
+	 * buses on root 0.
+	 */
+	if (bus->parent == NULL)
+		bus_number = 0;
+
+	/*
+	 * PCIe only has a single device connected to Octeon. It is
+	 * always device ID 0. Don't bother doing reads for other
+	 * device IDs on the first segment.
+	 */
+	if ((bus_number == 0) && (devfn >> 3 != 0))
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+
+	/*
+	 * The following is a workaround for the CN57XX, CN56XX,
+	 * CN55XX, and CN54XX errata with PCIe config reads from non
+	 * existent devices.  These chips will hang the PCIe link if a
+	 * config read is performed that causes a UR response.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1)) {
+		/*
+		 * For our EBH5600 board, port 0 has a bridge with two
+		 * PCI-X slots. We need a new special checks to make
+		 * sure we only probe valid stuff.  The PCIe->PCI-X
+		 * bridge only respondes to device ID 0, function
+		 * 0-1
+		 */
+		if ((bus_number == 0) && (devfn >= 2))
+			return PCIBIOS_FUNC_NOT_SUPPORTED;
+		/*
+		 * The PCI-X slots are device ID 2,3. Choose one of
+		 * the below "if" blocks based on what is plugged into
+		 * the board.
+		 */
+#if 1
+		/* Use this option if you aren't using either slot */
+		if (bus_number == 1)
+			return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+		/*
+		 * Use this option if you are using the first slot but
+		 * not the second.
+		 */
+		if ((bus_number == 1) && (devfn >> 3 != 2))
+			return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+		/*
+		 * Use this option if you are using the second slot
+		 * but not the first.
+		 */
+		if ((bus_number == 1) && (devfn >> 3 != 3))
+			return PCIBIOS_FUNC_NOT_SUPPORTED;
+#elif 0
+		/* Use this opion if you are using both slots */
+		if ((bus_number == 1) &&
+		    !((devfn == (2 << 3)) || (devfn == (3 << 3))))
+			return PCIBIOS_FUNC_NOT_SUPPORTED;
+#endif
+
+		/*
+		 * Shorten the DID timeout so bus errors for PCIe
+		 * config reads from non existent devices happen
+		 * faster. This allows us to continue booting even if
+		 * the above "if" checks are wrong.  Once one of these
+		 * errors happens, the PCIe port is dead.
+		 */
+		cvmmemctl_save.u64 = __read_64bit_c0_register($11, 7);
+		cvmmemctl.u64 = cvmmemctl_save.u64;
+		cvmmemctl.s.didtto = 2;
+		__write_64bit_c0_register($11, 7, cvmmemctl.u64);
+	}
+
+	switch (size) {
+	case 4:
+		*val = cvmx_pcie_config_read32(pcie_port, bus_number,
+					       devfn >> 3, devfn & 0x7, reg);
+		break;
+	case 2:
+		*val = cvmx_pcie_config_read16(pcie_port, bus_number,
+					       devfn >> 3, devfn & 0x7, reg);
+		break;
+	case 1:
+		*val = cvmx_pcie_config_read8(pcie_port, bus_number, devfn >> 3,
+					      devfn & 0x7, reg);
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
+	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1))
+		__write_64bit_c0_register($11, 7, cvmmemctl_save.u64);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int octeon_pcie0_read_config(struct pci_bus *bus, unsigned int devfn,
+				    int reg, int size, u32 *val)
+{
+	return octeon_pcie_read_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn,
+				    int reg, int size, u32 *val)
+{
+	return octeon_pcie_read_config(1, bus, devfn, reg, size, val);
+}
+
+
+
+/**
+ * Write a value to PCI configuration space
+ *
+ * @param bus
+ * @param devfn
+ * @param reg
+ * @param size
+ * @param val
+ * @return
+ */
+static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus,
+					   unsigned int devfn, int reg,
+					   int size, u32 val)
+{
+	int bus_number = bus->number;
+	/*
+	 * We need to force the bus number to be zero on the root
+	 * bus. Linux numbers the 2nd root bus to start after all
+	 * busses on root 0.
+	 */
+	if (bus->parent == NULL)
+		bus_number = 0;
+
+	switch (size) {
+	case 4:
+		cvmx_pcie_config_write32(pcie_port, bus_number, devfn >> 3,
+					 devfn & 0x7, reg, val);
+		return PCIBIOS_SUCCESSFUL;
+	case 2:
+		cvmx_pcie_config_write16(pcie_port, bus_number, devfn >> 3,
+					 devfn & 0x7, reg, val);
+		return PCIBIOS_SUCCESSFUL;
+	case 1:
+		cvmx_pcie_config_write8(pcie_port, bus_number, devfn >> 3,
+					devfn & 0x7, reg, val);
+		return PCIBIOS_SUCCESSFUL;
+	}
+#if PCI_CONFIG_SPACE_DELAY
+	udelay(PCI_CONFIG_SPACE_DELAY);
+#endif
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
+static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn,
+				     int reg, int size, u32 val)
+{
+	return octeon_pcie_write_config(0, bus, devfn, reg, size, val);
+}
+
+static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn,
+				     int reg, int size, u32 val)
+{
+	return octeon_pcie_write_config(1, bus, devfn, reg, size, val);
+}
+
+static struct pci_ops octeon_pcie0_ops = {
+	octeon_pcie0_read_config,
+	octeon_pcie0_write_config,
+};
+
+static struct resource octeon_pcie0_mem_resource = {
+	.name = "Octeon PCIe0 MEM",
+	.flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie0_io_resource = {
+	.name = "Octeon PCIe0 IO",
+	.flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie0_controller = {
+	.pci_ops = &octeon_pcie0_ops,
+	.mem_resource = &octeon_pcie0_mem_resource,
+	.io_resource = &octeon_pcie0_io_resource,
+};
+
+static struct pci_ops octeon_pcie1_ops = {
+	octeon_pcie1_read_config,
+	octeon_pcie1_write_config,
+};
+
+static struct resource octeon_pcie1_mem_resource = {
+	.name = "Octeon PCIe1 MEM",
+	.flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_pcie1_io_resource = {
+	.name = "Octeon PCIe1 IO",
+	.flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_pcie1_controller = {
+	.pci_ops = &octeon_pcie1_ops,
+	.mem_resource = &octeon_pcie1_mem_resource,
+	.io_resource = &octeon_pcie1_io_resource,
+};
+
+
+/**
+ * Initialize the Octeon PCIe controllers
+ *
+ * @return
+ */
+static int __init octeon_pcie_setup(void)
+{
+	union cvmx_npei_ctl_status npei_ctl_status;
+	int result;
+
+	/* These chips don't have PCIe */
+	if (!octeon_has_feature(OCTEON_FEATURE_PCIE))
+		return 0;
+
+	/* Point pcibios_map_irq() to the PCIe version of it */
+	octeon_pcibios_map_irq = octeon_pcie_pcibios_map_irq;
+
+	/* Use the PCIe based DMA mappings */
+	octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
+
+	/*
+	 * PCIe I/O range. It is based on port 0 but includes up until
+	 * port 1's end.
+	 */
+	set_io_port_base(CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0)));
+	ioport_resource.start = 0;
+	ioport_resource.end =
+		cvmx_pcie_get_io_base_address(1) -
+		cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1;
+
+	npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+	if (npei_ctl_status.s.host_mode) {
+		pr_notice("PCIe: Initializing port 0\n");
+		result = cvmx_pcie_rc_initialize(0);
+		if (result == 0) {
+			/* Memory offsets are physical addresses */
+			octeon_pcie0_controller.mem_offset =
+				cvmx_pcie_get_mem_base_address(0);
+			/* IO offsets are Mips virtual addresses */
+			octeon_pcie0_controller.io_map_base =
+				CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address
+						(0));
+			octeon_pcie0_controller.io_offset = 0;
+			/*
+			 * To keep things similar to PCI, we start
+			 * device addresses at the same place as PCI
+			 * uisng big bar support. This normally
+			 * translates to 4GB-256MB, which is the same
+			 * as most x86 PCs.
+			 */
+			octeon_pcie0_controller.mem_resource->start =
+				cvmx_pcie_get_mem_base_address(0) +
+				(4ul << 30) - (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+			octeon_pcie0_controller.mem_resource->end =
+				cvmx_pcie_get_mem_base_address(0) +
+				cvmx_pcie_get_mem_size(0) - 1;
+			/*
+			 * Ports must be above 16KB for the ISA bus
+			 * filtering in the PCI-X to PCI bridge.
+			 */
+			octeon_pcie0_controller.io_resource->start = 4 << 10;
+			octeon_pcie0_controller.io_resource->end =
+				cvmx_pcie_get_io_size(0) - 1;
+			register_pci_controller(&octeon_pcie0_controller);
+		}
+	} else {
+		pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
+	}
+
+	/* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		union cvmx_npei_dbg_data npei_dbg_data;
+		npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+		if (npei_dbg_data.cn52xx.qlm0_link_width)
+			return 0;
+	}
+
+	pr_notice("PCIe: Initializing port 1\n");
+	result = cvmx_pcie_rc_initialize(1);
+	if (result == 0) {
+		/* Memory offsets are physical addresses */
+		octeon_pcie1_controller.mem_offset =
+			cvmx_pcie_get_mem_base_address(1);
+		/* IO offsets are Mips virtual addresses */
+		octeon_pcie1_controller.io_map_base =
+			CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(1));
+		octeon_pcie1_controller.io_offset =
+			cvmx_pcie_get_io_base_address(1) -
+			cvmx_pcie_get_io_base_address(0);
+		/*
+		 * To keep things similar to PCI, we start device
+		 * addresses at the same place as PCI uisng big bar
+		 * support. This normally translates to 4GB-256MB,
+		 * which is the same as most x86 PCs.
+		 */
+		octeon_pcie1_controller.mem_resource->start =
+			cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
+			(OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+		octeon_pcie1_controller.mem_resource->end =
+			cvmx_pcie_get_mem_base_address(1) +
+			cvmx_pcie_get_mem_size(1) - 1;
+		/*
+		 * Ports must be above 16KB for the ISA bus filtering
+		 * in the PCI-X to PCI bridge.
+		 */
+		octeon_pcie1_controller.io_resource->start =
+			cvmx_pcie_get_io_base_address(1) -
+			cvmx_pcie_get_io_base_address(0);
+		octeon_pcie1_controller.io_resource->end =
+			octeon_pcie1_controller.io_resource->start +
+			cvmx_pcie_get_io_size(1) - 1;
+		register_pci_controller(&octeon_pcie1_controller);
+	}
+	return 0;
+}
+
+arch_initcall(octeon_pcie_setup);
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index c0047f8..8ab1d12 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -147,6 +147,10 @@
 #define cpu_has_mips_r	(cpu_has_mips32r1 | cpu_has_mips32r2 | \
 			 cpu_has_mips64r1 | cpu_has_mips64r2)
 
+#ifndef cpu_has_mips_r2_exec_hazard
+#define cpu_has_mips_r2_exec_hazard cpu_has_mips_r2
+#endif
+
 /*
  * MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
  * pre-MIPS32/MIPS53 processors have CLO, CLZ.  For 64-bit kernels
@@ -230,4 +234,8 @@
 #define cpu_scache_line_size()	cpu_data[0].scache.linesz
 #endif
 
+#ifndef cpu_hwrena_impl_bits
+#define cpu_hwrena_impl_bits		0
+#endif
+
 #endif /* __ASM_CPU_FEATURES_H */
diff --git a/arch/mips/include/asm/delay.h b/arch/mips/include/asm/delay.h
index a07e51b..d2d8949 100644
--- a/arch/mips/include/asm/delay.h
+++ b/arch/mips/include/asm/delay.h
@@ -15,7 +15,7 @@
 extern void __ndelay(unsigned int ns);
 extern void __udelay(unsigned int us);
 
-#define ndelay(ns) __udelay(ns)
+#define ndelay(ns) __ndelay(ns)
 #define udelay(us) __udelay(us)
 
 /* make sure "usecs *= ..." in udelay do not overflow. */
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
new file mode 100644
index 0000000..f5e85601
--- /dev/null
+++ b/arch/mips/include/asm/hugetlb.h
@@ -0,0 +1,114 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
+ */
+
+#ifndef __ASM_HUGETLB_H
+#define __ASM_HUGETLB_H
+
+#include <asm/page.h>
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+					 unsigned long addr,
+					 unsigned long len)
+{
+	return 0;
+}
+
+static inline int prepare_hugepage_range(struct file *file,
+					 unsigned long addr,
+					 unsigned long len)
+{
+	unsigned long task_size = STACK_TOP;
+	struct hstate *h = hstate_file(file);
+
+	if (len & ~huge_page_mask(h))
+		return -EINVAL;
+	if (addr & ~huge_page_mask(h))
+		return -EINVAL;
+	if (len > task_size)
+		return -ENOMEM;
+	if (task_size - len < addr)
+		return -EINVAL;
+	return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+					  unsigned long addr,
+					  unsigned long end,
+					  unsigned long floor,
+					  unsigned long ceiling)
+{
+	free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+				   pte_t *ptep, pte_t pte)
+{
+	set_pte_at(mm, addr, ptep, pte);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+					    unsigned long addr, pte_t *ptep)
+{
+	pte_t clear;
+	pte_t pte = *ptep;
+
+	pte_val(clear) = (unsigned long)invalid_pte_table;
+	set_pte_at(mm, addr, ptep, clear);
+	return pte;
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+					 unsigned long addr, pte_t *ptep)
+{
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+	unsigned long val = pte_val(pte) & ~_PAGE_GLOBAL;
+	return !val || (val == (unsigned long)invalid_pte_table);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+	return pte_wrprotect(pte);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+					   unsigned long addr, pte_t *ptep)
+{
+	ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+					     unsigned long addr,
+					     pte_t *ptep, pte_t pte,
+					     int dirty)
+{
+	return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+	return *ptep;
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+	return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+#endif /* __ASM_HUGETLB_H */
diff --git a/arch/mips/include/asm/ioctl.h b/arch/mips/include/asm/ioctl.h
index 9161634..c515a1a 100644
--- a/arch/mips/include/asm/ioctl.h
+++ b/arch/mips/include/asm/ioctl.h
@@ -3,40 +3,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1995, 96, 99, 2001 Ralf Baechle
+ * Copyright (C) 1995, 96, 99, 2001 Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2009 Wind River Systems
+ * Written by Ralf Baechle <ralf@linux-mips.org>
  */
-#ifndef _ASM_IOCTL_H
-#define _ASM_IOCTL_H
+#ifndef __ASM_IOCTL_H
+#define __ASM_IOCTL_H
 
-/*
- * The original linux ioctl numbering scheme was just a general
- * "anything goes" setup, where more or less random numbers were
- * assigned.  Sorry, I was clueless when I started out on this.
- *
- * On the alpha, we'll try to clean it up a bit, using a more sane
- * ioctl numbering, and also trying to be compatible with OSF/1 in
- * the process. I'd like to clean it up for the i386 as well, but
- * it's so painful recognizing both the new and the old numbers..
- *
- * The same applies for for the MIPS ABI; in fact even the macros
- * from Linux/Alpha fit almost perfectly.
- */
-
-#define _IOC_NRBITS	8
-#define _IOC_TYPEBITS	8
 #define _IOC_SIZEBITS	13
 #define _IOC_DIRBITS	3
 
-#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT	0
-#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
 /*
  * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
  * And this turns out useful to catch old ioctl numbers in header
@@ -46,53 +22,6 @@
 #define _IOC_READ	2U
 #define _IOC_WRITE	4U
 
-/*
- * The following are included for compatibility
- */
-#define _IOC_VOID	0x20000000
-#define _IOC_OUT	0x40000000
-#define _IOC_IN		0x80000000
-#define _IOC_INOUT	(IOC_IN|IOC_OUT)
+#include <asm-generic/ioctl.h>
 
-#define _IOC(dir, type, nr, size) \
-	(((dir)  << _IOC_DIRSHIFT) | \
-	 ((type) << _IOC_TYPESHIFT) | \
-	 ((nr)   << _IOC_NRSHIFT) | \
-	 ((size) << _IOC_SIZESHIFT))
-
-#ifdef __KERNEL__
-/* provoke compile error for invalid uses of size argument */
-extern unsigned int __invalid_size_argument_for_IOC;
-#define _IOC_TYPECHECK(t) \
-	((sizeof(t) == sizeof(t[1]) && \
-	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
-	  sizeof(t) : __invalid_size_argument_for_IOC)
-#else
-#define _IOC_TYPECHECK(t)	(sizeof(t))
-#endif
-
-/* used to create numbers */
-#define _IO(type, nr)		_IOC(_IOC_NONE, (type), (nr), 0)
-#define _IOR(type, nr, size)	_IOC(_IOC_READ, (type), (nr), (_IOC_TYPECHECK(size)))
-#define _IOW(type, nr, size)	_IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
-#define _IOWR(type, nr, size)	_IOC(_IOC_READ|_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
-#define _IOR_BAD(type, nr, size)	_IOC(_IOC_READ, (type), (nr), sizeof(size))
-#define _IOW_BAD(type, nr, size)	_IOC(_IOC_WRITE, (type), (nr), sizeof(size))
-#define _IOWR_BAD(type, nr, size)	_IOC(_IOC_READ|_IOC_WRITE, (type), (nr), sizeof(size))
-
-
-/* used to decode them.. */
-#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
-
-#endif /* _ASM_IOCTL_H */
+#endif /* __ASM_IOCTL_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1000_gpio.h b/arch/mips/include/asm/mach-au1x00/au1000_gpio.h
deleted file mode 100644
index d8c96fd..0000000
--- a/arch/mips/include/asm/mach-au1x00/au1000_gpio.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * FILE NAME au1000_gpio.h
- *
- * BRIEF MODULE DESCRIPTION
- *	API to Alchemy Au1xx0 GPIO device.
- *
- *  Author: MontaVista Software, Inc.  <source@mvista.com>
- *          Steve Longerbeam
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __AU1000_GPIO_H
-#define __AU1000_GPIO_H
-
-#include <linux/ioctl.h>
-
-#define AU1000GPIO_IOC_MAGIC 'A'
-
-#define AU1000GPIO_IN		_IOR(AU1000GPIO_IOC_MAGIC, 0, int)
-#define AU1000GPIO_SET		_IOW(AU1000GPIO_IOC_MAGIC, 1, int)
-#define AU1000GPIO_CLEAR	_IOW(AU1000GPIO_IOC_MAGIC, 2, int)
-#define AU1000GPIO_OUT		_IOW(AU1000GPIO_IOC_MAGIC, 3, int)
-#define AU1000GPIO_TRISTATE	_IOW(AU1000GPIO_IOC_MAGIC, 4, int)
-#define AU1000GPIO_AVAIL_MASK	_IOR(AU1000GPIO_IOC_MAGIC, 5, int)
-
-#ifdef __KERNEL__
-extern u32 get_au1000_avail_gpio_mask(void);
-extern int au1000gpio_tristate(u32 data);
-extern int au1000gpio_in(u32 *data);
-extern int au1000gpio_set(u32 data);
-extern int au1000gpio_clear(u32 data);
-extern int au1000gpio_out(u32 data);
-#endif
-
-#endif
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
new file mode 100644
index 0000000..127d4ed
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
@@ -0,0 +1,604 @@
+/*
+ * GPIO functions for Au1000, Au1500, Au1100, Au1550, Au1200
+ *
+ * Copyright (c) 2009 Manuel Lauss.
+ *
+ * Licensed under the terms outlined in the file COPYING.
+ */
+
+#ifndef _ALCHEMY_GPIO_AU1000_H_
+#define _ALCHEMY_GPIO_AU1000_H_
+
+#include <asm/mach-au1x00/au1000.h>
+
+/* The default GPIO numberspace as documented in the Alchemy manuals.
+ * GPIO0-31 from GPIO1 block,   GPIO200-215 from GPIO2 block.
+ */
+#define ALCHEMY_GPIO1_BASE	0
+#define ALCHEMY_GPIO2_BASE	200
+
+#define ALCHEMY_GPIO1_NUM	32
+#define ALCHEMY_GPIO2_NUM	16
+#define ALCHEMY_GPIO1_MAX 	(ALCHEMY_GPIO1_BASE + ALCHEMY_GPIO1_NUM - 1)
+#define ALCHEMY_GPIO2_MAX	(ALCHEMY_GPIO2_BASE + ALCHEMY_GPIO2_NUM - 1)
+
+#define MAKE_IRQ(intc, off)	(AU1000_INTC##intc##_INT_BASE + (off))
+
+
+static inline int au1000_gpio1_to_irq(int gpio)
+{
+	return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1000_gpio2_to_irq(int gpio)
+{
+	return -ENXIO;
+}
+
+#ifdef CONFIG_SOC_AU1000
+static inline int au1000_irq_to_gpio(int irq)
+{
+	if ((irq >= AU1000_GPIO_0) && (irq <= AU1000_GPIO_31))
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+
+	return -ENXIO;
+}
+#endif
+
+static inline int au1500_gpio1_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO1_BASE;
+
+	switch (gpio) {
+	case 0 ... 15:
+	case 20:
+	case 23 ... 28:	return MAKE_IRQ(1, gpio);
+	}
+
+	return -ENXIO;
+}
+
+static inline int au1500_gpio2_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO2_BASE;
+
+	switch (gpio) {
+	case 0 ... 3:	return MAKE_IRQ(1, 16 + gpio - 0);
+	case 4 ... 5:	return MAKE_IRQ(1, 21 + gpio - 4);
+	case 6 ... 7:	return MAKE_IRQ(1, 29 + gpio - 6);
+	}
+
+	return -ENXIO;
+}
+
+#ifdef CONFIG_SOC_AU1500
+static inline int au1500_irq_to_gpio(int irq)
+{
+	switch (irq) {
+	case AU1000_GPIO_0 ... AU1000_GPIO_15:
+	case AU1500_GPIO_20:
+	case AU1500_GPIO_23 ... AU1500_GPIO_28:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+	case AU1500_GPIO_200 ... AU1500_GPIO_203:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_200) + 0;
+	case AU1500_GPIO_204 ... AU1500_GPIO_205:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_204) + 4;
+	case AU1500_GPIO_206 ... AU1500_GPIO_207:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
+	case AU1500_GPIO_208_215:
+		return ALCHEMY_GPIO2_BASE + 8;
+	}
+
+	return -ENXIO;
+}
+#endif
+
+static inline int au1100_gpio1_to_irq(int gpio)
+{
+	return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1100_gpio2_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO2_BASE;
+
+	if ((gpio >= 8) && (gpio <= 15))
+		return MAKE_IRQ(0, 29);		/* shared GPIO208_215 */
+}
+
+#ifdef CONFIG_SOC_AU1100
+static inline int au1100_irq_to_gpio(int irq)
+{
+	switch (irq) {
+	case AU1000_GPIO_0 ... AU1000_GPIO_31:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+	case AU1100_GPIO_208_215:
+		return ALCHEMY_GPIO2_BASE + 8;
+	}
+
+	return -ENXIO;
+}
+#endif
+
+static inline int au1550_gpio1_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO1_BASE;
+
+	switch (gpio) {
+	case 0 ... 15:
+	case 20 ... 28:	return MAKE_IRQ(1, gpio);
+	case 16 ... 17:	return MAKE_IRQ(1, 18 + gpio - 16);
+	}
+
+	return -ENXIO;
+}
+
+static inline int au1550_gpio2_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO2_BASE;
+
+	switch (gpio) {
+	case 0:		return MAKE_IRQ(1, 16);
+	case 1 ... 5:	return MAKE_IRQ(1, 17);	/* shared GPIO201_205 */
+	case 6 ... 7:	return MAKE_IRQ(1, 29 + gpio - 6);
+	case 8 ... 15:	return MAKE_IRQ(1, 31);	/* shared GPIO208_215 */
+	}
+
+	return -ENXIO;
+}
+
+#ifdef CONFIG_SOC_AU1550
+static inline int au1550_irq_to_gpio(int irq)
+{
+	switch (irq) {
+	case AU1000_GPIO_0 ... AU1000_GPIO_15:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+	case AU1550_GPIO_200:
+	case AU1500_GPIO_201_205:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1550_GPIO_200) + 0;
+	case AU1500_GPIO_16 ... AU1500_GPIO_28:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1500_GPIO_16) + 16;
+	case AU1500_GPIO_206 ... AU1500_GPIO_208_218:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1500_GPIO_206) + 6;
+	}
+
+	return -ENXIO;
+}
+#endif
+
+static inline int au1200_gpio1_to_irq(int gpio)
+{
+	return MAKE_IRQ(1, gpio - ALCHEMY_GPIO1_BASE);
+}
+
+static inline int au1200_gpio2_to_irq(int gpio)
+{
+	gpio -= ALCHEMY_GPIO2_BASE;
+
+	switch (gpio) {
+	case 0 ... 2:	return MAKE_IRQ(0, 5 + gpio - 0);
+	case 3:		return MAKE_IRQ(0, 22);
+	case 4 ... 7:	return MAKE_IRQ(0, 24 + gpio - 4);
+	case 8 ... 15:	return MAKE_IRQ(0, 28);	/* shared GPIO208_215 */
+	}
+
+	return -ENXIO;
+}
+
+#ifdef CONFIG_SOC_AU1200
+static inline int au1200_irq_to_gpio(int irq)
+{
+	switch (irq) {
+	case AU1000_GPIO_0 ... AU1000_GPIO_31:
+		return ALCHEMY_GPIO1_BASE + (irq - AU1000_GPIO_0) + 0;
+	case AU1200_GPIO_200 ... AU1200_GPIO_202:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_200) + 0;
+	case AU1200_GPIO_203:
+		return ALCHEMY_GPIO2_BASE + 3;
+	case AU1200_GPIO_204 ... AU1200_GPIO_208_215:
+		return ALCHEMY_GPIO2_BASE + (irq - AU1200_GPIO_204) + 4;
+	}
+
+	return -ENXIO;
+}
+#endif
+
+/*
+ * GPIO1 block macros for common linux gpio functions.
+ */
+static inline void alchemy_gpio1_set_value(int gpio, int v)
+{
+	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+	unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
+	au_writel(mask, r);
+	au_sync();
+}
+
+static inline int alchemy_gpio1_get_value(int gpio)
+{
+	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+	return au_readl(SYS_PINSTATERD) & mask;
+}
+
+static inline int alchemy_gpio1_direction_input(int gpio)
+{
+	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
+	au_writel(mask, SYS_TRIOUTCLR);
+	au_sync();
+	return 0;
+}
+
+static inline int alchemy_gpio1_direction_output(int gpio, int v)
+{
+	/* hardware switches to "output" mode when one of the two
+	 * "set_value" registers is accessed.
+	 */
+	alchemy_gpio1_set_value(gpio, v);
+	return 0;
+}
+
+static inline int alchemy_gpio1_is_valid(int gpio)
+{
+	return ((gpio >= ALCHEMY_GPIO1_BASE) && (gpio <= ALCHEMY_GPIO1_MAX));
+}
+
+static inline int alchemy_gpio1_to_irq(int gpio)
+{
+#if defined(CONFIG_SOC_AU1000)
+	return au1000_gpio1_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1100)
+	return au1100_gpio1_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1500)
+	return au1500_gpio1_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1550)
+	return au1550_gpio1_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1200)
+	return au1200_gpio1_to_irq(gpio);
+#else
+	return -ENXIO;
+#endif
+}
+
+/*
+ * GPIO2 block macros for common linux GPIO functions. The 'gpio'
+ * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX.
+ */
+static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
+{
+	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
+	unsigned long d = au_readl(GPIO2_DIR);
+	if (to_out)
+		d |= mask;
+	else
+		d &= ~mask;
+	au_writel(d, GPIO2_DIR);
+	au_sync();
+}
+
+static inline void alchemy_gpio2_set_value(int gpio, int v)
+{
+	unsigned long mask;
+	mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
+	au_writel(mask, GPIO2_OUTPUT);
+	au_sync();
+}
+
+static inline int alchemy_gpio2_get_value(int gpio)
+{
+	return au_readl(GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
+}
+
+static inline int alchemy_gpio2_direction_input(int gpio)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	__alchemy_gpio2_mod_dir(gpio, 0);
+	local_irq_restore(flags);
+	return 0;
+}
+
+static inline int alchemy_gpio2_direction_output(int gpio, int v)
+{
+	unsigned long flags;
+	alchemy_gpio2_set_value(gpio, v);
+	local_irq_save(flags);
+	__alchemy_gpio2_mod_dir(gpio, 1);
+	local_irq_restore(flags);
+	return 0;
+}
+
+static inline int alchemy_gpio2_is_valid(int gpio)
+{
+	return ((gpio >= ALCHEMY_GPIO2_BASE) && (gpio <= ALCHEMY_GPIO2_MAX));
+}
+
+static inline int alchemy_gpio2_to_irq(int gpio)
+{
+#if defined(CONFIG_SOC_AU1000)
+	return au1000_gpio2_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1100)
+	return au1100_gpio2_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1500)
+	return au1500_gpio2_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1550)
+	return au1550_gpio2_to_irq(gpio);
+#elif defined(CONFIG_SOC_AU1200)
+	return au1200_gpio2_to_irq(gpio);
+#else
+	return -ENXIO;
+#endif
+}
+
+/**********************************************************************/
+
+/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
+ * SYS_PININPUTEN is written to at least once.  On Au1550/Au1200 this
+ * register enables use of GPIOs as wake source.
+ */
+static inline void alchemy_gpio1_input_enable(void)
+{
+	au_writel(0, SYS_PININPUTEN);	/* the write op is key */
+	au_sync();
+}
+
+/* GPIO2 shared interrupts and control */
+
+static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
+{
+	unsigned long r = au_readl(GPIO2_INTENABLE);
+	if (en)
+		r |= 1 << gpio2;
+	else
+		r &= ~(1 << gpio2);
+	au_writel(r, GPIO2_INTENABLE);
+	au_sync();
+}
+
+/**
+ * alchemy_gpio2_enable_int - Enable a GPIO2 pins' shared irq contribution.
+ * @gpio2:	The GPIO2 pin to activate (200...215).
+ *
+ * GPIO208-215 have one shared interrupt line to the INTC.  They are
+ * and'ed with a per-pin enable bit and finally or'ed together to form
+ * a single irq request (useful for active-high sources).
+ * With this function, a pins' individual contribution to the int request
+ * can be enabled.  As with all other GPIO-based interrupts, the INTC
+ * must be programmed to accept the GPIO208_215 interrupt as well.
+ *
+ * NOTE: Calling this macro is only necessary for GPIO208-215; all other
+ * GPIO2-based interrupts have their own request to the INTC.  Please
+ * consult your Alchemy databook for more information!
+ *
+ * NOTE: On the Au1550, GPIOs 201-205 also have a shared interrupt request
+ * line to the INTC, GPIO201_205.  This function can be used for those
+ * as well.
+ *
+ * NOTE: 'gpio2' parameter must be in range of the GPIO2 numberspace
+ * (200-215 by default). No sanity checks are made,
+ */
+static inline void alchemy_gpio2_enable_int(int gpio2)
+{
+	unsigned long flags;
+
+	gpio2 -= ALCHEMY_GPIO2_BASE;
+
+#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
+	/* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
+	gpio2 -= 8;
+#endif
+	local_irq_save(flags);
+	__alchemy_gpio2_mod_int(gpio2, 1);
+	local_irq_restore(flags);
+}
+
+/**
+ * alchemy_gpio2_disable_int - Disable a GPIO2 pins' shared irq contribution.
+ * @gpio2:	The GPIO2 pin to activate (200...215).
+ *
+ * see function alchemy_gpio2_enable_int() for more information.
+ */
+static inline void alchemy_gpio2_disable_int(int gpio2)
+{
+	unsigned long flags;
+
+	gpio2 -= ALCHEMY_GPIO2_BASE;
+
+#if defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
+	/* Au1100/Au1500 have GPIO208-215 enable bits at 0..7 */
+	gpio2 -= 8;
+#endif
+	local_irq_save(flags);
+	__alchemy_gpio2_mod_int(gpio2, 0);
+	local_irq_restore(flags);
+}
+
+/**
+ * alchemy_gpio2_enable -  Activate GPIO2 block.
+ *
+ * The GPIO2 block must be enabled excplicitly to work.  On systems
+ * where this isn't done by the bootloader, this macro can be used.
+ */
+static inline void alchemy_gpio2_enable(void)
+{
+	au_writel(3, GPIO2_ENABLE);	/* reset, clock enabled */
+	au_sync();
+	au_writel(1, GPIO2_ENABLE);	/* clock enabled */
+	au_sync();
+}
+
+/**
+ * alchemy_gpio2_disable - disable GPIO2 block.
+ *
+ * Disable and put GPIO2 block in low-power mode.
+ */
+static inline void alchemy_gpio2_disable(void)
+{
+	au_writel(2, GPIO2_ENABLE);	/* reset, clock disabled */
+	au_sync();
+}
+
+/**********************************************************************/
+
+/* wrappers for on-chip gpios; can be used before gpio chips have been
+ * registered with gpiolib.
+ */
+static inline int alchemy_gpio_direction_input(int gpio)
+{
+	return (gpio >= ALCHEMY_GPIO2_BASE) ?
+		alchemy_gpio2_direction_input(gpio) :
+		alchemy_gpio1_direction_input(gpio);
+}
+
+static inline int alchemy_gpio_direction_output(int gpio, int v)
+{
+	return (gpio >= ALCHEMY_GPIO2_BASE) ?
+		alchemy_gpio2_direction_output(gpio, v) :
+		alchemy_gpio1_direction_output(gpio, v);
+}
+
+static inline int alchemy_gpio_get_value(int gpio)
+{
+	return (gpio >= ALCHEMY_GPIO2_BASE) ?
+		alchemy_gpio2_get_value(gpio) :
+		alchemy_gpio1_get_value(gpio);
+}
+
+static inline void alchemy_gpio_set_value(int gpio, int v)
+{
+	if (gpio >= ALCHEMY_GPIO2_BASE)
+		alchemy_gpio2_set_value(gpio, v);
+	else
+		alchemy_gpio1_set_value(gpio, v);
+}
+
+static inline int alchemy_gpio_is_valid(int gpio)
+{
+	return (gpio >= ALCHEMY_GPIO2_BASE) ?
+		alchemy_gpio2_is_valid(gpio) :
+		alchemy_gpio1_is_valid(gpio);
+}
+
+static inline int alchemy_gpio_cansleep(int gpio)
+{
+	return 0;	/* Alchemy never gets tired */
+}
+
+static inline int alchemy_gpio_to_irq(int gpio)
+{
+	return (gpio >= ALCHEMY_GPIO2_BASE) ?
+		alchemy_gpio2_to_irq(gpio) :
+		alchemy_gpio1_to_irq(gpio);
+}
+
+static inline int alchemy_irq_to_gpio(int irq)
+{
+#if defined(CONFIG_SOC_AU1000)
+	return au1000_irq_to_gpio(irq);
+#elif defined(CONFIG_SOC_AU1100)
+	return au1100_irq_to_gpio(irq);
+#elif defined(CONFIG_SOC_AU1500)
+	return au1500_irq_to_gpio(irq);
+#elif defined(CONFIG_SOC_AU1550)
+	return au1550_irq_to_gpio(irq);
+#elif defined(CONFIG_SOC_AU1200)
+	return au1200_irq_to_gpio(irq);
+#else
+	return -ENXIO;
+#endif
+}
+
+/**********************************************************************/
+
+/* Linux gpio framework integration.
+ *
+ * 4 use cases of Au1000-Au1200 GPIOS:
+ *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
+ *	Board must register gpiochips.
+ *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
+ *	2 (1 for Au1000) gpio_chips are registered.
+ *
+ *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
+ *	the boards' gpio.h must provide	the linux gpio wrapper functions,
+ *
+ *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
+ *	inlinable gpio functions are provided which enable access to the
+ *	Au1000 gpios only by using the numbers straight out of the data-
+ *	sheets.
+
+ * Cases 1 and 3 are intended for boards which want to provide their own
+ * GPIO namespace and -operations (i.e. for example you have 8 GPIOs
+ * which are in part provided by spare Au1000 GPIO pins and in part by
+ * an external FPGA but you still want them to be accssible in linux
+ * as gpio0-7. The board can of course use the alchemy_gpioX_* functions
+ * as required).
+ */
+
+#ifndef CONFIG_GPIOLIB
+
+
+#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT	/* case (4) */
+
+static inline int gpio_direction_input(int gpio)
+{
+	return alchemy_gpio_direction_input(gpio);
+}
+
+static inline int gpio_direction_output(int gpio, int v)
+{
+	return alchemy_gpio_direction_output(gpio, v);
+}
+
+static inline int gpio_get_value(int gpio)
+{
+	return alchemy_gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(int gpio, int v)
+{
+	alchemy_gpio_set_value(gpio, v);
+}
+
+static inline int gpio_is_valid(int gpio)
+{
+	return alchemy_gpio_is_valid(gpio);
+}
+
+static inline int gpio_cansleep(int gpio)
+{
+	return alchemy_gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(int gpio)
+{
+	return alchemy_gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(int irq)
+{
+	return alchemy_irq_to_gpio(irq);
+}
+
+#endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */
+
+
+#else	/* CONFIG GPIOLIB */
+
+
+ /* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */
+#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT	/* case (2) */
+
+/* get everything through gpiolib */
+#define gpio_to_irq	__gpio_to_irq
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define irq_to_gpio	alchemy_irq_to_gpio
+
+#include <asm-generic/gpio.h>
+
+#endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */
+
+
+#endif	/* !CONFIG_GPIOLIB */
+
+#endif /* _ALCHEMY_GPIO_AU1000_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h
index 34d9b72..f9b7d41 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio.h
@@ -1,33 +1,10 @@
-#ifndef _AU1XXX_GPIO_H_
-#define _AU1XXX_GPIO_H_
+#ifndef _ALCHEMY_GPIO_H_
+#define _ALCHEMY_GPIO_H_
 
-#include <linux/types.h>
+#if defined(CONFIG_ALCHEMY_GPIO_AU1000)
 
-#define AU1XXX_GPIO_BASE	200
+#include <asm/mach-au1x00/gpio-au1000.h>
 
-/* GPIO bank 1 offsets */
-#define AU1000_GPIO1_TRI_OUT	0x0100
-#define AU1000_GPIO1_OUT	0x0108
-#define AU1000_GPIO1_ST		0x0110
-#define AU1000_GPIO1_CLR	0x010C
+#endif
 
-/* GPIO bank 2 offsets */
-#define AU1000_GPIO2_DIR	0x00
-#define AU1000_GPIO2_RSVD	0x04
-#define AU1000_GPIO2_OUT	0x08
-#define AU1000_GPIO2_ST		0x0C
-#define AU1000_GPIO2_INT	0x10
-#define AU1000_GPIO2_EN		0x14
-
-#define GPIO2_OUT_EN_MASK	0x00010000
-
-#define gpio_to_irq(gpio)	NULL
-
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-
-#define gpio_cansleep __gpio_cansleep
-
-#include <asm-generic/gpio.h>
-
-#endif /* _AU1XXX_GPIO_H_ */
+#endif	/* _ALCHEMY_GPIO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 1784fde..9850414 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -37,6 +37,9 @@
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
+	/* first set the gpio out value */
+	ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+	/* then set the gpio mode */
 	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
 	return 0;
 }
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index 04ce6e6..3d830756 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -47,11 +47,13 @@
 #define cpu_has_mips32r2	0
 #define cpu_has_mips64r1	0
 #define cpu_has_mips64r2	1
+#define cpu_has_mips_r2_exec_hazard 0
 #define cpu_has_dsp		0
 #define cpu_has_mipsmt		0
 #define cpu_has_userlocal	0
 #define cpu_has_vint		0
 #define cpu_has_veic		0
+#define cpu_hwrena_impl_bits	0xc0000000
 #define ARCH_HAS_READ_CURRENT_TIMER 1
 #define ARCH_HAS_IRQ_PER_CPU	1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
index f30fce9..17d5794 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -30,12 +30,14 @@
 	return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
 }
 
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	return dma_addr;
 }
 
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 	octeon_unmap_dma_mem(dev, dma_addr);
 }
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
index 36c611b..8da9807 100644
--- a/arch/mips/include/asm/mach-generic/dma-coherence.h
+++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
@@ -23,12 +23,14 @@
 	return page_to_phys(page);
 }
 
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	return dma_addr;
 }
 
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 }
 
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
index 4c21bfc..d3d0401 100644
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -33,12 +33,14 @@
 	return pa;
 }
 
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	return dma_addr & ~(0xffUL << 56);
 }
 
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 }
 
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
index 7ae40f4..3785595 100644
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -50,7 +50,8 @@
 }
 
 /* This is almost certainly wrong but it's what dma-ip32.c used to use  */
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	unsigned long addr = dma_addr & RAM_OFFSET_MASK;
 
@@ -60,7 +61,8 @@
 	return addr;
 }
 
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 }
 
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
index 1c7cd27..f93aee5 100644
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -22,12 +22,14 @@
 	return vdma_alloc(page_to_phys(page), PAGE_SIZE);
 }
 
-static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	return vdma_log2phys(dma_addr);
 }
 
-static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 	vdma_free(dma_addr);
 }
diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-lemote/dma-coherence.h
index 38fad7d..c8de5e7 100644
--- a/arch/mips/include/asm/mach-lemote/dma-coherence.h
+++ b/arch/mips/include/asm/mach-lemote/dma-coherence.h
@@ -25,12 +25,14 @@
 	return page_to_phys(page) | 0x80000000;
 }
 
-static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
 {
 	return dma_addr & 0x7fffffff;
 }
 
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
 {
 }
 
diff --git a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
index f3bc7ef..c3e4d3a 100644
--- a/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-rc32434/cpu-feature-overrides.h
@@ -53,11 +53,6 @@
 #define cpu_has_smartmips		0
 
 #define cpu_has_vtag_icache		0
-/* #define cpu_has_dc_aliases		? */
-/* #define cpu_has_ic_fills_f_dc	? */
-/* #define cpu_has_pindexed_dcache	? */
-
-/* #define cpu_icache_snoops_remote_store	? */
 
 #define cpu_has_mips32r1		1
 #define cpu_has_mips32r2		0
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 32ef8be..a581d60 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -220,6 +220,22 @@
 #error Bad page size configuration!
 #endif
 
+/*
+ * Default huge tlb size for a given kernel configuration
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PM_HUGE_MASK	PM_1M
+#elif defined(CONFIG_PAGE_SIZE_8KB)
+#define PM_HUGE_MASK	PM_4M
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+#define PM_HUGE_MASK	PM_16M
+#elif defined(CONFIG_PAGE_SIZE_32KB)
+#define PM_HUGE_MASK	PM_64M
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+#define PM_HUGE_MASK	PM_256M
+#elif defined(CONFIG_HUGETLB_PAGE)
+#error Bad page size configuration for hugetlbfs!
+#endif
 
 /*
  * Values used for computation of new tlb entries
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
index 692989a..f3c23a4 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
@@ -157,6 +157,13 @@
 	CVMX_BOARD_TYPE_NIC_XLE_4G = 21,
 	CVMX_BOARD_TYPE_EBT5600 = 22,
 	CVMX_BOARD_TYPE_EBH5201 = 23,
+	CVMX_BOARD_TYPE_EBT5200 = 24,
+	CVMX_BOARD_TYPE_CB5600  = 25,
+	CVMX_BOARD_TYPE_CB5601  = 26,
+	CVMX_BOARD_TYPE_CB5200  = 27,
+	/* Special 'generic' board type, supports many boards */
+	CVMX_BOARD_TYPE_GENERIC = 28,
+	CVMX_BOARD_TYPE_EBH5610 = 29,
 	CVMX_BOARD_TYPE_MAX,
 
 	/*
@@ -228,6 +235,12 @@
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_4G)
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5600)
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5201)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5200)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5600)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5601)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5200)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_GENERIC)
+		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5610)
 		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
 
 			/* Customer boards listed here */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h
index 1cbe4b5..8e708bd 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootmem.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
@@ -183,6 +183,64 @@
  * Returns 0 on failure,
  *         !0 on success
  */
+
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader, and assign it a name in the
+ * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
+ * Named blocks can later be freed.
+ *
+ * @size:      Size in bytes of block to allocate
+ * @alignment: Alignment required - must be power of 2
+ * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named(uint64_t size, uint64_t alignment,
+				      char *name);
+
+
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader, and assign it a name in the
+ * global named block table.  (part of the cvmx_bootmem_descriptor_t structure)
+ * Named blocks can later be freed.
+ *
+ * @size:     Size in bytes of block to allocate
+ * @address:  Physical address to allocate memory at.  If this
+ *            memory is not available, the allocation fails.
+ * @name:     name of block - must be less than CVMX_BOOTMEM_NAME_LEN
+ *            bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+					      char *name);
+
+
+
+/**
+ * Allocate a block of memory from a specific range of the free list
+ * that was passed to the application by the bootloader, and assign it
+ * a name in the global named block table.  (part of the
+ * cvmx_bootmem_descriptor_t structure) Named blocks can later be
+ * freed.  If request cannot be satisfied within the address range
+ * specified, NULL is returned
+ *
+ * @size:      Size in bytes of block to allocate
+ * @min_addr:  minimum address of range
+ * @max_addr:  maximum address of range
+ * @align:     Alignment of memory to be allocated. (must be a power of 2)
+ * @name:      name of block - must be less than CVMX_BOOTMEM_NAME_LEN bytes
+ *
+ * Returns a pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+					    uint64_t max_addr, uint64_t align,
+					    char *name);
+
 extern int cvmx_bootmem_free_named(char *name);
 
 /**
@@ -224,6 +282,33 @@
 			       uint32_t flags);
 
 /**
+ * Allocates a named block of physical memory from the free list, at
+ * (optional) requested address and alignment.
+ *
+ * @param size      size of region to allocate.  All requests are rounded
+ *                  up to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE
+ *                  bytes size
+ * @param min_addr Minimum address that block can occupy.
+ * @param max_addr  Specifies the maximum address_min (inclusive) that
+ *                  the allocation can use.
+ * @param alignment Requested alignment of the block.  If this
+ *                  alignment cannot be met, the allocation fails.
+ *                  This must be a power of 2.  (Note: Alignment of
+ *                  CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
+ *                  internally enforced.  Requested alignments of less
+ *                  than CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
+ *                  CVMX_BOOTMEM_ALIGNMENT_SIZE.)
+ * @param name      name to assign to named block
+ * @param flags     Flags to control options for the allocation.
+ *
+ * @return physical address of block allocated, or -1 on failure
+ */
+int64_t cvmx_bootmem_phy_named_block_alloc(uint64_t size, uint64_t min_addr,
+					   uint64_t max_addr,
+					   uint64_t alignment,
+					   char *name, uint32_t flags);
+
+/**
  * Finds a named memory block by name.
  * Also used for finding an unused entry in the named block table.
  *
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-errata.h b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
new file mode 100644
index 0000000..5fc9918
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-errata.h
@@ -0,0 +1,33 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_HELPER_ERRATA_H__
+#define __CVMX_HELPER_ERRATA_H__
+
+extern void __cvmx_helper_errata_qlm_disable_2nd_order_cdr(int qlm);
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-jtag.h b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
new file mode 100644
index 0000000..29f016d
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-helper-jtag.h
@@ -0,0 +1,43 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ *  Helper utilities for qlm_jtag.
+ *
+ */
+
+#ifndef __CVMX_HELPER_JTAG_H__
+#define __CVMX_HELPER_JTAG_H__
+
+extern void cvmx_helper_qlm_jtag_init(void);
+extern uint32_t cvmx_helper_qlm_jtag_shift(int qlm, int bits, uint32_t data);
+extern void cvmx_helper_qlm_jtag_shift_zeros(int qlm, int bits);
+extern void cvmx_helper_qlm_jtag_update(int qlm);
+
+#endif /* __CVMX_HELPER_JTAG_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
new file mode 100644
index 0000000..4b347bb
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -0,0 +1,2560 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPEI_DEFS_H__
+#define __CVMX_NPEI_DEFS_H__
+
+#define CVMX_NPEI_BAR1_INDEXX(offset) \
+	 (0x0000000000000000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_BIST_STATUS \
+	 (0x0000000000000580ull)
+#define CVMX_NPEI_BIST_STATUS2 \
+	 (0x0000000000000680ull)
+#define CVMX_NPEI_CTL_PORT0 \
+	 (0x0000000000000250ull)
+#define CVMX_NPEI_CTL_PORT1 \
+	 (0x0000000000000260ull)
+#define CVMX_NPEI_CTL_STATUS \
+	 (0x0000000000000570ull)
+#define CVMX_NPEI_CTL_STATUS2 \
+	 (0x0000000000003C00ull)
+#define CVMX_NPEI_DATA_OUT_CNT \
+	 (0x00000000000005F0ull)
+#define CVMX_NPEI_DBG_DATA \
+	 (0x0000000000000510ull)
+#define CVMX_NPEI_DBG_SELECT \
+	 (0x0000000000000500ull)
+#define CVMX_NPEI_DMA0_INT_LEVEL \
+	 (0x00000000000005C0ull)
+#define CVMX_NPEI_DMA1_INT_LEVEL \
+	 (0x00000000000005D0ull)
+#define CVMX_NPEI_DMAX_COUNTS(offset) \
+	 (0x0000000000000450ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_DBELL(offset) \
+	 (0x00000000000003B0ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_IBUFF_SADDR(offset) \
+	 (0x0000000000000400ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMAX_NADDR(offset) \
+	 (0x00000000000004A0ull + (((offset) & 7) * 16))
+#define CVMX_NPEI_DMA_CNTS \
+	 (0x00000000000005E0ull)
+#define CVMX_NPEI_DMA_CONTROL \
+	 (0x00000000000003A0ull)
+#define CVMX_NPEI_INT_A_ENB \
+	 (0x0000000000000560ull)
+#define CVMX_NPEI_INT_A_ENB2 \
+	 (0x0000000000003CE0ull)
+#define CVMX_NPEI_INT_A_SUM \
+	 (0x0000000000000550ull)
+#define CVMX_NPEI_INT_ENB \
+	 (0x0000000000000540ull)
+#define CVMX_NPEI_INT_ENB2 \
+	 (0x0000000000003CD0ull)
+#define CVMX_NPEI_INT_INFO \
+	 (0x0000000000000590ull)
+#define CVMX_NPEI_INT_SUM \
+	 (0x0000000000000530ull)
+#define CVMX_NPEI_INT_SUM2 \
+	 (0x0000000000003CC0ull)
+#define CVMX_NPEI_LAST_WIN_RDATA0 \
+	 (0x0000000000000600ull)
+#define CVMX_NPEI_LAST_WIN_RDATA1 \
+	 (0x0000000000000610ull)
+#define CVMX_NPEI_MEM_ACCESS_CTL \
+	 (0x00000000000004F0ull)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) \
+	 (0x0000000000000340ull + (((offset) & 31) * 16) - 16 * 12)
+#define CVMX_NPEI_MSI_ENB0 \
+	 (0x0000000000003C50ull)
+#define CVMX_NPEI_MSI_ENB1 \
+	 (0x0000000000003C60ull)
+#define CVMX_NPEI_MSI_ENB2 \
+	 (0x0000000000003C70ull)
+#define CVMX_NPEI_MSI_ENB3 \
+	 (0x0000000000003C80ull)
+#define CVMX_NPEI_MSI_RCV0 \
+	 (0x0000000000003C10ull)
+#define CVMX_NPEI_MSI_RCV1 \
+	 (0x0000000000003C20ull)
+#define CVMX_NPEI_MSI_RCV2 \
+	 (0x0000000000003C30ull)
+#define CVMX_NPEI_MSI_RCV3 \
+	 (0x0000000000003C40ull)
+#define CVMX_NPEI_MSI_RD_MAP \
+	 (0x0000000000003CA0ull)
+#define CVMX_NPEI_MSI_W1C_ENB0 \
+	 (0x0000000000003CF0ull)
+#define CVMX_NPEI_MSI_W1C_ENB1 \
+	 (0x0000000000003D00ull)
+#define CVMX_NPEI_MSI_W1C_ENB2 \
+	 (0x0000000000003D10ull)
+#define CVMX_NPEI_MSI_W1C_ENB3 \
+	 (0x0000000000003D20ull)
+#define CVMX_NPEI_MSI_W1S_ENB0 \
+	 (0x0000000000003D30ull)
+#define CVMX_NPEI_MSI_W1S_ENB1 \
+	 (0x0000000000003D40ull)
+#define CVMX_NPEI_MSI_W1S_ENB2 \
+	 (0x0000000000003D50ull)
+#define CVMX_NPEI_MSI_W1S_ENB3 \
+	 (0x0000000000003D60ull)
+#define CVMX_NPEI_MSI_WR_MAP \
+	 (0x0000000000003C90ull)
+#define CVMX_NPEI_PCIE_CREDIT_CNT \
+	 (0x0000000000003D70ull)
+#define CVMX_NPEI_PCIE_MSI_RCV \
+	 (0x0000000000003CB0ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B1 \
+	 (0x0000000000000650ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B2 \
+	 (0x0000000000000660ull)
+#define CVMX_NPEI_PCIE_MSI_RCV_B3 \
+	 (0x0000000000000670ull)
+#define CVMX_NPEI_PKTX_CNTS(offset) \
+	 (0x0000000000002400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_BADDR(offset) \
+	 (0x0000000000002800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
+	 (0x0000000000002C00ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
+	 (0x0000000000003000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_INSTR_HEADER(offset) \
+	 (0x0000000000003400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_IN_BP(offset) \
+	 (0x0000000000003800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_BADDR(offset) \
+	 (0x0000000000001400ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
+	 (0x0000000000001800ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
+	 (0x0000000000001C00ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKT_CNT_INT \
+	 (0x0000000000001110ull)
+#define CVMX_NPEI_PKT_CNT_INT_ENB \
+	 (0x0000000000001130ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ES \
+	 (0x00000000000010B0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_NS \
+	 (0x00000000000010A0ull)
+#define CVMX_NPEI_PKT_DATA_OUT_ROR \
+	 (0x0000000000001090ull)
+#define CVMX_NPEI_PKT_DPADDR \
+	 (0x0000000000001080ull)
+#define CVMX_NPEI_PKT_INPUT_CONTROL \
+	 (0x0000000000001150ull)
+#define CVMX_NPEI_PKT_INSTR_ENB \
+	 (0x0000000000001000ull)
+#define CVMX_NPEI_PKT_INSTR_RD_SIZE \
+	 (0x0000000000001190ull)
+#define CVMX_NPEI_PKT_INSTR_SIZE \
+	 (0x0000000000001020ull)
+#define CVMX_NPEI_PKT_INT_LEVELS \
+	 (0x0000000000001100ull)
+#define CVMX_NPEI_PKT_IN_BP \
+	 (0x00000000000006B0ull)
+#define CVMX_NPEI_PKT_IN_DONEX_CNTS(offset) \
+	 (0x0000000000002000ull + (((offset) & 31) * 16))
+#define CVMX_NPEI_PKT_IN_INSTR_COUNTS \
+	 (0x00000000000006A0ull)
+#define CVMX_NPEI_PKT_IN_PCIE_PORT \
+	 (0x00000000000011A0ull)
+#define CVMX_NPEI_PKT_IPTR \
+	 (0x0000000000001070ull)
+#define CVMX_NPEI_PKT_OUTPUT_WMARK \
+	 (0x0000000000001160ull)
+#define CVMX_NPEI_PKT_OUT_BMODE \
+	 (0x00000000000010D0ull)
+#define CVMX_NPEI_PKT_OUT_ENB \
+	 (0x0000000000001010ull)
+#define CVMX_NPEI_PKT_PCIE_PORT \
+	 (0x00000000000010E0ull)
+#define CVMX_NPEI_PKT_PORT_IN_RST \
+	 (0x0000000000000690ull)
+#define CVMX_NPEI_PKT_SLIST_ES \
+	 (0x0000000000001050ull)
+#define CVMX_NPEI_PKT_SLIST_ID_SIZE \
+	 (0x0000000000001180ull)
+#define CVMX_NPEI_PKT_SLIST_NS \
+	 (0x0000000000001040ull)
+#define CVMX_NPEI_PKT_SLIST_ROR \
+	 (0x0000000000001030ull)
+#define CVMX_NPEI_PKT_TIME_INT \
+	 (0x0000000000001120ull)
+#define CVMX_NPEI_PKT_TIME_INT_ENB \
+	 (0x0000000000001140ull)
+#define CVMX_NPEI_RSL_INT_BLOCKS \
+	 (0x0000000000000520ull)
+#define CVMX_NPEI_SCRATCH_1 \
+	 (0x0000000000000270ull)
+#define CVMX_NPEI_STATE1 \
+	 (0x0000000000000620ull)
+#define CVMX_NPEI_STATE2 \
+	 (0x0000000000000630ull)
+#define CVMX_NPEI_STATE3 \
+	 (0x0000000000000640ull)
+#define CVMX_NPEI_WINDOW_CTL \
+	 (0x0000000000000380ull)
+#define CVMX_NPEI_WIN_RD_ADDR \
+	 (0x0000000000000210ull)
+#define CVMX_NPEI_WIN_RD_DATA \
+	 (0x0000000000000240ull)
+#define CVMX_NPEI_WIN_WR_ADDR \
+	 (0x0000000000000200ull)
+#define CVMX_NPEI_WIN_WR_DATA \
+	 (0x0000000000000220ull)
+#define CVMX_NPEI_WIN_WR_MASK \
+	 (0x0000000000000230ull)
+
+union cvmx_npei_bar1_indexx {
+	uint32_t u32;
+	struct cvmx_npei_bar1_indexx_s {
+		uint32_t reserved_18_31:14;
+		uint32_t addr_idx:14;
+		uint32_t ca:1;
+		uint32_t end_swp:2;
+		uint32_t addr_v:1;
+	} s;
+	struct cvmx_npei_bar1_indexx_s cn52xx;
+	struct cvmx_npei_bar1_indexx_s cn52xxp1;
+	struct cvmx_npei_bar1_indexx_s cn56xx;
+	struct cvmx_npei_bar1_indexx_s cn56xxp1;
+};
+
+union cvmx_npei_bist_status {
+	uint64_t u64;
+	struct cvmx_npei_bist_status_s {
+		uint64_t pkt_rdf:1;
+		uint64_t pkt_pmem:1;
+		uint64_t pkt_p1:1;
+		uint64_t reserved_60_60:1;
+		uint64_t pcr_gim:1;
+		uint64_t pkt_pif:1;
+		uint64_t pcsr_int:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_sl:1;
+		uint64_t reserved_50_52:3;
+		uint64_t pkt_ind:1;
+		uint64_t pkt_slm:1;
+		uint64_t reserved_36_47:12;
+		uint64_t d0_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t reserved_31_31:1;
+		uint64_t n2p0_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p1_o:1;
+		uint64_t cpl_p0:1;
+		uint64_t cpl_p1:1;
+		uint64_t p2n1_po:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t csm0:1;
+		uint64_t csm1:1;
+		uint64_t dif0:1;
+		uint64_t dif1:1;
+		uint64_t dif2:1;
+		uint64_t dif3:1;
+		uint64_t reserved_2_2:1;
+		uint64_t msi:1;
+		uint64_t ncb_cmd:1;
+	} s;
+	struct cvmx_npei_bist_status_cn52xx {
+		uint64_t pkt_rdf:1;
+		uint64_t pkt_pmem:1;
+		uint64_t pkt_p1:1;
+		uint64_t reserved_60_60:1;
+		uint64_t pcr_gim:1;
+		uint64_t pkt_pif:1;
+		uint64_t pcsr_int:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_sl:1;
+		uint64_t pkt_imem:1;
+		uint64_t pkt_pfm:1;
+		uint64_t pkt_pof:1;
+		uint64_t reserved_48_49:2;
+		uint64_t pkt_pop0:1;
+		uint64_t pkt_pop1:1;
+		uint64_t d0_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d4_mem:1;
+		uint64_t ds_mem:1;
+		uint64_t reserved_36_39:4;
+		uint64_t d0_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t d4_pst:1;
+		uint64_t n2p0_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p1_o:1;
+		uint64_t cpl_p0:1;
+		uint64_t cpl_p1:1;
+		uint64_t p2n1_po:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t csm0:1;
+		uint64_t csm1:1;
+		uint64_t dif0:1;
+		uint64_t dif1:1;
+		uint64_t dif2:1;
+		uint64_t dif3:1;
+		uint64_t dif4:1;
+		uint64_t msi:1;
+		uint64_t ncb_cmd:1;
+	} cn52xx;
+	struct cvmx_npei_bist_status_cn52xxp1 {
+		uint64_t reserved_46_63:18;
+		uint64_t d0_mem0:1;
+		uint64_t d1_mem1:1;
+		uint64_t d2_mem2:1;
+		uint64_t d3_mem3:1;
+		uint64_t dr0_mem:1;
+		uint64_t d0_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t dr1_mem:1;
+		uint64_t d0_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t dr2_mem:1;
+		uint64_t n2p0_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p1_o:1;
+		uint64_t cpl_p0:1;
+		uint64_t cpl_p1:1;
+		uint64_t p2n1_po:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t csm0:1;
+		uint64_t csm1:1;
+		uint64_t dif0:1;
+		uint64_t dif1:1;
+		uint64_t dif2:1;
+		uint64_t dif3:1;
+		uint64_t dr3_mem:1;
+		uint64_t msi:1;
+		uint64_t ncb_cmd:1;
+	} cn52xxp1;
+	struct cvmx_npei_bist_status_cn56xx {
+		uint64_t pkt_rdf:1;
+		uint64_t reserved_60_62:3;
+		uint64_t pcr_gim:1;
+		uint64_t pkt_pif:1;
+		uint64_t pcsr_int:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_sl:1;
+		uint64_t pkt_imem:1;
+		uint64_t pkt_pfm:1;
+		uint64_t pkt_pof:1;
+		uint64_t reserved_48_49:2;
+		uint64_t pkt_pop0:1;
+		uint64_t pkt_pop1:1;
+		uint64_t d0_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d4_mem:1;
+		uint64_t ds_mem:1;
+		uint64_t reserved_36_39:4;
+		uint64_t d0_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t d4_pst:1;
+		uint64_t n2p0_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p1_o:1;
+		uint64_t cpl_p0:1;
+		uint64_t cpl_p1:1;
+		uint64_t p2n1_po:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t csm0:1;
+		uint64_t csm1:1;
+		uint64_t dif0:1;
+		uint64_t dif1:1;
+		uint64_t dif2:1;
+		uint64_t dif3:1;
+		uint64_t dif4:1;
+		uint64_t msi:1;
+		uint64_t ncb_cmd:1;
+	} cn56xx;
+	struct cvmx_npei_bist_status_cn56xxp1 {
+		uint64_t reserved_58_63:6;
+		uint64_t pcsr_int:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_sl:1;
+		uint64_t pkt_pout:1;
+		uint64_t pkt_imem:1;
+		uint64_t pkt_cntm:1;
+		uint64_t pkt_ind:1;
+		uint64_t pkt_slm:1;
+		uint64_t pkt_odf:1;
+		uint64_t pkt_oif:1;
+		uint64_t pkt_out:1;
+		uint64_t pkt_i0:1;
+		uint64_t pkt_i1:1;
+		uint64_t pkt_s0:1;
+		uint64_t pkt_s1:1;
+		uint64_t d0_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d4_mem:1;
+		uint64_t d0_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t d4_pst:1;
+		uint64_t n2p0_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p1_o:1;
+		uint64_t cpl_p0:1;
+		uint64_t cpl_p1:1;
+		uint64_t p2n1_po:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t csm0:1;
+		uint64_t csm1:1;
+		uint64_t dif0:1;
+		uint64_t dif1:1;
+		uint64_t dif2:1;
+		uint64_t dif3:1;
+		uint64_t dif4:1;
+		uint64_t msi:1;
+		uint64_t ncb_cmd:1;
+	} cn56xxp1;
+};
+
+union cvmx_npei_bist_status2 {
+	uint64_t u64;
+	struct cvmx_npei_bist_status2_s {
+		uint64_t reserved_5_63:59;
+		uint64_t psc_p0:1;
+		uint64_t psc_p1:1;
+		uint64_t pkt_gd:1;
+		uint64_t pkt_gl:1;
+		uint64_t pkt_blk:1;
+	} s;
+	struct cvmx_npei_bist_status2_s cn52xx;
+	struct cvmx_npei_bist_status2_s cn56xx;
+};
+
+union cvmx_npei_ctl_port0 {
+	uint64_t u64;
+	struct cvmx_npei_ctl_port0_s {
+		uint64_t reserved_21_63:43;
+		uint64_t waitl_com:1;
+		uint64_t intd:1;
+		uint64_t intc:1;
+		uint64_t intb:1;
+		uint64_t inta:1;
+		uint64_t intd_map:2;
+		uint64_t intc_map:2;
+		uint64_t intb_map:2;
+		uint64_t inta_map:2;
+		uint64_t ctlp_ro:1;
+		uint64_t reserved_6_6:1;
+		uint64_t ptlp_ro:1;
+		uint64_t bar2_enb:1;
+		uint64_t bar2_esx:2;
+		uint64_t bar2_cax:1;
+		uint64_t wait_com:1;
+	} s;
+	struct cvmx_npei_ctl_port0_s cn52xx;
+	struct cvmx_npei_ctl_port0_s cn52xxp1;
+	struct cvmx_npei_ctl_port0_s cn56xx;
+	struct cvmx_npei_ctl_port0_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_port1 {
+	uint64_t u64;
+	struct cvmx_npei_ctl_port1_s {
+		uint64_t reserved_21_63:43;
+		uint64_t waitl_com:1;
+		uint64_t intd:1;
+		uint64_t intc:1;
+		uint64_t intb:1;
+		uint64_t inta:1;
+		uint64_t intd_map:2;
+		uint64_t intc_map:2;
+		uint64_t intb_map:2;
+		uint64_t inta_map:2;
+		uint64_t ctlp_ro:1;
+		uint64_t reserved_6_6:1;
+		uint64_t ptlp_ro:1;
+		uint64_t bar2_enb:1;
+		uint64_t bar2_esx:2;
+		uint64_t bar2_cax:1;
+		uint64_t wait_com:1;
+	} s;
+	struct cvmx_npei_ctl_port1_s cn52xx;
+	struct cvmx_npei_ctl_port1_s cn52xxp1;
+	struct cvmx_npei_ctl_port1_s cn56xx;
+	struct cvmx_npei_ctl_port1_s cn56xxp1;
+};
+
+union cvmx_npei_ctl_status {
+	uint64_t u64;
+	struct cvmx_npei_ctl_status_s {
+		uint64_t reserved_44_63:20;
+		uint64_t p1_ntags:6;
+		uint64_t p0_ntags:6;
+		uint64_t cfg_rtry:16;
+		uint64_t ring_en:1;
+		uint64_t lnk_rst:1;
+		uint64_t arb:1;
+		uint64_t pkt_bp:4;
+		uint64_t host_mode:1;
+		uint64_t chip_rev:8;
+	} s;
+	struct cvmx_npei_ctl_status_s cn52xx;
+	struct cvmx_npei_ctl_status_cn52xxp1 {
+		uint64_t reserved_44_63:20;
+		uint64_t p1_ntags:6;
+		uint64_t p0_ntags:6;
+		uint64_t cfg_rtry:16;
+		uint64_t reserved_15_15:1;
+		uint64_t lnk_rst:1;
+		uint64_t arb:1;
+		uint64_t reserved_9_12:4;
+		uint64_t host_mode:1;
+		uint64_t chip_rev:8;
+	} cn52xxp1;
+	struct cvmx_npei_ctl_status_s cn56xx;
+	struct cvmx_npei_ctl_status_cn56xxp1 {
+		uint64_t reserved_16_63:48;
+		uint64_t ring_en:1;
+		uint64_t lnk_rst:1;
+		uint64_t arb:1;
+		uint64_t pkt_bp:4;
+		uint64_t host_mode:1;
+		uint64_t chip_rev:8;
+	} cn56xxp1;
+};
+
+union cvmx_npei_ctl_status2 {
+	uint64_t u64;
+	struct cvmx_npei_ctl_status2_s {
+		uint64_t reserved_16_63:48;
+		uint64_t mps:1;
+		uint64_t mrrs:3;
+		uint64_t c1_w_flt:1;
+		uint64_t c0_w_flt:1;
+		uint64_t c1_b1_s:3;
+		uint64_t c0_b1_s:3;
+		uint64_t c1_wi_d:1;
+		uint64_t c1_b0_d:1;
+		uint64_t c0_wi_d:1;
+		uint64_t c0_b0_d:1;
+	} s;
+	struct cvmx_npei_ctl_status2_s cn52xx;
+	struct cvmx_npei_ctl_status2_s cn52xxp1;
+	struct cvmx_npei_ctl_status2_s cn56xx;
+	struct cvmx_npei_ctl_status2_s cn56xxp1;
+};
+
+union cvmx_npei_data_out_cnt {
+	uint64_t u64;
+	struct cvmx_npei_data_out_cnt_s {
+		uint64_t reserved_44_63:20;
+		uint64_t p1_ucnt:16;
+		uint64_t p1_fcnt:6;
+		uint64_t p0_ucnt:16;
+		uint64_t p0_fcnt:6;
+	} s;
+	struct cvmx_npei_data_out_cnt_s cn52xx;
+	struct cvmx_npei_data_out_cnt_s cn52xxp1;
+	struct cvmx_npei_data_out_cnt_s cn56xx;
+	struct cvmx_npei_data_out_cnt_s cn56xxp1;
+};
+
+union cvmx_npei_dbg_data {
+	uint64_t u64;
+	struct cvmx_npei_dbg_data_s {
+		uint64_t reserved_28_63:36;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t reserved_25_26:2;
+		uint64_t qlm1_spd:2;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} s;
+	struct cvmx_npei_dbg_data_cn52xx {
+		uint64_t reserved_29_63:35;
+		uint64_t qlm0_link_width:1;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t qlm1_mode:2;
+		uint64_t qlm1_spd:2;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} cn52xx;
+	struct cvmx_npei_dbg_data_cn52xx cn52xxp1;
+	struct cvmx_npei_dbg_data_cn56xx {
+		uint64_t reserved_29_63:35;
+		uint64_t qlm2_rev_lanes:1;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t qlm3_spd:2;
+		uint64_t qlm1_spd:2;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} cn56xx;
+	struct cvmx_npei_dbg_data_cn56xx cn56xxp1;
+};
+
+union cvmx_npei_dbg_select {
+	uint64_t u64;
+	struct cvmx_npei_dbg_select_s {
+		uint64_t reserved_16_63:48;
+		uint64_t dbg_sel:16;
+	} s;
+	struct cvmx_npei_dbg_select_s cn52xx;
+	struct cvmx_npei_dbg_select_s cn52xxp1;
+	struct cvmx_npei_dbg_select_s cn56xx;
+	struct cvmx_npei_dbg_select_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_counts {
+	uint64_t u64;
+	struct cvmx_npei_dmax_counts_s {
+		uint64_t reserved_39_63:25;
+		uint64_t fcnt:7;
+		uint64_t dbell:32;
+	} s;
+	struct cvmx_npei_dmax_counts_s cn52xx;
+	struct cvmx_npei_dmax_counts_s cn52xxp1;
+	struct cvmx_npei_dmax_counts_s cn56xx;
+	struct cvmx_npei_dmax_counts_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_dbell {
+	uint32_t u32;
+	struct cvmx_npei_dmax_dbell_s {
+		uint32_t reserved_16_31:16;
+		uint32_t dbell:16;
+	} s;
+	struct cvmx_npei_dmax_dbell_s cn52xx;
+	struct cvmx_npei_dmax_dbell_s cn52xxp1;
+	struct cvmx_npei_dmax_dbell_s cn56xx;
+	struct cvmx_npei_dmax_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_dmax_ibuff_saddr {
+	uint64_t u64;
+	struct cvmx_npei_dmax_ibuff_saddr_s {
+		uint64_t reserved_37_63:27;
+		uint64_t idle:1;
+		uint64_t saddr:29;
+		uint64_t reserved_0_6:7;
+	} s;
+	struct cvmx_npei_dmax_ibuff_saddr_cn52xx {
+		uint64_t reserved_36_63:28;
+		uint64_t saddr:29;
+		uint64_t reserved_0_6:7;
+	} cn52xx;
+	struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn52xxp1;
+	struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
+	struct cvmx_npei_dmax_ibuff_saddr_cn52xx cn56xxp1;
+};
+
+union cvmx_npei_dmax_naddr {
+	uint64_t u64;
+	struct cvmx_npei_dmax_naddr_s {
+		uint64_t reserved_36_63:28;
+		uint64_t addr:36;
+	} s;
+	struct cvmx_npei_dmax_naddr_s cn52xx;
+	struct cvmx_npei_dmax_naddr_s cn52xxp1;
+	struct cvmx_npei_dmax_naddr_s cn56xx;
+	struct cvmx_npei_dmax_naddr_s cn56xxp1;
+};
+
+union cvmx_npei_dma0_int_level {
+	uint64_t u64;
+	struct cvmx_npei_dma0_int_level_s {
+		uint64_t time:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_dma0_int_level_s cn52xx;
+	struct cvmx_npei_dma0_int_level_s cn52xxp1;
+	struct cvmx_npei_dma0_int_level_s cn56xx;
+	struct cvmx_npei_dma0_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma1_int_level {
+	uint64_t u64;
+	struct cvmx_npei_dma1_int_level_s {
+		uint64_t time:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_dma1_int_level_s cn52xx;
+	struct cvmx_npei_dma1_int_level_s cn52xxp1;
+	struct cvmx_npei_dma1_int_level_s cn56xx;
+	struct cvmx_npei_dma1_int_level_s cn56xxp1;
+};
+
+union cvmx_npei_dma_cnts {
+	uint64_t u64;
+	struct cvmx_npei_dma_cnts_s {
+		uint64_t dma1:32;
+		uint64_t dma0:32;
+	} s;
+	struct cvmx_npei_dma_cnts_s cn52xx;
+	struct cvmx_npei_dma_cnts_s cn52xxp1;
+	struct cvmx_npei_dma_cnts_s cn56xx;
+	struct cvmx_npei_dma_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_dma_control {
+	uint64_t u64;
+	struct cvmx_npei_dma_control_s {
+		uint64_t reserved_39_63:25;
+		uint64_t dma4_enb:1;
+		uint64_t dma3_enb:1;
+		uint64_t dma2_enb:1;
+		uint64_t dma1_enb:1;
+		uint64_t dma0_enb:1;
+		uint64_t b0_lend:1;
+		uint64_t dwb_denb:1;
+		uint64_t dwb_ichk:9;
+		uint64_t fpa_que:3;
+		uint64_t o_add1:1;
+		uint64_t o_ro:1;
+		uint64_t o_ns:1;
+		uint64_t o_es:2;
+		uint64_t o_mode:1;
+		uint64_t csize:14;
+	} s;
+	struct cvmx_npei_dma_control_s cn52xx;
+	struct cvmx_npei_dma_control_cn52xxp1 {
+		uint64_t reserved_38_63:26;
+		uint64_t dma3_enb:1;
+		uint64_t dma2_enb:1;
+		uint64_t dma1_enb:1;
+		uint64_t dma0_enb:1;
+		uint64_t b0_lend:1;
+		uint64_t dwb_denb:1;
+		uint64_t dwb_ichk:9;
+		uint64_t fpa_que:3;
+		uint64_t o_add1:1;
+		uint64_t o_ro:1;
+		uint64_t o_ns:1;
+		uint64_t o_es:2;
+		uint64_t o_mode:1;
+		uint64_t csize:14;
+	} cn52xxp1;
+	struct cvmx_npei_dma_control_s cn56xx;
+	struct cvmx_npei_dma_control_s cn56xxp1;
+};
+
+union cvmx_npei_int_a_enb {
+	uint64_t u64;
+	struct cvmx_npei_int_a_enb_s {
+		uint64_t reserved_10_63:54;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} s;
+	struct cvmx_npei_int_a_enb_cn52xx {
+		uint64_t reserved_8_63:56;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} cn52xx;
+	struct cvmx_npei_int_a_enb_cn52xxp1 {
+		uint64_t reserved_2_63:62;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_a_enb_s cn56xx;
+};
+
+union cvmx_npei_int_a_enb2 {
+	uint64_t u64;
+	struct cvmx_npei_int_a_enb2_s {
+		uint64_t reserved_10_63:54;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} s;
+	struct cvmx_npei_int_a_enb2_cn52xx {
+		uint64_t reserved_8_63:56;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t reserved_0_1:2;
+	} cn52xx;
+	struct cvmx_npei_int_a_enb2_cn52xxp1 {
+		uint64_t reserved_2_63:62;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_a_enb2_s cn56xx;
+};
+
+union cvmx_npei_int_a_sum {
+	uint64_t u64;
+	struct cvmx_npei_int_a_sum_s {
+		uint64_t reserved_10_63:54;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} s;
+	struct cvmx_npei_int_a_sum_cn52xx {
+		uint64_t reserved_8_63:56;
+		uint64_t p1_rdlk:1;
+		uint64_t p0_rdlk:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} cn52xx;
+	struct cvmx_npei_int_a_sum_cn52xxp1 {
+		uint64_t reserved_2_63:62;
+		uint64_t dma1_cpl:1;
+		uint64_t dma0_cpl:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_a_sum_s cn56xx;
+};
+
+union cvmx_npei_int_enb {
+	uint64_t u64;
+	struct cvmx_npei_int_enb_s {
+		uint64_t mio_inta:1;
+		uint64_t reserved_62_62:1;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npei_int_enb_s cn52xx;
+	struct cvmx_npei_int_enb_cn52xxp1 {
+		uint64_t mio_inta:1;
+		uint64_t reserved_62_62:1;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_enb_s cn56xx;
+	struct cvmx_npei_int_enb_cn56xxp1 {
+		uint64_t mio_inta:1;
+		uint64_t reserved_61_62:2;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn56xxp1;
+};
+
+union cvmx_npei_int_enb2 {
+	uint64_t u64;
+	struct cvmx_npei_int_enb2_s {
+		uint64_t reserved_62_63:2;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npei_int_enb2_s cn52xx;
+	struct cvmx_npei_int_enb2_cn52xxp1 {
+		uint64_t reserved_62_63:2;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_enb2_s cn56xx;
+	struct cvmx_npei_int_enb2_cn56xxp1 {
+		uint64_t reserved_61_63:3;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn56xxp1;
+};
+
+union cvmx_npei_int_info {
+	uint64_t u64;
+	struct cvmx_npei_int_info_s {
+		uint64_t reserved_12_63:52;
+		uint64_t pidbof:6;
+		uint64_t psldbof:6;
+	} s;
+	struct cvmx_npei_int_info_s cn52xx;
+	struct cvmx_npei_int_info_s cn56xx;
+	struct cvmx_npei_int_info_s cn56xxp1;
+};
+
+union cvmx_npei_int_sum {
+	uint64_t u64;
+	struct cvmx_npei_int_sum_s {
+		uint64_t mio_inta:1;
+		uint64_t reserved_62_62:1;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npei_int_sum_s cn52xx;
+	struct cvmx_npei_int_sum_cn52xxp1 {
+		uint64_t mio_inta:1;
+		uint64_t reserved_62_62:1;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t reserved_15_18:4;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn52xxp1;
+	struct cvmx_npei_int_sum_s cn56xx;
+	struct cvmx_npei_int_sum_cn56xxp1 {
+		uint64_t mio_inta:1;
+		uint64_t reserved_61_62:2;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_aeri:1;
+		uint64_t ptime:1;
+		uint64_t pcnt:1;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn56xxp1;
+};
+
+union cvmx_npei_int_sum2 {
+	uint64_t u64;
+	struct cvmx_npei_int_sum2_s {
+		uint64_t mio_inta:1;
+		uint64_t reserved_62_62:1;
+		uint64_t int_a:1;
+		uint64_t c1_ldwn:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c1_hpint:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_wake:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_aeri:1;
+		uint64_t c0_hpint:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_wake:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_aeri:1;
+		uint64_t reserved_15_18:4;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t dma1fi:1;
+		uint64_t dma0fi:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma0dbo:1;
+		uint64_t iob2big:1;
+		uint64_t bar0_to:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npei_int_sum2_s cn52xx;
+	struct cvmx_npei_int_sum2_s cn52xxp1;
+	struct cvmx_npei_int_sum2_s cn56xx;
+};
+
+union cvmx_npei_last_win_rdata0 {
+	uint64_t u64;
+	struct cvmx_npei_last_win_rdata0_s {
+		uint64_t data:64;
+	} s;
+	struct cvmx_npei_last_win_rdata0_s cn52xx;
+	struct cvmx_npei_last_win_rdata0_s cn52xxp1;
+	struct cvmx_npei_last_win_rdata0_s cn56xx;
+	struct cvmx_npei_last_win_rdata0_s cn56xxp1;
+};
+
+union cvmx_npei_last_win_rdata1 {
+	uint64_t u64;
+	struct cvmx_npei_last_win_rdata1_s {
+		uint64_t data:64;
+	} s;
+	struct cvmx_npei_last_win_rdata1_s cn52xx;
+	struct cvmx_npei_last_win_rdata1_s cn52xxp1;
+	struct cvmx_npei_last_win_rdata1_s cn56xx;
+	struct cvmx_npei_last_win_rdata1_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_ctl {
+	uint64_t u64;
+	struct cvmx_npei_mem_access_ctl_s {
+		uint64_t reserved_14_63:50;
+		uint64_t max_word:4;
+		uint64_t timer:10;
+	} s;
+	struct cvmx_npei_mem_access_ctl_s cn52xx;
+	struct cvmx_npei_mem_access_ctl_s cn52xxp1;
+	struct cvmx_npei_mem_access_ctl_s cn56xx;
+	struct cvmx_npei_mem_access_ctl_s cn56xxp1;
+};
+
+union cvmx_npei_mem_access_subidx {
+	uint64_t u64;
+	struct cvmx_npei_mem_access_subidx_s {
+		uint64_t reserved_42_63:22;
+		uint64_t zero:1;
+		uint64_t port:2;
+		uint64_t nmerge:1;
+		uint64_t esr:2;
+		uint64_t esw:2;
+		uint64_t nsr:1;
+		uint64_t nsw:1;
+		uint64_t ror:1;
+		uint64_t row:1;
+		uint64_t ba:30;
+	} s;
+	struct cvmx_npei_mem_access_subidx_s cn52xx;
+	struct cvmx_npei_mem_access_subidx_s cn52xxp1;
+	struct cvmx_npei_mem_access_subidx_s cn56xx;
+	struct cvmx_npei_mem_access_subidx_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb0 {
+	uint64_t u64;
+	struct cvmx_npei_msi_enb0_s {
+		uint64_t enb:64;
+	} s;
+	struct cvmx_npei_msi_enb0_s cn52xx;
+	struct cvmx_npei_msi_enb0_s cn52xxp1;
+	struct cvmx_npei_msi_enb0_s cn56xx;
+	struct cvmx_npei_msi_enb0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb1 {
+	uint64_t u64;
+	struct cvmx_npei_msi_enb1_s {
+		uint64_t enb:64;
+	} s;
+	struct cvmx_npei_msi_enb1_s cn52xx;
+	struct cvmx_npei_msi_enb1_s cn52xxp1;
+	struct cvmx_npei_msi_enb1_s cn56xx;
+	struct cvmx_npei_msi_enb1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb2 {
+	uint64_t u64;
+	struct cvmx_npei_msi_enb2_s {
+		uint64_t enb:64;
+	} s;
+	struct cvmx_npei_msi_enb2_s cn52xx;
+	struct cvmx_npei_msi_enb2_s cn52xxp1;
+	struct cvmx_npei_msi_enb2_s cn56xx;
+	struct cvmx_npei_msi_enb2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_enb3 {
+	uint64_t u64;
+	struct cvmx_npei_msi_enb3_s {
+		uint64_t enb:64;
+	} s;
+	struct cvmx_npei_msi_enb3_s cn52xx;
+	struct cvmx_npei_msi_enb3_s cn52xxp1;
+	struct cvmx_npei_msi_enb3_s cn56xx;
+	struct cvmx_npei_msi_enb3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv0 {
+	uint64_t u64;
+	struct cvmx_npei_msi_rcv0_s {
+		uint64_t intr:64;
+	} s;
+	struct cvmx_npei_msi_rcv0_s cn52xx;
+	struct cvmx_npei_msi_rcv0_s cn52xxp1;
+	struct cvmx_npei_msi_rcv0_s cn56xx;
+	struct cvmx_npei_msi_rcv0_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv1 {
+	uint64_t u64;
+	struct cvmx_npei_msi_rcv1_s {
+		uint64_t intr:64;
+	} s;
+	struct cvmx_npei_msi_rcv1_s cn52xx;
+	struct cvmx_npei_msi_rcv1_s cn52xxp1;
+	struct cvmx_npei_msi_rcv1_s cn56xx;
+	struct cvmx_npei_msi_rcv1_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv2 {
+	uint64_t u64;
+	struct cvmx_npei_msi_rcv2_s {
+		uint64_t intr:64;
+	} s;
+	struct cvmx_npei_msi_rcv2_s cn52xx;
+	struct cvmx_npei_msi_rcv2_s cn52xxp1;
+	struct cvmx_npei_msi_rcv2_s cn56xx;
+	struct cvmx_npei_msi_rcv2_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rcv3 {
+	uint64_t u64;
+	struct cvmx_npei_msi_rcv3_s {
+		uint64_t intr:64;
+	} s;
+	struct cvmx_npei_msi_rcv3_s cn52xx;
+	struct cvmx_npei_msi_rcv3_s cn52xxp1;
+	struct cvmx_npei_msi_rcv3_s cn56xx;
+	struct cvmx_npei_msi_rcv3_s cn56xxp1;
+};
+
+union cvmx_npei_msi_rd_map {
+	uint64_t u64;
+	struct cvmx_npei_msi_rd_map_s {
+		uint64_t reserved_16_63:48;
+		uint64_t rd_int:8;
+		uint64_t msi_int:8;
+	} s;
+	struct cvmx_npei_msi_rd_map_s cn52xx;
+	struct cvmx_npei_msi_rd_map_s cn52xxp1;
+	struct cvmx_npei_msi_rd_map_s cn56xx;
+	struct cvmx_npei_msi_rd_map_s cn56xxp1;
+};
+
+union cvmx_npei_msi_w1c_enb0 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1c_enb0_s {
+		uint64_t clr:64;
+	} s;
+	struct cvmx_npei_msi_w1c_enb0_s cn52xx;
+	struct cvmx_npei_msi_w1c_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb1 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1c_enb1_s {
+		uint64_t clr:64;
+	} s;
+	struct cvmx_npei_msi_w1c_enb1_s cn52xx;
+	struct cvmx_npei_msi_w1c_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb2 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1c_enb2_s {
+		uint64_t clr:64;
+	} s;
+	struct cvmx_npei_msi_w1c_enb2_s cn52xx;
+	struct cvmx_npei_msi_w1c_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1c_enb3 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1c_enb3_s {
+		uint64_t clr:64;
+	} s;
+	struct cvmx_npei_msi_w1c_enb3_s cn52xx;
+	struct cvmx_npei_msi_w1c_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb0 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1s_enb0_s {
+		uint64_t set:64;
+	} s;
+	struct cvmx_npei_msi_w1s_enb0_s cn52xx;
+	struct cvmx_npei_msi_w1s_enb0_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb1 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1s_enb1_s {
+		uint64_t set:64;
+	} s;
+	struct cvmx_npei_msi_w1s_enb1_s cn52xx;
+	struct cvmx_npei_msi_w1s_enb1_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb2 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1s_enb2_s {
+		uint64_t set:64;
+	} s;
+	struct cvmx_npei_msi_w1s_enb2_s cn52xx;
+	struct cvmx_npei_msi_w1s_enb2_s cn56xx;
+};
+
+union cvmx_npei_msi_w1s_enb3 {
+	uint64_t u64;
+	struct cvmx_npei_msi_w1s_enb3_s {
+		uint64_t set:64;
+	} s;
+	struct cvmx_npei_msi_w1s_enb3_s cn52xx;
+	struct cvmx_npei_msi_w1s_enb3_s cn56xx;
+};
+
+union cvmx_npei_msi_wr_map {
+	uint64_t u64;
+	struct cvmx_npei_msi_wr_map_s {
+		uint64_t reserved_16_63:48;
+		uint64_t ciu_int:8;
+		uint64_t msi_int:8;
+	} s;
+	struct cvmx_npei_msi_wr_map_s cn52xx;
+	struct cvmx_npei_msi_wr_map_s cn52xxp1;
+	struct cvmx_npei_msi_wr_map_s cn56xx;
+	struct cvmx_npei_msi_wr_map_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_credit_cnt {
+	uint64_t u64;
+	struct cvmx_npei_pcie_credit_cnt_s {
+		uint64_t reserved_48_63:16;
+		uint64_t p1_ccnt:8;
+		uint64_t p1_ncnt:8;
+		uint64_t p1_pcnt:8;
+		uint64_t p0_ccnt:8;
+		uint64_t p0_ncnt:8;
+		uint64_t p0_pcnt:8;
+	} s;
+	struct cvmx_npei_pcie_credit_cnt_s cn52xx;
+	struct cvmx_npei_pcie_credit_cnt_s cn56xx;
+};
+
+union cvmx_npei_pcie_msi_rcv {
+	uint64_t u64;
+	struct cvmx_npei_pcie_msi_rcv_s {
+		uint64_t reserved_8_63:56;
+		uint64_t intr:8;
+	} s;
+	struct cvmx_npei_pcie_msi_rcv_s cn52xx;
+	struct cvmx_npei_pcie_msi_rcv_s cn52xxp1;
+	struct cvmx_npei_pcie_msi_rcv_s cn56xx;
+	struct cvmx_npei_pcie_msi_rcv_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b1 {
+	uint64_t u64;
+	struct cvmx_npei_pcie_msi_rcv_b1_s {
+		uint64_t reserved_16_63:48;
+		uint64_t intr:8;
+		uint64_t reserved_0_7:8;
+	} s;
+	struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx;
+	struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1;
+	struct cvmx_npei_pcie_msi_rcv_b1_s cn56xx;
+	struct cvmx_npei_pcie_msi_rcv_b1_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b2 {
+	uint64_t u64;
+	struct cvmx_npei_pcie_msi_rcv_b2_s {
+		uint64_t reserved_24_63:40;
+		uint64_t intr:8;
+		uint64_t reserved_0_15:16;
+	} s;
+	struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx;
+	struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1;
+	struct cvmx_npei_pcie_msi_rcv_b2_s cn56xx;
+	struct cvmx_npei_pcie_msi_rcv_b2_s cn56xxp1;
+};
+
+union cvmx_npei_pcie_msi_rcv_b3 {
+	uint64_t u64;
+	struct cvmx_npei_pcie_msi_rcv_b3_s {
+		uint64_t reserved_32_63:32;
+		uint64_t intr:8;
+		uint64_t reserved_0_23:24;
+	} s;
+	struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx;
+	struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1;
+	struct cvmx_npei_pcie_msi_rcv_b3_s cn56xx;
+	struct cvmx_npei_pcie_msi_rcv_b3_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_cnts {
+	uint64_t u64;
+	struct cvmx_npei_pktx_cnts_s {
+		uint64_t reserved_54_63:10;
+		uint64_t timer:22;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_pktx_cnts_s cn52xx;
+	struct cvmx_npei_pktx_cnts_s cn56xx;
+	struct cvmx_npei_pktx_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_in_bp {
+	uint64_t u64;
+	struct cvmx_npei_pktx_in_bp_s {
+		uint64_t wmark:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_pktx_in_bp_s cn52xx;
+	struct cvmx_npei_pktx_in_bp_s cn56xx;
+	struct cvmx_npei_pktx_in_bp_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_baddr {
+	uint64_t u64;
+	struct cvmx_npei_pktx_instr_baddr_s {
+		uint64_t addr:61;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_npei_pktx_instr_baddr_s cn52xx;
+	struct cvmx_npei_pktx_instr_baddr_s cn56xx;
+	struct cvmx_npei_pktx_instr_baddr_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_baoff_dbell {
+	uint64_t u64;
+	struct cvmx_npei_pktx_instr_baoff_dbell_s {
+		uint64_t aoff:32;
+		uint64_t dbell:32;
+	} s;
+	struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
+	struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
+	struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_fifo_rsize {
+	uint64_t u64;
+	struct cvmx_npei_pktx_instr_fifo_rsize_s {
+		uint64_t max:9;
+		uint64_t rrp:9;
+		uint64_t wrp:9;
+		uint64_t fcnt:5;
+		uint64_t rsize:32;
+	} s;
+	struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
+	struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
+	struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_instr_header {
+	uint64_t u64;
+	struct cvmx_npei_pktx_instr_header_s {
+		uint64_t reserved_44_63:20;
+		uint64_t pbp:1;
+		uint64_t rsv_f:5;
+		uint64_t rparmode:2;
+		uint64_t rsv_e:1;
+		uint64_t rskp_len:7;
+		uint64_t rsv_d:6;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_c:5;
+		uint64_t par_mode:2;
+		uint64_t rsv_b:1;
+		uint64_t skp_len:7;
+		uint64_t rsv_a:6;
+	} s;
+	struct cvmx_npei_pktx_instr_header_s cn52xx;
+	struct cvmx_npei_pktx_instr_header_s cn56xx;
+	struct cvmx_npei_pktx_instr_header_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_baddr {
+	uint64_t u64;
+	struct cvmx_npei_pktx_slist_baddr_s {
+		uint64_t addr:60;
+		uint64_t reserved_0_3:4;
+	} s;
+	struct cvmx_npei_pktx_slist_baddr_s cn52xx;
+	struct cvmx_npei_pktx_slist_baddr_s cn56xx;
+	struct cvmx_npei_pktx_slist_baddr_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_baoff_dbell {
+	uint64_t u64;
+	struct cvmx_npei_pktx_slist_baoff_dbell_s {
+		uint64_t aoff:32;
+		uint64_t dbell:32;
+	} s;
+	struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
+	struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
+	struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xxp1;
+};
+
+union cvmx_npei_pktx_slist_fifo_rsize {
+	uint64_t u64;
+	struct cvmx_npei_pktx_slist_fifo_rsize_s {
+		uint64_t reserved_32_63:32;
+		uint64_t rsize:32;
+	} s;
+	struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
+	struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
+	struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_cnt_int {
+	uint64_t u64;
+	struct cvmx_npei_pkt_cnt_int_s {
+		uint64_t reserved_32_63:32;
+		uint64_t port:32;
+	} s;
+	struct cvmx_npei_pkt_cnt_int_s cn52xx;
+	struct cvmx_npei_pkt_cnt_int_s cn56xx;
+	struct cvmx_npei_pkt_cnt_int_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_cnt_int_enb {
+	uint64_t u64;
+	struct cvmx_npei_pkt_cnt_int_enb_s {
+		uint64_t reserved_32_63:32;
+		uint64_t port:32;
+	} s;
+	struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
+	struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
+	struct cvmx_npei_pkt_cnt_int_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_es {
+	uint64_t u64;
+	struct cvmx_npei_pkt_data_out_es_s {
+		uint64_t es:64;
+	} s;
+	struct cvmx_npei_pkt_data_out_es_s cn52xx;
+	struct cvmx_npei_pkt_data_out_es_s cn56xx;
+	struct cvmx_npei_pkt_data_out_es_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_ns {
+	uint64_t u64;
+	struct cvmx_npei_pkt_data_out_ns_s {
+		uint64_t reserved_32_63:32;
+		uint64_t nsr:32;
+	} s;
+	struct cvmx_npei_pkt_data_out_ns_s cn52xx;
+	struct cvmx_npei_pkt_data_out_ns_s cn56xx;
+	struct cvmx_npei_pkt_data_out_ns_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_data_out_ror {
+	uint64_t u64;
+	struct cvmx_npei_pkt_data_out_ror_s {
+		uint64_t reserved_32_63:32;
+		uint64_t ror:32;
+	} s;
+	struct cvmx_npei_pkt_data_out_ror_s cn52xx;
+	struct cvmx_npei_pkt_data_out_ror_s cn56xx;
+	struct cvmx_npei_pkt_data_out_ror_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_dpaddr {
+	uint64_t u64;
+	struct cvmx_npei_pkt_dpaddr_s {
+		uint64_t reserved_32_63:32;
+		uint64_t dptr:32;
+	} s;
+	struct cvmx_npei_pkt_dpaddr_s cn52xx;
+	struct cvmx_npei_pkt_dpaddr_s cn56xx;
+	struct cvmx_npei_pkt_dpaddr_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_in_bp {
+	uint64_t u64;
+	struct cvmx_npei_pkt_in_bp_s {
+		uint64_t reserved_32_63:32;
+		uint64_t bp:32;
+	} s;
+	struct cvmx_npei_pkt_in_bp_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_donex_cnts {
+	uint64_t u64;
+	struct cvmx_npei_pkt_in_donex_cnts_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
+	struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
+	struct cvmx_npei_pkt_in_donex_cnts_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_in_instr_counts {
+	uint64_t u64;
+	struct cvmx_npei_pkt_in_instr_counts_s {
+		uint64_t wr_cnt:32;
+		uint64_t rd_cnt:32;
+	} s;
+	struct cvmx_npei_pkt_in_instr_counts_s cn52xx;
+	struct cvmx_npei_pkt_in_instr_counts_s cn56xx;
+};
+
+union cvmx_npei_pkt_in_pcie_port {
+	uint64_t u64;
+	struct cvmx_npei_pkt_in_pcie_port_s {
+		uint64_t pp:64;
+	} s;
+	struct cvmx_npei_pkt_in_pcie_port_s cn52xx;
+	struct cvmx_npei_pkt_in_pcie_port_s cn56xx;
+};
+
+union cvmx_npei_pkt_input_control {
+	uint64_t u64;
+	struct cvmx_npei_pkt_input_control_s {
+		uint64_t reserved_23_63:41;
+		uint64_t pkt_rr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t d_nsr:1;
+		uint64_t d_esr:2;
+		uint64_t d_ror:1;
+		uint64_t use_csr:1;
+		uint64_t nsr:1;
+		uint64_t esr:2;
+		uint64_t ror:1;
+	} s;
+	struct cvmx_npei_pkt_input_control_s cn52xx;
+	struct cvmx_npei_pkt_input_control_s cn56xx;
+	struct cvmx_npei_pkt_input_control_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_instr_enb {
+	uint64_t u64;
+	struct cvmx_npei_pkt_instr_enb_s {
+		uint64_t reserved_32_63:32;
+		uint64_t enb:32;
+	} s;
+	struct cvmx_npei_pkt_instr_enb_s cn52xx;
+	struct cvmx_npei_pkt_instr_enb_s cn56xx;
+	struct cvmx_npei_pkt_instr_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_instr_rd_size {
+	uint64_t u64;
+	struct cvmx_npei_pkt_instr_rd_size_s {
+		uint64_t rdsize:64;
+	} s;
+	struct cvmx_npei_pkt_instr_rd_size_s cn52xx;
+	struct cvmx_npei_pkt_instr_rd_size_s cn56xx;
+};
+
+union cvmx_npei_pkt_instr_size {
+	uint64_t u64;
+	struct cvmx_npei_pkt_instr_size_s {
+		uint64_t reserved_32_63:32;
+		uint64_t is_64b:32;
+	} s;
+	struct cvmx_npei_pkt_instr_size_s cn52xx;
+	struct cvmx_npei_pkt_instr_size_s cn56xx;
+	struct cvmx_npei_pkt_instr_size_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_int_levels {
+	uint64_t u64;
+	struct cvmx_npei_pkt_int_levels_s {
+		uint64_t reserved_54_63:10;
+		uint64_t time:22;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_npei_pkt_int_levels_s cn52xx;
+	struct cvmx_npei_pkt_int_levels_s cn56xx;
+	struct cvmx_npei_pkt_int_levels_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_iptr {
+	uint64_t u64;
+	struct cvmx_npei_pkt_iptr_s {
+		uint64_t reserved_32_63:32;
+		uint64_t iptr:32;
+	} s;
+	struct cvmx_npei_pkt_iptr_s cn52xx;
+	struct cvmx_npei_pkt_iptr_s cn56xx;
+	struct cvmx_npei_pkt_iptr_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_out_bmode {
+	uint64_t u64;
+	struct cvmx_npei_pkt_out_bmode_s {
+		uint64_t reserved_32_63:32;
+		uint64_t bmode:32;
+	} s;
+	struct cvmx_npei_pkt_out_bmode_s cn52xx;
+	struct cvmx_npei_pkt_out_bmode_s cn56xx;
+	struct cvmx_npei_pkt_out_bmode_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_out_enb {
+	uint64_t u64;
+	struct cvmx_npei_pkt_out_enb_s {
+		uint64_t reserved_32_63:32;
+		uint64_t enb:32;
+	} s;
+	struct cvmx_npei_pkt_out_enb_s cn52xx;
+	struct cvmx_npei_pkt_out_enb_s cn56xx;
+	struct cvmx_npei_pkt_out_enb_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_output_wmark {
+	uint64_t u64;
+	struct cvmx_npei_pkt_output_wmark_s {
+		uint64_t reserved_32_63:32;
+		uint64_t wmark:32;
+	} s;
+	struct cvmx_npei_pkt_output_wmark_s cn52xx;
+	struct cvmx_npei_pkt_output_wmark_s cn56xx;
+};
+
+union cvmx_npei_pkt_pcie_port {
+	uint64_t u64;
+	struct cvmx_npei_pkt_pcie_port_s {
+		uint64_t pp:64;
+	} s;
+	struct cvmx_npei_pkt_pcie_port_s cn52xx;
+	struct cvmx_npei_pkt_pcie_port_s cn56xx;
+	struct cvmx_npei_pkt_pcie_port_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_port_in_rst {
+	uint64_t u64;
+	struct cvmx_npei_pkt_port_in_rst_s {
+		uint64_t in_rst:32;
+		uint64_t out_rst:32;
+	} s;
+	struct cvmx_npei_pkt_port_in_rst_s cn52xx;
+	struct cvmx_npei_pkt_port_in_rst_s cn56xx;
+};
+
+union cvmx_npei_pkt_slist_es {
+	uint64_t u64;
+	struct cvmx_npei_pkt_slist_es_s {
+		uint64_t es:64;
+	} s;
+	struct cvmx_npei_pkt_slist_es_s cn52xx;
+	struct cvmx_npei_pkt_slist_es_s cn56xx;
+	struct cvmx_npei_pkt_slist_es_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_id_size {
+	uint64_t u64;
+	struct cvmx_npei_pkt_slist_id_size_s {
+		uint64_t reserved_23_63:41;
+		uint64_t isize:7;
+		uint64_t bsize:16;
+	} s;
+	struct cvmx_npei_pkt_slist_id_size_s cn52xx;
+	struct cvmx_npei_pkt_slist_id_size_s cn56xx;
+	struct cvmx_npei_pkt_slist_id_size_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_ns {
+	uint64_t u64;
+	struct cvmx_npei_pkt_slist_ns_s {
+		uint64_t reserved_32_63:32;
+		uint64_t nsr:32;
+	} s;
+	struct cvmx_npei_pkt_slist_ns_s cn52xx;
+	struct cvmx_npei_pkt_slist_ns_s cn56xx;
+	struct cvmx_npei_pkt_slist_ns_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_slist_ror {
+	uint64_t u64;
+	struct cvmx_npei_pkt_slist_ror_s {
+		uint64_t reserved_32_63:32;
+		uint64_t ror:32;
+	} s;
+	struct cvmx_npei_pkt_slist_ror_s cn52xx;
+	struct cvmx_npei_pkt_slist_ror_s cn56xx;
+	struct cvmx_npei_pkt_slist_ror_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_time_int {
+	uint64_t u64;
+	struct cvmx_npei_pkt_time_int_s {
+		uint64_t reserved_32_63:32;
+		uint64_t port:32;
+	} s;
+	struct cvmx_npei_pkt_time_int_s cn52xx;
+	struct cvmx_npei_pkt_time_int_s cn56xx;
+	struct cvmx_npei_pkt_time_int_s cn56xxp1;
+};
+
+union cvmx_npei_pkt_time_int_enb {
+	uint64_t u64;
+	struct cvmx_npei_pkt_time_int_enb_s {
+		uint64_t reserved_32_63:32;
+		uint64_t port:32;
+	} s;
+	struct cvmx_npei_pkt_time_int_enb_s cn52xx;
+	struct cvmx_npei_pkt_time_int_enb_s cn56xx;
+	struct cvmx_npei_pkt_time_int_enb_s cn56xxp1;
+};
+
+union cvmx_npei_rsl_int_blocks {
+	uint64_t u64;
+	struct cvmx_npei_rsl_int_blocks_s {
+		uint64_t reserved_31_63:33;
+		uint64_t iob:1;
+		uint64_t lmc1:1;
+		uint64_t agl:1;
+		uint64_t reserved_24_27:4;
+		uint64_t asxpcs1:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t usb1:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t reserved_6_6:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npei:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} s;
+	struct cvmx_npei_rsl_int_blocks_s cn52xx;
+	struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
+	struct cvmx_npei_rsl_int_blocks_cn56xx {
+		uint64_t reserved_31_63:33;
+		uint64_t iob:1;
+		uint64_t lmc1:1;
+		uint64_t agl:1;
+		uint64_t reserved_24_27:4;
+		uint64_t asxpcs1:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t reserved_6_6:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npei:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} cn56xx;
+	struct cvmx_npei_rsl_int_blocks_cn56xx cn56xxp1;
+};
+
+union cvmx_npei_scratch_1 {
+	uint64_t u64;
+	struct cvmx_npei_scratch_1_s {
+		uint64_t data:64;
+	} s;
+	struct cvmx_npei_scratch_1_s cn52xx;
+	struct cvmx_npei_scratch_1_s cn52xxp1;
+	struct cvmx_npei_scratch_1_s cn56xx;
+	struct cvmx_npei_scratch_1_s cn56xxp1;
+};
+
+union cvmx_npei_state1 {
+	uint64_t u64;
+	struct cvmx_npei_state1_s {
+		uint64_t cpl1:12;
+		uint64_t cpl0:12;
+		uint64_t arb:1;
+		uint64_t csr:39;
+	} s;
+	struct cvmx_npei_state1_s cn52xx;
+	struct cvmx_npei_state1_s cn52xxp1;
+	struct cvmx_npei_state1_s cn56xx;
+	struct cvmx_npei_state1_s cn56xxp1;
+};
+
+union cvmx_npei_state2 {
+	uint64_t u64;
+	struct cvmx_npei_state2_s {
+		uint64_t reserved_48_63:16;
+		uint64_t npei:1;
+		uint64_t rac:1;
+		uint64_t csm1:15;
+		uint64_t csm0:15;
+		uint64_t nnp0:8;
+		uint64_t nnd:8;
+	} s;
+	struct cvmx_npei_state2_s cn52xx;
+	struct cvmx_npei_state2_s cn52xxp1;
+	struct cvmx_npei_state2_s cn56xx;
+	struct cvmx_npei_state2_s cn56xxp1;
+};
+
+union cvmx_npei_state3 {
+	uint64_t u64;
+	struct cvmx_npei_state3_s {
+		uint64_t reserved_56_63:8;
+		uint64_t psm1:15;
+		uint64_t psm0:15;
+		uint64_t nsm1:13;
+		uint64_t nsm0:13;
+	} s;
+	struct cvmx_npei_state3_s cn52xx;
+	struct cvmx_npei_state3_s cn52xxp1;
+	struct cvmx_npei_state3_s cn56xx;
+	struct cvmx_npei_state3_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_addr {
+	uint64_t u64;
+	struct cvmx_npei_win_rd_addr_s {
+		uint64_t reserved_51_63:13;
+		uint64_t ld_cmd:2;
+		uint64_t iobit:1;
+		uint64_t rd_addr:48;
+	} s;
+	struct cvmx_npei_win_rd_addr_s cn52xx;
+	struct cvmx_npei_win_rd_addr_s cn52xxp1;
+	struct cvmx_npei_win_rd_addr_s cn56xx;
+	struct cvmx_npei_win_rd_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_rd_data {
+	uint64_t u64;
+	struct cvmx_npei_win_rd_data_s {
+		uint64_t rd_data:64;
+	} s;
+	struct cvmx_npei_win_rd_data_s cn52xx;
+	struct cvmx_npei_win_rd_data_s cn52xxp1;
+	struct cvmx_npei_win_rd_data_s cn56xx;
+	struct cvmx_npei_win_rd_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_addr {
+	uint64_t u64;
+	struct cvmx_npei_win_wr_addr_s {
+		uint64_t reserved_49_63:15;
+		uint64_t iobit:1;
+		uint64_t wr_addr:46;
+		uint64_t reserved_0_1:2;
+	} s;
+	struct cvmx_npei_win_wr_addr_s cn52xx;
+	struct cvmx_npei_win_wr_addr_s cn52xxp1;
+	struct cvmx_npei_win_wr_addr_s cn56xx;
+	struct cvmx_npei_win_wr_addr_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_data {
+	uint64_t u64;
+	struct cvmx_npei_win_wr_data_s {
+		uint64_t wr_data:64;
+	} s;
+	struct cvmx_npei_win_wr_data_s cn52xx;
+	struct cvmx_npei_win_wr_data_s cn52xxp1;
+	struct cvmx_npei_win_wr_data_s cn56xx;
+	struct cvmx_npei_win_wr_data_s cn56xxp1;
+};
+
+union cvmx_npei_win_wr_mask {
+	uint64_t u64;
+	struct cvmx_npei_win_wr_mask_s {
+		uint64_t reserved_8_63:56;
+		uint64_t wr_mask:8;
+	} s;
+	struct cvmx_npei_win_wr_mask_s cn52xx;
+	struct cvmx_npei_win_wr_mask_s cn52xxp1;
+	struct cvmx_npei_win_wr_mask_s cn56xx;
+	struct cvmx_npei_win_wr_mask_s cn56xxp1;
+};
+
+union cvmx_npei_window_ctl {
+	uint64_t u64;
+	struct cvmx_npei_window_ctl_s {
+		uint64_t reserved_32_63:32;
+		uint64_t time:32;
+	} s;
+	struct cvmx_npei_window_ctl_s cn52xx;
+	struct cvmx_npei_window_ctl_s cn52xxp1;
+	struct cvmx_npei_window_ctl_s cn56xx;
+	struct cvmx_npei_window_ctl_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
new file mode 100644
index 0000000..4e03cd8
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -0,0 +1,1735 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_NPI_DEFS_H__
+#define __CVMX_NPI_DEFS_H__
+
+#define CVMX_NPI_BASE_ADDR_INPUT0 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000070ull)
+#define CVMX_NPI_BASE_ADDR_INPUT1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000080ull)
+#define CVMX_NPI_BASE_ADDR_INPUT2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000090ull)
+#define CVMX_NPI_BASE_ADDR_INPUT3 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000A0ull)
+#define CVMX_NPI_BASE_ADDR_INPUTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000070ull + (((offset) & 3) * 16))
+#define CVMX_NPI_BASE_ADDR_OUTPUT0 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000B8ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT1 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000C0ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT2 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000C8ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUT3 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000D0ull)
+#define CVMX_NPI_BASE_ADDR_OUTPUTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000000B8ull + (((offset) & 3) * 8))
+#define CVMX_NPI_BIST_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011F00000003F8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT0 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000E0ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT1 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000E8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT2 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000F0ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUT3 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000F8ull)
+#define CVMX_NPI_BUFF_SIZE_OUTPUTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000000E0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_COMP_CTL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000218ull)
+#define CVMX_NPI_CTL_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000010ull)
+#define CVMX_NPI_DBG_SELECT \
+	 CVMX_ADD_IO_SEG(0x00011F0000000008ull)
+#define CVMX_NPI_DMA_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000128ull)
+#define CVMX_NPI_DMA_HIGHP_COUNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000148ull)
+#define CVMX_NPI_DMA_HIGHP_NADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000158ull)
+#define CVMX_NPI_DMA_LOWP_COUNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000140ull)
+#define CVMX_NPI_DMA_LOWP_NADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000150ull)
+#define CVMX_NPI_HIGHP_DBELL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000120ull)
+#define CVMX_NPI_HIGHP_IBUFF_SADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000110ull)
+#define CVMX_NPI_INPUT_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000138ull)
+#define CVMX_NPI_INT_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000000020ull)
+#define CVMX_NPI_INT_SUM \
+	 CVMX_ADD_IO_SEG(0x00011F0000000018ull)
+#define CVMX_NPI_LOWP_DBELL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000118ull)
+#define CVMX_NPI_LOWP_IBUFF_SADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000108ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID3 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000028ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID4 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000030ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID5 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000038ull)
+#define CVMX_NPI_MEM_ACCESS_SUBID6 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000040ull)
+#define CVMX_NPI_MEM_ACCESS_SUBIDX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000028ull + (((offset) & 7) * 8) - 8 * 3)
+#define CVMX_NPI_MSI_RCV \
+	 (0x0000000000000190ull)
+#define CVMX_NPI_NPI_MSI_RCV \
+	 CVMX_ADD_IO_SEG(0x00011F0000001190ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT0 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000050ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000058ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000060ull)
+#define CVMX_NPI_NUM_DESC_OUTPUT3 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000068ull)
+#define CVMX_NPI_NUM_DESC_OUTPUTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000050ull + (((offset) & 3) * 8))
+#define CVMX_NPI_OUTPUT_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F0000000100ull)
+#define CVMX_NPI_P0_DBPAIR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000180ull)
+#define CVMX_NPI_P0_INSTR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F00000001C0ull)
+#define CVMX_NPI_P0_INSTR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000001A0ull)
+#define CVMX_NPI_P0_PAIR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000160ull)
+#define CVMX_NPI_P1_DBPAIR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000188ull)
+#define CVMX_NPI_P1_INSTR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F00000001C8ull)
+#define CVMX_NPI_P1_INSTR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000001A8ull)
+#define CVMX_NPI_P1_PAIR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000168ull)
+#define CVMX_NPI_P2_DBPAIR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000190ull)
+#define CVMX_NPI_P2_INSTR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F00000001D0ull)
+#define CVMX_NPI_P2_INSTR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000001B0ull)
+#define CVMX_NPI_P2_PAIR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000170ull)
+#define CVMX_NPI_P3_DBPAIR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000198ull)
+#define CVMX_NPI_P3_INSTR_ADDR \
+	 CVMX_ADD_IO_SEG(0x00011F00000001D8ull)
+#define CVMX_NPI_P3_INSTR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000001B8ull)
+#define CVMX_NPI_P3_PAIR_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000178ull)
+#define CVMX_NPI_PCI_BAR1_INDEXX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000001100ull + (((offset) & 31) * 4))
+#define CVMX_NPI_PCI_BIST_REG \
+	 CVMX_ADD_IO_SEG(0x00011F00000011C0ull)
+#define CVMX_NPI_PCI_BURST_SIZE \
+	 CVMX_ADD_IO_SEG(0x00011F00000000D8ull)
+#define CVMX_NPI_PCI_CFG00 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001800ull)
+#define CVMX_NPI_PCI_CFG01 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001804ull)
+#define CVMX_NPI_PCI_CFG02 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001808ull)
+#define CVMX_NPI_PCI_CFG03 \
+	 CVMX_ADD_IO_SEG(0x00011F000000180Cull)
+#define CVMX_NPI_PCI_CFG04 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001810ull)
+#define CVMX_NPI_PCI_CFG05 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001814ull)
+#define CVMX_NPI_PCI_CFG06 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001818ull)
+#define CVMX_NPI_PCI_CFG07 \
+	 CVMX_ADD_IO_SEG(0x00011F000000181Cull)
+#define CVMX_NPI_PCI_CFG08 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001820ull)
+#define CVMX_NPI_PCI_CFG09 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001824ull)
+#define CVMX_NPI_PCI_CFG10 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001828ull)
+#define CVMX_NPI_PCI_CFG11 \
+	 CVMX_ADD_IO_SEG(0x00011F000000182Cull)
+#define CVMX_NPI_PCI_CFG12 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001830ull)
+#define CVMX_NPI_PCI_CFG13 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001834ull)
+#define CVMX_NPI_PCI_CFG15 \
+	 CVMX_ADD_IO_SEG(0x00011F000000183Cull)
+#define CVMX_NPI_PCI_CFG16 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001840ull)
+#define CVMX_NPI_PCI_CFG17 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001844ull)
+#define CVMX_NPI_PCI_CFG18 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001848ull)
+#define CVMX_NPI_PCI_CFG19 \
+	 CVMX_ADD_IO_SEG(0x00011F000000184Cull)
+#define CVMX_NPI_PCI_CFG20 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001850ull)
+#define CVMX_NPI_PCI_CFG21 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001854ull)
+#define CVMX_NPI_PCI_CFG22 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001858ull)
+#define CVMX_NPI_PCI_CFG56 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018E0ull)
+#define CVMX_NPI_PCI_CFG57 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018E4ull)
+#define CVMX_NPI_PCI_CFG58 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018E8ull)
+#define CVMX_NPI_PCI_CFG59 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018ECull)
+#define CVMX_NPI_PCI_CFG60 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018F0ull)
+#define CVMX_NPI_PCI_CFG61 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018F4ull)
+#define CVMX_NPI_PCI_CFG62 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018F8ull)
+#define CVMX_NPI_PCI_CFG63 \
+	 CVMX_ADD_IO_SEG(0x00011F00000018FCull)
+#define CVMX_NPI_PCI_CNT_REG \
+	 CVMX_ADD_IO_SEG(0x00011F00000011B8ull)
+#define CVMX_NPI_PCI_CTL_STATUS_2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000118Cull)
+#define CVMX_NPI_PCI_INT_ARB_CFG \
+	 CVMX_ADD_IO_SEG(0x00011F0000000130ull)
+#define CVMX_NPI_PCI_INT_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F00000011A0ull)
+#define CVMX_NPI_PCI_INT_SUM2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001198ull)
+#define CVMX_NPI_PCI_READ_CMD \
+	 CVMX_ADD_IO_SEG(0x00011F0000000048ull)
+#define CVMX_NPI_PCI_READ_CMD_6 \
+	 CVMX_ADD_IO_SEG(0x00011F0000001180ull)
+#define CVMX_NPI_PCI_READ_CMD_C \
+	 CVMX_ADD_IO_SEG(0x00011F0000001184ull)
+#define CVMX_NPI_PCI_READ_CMD_E \
+	 CVMX_ADD_IO_SEG(0x00011F0000001188ull)
+#define CVMX_NPI_PCI_SCM_REG \
+	 CVMX_ADD_IO_SEG(0x00011F00000011A8ull)
+#define CVMX_NPI_PCI_TSR_REG \
+	 CVMX_ADD_IO_SEG(0x00011F00000011B0ull)
+#define CVMX_NPI_PORT32_INSTR_HDR \
+	 CVMX_ADD_IO_SEG(0x00011F00000001F8ull)
+#define CVMX_NPI_PORT33_INSTR_HDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000200ull)
+#define CVMX_NPI_PORT34_INSTR_HDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000208ull)
+#define CVMX_NPI_PORT35_INSTR_HDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000000210ull)
+#define CVMX_NPI_PORT_BP_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F00000001F0ull)
+#define CVMX_NPI_PX_DBPAIR_ADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000180ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_INSTR_ADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000001C0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_INSTR_CNTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000001A0ull + (((offset) & 3) * 8))
+#define CVMX_NPI_PX_PAIR_CNTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000160ull + (((offset) & 3) * 8))
+#define CVMX_NPI_RSL_INT_BLOCKS \
+	 CVMX_ADD_IO_SEG(0x00011F0000000000ull)
+#define CVMX_NPI_SIZE_INPUT0 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000078ull)
+#define CVMX_NPI_SIZE_INPUT1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000088ull)
+#define CVMX_NPI_SIZE_INPUT2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000000098ull)
+#define CVMX_NPI_SIZE_INPUT3 \
+	 CVMX_ADD_IO_SEG(0x00011F00000000A8ull)
+#define CVMX_NPI_SIZE_INPUTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000000078ull + (((offset) & 3) * 16))
+#define CVMX_NPI_WIN_READ_TO \
+	 CVMX_ADD_IO_SEG(0x00011F00000001E0ull)
+
+union cvmx_npi_base_addr_inputx {
+	uint64_t u64;
+	struct cvmx_npi_base_addr_inputx_s {
+		uint64_t baddr:61;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_npi_base_addr_inputx_s cn30xx;
+	struct cvmx_npi_base_addr_inputx_s cn31xx;
+	struct cvmx_npi_base_addr_inputx_s cn38xx;
+	struct cvmx_npi_base_addr_inputx_s cn38xxp2;
+	struct cvmx_npi_base_addr_inputx_s cn50xx;
+	struct cvmx_npi_base_addr_inputx_s cn58xx;
+	struct cvmx_npi_base_addr_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_base_addr_outputx {
+	uint64_t u64;
+	struct cvmx_npi_base_addr_outputx_s {
+		uint64_t baddr:61;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_npi_base_addr_outputx_s cn30xx;
+	struct cvmx_npi_base_addr_outputx_s cn31xx;
+	struct cvmx_npi_base_addr_outputx_s cn38xx;
+	struct cvmx_npi_base_addr_outputx_s cn38xxp2;
+	struct cvmx_npi_base_addr_outputx_s cn50xx;
+	struct cvmx_npi_base_addr_outputx_s cn58xx;
+	struct cvmx_npi_base_addr_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_bist_status {
+	uint64_t u64;
+	struct cvmx_npi_bist_status_s {
+		uint64_t reserved_20_63:44;
+		uint64_t csr_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pof0_bs:1;
+		uint64_t pof1_bs:1;
+		uint64_t pof2_bs:1;
+		uint64_t pof3_bs:1;
+		uint64_t pos_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dpi_bs:1;
+	} s;
+	struct cvmx_npi_bist_status_cn30xx {
+		uint64_t reserved_20_63:44;
+		uint64_t csr_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pof0_bs:1;
+		uint64_t reserved_5_7:3;
+		uint64_t pos_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dpi_bs:1;
+	} cn30xx;
+	struct cvmx_npi_bist_status_s cn31xx;
+	struct cvmx_npi_bist_status_s cn38xx;
+	struct cvmx_npi_bist_status_s cn38xxp2;
+	struct cvmx_npi_bist_status_cn50xx {
+		uint64_t reserved_20_63:44;
+		uint64_t csr_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pof0_bs:1;
+		uint64_t pof1_bs:1;
+		uint64_t reserved_5_6:2;
+		uint64_t pos_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dpi_bs:1;
+	} cn50xx;
+	struct cvmx_npi_bist_status_s cn58xx;
+	struct cvmx_npi_bist_status_s cn58xxp1;
+};
+
+union cvmx_npi_buff_size_outputx {
+	uint64_t u64;
+	struct cvmx_npi_buff_size_outputx_s {
+		uint64_t reserved_23_63:41;
+		uint64_t isize:7;
+		uint64_t bsize:16;
+	} s;
+	struct cvmx_npi_buff_size_outputx_s cn30xx;
+	struct cvmx_npi_buff_size_outputx_s cn31xx;
+	struct cvmx_npi_buff_size_outputx_s cn38xx;
+	struct cvmx_npi_buff_size_outputx_s cn38xxp2;
+	struct cvmx_npi_buff_size_outputx_s cn50xx;
+	struct cvmx_npi_buff_size_outputx_s cn58xx;
+	struct cvmx_npi_buff_size_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_comp_ctl {
+	uint64_t u64;
+	struct cvmx_npi_comp_ctl_s {
+		uint64_t reserved_10_63:54;
+		uint64_t pctl:5;
+		uint64_t nctl:5;
+	} s;
+	struct cvmx_npi_comp_ctl_s cn50xx;
+	struct cvmx_npi_comp_ctl_s cn58xx;
+	struct cvmx_npi_comp_ctl_s cn58xxp1;
+};
+
+union cvmx_npi_ctl_status {
+	uint64_t u64;
+	struct cvmx_npi_ctl_status_s {
+		uint64_t reserved_63_63:1;
+		uint64_t chip_rev:8;
+		uint64_t dis_pniw:1;
+		uint64_t out3_enb:1;
+		uint64_t out2_enb:1;
+		uint64_t out1_enb:1;
+		uint64_t out0_enb:1;
+		uint64_t ins3_enb:1;
+		uint64_t ins2_enb:1;
+		uint64_t ins1_enb:1;
+		uint64_t ins0_enb:1;
+		uint64_t ins3_64b:1;
+		uint64_t ins2_64b:1;
+		uint64_t ins1_64b:1;
+		uint64_t ins0_64b:1;
+		uint64_t pci_wdis:1;
+		uint64_t wait_com:1;
+		uint64_t reserved_37_39:3;
+		uint64_t max_word:5;
+		uint64_t reserved_10_31:22;
+		uint64_t timer:10;
+	} s;
+	struct cvmx_npi_ctl_status_cn30xx {
+		uint64_t reserved_63_63:1;
+		uint64_t chip_rev:8;
+		uint64_t dis_pniw:1;
+		uint64_t reserved_51_53:3;
+		uint64_t out0_enb:1;
+		uint64_t reserved_47_49:3;
+		uint64_t ins0_enb:1;
+		uint64_t reserved_43_45:3;
+		uint64_t ins0_64b:1;
+		uint64_t pci_wdis:1;
+		uint64_t wait_com:1;
+		uint64_t reserved_37_39:3;
+		uint64_t max_word:5;
+		uint64_t reserved_10_31:22;
+		uint64_t timer:10;
+	} cn30xx;
+	struct cvmx_npi_ctl_status_cn31xx {
+		uint64_t reserved_63_63:1;
+		uint64_t chip_rev:8;
+		uint64_t dis_pniw:1;
+		uint64_t reserved_52_53:2;
+		uint64_t out1_enb:1;
+		uint64_t out0_enb:1;
+		uint64_t reserved_48_49:2;
+		uint64_t ins1_enb:1;
+		uint64_t ins0_enb:1;
+		uint64_t reserved_44_45:2;
+		uint64_t ins1_64b:1;
+		uint64_t ins0_64b:1;
+		uint64_t pci_wdis:1;
+		uint64_t wait_com:1;
+		uint64_t reserved_37_39:3;
+		uint64_t max_word:5;
+		uint64_t reserved_10_31:22;
+		uint64_t timer:10;
+	} cn31xx;
+	struct cvmx_npi_ctl_status_s cn38xx;
+	struct cvmx_npi_ctl_status_s cn38xxp2;
+	struct cvmx_npi_ctl_status_cn31xx cn50xx;
+	struct cvmx_npi_ctl_status_s cn58xx;
+	struct cvmx_npi_ctl_status_s cn58xxp1;
+};
+
+union cvmx_npi_dbg_select {
+	uint64_t u64;
+	struct cvmx_npi_dbg_select_s {
+		uint64_t reserved_16_63:48;
+		uint64_t dbg_sel:16;
+	} s;
+	struct cvmx_npi_dbg_select_s cn30xx;
+	struct cvmx_npi_dbg_select_s cn31xx;
+	struct cvmx_npi_dbg_select_s cn38xx;
+	struct cvmx_npi_dbg_select_s cn38xxp2;
+	struct cvmx_npi_dbg_select_s cn50xx;
+	struct cvmx_npi_dbg_select_s cn58xx;
+	struct cvmx_npi_dbg_select_s cn58xxp1;
+};
+
+union cvmx_npi_dma_control {
+	uint64_t u64;
+	struct cvmx_npi_dma_control_s {
+		uint64_t reserved_36_63:28;
+		uint64_t b0_lend:1;
+		uint64_t dwb_denb:1;
+		uint64_t dwb_ichk:9;
+		uint64_t fpa_que:3;
+		uint64_t o_add1:1;
+		uint64_t o_ro:1;
+		uint64_t o_ns:1;
+		uint64_t o_es:2;
+		uint64_t o_mode:1;
+		uint64_t hp_enb:1;
+		uint64_t lp_enb:1;
+		uint64_t csize:14;
+	} s;
+	struct cvmx_npi_dma_control_s cn30xx;
+	struct cvmx_npi_dma_control_s cn31xx;
+	struct cvmx_npi_dma_control_s cn38xx;
+	struct cvmx_npi_dma_control_s cn38xxp2;
+	struct cvmx_npi_dma_control_s cn50xx;
+	struct cvmx_npi_dma_control_s cn58xx;
+	struct cvmx_npi_dma_control_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_counts {
+	uint64_t u64;
+	struct cvmx_npi_dma_highp_counts_s {
+		uint64_t reserved_39_63:25;
+		uint64_t fcnt:7;
+		uint64_t dbell:32;
+	} s;
+	struct cvmx_npi_dma_highp_counts_s cn30xx;
+	struct cvmx_npi_dma_highp_counts_s cn31xx;
+	struct cvmx_npi_dma_highp_counts_s cn38xx;
+	struct cvmx_npi_dma_highp_counts_s cn38xxp2;
+	struct cvmx_npi_dma_highp_counts_s cn50xx;
+	struct cvmx_npi_dma_highp_counts_s cn58xx;
+	struct cvmx_npi_dma_highp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_highp_naddr {
+	uint64_t u64;
+	struct cvmx_npi_dma_highp_naddr_s {
+		uint64_t reserved_40_63:24;
+		uint64_t state:4;
+		uint64_t addr:36;
+	} s;
+	struct cvmx_npi_dma_highp_naddr_s cn30xx;
+	struct cvmx_npi_dma_highp_naddr_s cn31xx;
+	struct cvmx_npi_dma_highp_naddr_s cn38xx;
+	struct cvmx_npi_dma_highp_naddr_s cn38xxp2;
+	struct cvmx_npi_dma_highp_naddr_s cn50xx;
+	struct cvmx_npi_dma_highp_naddr_s cn58xx;
+	struct cvmx_npi_dma_highp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_counts {
+	uint64_t u64;
+	struct cvmx_npi_dma_lowp_counts_s {
+		uint64_t reserved_39_63:25;
+		uint64_t fcnt:7;
+		uint64_t dbell:32;
+	} s;
+	struct cvmx_npi_dma_lowp_counts_s cn30xx;
+	struct cvmx_npi_dma_lowp_counts_s cn31xx;
+	struct cvmx_npi_dma_lowp_counts_s cn38xx;
+	struct cvmx_npi_dma_lowp_counts_s cn38xxp2;
+	struct cvmx_npi_dma_lowp_counts_s cn50xx;
+	struct cvmx_npi_dma_lowp_counts_s cn58xx;
+	struct cvmx_npi_dma_lowp_counts_s cn58xxp1;
+};
+
+union cvmx_npi_dma_lowp_naddr {
+	uint64_t u64;
+	struct cvmx_npi_dma_lowp_naddr_s {
+		uint64_t reserved_40_63:24;
+		uint64_t state:4;
+		uint64_t addr:36;
+	} s;
+	struct cvmx_npi_dma_lowp_naddr_s cn30xx;
+	struct cvmx_npi_dma_lowp_naddr_s cn31xx;
+	struct cvmx_npi_dma_lowp_naddr_s cn38xx;
+	struct cvmx_npi_dma_lowp_naddr_s cn38xxp2;
+	struct cvmx_npi_dma_lowp_naddr_s cn50xx;
+	struct cvmx_npi_dma_lowp_naddr_s cn58xx;
+	struct cvmx_npi_dma_lowp_naddr_s cn58xxp1;
+};
+
+union cvmx_npi_highp_dbell {
+	uint64_t u64;
+	struct cvmx_npi_highp_dbell_s {
+		uint64_t reserved_16_63:48;
+		uint64_t dbell:16;
+	} s;
+	struct cvmx_npi_highp_dbell_s cn30xx;
+	struct cvmx_npi_highp_dbell_s cn31xx;
+	struct cvmx_npi_highp_dbell_s cn38xx;
+	struct cvmx_npi_highp_dbell_s cn38xxp2;
+	struct cvmx_npi_highp_dbell_s cn50xx;
+	struct cvmx_npi_highp_dbell_s cn58xx;
+	struct cvmx_npi_highp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_highp_ibuff_saddr {
+	uint64_t u64;
+	struct cvmx_npi_highp_ibuff_saddr_s {
+		uint64_t reserved_36_63:28;
+		uint64_t saddr:36;
+	} s;
+	struct cvmx_npi_highp_ibuff_saddr_s cn30xx;
+	struct cvmx_npi_highp_ibuff_saddr_s cn31xx;
+	struct cvmx_npi_highp_ibuff_saddr_s cn38xx;
+	struct cvmx_npi_highp_ibuff_saddr_s cn38xxp2;
+	struct cvmx_npi_highp_ibuff_saddr_s cn50xx;
+	struct cvmx_npi_highp_ibuff_saddr_s cn58xx;
+	struct cvmx_npi_highp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_input_control {
+	uint64_t u64;
+	struct cvmx_npi_input_control_s {
+		uint64_t reserved_23_63:41;
+		uint64_t pkt_rr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t d_nsr:1;
+		uint64_t d_esr:2;
+		uint64_t d_ror:1;
+		uint64_t use_csr:1;
+		uint64_t nsr:1;
+		uint64_t esr:2;
+		uint64_t ror:1;
+	} s;
+	struct cvmx_npi_input_control_cn30xx {
+		uint64_t reserved_22_63:42;
+		uint64_t pbp_dhi:13;
+		uint64_t d_nsr:1;
+		uint64_t d_esr:2;
+		uint64_t d_ror:1;
+		uint64_t use_csr:1;
+		uint64_t nsr:1;
+		uint64_t esr:2;
+		uint64_t ror:1;
+	} cn30xx;
+	struct cvmx_npi_input_control_cn30xx cn31xx;
+	struct cvmx_npi_input_control_s cn38xx;
+	struct cvmx_npi_input_control_cn30xx cn38xxp2;
+	struct cvmx_npi_input_control_s cn50xx;
+	struct cvmx_npi_input_control_s cn58xx;
+	struct cvmx_npi_input_control_s cn58xxp1;
+};
+
+union cvmx_npi_int_enb {
+	uint64_t u64;
+	struct cvmx_npi_int_enb_s {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t i3_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t p3_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t p3_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t g3_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t p3_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t p3_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t i3_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t i3_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t po3_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npi_int_enb_cn30xx {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t reserved_36_38:3;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_32_34:3;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_28_30:3;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_24_26:3;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_20_22:3;
+		uint64_t p0_perr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_12_14:3;
+		uint64_t i0_overf:1;
+		uint64_t reserved_8_10:3;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_4_6:3;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn30xx;
+	struct cvmx_npi_int_enb_cn31xx {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t reserved_37_38:2;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_33_34:2;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_29_30:2;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_25_26:2;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_21_22:2;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t reserved_17_18:2;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_13_14:2;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t reserved_9_10:2;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_5_6:2;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn31xx;
+	struct cvmx_npi_int_enb_s cn38xx;
+	struct cvmx_npi_int_enb_cn38xxp2 {
+		uint64_t reserved_42_63:22;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t i3_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t p3_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t p3_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t g3_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t p3_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t p3_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t i3_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t i3_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t po3_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn38xxp2;
+	struct cvmx_npi_int_enb_cn31xx cn50xx;
+	struct cvmx_npi_int_enb_s cn58xx;
+	struct cvmx_npi_int_enb_s cn58xxp1;
+};
+
+union cvmx_npi_int_sum {
+	uint64_t u64;
+	struct cvmx_npi_int_sum_s {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t i3_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t p3_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t p3_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t g3_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t p3_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t p3_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t i3_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t i3_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t po3_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} s;
+	struct cvmx_npi_int_sum_cn30xx {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t reserved_36_38:3;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_32_34:3;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_28_30:3;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_24_26:3;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_20_22:3;
+		uint64_t p0_perr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_12_14:3;
+		uint64_t i0_overf:1;
+		uint64_t reserved_8_10:3;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_4_6:3;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn30xx;
+	struct cvmx_npi_int_sum_cn31xx {
+		uint64_t reserved_62_63:2;
+		uint64_t q1_a_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pcf_p_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t rwx_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t fcr_s_e:1;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t reserved_37_38:2;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_33_34:2;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_29_30:2;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_25_26:2;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_21_22:2;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t reserved_17_18:2;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_13_14:2;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t reserved_9_10:2;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_5_6:2;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn31xx;
+	struct cvmx_npi_int_sum_s cn38xx;
+	struct cvmx_npi_int_sum_cn38xxp2 {
+		uint64_t reserved_42_63:22;
+		uint64_t iobdma:1;
+		uint64_t p_dperr:1;
+		uint64_t win_rto:1;
+		uint64_t i3_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i0_pperr:1;
+		uint64_t p3_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p0_ptout:1;
+		uint64_t p3_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p0_pperr:1;
+		uint64_t g3_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g0_rtout:1;
+		uint64_t p3_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p0_perr:1;
+		uint64_t p3_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p0_rtout:1;
+		uint64_t i3_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i0_overf:1;
+		uint64_t i3_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i0_rtout:1;
+		uint64_t po3_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po0_2sml:1;
+		uint64_t pci_rsl:1;
+		uint64_t rml_wto:1;
+		uint64_t rml_rto:1;
+	} cn38xxp2;
+	struct cvmx_npi_int_sum_cn31xx cn50xx;
+	struct cvmx_npi_int_sum_s cn58xx;
+	struct cvmx_npi_int_sum_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_dbell {
+	uint64_t u64;
+	struct cvmx_npi_lowp_dbell_s {
+		uint64_t reserved_16_63:48;
+		uint64_t dbell:16;
+	} s;
+	struct cvmx_npi_lowp_dbell_s cn30xx;
+	struct cvmx_npi_lowp_dbell_s cn31xx;
+	struct cvmx_npi_lowp_dbell_s cn38xx;
+	struct cvmx_npi_lowp_dbell_s cn38xxp2;
+	struct cvmx_npi_lowp_dbell_s cn50xx;
+	struct cvmx_npi_lowp_dbell_s cn58xx;
+	struct cvmx_npi_lowp_dbell_s cn58xxp1;
+};
+
+union cvmx_npi_lowp_ibuff_saddr {
+	uint64_t u64;
+	struct cvmx_npi_lowp_ibuff_saddr_s {
+		uint64_t reserved_36_63:28;
+		uint64_t saddr:36;
+	} s;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn30xx;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn31xx;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn38xx;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn38xxp2;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn50xx;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn58xx;
+	struct cvmx_npi_lowp_ibuff_saddr_s cn58xxp1;
+};
+
+union cvmx_npi_mem_access_subidx {
+	uint64_t u64;
+	struct cvmx_npi_mem_access_subidx_s {
+		uint64_t reserved_38_63:26;
+		uint64_t shortl:1;
+		uint64_t nmerge:1;
+		uint64_t esr:2;
+		uint64_t esw:2;
+		uint64_t nsr:1;
+		uint64_t nsw:1;
+		uint64_t ror:1;
+		uint64_t row:1;
+		uint64_t ba:28;
+	} s;
+	struct cvmx_npi_mem_access_subidx_s cn30xx;
+	struct cvmx_npi_mem_access_subidx_cn31xx {
+		uint64_t reserved_36_63:28;
+		uint64_t esr:2;
+		uint64_t esw:2;
+		uint64_t nsr:1;
+		uint64_t nsw:1;
+		uint64_t ror:1;
+		uint64_t row:1;
+		uint64_t ba:28;
+	} cn31xx;
+	struct cvmx_npi_mem_access_subidx_s cn38xx;
+	struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2;
+	struct cvmx_npi_mem_access_subidx_s cn50xx;
+	struct cvmx_npi_mem_access_subidx_s cn58xx;
+	struct cvmx_npi_mem_access_subidx_s cn58xxp1;
+};
+
+union cvmx_npi_msi_rcv {
+	uint64_t u64;
+	struct cvmx_npi_msi_rcv_s {
+		uint64_t int_vec:64;
+	} s;
+	struct cvmx_npi_msi_rcv_s cn30xx;
+	struct cvmx_npi_msi_rcv_s cn31xx;
+	struct cvmx_npi_msi_rcv_s cn38xx;
+	struct cvmx_npi_msi_rcv_s cn38xxp2;
+	struct cvmx_npi_msi_rcv_s cn50xx;
+	struct cvmx_npi_msi_rcv_s cn58xx;
+	struct cvmx_npi_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_npi_num_desc_outputx {
+	uint64_t u64;
+	struct cvmx_npi_num_desc_outputx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t size:32;
+	} s;
+	struct cvmx_npi_num_desc_outputx_s cn30xx;
+	struct cvmx_npi_num_desc_outputx_s cn31xx;
+	struct cvmx_npi_num_desc_outputx_s cn38xx;
+	struct cvmx_npi_num_desc_outputx_s cn38xxp2;
+	struct cvmx_npi_num_desc_outputx_s cn50xx;
+	struct cvmx_npi_num_desc_outputx_s cn58xx;
+	struct cvmx_npi_num_desc_outputx_s cn58xxp1;
+};
+
+union cvmx_npi_output_control {
+	uint64_t u64;
+	struct cvmx_npi_output_control_s {
+		uint64_t reserved_49_63:15;
+		uint64_t pkt_rr:1;
+		uint64_t p3_bmode:1;
+		uint64_t p2_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t p0_bmode:1;
+		uint64_t o3_es:2;
+		uint64_t o3_ns:1;
+		uint64_t o3_ro:1;
+		uint64_t o2_es:2;
+		uint64_t o2_ns:1;
+		uint64_t o2_ro:1;
+		uint64_t o1_es:2;
+		uint64_t o1_ns:1;
+		uint64_t o1_ro:1;
+		uint64_t o0_es:2;
+		uint64_t o0_ns:1;
+		uint64_t o0_ro:1;
+		uint64_t o3_csrm:1;
+		uint64_t o2_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_20_23:4;
+		uint64_t iptr_o3:1;
+		uint64_t iptr_o2:1;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o0:1;
+		uint64_t esr_sl3:2;
+		uint64_t nsr_sl3:1;
+		uint64_t ror_sl3:1;
+		uint64_t esr_sl2:2;
+		uint64_t nsr_sl2:1;
+		uint64_t ror_sl2:1;
+		uint64_t esr_sl1:2;
+		uint64_t nsr_sl1:1;
+		uint64_t ror_sl1:1;
+		uint64_t esr_sl0:2;
+		uint64_t nsr_sl0:1;
+		uint64_t ror_sl0:1;
+	} s;
+	struct cvmx_npi_output_control_cn30xx {
+		uint64_t reserved_45_63:19;
+		uint64_t p0_bmode:1;
+		uint64_t reserved_32_43:12;
+		uint64_t o0_es:2;
+		uint64_t o0_ns:1;
+		uint64_t o0_ro:1;
+		uint64_t reserved_25_27:3;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_17_23:7;
+		uint64_t iptr_o0:1;
+		uint64_t reserved_4_15:12;
+		uint64_t esr_sl0:2;
+		uint64_t nsr_sl0:1;
+		uint64_t ror_sl0:1;
+	} cn30xx;
+	struct cvmx_npi_output_control_cn31xx {
+		uint64_t reserved_46_63:18;
+		uint64_t p1_bmode:1;
+		uint64_t p0_bmode:1;
+		uint64_t reserved_36_43:8;
+		uint64_t o1_es:2;
+		uint64_t o1_ns:1;
+		uint64_t o1_ro:1;
+		uint64_t o0_es:2;
+		uint64_t o0_ns:1;
+		uint64_t o0_ro:1;
+		uint64_t reserved_26_27:2;
+		uint64_t o1_csrm:1;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_18_23:6;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o0:1;
+		uint64_t reserved_8_15:8;
+		uint64_t esr_sl1:2;
+		uint64_t nsr_sl1:1;
+		uint64_t ror_sl1:1;
+		uint64_t esr_sl0:2;
+		uint64_t nsr_sl0:1;
+		uint64_t ror_sl0:1;
+	} cn31xx;
+	struct cvmx_npi_output_control_s cn38xx;
+	struct cvmx_npi_output_control_cn38xxp2 {
+		uint64_t reserved_48_63:16;
+		uint64_t p3_bmode:1;
+		uint64_t p2_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t p0_bmode:1;
+		uint64_t o3_es:2;
+		uint64_t o3_ns:1;
+		uint64_t o3_ro:1;
+		uint64_t o2_es:2;
+		uint64_t o2_ns:1;
+		uint64_t o2_ro:1;
+		uint64_t o1_es:2;
+		uint64_t o1_ns:1;
+		uint64_t o1_ro:1;
+		uint64_t o0_es:2;
+		uint64_t o0_ns:1;
+		uint64_t o0_ro:1;
+		uint64_t o3_csrm:1;
+		uint64_t o2_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_20_23:4;
+		uint64_t iptr_o3:1;
+		uint64_t iptr_o2:1;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o0:1;
+		uint64_t esr_sl3:2;
+		uint64_t nsr_sl3:1;
+		uint64_t ror_sl3:1;
+		uint64_t esr_sl2:2;
+		uint64_t nsr_sl2:1;
+		uint64_t ror_sl2:1;
+		uint64_t esr_sl1:2;
+		uint64_t nsr_sl1:1;
+		uint64_t ror_sl1:1;
+		uint64_t esr_sl0:2;
+		uint64_t nsr_sl0:1;
+		uint64_t ror_sl0:1;
+	} cn38xxp2;
+	struct cvmx_npi_output_control_cn50xx {
+		uint64_t reserved_49_63:15;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_46_47:2;
+		uint64_t p1_bmode:1;
+		uint64_t p0_bmode:1;
+		uint64_t reserved_36_43:8;
+		uint64_t o1_es:2;
+		uint64_t o1_ns:1;
+		uint64_t o1_ro:1;
+		uint64_t o0_es:2;
+		uint64_t o0_ns:1;
+		uint64_t o0_ro:1;
+		uint64_t reserved_26_27:2;
+		uint64_t o1_csrm:1;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_18_23:6;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o0:1;
+		uint64_t reserved_8_15:8;
+		uint64_t esr_sl1:2;
+		uint64_t nsr_sl1:1;
+		uint64_t ror_sl1:1;
+		uint64_t esr_sl0:2;
+		uint64_t nsr_sl0:1;
+		uint64_t ror_sl0:1;
+	} cn50xx;
+	struct cvmx_npi_output_control_s cn58xx;
+	struct cvmx_npi_output_control_s cn58xxp1;
+};
+
+union cvmx_npi_px_dbpair_addr {
+	uint64_t u64;
+	struct cvmx_npi_px_dbpair_addr_s {
+		uint64_t reserved_63_63:1;
+		uint64_t state:2;
+		uint64_t naddr:61;
+	} s;
+	struct cvmx_npi_px_dbpair_addr_s cn30xx;
+	struct cvmx_npi_px_dbpair_addr_s cn31xx;
+	struct cvmx_npi_px_dbpair_addr_s cn38xx;
+	struct cvmx_npi_px_dbpair_addr_s cn38xxp2;
+	struct cvmx_npi_px_dbpair_addr_s cn50xx;
+	struct cvmx_npi_px_dbpair_addr_s cn58xx;
+	struct cvmx_npi_px_dbpair_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_addr {
+	uint64_t u64;
+	struct cvmx_npi_px_instr_addr_s {
+		uint64_t state:3;
+		uint64_t naddr:61;
+	} s;
+	struct cvmx_npi_px_instr_addr_s cn30xx;
+	struct cvmx_npi_px_instr_addr_s cn31xx;
+	struct cvmx_npi_px_instr_addr_s cn38xx;
+	struct cvmx_npi_px_instr_addr_s cn38xxp2;
+	struct cvmx_npi_px_instr_addr_s cn50xx;
+	struct cvmx_npi_px_instr_addr_s cn58xx;
+	struct cvmx_npi_px_instr_addr_s cn58xxp1;
+};
+
+union cvmx_npi_px_instr_cnts {
+	uint64_t u64;
+	struct cvmx_npi_px_instr_cnts_s {
+		uint64_t reserved_38_63:26;
+		uint64_t fcnt:6;
+		uint64_t avail:32;
+	} s;
+	struct cvmx_npi_px_instr_cnts_s cn30xx;
+	struct cvmx_npi_px_instr_cnts_s cn31xx;
+	struct cvmx_npi_px_instr_cnts_s cn38xx;
+	struct cvmx_npi_px_instr_cnts_s cn38xxp2;
+	struct cvmx_npi_px_instr_cnts_s cn50xx;
+	struct cvmx_npi_px_instr_cnts_s cn58xx;
+	struct cvmx_npi_px_instr_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_px_pair_cnts {
+	uint64_t u64;
+	struct cvmx_npi_px_pair_cnts_s {
+		uint64_t reserved_37_63:27;
+		uint64_t fcnt:5;
+		uint64_t avail:32;
+	} s;
+	struct cvmx_npi_px_pair_cnts_s cn30xx;
+	struct cvmx_npi_px_pair_cnts_s cn31xx;
+	struct cvmx_npi_px_pair_cnts_s cn38xx;
+	struct cvmx_npi_px_pair_cnts_s cn38xxp2;
+	struct cvmx_npi_px_pair_cnts_s cn50xx;
+	struct cvmx_npi_px_pair_cnts_s cn58xx;
+	struct cvmx_npi_px_pair_cnts_s cn58xxp1;
+};
+
+union cvmx_npi_pci_burst_size {
+	uint64_t u64;
+	struct cvmx_npi_pci_burst_size_s {
+		uint64_t reserved_14_63:50;
+		uint64_t wr_brst:7;
+		uint64_t rd_brst:7;
+	} s;
+	struct cvmx_npi_pci_burst_size_s cn30xx;
+	struct cvmx_npi_pci_burst_size_s cn31xx;
+	struct cvmx_npi_pci_burst_size_s cn38xx;
+	struct cvmx_npi_pci_burst_size_s cn38xxp2;
+	struct cvmx_npi_pci_burst_size_s cn50xx;
+	struct cvmx_npi_pci_burst_size_s cn58xx;
+	struct cvmx_npi_pci_burst_size_s cn58xxp1;
+};
+
+union cvmx_npi_pci_int_arb_cfg {
+	uint64_t u64;
+	struct cvmx_npi_pci_int_arb_cfg_s {
+		uint64_t reserved_13_63:51;
+		uint64_t hostmode:1;
+		uint64_t pci_ovr:4;
+		uint64_t reserved_5_7:3;
+		uint64_t en:1;
+		uint64_t park_mod:1;
+		uint64_t park_dev:3;
+	} s;
+	struct cvmx_npi_pci_int_arb_cfg_cn30xx {
+		uint64_t reserved_5_63:59;
+		uint64_t en:1;
+		uint64_t park_mod:1;
+		uint64_t park_dev:3;
+	} cn30xx;
+	struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx;
+	struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx;
+	struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xxp2;
+	struct cvmx_npi_pci_int_arb_cfg_s cn50xx;
+	struct cvmx_npi_pci_int_arb_cfg_s cn58xx;
+	struct cvmx_npi_pci_int_arb_cfg_s cn58xxp1;
+};
+
+union cvmx_npi_pci_read_cmd {
+	uint64_t u64;
+	struct cvmx_npi_pci_read_cmd_s {
+		uint64_t reserved_11_63:53;
+		uint64_t cmd_size:11;
+	} s;
+	struct cvmx_npi_pci_read_cmd_s cn30xx;
+	struct cvmx_npi_pci_read_cmd_s cn31xx;
+	struct cvmx_npi_pci_read_cmd_s cn38xx;
+	struct cvmx_npi_pci_read_cmd_s cn38xxp2;
+	struct cvmx_npi_pci_read_cmd_s cn50xx;
+	struct cvmx_npi_pci_read_cmd_s cn58xx;
+	struct cvmx_npi_pci_read_cmd_s cn58xxp1;
+};
+
+union cvmx_npi_port32_instr_hdr {
+	uint64_t u64;
+	struct cvmx_npi_port32_instr_hdr_s {
+		uint64_t reserved_44_63:20;
+		uint64_t pbp:1;
+		uint64_t rsv_f:5;
+		uint64_t rparmode:2;
+		uint64_t rsv_e:1;
+		uint64_t rskp_len:7;
+		uint64_t rsv_d:6;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_c:5;
+		uint64_t par_mode:2;
+		uint64_t rsv_b:1;
+		uint64_t skp_len:7;
+		uint64_t rsv_a:6;
+	} s;
+	struct cvmx_npi_port32_instr_hdr_s cn30xx;
+	struct cvmx_npi_port32_instr_hdr_s cn31xx;
+	struct cvmx_npi_port32_instr_hdr_s cn38xx;
+	struct cvmx_npi_port32_instr_hdr_s cn38xxp2;
+	struct cvmx_npi_port32_instr_hdr_s cn50xx;
+	struct cvmx_npi_port32_instr_hdr_s cn58xx;
+	struct cvmx_npi_port32_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port33_instr_hdr {
+	uint64_t u64;
+	struct cvmx_npi_port33_instr_hdr_s {
+		uint64_t reserved_44_63:20;
+		uint64_t pbp:1;
+		uint64_t rsv_f:5;
+		uint64_t rparmode:2;
+		uint64_t rsv_e:1;
+		uint64_t rskp_len:7;
+		uint64_t rsv_d:6;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_c:5;
+		uint64_t par_mode:2;
+		uint64_t rsv_b:1;
+		uint64_t skp_len:7;
+		uint64_t rsv_a:6;
+	} s;
+	struct cvmx_npi_port33_instr_hdr_s cn31xx;
+	struct cvmx_npi_port33_instr_hdr_s cn38xx;
+	struct cvmx_npi_port33_instr_hdr_s cn38xxp2;
+	struct cvmx_npi_port33_instr_hdr_s cn50xx;
+	struct cvmx_npi_port33_instr_hdr_s cn58xx;
+	struct cvmx_npi_port33_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port34_instr_hdr {
+	uint64_t u64;
+	struct cvmx_npi_port34_instr_hdr_s {
+		uint64_t reserved_44_63:20;
+		uint64_t pbp:1;
+		uint64_t rsv_f:5;
+		uint64_t rparmode:2;
+		uint64_t rsv_e:1;
+		uint64_t rskp_len:7;
+		uint64_t rsv_d:6;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_c:5;
+		uint64_t par_mode:2;
+		uint64_t rsv_b:1;
+		uint64_t skp_len:7;
+		uint64_t rsv_a:6;
+	} s;
+	struct cvmx_npi_port34_instr_hdr_s cn38xx;
+	struct cvmx_npi_port34_instr_hdr_s cn38xxp2;
+	struct cvmx_npi_port34_instr_hdr_s cn58xx;
+	struct cvmx_npi_port34_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port35_instr_hdr {
+	uint64_t u64;
+	struct cvmx_npi_port35_instr_hdr_s {
+		uint64_t reserved_44_63:20;
+		uint64_t pbp:1;
+		uint64_t rsv_f:5;
+		uint64_t rparmode:2;
+		uint64_t rsv_e:1;
+		uint64_t rskp_len:7;
+		uint64_t rsv_d:6;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_c:5;
+		uint64_t par_mode:2;
+		uint64_t rsv_b:1;
+		uint64_t skp_len:7;
+		uint64_t rsv_a:6;
+	} s;
+	struct cvmx_npi_port35_instr_hdr_s cn38xx;
+	struct cvmx_npi_port35_instr_hdr_s cn38xxp2;
+	struct cvmx_npi_port35_instr_hdr_s cn58xx;
+	struct cvmx_npi_port35_instr_hdr_s cn58xxp1;
+};
+
+union cvmx_npi_port_bp_control {
+	uint64_t u64;
+	struct cvmx_npi_port_bp_control_s {
+		uint64_t reserved_8_63:56;
+		uint64_t bp_on:4;
+		uint64_t enb:4;
+	} s;
+	struct cvmx_npi_port_bp_control_s cn30xx;
+	struct cvmx_npi_port_bp_control_s cn31xx;
+	struct cvmx_npi_port_bp_control_s cn38xx;
+	struct cvmx_npi_port_bp_control_s cn38xxp2;
+	struct cvmx_npi_port_bp_control_s cn50xx;
+	struct cvmx_npi_port_bp_control_s cn58xx;
+	struct cvmx_npi_port_bp_control_s cn58xxp1;
+};
+
+union cvmx_npi_rsl_int_blocks {
+	uint64_t u64;
+	struct cvmx_npi_rsl_int_blocks_s {
+		uint64_t reserved_32_63:32;
+		uint64_t rint_31:1;
+		uint64_t iob:1;
+		uint64_t reserved_28_29:2;
+		uint64_t rint_27:1;
+		uint64_t rint_26:1;
+		uint64_t rint_25:1;
+		uint64_t rint_24:1;
+		uint64_t asx1:1;
+		uint64_t asx0:1;
+		uint64_t rint_21:1;
+		uint64_t pip:1;
+		uint64_t spx1:1;
+		uint64_t spx0:1;
+		uint64_t lmc:1;
+		uint64_t l2c:1;
+		uint64_t rint_15:1;
+		uint64_t reserved_13_14:2;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t rint_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npi:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} s;
+	struct cvmx_npi_rsl_int_blocks_cn30xx {
+		uint64_t reserved_32_63:32;
+		uint64_t rint_31:1;
+		uint64_t iob:1;
+		uint64_t rint_29:1;
+		uint64_t rint_28:1;
+		uint64_t rint_27:1;
+		uint64_t rint_26:1;
+		uint64_t rint_25:1;
+		uint64_t rint_24:1;
+		uint64_t asx1:1;
+		uint64_t asx0:1;
+		uint64_t rint_21:1;
+		uint64_t pip:1;
+		uint64_t spx1:1;
+		uint64_t spx0:1;
+		uint64_t lmc:1;
+		uint64_t l2c:1;
+		uint64_t rint_15:1;
+		uint64_t rint_14:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t rint_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npi:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} cn30xx;
+	struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx;
+	struct cvmx_npi_rsl_int_blocks_cn38xx {
+		uint64_t reserved_32_63:32;
+		uint64_t rint_31:1;
+		uint64_t iob:1;
+		uint64_t rint_29:1;
+		uint64_t rint_28:1;
+		uint64_t rint_27:1;
+		uint64_t rint_26:1;
+		uint64_t rint_25:1;
+		uint64_t rint_24:1;
+		uint64_t asx1:1;
+		uint64_t asx0:1;
+		uint64_t rint_21:1;
+		uint64_t pip:1;
+		uint64_t spx1:1;
+		uint64_t spx0:1;
+		uint64_t lmc:1;
+		uint64_t l2c:1;
+		uint64_t rint_15:1;
+		uint64_t rint_14:1;
+		uint64_t rint_13:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t rint_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npi:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} cn38xx;
+	struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2;
+	struct cvmx_npi_rsl_int_blocks_cn50xx {
+		uint64_t reserved_31_63:33;
+		uint64_t iob:1;
+		uint64_t lmc1:1;
+		uint64_t agl:1;
+		uint64_t reserved_24_27:4;
+		uint64_t asx1:1;
+		uint64_t asx0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t spx1:1;
+		uint64_t spx0:1;
+		uint64_t lmc:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t npi:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+	} cn50xx;
+	struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx;
+	struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1;
+};
+
+union cvmx_npi_size_inputx {
+	uint64_t u64;
+	struct cvmx_npi_size_inputx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t size:32;
+	} s;
+	struct cvmx_npi_size_inputx_s cn30xx;
+	struct cvmx_npi_size_inputx_s cn31xx;
+	struct cvmx_npi_size_inputx_s cn38xx;
+	struct cvmx_npi_size_inputx_s cn38xxp2;
+	struct cvmx_npi_size_inputx_s cn50xx;
+	struct cvmx_npi_size_inputx_s cn58xx;
+	struct cvmx_npi_size_inputx_s cn58xxp1;
+};
+
+union cvmx_npi_win_read_to {
+	uint64_t u64;
+	struct cvmx_npi_win_read_to_s {
+		uint64_t reserved_32_63:32;
+		uint64_t time:32;
+	} s;
+	struct cvmx_npi_win_read_to_s cn30xx;
+	struct cvmx_npi_win_read_to_s cn31xx;
+	struct cvmx_npi_win_read_to_s cn38xx;
+	struct cvmx_npi_win_read_to_s cn38xxp2;
+	struct cvmx_npi_win_read_to_s cn50xx;
+	struct cvmx_npi_win_read_to_s cn58xx;
+	struct cvmx_npi_win_read_to_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
new file mode 100644
index 0000000..90f8d65
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -0,0 +1,1645 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCI_DEFS_H__
+#define __CVMX_PCI_DEFS_H__
+
+#define CVMX_PCI_BAR1_INDEXX(offset) \
+	 (0x0000000000000100ull + (((offset) & 31) * 4))
+#define CVMX_PCI_BIST_REG \
+	 (0x00000000000001C0ull)
+#define CVMX_PCI_CFG00 \
+	 (0x0000000000000000ull)
+#define CVMX_PCI_CFG01 \
+	 (0x0000000000000004ull)
+#define CVMX_PCI_CFG02 \
+	 (0x0000000000000008ull)
+#define CVMX_PCI_CFG03 \
+	 (0x000000000000000Cull)
+#define CVMX_PCI_CFG04 \
+	 (0x0000000000000010ull)
+#define CVMX_PCI_CFG05 \
+	 (0x0000000000000014ull)
+#define CVMX_PCI_CFG06 \
+	 (0x0000000000000018ull)
+#define CVMX_PCI_CFG07 \
+	 (0x000000000000001Cull)
+#define CVMX_PCI_CFG08 \
+	 (0x0000000000000020ull)
+#define CVMX_PCI_CFG09 \
+	 (0x0000000000000024ull)
+#define CVMX_PCI_CFG10 \
+	 (0x0000000000000028ull)
+#define CVMX_PCI_CFG11 \
+	 (0x000000000000002Cull)
+#define CVMX_PCI_CFG12 \
+	 (0x0000000000000030ull)
+#define CVMX_PCI_CFG13 \
+	 (0x0000000000000034ull)
+#define CVMX_PCI_CFG15 \
+	 (0x000000000000003Cull)
+#define CVMX_PCI_CFG16 \
+	 (0x0000000000000040ull)
+#define CVMX_PCI_CFG17 \
+	 (0x0000000000000044ull)
+#define CVMX_PCI_CFG18 \
+	 (0x0000000000000048ull)
+#define CVMX_PCI_CFG19 \
+	 (0x000000000000004Cull)
+#define CVMX_PCI_CFG20 \
+	 (0x0000000000000050ull)
+#define CVMX_PCI_CFG21 \
+	 (0x0000000000000054ull)
+#define CVMX_PCI_CFG22 \
+	 (0x0000000000000058ull)
+#define CVMX_PCI_CFG56 \
+	 (0x00000000000000E0ull)
+#define CVMX_PCI_CFG57 \
+	 (0x00000000000000E4ull)
+#define CVMX_PCI_CFG58 \
+	 (0x00000000000000E8ull)
+#define CVMX_PCI_CFG59 \
+	 (0x00000000000000ECull)
+#define CVMX_PCI_CFG60 \
+	 (0x00000000000000F0ull)
+#define CVMX_PCI_CFG61 \
+	 (0x00000000000000F4ull)
+#define CVMX_PCI_CFG62 \
+	 (0x00000000000000F8ull)
+#define CVMX_PCI_CFG63 \
+	 (0x00000000000000FCull)
+#define CVMX_PCI_CNT_REG \
+	 (0x00000000000001B8ull)
+#define CVMX_PCI_CTL_STATUS_2 \
+	 (0x000000000000018Cull)
+#define CVMX_PCI_DBELL_0 \
+	 (0x0000000000000080ull)
+#define CVMX_PCI_DBELL_1 \
+	 (0x0000000000000088ull)
+#define CVMX_PCI_DBELL_2 \
+	 (0x0000000000000090ull)
+#define CVMX_PCI_DBELL_3 \
+	 (0x0000000000000098ull)
+#define CVMX_PCI_DBELL_X(offset) \
+	 (0x0000000000000080ull + (((offset) & 3) * 8))
+#define CVMX_PCI_DMA_CNT0 \
+	 (0x00000000000000A0ull)
+#define CVMX_PCI_DMA_CNT1 \
+	 (0x00000000000000A8ull)
+#define CVMX_PCI_DMA_CNTX(offset) \
+	 (0x00000000000000A0ull + (((offset) & 1) * 8))
+#define CVMX_PCI_DMA_INT_LEV0 \
+	 (0x00000000000000A4ull)
+#define CVMX_PCI_DMA_INT_LEV1 \
+	 (0x00000000000000ACull)
+#define CVMX_PCI_DMA_INT_LEVX(offset) \
+	 (0x00000000000000A4ull + (((offset) & 1) * 8))
+#define CVMX_PCI_DMA_TIME0 \
+	 (0x00000000000000B0ull)
+#define CVMX_PCI_DMA_TIME1 \
+	 (0x00000000000000B4ull)
+#define CVMX_PCI_DMA_TIMEX(offset) \
+	 (0x00000000000000B0ull + (((offset) & 1) * 4))
+#define CVMX_PCI_INSTR_COUNT0 \
+	 (0x0000000000000084ull)
+#define CVMX_PCI_INSTR_COUNT1 \
+	 (0x000000000000008Cull)
+#define CVMX_PCI_INSTR_COUNT2 \
+	 (0x0000000000000094ull)
+#define CVMX_PCI_INSTR_COUNT3 \
+	 (0x000000000000009Cull)
+#define CVMX_PCI_INSTR_COUNTX(offset) \
+	 (0x0000000000000084ull + (((offset) & 3) * 8))
+#define CVMX_PCI_INT_ENB \
+	 (0x0000000000000038ull)
+#define CVMX_PCI_INT_ENB2 \
+	 (0x00000000000001A0ull)
+#define CVMX_PCI_INT_SUM \
+	 (0x0000000000000030ull)
+#define CVMX_PCI_INT_SUM2 \
+	 (0x0000000000000198ull)
+#define CVMX_PCI_MSI_RCV \
+	 (0x00000000000000F0ull)
+#define CVMX_PCI_PKTS_SENT0 \
+	 (0x0000000000000040ull)
+#define CVMX_PCI_PKTS_SENT1 \
+	 (0x0000000000000050ull)
+#define CVMX_PCI_PKTS_SENT2 \
+	 (0x0000000000000060ull)
+#define CVMX_PCI_PKTS_SENT3 \
+	 (0x0000000000000070ull)
+#define CVMX_PCI_PKTS_SENTX(offset) \
+	 (0x0000000000000040ull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKTS_SENT_INT_LEV0 \
+	 (0x0000000000000048ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV1 \
+	 (0x0000000000000058ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV2 \
+	 (0x0000000000000068ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEV3 \
+	 (0x0000000000000078ull)
+#define CVMX_PCI_PKTS_SENT_INT_LEVX(offset) \
+	 (0x0000000000000048ull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKTS_SENT_TIME0 \
+	 (0x000000000000004Cull)
+#define CVMX_PCI_PKTS_SENT_TIME1 \
+	 (0x000000000000005Cull)
+#define CVMX_PCI_PKTS_SENT_TIME2 \
+	 (0x000000000000006Cull)
+#define CVMX_PCI_PKTS_SENT_TIME3 \
+	 (0x000000000000007Cull)
+#define CVMX_PCI_PKTS_SENT_TIMEX(offset) \
+	 (0x000000000000004Cull + (((offset) & 3) * 16))
+#define CVMX_PCI_PKT_CREDITS0 \
+	 (0x0000000000000044ull)
+#define CVMX_PCI_PKT_CREDITS1 \
+	 (0x0000000000000054ull)
+#define CVMX_PCI_PKT_CREDITS2 \
+	 (0x0000000000000064ull)
+#define CVMX_PCI_PKT_CREDITS3 \
+	 (0x0000000000000074ull)
+#define CVMX_PCI_PKT_CREDITSX(offset) \
+	 (0x0000000000000044ull + (((offset) & 3) * 16))
+#define CVMX_PCI_READ_CMD_6 \
+	 (0x0000000000000180ull)
+#define CVMX_PCI_READ_CMD_C \
+	 (0x0000000000000184ull)
+#define CVMX_PCI_READ_CMD_E \
+	 (0x0000000000000188ull)
+#define CVMX_PCI_READ_TIMEOUT \
+	 CVMX_ADD_IO_SEG(0x00011F00000000B0ull)
+#define CVMX_PCI_SCM_REG \
+	 (0x00000000000001A8ull)
+#define CVMX_PCI_TSR_REG \
+	 (0x00000000000001B0ull)
+#define CVMX_PCI_WIN_RD_ADDR \
+	 (0x0000000000000008ull)
+#define CVMX_PCI_WIN_RD_DATA \
+	 (0x0000000000000020ull)
+#define CVMX_PCI_WIN_WR_ADDR \
+	 (0x0000000000000000ull)
+#define CVMX_PCI_WIN_WR_DATA \
+	 (0x0000000000000010ull)
+#define CVMX_PCI_WIN_WR_MASK \
+	 (0x0000000000000018ull)
+
+union cvmx_pci_bar1_indexx {
+	uint32_t u32;
+	struct cvmx_pci_bar1_indexx_s {
+		uint32_t reserved_18_31:14;
+		uint32_t addr_idx:14;
+		uint32_t ca:1;
+		uint32_t end_swp:2;
+		uint32_t addr_v:1;
+	} s;
+	struct cvmx_pci_bar1_indexx_s cn30xx;
+	struct cvmx_pci_bar1_indexx_s cn31xx;
+	struct cvmx_pci_bar1_indexx_s cn38xx;
+	struct cvmx_pci_bar1_indexx_s cn38xxp2;
+	struct cvmx_pci_bar1_indexx_s cn50xx;
+	struct cvmx_pci_bar1_indexx_s cn58xx;
+	struct cvmx_pci_bar1_indexx_s cn58xxp1;
+};
+
+union cvmx_pci_bist_reg {
+	uint64_t u64;
+	struct cvmx_pci_bist_reg_s {
+		uint64_t reserved_10_63:54;
+		uint64_t rsp_bs:1;
+		uint64_t dma0_bs:1;
+		uint64_t cmd0_bs:1;
+		uint64_t cmd_bs:1;
+		uint64_t csr2p_bs:1;
+		uint64_t csrr_bs:1;
+		uint64_t rsp2p_bs:1;
+		uint64_t csr2n_bs:1;
+		uint64_t dat2n_bs:1;
+		uint64_t dbg2n_bs:1;
+	} s;
+	struct cvmx_pci_bist_reg_s cn50xx;
+};
+
+union cvmx_pci_cfg00 {
+	uint32_t u32;
+	struct cvmx_pci_cfg00_s {
+		uint32_t devid:16;
+		uint32_t vendid:16;
+	} s;
+	struct cvmx_pci_cfg00_s cn30xx;
+	struct cvmx_pci_cfg00_s cn31xx;
+	struct cvmx_pci_cfg00_s cn38xx;
+	struct cvmx_pci_cfg00_s cn38xxp2;
+	struct cvmx_pci_cfg00_s cn50xx;
+	struct cvmx_pci_cfg00_s cn58xx;
+	struct cvmx_pci_cfg00_s cn58xxp1;
+};
+
+union cvmx_pci_cfg01 {
+	uint32_t u32;
+	struct cvmx_pci_cfg01_s {
+		uint32_t dpe:1;
+		uint32_t sse:1;
+		uint32_t rma:1;
+		uint32_t rta:1;
+		uint32_t sta:1;
+		uint32_t devt:2;
+		uint32_t mdpe:1;
+		uint32_t fbb:1;
+		uint32_t reserved_22_22:1;
+		uint32_t m66:1;
+		uint32_t cle:1;
+		uint32_t i_stat:1;
+		uint32_t reserved_11_18:8;
+		uint32_t i_dis:1;
+		uint32_t fbbe:1;
+		uint32_t see:1;
+		uint32_t ads:1;
+		uint32_t pee:1;
+		uint32_t vps:1;
+		uint32_t mwice:1;
+		uint32_t scse:1;
+		uint32_t me:1;
+		uint32_t msae:1;
+		uint32_t isae:1;
+	} s;
+	struct cvmx_pci_cfg01_s cn30xx;
+	struct cvmx_pci_cfg01_s cn31xx;
+	struct cvmx_pci_cfg01_s cn38xx;
+	struct cvmx_pci_cfg01_s cn38xxp2;
+	struct cvmx_pci_cfg01_s cn50xx;
+	struct cvmx_pci_cfg01_s cn58xx;
+	struct cvmx_pci_cfg01_s cn58xxp1;
+};
+
+union cvmx_pci_cfg02 {
+	uint32_t u32;
+	struct cvmx_pci_cfg02_s {
+		uint32_t cc:24;
+		uint32_t rid:8;
+	} s;
+	struct cvmx_pci_cfg02_s cn30xx;
+	struct cvmx_pci_cfg02_s cn31xx;
+	struct cvmx_pci_cfg02_s cn38xx;
+	struct cvmx_pci_cfg02_s cn38xxp2;
+	struct cvmx_pci_cfg02_s cn50xx;
+	struct cvmx_pci_cfg02_s cn58xx;
+	struct cvmx_pci_cfg02_s cn58xxp1;
+};
+
+union cvmx_pci_cfg03 {
+	uint32_t u32;
+	struct cvmx_pci_cfg03_s {
+		uint32_t bcap:1;
+		uint32_t brb:1;
+		uint32_t reserved_28_29:2;
+		uint32_t bcod:4;
+		uint32_t ht:8;
+		uint32_t lt:8;
+		uint32_t cls:8;
+	} s;
+	struct cvmx_pci_cfg03_s cn30xx;
+	struct cvmx_pci_cfg03_s cn31xx;
+	struct cvmx_pci_cfg03_s cn38xx;
+	struct cvmx_pci_cfg03_s cn38xxp2;
+	struct cvmx_pci_cfg03_s cn50xx;
+	struct cvmx_pci_cfg03_s cn58xx;
+	struct cvmx_pci_cfg03_s cn58xxp1;
+};
+
+union cvmx_pci_cfg04 {
+	uint32_t u32;
+	struct cvmx_pci_cfg04_s {
+		uint32_t lbase:20;
+		uint32_t lbasez:8;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pci_cfg04_s cn30xx;
+	struct cvmx_pci_cfg04_s cn31xx;
+	struct cvmx_pci_cfg04_s cn38xx;
+	struct cvmx_pci_cfg04_s cn38xxp2;
+	struct cvmx_pci_cfg04_s cn50xx;
+	struct cvmx_pci_cfg04_s cn58xx;
+	struct cvmx_pci_cfg04_s cn58xxp1;
+};
+
+union cvmx_pci_cfg05 {
+	uint32_t u32;
+	struct cvmx_pci_cfg05_s {
+		uint32_t hbase:32;
+	} s;
+	struct cvmx_pci_cfg05_s cn30xx;
+	struct cvmx_pci_cfg05_s cn31xx;
+	struct cvmx_pci_cfg05_s cn38xx;
+	struct cvmx_pci_cfg05_s cn38xxp2;
+	struct cvmx_pci_cfg05_s cn50xx;
+	struct cvmx_pci_cfg05_s cn58xx;
+	struct cvmx_pci_cfg05_s cn58xxp1;
+};
+
+union cvmx_pci_cfg06 {
+	uint32_t u32;
+	struct cvmx_pci_cfg06_s {
+		uint32_t lbase:5;
+		uint32_t lbasez:23;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pci_cfg06_s cn30xx;
+	struct cvmx_pci_cfg06_s cn31xx;
+	struct cvmx_pci_cfg06_s cn38xx;
+	struct cvmx_pci_cfg06_s cn38xxp2;
+	struct cvmx_pci_cfg06_s cn50xx;
+	struct cvmx_pci_cfg06_s cn58xx;
+	struct cvmx_pci_cfg06_s cn58xxp1;
+};
+
+union cvmx_pci_cfg07 {
+	uint32_t u32;
+	struct cvmx_pci_cfg07_s {
+		uint32_t hbase:32;
+	} s;
+	struct cvmx_pci_cfg07_s cn30xx;
+	struct cvmx_pci_cfg07_s cn31xx;
+	struct cvmx_pci_cfg07_s cn38xx;
+	struct cvmx_pci_cfg07_s cn38xxp2;
+	struct cvmx_pci_cfg07_s cn50xx;
+	struct cvmx_pci_cfg07_s cn58xx;
+	struct cvmx_pci_cfg07_s cn58xxp1;
+};
+
+union cvmx_pci_cfg08 {
+	uint32_t u32;
+	struct cvmx_pci_cfg08_s {
+		uint32_t lbasez:28;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pci_cfg08_s cn30xx;
+	struct cvmx_pci_cfg08_s cn31xx;
+	struct cvmx_pci_cfg08_s cn38xx;
+	struct cvmx_pci_cfg08_s cn38xxp2;
+	struct cvmx_pci_cfg08_s cn50xx;
+	struct cvmx_pci_cfg08_s cn58xx;
+	struct cvmx_pci_cfg08_s cn58xxp1;
+};
+
+union cvmx_pci_cfg09 {
+	uint32_t u32;
+	struct cvmx_pci_cfg09_s {
+		uint32_t hbase:25;
+		uint32_t hbasez:7;
+	} s;
+	struct cvmx_pci_cfg09_s cn30xx;
+	struct cvmx_pci_cfg09_s cn31xx;
+	struct cvmx_pci_cfg09_s cn38xx;
+	struct cvmx_pci_cfg09_s cn38xxp2;
+	struct cvmx_pci_cfg09_s cn50xx;
+	struct cvmx_pci_cfg09_s cn58xx;
+	struct cvmx_pci_cfg09_s cn58xxp1;
+};
+
+union cvmx_pci_cfg10 {
+	uint32_t u32;
+	struct cvmx_pci_cfg10_s {
+		uint32_t cisp:32;
+	} s;
+	struct cvmx_pci_cfg10_s cn30xx;
+	struct cvmx_pci_cfg10_s cn31xx;
+	struct cvmx_pci_cfg10_s cn38xx;
+	struct cvmx_pci_cfg10_s cn38xxp2;
+	struct cvmx_pci_cfg10_s cn50xx;
+	struct cvmx_pci_cfg10_s cn58xx;
+	struct cvmx_pci_cfg10_s cn58xxp1;
+};
+
+union cvmx_pci_cfg11 {
+	uint32_t u32;
+	struct cvmx_pci_cfg11_s {
+		uint32_t ssid:16;
+		uint32_t ssvid:16;
+	} s;
+	struct cvmx_pci_cfg11_s cn30xx;
+	struct cvmx_pci_cfg11_s cn31xx;
+	struct cvmx_pci_cfg11_s cn38xx;
+	struct cvmx_pci_cfg11_s cn38xxp2;
+	struct cvmx_pci_cfg11_s cn50xx;
+	struct cvmx_pci_cfg11_s cn58xx;
+	struct cvmx_pci_cfg11_s cn58xxp1;
+};
+
+union cvmx_pci_cfg12 {
+	uint32_t u32;
+	struct cvmx_pci_cfg12_s {
+		uint32_t erbar:16;
+		uint32_t erbarz:5;
+		uint32_t reserved_1_10:10;
+		uint32_t erbar_en:1;
+	} s;
+	struct cvmx_pci_cfg12_s cn30xx;
+	struct cvmx_pci_cfg12_s cn31xx;
+	struct cvmx_pci_cfg12_s cn38xx;
+	struct cvmx_pci_cfg12_s cn38xxp2;
+	struct cvmx_pci_cfg12_s cn50xx;
+	struct cvmx_pci_cfg12_s cn58xx;
+	struct cvmx_pci_cfg12_s cn58xxp1;
+};
+
+union cvmx_pci_cfg13 {
+	uint32_t u32;
+	struct cvmx_pci_cfg13_s {
+		uint32_t reserved_8_31:24;
+		uint32_t cp:8;
+	} s;
+	struct cvmx_pci_cfg13_s cn30xx;
+	struct cvmx_pci_cfg13_s cn31xx;
+	struct cvmx_pci_cfg13_s cn38xx;
+	struct cvmx_pci_cfg13_s cn38xxp2;
+	struct cvmx_pci_cfg13_s cn50xx;
+	struct cvmx_pci_cfg13_s cn58xx;
+	struct cvmx_pci_cfg13_s cn58xxp1;
+};
+
+union cvmx_pci_cfg15 {
+	uint32_t u32;
+	struct cvmx_pci_cfg15_s {
+		uint32_t ml:8;
+		uint32_t mg:8;
+		uint32_t inta:8;
+		uint32_t il:8;
+	} s;
+	struct cvmx_pci_cfg15_s cn30xx;
+	struct cvmx_pci_cfg15_s cn31xx;
+	struct cvmx_pci_cfg15_s cn38xx;
+	struct cvmx_pci_cfg15_s cn38xxp2;
+	struct cvmx_pci_cfg15_s cn50xx;
+	struct cvmx_pci_cfg15_s cn58xx;
+	struct cvmx_pci_cfg15_s cn58xxp1;
+};
+
+union cvmx_pci_cfg16 {
+	uint32_t u32;
+	struct cvmx_pci_cfg16_s {
+		uint32_t trdnpr:1;
+		uint32_t trdard:1;
+		uint32_t rdsati:1;
+		uint32_t trdrs:1;
+		uint32_t trtae:1;
+		uint32_t twsei:1;
+		uint32_t twsen:1;
+		uint32_t twtae:1;
+		uint32_t tmae:1;
+		uint32_t tslte:3;
+		uint32_t tilt:4;
+		uint32_t pbe:12;
+		uint32_t dppmr:1;
+		uint32_t reserved_2_2:1;
+		uint32_t tswc:1;
+		uint32_t mltd:1;
+	} s;
+	struct cvmx_pci_cfg16_s cn30xx;
+	struct cvmx_pci_cfg16_s cn31xx;
+	struct cvmx_pci_cfg16_s cn38xx;
+	struct cvmx_pci_cfg16_s cn38xxp2;
+	struct cvmx_pci_cfg16_s cn50xx;
+	struct cvmx_pci_cfg16_s cn58xx;
+	struct cvmx_pci_cfg16_s cn58xxp1;
+};
+
+union cvmx_pci_cfg17 {
+	uint32_t u32;
+	struct cvmx_pci_cfg17_s {
+		uint32_t tscme:32;
+	} s;
+	struct cvmx_pci_cfg17_s cn30xx;
+	struct cvmx_pci_cfg17_s cn31xx;
+	struct cvmx_pci_cfg17_s cn38xx;
+	struct cvmx_pci_cfg17_s cn38xxp2;
+	struct cvmx_pci_cfg17_s cn50xx;
+	struct cvmx_pci_cfg17_s cn58xx;
+	struct cvmx_pci_cfg17_s cn58xxp1;
+};
+
+union cvmx_pci_cfg18 {
+	uint32_t u32;
+	struct cvmx_pci_cfg18_s {
+		uint32_t tdsrps:32;
+	} s;
+	struct cvmx_pci_cfg18_s cn30xx;
+	struct cvmx_pci_cfg18_s cn31xx;
+	struct cvmx_pci_cfg18_s cn38xx;
+	struct cvmx_pci_cfg18_s cn38xxp2;
+	struct cvmx_pci_cfg18_s cn50xx;
+	struct cvmx_pci_cfg18_s cn58xx;
+	struct cvmx_pci_cfg18_s cn58xxp1;
+};
+
+union cvmx_pci_cfg19 {
+	uint32_t u32;
+	struct cvmx_pci_cfg19_s {
+		uint32_t mrbcm:1;
+		uint32_t mrbci:1;
+		uint32_t mdwe:1;
+		uint32_t mdre:1;
+		uint32_t mdrimc:1;
+		uint32_t mdrrmc:3;
+		uint32_t tmes:8;
+		uint32_t teci:1;
+		uint32_t tmei:1;
+		uint32_t tmse:1;
+		uint32_t tmdpes:1;
+		uint32_t tmapes:1;
+		uint32_t reserved_9_10:2;
+		uint32_t tibcd:1;
+		uint32_t tibde:1;
+		uint32_t reserved_6_6:1;
+		uint32_t tidomc:1;
+		uint32_t tdomc:5;
+	} s;
+	struct cvmx_pci_cfg19_s cn30xx;
+	struct cvmx_pci_cfg19_s cn31xx;
+	struct cvmx_pci_cfg19_s cn38xx;
+	struct cvmx_pci_cfg19_s cn38xxp2;
+	struct cvmx_pci_cfg19_s cn50xx;
+	struct cvmx_pci_cfg19_s cn58xx;
+	struct cvmx_pci_cfg19_s cn58xxp1;
+};
+
+union cvmx_pci_cfg20 {
+	uint32_t u32;
+	struct cvmx_pci_cfg20_s {
+		uint32_t mdsp:32;
+	} s;
+	struct cvmx_pci_cfg20_s cn30xx;
+	struct cvmx_pci_cfg20_s cn31xx;
+	struct cvmx_pci_cfg20_s cn38xx;
+	struct cvmx_pci_cfg20_s cn38xxp2;
+	struct cvmx_pci_cfg20_s cn50xx;
+	struct cvmx_pci_cfg20_s cn58xx;
+	struct cvmx_pci_cfg20_s cn58xxp1;
+};
+
+union cvmx_pci_cfg21 {
+	uint32_t u32;
+	struct cvmx_pci_cfg21_s {
+		uint32_t scmre:32;
+	} s;
+	struct cvmx_pci_cfg21_s cn30xx;
+	struct cvmx_pci_cfg21_s cn31xx;
+	struct cvmx_pci_cfg21_s cn38xx;
+	struct cvmx_pci_cfg21_s cn38xxp2;
+	struct cvmx_pci_cfg21_s cn50xx;
+	struct cvmx_pci_cfg21_s cn58xx;
+	struct cvmx_pci_cfg21_s cn58xxp1;
+};
+
+union cvmx_pci_cfg22 {
+	uint32_t u32;
+	struct cvmx_pci_cfg22_s {
+		uint32_t mac:7;
+		uint32_t reserved_19_24:6;
+		uint32_t flush:1;
+		uint32_t mra:1;
+		uint32_t mtta:1;
+		uint32_t mrv:8;
+		uint32_t mttv:8;
+	} s;
+	struct cvmx_pci_cfg22_s cn30xx;
+	struct cvmx_pci_cfg22_s cn31xx;
+	struct cvmx_pci_cfg22_s cn38xx;
+	struct cvmx_pci_cfg22_s cn38xxp2;
+	struct cvmx_pci_cfg22_s cn50xx;
+	struct cvmx_pci_cfg22_s cn58xx;
+	struct cvmx_pci_cfg22_s cn58xxp1;
+};
+
+union cvmx_pci_cfg56 {
+	uint32_t u32;
+	struct cvmx_pci_cfg56_s {
+		uint32_t reserved_23_31:9;
+		uint32_t most:3;
+		uint32_t mmbc:2;
+		uint32_t roe:1;
+		uint32_t dpere:1;
+		uint32_t ncp:8;
+		uint32_t pxcid:8;
+	} s;
+	struct cvmx_pci_cfg56_s cn30xx;
+	struct cvmx_pci_cfg56_s cn31xx;
+	struct cvmx_pci_cfg56_s cn38xx;
+	struct cvmx_pci_cfg56_s cn38xxp2;
+	struct cvmx_pci_cfg56_s cn50xx;
+	struct cvmx_pci_cfg56_s cn58xx;
+	struct cvmx_pci_cfg56_s cn58xxp1;
+};
+
+union cvmx_pci_cfg57 {
+	uint32_t u32;
+	struct cvmx_pci_cfg57_s {
+		uint32_t reserved_30_31:2;
+		uint32_t scemr:1;
+		uint32_t mcrsd:3;
+		uint32_t mostd:3;
+		uint32_t mmrbcd:2;
+		uint32_t dc:1;
+		uint32_t usc:1;
+		uint32_t scd:1;
+		uint32_t m133:1;
+		uint32_t w64:1;
+		uint32_t bn:8;
+		uint32_t dn:5;
+		uint32_t fn:3;
+	} s;
+	struct cvmx_pci_cfg57_s cn30xx;
+	struct cvmx_pci_cfg57_s cn31xx;
+	struct cvmx_pci_cfg57_s cn38xx;
+	struct cvmx_pci_cfg57_s cn38xxp2;
+	struct cvmx_pci_cfg57_s cn50xx;
+	struct cvmx_pci_cfg57_s cn58xx;
+	struct cvmx_pci_cfg57_s cn58xxp1;
+};
+
+union cvmx_pci_cfg58 {
+	uint32_t u32;
+	struct cvmx_pci_cfg58_s {
+		uint32_t pmes:5;
+		uint32_t d2s:1;
+		uint32_t d1s:1;
+		uint32_t auxc:3;
+		uint32_t dsi:1;
+		uint32_t reserved_20_20:1;
+		uint32_t pmec:1;
+		uint32_t pcimiv:3;
+		uint32_t ncp:8;
+		uint32_t pmcid:8;
+	} s;
+	struct cvmx_pci_cfg58_s cn30xx;
+	struct cvmx_pci_cfg58_s cn31xx;
+	struct cvmx_pci_cfg58_s cn38xx;
+	struct cvmx_pci_cfg58_s cn38xxp2;
+	struct cvmx_pci_cfg58_s cn50xx;
+	struct cvmx_pci_cfg58_s cn58xx;
+	struct cvmx_pci_cfg58_s cn58xxp1;
+};
+
+union cvmx_pci_cfg59 {
+	uint32_t u32;
+	struct cvmx_pci_cfg59_s {
+		uint32_t pmdia:8;
+		uint32_t bpccen:1;
+		uint32_t bd3h:1;
+		uint32_t reserved_16_21:6;
+		uint32_t pmess:1;
+		uint32_t pmedsia:2;
+		uint32_t pmds:4;
+		uint32_t pmeens:1;
+		uint32_t reserved_2_7:6;
+		uint32_t ps:2;
+	} s;
+	struct cvmx_pci_cfg59_s cn30xx;
+	struct cvmx_pci_cfg59_s cn31xx;
+	struct cvmx_pci_cfg59_s cn38xx;
+	struct cvmx_pci_cfg59_s cn38xxp2;
+	struct cvmx_pci_cfg59_s cn50xx;
+	struct cvmx_pci_cfg59_s cn58xx;
+	struct cvmx_pci_cfg59_s cn58xxp1;
+};
+
+union cvmx_pci_cfg60 {
+	uint32_t u32;
+	struct cvmx_pci_cfg60_s {
+		uint32_t reserved_24_31:8;
+		uint32_t m64:1;
+		uint32_t mme:3;
+		uint32_t mmc:3;
+		uint32_t msien:1;
+		uint32_t ncp:8;
+		uint32_t msicid:8;
+	} s;
+	struct cvmx_pci_cfg60_s cn30xx;
+	struct cvmx_pci_cfg60_s cn31xx;
+	struct cvmx_pci_cfg60_s cn38xx;
+	struct cvmx_pci_cfg60_s cn38xxp2;
+	struct cvmx_pci_cfg60_s cn50xx;
+	struct cvmx_pci_cfg60_s cn58xx;
+	struct cvmx_pci_cfg60_s cn58xxp1;
+};
+
+union cvmx_pci_cfg61 {
+	uint32_t u32;
+	struct cvmx_pci_cfg61_s {
+		uint32_t msi31t2:30;
+		uint32_t reserved_0_1:2;
+	} s;
+	struct cvmx_pci_cfg61_s cn30xx;
+	struct cvmx_pci_cfg61_s cn31xx;
+	struct cvmx_pci_cfg61_s cn38xx;
+	struct cvmx_pci_cfg61_s cn38xxp2;
+	struct cvmx_pci_cfg61_s cn50xx;
+	struct cvmx_pci_cfg61_s cn58xx;
+	struct cvmx_pci_cfg61_s cn58xxp1;
+};
+
+union cvmx_pci_cfg62 {
+	uint32_t u32;
+	struct cvmx_pci_cfg62_s {
+		uint32_t msi:32;
+	} s;
+	struct cvmx_pci_cfg62_s cn30xx;
+	struct cvmx_pci_cfg62_s cn31xx;
+	struct cvmx_pci_cfg62_s cn38xx;
+	struct cvmx_pci_cfg62_s cn38xxp2;
+	struct cvmx_pci_cfg62_s cn50xx;
+	struct cvmx_pci_cfg62_s cn58xx;
+	struct cvmx_pci_cfg62_s cn58xxp1;
+};
+
+union cvmx_pci_cfg63 {
+	uint32_t u32;
+	struct cvmx_pci_cfg63_s {
+		uint32_t reserved_16_31:16;
+		uint32_t msimd:16;
+	} s;
+	struct cvmx_pci_cfg63_s cn30xx;
+	struct cvmx_pci_cfg63_s cn31xx;
+	struct cvmx_pci_cfg63_s cn38xx;
+	struct cvmx_pci_cfg63_s cn38xxp2;
+	struct cvmx_pci_cfg63_s cn50xx;
+	struct cvmx_pci_cfg63_s cn58xx;
+	struct cvmx_pci_cfg63_s cn58xxp1;
+};
+
+union cvmx_pci_cnt_reg {
+	uint64_t u64;
+	struct cvmx_pci_cnt_reg_s {
+		uint64_t reserved_38_63:26;
+		uint64_t hm_pcix:1;
+		uint64_t hm_speed:2;
+		uint64_t ap_pcix:1;
+		uint64_t ap_speed:2;
+		uint64_t pcicnt:32;
+	} s;
+	struct cvmx_pci_cnt_reg_s cn50xx;
+	struct cvmx_pci_cnt_reg_s cn58xx;
+	struct cvmx_pci_cnt_reg_s cn58xxp1;
+};
+
+union cvmx_pci_ctl_status_2 {
+	uint32_t u32;
+	struct cvmx_pci_ctl_status_2_s {
+		uint32_t reserved_29_31:3;
+		uint32_t bb1_hole:3;
+		uint32_t bb1_siz:1;
+		uint32_t bb_ca:1;
+		uint32_t bb_es:2;
+		uint32_t bb1:1;
+		uint32_t bb0:1;
+		uint32_t erst_n:1;
+		uint32_t bar2pres:1;
+		uint32_t scmtyp:1;
+		uint32_t scm:1;
+		uint32_t en_wfilt:1;
+		uint32_t reserved_14_14:1;
+		uint32_t ap_pcix:1;
+		uint32_t ap_64ad:1;
+		uint32_t b12_bist:1;
+		uint32_t pmo_amod:1;
+		uint32_t pmo_fpc:3;
+		uint32_t tsr_hwm:3;
+		uint32_t bar2_enb:1;
+		uint32_t bar2_esx:2;
+		uint32_t bar2_cax:1;
+	} s;
+	struct cvmx_pci_ctl_status_2_s cn30xx;
+	struct cvmx_pci_ctl_status_2_cn31xx {
+		uint32_t reserved_20_31:12;
+		uint32_t erst_n:1;
+		uint32_t bar2pres:1;
+		uint32_t scmtyp:1;
+		uint32_t scm:1;
+		uint32_t en_wfilt:1;
+		uint32_t reserved_14_14:1;
+		uint32_t ap_pcix:1;
+		uint32_t ap_64ad:1;
+		uint32_t b12_bist:1;
+		uint32_t pmo_amod:1;
+		uint32_t pmo_fpc:3;
+		uint32_t tsr_hwm:3;
+		uint32_t bar2_enb:1;
+		uint32_t bar2_esx:2;
+		uint32_t bar2_cax:1;
+	} cn31xx;
+	struct cvmx_pci_ctl_status_2_s cn38xx;
+	struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2;
+	struct cvmx_pci_ctl_status_2_s cn50xx;
+	struct cvmx_pci_ctl_status_2_s cn58xx;
+	struct cvmx_pci_ctl_status_2_s cn58xxp1;
+};
+
+union cvmx_pci_dbellx {
+	uint32_t u32;
+	struct cvmx_pci_dbellx_s {
+		uint32_t reserved_16_31:16;
+		uint32_t inc_val:16;
+	} s;
+	struct cvmx_pci_dbellx_s cn30xx;
+	struct cvmx_pci_dbellx_s cn31xx;
+	struct cvmx_pci_dbellx_s cn38xx;
+	struct cvmx_pci_dbellx_s cn38xxp2;
+	struct cvmx_pci_dbellx_s cn50xx;
+	struct cvmx_pci_dbellx_s cn58xx;
+	struct cvmx_pci_dbellx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_cntx {
+	uint32_t u32;
+	struct cvmx_pci_dma_cntx_s {
+		uint32_t dma_cnt:32;
+	} s;
+	struct cvmx_pci_dma_cntx_s cn30xx;
+	struct cvmx_pci_dma_cntx_s cn31xx;
+	struct cvmx_pci_dma_cntx_s cn38xx;
+	struct cvmx_pci_dma_cntx_s cn38xxp2;
+	struct cvmx_pci_dma_cntx_s cn50xx;
+	struct cvmx_pci_dma_cntx_s cn58xx;
+	struct cvmx_pci_dma_cntx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_int_levx {
+	uint32_t u32;
+	struct cvmx_pci_dma_int_levx_s {
+		uint32_t pkt_cnt:32;
+	} s;
+	struct cvmx_pci_dma_int_levx_s cn30xx;
+	struct cvmx_pci_dma_int_levx_s cn31xx;
+	struct cvmx_pci_dma_int_levx_s cn38xx;
+	struct cvmx_pci_dma_int_levx_s cn38xxp2;
+	struct cvmx_pci_dma_int_levx_s cn50xx;
+	struct cvmx_pci_dma_int_levx_s cn58xx;
+	struct cvmx_pci_dma_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_dma_timex {
+	uint32_t u32;
+	struct cvmx_pci_dma_timex_s {
+		uint32_t dma_time:32;
+	} s;
+	struct cvmx_pci_dma_timex_s cn30xx;
+	struct cvmx_pci_dma_timex_s cn31xx;
+	struct cvmx_pci_dma_timex_s cn38xx;
+	struct cvmx_pci_dma_timex_s cn38xxp2;
+	struct cvmx_pci_dma_timex_s cn50xx;
+	struct cvmx_pci_dma_timex_s cn58xx;
+	struct cvmx_pci_dma_timex_s cn58xxp1;
+};
+
+union cvmx_pci_instr_countx {
+	uint32_t u32;
+	struct cvmx_pci_instr_countx_s {
+		uint32_t icnt:32;
+	} s;
+	struct cvmx_pci_instr_countx_s cn30xx;
+	struct cvmx_pci_instr_countx_s cn31xx;
+	struct cvmx_pci_instr_countx_s cn38xx;
+	struct cvmx_pci_instr_countx_s cn38xxp2;
+	struct cvmx_pci_instr_countx_s cn50xx;
+	struct cvmx_pci_instr_countx_s cn58xx;
+	struct cvmx_pci_instr_countx_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb {
+	uint64_t u64;
+	struct cvmx_pci_int_enb_s {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t idtime1:1;
+		uint64_t idtime0:1;
+		uint64_t idcnt1:1;
+		uint64_t idcnt0:1;
+		uint64_t iptime3:1;
+		uint64_t iptime2:1;
+		uint64_t iptime1:1;
+		uint64_t iptime0:1;
+		uint64_t ipcnt3:1;
+		uint64_t ipcnt2:1;
+		uint64_t ipcnt1:1;
+		uint64_t ipcnt0:1;
+		uint64_t irsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t idperr:1;
+		uint64_t iaperr:1;
+		uint64_t iserr:1;
+		uint64_t itsr_abt:1;
+		uint64_t imsc_msg:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_per:1;
+		uint64_t imr_tto:1;
+		uint64_t imr_abt:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_wtto:1;
+		uint64_t imr_wabt:1;
+		uint64_t itr_wabt:1;
+	} s;
+	struct cvmx_pci_int_enb_cn30xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t idtime1:1;
+		uint64_t idtime0:1;
+		uint64_t idcnt1:1;
+		uint64_t idcnt0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t iptime0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t ipcnt0:1;
+		uint64_t irsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t idperr:1;
+		uint64_t iaperr:1;
+		uint64_t iserr:1;
+		uint64_t itsr_abt:1;
+		uint64_t imsc_msg:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_per:1;
+		uint64_t imr_tto:1;
+		uint64_t imr_abt:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_wtto:1;
+		uint64_t imr_wabt:1;
+		uint64_t itr_wabt:1;
+	} cn30xx;
+	struct cvmx_pci_int_enb_cn31xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t idtime1:1;
+		uint64_t idtime0:1;
+		uint64_t idcnt1:1;
+		uint64_t idcnt0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t iptime1:1;
+		uint64_t iptime0:1;
+		uint64_t reserved_19_20:2;
+		uint64_t ipcnt1:1;
+		uint64_t ipcnt0:1;
+		uint64_t irsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t idperr:1;
+		uint64_t iaperr:1;
+		uint64_t iserr:1;
+		uint64_t itsr_abt:1;
+		uint64_t imsc_msg:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_per:1;
+		uint64_t imr_tto:1;
+		uint64_t imr_abt:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_wtto:1;
+		uint64_t imr_wabt:1;
+		uint64_t itr_wabt:1;
+	} cn31xx;
+	struct cvmx_pci_int_enb_s cn38xx;
+	struct cvmx_pci_int_enb_s cn38xxp2;
+	struct cvmx_pci_int_enb_cn31xx cn50xx;
+	struct cvmx_pci_int_enb_s cn58xx;
+	struct cvmx_pci_int_enb_s cn58xxp1;
+};
+
+union cvmx_pci_int_enb2 {
+	uint64_t u64;
+	struct cvmx_pci_int_enb2_s {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t rdtime1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdcnt0:1;
+		uint64_t rptime3:1;
+		uint64_t rptime2:1;
+		uint64_t rptime1:1;
+		uint64_t rptime0:1;
+		uint64_t rpcnt3:1;
+		uint64_t rpcnt2:1;
+		uint64_t rpcnt1:1;
+		uint64_t rpcnt0:1;
+		uint64_t rrsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t rdperr:1;
+		uint64_t raperr:1;
+		uint64_t rserr:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmr_abt:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rtr_wabt:1;
+	} s;
+	struct cvmx_pci_int_enb2_cn30xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t rdtime1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdcnt0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t rptime0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t rpcnt0:1;
+		uint64_t rrsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t rdperr:1;
+		uint64_t raperr:1;
+		uint64_t rserr:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmr_abt:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rtr_wabt:1;
+	} cn30xx;
+	struct cvmx_pci_int_enb2_cn31xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t rdtime1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdcnt0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t rptime1:1;
+		uint64_t rptime0:1;
+		uint64_t reserved_19_20:2;
+		uint64_t rpcnt1:1;
+		uint64_t rpcnt0:1;
+		uint64_t rrsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t rdperr:1;
+		uint64_t raperr:1;
+		uint64_t rserr:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmr_abt:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rtr_wabt:1;
+	} cn31xx;
+	struct cvmx_pci_int_enb2_s cn38xx;
+	struct cvmx_pci_int_enb2_s cn38xxp2;
+	struct cvmx_pci_int_enb2_cn31xx cn50xx;
+	struct cvmx_pci_int_enb2_s cn58xx;
+	struct cvmx_pci_int_enb2_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum {
+	uint64_t u64;
+	struct cvmx_pci_int_sum_s {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t ptime3:1;
+		uint64_t ptime2:1;
+		uint64_t ptime1:1;
+		uint64_t ptime0:1;
+		uint64_t pcnt3:1;
+		uint64_t pcnt2:1;
+		uint64_t pcnt1:1;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} s;
+	struct cvmx_pci_int_sum_cn30xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t ptime0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} cn30xx;
+	struct cvmx_pci_int_sum_cn31xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t ptime1:1;
+		uint64_t ptime0:1;
+		uint64_t reserved_19_20:2;
+		uint64_t pcnt1:1;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} cn31xx;
+	struct cvmx_pci_int_sum_s cn38xx;
+	struct cvmx_pci_int_sum_s cn38xxp2;
+	struct cvmx_pci_int_sum_cn31xx cn50xx;
+	struct cvmx_pci_int_sum_s cn58xx;
+	struct cvmx_pci_int_sum_s cn58xxp1;
+};
+
+union cvmx_pci_int_sum2 {
+	uint64_t u64;
+	struct cvmx_pci_int_sum2_s {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t ptime3:1;
+		uint64_t ptime2:1;
+		uint64_t ptime1:1;
+		uint64_t ptime0:1;
+		uint64_t pcnt3:1;
+		uint64_t pcnt2:1;
+		uint64_t pcnt1:1;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} s;
+	struct cvmx_pci_int_sum2_cn30xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t ptime0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} cn30xx;
+	struct cvmx_pci_int_sum2_cn31xx {
+		uint64_t reserved_34_63:30;
+		uint64_t ill_rd:1;
+		uint64_t ill_wr:1;
+		uint64_t win_wr:1;
+		uint64_t dma1_fi:1;
+		uint64_t dma0_fi:1;
+		uint64_t dtime1:1;
+		uint64_t dtime0:1;
+		uint64_t dcnt1:1;
+		uint64_t dcnt0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t ptime1:1;
+		uint64_t ptime0:1;
+		uint64_t reserved_19_20:2;
+		uint64_t pcnt1:1;
+		uint64_t pcnt0:1;
+		uint64_t rsl_int:1;
+		uint64_t ill_rrd:1;
+		uint64_t ill_rwr:1;
+		uint64_t dperr:1;
+		uint64_t aperr:1;
+		uint64_t serr:1;
+		uint64_t tsr_abt:1;
+		uint64_t msc_msg:1;
+		uint64_t msi_mabt:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_per:1;
+		uint64_t mr_tto:1;
+		uint64_t mr_abt:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_wtto:1;
+		uint64_t mr_wabt:1;
+		uint64_t tr_wabt:1;
+	} cn31xx;
+	struct cvmx_pci_int_sum2_s cn38xx;
+	struct cvmx_pci_int_sum2_s cn38xxp2;
+	struct cvmx_pci_int_sum2_cn31xx cn50xx;
+	struct cvmx_pci_int_sum2_s cn58xx;
+	struct cvmx_pci_int_sum2_s cn58xxp1;
+};
+
+union cvmx_pci_msi_rcv {
+	uint32_t u32;
+	struct cvmx_pci_msi_rcv_s {
+		uint32_t reserved_6_31:26;
+		uint32_t intr:6;
+	} s;
+	struct cvmx_pci_msi_rcv_s cn30xx;
+	struct cvmx_pci_msi_rcv_s cn31xx;
+	struct cvmx_pci_msi_rcv_s cn38xx;
+	struct cvmx_pci_msi_rcv_s cn38xxp2;
+	struct cvmx_pci_msi_rcv_s cn50xx;
+	struct cvmx_pci_msi_rcv_s cn58xx;
+	struct cvmx_pci_msi_rcv_s cn58xxp1;
+};
+
+union cvmx_pci_pkt_creditsx {
+	uint32_t u32;
+	struct cvmx_pci_pkt_creditsx_s {
+		uint32_t pkt_cnt:16;
+		uint32_t ptr_cnt:16;
+	} s;
+	struct cvmx_pci_pkt_creditsx_s cn30xx;
+	struct cvmx_pci_pkt_creditsx_s cn31xx;
+	struct cvmx_pci_pkt_creditsx_s cn38xx;
+	struct cvmx_pci_pkt_creditsx_s cn38xxp2;
+	struct cvmx_pci_pkt_creditsx_s cn50xx;
+	struct cvmx_pci_pkt_creditsx_s cn58xx;
+	struct cvmx_pci_pkt_creditsx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sentx {
+	uint32_t u32;
+	struct cvmx_pci_pkts_sentx_s {
+		uint32_t pkt_cnt:32;
+	} s;
+	struct cvmx_pci_pkts_sentx_s cn30xx;
+	struct cvmx_pci_pkts_sentx_s cn31xx;
+	struct cvmx_pci_pkts_sentx_s cn38xx;
+	struct cvmx_pci_pkts_sentx_s cn38xxp2;
+	struct cvmx_pci_pkts_sentx_s cn50xx;
+	struct cvmx_pci_pkts_sentx_s cn58xx;
+	struct cvmx_pci_pkts_sentx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_int_levx {
+	uint32_t u32;
+	struct cvmx_pci_pkts_sent_int_levx_s {
+		uint32_t pkt_cnt:32;
+	} s;
+	struct cvmx_pci_pkts_sent_int_levx_s cn30xx;
+	struct cvmx_pci_pkts_sent_int_levx_s cn31xx;
+	struct cvmx_pci_pkts_sent_int_levx_s cn38xx;
+	struct cvmx_pci_pkts_sent_int_levx_s cn38xxp2;
+	struct cvmx_pci_pkts_sent_int_levx_s cn50xx;
+	struct cvmx_pci_pkts_sent_int_levx_s cn58xx;
+	struct cvmx_pci_pkts_sent_int_levx_s cn58xxp1;
+};
+
+union cvmx_pci_pkts_sent_timex {
+	uint32_t u32;
+	struct cvmx_pci_pkts_sent_timex_s {
+		uint32_t pkt_time:32;
+	} s;
+	struct cvmx_pci_pkts_sent_timex_s cn30xx;
+	struct cvmx_pci_pkts_sent_timex_s cn31xx;
+	struct cvmx_pci_pkts_sent_timex_s cn38xx;
+	struct cvmx_pci_pkts_sent_timex_s cn38xxp2;
+	struct cvmx_pci_pkts_sent_timex_s cn50xx;
+	struct cvmx_pci_pkts_sent_timex_s cn58xx;
+	struct cvmx_pci_pkts_sent_timex_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_6 {
+	uint32_t u32;
+	struct cvmx_pci_read_cmd_6_s {
+		uint32_t reserved_9_31:23;
+		uint32_t min_data:6;
+		uint32_t prefetch:3;
+	} s;
+	struct cvmx_pci_read_cmd_6_s cn30xx;
+	struct cvmx_pci_read_cmd_6_s cn31xx;
+	struct cvmx_pci_read_cmd_6_s cn38xx;
+	struct cvmx_pci_read_cmd_6_s cn38xxp2;
+	struct cvmx_pci_read_cmd_6_s cn50xx;
+	struct cvmx_pci_read_cmd_6_s cn58xx;
+	struct cvmx_pci_read_cmd_6_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_c {
+	uint32_t u32;
+	struct cvmx_pci_read_cmd_c_s {
+		uint32_t reserved_9_31:23;
+		uint32_t min_data:6;
+		uint32_t prefetch:3;
+	} s;
+	struct cvmx_pci_read_cmd_c_s cn30xx;
+	struct cvmx_pci_read_cmd_c_s cn31xx;
+	struct cvmx_pci_read_cmd_c_s cn38xx;
+	struct cvmx_pci_read_cmd_c_s cn38xxp2;
+	struct cvmx_pci_read_cmd_c_s cn50xx;
+	struct cvmx_pci_read_cmd_c_s cn58xx;
+	struct cvmx_pci_read_cmd_c_s cn58xxp1;
+};
+
+union cvmx_pci_read_cmd_e {
+	uint32_t u32;
+	struct cvmx_pci_read_cmd_e_s {
+		uint32_t reserved_9_31:23;
+		uint32_t min_data:6;
+		uint32_t prefetch:3;
+	} s;
+	struct cvmx_pci_read_cmd_e_s cn30xx;
+	struct cvmx_pci_read_cmd_e_s cn31xx;
+	struct cvmx_pci_read_cmd_e_s cn38xx;
+	struct cvmx_pci_read_cmd_e_s cn38xxp2;
+	struct cvmx_pci_read_cmd_e_s cn50xx;
+	struct cvmx_pci_read_cmd_e_s cn58xx;
+	struct cvmx_pci_read_cmd_e_s cn58xxp1;
+};
+
+union cvmx_pci_read_timeout {
+	uint64_t u64;
+	struct cvmx_pci_read_timeout_s {
+		uint64_t reserved_32_63:32;
+		uint64_t enb:1;
+		uint64_t cnt:31;
+	} s;
+	struct cvmx_pci_read_timeout_s cn30xx;
+	struct cvmx_pci_read_timeout_s cn31xx;
+	struct cvmx_pci_read_timeout_s cn38xx;
+	struct cvmx_pci_read_timeout_s cn38xxp2;
+	struct cvmx_pci_read_timeout_s cn50xx;
+	struct cvmx_pci_read_timeout_s cn58xx;
+	struct cvmx_pci_read_timeout_s cn58xxp1;
+};
+
+union cvmx_pci_scm_reg {
+	uint64_t u64;
+	struct cvmx_pci_scm_reg_s {
+		uint64_t reserved_32_63:32;
+		uint64_t scm:32;
+	} s;
+	struct cvmx_pci_scm_reg_s cn30xx;
+	struct cvmx_pci_scm_reg_s cn31xx;
+	struct cvmx_pci_scm_reg_s cn38xx;
+	struct cvmx_pci_scm_reg_s cn38xxp2;
+	struct cvmx_pci_scm_reg_s cn50xx;
+	struct cvmx_pci_scm_reg_s cn58xx;
+	struct cvmx_pci_scm_reg_s cn58xxp1;
+};
+
+union cvmx_pci_tsr_reg {
+	uint64_t u64;
+	struct cvmx_pci_tsr_reg_s {
+		uint64_t reserved_36_63:28;
+		uint64_t tsr:36;
+	} s;
+	struct cvmx_pci_tsr_reg_s cn30xx;
+	struct cvmx_pci_tsr_reg_s cn31xx;
+	struct cvmx_pci_tsr_reg_s cn38xx;
+	struct cvmx_pci_tsr_reg_s cn38xxp2;
+	struct cvmx_pci_tsr_reg_s cn50xx;
+	struct cvmx_pci_tsr_reg_s cn58xx;
+	struct cvmx_pci_tsr_reg_s cn58xxp1;
+};
+
+union cvmx_pci_win_rd_addr {
+	uint64_t u64;
+	struct cvmx_pci_win_rd_addr_s {
+		uint64_t reserved_49_63:15;
+		uint64_t iobit:1;
+		uint64_t reserved_0_47:48;
+	} s;
+	struct cvmx_pci_win_rd_addr_cn30xx {
+		uint64_t reserved_49_63:15;
+		uint64_t iobit:1;
+		uint64_t rd_addr:46;
+		uint64_t reserved_0_1:2;
+	} cn30xx;
+	struct cvmx_pci_win_rd_addr_cn30xx cn31xx;
+	struct cvmx_pci_win_rd_addr_cn38xx {
+		uint64_t reserved_49_63:15;
+		uint64_t iobit:1;
+		uint64_t rd_addr:45;
+		uint64_t reserved_0_2:3;
+	} cn38xx;
+	struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2;
+	struct cvmx_pci_win_rd_addr_cn30xx cn50xx;
+	struct cvmx_pci_win_rd_addr_cn38xx cn58xx;
+	struct cvmx_pci_win_rd_addr_cn38xx cn58xxp1;
+};
+
+union cvmx_pci_win_rd_data {
+	uint64_t u64;
+	struct cvmx_pci_win_rd_data_s {
+		uint64_t rd_data:64;
+	} s;
+	struct cvmx_pci_win_rd_data_s cn30xx;
+	struct cvmx_pci_win_rd_data_s cn31xx;
+	struct cvmx_pci_win_rd_data_s cn38xx;
+	struct cvmx_pci_win_rd_data_s cn38xxp2;
+	struct cvmx_pci_win_rd_data_s cn50xx;
+	struct cvmx_pci_win_rd_data_s cn58xx;
+	struct cvmx_pci_win_rd_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_addr {
+	uint64_t u64;
+	struct cvmx_pci_win_wr_addr_s {
+		uint64_t reserved_49_63:15;
+		uint64_t iobit:1;
+		uint64_t wr_addr:45;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_pci_win_wr_addr_s cn30xx;
+	struct cvmx_pci_win_wr_addr_s cn31xx;
+	struct cvmx_pci_win_wr_addr_s cn38xx;
+	struct cvmx_pci_win_wr_addr_s cn38xxp2;
+	struct cvmx_pci_win_wr_addr_s cn50xx;
+	struct cvmx_pci_win_wr_addr_s cn58xx;
+	struct cvmx_pci_win_wr_addr_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_data {
+	uint64_t u64;
+	struct cvmx_pci_win_wr_data_s {
+		uint64_t wr_data:64;
+	} s;
+	struct cvmx_pci_win_wr_data_s cn30xx;
+	struct cvmx_pci_win_wr_data_s cn31xx;
+	struct cvmx_pci_win_wr_data_s cn38xx;
+	struct cvmx_pci_win_wr_data_s cn38xxp2;
+	struct cvmx_pci_win_wr_data_s cn50xx;
+	struct cvmx_pci_win_wr_data_s cn58xx;
+	struct cvmx_pci_win_wr_data_s cn58xxp1;
+};
+
+union cvmx_pci_win_wr_mask {
+	uint64_t u64;
+	struct cvmx_pci_win_wr_mask_s {
+		uint64_t reserved_8_63:56;
+		uint64_t wr_mask:8;
+	} s;
+	struct cvmx_pci_win_wr_mask_s cn30xx;
+	struct cvmx_pci_win_wr_mask_s cn31xx;
+	struct cvmx_pci_win_wr_mask_s cn38xx;
+	struct cvmx_pci_win_wr_mask_s cn38xxp2;
+	struct cvmx_pci_win_wr_mask_s cn50xx;
+	struct cvmx_pci_win_wr_mask_s cn58xx;
+	struct cvmx_pci_win_wr_mask_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
new file mode 100644
index 0000000..d553f8e
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pcieep-defs.h
@@ -0,0 +1,1365 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIEEP_DEFS_H__
+#define __CVMX_PCIEEP_DEFS_H__
+
+#define CVMX_PCIEEP_CFG000 \
+	 (0x0000000000000000ull)
+#define CVMX_PCIEEP_CFG001 \
+	 (0x0000000000000004ull)
+#define CVMX_PCIEEP_CFG002 \
+	 (0x0000000000000008ull)
+#define CVMX_PCIEEP_CFG003 \
+	 (0x000000000000000Cull)
+#define CVMX_PCIEEP_CFG004 \
+	 (0x0000000000000010ull)
+#define CVMX_PCIEEP_CFG004_MASK \
+	 (0x0000000080000010ull)
+#define CVMX_PCIEEP_CFG005 \
+	 (0x0000000000000014ull)
+#define CVMX_PCIEEP_CFG005_MASK \
+	 (0x0000000080000014ull)
+#define CVMX_PCIEEP_CFG006 \
+	 (0x0000000000000018ull)
+#define CVMX_PCIEEP_CFG006_MASK \
+	 (0x0000000080000018ull)
+#define CVMX_PCIEEP_CFG007 \
+	 (0x000000000000001Cull)
+#define CVMX_PCIEEP_CFG007_MASK \
+	 (0x000000008000001Cull)
+#define CVMX_PCIEEP_CFG008 \
+	 (0x0000000000000020ull)
+#define CVMX_PCIEEP_CFG008_MASK \
+	 (0x0000000080000020ull)
+#define CVMX_PCIEEP_CFG009 \
+	 (0x0000000000000024ull)
+#define CVMX_PCIEEP_CFG009_MASK \
+	 (0x0000000080000024ull)
+#define CVMX_PCIEEP_CFG010 \
+	 (0x0000000000000028ull)
+#define CVMX_PCIEEP_CFG011 \
+	 (0x000000000000002Cull)
+#define CVMX_PCIEEP_CFG012 \
+	 (0x0000000000000030ull)
+#define CVMX_PCIEEP_CFG012_MASK \
+	 (0x0000000080000030ull)
+#define CVMX_PCIEEP_CFG013 \
+	 (0x0000000000000034ull)
+#define CVMX_PCIEEP_CFG015 \
+	 (0x000000000000003Cull)
+#define CVMX_PCIEEP_CFG016 \
+	 (0x0000000000000040ull)
+#define CVMX_PCIEEP_CFG017 \
+	 (0x0000000000000044ull)
+#define CVMX_PCIEEP_CFG020 \
+	 (0x0000000000000050ull)
+#define CVMX_PCIEEP_CFG021 \
+	 (0x0000000000000054ull)
+#define CVMX_PCIEEP_CFG022 \
+	 (0x0000000000000058ull)
+#define CVMX_PCIEEP_CFG023 \
+	 (0x000000000000005Cull)
+#define CVMX_PCIEEP_CFG028 \
+	 (0x0000000000000070ull)
+#define CVMX_PCIEEP_CFG029 \
+	 (0x0000000000000074ull)
+#define CVMX_PCIEEP_CFG030 \
+	 (0x0000000000000078ull)
+#define CVMX_PCIEEP_CFG031 \
+	 (0x000000000000007Cull)
+#define CVMX_PCIEEP_CFG032 \
+	 (0x0000000000000080ull)
+#define CVMX_PCIEEP_CFG033 \
+	 (0x0000000000000084ull)
+#define CVMX_PCIEEP_CFG034 \
+	 (0x0000000000000088ull)
+#define CVMX_PCIEEP_CFG037 \
+	 (0x0000000000000094ull)
+#define CVMX_PCIEEP_CFG038 \
+	 (0x0000000000000098ull)
+#define CVMX_PCIEEP_CFG039 \
+	 (0x000000000000009Cull)
+#define CVMX_PCIEEP_CFG040 \
+	 (0x00000000000000A0ull)
+#define CVMX_PCIEEP_CFG041 \
+	 (0x00000000000000A4ull)
+#define CVMX_PCIEEP_CFG042 \
+	 (0x00000000000000A8ull)
+#define CVMX_PCIEEP_CFG064 \
+	 (0x0000000000000100ull)
+#define CVMX_PCIEEP_CFG065 \
+	 (0x0000000000000104ull)
+#define CVMX_PCIEEP_CFG066 \
+	 (0x0000000000000108ull)
+#define CVMX_PCIEEP_CFG067 \
+	 (0x000000000000010Cull)
+#define CVMX_PCIEEP_CFG068 \
+	 (0x0000000000000110ull)
+#define CVMX_PCIEEP_CFG069 \
+	 (0x0000000000000114ull)
+#define CVMX_PCIEEP_CFG070 \
+	 (0x0000000000000118ull)
+#define CVMX_PCIEEP_CFG071 \
+	 (0x000000000000011Cull)
+#define CVMX_PCIEEP_CFG072 \
+	 (0x0000000000000120ull)
+#define CVMX_PCIEEP_CFG073 \
+	 (0x0000000000000124ull)
+#define CVMX_PCIEEP_CFG074 \
+	 (0x0000000000000128ull)
+#define CVMX_PCIEEP_CFG448 \
+	 (0x0000000000000700ull)
+#define CVMX_PCIEEP_CFG449 \
+	 (0x0000000000000704ull)
+#define CVMX_PCIEEP_CFG450 \
+	 (0x0000000000000708ull)
+#define CVMX_PCIEEP_CFG451 \
+	 (0x000000000000070Cull)
+#define CVMX_PCIEEP_CFG452 \
+	 (0x0000000000000710ull)
+#define CVMX_PCIEEP_CFG453 \
+	 (0x0000000000000714ull)
+#define CVMX_PCIEEP_CFG454 \
+	 (0x0000000000000718ull)
+#define CVMX_PCIEEP_CFG455 \
+	 (0x000000000000071Cull)
+#define CVMX_PCIEEP_CFG456 \
+	 (0x0000000000000720ull)
+#define CVMX_PCIEEP_CFG458 \
+	 (0x0000000000000728ull)
+#define CVMX_PCIEEP_CFG459 \
+	 (0x000000000000072Cull)
+#define CVMX_PCIEEP_CFG460 \
+	 (0x0000000000000730ull)
+#define CVMX_PCIEEP_CFG461 \
+	 (0x0000000000000734ull)
+#define CVMX_PCIEEP_CFG462 \
+	 (0x0000000000000738ull)
+#define CVMX_PCIEEP_CFG463 \
+	 (0x000000000000073Cull)
+#define CVMX_PCIEEP_CFG464 \
+	 (0x0000000000000740ull)
+#define CVMX_PCIEEP_CFG465 \
+	 (0x0000000000000744ull)
+#define CVMX_PCIEEP_CFG466 \
+	 (0x0000000000000748ull)
+#define CVMX_PCIEEP_CFG467 \
+	 (0x000000000000074Cull)
+#define CVMX_PCIEEP_CFG468 \
+	 (0x0000000000000750ull)
+#define CVMX_PCIEEP_CFG490 \
+	 (0x00000000000007A8ull)
+#define CVMX_PCIEEP_CFG491 \
+	 (0x00000000000007ACull)
+#define CVMX_PCIEEP_CFG492 \
+	 (0x00000000000007B0ull)
+#define CVMX_PCIEEP_CFG516 \
+	 (0x0000000000000810ull)
+#define CVMX_PCIEEP_CFG517 \
+	 (0x0000000000000814ull)
+
+union cvmx_pcieep_cfg000 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg000_s {
+		uint32_t devid:16;
+		uint32_t vendid:16;
+	} s;
+	struct cvmx_pcieep_cfg000_s cn52xx;
+	struct cvmx_pcieep_cfg000_s cn52xxp1;
+	struct cvmx_pcieep_cfg000_s cn56xx;
+	struct cvmx_pcieep_cfg000_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg001 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg001_s {
+		uint32_t dpe:1;
+		uint32_t sse:1;
+		uint32_t rma:1;
+		uint32_t rta:1;
+		uint32_t sta:1;
+		uint32_t devt:2;
+		uint32_t mdpe:1;
+		uint32_t fbb:1;
+		uint32_t reserved_22_22:1;
+		uint32_t m66:1;
+		uint32_t cl:1;
+		uint32_t i_stat:1;
+		uint32_t reserved_11_18:8;
+		uint32_t i_dis:1;
+		uint32_t fbbe:1;
+		uint32_t see:1;
+		uint32_t ids_wcc:1;
+		uint32_t per:1;
+		uint32_t vps:1;
+		uint32_t mwice:1;
+		uint32_t scse:1;
+		uint32_t me:1;
+		uint32_t msae:1;
+		uint32_t isae:1;
+	} s;
+	struct cvmx_pcieep_cfg001_s cn52xx;
+	struct cvmx_pcieep_cfg001_s cn52xxp1;
+	struct cvmx_pcieep_cfg001_s cn56xx;
+	struct cvmx_pcieep_cfg001_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg002 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg002_s {
+		uint32_t bcc:8;
+		uint32_t sc:8;
+		uint32_t pi:8;
+		uint32_t rid:8;
+	} s;
+	struct cvmx_pcieep_cfg002_s cn52xx;
+	struct cvmx_pcieep_cfg002_s cn52xxp1;
+	struct cvmx_pcieep_cfg002_s cn56xx;
+	struct cvmx_pcieep_cfg002_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg003 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg003_s {
+		uint32_t bist:8;
+		uint32_t mfd:1;
+		uint32_t chf:7;
+		uint32_t lt:8;
+		uint32_t cls:8;
+	} s;
+	struct cvmx_pcieep_cfg003_s cn52xx;
+	struct cvmx_pcieep_cfg003_s cn52xxp1;
+	struct cvmx_pcieep_cfg003_s cn56xx;
+	struct cvmx_pcieep_cfg003_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg004_s {
+		uint32_t lbab:18;
+		uint32_t reserved_4_13:10;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pcieep_cfg004_s cn52xx;
+	struct cvmx_pcieep_cfg004_s cn52xxp1;
+	struct cvmx_pcieep_cfg004_s cn56xx;
+	struct cvmx_pcieep_cfg004_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg004_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg004_mask_s {
+		uint32_t lmask:31;
+		uint32_t enb:1;
+	} s;
+	struct cvmx_pcieep_cfg004_mask_s cn52xx;
+	struct cvmx_pcieep_cfg004_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg004_mask_s cn56xx;
+	struct cvmx_pcieep_cfg004_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg005_s {
+		uint32_t ubab:32;
+	} s;
+	struct cvmx_pcieep_cfg005_s cn52xx;
+	struct cvmx_pcieep_cfg005_s cn52xxp1;
+	struct cvmx_pcieep_cfg005_s cn56xx;
+	struct cvmx_pcieep_cfg005_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg005_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg005_mask_s {
+		uint32_t umask:32;
+	} s;
+	struct cvmx_pcieep_cfg005_mask_s cn52xx;
+	struct cvmx_pcieep_cfg005_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg005_mask_s cn56xx;
+	struct cvmx_pcieep_cfg005_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg006_s {
+		uint32_t lbab:6;
+		uint32_t reserved_4_25:22;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pcieep_cfg006_s cn52xx;
+	struct cvmx_pcieep_cfg006_s cn52xxp1;
+	struct cvmx_pcieep_cfg006_s cn56xx;
+	struct cvmx_pcieep_cfg006_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg006_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg006_mask_s {
+		uint32_t lmask:31;
+		uint32_t enb:1;
+	} s;
+	struct cvmx_pcieep_cfg006_mask_s cn52xx;
+	struct cvmx_pcieep_cfg006_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg006_mask_s cn56xx;
+	struct cvmx_pcieep_cfg006_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg007_s {
+		uint32_t ubab:32;
+	} s;
+	struct cvmx_pcieep_cfg007_s cn52xx;
+	struct cvmx_pcieep_cfg007_s cn52xxp1;
+	struct cvmx_pcieep_cfg007_s cn56xx;
+	struct cvmx_pcieep_cfg007_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg007_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg007_mask_s {
+		uint32_t umask:32;
+	} s;
+	struct cvmx_pcieep_cfg007_mask_s cn52xx;
+	struct cvmx_pcieep_cfg007_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg007_mask_s cn56xx;
+	struct cvmx_pcieep_cfg007_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg008_s {
+		uint32_t reserved_4_31:28;
+		uint32_t pf:1;
+		uint32_t typ:2;
+		uint32_t mspc:1;
+	} s;
+	struct cvmx_pcieep_cfg008_s cn52xx;
+	struct cvmx_pcieep_cfg008_s cn52xxp1;
+	struct cvmx_pcieep_cfg008_s cn56xx;
+	struct cvmx_pcieep_cfg008_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg008_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg008_mask_s {
+		uint32_t lmask:31;
+		uint32_t enb:1;
+	} s;
+	struct cvmx_pcieep_cfg008_mask_s cn52xx;
+	struct cvmx_pcieep_cfg008_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg008_mask_s cn56xx;
+	struct cvmx_pcieep_cfg008_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg009_s {
+		uint32_t ubab:25;
+		uint32_t reserved_0_6:7;
+	} s;
+	struct cvmx_pcieep_cfg009_s cn52xx;
+	struct cvmx_pcieep_cfg009_s cn52xxp1;
+	struct cvmx_pcieep_cfg009_s cn56xx;
+	struct cvmx_pcieep_cfg009_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg009_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg009_mask_s {
+		uint32_t umask:32;
+	} s;
+	struct cvmx_pcieep_cfg009_mask_s cn52xx;
+	struct cvmx_pcieep_cfg009_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg009_mask_s cn56xx;
+	struct cvmx_pcieep_cfg009_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg010 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg010_s {
+		uint32_t cisp:32;
+	} s;
+	struct cvmx_pcieep_cfg010_s cn52xx;
+	struct cvmx_pcieep_cfg010_s cn52xxp1;
+	struct cvmx_pcieep_cfg010_s cn56xx;
+	struct cvmx_pcieep_cfg010_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg011 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg011_s {
+		uint32_t ssid:16;
+		uint32_t ssvid:16;
+	} s;
+	struct cvmx_pcieep_cfg011_s cn52xx;
+	struct cvmx_pcieep_cfg011_s cn52xxp1;
+	struct cvmx_pcieep_cfg011_s cn56xx;
+	struct cvmx_pcieep_cfg011_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg012_s {
+		uint32_t eraddr:16;
+		uint32_t reserved_1_15:15;
+		uint32_t er_en:1;
+	} s;
+	struct cvmx_pcieep_cfg012_s cn52xx;
+	struct cvmx_pcieep_cfg012_s cn52xxp1;
+	struct cvmx_pcieep_cfg012_s cn56xx;
+	struct cvmx_pcieep_cfg012_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg012_mask {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg012_mask_s {
+		uint32_t mask:31;
+		uint32_t enb:1;
+	} s;
+	struct cvmx_pcieep_cfg012_mask_s cn52xx;
+	struct cvmx_pcieep_cfg012_mask_s cn52xxp1;
+	struct cvmx_pcieep_cfg012_mask_s cn56xx;
+	struct cvmx_pcieep_cfg012_mask_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg013 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg013_s {
+		uint32_t reserved_8_31:24;
+		uint32_t cp:8;
+	} s;
+	struct cvmx_pcieep_cfg013_s cn52xx;
+	struct cvmx_pcieep_cfg013_s cn52xxp1;
+	struct cvmx_pcieep_cfg013_s cn56xx;
+	struct cvmx_pcieep_cfg013_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg015 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg015_s {
+		uint32_t ml:8;
+		uint32_t mg:8;
+		uint32_t inta:8;
+		uint32_t il:8;
+	} s;
+	struct cvmx_pcieep_cfg015_s cn52xx;
+	struct cvmx_pcieep_cfg015_s cn52xxp1;
+	struct cvmx_pcieep_cfg015_s cn56xx;
+	struct cvmx_pcieep_cfg015_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg016 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg016_s {
+		uint32_t pmes:5;
+		uint32_t d2s:1;
+		uint32_t d1s:1;
+		uint32_t auxc:3;
+		uint32_t dsi:1;
+		uint32_t reserved_20_20:1;
+		uint32_t pme_clock:1;
+		uint32_t pmsv:3;
+		uint32_t ncp:8;
+		uint32_t pmcid:8;
+	} s;
+	struct cvmx_pcieep_cfg016_s cn52xx;
+	struct cvmx_pcieep_cfg016_s cn52xxp1;
+	struct cvmx_pcieep_cfg016_s cn56xx;
+	struct cvmx_pcieep_cfg016_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg017 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg017_s {
+		uint32_t pmdia:8;
+		uint32_t bpccee:1;
+		uint32_t bd3h:1;
+		uint32_t reserved_16_21:6;
+		uint32_t pmess:1;
+		uint32_t pmedsia:2;
+		uint32_t pmds:4;
+		uint32_t pmeens:1;
+		uint32_t reserved_4_7:4;
+		uint32_t nsr:1;
+		uint32_t reserved_2_2:1;
+		uint32_t ps:2;
+	} s;
+	struct cvmx_pcieep_cfg017_s cn52xx;
+	struct cvmx_pcieep_cfg017_s cn52xxp1;
+	struct cvmx_pcieep_cfg017_s cn56xx;
+	struct cvmx_pcieep_cfg017_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg020 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg020_s {
+		uint32_t reserved_24_31:8;
+		uint32_t m64:1;
+		uint32_t mme:3;
+		uint32_t mmc:3;
+		uint32_t msien:1;
+		uint32_t ncp:8;
+		uint32_t msicid:8;
+	} s;
+	struct cvmx_pcieep_cfg020_s cn52xx;
+	struct cvmx_pcieep_cfg020_s cn52xxp1;
+	struct cvmx_pcieep_cfg020_s cn56xx;
+	struct cvmx_pcieep_cfg020_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg021 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg021_s {
+		uint32_t lmsi:30;
+		uint32_t reserved_0_1:2;
+	} s;
+	struct cvmx_pcieep_cfg021_s cn52xx;
+	struct cvmx_pcieep_cfg021_s cn52xxp1;
+	struct cvmx_pcieep_cfg021_s cn56xx;
+	struct cvmx_pcieep_cfg021_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg022 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg022_s {
+		uint32_t umsi:32;
+	} s;
+	struct cvmx_pcieep_cfg022_s cn52xx;
+	struct cvmx_pcieep_cfg022_s cn52xxp1;
+	struct cvmx_pcieep_cfg022_s cn56xx;
+	struct cvmx_pcieep_cfg022_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg023 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg023_s {
+		uint32_t reserved_16_31:16;
+		uint32_t msimd:16;
+	} s;
+	struct cvmx_pcieep_cfg023_s cn52xx;
+	struct cvmx_pcieep_cfg023_s cn52xxp1;
+	struct cvmx_pcieep_cfg023_s cn56xx;
+	struct cvmx_pcieep_cfg023_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg028 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg028_s {
+		uint32_t reserved_30_31:2;
+		uint32_t imn:5;
+		uint32_t si:1;
+		uint32_t dpt:4;
+		uint32_t pciecv:4;
+		uint32_t ncp:8;
+		uint32_t pcieid:8;
+	} s;
+	struct cvmx_pcieep_cfg028_s cn52xx;
+	struct cvmx_pcieep_cfg028_s cn52xxp1;
+	struct cvmx_pcieep_cfg028_s cn56xx;
+	struct cvmx_pcieep_cfg028_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg029 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg029_s {
+		uint32_t reserved_28_31:4;
+		uint32_t cspls:2;
+		uint32_t csplv:8;
+		uint32_t reserved_16_17:2;
+		uint32_t rber:1;
+		uint32_t reserved_12_14:3;
+		uint32_t el1al:3;
+		uint32_t el0al:3;
+		uint32_t etfs:1;
+		uint32_t pfs:2;
+		uint32_t mpss:3;
+	} s;
+	struct cvmx_pcieep_cfg029_s cn52xx;
+	struct cvmx_pcieep_cfg029_s cn52xxp1;
+	struct cvmx_pcieep_cfg029_s cn56xx;
+	struct cvmx_pcieep_cfg029_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg030 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg030_s {
+		uint32_t reserved_22_31:10;
+		uint32_t tp:1;
+		uint32_t ap_d:1;
+		uint32_t ur_d:1;
+		uint32_t fe_d:1;
+		uint32_t nfe_d:1;
+		uint32_t ce_d:1;
+		uint32_t reserved_15_15:1;
+		uint32_t mrrs:3;
+		uint32_t ns_en:1;
+		uint32_t ap_en:1;
+		uint32_t pf_en:1;
+		uint32_t etf_en:1;
+		uint32_t mps:3;
+		uint32_t ro_en:1;
+		uint32_t ur_en:1;
+		uint32_t fe_en:1;
+		uint32_t nfe_en:1;
+		uint32_t ce_en:1;
+	} s;
+	struct cvmx_pcieep_cfg030_s cn52xx;
+	struct cvmx_pcieep_cfg030_s cn52xxp1;
+	struct cvmx_pcieep_cfg030_s cn56xx;
+	struct cvmx_pcieep_cfg030_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg031 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg031_s {
+		uint32_t pnum:8;
+		uint32_t reserved_22_23:2;
+		uint32_t lbnc:1;
+		uint32_t dllarc:1;
+		uint32_t sderc:1;
+		uint32_t cpm:1;
+		uint32_t l1el:3;
+		uint32_t l0el:3;
+		uint32_t aslpms:2;
+		uint32_t mlw:6;
+		uint32_t mls:4;
+	} s;
+	struct cvmx_pcieep_cfg031_s cn52xx;
+	struct cvmx_pcieep_cfg031_s cn52xxp1;
+	struct cvmx_pcieep_cfg031_s cn56xx;
+	struct cvmx_pcieep_cfg031_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg032 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg032_s {
+		uint32_t reserved_30_31:2;
+		uint32_t dlla:1;
+		uint32_t scc:1;
+		uint32_t lt:1;
+		uint32_t reserved_26_26:1;
+		uint32_t nlw:6;
+		uint32_t ls:4;
+		uint32_t reserved_10_15:6;
+		uint32_t hawd:1;
+		uint32_t ecpm:1;
+		uint32_t es:1;
+		uint32_t ccc:1;
+		uint32_t rl:1;
+		uint32_t ld:1;
+		uint32_t rcb:1;
+		uint32_t reserved_2_2:1;
+		uint32_t aslpc:2;
+	} s;
+	struct cvmx_pcieep_cfg032_s cn52xx;
+	struct cvmx_pcieep_cfg032_s cn52xxp1;
+	struct cvmx_pcieep_cfg032_s cn56xx;
+	struct cvmx_pcieep_cfg032_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg033 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg033_s {
+		uint32_t ps_num:13;
+		uint32_t nccs:1;
+		uint32_t emip:1;
+		uint32_t sp_ls:2;
+		uint32_t sp_lv:8;
+		uint32_t hp_c:1;
+		uint32_t hp_s:1;
+		uint32_t pip:1;
+		uint32_t aip:1;
+		uint32_t mrlsp:1;
+		uint32_t pcp:1;
+		uint32_t abp:1;
+	} s;
+	struct cvmx_pcieep_cfg033_s cn52xx;
+	struct cvmx_pcieep_cfg033_s cn52xxp1;
+	struct cvmx_pcieep_cfg033_s cn56xx;
+	struct cvmx_pcieep_cfg033_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg034 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg034_s {
+		uint32_t reserved_25_31:7;
+		uint32_t dlls_c:1;
+		uint32_t emis:1;
+		uint32_t pds:1;
+		uint32_t mrlss:1;
+		uint32_t ccint_d:1;
+		uint32_t pd_c:1;
+		uint32_t mrls_c:1;
+		uint32_t pf_d:1;
+		uint32_t abp_d:1;
+		uint32_t reserved_13_15:3;
+		uint32_t dlls_en:1;
+		uint32_t emic:1;
+		uint32_t pcc:1;
+		uint32_t pic:2;
+		uint32_t aic:2;
+		uint32_t hpint_en:1;
+		uint32_t ccint_en:1;
+		uint32_t pd_en:1;
+		uint32_t mrls_en:1;
+		uint32_t pf_en:1;
+		uint32_t abp_en:1;
+	} s;
+	struct cvmx_pcieep_cfg034_s cn52xx;
+	struct cvmx_pcieep_cfg034_s cn52xxp1;
+	struct cvmx_pcieep_cfg034_s cn56xx;
+	struct cvmx_pcieep_cfg034_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg037 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg037_s {
+		uint32_t reserved_5_31:27;
+		uint32_t ctds:1;
+		uint32_t ctrs:4;
+	} s;
+	struct cvmx_pcieep_cfg037_s cn52xx;
+	struct cvmx_pcieep_cfg037_s cn52xxp1;
+	struct cvmx_pcieep_cfg037_s cn56xx;
+	struct cvmx_pcieep_cfg037_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg038 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg038_s {
+		uint32_t reserved_5_31:27;
+		uint32_t ctd:1;
+		uint32_t ctv:4;
+	} s;
+	struct cvmx_pcieep_cfg038_s cn52xx;
+	struct cvmx_pcieep_cfg038_s cn52xxp1;
+	struct cvmx_pcieep_cfg038_s cn56xx;
+	struct cvmx_pcieep_cfg038_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg039 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg039_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pcieep_cfg039_s cn52xx;
+	struct cvmx_pcieep_cfg039_s cn52xxp1;
+	struct cvmx_pcieep_cfg039_s cn56xx;
+	struct cvmx_pcieep_cfg039_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg040 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg040_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pcieep_cfg040_s cn52xx;
+	struct cvmx_pcieep_cfg040_s cn52xxp1;
+	struct cvmx_pcieep_cfg040_s cn56xx;
+	struct cvmx_pcieep_cfg040_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg041 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg041_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pcieep_cfg041_s cn52xx;
+	struct cvmx_pcieep_cfg041_s cn52xxp1;
+	struct cvmx_pcieep_cfg041_s cn56xx;
+	struct cvmx_pcieep_cfg041_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg042 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg042_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pcieep_cfg042_s cn52xx;
+	struct cvmx_pcieep_cfg042_s cn52xxp1;
+	struct cvmx_pcieep_cfg042_s cn56xx;
+	struct cvmx_pcieep_cfg042_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg064 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg064_s {
+		uint32_t nco:12;
+		uint32_t cv:4;
+		uint32_t pcieec:16;
+	} s;
+	struct cvmx_pcieep_cfg064_s cn52xx;
+	struct cvmx_pcieep_cfg064_s cn52xxp1;
+	struct cvmx_pcieep_cfg064_s cn56xx;
+	struct cvmx_pcieep_cfg064_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg065 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg065_s {
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pcieep_cfg065_s cn52xx;
+	struct cvmx_pcieep_cfg065_s cn52xxp1;
+	struct cvmx_pcieep_cfg065_s cn56xx;
+	struct cvmx_pcieep_cfg065_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg066 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg066_s {
+		uint32_t reserved_21_31:11;
+		uint32_t urem:1;
+		uint32_t ecrcem:1;
+		uint32_t mtlpm:1;
+		uint32_t rom:1;
+		uint32_t ucm:1;
+		uint32_t cam:1;
+		uint32_t ctm:1;
+		uint32_t fcpem:1;
+		uint32_t ptlpm:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdem:1;
+		uint32_t dlpem:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pcieep_cfg066_s cn52xx;
+	struct cvmx_pcieep_cfg066_s cn52xxp1;
+	struct cvmx_pcieep_cfg066_s cn56xx;
+	struct cvmx_pcieep_cfg066_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg067 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg067_s {
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pcieep_cfg067_s cn52xx;
+	struct cvmx_pcieep_cfg067_s cn52xxp1;
+	struct cvmx_pcieep_cfg067_s cn56xx;
+	struct cvmx_pcieep_cfg067_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg068 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg068_s {
+		uint32_t reserved_14_31:18;
+		uint32_t anfes:1;
+		uint32_t rtts:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrs:1;
+		uint32_t bdllps:1;
+		uint32_t btlps:1;
+		uint32_t reserved_1_5:5;
+		uint32_t res:1;
+	} s;
+	struct cvmx_pcieep_cfg068_s cn52xx;
+	struct cvmx_pcieep_cfg068_s cn52xxp1;
+	struct cvmx_pcieep_cfg068_s cn56xx;
+	struct cvmx_pcieep_cfg068_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg069 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg069_s {
+		uint32_t reserved_14_31:18;
+		uint32_t anfem:1;
+		uint32_t rttm:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrm:1;
+		uint32_t bdllpm:1;
+		uint32_t btlpm:1;
+		uint32_t reserved_1_5:5;
+		uint32_t rem:1;
+	} s;
+	struct cvmx_pcieep_cfg069_s cn52xx;
+	struct cvmx_pcieep_cfg069_s cn52xxp1;
+	struct cvmx_pcieep_cfg069_s cn56xx;
+	struct cvmx_pcieep_cfg069_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg070 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg070_s {
+		uint32_t reserved_9_31:23;
+		uint32_t ce:1;
+		uint32_t cc:1;
+		uint32_t ge:1;
+		uint32_t gc:1;
+		uint32_t fep:5;
+	} s;
+	struct cvmx_pcieep_cfg070_s cn52xx;
+	struct cvmx_pcieep_cfg070_s cn52xxp1;
+	struct cvmx_pcieep_cfg070_s cn56xx;
+	struct cvmx_pcieep_cfg070_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg071 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg071_s {
+		uint32_t dword1:32;
+	} s;
+	struct cvmx_pcieep_cfg071_s cn52xx;
+	struct cvmx_pcieep_cfg071_s cn52xxp1;
+	struct cvmx_pcieep_cfg071_s cn56xx;
+	struct cvmx_pcieep_cfg071_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg072 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg072_s {
+		uint32_t dword2:32;
+	} s;
+	struct cvmx_pcieep_cfg072_s cn52xx;
+	struct cvmx_pcieep_cfg072_s cn52xxp1;
+	struct cvmx_pcieep_cfg072_s cn56xx;
+	struct cvmx_pcieep_cfg072_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg073 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg073_s {
+		uint32_t dword3:32;
+	} s;
+	struct cvmx_pcieep_cfg073_s cn52xx;
+	struct cvmx_pcieep_cfg073_s cn52xxp1;
+	struct cvmx_pcieep_cfg073_s cn56xx;
+	struct cvmx_pcieep_cfg073_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg074 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg074_s {
+		uint32_t dword4:32;
+	} s;
+	struct cvmx_pcieep_cfg074_s cn52xx;
+	struct cvmx_pcieep_cfg074_s cn52xxp1;
+	struct cvmx_pcieep_cfg074_s cn56xx;
+	struct cvmx_pcieep_cfg074_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg448 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg448_s {
+		uint32_t rtl:16;
+		uint32_t rtltl:16;
+	} s;
+	struct cvmx_pcieep_cfg448_s cn52xx;
+	struct cvmx_pcieep_cfg448_s cn52xxp1;
+	struct cvmx_pcieep_cfg448_s cn56xx;
+	struct cvmx_pcieep_cfg448_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg449 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg449_s {
+		uint32_t omr:32;
+	} s;
+	struct cvmx_pcieep_cfg449_s cn52xx;
+	struct cvmx_pcieep_cfg449_s cn52xxp1;
+	struct cvmx_pcieep_cfg449_s cn56xx;
+	struct cvmx_pcieep_cfg449_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg450 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg450_s {
+		uint32_t lpec:8;
+		uint32_t reserved_22_23:2;
+		uint32_t link_state:6;
+		uint32_t force_link:1;
+		uint32_t reserved_8_14:7;
+		uint32_t link_num:8;
+	} s;
+	struct cvmx_pcieep_cfg450_s cn52xx;
+	struct cvmx_pcieep_cfg450_s cn52xxp1;
+	struct cvmx_pcieep_cfg450_s cn56xx;
+	struct cvmx_pcieep_cfg450_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg451 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg451_s {
+		uint32_t reserved_30_31:2;
+		uint32_t l1el:3;
+		uint32_t l0el:3;
+		uint32_t n_fts_cc:8;
+		uint32_t n_fts:8;
+		uint32_t ack_freq:8;
+	} s;
+	struct cvmx_pcieep_cfg451_s cn52xx;
+	struct cvmx_pcieep_cfg451_s cn52xxp1;
+	struct cvmx_pcieep_cfg451_s cn56xx;
+	struct cvmx_pcieep_cfg451_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg452 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg452_s {
+		uint32_t reserved_26_31:6;
+		uint32_t eccrc:1;
+		uint32_t reserved_22_24:3;
+		uint32_t lme:6;
+		uint32_t reserved_8_15:8;
+		uint32_t flm:1;
+		uint32_t reserved_6_6:1;
+		uint32_t dllle:1;
+		uint32_t reserved_4_4:1;
+		uint32_t ra:1;
+		uint32_t le:1;
+		uint32_t sd:1;
+		uint32_t omr:1;
+	} s;
+	struct cvmx_pcieep_cfg452_s cn52xx;
+	struct cvmx_pcieep_cfg452_s cn52xxp1;
+	struct cvmx_pcieep_cfg452_s cn56xx;
+	struct cvmx_pcieep_cfg452_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg453 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg453_s {
+		uint32_t dlld:1;
+		uint32_t reserved_26_30:5;
+		uint32_t ack_nak:1;
+		uint32_t fcd:1;
+		uint32_t ilst:24;
+	} s;
+	struct cvmx_pcieep_cfg453_s cn52xx;
+	struct cvmx_pcieep_cfg453_s cn52xxp1;
+	struct cvmx_pcieep_cfg453_s cn56xx;
+	struct cvmx_pcieep_cfg453_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg454 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg454_s {
+		uint32_t reserved_29_31:3;
+		uint32_t tmfcwt:5;
+		uint32_t tmanlt:5;
+		uint32_t tmrt:5;
+		uint32_t reserved_11_13:3;
+		uint32_t nskps:3;
+		uint32_t reserved_4_7:4;
+		uint32_t ntss:4;
+	} s;
+	struct cvmx_pcieep_cfg454_s cn52xx;
+	struct cvmx_pcieep_cfg454_s cn52xxp1;
+	struct cvmx_pcieep_cfg454_s cn56xx;
+	struct cvmx_pcieep_cfg454_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg455 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg455_s {
+		uint32_t m_cfg0_filt:1;
+		uint32_t m_io_filt:1;
+		uint32_t msg_ctrl:1;
+		uint32_t m_cpl_ecrc_filt:1;
+		uint32_t m_ecrc_filt:1;
+		uint32_t m_cpl_len_err:1;
+		uint32_t m_cpl_attr_err:1;
+		uint32_t m_cpl_tc_err:1;
+		uint32_t m_cpl_fun_err:1;
+		uint32_t m_cpl_rid_err:1;
+		uint32_t m_cpl_tag_err:1;
+		uint32_t m_lk_filt:1;
+		uint32_t m_cfg1_filt:1;
+		uint32_t m_bar_match:1;
+		uint32_t m_pois_filt:1;
+		uint32_t m_fun:1;
+		uint32_t dfcwt:1;
+		uint32_t reserved_11_14:4;
+		uint32_t skpiv:11;
+	} s;
+	struct cvmx_pcieep_cfg455_s cn52xx;
+	struct cvmx_pcieep_cfg455_s cn52xxp1;
+	struct cvmx_pcieep_cfg455_s cn56xx;
+	struct cvmx_pcieep_cfg455_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg456 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg456_s {
+		uint32_t reserved_2_31:30;
+		uint32_t m_vend1_drp:1;
+		uint32_t m_vend0_drp:1;
+	} s;
+	struct cvmx_pcieep_cfg456_s cn52xx;
+	struct cvmx_pcieep_cfg456_s cn52xxp1;
+	struct cvmx_pcieep_cfg456_s cn56xx;
+	struct cvmx_pcieep_cfg456_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg458 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg458_s {
+		uint32_t dbg_info_l32:32;
+	} s;
+	struct cvmx_pcieep_cfg458_s cn52xx;
+	struct cvmx_pcieep_cfg458_s cn52xxp1;
+	struct cvmx_pcieep_cfg458_s cn56xx;
+	struct cvmx_pcieep_cfg458_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg459 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg459_s {
+		uint32_t dbg_info_u32:32;
+	} s;
+	struct cvmx_pcieep_cfg459_s cn52xx;
+	struct cvmx_pcieep_cfg459_s cn52xxp1;
+	struct cvmx_pcieep_cfg459_s cn56xx;
+	struct cvmx_pcieep_cfg459_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg460 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg460_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tphfcc:8;
+		uint32_t tpdfcc:12;
+	} s;
+	struct cvmx_pcieep_cfg460_s cn52xx;
+	struct cvmx_pcieep_cfg460_s cn52xxp1;
+	struct cvmx_pcieep_cfg460_s cn56xx;
+	struct cvmx_pcieep_cfg460_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg461 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg461_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tchfcc:8;
+		uint32_t tcdfcc:12;
+	} s;
+	struct cvmx_pcieep_cfg461_s cn52xx;
+	struct cvmx_pcieep_cfg461_s cn52xxp1;
+	struct cvmx_pcieep_cfg461_s cn56xx;
+	struct cvmx_pcieep_cfg461_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg462 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg462_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tchfcc:8;
+		uint32_t tcdfcc:12;
+	} s;
+	struct cvmx_pcieep_cfg462_s cn52xx;
+	struct cvmx_pcieep_cfg462_s cn52xxp1;
+	struct cvmx_pcieep_cfg462_s cn56xx;
+	struct cvmx_pcieep_cfg462_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg463 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg463_s {
+		uint32_t reserved_3_31:29;
+		uint32_t rqne:1;
+		uint32_t trbne:1;
+		uint32_t rtlpfccnr:1;
+	} s;
+	struct cvmx_pcieep_cfg463_s cn52xx;
+	struct cvmx_pcieep_cfg463_s cn52xxp1;
+	struct cvmx_pcieep_cfg463_s cn56xx;
+	struct cvmx_pcieep_cfg463_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg464 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg464_s {
+		uint32_t wrr_vc3:8;
+		uint32_t wrr_vc2:8;
+		uint32_t wrr_vc1:8;
+		uint32_t wrr_vc0:8;
+	} s;
+	struct cvmx_pcieep_cfg464_s cn52xx;
+	struct cvmx_pcieep_cfg464_s cn52xxp1;
+	struct cvmx_pcieep_cfg464_s cn56xx;
+	struct cvmx_pcieep_cfg464_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg465 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg465_s {
+		uint32_t wrr_vc7:8;
+		uint32_t wrr_vc6:8;
+		uint32_t wrr_vc5:8;
+		uint32_t wrr_vc4:8;
+	} s;
+	struct cvmx_pcieep_cfg465_s cn52xx;
+	struct cvmx_pcieep_cfg465_s cn52xxp1;
+	struct cvmx_pcieep_cfg465_s cn56xx;
+	struct cvmx_pcieep_cfg465_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg466 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg466_s {
+		uint32_t rx_queue_order:1;
+		uint32_t type_ordering:1;
+		uint32_t reserved_24_29:6;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pcieep_cfg466_s cn52xx;
+	struct cvmx_pcieep_cfg466_s cn52xxp1;
+	struct cvmx_pcieep_cfg466_s cn56xx;
+	struct cvmx_pcieep_cfg466_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg467 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg467_s {
+		uint32_t reserved_24_31:8;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pcieep_cfg467_s cn52xx;
+	struct cvmx_pcieep_cfg467_s cn52xxp1;
+	struct cvmx_pcieep_cfg467_s cn56xx;
+	struct cvmx_pcieep_cfg467_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg468 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg468_s {
+		uint32_t reserved_24_31:8;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pcieep_cfg468_s cn52xx;
+	struct cvmx_pcieep_cfg468_s cn52xxp1;
+	struct cvmx_pcieep_cfg468_s cn56xx;
+	struct cvmx_pcieep_cfg468_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg490 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg490_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pcieep_cfg490_s cn52xx;
+	struct cvmx_pcieep_cfg490_s cn52xxp1;
+	struct cvmx_pcieep_cfg490_s cn56xx;
+	struct cvmx_pcieep_cfg490_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg491 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg491_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pcieep_cfg491_s cn52xx;
+	struct cvmx_pcieep_cfg491_s cn52xxp1;
+	struct cvmx_pcieep_cfg491_s cn56xx;
+	struct cvmx_pcieep_cfg491_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg492 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg492_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pcieep_cfg492_s cn52xx;
+	struct cvmx_pcieep_cfg492_s cn52xxp1;
+	struct cvmx_pcieep_cfg492_s cn56xx;
+	struct cvmx_pcieep_cfg492_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg516 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg516_s {
+		uint32_t phy_stat:32;
+	} s;
+	struct cvmx_pcieep_cfg516_s cn52xx;
+	struct cvmx_pcieep_cfg516_s cn52xxp1;
+	struct cvmx_pcieep_cfg516_s cn56xx;
+	struct cvmx_pcieep_cfg516_s cn56xxp1;
+};
+
+union cvmx_pcieep_cfg517 {
+	uint32_t u32;
+	struct cvmx_pcieep_cfg517_s {
+		uint32_t phy_ctrl:32;
+	} s;
+	struct cvmx_pcieep_cfg517_s cn52xx;
+	struct cvmx_pcieep_cfg517_s cn52xxp1;
+	struct cvmx_pcieep_cfg517_s cn56xx;
+	struct cvmx_pcieep_cfg517_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
new file mode 100644
index 0000000..75574c9
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -0,0 +1,1397 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCIERCX_DEFS_H__
+#define __CVMX_PCIERCX_DEFS_H__
+
+#define CVMX_PCIERCX_CFG000(offset) \
+	 (0x0000000000000000ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG001(offset) \
+	 (0x0000000000000004ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG002(offset) \
+	 (0x0000000000000008ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG003(offset) \
+	 (0x000000000000000Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG004(offset) \
+	 (0x0000000000000010ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG005(offset) \
+	 (0x0000000000000014ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG006(offset) \
+	 (0x0000000000000018ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG007(offset) \
+	 (0x000000000000001Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG008(offset) \
+	 (0x0000000000000020ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG009(offset) \
+	 (0x0000000000000024ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG010(offset) \
+	 (0x0000000000000028ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG011(offset) \
+	 (0x000000000000002Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG012(offset) \
+	 (0x0000000000000030ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG013(offset) \
+	 (0x0000000000000034ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG014(offset) \
+	 (0x0000000000000038ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG015(offset) \
+	 (0x000000000000003Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG016(offset) \
+	 (0x0000000000000040ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG017(offset) \
+	 (0x0000000000000044ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG020(offset) \
+	 (0x0000000000000050ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG021(offset) \
+	 (0x0000000000000054ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG022(offset) \
+	 (0x0000000000000058ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG023(offset) \
+	 (0x000000000000005Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG028(offset) \
+	 (0x0000000000000070ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG029(offset) \
+	 (0x0000000000000074ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG030(offset) \
+	 (0x0000000000000078ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG031(offset) \
+	 (0x000000000000007Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG032(offset) \
+	 (0x0000000000000080ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG033(offset) \
+	 (0x0000000000000084ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG034(offset) \
+	 (0x0000000000000088ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG035(offset) \
+	 (0x000000000000008Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG036(offset) \
+	 (0x0000000000000090ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG037(offset) \
+	 (0x0000000000000094ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG038(offset) \
+	 (0x0000000000000098ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG039(offset) \
+	 (0x000000000000009Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG040(offset) \
+	 (0x00000000000000A0ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG041(offset) \
+	 (0x00000000000000A4ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG042(offset) \
+	 (0x00000000000000A8ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG064(offset) \
+	 (0x0000000000000100ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG065(offset) \
+	 (0x0000000000000104ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG066(offset) \
+	 (0x0000000000000108ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG067(offset) \
+	 (0x000000000000010Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG068(offset) \
+	 (0x0000000000000110ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG069(offset) \
+	 (0x0000000000000114ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG070(offset) \
+	 (0x0000000000000118ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG071(offset) \
+	 (0x000000000000011Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG072(offset) \
+	 (0x0000000000000120ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG073(offset) \
+	 (0x0000000000000124ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG074(offset) \
+	 (0x0000000000000128ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG075(offset) \
+	 (0x000000000000012Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG076(offset) \
+	 (0x0000000000000130ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG077(offset) \
+	 (0x0000000000000134ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG448(offset) \
+	 (0x0000000000000700ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG449(offset) \
+	 (0x0000000000000704ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG450(offset) \
+	 (0x0000000000000708ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG451(offset) \
+	 (0x000000000000070Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG452(offset) \
+	 (0x0000000000000710ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG453(offset) \
+	 (0x0000000000000714ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG454(offset) \
+	 (0x0000000000000718ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG455(offset) \
+	 (0x000000000000071Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG456(offset) \
+	 (0x0000000000000720ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG458(offset) \
+	 (0x0000000000000728ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG459(offset) \
+	 (0x000000000000072Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG460(offset) \
+	 (0x0000000000000730ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG461(offset) \
+	 (0x0000000000000734ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG462(offset) \
+	 (0x0000000000000738ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG463(offset) \
+	 (0x000000000000073Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG464(offset) \
+	 (0x0000000000000740ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG465(offset) \
+	 (0x0000000000000744ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG466(offset) \
+	 (0x0000000000000748ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG467(offset) \
+	 (0x000000000000074Cull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG468(offset) \
+	 (0x0000000000000750ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG490(offset) \
+	 (0x00000000000007A8ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG491(offset) \
+	 (0x00000000000007ACull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG492(offset) \
+	 (0x00000000000007B0ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG516(offset) \
+	 (0x0000000000000810ull + (((offset) & 1) * 0))
+#define CVMX_PCIERCX_CFG517(offset) \
+	 (0x0000000000000814ull + (((offset) & 1) * 0))
+
+union cvmx_pciercx_cfg000 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg000_s {
+		uint32_t devid:16;
+		uint32_t vendid:16;
+	} s;
+	struct cvmx_pciercx_cfg000_s cn52xx;
+	struct cvmx_pciercx_cfg000_s cn52xxp1;
+	struct cvmx_pciercx_cfg000_s cn56xx;
+	struct cvmx_pciercx_cfg000_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg001 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg001_s {
+		uint32_t dpe:1;
+		uint32_t sse:1;
+		uint32_t rma:1;
+		uint32_t rta:1;
+		uint32_t sta:1;
+		uint32_t devt:2;
+		uint32_t mdpe:1;
+		uint32_t fbb:1;
+		uint32_t reserved_22_22:1;
+		uint32_t m66:1;
+		uint32_t cl:1;
+		uint32_t i_stat:1;
+		uint32_t reserved_11_18:8;
+		uint32_t i_dis:1;
+		uint32_t fbbe:1;
+		uint32_t see:1;
+		uint32_t ids_wcc:1;
+		uint32_t per:1;
+		uint32_t vps:1;
+		uint32_t mwice:1;
+		uint32_t scse:1;
+		uint32_t me:1;
+		uint32_t msae:1;
+		uint32_t isae:1;
+	} s;
+	struct cvmx_pciercx_cfg001_s cn52xx;
+	struct cvmx_pciercx_cfg001_s cn52xxp1;
+	struct cvmx_pciercx_cfg001_s cn56xx;
+	struct cvmx_pciercx_cfg001_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg002 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg002_s {
+		uint32_t bcc:8;
+		uint32_t sc:8;
+		uint32_t pi:8;
+		uint32_t rid:8;
+	} s;
+	struct cvmx_pciercx_cfg002_s cn52xx;
+	struct cvmx_pciercx_cfg002_s cn52xxp1;
+	struct cvmx_pciercx_cfg002_s cn56xx;
+	struct cvmx_pciercx_cfg002_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg003 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg003_s {
+		uint32_t bist:8;
+		uint32_t mfd:1;
+		uint32_t chf:7;
+		uint32_t lt:8;
+		uint32_t cls:8;
+	} s;
+	struct cvmx_pciercx_cfg003_s cn52xx;
+	struct cvmx_pciercx_cfg003_s cn52xxp1;
+	struct cvmx_pciercx_cfg003_s cn56xx;
+	struct cvmx_pciercx_cfg003_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg004 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg004_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg004_s cn52xx;
+	struct cvmx_pciercx_cfg004_s cn52xxp1;
+	struct cvmx_pciercx_cfg004_s cn56xx;
+	struct cvmx_pciercx_cfg004_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg005 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg005_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg005_s cn52xx;
+	struct cvmx_pciercx_cfg005_s cn52xxp1;
+	struct cvmx_pciercx_cfg005_s cn56xx;
+	struct cvmx_pciercx_cfg005_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg006 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg006_s {
+		uint32_t slt:8;
+		uint32_t subbnum:8;
+		uint32_t sbnum:8;
+		uint32_t pbnum:8;
+	} s;
+	struct cvmx_pciercx_cfg006_s cn52xx;
+	struct cvmx_pciercx_cfg006_s cn52xxp1;
+	struct cvmx_pciercx_cfg006_s cn56xx;
+	struct cvmx_pciercx_cfg006_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg007 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg007_s {
+		uint32_t dpe:1;
+		uint32_t sse:1;
+		uint32_t rma:1;
+		uint32_t rta:1;
+		uint32_t sta:1;
+		uint32_t devt:2;
+		uint32_t mdpe:1;
+		uint32_t fbb:1;
+		uint32_t reserved_22_22:1;
+		uint32_t m66:1;
+		uint32_t reserved_16_20:5;
+		uint32_t lio_limi:4;
+		uint32_t reserved_9_11:3;
+		uint32_t io32b:1;
+		uint32_t lio_base:4;
+		uint32_t reserved_1_3:3;
+		uint32_t io32a:1;
+	} s;
+	struct cvmx_pciercx_cfg007_s cn52xx;
+	struct cvmx_pciercx_cfg007_s cn52xxp1;
+	struct cvmx_pciercx_cfg007_s cn56xx;
+	struct cvmx_pciercx_cfg007_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg008 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg008_s {
+		uint32_t ml_addr:12;
+		uint32_t reserved_16_19:4;
+		uint32_t mb_addr:12;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pciercx_cfg008_s cn52xx;
+	struct cvmx_pciercx_cfg008_s cn52xxp1;
+	struct cvmx_pciercx_cfg008_s cn56xx;
+	struct cvmx_pciercx_cfg008_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg009 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg009_s {
+		uint32_t lmem_limit:12;
+		uint32_t reserved_17_19:3;
+		uint32_t mem64b:1;
+		uint32_t lmem_base:12;
+		uint32_t reserved_1_3:3;
+		uint32_t mem64a:1;
+	} s;
+	struct cvmx_pciercx_cfg009_s cn52xx;
+	struct cvmx_pciercx_cfg009_s cn52xxp1;
+	struct cvmx_pciercx_cfg009_s cn56xx;
+	struct cvmx_pciercx_cfg009_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg010 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg010_s {
+		uint32_t umem_base:32;
+	} s;
+	struct cvmx_pciercx_cfg010_s cn52xx;
+	struct cvmx_pciercx_cfg010_s cn52xxp1;
+	struct cvmx_pciercx_cfg010_s cn56xx;
+	struct cvmx_pciercx_cfg010_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg011 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg011_s {
+		uint32_t umem_limit:32;
+	} s;
+	struct cvmx_pciercx_cfg011_s cn52xx;
+	struct cvmx_pciercx_cfg011_s cn52xxp1;
+	struct cvmx_pciercx_cfg011_s cn56xx;
+	struct cvmx_pciercx_cfg011_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg012 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg012_s {
+		uint32_t uio_limit:16;
+		uint32_t uio_base:16;
+	} s;
+	struct cvmx_pciercx_cfg012_s cn52xx;
+	struct cvmx_pciercx_cfg012_s cn52xxp1;
+	struct cvmx_pciercx_cfg012_s cn56xx;
+	struct cvmx_pciercx_cfg012_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg013 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg013_s {
+		uint32_t reserved_8_31:24;
+		uint32_t cp:8;
+	} s;
+	struct cvmx_pciercx_cfg013_s cn52xx;
+	struct cvmx_pciercx_cfg013_s cn52xxp1;
+	struct cvmx_pciercx_cfg013_s cn56xx;
+	struct cvmx_pciercx_cfg013_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg014 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg014_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg014_s cn52xx;
+	struct cvmx_pciercx_cfg014_s cn52xxp1;
+	struct cvmx_pciercx_cfg014_s cn56xx;
+	struct cvmx_pciercx_cfg014_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg015 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg015_s {
+		uint32_t reserved_28_31:4;
+		uint32_t dtsees:1;
+		uint32_t dts:1;
+		uint32_t sdt:1;
+		uint32_t pdt:1;
+		uint32_t fbbe:1;
+		uint32_t sbrst:1;
+		uint32_t mam:1;
+		uint32_t vga16d:1;
+		uint32_t vgae:1;
+		uint32_t isae:1;
+		uint32_t see:1;
+		uint32_t pere:1;
+		uint32_t inta:8;
+		uint32_t il:8;
+	} s;
+	struct cvmx_pciercx_cfg015_s cn52xx;
+	struct cvmx_pciercx_cfg015_s cn52xxp1;
+	struct cvmx_pciercx_cfg015_s cn56xx;
+	struct cvmx_pciercx_cfg015_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg016 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg016_s {
+		uint32_t pmes:5;
+		uint32_t d2s:1;
+		uint32_t d1s:1;
+		uint32_t auxc:3;
+		uint32_t dsi:1;
+		uint32_t reserved_20_20:1;
+		uint32_t pme_clock:1;
+		uint32_t pmsv:3;
+		uint32_t ncp:8;
+		uint32_t pmcid:8;
+	} s;
+	struct cvmx_pciercx_cfg016_s cn52xx;
+	struct cvmx_pciercx_cfg016_s cn52xxp1;
+	struct cvmx_pciercx_cfg016_s cn56xx;
+	struct cvmx_pciercx_cfg016_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg017 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg017_s {
+		uint32_t pmdia:8;
+		uint32_t bpccee:1;
+		uint32_t bd3h:1;
+		uint32_t reserved_16_21:6;
+		uint32_t pmess:1;
+		uint32_t pmedsia:2;
+		uint32_t pmds:4;
+		uint32_t pmeens:1;
+		uint32_t reserved_4_7:4;
+		uint32_t nsr:1;
+		uint32_t reserved_2_2:1;
+		uint32_t ps:2;
+	} s;
+	struct cvmx_pciercx_cfg017_s cn52xx;
+	struct cvmx_pciercx_cfg017_s cn52xxp1;
+	struct cvmx_pciercx_cfg017_s cn56xx;
+	struct cvmx_pciercx_cfg017_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg020 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg020_s {
+		uint32_t reserved_24_31:8;
+		uint32_t m64:1;
+		uint32_t mme:3;
+		uint32_t mmc:3;
+		uint32_t msien:1;
+		uint32_t ncp:8;
+		uint32_t msicid:8;
+	} s;
+	struct cvmx_pciercx_cfg020_s cn52xx;
+	struct cvmx_pciercx_cfg020_s cn52xxp1;
+	struct cvmx_pciercx_cfg020_s cn56xx;
+	struct cvmx_pciercx_cfg020_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg021 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg021_s {
+		uint32_t lmsi:30;
+		uint32_t reserved_0_1:2;
+	} s;
+	struct cvmx_pciercx_cfg021_s cn52xx;
+	struct cvmx_pciercx_cfg021_s cn52xxp1;
+	struct cvmx_pciercx_cfg021_s cn56xx;
+	struct cvmx_pciercx_cfg021_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg022 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg022_s {
+		uint32_t umsi:32;
+	} s;
+	struct cvmx_pciercx_cfg022_s cn52xx;
+	struct cvmx_pciercx_cfg022_s cn52xxp1;
+	struct cvmx_pciercx_cfg022_s cn56xx;
+	struct cvmx_pciercx_cfg022_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg023 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg023_s {
+		uint32_t reserved_16_31:16;
+		uint32_t msimd:16;
+	} s;
+	struct cvmx_pciercx_cfg023_s cn52xx;
+	struct cvmx_pciercx_cfg023_s cn52xxp1;
+	struct cvmx_pciercx_cfg023_s cn56xx;
+	struct cvmx_pciercx_cfg023_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg028 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg028_s {
+		uint32_t reserved_30_31:2;
+		uint32_t imn:5;
+		uint32_t si:1;
+		uint32_t dpt:4;
+		uint32_t pciecv:4;
+		uint32_t ncp:8;
+		uint32_t pcieid:8;
+	} s;
+	struct cvmx_pciercx_cfg028_s cn52xx;
+	struct cvmx_pciercx_cfg028_s cn52xxp1;
+	struct cvmx_pciercx_cfg028_s cn56xx;
+	struct cvmx_pciercx_cfg028_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg029 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg029_s {
+		uint32_t reserved_28_31:4;
+		uint32_t cspls:2;
+		uint32_t csplv:8;
+		uint32_t reserved_16_17:2;
+		uint32_t rber:1;
+		uint32_t reserved_12_14:3;
+		uint32_t el1al:3;
+		uint32_t el0al:3;
+		uint32_t etfs:1;
+		uint32_t pfs:2;
+		uint32_t mpss:3;
+	} s;
+	struct cvmx_pciercx_cfg029_s cn52xx;
+	struct cvmx_pciercx_cfg029_s cn52xxp1;
+	struct cvmx_pciercx_cfg029_s cn56xx;
+	struct cvmx_pciercx_cfg029_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg030 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg030_s {
+		uint32_t reserved_22_31:10;
+		uint32_t tp:1;
+		uint32_t ap_d:1;
+		uint32_t ur_d:1;
+		uint32_t fe_d:1;
+		uint32_t nfe_d:1;
+		uint32_t ce_d:1;
+		uint32_t reserved_15_15:1;
+		uint32_t mrrs:3;
+		uint32_t ns_en:1;
+		uint32_t ap_en:1;
+		uint32_t pf_en:1;
+		uint32_t etf_en:1;
+		uint32_t mps:3;
+		uint32_t ro_en:1;
+		uint32_t ur_en:1;
+		uint32_t fe_en:1;
+		uint32_t nfe_en:1;
+		uint32_t ce_en:1;
+	} s;
+	struct cvmx_pciercx_cfg030_s cn52xx;
+	struct cvmx_pciercx_cfg030_s cn52xxp1;
+	struct cvmx_pciercx_cfg030_s cn56xx;
+	struct cvmx_pciercx_cfg030_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg031 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg031_s {
+		uint32_t pnum:8;
+		uint32_t reserved_22_23:2;
+		uint32_t lbnc:1;
+		uint32_t dllarc:1;
+		uint32_t sderc:1;
+		uint32_t cpm:1;
+		uint32_t l1el:3;
+		uint32_t l0el:3;
+		uint32_t aslpms:2;
+		uint32_t mlw:6;
+		uint32_t mls:4;
+	} s;
+	struct cvmx_pciercx_cfg031_s cn52xx;
+	struct cvmx_pciercx_cfg031_s cn52xxp1;
+	struct cvmx_pciercx_cfg031_s cn56xx;
+	struct cvmx_pciercx_cfg031_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg032 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg032_s {
+		uint32_t lab:1;
+		uint32_t lbm:1;
+		uint32_t dlla:1;
+		uint32_t scc:1;
+		uint32_t lt:1;
+		uint32_t reserved_26_26:1;
+		uint32_t nlw:6;
+		uint32_t ls:4;
+		uint32_t reserved_12_15:4;
+		uint32_t lab_int_enb:1;
+		uint32_t lbm_int_enb:1;
+		uint32_t hawd:1;
+		uint32_t ecpm:1;
+		uint32_t es:1;
+		uint32_t ccc:1;
+		uint32_t rl:1;
+		uint32_t ld:1;
+		uint32_t rcb:1;
+		uint32_t reserved_2_2:1;
+		uint32_t aslpc:2;
+	} s;
+	struct cvmx_pciercx_cfg032_s cn52xx;
+	struct cvmx_pciercx_cfg032_s cn52xxp1;
+	struct cvmx_pciercx_cfg032_s cn56xx;
+	struct cvmx_pciercx_cfg032_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg033 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg033_s {
+		uint32_t ps_num:13;
+		uint32_t nccs:1;
+		uint32_t emip:1;
+		uint32_t sp_ls:2;
+		uint32_t sp_lv:8;
+		uint32_t hp_c:1;
+		uint32_t hp_s:1;
+		uint32_t pip:1;
+		uint32_t aip:1;
+		uint32_t mrlsp:1;
+		uint32_t pcp:1;
+		uint32_t abp:1;
+	} s;
+	struct cvmx_pciercx_cfg033_s cn52xx;
+	struct cvmx_pciercx_cfg033_s cn52xxp1;
+	struct cvmx_pciercx_cfg033_s cn56xx;
+	struct cvmx_pciercx_cfg033_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg034 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg034_s {
+		uint32_t reserved_25_31:7;
+		uint32_t dlls_c:1;
+		uint32_t emis:1;
+		uint32_t pds:1;
+		uint32_t mrlss:1;
+		uint32_t ccint_d:1;
+		uint32_t pd_c:1;
+		uint32_t mrls_c:1;
+		uint32_t pf_d:1;
+		uint32_t abp_d:1;
+		uint32_t reserved_13_15:3;
+		uint32_t dlls_en:1;
+		uint32_t emic:1;
+		uint32_t pcc:1;
+		uint32_t pic:2;
+		uint32_t aic:2;
+		uint32_t hpint_en:1;
+		uint32_t ccint_en:1;
+		uint32_t pd_en:1;
+		uint32_t mrls_en:1;
+		uint32_t pf_en:1;
+		uint32_t abp_en:1;
+	} s;
+	struct cvmx_pciercx_cfg034_s cn52xx;
+	struct cvmx_pciercx_cfg034_s cn52xxp1;
+	struct cvmx_pciercx_cfg034_s cn56xx;
+	struct cvmx_pciercx_cfg034_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg035 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg035_s {
+		uint32_t reserved_17_31:15;
+		uint32_t crssv:1;
+		uint32_t reserved_5_15:11;
+		uint32_t crssve:1;
+		uint32_t pmeie:1;
+		uint32_t sefee:1;
+		uint32_t senfee:1;
+		uint32_t secee:1;
+	} s;
+	struct cvmx_pciercx_cfg035_s cn52xx;
+	struct cvmx_pciercx_cfg035_s cn52xxp1;
+	struct cvmx_pciercx_cfg035_s cn56xx;
+	struct cvmx_pciercx_cfg035_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg036 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg036_s {
+		uint32_t reserved_18_31:14;
+		uint32_t pme_pend:1;
+		uint32_t pme_stat:1;
+		uint32_t pme_rid:16;
+	} s;
+	struct cvmx_pciercx_cfg036_s cn52xx;
+	struct cvmx_pciercx_cfg036_s cn52xxp1;
+	struct cvmx_pciercx_cfg036_s cn56xx;
+	struct cvmx_pciercx_cfg036_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg037 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg037_s {
+		uint32_t reserved_5_31:27;
+		uint32_t ctds:1;
+		uint32_t ctrs:4;
+	} s;
+	struct cvmx_pciercx_cfg037_s cn52xx;
+	struct cvmx_pciercx_cfg037_s cn52xxp1;
+	struct cvmx_pciercx_cfg037_s cn56xx;
+	struct cvmx_pciercx_cfg037_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg038 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg038_s {
+		uint32_t reserved_5_31:27;
+		uint32_t ctd:1;
+		uint32_t ctv:4;
+	} s;
+	struct cvmx_pciercx_cfg038_s cn52xx;
+	struct cvmx_pciercx_cfg038_s cn52xxp1;
+	struct cvmx_pciercx_cfg038_s cn56xx;
+	struct cvmx_pciercx_cfg038_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg039 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg039_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg039_s cn52xx;
+	struct cvmx_pciercx_cfg039_s cn52xxp1;
+	struct cvmx_pciercx_cfg039_s cn56xx;
+	struct cvmx_pciercx_cfg039_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg040 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg040_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg040_s cn52xx;
+	struct cvmx_pciercx_cfg040_s cn52xxp1;
+	struct cvmx_pciercx_cfg040_s cn56xx;
+	struct cvmx_pciercx_cfg040_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg041 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg041_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg041_s cn52xx;
+	struct cvmx_pciercx_cfg041_s cn52xxp1;
+	struct cvmx_pciercx_cfg041_s cn56xx;
+	struct cvmx_pciercx_cfg041_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg042 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg042_s {
+		uint32_t reserved_0_31:32;
+	} s;
+	struct cvmx_pciercx_cfg042_s cn52xx;
+	struct cvmx_pciercx_cfg042_s cn52xxp1;
+	struct cvmx_pciercx_cfg042_s cn56xx;
+	struct cvmx_pciercx_cfg042_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg064 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg064_s {
+		uint32_t nco:12;
+		uint32_t cv:4;
+		uint32_t pcieec:16;
+	} s;
+	struct cvmx_pciercx_cfg064_s cn52xx;
+	struct cvmx_pciercx_cfg064_s cn52xxp1;
+	struct cvmx_pciercx_cfg064_s cn56xx;
+	struct cvmx_pciercx_cfg064_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg065 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg065_s {
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pciercx_cfg065_s cn52xx;
+	struct cvmx_pciercx_cfg065_s cn52xxp1;
+	struct cvmx_pciercx_cfg065_s cn56xx;
+	struct cvmx_pciercx_cfg065_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg066 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg066_s {
+		uint32_t reserved_21_31:11;
+		uint32_t urem:1;
+		uint32_t ecrcem:1;
+		uint32_t mtlpm:1;
+		uint32_t rom:1;
+		uint32_t ucm:1;
+		uint32_t cam:1;
+		uint32_t ctm:1;
+		uint32_t fcpem:1;
+		uint32_t ptlpm:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdem:1;
+		uint32_t dlpem:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pciercx_cfg066_s cn52xx;
+	struct cvmx_pciercx_cfg066_s cn52xxp1;
+	struct cvmx_pciercx_cfg066_s cn56xx;
+	struct cvmx_pciercx_cfg066_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg067 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg067_s {
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+	} s;
+	struct cvmx_pciercx_cfg067_s cn52xx;
+	struct cvmx_pciercx_cfg067_s cn52xxp1;
+	struct cvmx_pciercx_cfg067_s cn56xx;
+	struct cvmx_pciercx_cfg067_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg068 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg068_s {
+		uint32_t reserved_14_31:18;
+		uint32_t anfes:1;
+		uint32_t rtts:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrs:1;
+		uint32_t bdllps:1;
+		uint32_t btlps:1;
+		uint32_t reserved_1_5:5;
+		uint32_t res:1;
+	} s;
+	struct cvmx_pciercx_cfg068_s cn52xx;
+	struct cvmx_pciercx_cfg068_s cn52xxp1;
+	struct cvmx_pciercx_cfg068_s cn56xx;
+	struct cvmx_pciercx_cfg068_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg069 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg069_s {
+		uint32_t reserved_14_31:18;
+		uint32_t anfem:1;
+		uint32_t rttm:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrm:1;
+		uint32_t bdllpm:1;
+		uint32_t btlpm:1;
+		uint32_t reserved_1_5:5;
+		uint32_t rem:1;
+	} s;
+	struct cvmx_pciercx_cfg069_s cn52xx;
+	struct cvmx_pciercx_cfg069_s cn52xxp1;
+	struct cvmx_pciercx_cfg069_s cn56xx;
+	struct cvmx_pciercx_cfg069_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg070 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg070_s {
+		uint32_t reserved_9_31:23;
+		uint32_t ce:1;
+		uint32_t cc:1;
+		uint32_t ge:1;
+		uint32_t gc:1;
+		uint32_t fep:5;
+	} s;
+	struct cvmx_pciercx_cfg070_s cn52xx;
+	struct cvmx_pciercx_cfg070_s cn52xxp1;
+	struct cvmx_pciercx_cfg070_s cn56xx;
+	struct cvmx_pciercx_cfg070_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg071 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg071_s {
+		uint32_t dword1:32;
+	} s;
+	struct cvmx_pciercx_cfg071_s cn52xx;
+	struct cvmx_pciercx_cfg071_s cn52xxp1;
+	struct cvmx_pciercx_cfg071_s cn56xx;
+	struct cvmx_pciercx_cfg071_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg072 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg072_s {
+		uint32_t dword2:32;
+	} s;
+	struct cvmx_pciercx_cfg072_s cn52xx;
+	struct cvmx_pciercx_cfg072_s cn52xxp1;
+	struct cvmx_pciercx_cfg072_s cn56xx;
+	struct cvmx_pciercx_cfg072_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg073 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg073_s {
+		uint32_t dword3:32;
+	} s;
+	struct cvmx_pciercx_cfg073_s cn52xx;
+	struct cvmx_pciercx_cfg073_s cn52xxp1;
+	struct cvmx_pciercx_cfg073_s cn56xx;
+	struct cvmx_pciercx_cfg073_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg074 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg074_s {
+		uint32_t dword4:32;
+	} s;
+	struct cvmx_pciercx_cfg074_s cn52xx;
+	struct cvmx_pciercx_cfg074_s cn52xxp1;
+	struct cvmx_pciercx_cfg074_s cn56xx;
+	struct cvmx_pciercx_cfg074_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg075 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg075_s {
+		uint32_t reserved_3_31:29;
+		uint32_t fere:1;
+		uint32_t nfere:1;
+		uint32_t cere:1;
+	} s;
+	struct cvmx_pciercx_cfg075_s cn52xx;
+	struct cvmx_pciercx_cfg075_s cn52xxp1;
+	struct cvmx_pciercx_cfg075_s cn56xx;
+	struct cvmx_pciercx_cfg075_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg076 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg076_s {
+		uint32_t aeimn:5;
+		uint32_t reserved_7_26:20;
+		uint32_t femr:1;
+		uint32_t nfemr:1;
+		uint32_t fuf:1;
+		uint32_t multi_efnfr:1;
+		uint32_t efnfr:1;
+		uint32_t multi_ecr:1;
+		uint32_t ecr:1;
+	} s;
+	struct cvmx_pciercx_cfg076_s cn52xx;
+	struct cvmx_pciercx_cfg076_s cn52xxp1;
+	struct cvmx_pciercx_cfg076_s cn56xx;
+	struct cvmx_pciercx_cfg076_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg077 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg077_s {
+		uint32_t efnfsi:16;
+		uint32_t ecsi:16;
+	} s;
+	struct cvmx_pciercx_cfg077_s cn52xx;
+	struct cvmx_pciercx_cfg077_s cn52xxp1;
+	struct cvmx_pciercx_cfg077_s cn56xx;
+	struct cvmx_pciercx_cfg077_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg448 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg448_s {
+		uint32_t rtl:16;
+		uint32_t rtltl:16;
+	} s;
+	struct cvmx_pciercx_cfg448_s cn52xx;
+	struct cvmx_pciercx_cfg448_s cn52xxp1;
+	struct cvmx_pciercx_cfg448_s cn56xx;
+	struct cvmx_pciercx_cfg448_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg449 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg449_s {
+		uint32_t omr:32;
+	} s;
+	struct cvmx_pciercx_cfg449_s cn52xx;
+	struct cvmx_pciercx_cfg449_s cn52xxp1;
+	struct cvmx_pciercx_cfg449_s cn56xx;
+	struct cvmx_pciercx_cfg449_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg450 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg450_s {
+		uint32_t lpec:8;
+		uint32_t reserved_22_23:2;
+		uint32_t link_state:6;
+		uint32_t force_link:1;
+		uint32_t reserved_8_14:7;
+		uint32_t link_num:8;
+	} s;
+	struct cvmx_pciercx_cfg450_s cn52xx;
+	struct cvmx_pciercx_cfg450_s cn52xxp1;
+	struct cvmx_pciercx_cfg450_s cn56xx;
+	struct cvmx_pciercx_cfg450_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg451 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg451_s {
+		uint32_t reserved_30_31:2;
+		uint32_t l1el:3;
+		uint32_t l0el:3;
+		uint32_t n_fts_cc:8;
+		uint32_t n_fts:8;
+		uint32_t ack_freq:8;
+	} s;
+	struct cvmx_pciercx_cfg451_s cn52xx;
+	struct cvmx_pciercx_cfg451_s cn52xxp1;
+	struct cvmx_pciercx_cfg451_s cn56xx;
+	struct cvmx_pciercx_cfg451_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg452 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg452_s {
+		uint32_t reserved_26_31:6;
+		uint32_t eccrc:1;
+		uint32_t reserved_22_24:3;
+		uint32_t lme:6;
+		uint32_t reserved_8_15:8;
+		uint32_t flm:1;
+		uint32_t reserved_6_6:1;
+		uint32_t dllle:1;
+		uint32_t reserved_4_4:1;
+		uint32_t ra:1;
+		uint32_t le:1;
+		uint32_t sd:1;
+		uint32_t omr:1;
+	} s;
+	struct cvmx_pciercx_cfg452_s cn52xx;
+	struct cvmx_pciercx_cfg452_s cn52xxp1;
+	struct cvmx_pciercx_cfg452_s cn56xx;
+	struct cvmx_pciercx_cfg452_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg453 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg453_s {
+		uint32_t dlld:1;
+		uint32_t reserved_26_30:5;
+		uint32_t ack_nak:1;
+		uint32_t fcd:1;
+		uint32_t ilst:24;
+	} s;
+	struct cvmx_pciercx_cfg453_s cn52xx;
+	struct cvmx_pciercx_cfg453_s cn52xxp1;
+	struct cvmx_pciercx_cfg453_s cn56xx;
+	struct cvmx_pciercx_cfg453_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg454 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg454_s {
+		uint32_t reserved_29_31:3;
+		uint32_t tmfcwt:5;
+		uint32_t tmanlt:5;
+		uint32_t tmrt:5;
+		uint32_t reserved_11_13:3;
+		uint32_t nskps:3;
+		uint32_t reserved_4_7:4;
+		uint32_t ntss:4;
+	} s;
+	struct cvmx_pciercx_cfg454_s cn52xx;
+	struct cvmx_pciercx_cfg454_s cn52xxp1;
+	struct cvmx_pciercx_cfg454_s cn56xx;
+	struct cvmx_pciercx_cfg454_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg455 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg455_s {
+		uint32_t m_cfg0_filt:1;
+		uint32_t m_io_filt:1;
+		uint32_t msg_ctrl:1;
+		uint32_t m_cpl_ecrc_filt:1;
+		uint32_t m_ecrc_filt:1;
+		uint32_t m_cpl_len_err:1;
+		uint32_t m_cpl_attr_err:1;
+		uint32_t m_cpl_tc_err:1;
+		uint32_t m_cpl_fun_err:1;
+		uint32_t m_cpl_rid_err:1;
+		uint32_t m_cpl_tag_err:1;
+		uint32_t m_lk_filt:1;
+		uint32_t m_cfg1_filt:1;
+		uint32_t m_bar_match:1;
+		uint32_t m_pois_filt:1;
+		uint32_t m_fun:1;
+		uint32_t dfcwt:1;
+		uint32_t reserved_11_14:4;
+		uint32_t skpiv:11;
+	} s;
+	struct cvmx_pciercx_cfg455_s cn52xx;
+	struct cvmx_pciercx_cfg455_s cn52xxp1;
+	struct cvmx_pciercx_cfg455_s cn56xx;
+	struct cvmx_pciercx_cfg455_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg456 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg456_s {
+		uint32_t reserved_2_31:30;
+		uint32_t m_vend1_drp:1;
+		uint32_t m_vend0_drp:1;
+	} s;
+	struct cvmx_pciercx_cfg456_s cn52xx;
+	struct cvmx_pciercx_cfg456_s cn52xxp1;
+	struct cvmx_pciercx_cfg456_s cn56xx;
+	struct cvmx_pciercx_cfg456_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg458 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg458_s {
+		uint32_t dbg_info_l32:32;
+	} s;
+	struct cvmx_pciercx_cfg458_s cn52xx;
+	struct cvmx_pciercx_cfg458_s cn52xxp1;
+	struct cvmx_pciercx_cfg458_s cn56xx;
+	struct cvmx_pciercx_cfg458_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg459 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg459_s {
+		uint32_t dbg_info_u32:32;
+	} s;
+	struct cvmx_pciercx_cfg459_s cn52xx;
+	struct cvmx_pciercx_cfg459_s cn52xxp1;
+	struct cvmx_pciercx_cfg459_s cn56xx;
+	struct cvmx_pciercx_cfg459_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg460 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg460_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tphfcc:8;
+		uint32_t tpdfcc:12;
+	} s;
+	struct cvmx_pciercx_cfg460_s cn52xx;
+	struct cvmx_pciercx_cfg460_s cn52xxp1;
+	struct cvmx_pciercx_cfg460_s cn56xx;
+	struct cvmx_pciercx_cfg460_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg461 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg461_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tchfcc:8;
+		uint32_t tcdfcc:12;
+	} s;
+	struct cvmx_pciercx_cfg461_s cn52xx;
+	struct cvmx_pciercx_cfg461_s cn52xxp1;
+	struct cvmx_pciercx_cfg461_s cn56xx;
+	struct cvmx_pciercx_cfg461_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg462 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg462_s {
+		uint32_t reserved_20_31:12;
+		uint32_t tchfcc:8;
+		uint32_t tcdfcc:12;
+	} s;
+	struct cvmx_pciercx_cfg462_s cn52xx;
+	struct cvmx_pciercx_cfg462_s cn52xxp1;
+	struct cvmx_pciercx_cfg462_s cn56xx;
+	struct cvmx_pciercx_cfg462_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg463 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg463_s {
+		uint32_t reserved_3_31:29;
+		uint32_t rqne:1;
+		uint32_t trbne:1;
+		uint32_t rtlpfccnr:1;
+	} s;
+	struct cvmx_pciercx_cfg463_s cn52xx;
+	struct cvmx_pciercx_cfg463_s cn52xxp1;
+	struct cvmx_pciercx_cfg463_s cn56xx;
+	struct cvmx_pciercx_cfg463_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg464 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg464_s {
+		uint32_t wrr_vc3:8;
+		uint32_t wrr_vc2:8;
+		uint32_t wrr_vc1:8;
+		uint32_t wrr_vc0:8;
+	} s;
+	struct cvmx_pciercx_cfg464_s cn52xx;
+	struct cvmx_pciercx_cfg464_s cn52xxp1;
+	struct cvmx_pciercx_cfg464_s cn56xx;
+	struct cvmx_pciercx_cfg464_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg465 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg465_s {
+		uint32_t wrr_vc7:8;
+		uint32_t wrr_vc6:8;
+		uint32_t wrr_vc5:8;
+		uint32_t wrr_vc4:8;
+	} s;
+	struct cvmx_pciercx_cfg465_s cn52xx;
+	struct cvmx_pciercx_cfg465_s cn52xxp1;
+	struct cvmx_pciercx_cfg465_s cn56xx;
+	struct cvmx_pciercx_cfg465_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg466 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg466_s {
+		uint32_t rx_queue_order:1;
+		uint32_t type_ordering:1;
+		uint32_t reserved_24_29:6;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pciercx_cfg466_s cn52xx;
+	struct cvmx_pciercx_cfg466_s cn52xxp1;
+	struct cvmx_pciercx_cfg466_s cn56xx;
+	struct cvmx_pciercx_cfg466_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg467 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg467_s {
+		uint32_t reserved_24_31:8;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pciercx_cfg467_s cn52xx;
+	struct cvmx_pciercx_cfg467_s cn52xxp1;
+	struct cvmx_pciercx_cfg467_s cn56xx;
+	struct cvmx_pciercx_cfg467_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg468 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg468_s {
+		uint32_t reserved_24_31:8;
+		uint32_t queue_mode:3;
+		uint32_t reserved_20_20:1;
+		uint32_t header_credits:8;
+		uint32_t data_credits:12;
+	} s;
+	struct cvmx_pciercx_cfg468_s cn52xx;
+	struct cvmx_pciercx_cfg468_s cn52xxp1;
+	struct cvmx_pciercx_cfg468_s cn56xx;
+	struct cvmx_pciercx_cfg468_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg490 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg490_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pciercx_cfg490_s cn52xx;
+	struct cvmx_pciercx_cfg490_s cn52xxp1;
+	struct cvmx_pciercx_cfg490_s cn56xx;
+	struct cvmx_pciercx_cfg490_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg491 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg491_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pciercx_cfg491_s cn52xx;
+	struct cvmx_pciercx_cfg491_s cn52xxp1;
+	struct cvmx_pciercx_cfg491_s cn56xx;
+	struct cvmx_pciercx_cfg491_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg492 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg492_s {
+		uint32_t reserved_26_31:6;
+		uint32_t header_depth:10;
+		uint32_t reserved_14_15:2;
+		uint32_t data_depth:14;
+	} s;
+	struct cvmx_pciercx_cfg492_s cn52xx;
+	struct cvmx_pciercx_cfg492_s cn52xxp1;
+	struct cvmx_pciercx_cfg492_s cn56xx;
+	struct cvmx_pciercx_cfg492_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg516 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg516_s {
+		uint32_t phy_stat:32;
+	} s;
+	struct cvmx_pciercx_cfg516_s cn52xx;
+	struct cvmx_pciercx_cfg516_s cn52xxp1;
+	struct cvmx_pciercx_cfg516_s cn56xx;
+	struct cvmx_pciercx_cfg516_s cn56xxp1;
+};
+
+union cvmx_pciercx_cfg517 {
+	uint32_t u32;
+	struct cvmx_pciercx_cfg517_s {
+		uint32_t phy_ctrl:32;
+	} s;
+	struct cvmx_pciercx_cfg517_s cn52xx;
+	struct cvmx_pciercx_cfg517_s cn52xxp1;
+	struct cvmx_pciercx_cfg517_s cn56xx;
+	struct cvmx_pciercx_cfg517_s cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
new file mode 100644
index 0000000..f40cfaf
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -0,0 +1,410 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PESCX_DEFS_H__
+#define __CVMX_PESCX_DEFS_H__
+
+#define CVMX_PESCX_BIST_STATUS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000018ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_BIST_STATUS2(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000418ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CFG_RD(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000030ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CFG_WR(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000028ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CPL_LUT_VALID(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000098ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CTL_STATUS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000000ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_CTL_STATUS2(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000400ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DBG_INFO(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000008ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DBG_INFO_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C80000A0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_DIAG_STATUS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000020ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR0_START(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000080ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR1_START(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000088ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2N_BAR2_START(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000090ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2P_BARX_END(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000048ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_P2P_BARX_START(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000040ull + (((offset) & 3) * 16) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PESCX_TLP_CREDITS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800C8000038ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_pescx_bist_status {
+	uint64_t u64;
+	struct cvmx_pescx_bist_status_s {
+		uint64_t reserved_13_63:51;
+		uint64_t rqdata5:1;
+		uint64_t ctlp_or:1;
+		uint64_t ntlp_or:1;
+		uint64_t ptlp_or:1;
+		uint64_t retry:1;
+		uint64_t rqdata0:1;
+		uint64_t rqdata1:1;
+		uint64_t rqdata2:1;
+		uint64_t rqdata3:1;
+		uint64_t rqdata4:1;
+		uint64_t rqhdr1:1;
+		uint64_t rqhdr0:1;
+		uint64_t sot:1;
+	} s;
+	struct cvmx_pescx_bist_status_s cn52xx;
+	struct cvmx_pescx_bist_status_cn52xxp1 {
+		uint64_t reserved_12_63:52;
+		uint64_t ctlp_or:1;
+		uint64_t ntlp_or:1;
+		uint64_t ptlp_or:1;
+		uint64_t retry:1;
+		uint64_t rqdata0:1;
+		uint64_t rqdata1:1;
+		uint64_t rqdata2:1;
+		uint64_t rqdata3:1;
+		uint64_t rqdata4:1;
+		uint64_t rqhdr1:1;
+		uint64_t rqhdr0:1;
+		uint64_t sot:1;
+	} cn52xxp1;
+	struct cvmx_pescx_bist_status_s cn56xx;
+	struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_bist_status2 {
+	uint64_t u64;
+	struct cvmx_pescx_bist_status2_s {
+		uint64_t reserved_14_63:50;
+		uint64_t cto_p2e:1;
+		uint64_t e2p_cpl:1;
+		uint64_t e2p_n:1;
+		uint64_t e2p_p:1;
+		uint64_t e2p_rsl:1;
+		uint64_t dbg_p2e:1;
+		uint64_t peai_p2e:1;
+		uint64_t rsl_p2e:1;
+		uint64_t pef_tpf1:1;
+		uint64_t pef_tpf0:1;
+		uint64_t pef_tnf:1;
+		uint64_t pef_tcf1:1;
+		uint64_t pef_tc0:1;
+		uint64_t ppf:1;
+	} s;
+	struct cvmx_pescx_bist_status2_s cn52xx;
+	struct cvmx_pescx_bist_status2_s cn52xxp1;
+	struct cvmx_pescx_bist_status2_s cn56xx;
+	struct cvmx_pescx_bist_status2_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_rd {
+	uint64_t u64;
+	struct cvmx_pescx_cfg_rd_s {
+		uint64_t data:32;
+		uint64_t addr:32;
+	} s;
+	struct cvmx_pescx_cfg_rd_s cn52xx;
+	struct cvmx_pescx_cfg_rd_s cn52xxp1;
+	struct cvmx_pescx_cfg_rd_s cn56xx;
+	struct cvmx_pescx_cfg_rd_s cn56xxp1;
+};
+
+union cvmx_pescx_cfg_wr {
+	uint64_t u64;
+	struct cvmx_pescx_cfg_wr_s {
+		uint64_t data:32;
+		uint64_t addr:32;
+	} s;
+	struct cvmx_pescx_cfg_wr_s cn52xx;
+	struct cvmx_pescx_cfg_wr_s cn52xxp1;
+	struct cvmx_pescx_cfg_wr_s cn56xx;
+	struct cvmx_pescx_cfg_wr_s cn56xxp1;
+};
+
+union cvmx_pescx_cpl_lut_valid {
+	uint64_t u64;
+	struct cvmx_pescx_cpl_lut_valid_s {
+		uint64_t reserved_32_63:32;
+		uint64_t tag:32;
+	} s;
+	struct cvmx_pescx_cpl_lut_valid_s cn52xx;
+	struct cvmx_pescx_cpl_lut_valid_s cn52xxp1;
+	struct cvmx_pescx_cpl_lut_valid_s cn56xx;
+	struct cvmx_pescx_cpl_lut_valid_s cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status {
+	uint64_t u64;
+	struct cvmx_pescx_ctl_status_s {
+		uint64_t reserved_28_63:36;
+		uint64_t dnum:5;
+		uint64_t pbus:8;
+		uint64_t qlm_cfg:2;
+		uint64_t lane_swp:1;
+		uint64_t pm_xtoff:1;
+		uint64_t pm_xpme:1;
+		uint64_t ob_p_cmd:1;
+		uint64_t reserved_7_8:2;
+		uint64_t nf_ecrc:1;
+		uint64_t dly_one:1;
+		uint64_t lnk_enb:1;
+		uint64_t ro_ctlp:1;
+		uint64_t reserved_2_2:1;
+		uint64_t inv_ecrc:1;
+		uint64_t inv_lcrc:1;
+	} s;
+	struct cvmx_pescx_ctl_status_s cn52xx;
+	struct cvmx_pescx_ctl_status_s cn52xxp1;
+	struct cvmx_pescx_ctl_status_cn56xx {
+		uint64_t reserved_28_63:36;
+		uint64_t dnum:5;
+		uint64_t pbus:8;
+		uint64_t qlm_cfg:2;
+		uint64_t reserved_12_12:1;
+		uint64_t pm_xtoff:1;
+		uint64_t pm_xpme:1;
+		uint64_t ob_p_cmd:1;
+		uint64_t reserved_7_8:2;
+		uint64_t nf_ecrc:1;
+		uint64_t dly_one:1;
+		uint64_t lnk_enb:1;
+		uint64_t ro_ctlp:1;
+		uint64_t reserved_2_2:1;
+		uint64_t inv_ecrc:1;
+		uint64_t inv_lcrc:1;
+	} cn56xx;
+	struct cvmx_pescx_ctl_status_cn56xx cn56xxp1;
+};
+
+union cvmx_pescx_ctl_status2 {
+	uint64_t u64;
+	struct cvmx_pescx_ctl_status2_s {
+		uint64_t reserved_2_63:62;
+		uint64_t pclk_run:1;
+		uint64_t pcierst:1;
+	} s;
+	struct cvmx_pescx_ctl_status2_s cn52xx;
+	struct cvmx_pescx_ctl_status2_cn52xxp1 {
+		uint64_t reserved_1_63:63;
+		uint64_t pcierst:1;
+	} cn52xxp1;
+	struct cvmx_pescx_ctl_status2_s cn56xx;
+	struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info {
+	uint64_t u64;
+	struct cvmx_pescx_dbg_info_s {
+		uint64_t reserved_31_63:33;
+		uint64_t ecrc_e:1;
+		uint64_t rawwpp:1;
+		uint64_t racpp:1;
+		uint64_t ramtlp:1;
+		uint64_t rarwdns:1;
+		uint64_t caar:1;
+		uint64_t racca:1;
+		uint64_t racur:1;
+		uint64_t rauc:1;
+		uint64_t rqo:1;
+		uint64_t fcuv:1;
+		uint64_t rpe:1;
+		uint64_t fcpvwt:1;
+		uint64_t dpeoosd:1;
+		uint64_t rtwdle:1;
+		uint64_t rdwdle:1;
+		uint64_t mre:1;
+		uint64_t rte:1;
+		uint64_t acto:1;
+		uint64_t rvdm:1;
+		uint64_t rumep:1;
+		uint64_t rptamrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rfemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rcemrc:1;
+		uint64_t rpoison:1;
+		uint64_t recrce:1;
+		uint64_t rtlplle:1;
+		uint64_t rtlpmal:1;
+		uint64_t spoison:1;
+	} s;
+	struct cvmx_pescx_dbg_info_s cn52xx;
+	struct cvmx_pescx_dbg_info_s cn52xxp1;
+	struct cvmx_pescx_dbg_info_s cn56xx;
+	struct cvmx_pescx_dbg_info_s cn56xxp1;
+};
+
+union cvmx_pescx_dbg_info_en {
+	uint64_t u64;
+	struct cvmx_pescx_dbg_info_en_s {
+		uint64_t reserved_31_63:33;
+		uint64_t ecrc_e:1;
+		uint64_t rawwpp:1;
+		uint64_t racpp:1;
+		uint64_t ramtlp:1;
+		uint64_t rarwdns:1;
+		uint64_t caar:1;
+		uint64_t racca:1;
+		uint64_t racur:1;
+		uint64_t rauc:1;
+		uint64_t rqo:1;
+		uint64_t fcuv:1;
+		uint64_t rpe:1;
+		uint64_t fcpvwt:1;
+		uint64_t dpeoosd:1;
+		uint64_t rtwdle:1;
+		uint64_t rdwdle:1;
+		uint64_t mre:1;
+		uint64_t rte:1;
+		uint64_t acto:1;
+		uint64_t rvdm:1;
+		uint64_t rumep:1;
+		uint64_t rptamrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rfemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rcemrc:1;
+		uint64_t rpoison:1;
+		uint64_t recrce:1;
+		uint64_t rtlplle:1;
+		uint64_t rtlpmal:1;
+		uint64_t spoison:1;
+	} s;
+	struct cvmx_pescx_dbg_info_en_s cn52xx;
+	struct cvmx_pescx_dbg_info_en_s cn52xxp1;
+	struct cvmx_pescx_dbg_info_en_s cn56xx;
+	struct cvmx_pescx_dbg_info_en_s cn56xxp1;
+};
+
+union cvmx_pescx_diag_status {
+	uint64_t u64;
+	struct cvmx_pescx_diag_status_s {
+		uint64_t reserved_4_63:60;
+		uint64_t pm_dst:1;
+		uint64_t pm_stat:1;
+		uint64_t pm_en:1;
+		uint64_t aux_en:1;
+	} s;
+	struct cvmx_pescx_diag_status_s cn52xx;
+	struct cvmx_pescx_diag_status_s cn52xxp1;
+	struct cvmx_pescx_diag_status_s cn56xx;
+	struct cvmx_pescx_diag_status_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar0_start {
+	uint64_t u64;
+	struct cvmx_pescx_p2n_bar0_start_s {
+		uint64_t addr:50;
+		uint64_t reserved_0_13:14;
+	} s;
+	struct cvmx_pescx_p2n_bar0_start_s cn52xx;
+	struct cvmx_pescx_p2n_bar0_start_s cn52xxp1;
+	struct cvmx_pescx_p2n_bar0_start_s cn56xx;
+	struct cvmx_pescx_p2n_bar0_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar1_start {
+	uint64_t u64;
+	struct cvmx_pescx_p2n_bar1_start_s {
+		uint64_t addr:38;
+		uint64_t reserved_0_25:26;
+	} s;
+	struct cvmx_pescx_p2n_bar1_start_s cn52xx;
+	struct cvmx_pescx_p2n_bar1_start_s cn52xxp1;
+	struct cvmx_pescx_p2n_bar1_start_s cn56xx;
+	struct cvmx_pescx_p2n_bar1_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2n_bar2_start {
+	uint64_t u64;
+	struct cvmx_pescx_p2n_bar2_start_s {
+		uint64_t addr:25;
+		uint64_t reserved_0_38:39;
+	} s;
+	struct cvmx_pescx_p2n_bar2_start_s cn52xx;
+	struct cvmx_pescx_p2n_bar2_start_s cn52xxp1;
+	struct cvmx_pescx_p2n_bar2_start_s cn56xx;
+	struct cvmx_pescx_p2n_bar2_start_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_end {
+	uint64_t u64;
+	struct cvmx_pescx_p2p_barx_end_s {
+		uint64_t addr:52;
+		uint64_t reserved_0_11:12;
+	} s;
+	struct cvmx_pescx_p2p_barx_end_s cn52xx;
+	struct cvmx_pescx_p2p_barx_end_s cn52xxp1;
+	struct cvmx_pescx_p2p_barx_end_s cn56xx;
+	struct cvmx_pescx_p2p_barx_end_s cn56xxp1;
+};
+
+union cvmx_pescx_p2p_barx_start {
+	uint64_t u64;
+	struct cvmx_pescx_p2p_barx_start_s {
+		uint64_t addr:52;
+		uint64_t reserved_0_11:12;
+	} s;
+	struct cvmx_pescx_p2p_barx_start_s cn52xx;
+	struct cvmx_pescx_p2p_barx_start_s cn52xxp1;
+	struct cvmx_pescx_p2p_barx_start_s cn56xx;
+	struct cvmx_pescx_p2p_barx_start_s cn56xxp1;
+};
+
+union cvmx_pescx_tlp_credits {
+	uint64_t u64;
+	struct cvmx_pescx_tlp_credits_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pescx_tlp_credits_cn52xx {
+		uint64_t reserved_56_63:8;
+		uint64_t peai_ppf:8;
+		uint64_t pesc_cpl:8;
+		uint64_t pesc_np:8;
+		uint64_t pesc_p:8;
+		uint64_t npei_cpl:8;
+		uint64_t npei_np:8;
+		uint64_t npei_p:8;
+	} cn52xx;
+	struct cvmx_pescx_tlp_credits_cn52xxp1 {
+		uint64_t reserved_38_63:26;
+		uint64_t peai_ppf:8;
+		uint64_t pesc_cpl:5;
+		uint64_t pesc_np:5;
+		uint64_t pesc_p:5;
+		uint64_t npei_cpl:5;
+		uint64_t npei_np:5;
+		uint64_t npei_p:5;
+	} cn52xxp1;
+	struct cvmx_pescx_tlp_credits_cn52xx cn56xx;
+	struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
new file mode 100644
index 0000000..5ea5dc5
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -0,0 +1,229 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * cvmx-pexp-defs.h
+ *
+ * Configuration and status register (CSR) definitions for
+ * OCTEON PEXP.
+ *
+ */
+#ifndef __CVMX_PEXP_DEFS_H__
+#define __CVMX_PEXP_DEFS_H__
+
+#define CVMX_PEXP_NPEI_BAR1_INDEXX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000008000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_BIST_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011F0000008580ull)
+#define CVMX_PEXP_NPEI_BIST_STATUS2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008680ull)
+#define CVMX_PEXP_NPEI_CTL_PORT0 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008250ull)
+#define CVMX_PEXP_NPEI_CTL_PORT1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008260ull)
+#define CVMX_PEXP_NPEI_CTL_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011F0000008570ull)
+#define CVMX_PEXP_NPEI_CTL_STATUS2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC00ull)
+#define CVMX_PEXP_NPEI_DATA_OUT_CNT \
+	 CVMX_ADD_IO_SEG(0x00011F00000085F0ull)
+#define CVMX_PEXP_NPEI_DBG_DATA \
+	 CVMX_ADD_IO_SEG(0x00011F0000008510ull)
+#define CVMX_PEXP_NPEI_DBG_SELECT \
+	 CVMX_ADD_IO_SEG(0x00011F0000008500ull)
+#define CVMX_PEXP_NPEI_DMA0_INT_LEVEL \
+	 CVMX_ADD_IO_SEG(0x00011F00000085C0ull)
+#define CVMX_PEXP_NPEI_DMA1_INT_LEVEL \
+	 CVMX_ADD_IO_SEG(0x00011F00000085D0ull)
+#define CVMX_PEXP_NPEI_DMAX_COUNTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000008450ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_DBELL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000083B0ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_IBUFF_SADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000008400ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMAX_NADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F00000084A0ull + (((offset) & 7) * 16))
+#define CVMX_PEXP_NPEI_DMA_CNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000085E0ull)
+#define CVMX_PEXP_NPEI_DMA_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F00000083A0ull)
+#define CVMX_PEXP_NPEI_INT_A_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000008560ull)
+#define CVMX_PEXP_NPEI_INT_A_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCE0ull)
+#define CVMX_PEXP_NPEI_INT_A_SUM \
+	 CVMX_ADD_IO_SEG(0x00011F0000008550ull)
+#define CVMX_PEXP_NPEI_INT_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000008540ull)
+#define CVMX_PEXP_NPEI_INT_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCD0ull)
+#define CVMX_PEXP_NPEI_INT_INFO \
+	 CVMX_ADD_IO_SEG(0x00011F0000008590ull)
+#define CVMX_PEXP_NPEI_INT_SUM \
+	 CVMX_ADD_IO_SEG(0x00011F0000008530ull)
+#define CVMX_PEXP_NPEI_INT_SUM2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCC0ull)
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA0 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008600ull)
+#define CVMX_PEXP_NPEI_LAST_WIN_RDATA1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008610ull)
+#define CVMX_PEXP_NPEI_MEM_ACCESS_CTL \
+	 CVMX_ADD_IO_SEG(0x00011F00000084F0ull)
+#define CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000008280ull + (((offset) & 31) * 16) - 16 * 12)
+#define CVMX_PEXP_NPEI_MSI_ENB0 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC50ull)
+#define CVMX_PEXP_NPEI_MSI_ENB1 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC60ull)
+#define CVMX_PEXP_NPEI_MSI_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC70ull)
+#define CVMX_PEXP_NPEI_MSI_ENB3 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC80ull)
+#define CVMX_PEXP_NPEI_MSI_RCV0 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC10ull)
+#define CVMX_PEXP_NPEI_MSI_RCV1 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC20ull)
+#define CVMX_PEXP_NPEI_MSI_RCV2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC30ull)
+#define CVMX_PEXP_NPEI_MSI_RCV3 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC40ull)
+#define CVMX_PEXP_NPEI_MSI_RD_MAP \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCA0ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB0 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCF0ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB1 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD00ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD10ull)
+#define CVMX_PEXP_NPEI_MSI_W1C_ENB3 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD20ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB0 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD30ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB1 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD40ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB2 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD50ull)
+#define CVMX_PEXP_NPEI_MSI_W1S_ENB3 \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD60ull)
+#define CVMX_PEXP_NPEI_MSI_WR_MAP \
+	 CVMX_ADD_IO_SEG(0x00011F000000BC90ull)
+#define CVMX_PEXP_NPEI_PCIE_CREDIT_CNT \
+	 CVMX_ADD_IO_SEG(0x00011F000000BD70ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV \
+	 CVMX_ADD_IO_SEG(0x00011F000000BCB0ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008650ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008660ull)
+#define CVMX_PEXP_NPEI_PCIE_MSI_RCV_B3 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008670ull)
+#define CVMX_PEXP_NPEI_PKTX_CNTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000A400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000A800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_BAOFF_DBELL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000AC00ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_FIFO_RSIZE(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000B000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_INSTR_HEADER(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000B400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_IN_BP(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000B800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BADDR(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000009400ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_BAOFF_DBELL(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000009800ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKTX_SLIST_FIFO_RSIZE(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F0000009C00ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKT_CNT_INT \
+	 CVMX_ADD_IO_SEG(0x00011F0000009110ull)
+#define CVMX_PEXP_NPEI_PKT_CNT_INT_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000009130ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ES \
+	 CVMX_ADD_IO_SEG(0x00011F00000090B0ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_NS \
+	 CVMX_ADD_IO_SEG(0x00011F00000090A0ull)
+#define CVMX_PEXP_NPEI_PKT_DATA_OUT_ROR \
+	 CVMX_ADD_IO_SEG(0x00011F0000009090ull)
+#define CVMX_PEXP_NPEI_PKT_DPADDR \
+	 CVMX_ADD_IO_SEG(0x00011F0000009080ull)
+#define CVMX_PEXP_NPEI_PKT_INPUT_CONTROL \
+	 CVMX_ADD_IO_SEG(0x00011F0000009150ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000009000ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_RD_SIZE \
+	 CVMX_ADD_IO_SEG(0x00011F0000009190ull)
+#define CVMX_PEXP_NPEI_PKT_INSTR_SIZE \
+	 CVMX_ADD_IO_SEG(0x00011F0000009020ull)
+#define CVMX_PEXP_NPEI_PKT_INT_LEVELS \
+	 CVMX_ADD_IO_SEG(0x00011F0000009100ull)
+#define CVMX_PEXP_NPEI_PKT_IN_BP \
+	 CVMX_ADD_IO_SEG(0x00011F00000086B0ull)
+#define CVMX_PEXP_NPEI_PKT_IN_DONEX_CNTS(offset) \
+	 CVMX_ADD_IO_SEG(0x00011F000000A000ull + (((offset) & 31) * 16))
+#define CVMX_PEXP_NPEI_PKT_IN_INSTR_COUNTS \
+	 CVMX_ADD_IO_SEG(0x00011F00000086A0ull)
+#define CVMX_PEXP_NPEI_PKT_IN_PCIE_PORT \
+	 CVMX_ADD_IO_SEG(0x00011F00000091A0ull)
+#define CVMX_PEXP_NPEI_PKT_IPTR \
+	 CVMX_ADD_IO_SEG(0x00011F0000009070ull)
+#define CVMX_PEXP_NPEI_PKT_OUTPUT_WMARK \
+	 CVMX_ADD_IO_SEG(0x00011F0000009160ull)
+#define CVMX_PEXP_NPEI_PKT_OUT_BMODE \
+	 CVMX_ADD_IO_SEG(0x00011F00000090D0ull)
+#define CVMX_PEXP_NPEI_PKT_OUT_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000009010ull)
+#define CVMX_PEXP_NPEI_PKT_PCIE_PORT \
+	 CVMX_ADD_IO_SEG(0x00011F00000090E0ull)
+#define CVMX_PEXP_NPEI_PKT_PORT_IN_RST \
+	 CVMX_ADD_IO_SEG(0x00011F0000008690ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ES \
+	 CVMX_ADD_IO_SEG(0x00011F0000009050ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ID_SIZE \
+	 CVMX_ADD_IO_SEG(0x00011F0000009180ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_NS \
+	 CVMX_ADD_IO_SEG(0x00011F0000009040ull)
+#define CVMX_PEXP_NPEI_PKT_SLIST_ROR \
+	 CVMX_ADD_IO_SEG(0x00011F0000009030ull)
+#define CVMX_PEXP_NPEI_PKT_TIME_INT \
+	 CVMX_ADD_IO_SEG(0x00011F0000009120ull)
+#define CVMX_PEXP_NPEI_PKT_TIME_INT_ENB \
+	 CVMX_ADD_IO_SEG(0x00011F0000009140ull)
+#define CVMX_PEXP_NPEI_RSL_INT_BLOCKS \
+	 CVMX_ADD_IO_SEG(0x00011F0000008520ull)
+#define CVMX_PEXP_NPEI_SCRATCH_1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008270ull)
+#define CVMX_PEXP_NPEI_STATE1 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008620ull)
+#define CVMX_PEXP_NPEI_STATE2 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008630ull)
+#define CVMX_PEXP_NPEI_STATE3 \
+	 CVMX_ADD_IO_SEG(0x00011F0000008640ull)
+#define CVMX_PEXP_NPEI_WINDOW_CTL \
+	 CVMX_ADD_IO_SEG(0x00011F0000008380ull)
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 03fddfa..e31e3fe 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -376,6 +376,18 @@
 }
 
 /**
+ * Wait for the specified number of cycle
+ *
+ */
+static inline void cvmx_wait(uint64_t cycles)
+{
+	uint64_t done = cvmx_get_cycle() + cycles;
+
+	while (cvmx_get_cycle() < done)
+		; /* Spin */
+}
+
+/**
  * Reads a chip global cycle counter.  This counts CPU cycles since
  * chip reset.  The counter is 64 bit.
  * This register does not exist on CN38XX pass 1 silicion
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
index 04fac68..ef24a7b 100644
--- a/arch/mips/include/asm/octeon/octeon-feature.h
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -57,6 +57,13 @@
 	OCTEON_FEATURE_RAID,
 	/* Octeon has a builtin USB */
 	OCTEON_FEATURE_USB,
+	/* Octeon IPD can run without using work queue entries */
+	OCTEON_FEATURE_NO_WPTR,
+	/* Octeon has DFA state machines */
+	OCTEON_FEATURE_DFA,
+	/* Octeon MDIO block supports clause 45 transactions for 10
+	 * Gig support */
+	OCTEON_FEATURE_MDIO_CLAUSE_45,
 };
 
 static inline int cvmx_fuse_read(int fuse);
@@ -112,6 +119,26 @@
 	case OCTEON_FEATURE_USB:
 		return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
 			 || OCTEON_IS_MODEL(OCTEON_CN58XX));
+	case OCTEON_FEATURE_NO_WPTR:
+		return (OCTEON_IS_MODEL(OCTEON_CN56XX)
+			 || OCTEON_IS_MODEL(OCTEON_CN52XX))
+			&& !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+			&& !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
+	case OCTEON_FEATURE_DFA:
+		if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
+		    && !OCTEON_IS_MODEL(OCTEON_CN31XX)
+		    && !OCTEON_IS_MODEL(OCTEON_CN58XX))
+			return 0;
+		else if (OCTEON_IS_MODEL(OCTEON_CN3020))
+			return 0;
+		else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+			return 1;
+		else
+			return !cvmx_fuse_read(120);
+	case OCTEON_FEATURE_MDIO_CLAUSE_45:
+		return !(OCTEON_IS_MODEL(OCTEON_CN3XXX)
+			 || OCTEON_IS_MODEL(OCTEON_CN58XX)
+			 || OCTEON_IS_MODEL(OCTEON_CN50XX));
 	}
 	return 0;
 }
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index edc6760..cac9b1a 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -245,4 +245,6 @@
 	return cvmx_read64_uint32(address ^ 4);
 }
 
+extern struct cvmx_bootinfo *octeon_bootinfo;
+
 #endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 72c80d2..dc0eaa7 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -32,6 +32,11 @@
 #define PAGE_SIZE	(1UL << PAGE_SHIFT)
 #define PAGE_MASK       (~((1 << PAGE_SHIFT) - 1))
 
+#define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
+#define HPAGE_SIZE	((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK	(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/pfn.h>
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index 51b34a4..1073e6d 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -72,6 +72,7 @@
 #else
 
 #define _PAGE_R4KBUG                (1<<5)  /* workaround for r4k bug  */
+#define _PAGE_HUGE                  (1<<5)  /* huge tlb page */
 #define _PAGE_GLOBAL                (1<<6)
 #define _PAGE_VALID                 (1<<7)
 #define _PAGE_SILENT_READ           (1<<7)  /* synonym                 */
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 6a0edf7..1a9f9b2 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -292,6 +292,16 @@
 		pte_val(pte) |= _PAGE_SILENT_READ;
 	return pte;
 }
+
+#ifdef _PAGE_HUGE
+static inline int pte_huge(pte_t pte)	{ return pte_val(pte) & _PAGE_HUGE; }
+
+static inline pte_t pte_mkhuge(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_HUGE;
+	return pte;
+}
+#endif /* _PAGE_HUGE */
 #endif
 static inline int pte_special(pte_t pte)	{ return 0; }
 static inline pte_t pte_mkspecial(pte_t pte)	{ return pte; }
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index 4c140db..387bf59 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -399,6 +399,7 @@
 __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32)
 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32)
 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 64)
 __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64)
 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
 __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
diff --git a/arch/mips/include/asm/suspend.h b/arch/mips/include/asm/suspend.h
new file mode 100644
index 0000000..294cdb6
--- /dev/null
+++ b/arch/mips/include/asm/suspend.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_SUSPEND_H
+#define __ASM_SUSPEND_H
+
+static inline int arch_prepare_suspend(void) { return 0; }
+
+/* References to section boundaries */
+extern const void __nosave_begin, __nosave_end;
+
+#endif /* __ASM_SUSPEND_H */
diff --git a/arch/mips/include/asm/txx9/dmac.h b/arch/mips/include/asm/txx9/dmac.h
new file mode 100644
index 0000000..5e9151f
--- /dev/null
+++ b/arch/mips/include/asm/txx9/dmac.h
@@ -0,0 +1,51 @@
+/*
+ * TXx9 SoC DMA Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_TXX9_DMAC_H
+#define __ASM_TXX9_DMAC_H
+
+#include <linux/dmaengine.h>
+
+#define TXX9_DMA_MAX_NR_CHANNELS	4
+
+/**
+ * struct txx9dmac_platform_data - Controller configuration parameters
+ * @memcpy_chan: Channel used for DMA_MEMCPY
+ * @have_64bit_regs: DMAC have 64 bit registers
+ */
+struct txx9dmac_platform_data {
+	int	memcpy_chan;
+	bool	have_64bit_regs;
+};
+
+/**
+ * struct txx9dmac_chan_platform_data - Channel configuration parameters
+ * @dmac_dev: A platform device for DMAC
+ */
+struct txx9dmac_chan_platform_data {
+	struct platform_device *dmac_dev;
+};
+
+/**
+ * struct txx9dmac_slave - Controller-specific information about a slave
+ * @tx_reg: physical address of data register used for
+ *	memory-to-peripheral transfers
+ * @rx_reg: physical address of data register used for
+ *	peripheral-to-memory transfers
+ * @reg_width: peripheral register width
+ */
+struct txx9dmac_slave {
+	u64		tx_reg;
+	u64		rx_reg;
+	unsigned int	reg_width;
+};
+
+void txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+		    const struct txx9dmac_platform_data *pdata);
+
+#endif /* __ASM_TXX9_DMAC_H */
diff --git a/arch/mips/include/asm/txx9/generic.h b/arch/mips/include/asm/txx9/generic.h
index 9cde009..827dc22 100644
--- a/arch/mips/include/asm/txx9/generic.h
+++ b/arch/mips/include/asm/txx9/generic.h
@@ -91,4 +91,10 @@
 		       void (*putc)(unsigned int pos, unsigned char val));
 int txx9_7segled_putc(unsigned int pos, char c);
 
+void __init txx9_aclc_init(unsigned long baseaddr, int irq,
+			   unsigned int dmac_id,
+			   unsigned int dma_chan_out,
+			   unsigned int dma_chan_in);
+void __init txx9_sramc_init(struct resource *r);
+
 #endif /* __ASM_TXX9_GENERIC_H */
diff --git a/arch/mips/include/asm/txx9/tx4927.h b/arch/mips/include/asm/txx9/tx4927.h
index 7d813f1..18c98c5 100644
--- a/arch/mips/include/asm/txx9/tx4927.h
+++ b/arch/mips/include/asm/txx9/tx4927.h
@@ -41,6 +41,7 @@
 
 #define TX4927_SDRAMC_REG	(TX4927_REG_BASE + 0x8000)
 #define TX4927_EBUSC_REG	(TX4927_REG_BASE + 0x9000)
+#define TX4927_DMA_REG		(TX4927_REG_BASE + 0xb000)
 #define TX4927_PCIC_REG		(TX4927_REG_BASE + 0xd000)
 #define TX4927_CCFG_REG		(TX4927_REG_BASE + 0xe000)
 #define TX4927_IRC_REG		(TX4927_REG_BASE + 0xf600)
@@ -49,6 +50,7 @@
 #define TX4927_NR_SIO	2
 #define TX4927_SIO_REG(ch)	(TX4927_REG_BASE + 0xf300 + (ch) * 0x100)
 #define TX4927_PIO_REG		(TX4927_REG_BASE + 0xf500)
+#define TX4927_ACLC_REG		(TX4927_REG_BASE + 0xf700)
 
 #define TX4927_IR_ECCERR	0
 #define TX4927_IR_WTOERR	1
@@ -265,5 +267,7 @@
 void tx4927_setup_pcierr_irq(void);
 void tx4927_irq_init(void);
 void tx4927_mtd_init(int ch);
+void tx4927_dmac_init(int memcpy_chan);
+void tx4927_aclc_init(unsigned int dma_chan_out, unsigned int dma_chan_in);
 
 #endif /* __ASM_TXX9_TX4927_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
index cd8bc20..8a178f1 100644
--- a/arch/mips/include/asm/txx9/tx4938.h
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -305,5 +305,8 @@
 };
 
 void tx4938_ata_init(unsigned int irq, unsigned int shift, int tune);
+void tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1);
+void tx4938_aclc_init(void);
+void tx4938_sramc_init(void);
 
 #endif
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index f02c50b..d4f342c 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -45,6 +45,8 @@
 #define TX4939_RTC_REG		(TX4939_REG_BASE + 0xfb00)
 #define TX4939_CIR_REG		(TX4939_REG_BASE + 0xfc00)
 
+#define TX4939_RNG_REG		(TX4939_CRYPTO_REG + 0xb0)
+
 struct tx4939_le_reg {
 	__u32 r;
 	__u32 unused;
@@ -544,5 +546,9 @@
 void tx4939_rtc_init(void);
 void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
 		       unsigned char ch_mask, unsigned char wide_mask);
+void tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1);
+void tx4939_aclc_init(void);
+void tx4939_sramc_init(void);
+void tx4939_rng_init(void);
 
 #endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index c901c22..8d006ec 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/kbuild.h>
+#include <linux/suspend.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
 
@@ -326,3 +327,15 @@
 	BLANK();
 }
 #endif
+
+#ifdef CONFIG_HIBERNATION
+void output_pbe_defines(void)
+{
+	COMMENT(" Linux struct pbe offsets. ");
+	OFFSET(PBE_ADDRESS, pbe, address);
+	OFFSET(PBE_ORIG_ADDRESS, pbe, orig_address);
+	OFFSET(PBE_NEXT, pbe, next);
+	DEFINE(PBE_SIZE, sizeof(struct pbe));
+	BLANK();
+}
+#endif
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
index 2e911e3..0037f21 100644
--- a/arch/mips/kernel/cevt-txx9.c
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -20,22 +20,29 @@
 #define TIMER_CCD	0	/* 1/2 */
 #define TIMER_CLK(imclk)	((imclk) / (2 << TIMER_CCD))
 
-static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
+struct txx9_clocksource {
+	struct clocksource cs;
+	struct txx9_tmr_reg __iomem *tmrptr;
+};
 
 static cycle_t txx9_cs_read(struct clocksource *cs)
 {
-	return __raw_readl(&txx9_cs_tmrptr->trr);
+	struct txx9_clocksource *txx9_cs =
+		container_of(cs, struct txx9_clocksource, cs);
+	return __raw_readl(&txx9_cs->tmrptr->trr);
 }
 
 /* Use 1 bit smaller width to use full bits in that width */
 #define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
 
-static struct clocksource txx9_clocksource = {
-	.name		= "TXx9",
-	.rating		= 200,
-	.read		= txx9_cs_read,
-	.mask		= CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+static struct txx9_clocksource txx9_clocksource = {
+	.cs = {
+		.name		= "TXx9",
+		.rating		= 200,
+		.read		= txx9_cs_read,
+		.mask		= CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
+		.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+	},
 };
 
 void __init txx9_clocksource_init(unsigned long baseaddr,
@@ -43,8 +50,8 @@
 {
 	struct txx9_tmr_reg __iomem *tmrptr;
 
-	clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk));
-	clocksource_register(&txx9_clocksource);
+	clocksource_set_clock(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
+	clocksource_register(&txx9_clocksource.cs);
 
 	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
 	__raw_writel(TCR_BASE, &tmrptr->tcr);
@@ -53,10 +60,13 @@
 	__raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
 	__raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
 	__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
-	txx9_cs_tmrptr = tmrptr;
+	txx9_clocksource.tmrptr = tmrptr;
 }
 
-static struct txx9_tmr_reg __iomem *txx9_tmrptr;
+struct txx9_clock_event_device {
+	struct clock_event_device cd;
+	struct txx9_tmr_reg __iomem *tmrptr;
+};
 
 static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
 {
@@ -69,7 +79,9 @@
 static void txx9tmr_set_mode(enum clock_event_mode mode,
 			     struct clock_event_device *evt)
 {
-	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+	struct txx9_clock_event_device *txx9_cd =
+		container_of(evt, struct txx9_clock_event_device, cd);
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 
 	txx9tmr_stop_and_clear(tmrptr);
 	switch (mode) {
@@ -99,7 +111,9 @@
 static int txx9tmr_set_next_event(unsigned long delta,
 				  struct clock_event_device *evt)
 {
-	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+	struct txx9_clock_event_device *txx9_cd =
+		container_of(evt, struct txx9_clock_event_device, cd);
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 
 	txx9tmr_stop_and_clear(tmrptr);
 	/* start timer */
@@ -108,18 +122,22 @@
 	return 0;
 }
 
-static struct clock_event_device txx9tmr_clock_event_device = {
-	.name		= "TXx9",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.rating		= 200,
-	.set_mode	= txx9tmr_set_mode,
-	.set_next_event	= txx9tmr_set_next_event,
+static struct txx9_clock_event_device txx9_clock_event_device = {
+	.cd = {
+		.name		= "TXx9",
+		.features	= CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_ONESHOT,
+		.rating		= 200,
+		.set_mode	= txx9tmr_set_mode,
+		.set_next_event	= txx9tmr_set_next_event,
+	},
 };
 
 static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *cd = &txx9tmr_clock_event_device;
-	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+	struct txx9_clock_event_device *txx9_cd = dev_id;
+	struct clock_event_device *cd = &txx9_cd->cd;
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
 
 	__raw_writel(0, &tmrptr->tisr);	/* ack interrupt */
 	cd->event_handler(cd);
@@ -130,19 +148,20 @@
 	.handler	= txx9tmr_interrupt,
 	.flags		= IRQF_DISABLED | IRQF_PERCPU,
 	.name		= "txx9tmr",
+	.dev_id		= &txx9_clock_event_device,
 };
 
 void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
 				 unsigned int imbusclk)
 {
-	struct clock_event_device *cd = &txx9tmr_clock_event_device;
+	struct clock_event_device *cd = &txx9_clock_event_device.cd;
 	struct txx9_tmr_reg __iomem *tmrptr;
 
 	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
 	txx9tmr_stop_and_clear(tmrptr);
 	__raw_writel(TIMER_CCD, &tmrptr->ccdr);
 	__raw_writel(0, &tmrptr->itmr);
-	txx9_tmrptr = tmrptr;
+	txx9_clock_event_device.tmrptr = tmrptr;
 
 	clockevent_set_clock(cd, TIMER_CLK(imbusclk));
 	cd->max_delta_ns =
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 5f5af7d..37d51cd 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -924,6 +924,7 @@
 	int irq = MIPS_CPU_IRQ_BASE + 1;
 
 	smtc_ipi_nq(&freeIPIq, pipi);
+
 	switch (type_copy) {
 	case SMTC_CLOCK_TICK:
 		irq_enter();
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index e83da17..08f1edf 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1502,7 +1502,7 @@
 			 status_set);
 
 	if (cpu_has_mips_r2) {
-		unsigned int enable = 0x0000000f;
+		unsigned int enable = 0x0000000f | cpu_hwrena_impl_bits;
 
 		if (!noulri && cpu_has_userlocal)
 			enable |= (1 << 29);
@@ -1510,10 +1510,6 @@
 		write_c0_hwrena(enable);
 	}
 
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-	write_c0_hwrena(0xc000000f); /* Octeon has register 30 and 31 */
-#endif
-
 #ifdef CONFIG_MIPS_MT_SMTC
 	if (!secondaryTC) {
 #endif /* CONFIG_MIPS_MT_SMTC */
diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c
index f69c6b5..6b3b1de9 100644
--- a/arch/mips/lib/delay.c
+++ b/arch/mips/lib/delay.c
@@ -43,7 +43,7 @@
 {
 	unsigned int lpj = current_cpu_data.udelay_val;
 
-	__delay((us * 0x000010c7 * HZ * lpj) >> 32);
+	__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
 EXPORT_SYMBOL(__udelay);
 
@@ -51,6 +51,6 @@
 {
 	unsigned int lpj = current_cpu_data.udelay_val;
 
-	__delay((us * 0x00000005 * HZ * lpj) >> 32);
+	__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
 EXPORT_SYMBOL(__ndelay);
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index d7ec955..f0e4355 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -8,6 +8,7 @@
 obj-$(CONFIG_32BIT)		+= ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)		+= pgtable-64.o
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 
 obj-$(CONFIG_CPU_LOONGSON2)	+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_MIPS32)	+= c-r4k.o cex-gen.o tlb-r4k.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 171951d..71fe4cb 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -100,6 +100,12 @@
 	blast_dcache32_page(addr);
 }
 
+static inline void r4k_blast_dcache_page_dc64(unsigned long addr)
+{
+	R4600_HIT_CACHEOP_WAR_IMPL;
+	blast_dcache64_page(addr);
+}
+
 static void __cpuinit r4k_blast_dcache_page_setup(void)
 {
 	unsigned long  dc_lsize = cpu_dcache_line_size();
@@ -110,6 +116,8 @@
 		r4k_blast_dcache_page = blast_dcache16_page;
 	else if (dc_lsize == 32)
 		r4k_blast_dcache_page = r4k_blast_dcache_page_dc32;
+	else if (dc_lsize == 64)
+		r4k_blast_dcache_page = r4k_blast_dcache_page_dc64;
 }
 
 static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
@@ -124,6 +132,8 @@
 		r4k_blast_dcache_page_indexed = blast_dcache16_page_indexed;
 	else if (dc_lsize == 32)
 		r4k_blast_dcache_page_indexed = blast_dcache32_page_indexed;
+	else if (dc_lsize == 64)
+		r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed;
 }
 
 static void (* r4k_blast_dcache)(void);
@@ -138,6 +148,8 @@
 		r4k_blast_dcache = blast_dcache16;
 	else if (dc_lsize == 32)
 		r4k_blast_dcache = blast_dcache32;
+	else if (dc_lsize == 64)
+		r4k_blast_dcache = blast_dcache64;
 }
 
 /* force code alignment (used for TX49XX_ICACHE_INDEX_INV_WAR) */
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4fdb7f5..7e48e76 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -20,9 +20,10 @@
 
 #include <dma-coherence.h>
 
-static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr)
+static inline unsigned long dma_addr_to_virt(struct device *dev,
+	dma_addr_t dma_addr)
 {
-	unsigned long addr = plat_dma_addr_to_phys(dma_addr);
+	unsigned long addr = plat_dma_addr_to_phys(dev, dma_addr);
 
 	return (unsigned long)phys_to_virt(addr);
 }
@@ -111,7 +112,7 @@
 void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
 	dma_addr_t dma_handle)
 {
-	plat_unmap_dma_mem(dev, dma_handle);
+	plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
 	free_pages((unsigned long) vaddr, get_order(size));
 }
 
@@ -122,7 +123,7 @@
 {
 	unsigned long addr = (unsigned long) vaddr;
 
-	plat_unmap_dma_mem(dev, dma_handle);
+	plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
 
 	if (!plat_device_is_coherent(dev))
 		addr = CAC_ADDR(addr);
@@ -170,10 +171,10 @@
 	enum dma_data_direction direction)
 {
 	if (cpu_is_noncoherent_r10000(dev))
-		__dma_sync(dma_addr_to_virt(dma_addr), size,
+		__dma_sync(dma_addr_to_virt(dev, dma_addr), size,
 		           direction);
 
-	plat_unmap_dma_mem(dev, dma_addr);
+	plat_unmap_dma_mem(dev, dma_addr, size, direction);
 }
 
 EXPORT_SYMBOL(dma_unmap_single);
@@ -232,7 +233,7 @@
 			if (addr)
 				__dma_sync(addr, sg->length, direction);
 		}
-		plat_unmap_dma_mem(dev, sg->dma_address);
+		plat_unmap_dma_mem(dev, sg->dma_address, sg->length, direction);
 	}
 }
 
@@ -246,7 +247,7 @@
 	if (cpu_is_noncoherent_r10000(dev)) {
 		unsigned long addr;
 
-		addr = dma_addr_to_virt(dma_handle);
+		addr = dma_addr_to_virt(dev, dma_handle);
 		__dma_sync(addr, size, direction);
 	}
 }
@@ -262,7 +263,7 @@
 	if (!plat_device_is_coherent(dev)) {
 		unsigned long addr;
 
-		addr = dma_addr_to_virt(dma_handle);
+		addr = dma_addr_to_virt(dev, dma_handle);
 		__dma_sync(addr, size, direction);
 	}
 }
@@ -277,7 +278,7 @@
 	if (cpu_is_noncoherent_r10000(dev)) {
 		unsigned long addr;
 
-		addr = dma_addr_to_virt(dma_handle);
+		addr = dma_addr_to_virt(dev, dma_handle);
 		__dma_sync(addr + offset, size, direction);
 	}
 }
@@ -293,7 +294,7 @@
 	if (!plat_device_is_coherent(dev)) {
 		unsigned long addr;
 
-		addr = dma_addr_to_virt(dma_handle);
+		addr = dma_addr_to_virt(dev, dma_handle);
 		__dma_sync(addr + offset, size, direction);
 	}
 }
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c
new file mode 100644
index 0000000..471c09a
--- /dev/null
+++ b/arch/mips/mm/hugetlbpage.c
@@ -0,0 +1,101 @@
+/*
+ * MIPS Huge TLB Page Support for Kernel.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ * Copyright 2005, Embedded Alley Solutions, Inc.
+ * Matt Porter <mporter@embeddedalley.com>
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <asm/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr,
+		      unsigned long sz)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pte_t *pte = NULL;
+
+	pgd = pgd_offset(mm, addr);
+	pud = pud_alloc(mm, pgd, addr);
+	if (pud)
+		pte = (pte_t *)pmd_alloc(mm, pud, addr);
+
+	return pte;
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd = NULL;
+
+	pgd = pgd_offset(mm, addr);
+	if (pgd_present(*pgd)) {
+		pud = pud_offset(pgd, addr);
+		if (pud_present(*pud))
+			pmd = pmd_offset(pud, addr);
+	}
+	return (pte_t *) pmd;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+	return 0;
+}
+
+/*
+ * This function checks for proper alignment of input addr and len parameters.
+ */
+int is_aligned_hugepage_range(unsigned long addr, unsigned long len)
+{
+	if (len & ~HPAGE_MASK)
+		return -EINVAL;
+	if (addr & ~HPAGE_MASK)
+		return -EINVAL;
+	return 0;
+}
+
+struct page *
+follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
+{
+	return ERR_PTR(-EINVAL);
+}
+
+int pmd_huge(pmd_t pmd)
+{
+	return (pmd_val(pmd) & _PAGE_HUGE) != 0;
+}
+
+int pud_huge(pud_t pud)
+{
+	return (pud_val(pud) & _PAGE_HUGE) != 0;
+}
+
+struct page *
+follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+		pmd_t *pmd, int write)
+{
+	struct page *page;
+
+	page = pte_page(*(pte_t *)pmd);
+	if (page)
+		page += ((address & ~HPAGE_MASK) >> PAGE_SHIFT);
+	return page;
+}
+
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 892be42..f60fe51 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/hugetlb.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
@@ -295,21 +296,41 @@
 	pudp = pud_offset(pgdp, address);
 	pmdp = pmd_offset(pudp, address);
 	idx = read_c0_index();
-	ptep = pte_offset_map(pmdp, address);
+#ifdef CONFIG_HUGETLB_PAGE
+	/* this could be a huge page  */
+	if (pmd_huge(*pmdp)) {
+		unsigned long lo;
+		write_c0_pagemask(PM_HUGE_MASK);
+		ptep = (pte_t *)pmdp;
+		lo = pte_val(*ptep) >> 6;
+		write_c0_entrylo0(lo);
+		write_c0_entrylo1(lo + (HPAGE_SIZE >> 7));
+
+		mtc0_tlbw_hazard();
+		if (idx < 0)
+			tlb_write_random();
+		else
+			tlb_write_indexed();
+		write_c0_pagemask(PM_DEFAULT_MASK);
+	} else
+#endif
+	{
+		ptep = pte_offset_map(pmdp, address);
 
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
-	write_c0_entrylo0(ptep->pte_high);
-	ptep++;
-	write_c0_entrylo1(ptep->pte_high);
+		write_c0_entrylo0(ptep->pte_high);
+		ptep++;
+		write_c0_entrylo1(ptep->pte_high);
 #else
-	write_c0_entrylo0(pte_val(*ptep++) >> 6);
-	write_c0_entrylo1(pte_val(*ptep) >> 6);
+		write_c0_entrylo0(pte_val(*ptep++) >> 6);
+		write_c0_entrylo1(pte_val(*ptep) >> 6);
 #endif
-	mtc0_tlbw_hazard();
-	if (idx < 0)
-		tlb_write_random();
-	else
-		tlb_write_indexed();
+		mtc0_tlbw_hazard();
+		if (idx < 0)
+			tlb_write_random();
+		else
+			tlb_write_indexed();
+	}
 	tlbw_use_hazard();
 	FLUSH_ITLB_VM(vma);
 	EXIT_CRITICAL(flags);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 0615b62..8f606ea 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -6,8 +6,9 @@
  * Synthesize TLB refill handlers at runtime.
  *
  * Copyright (C) 2004, 2005, 2006, 2008  Thiemo Seufer
- * Copyright (C) 2005, 2007  Maciej W. Rozycki
+ * Copyright (C) 2005, 2007, 2008, 2009  Maciej W. Rozycki
  * Copyright (C) 2006  Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2008, 2009 Cavium Networks, Inc.
  *
  * ... and the days got worse and worse and now you see
  * I've gone completly out of my mind.
@@ -19,6 +20,7 @@
  * (Condolences to Napoleon XIV)
  */
 
+#include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -82,6 +84,9 @@
 	label_nopage_tlbm,
 	label_smp_pgtable_change,
 	label_r3000_write_probe_fail,
+#ifdef CONFIG_HUGETLB_PAGE
+	label_tlb_huge_update,
+#endif
 };
 
 UASM_L_LA(_second_part)
@@ -98,6 +103,9 @@
 UASM_L_LA(_nopage_tlbm)
 UASM_L_LA(_smp_pgtable_change)
 UASM_L_LA(_r3000_write_probe_fail)
+#ifdef CONFIG_HUGETLB_PAGE
+UASM_L_LA(_tlb_huge_update)
+#endif
 
 /*
  * For debug purposes.
@@ -125,6 +133,7 @@
 #define C0_TCBIND	2, 2
 #define C0_ENTRYLO1	3, 0
 #define C0_CONTEXT	4, 0
+#define C0_PAGEMASK	5, 0
 #define C0_BADVADDR	8, 0
 #define C0_ENTRYHI	10, 0
 #define C0_EPC		14, 0
@@ -258,7 +267,8 @@
 	}
 
 	if (cpu_has_mips_r2) {
-		uasm_i_ehb(p);
+		if (cpu_has_mips_r2_exec_hazard)
+			uasm_i_ehb(p);
 		tlbw(p);
 		return;
 	}
@@ -310,7 +320,6 @@
 	case CPU_BCM3302:
 	case CPU_BCM4710:
 	case CPU_LOONGSON2:
-	case CPU_CAVIUM_OCTEON:
 	case CPU_R5500:
 		if (m4kc_tlbp_war())
 			uasm_i_nop(p);
@@ -382,6 +391,98 @@
 	}
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static __cpuinit void build_huge_tlb_write_entry(u32 **p,
+						 struct uasm_label **l,
+						 struct uasm_reloc **r,
+						 unsigned int tmp,
+						 enum tlb_write_entry wmode)
+{
+	/* Set huge page tlb entry size */
+	uasm_i_lui(p, tmp, PM_HUGE_MASK >> 16);
+	uasm_i_ori(p, tmp, tmp, PM_HUGE_MASK & 0xffff);
+	uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+
+	build_tlb_write_entry(p, l, r, wmode);
+
+	/* Reset default page size */
+	if (PM_DEFAULT_MASK >> 16) {
+		uasm_i_lui(p, tmp, PM_DEFAULT_MASK >> 16);
+		uasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK & 0xffff);
+		uasm_il_b(p, r, label_leave);
+		uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+	} else if (PM_DEFAULT_MASK) {
+		uasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);
+		uasm_il_b(p, r, label_leave);
+		uasm_i_mtc0(p, tmp, C0_PAGEMASK);
+	} else {
+		uasm_il_b(p, r, label_leave);
+		uasm_i_mtc0(p, 0, C0_PAGEMASK);
+	}
+}
+
+/*
+ * Check if Huge PTE is present, if so then jump to LABEL.
+ */
+static void __cpuinit
+build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,
+		unsigned int pmd, int lid)
+{
+	UASM_i_LW(p, tmp, 0, pmd);
+	uasm_i_andi(p, tmp, tmp, _PAGE_HUGE);
+	uasm_il_bnez(p, r, tmp, lid);
+}
+
+static __cpuinit void build_huge_update_entries(u32 **p,
+						unsigned int pte,
+						unsigned int tmp)
+{
+	int small_sequence;
+
+	/*
+	 * A huge PTE describes an area the size of the
+	 * configured huge page size. This is twice the
+	 * of the large TLB entry size we intend to use.
+	 * A TLB entry half the size of the configured
+	 * huge page size is configured into entrylo0
+	 * and entrylo1 to cover the contiguous huge PTE
+	 * address space.
+	 */
+	small_sequence = (HPAGE_SIZE >> 7) < 0x10000;
+
+	/* We can clobber tmp.  It isn't used after this.*/
+	if (!small_sequence)
+		uasm_i_lui(p, tmp, HPAGE_SIZE >> (7 + 16));
+
+	UASM_i_SRL(p, pte, pte, 6); /* convert to entrylo */
+	uasm_i_mtc0(p, pte, C0_ENTRYLO0); /* load it */
+	/* convert to entrylo1 */
+	if (small_sequence)
+		UASM_i_ADDIU(p, pte, pte, HPAGE_SIZE >> 7);
+	else
+		UASM_i_ADDU(p, pte, pte, tmp);
+
+	uasm_i_mtc0(p, pte, C0_ENTRYLO1); /* load it */
+}
+
+static __cpuinit void build_huge_handler_tail(u32 **p,
+					      struct uasm_reloc **r,
+					      struct uasm_label **l,
+					      unsigned int pte,
+					      unsigned int ptr)
+{
+#ifdef CONFIG_SMP
+	UASM_i_SC(p, pte, 0, ptr);
+	uasm_il_beqz(p, r, pte, label_tlb_huge_update);
+	UASM_i_LW(p, pte, 0, ptr); /* Needed because SC killed our PTE */
+#else
+	UASM_i_SW(p, pte, 0, ptr);
+#endif
+	build_huge_update_entries(p, pte, ptr);
+	build_huge_tlb_write_entry(p, l, r, pte, tlb_indexed);
+}
+#endif /* CONFIG_HUGETLB_PAGE */
+
 #ifdef CONFIG_64BIT
 /*
  * TMP and PTR are scratch.
@@ -649,6 +750,14 @@
 #endif
 }
 
+/*
+ * For a 64-bit kernel, we are using the 64-bit XTLB refill exception
+ * because EXL == 0.  If we wrap, we can also use the 32 instruction
+ * slots before the XTLB refill exception handler which belong to the
+ * unused TLB refill exception.
+ */
+#define MIPS64_REFILL_INSNS 32
+
 static void __cpuinit build_r4000_tlb_refill_handler(void)
 {
 	u32 *p = tlb_handler;
@@ -680,12 +789,23 @@
 	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
 #endif
 
+#ifdef CONFIG_HUGETLB_PAGE
+	build_is_huge_pte(&p, &r, K0, K1, label_tlb_huge_update);
+#endif
+
 	build_get_ptep(&p, K0, K1);
 	build_update_entries(&p, K0, K1);
 	build_tlb_write_entry(&p, &l, &r, tlb_random);
 	uasm_l_leave(&l, p);
 	uasm_i_eret(&p); /* return from trap */
 
+#ifdef CONFIG_HUGETLB_PAGE
+	uasm_l_tlb_huge_update(&l, p);
+	UASM_i_LW(&p, K0, 0, K1);
+	build_huge_update_entries(&p, K0, K1);
+	build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random);
+#endif
+
 #ifdef CONFIG_64BIT
 	build_get_pgd_vmalloc64(&p, &l, &r, K0, K1);
 #endif
@@ -702,9 +822,10 @@
 	if ((p - tlb_handler) > 64)
 		panic("TLB refill handler space exceeded");
 #else
-	if (((p - tlb_handler) > 63)
-	    || (((p - tlb_handler) > 61)
-		&& uasm_insn_has_bdelay(relocs, tlb_handler + 29)))
+	if (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 1)
+	    || (((p - tlb_handler) > (MIPS64_REFILL_INSNS * 2) - 3)
+		&& uasm_insn_has_bdelay(relocs,
+					tlb_handler + MIPS64_REFILL_INSNS - 3)))
 		panic("TLB refill handler space exceeded");
 #endif
 
@@ -717,39 +838,74 @@
 	uasm_copy_handler(relocs, labels, tlb_handler, p, f);
 	final_len = p - tlb_handler;
 #else /* CONFIG_64BIT */
-	f = final_handler + 32;
-	if ((p - tlb_handler) <= 32) {
+	f = final_handler + MIPS64_REFILL_INSNS;
+	if ((p - tlb_handler) <= MIPS64_REFILL_INSNS) {
 		/* Just copy the handler. */
 		uasm_copy_handler(relocs, labels, tlb_handler, p, f);
 		final_len = p - tlb_handler;
 	} else {
-		u32 *split = tlb_handler + 30;
+#if defined(CONFIG_HUGETLB_PAGE)
+		const enum label_id ls = label_tlb_huge_update;
+#elif defined(MODULE_START)
+		const enum label_id ls = label_module_alloc;
+#else
+		const enum label_id ls = label_vmalloc;
+#endif
+		u32 *split;
+		int ov = 0;
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(labels) && labels[i].lab != ls; i++)
+			;
+		BUG_ON(i == ARRAY_SIZE(labels));
+		split = labels[i].addr;
 
 		/*
-		 * Find the split point.
+		 * See if we have overflown one way or the other.
 		 */
-		if (uasm_insn_has_bdelay(relocs, split - 1))
-			split--;
+		if (split > tlb_handler + MIPS64_REFILL_INSNS ||
+		    split < p - MIPS64_REFILL_INSNS)
+			ov = 1;
 
+		if (ov) {
+			/*
+			 * Split two instructions before the end.  One
+			 * for the branch and one for the instruction
+			 * in the delay slot.
+			 */
+			split = tlb_handler + MIPS64_REFILL_INSNS - 2;
+
+			/*
+			 * If the branch would fall in a delay slot,
+			 * we must back up an additional instruction
+			 * so that it is no longer in a delay slot.
+			 */
+			if (uasm_insn_has_bdelay(relocs, split - 1))
+				split--;
+		}
 		/* Copy first part of the handler. */
 		uasm_copy_handler(relocs, labels, tlb_handler, split, f);
 		f += split - tlb_handler;
 
-		/* Insert branch. */
-		uasm_l_split(&l, final_handler);
-		uasm_il_b(&f, &r, label_split);
-		if (uasm_insn_has_bdelay(relocs, split))
-			uasm_i_nop(&f);
-		else {
-			uasm_copy_handler(relocs, labels, split, split + 1, f);
-			uasm_move_labels(labels, f, f + 1, -1);
-			f++;
-			split++;
+		if (ov) {
+			/* Insert branch. */
+			uasm_l_split(&l, final_handler);
+			uasm_il_b(&f, &r, label_split);
+			if (uasm_insn_has_bdelay(relocs, split))
+				uasm_i_nop(&f);
+			else {
+				uasm_copy_handler(relocs, labels,
+						  split, split + 1, f);
+				uasm_move_labels(labels, f, f + 1, -1);
+				f++;
+				split++;
+			}
 		}
 
 		/* Copy the rest of the handler. */
 		uasm_copy_handler(relocs, labels, split, p, final_handler);
-		final_len = (f - (final_handler + 32)) + (p - split);
+		final_len = (f - (final_handler + MIPS64_REFILL_INSNS)) +
+			    (p - split);
 	}
 #endif /* CONFIG_64BIT */
 
@@ -782,7 +938,7 @@
 u32 handle_tlbm[FASTPATH_SIZE] __cacheline_aligned;
 
 static void __cpuinit
-iPTE_LW(u32 **p, struct uasm_label **l, unsigned int pte, unsigned int ptr)
+iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
 {
 #ifdef CONFIG_SMP
 # ifdef CONFIG_64BIT_PHYS_ADDR
@@ -862,13 +1018,13 @@
  * with it's original value.
  */
 static void __cpuinit
-build_pte_present(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+build_pte_present(u32 **p, struct uasm_reloc **r,
 		  unsigned int pte, unsigned int ptr, enum label_id lid)
 {
 	uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
 	uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
 	uasm_il_bnez(p, r, pte, lid);
-	iPTE_LW(p, l, pte, ptr);
+	iPTE_LW(p, pte, ptr);
 }
 
 /* Make PTE valid, store result in PTR. */
@@ -886,13 +1042,13 @@
  * restore PTE with value from PTR when done.
  */
 static void __cpuinit
-build_pte_writable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+build_pte_writable(u32 **p, struct uasm_reloc **r,
 		   unsigned int pte, unsigned int ptr, enum label_id lid)
 {
 	uasm_i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
 	uasm_i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
 	uasm_il_bnez(p, r, pte, lid);
-	iPTE_LW(p, l, pte, ptr);
+	iPTE_LW(p, pte, ptr);
 }
 
 /* Make PTE writable, update software status bits as well, then store
@@ -913,12 +1069,12 @@
  * restore PTE with value from PTR when done.
  */
 static void __cpuinit
-build_pte_modifiable(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
+build_pte_modifiable(u32 **p, struct uasm_reloc **r,
 		     unsigned int pte, unsigned int ptr, enum label_id lid)
 {
 	uasm_i_andi(p, pte, pte, _PAGE_WRITE);
 	uasm_il_beqz(p, r, pte, lid);
-	iPTE_LW(p, l, pte, ptr);
+	iPTE_LW(p, pte, ptr);
 }
 
 /*
@@ -994,7 +1150,7 @@
 	memset(relocs, 0, sizeof(relocs));
 
 	build_r3000_tlbchange_handler_head(&p, K0, K1);
-	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
 	uasm_i_nop(&p); /* load delay */
 	build_make_valid(&p, &r, K0, K1);
 	build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
@@ -1024,7 +1180,7 @@
 	memset(relocs, 0, sizeof(relocs));
 
 	build_r3000_tlbchange_handler_head(&p, K0, K1);
-	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
 	uasm_i_nop(&p); /* load delay */
 	build_make_write(&p, &r, K0, K1);
 	build_r3000_tlb_reload_write(&p, &l, &r, K0, K1);
@@ -1054,7 +1210,7 @@
 	memset(relocs, 0, sizeof(relocs));
 
 	build_r3000_tlbchange_handler_head(&p, K0, K1);
-	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
 	uasm_i_nop(&p); /* load delay */
 	build_make_write(&p, &r, K0, K1);
 	build_r3000_pte_reload_tlbwi(&p, K0, K1);
@@ -1087,6 +1243,15 @@
 	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
 #endif
 
+#ifdef CONFIG_HUGETLB_PAGE
+	/*
+	 * For huge tlb entries, pmd doesn't contain an address but
+	 * instead contains the tlb pte. Check the PAGE_HUGE bit and
+	 * see if we need to jump to huge tlb processing.
+	 */
+	build_is_huge_pte(p, r, pte, ptr, label_tlb_huge_update);
+#endif
+
 	UASM_i_MFC0(p, pte, C0_BADVADDR);
 	UASM_i_LW(p, ptr, 0, ptr);
 	UASM_i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
@@ -1096,7 +1261,7 @@
 #ifdef CONFIG_SMP
 	uasm_l_smp_pgtable_change(l, *p);
 #endif
-	iPTE_LW(p, l, pte, ptr); /* get even pte */
+	iPTE_LW(p, pte, ptr); /* get even pte */
 	if (!m4kc_tlbp_war())
 		build_tlb_probe_entry(p);
 }
@@ -1138,12 +1303,25 @@
 	}
 
 	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
-	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
+	build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
 	if (m4kc_tlbp_war())
 		build_tlb_probe_entry(&p);
 	build_make_valid(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
 
+#ifdef CONFIG_HUGETLB_PAGE
+	/*
+	 * This is the entry point when build_r4000_tlbchange_handler_head
+	 * spots a huge page.
+	 */
+	uasm_l_tlb_huge_update(&l, p);
+	iPTE_LW(&p, K0, K1);
+	build_pte_present(&p, &r, K0, K1, label_nopage_tlbl);
+	build_tlb_probe_entry(&p);
+	uasm_i_ori(&p, K0, K0, (_PAGE_ACCESSED | _PAGE_VALID));
+	build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
 	uasm_l_nopage_tlbl(&l, p);
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
 	uasm_i_nop(&p);
@@ -1169,12 +1347,26 @@
 	memset(relocs, 0, sizeof(relocs));
 
 	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
-	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
+	build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
 	if (m4kc_tlbp_war())
 		build_tlb_probe_entry(&p);
 	build_make_write(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
 
+#ifdef CONFIG_HUGETLB_PAGE
+	/*
+	 * This is the entry point when
+	 * build_r4000_tlbchange_handler_head spots a huge page.
+	 */
+	uasm_l_tlb_huge_update(&l, p);
+	iPTE_LW(&p, K0, K1);
+	build_pte_writable(&p, &r, K0, K1, label_nopage_tlbs);
+	build_tlb_probe_entry(&p);
+	uasm_i_ori(&p, K0, K0,
+		   _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+	build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
 	uasm_l_nopage_tlbs(&l, p);
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
@@ -1200,13 +1392,27 @@
 	memset(relocs, 0, sizeof(relocs));
 
 	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
-	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
+	build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
 	if (m4kc_tlbp_war())
 		build_tlb_probe_entry(&p);
 	/* Present and writable bits set, set accessed and dirty bits. */
 	build_make_write(&p, &r, K0, K1);
 	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
 
+#ifdef CONFIG_HUGETLB_PAGE
+	/*
+	 * This is the entry point when
+	 * build_r4000_tlbchange_handler_head spots a huge page.
+	 */
+	uasm_l_tlb_huge_update(&l, p);
+	iPTE_LW(&p, K0, K1);
+	build_pte_modifiable(&p, &r, K0, K1, label_nopage_tlbm);
+	build_tlb_probe_entry(&p);
+	uasm_i_ori(&p, K0, K0,
+		   _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
+	build_huge_handler_tail(&p, &r, &l, K0, K1);
+#endif
+
 	uasm_l_nopage_tlbm(&l, p);
 	uasm_i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
 	uasm_i_nop(&p);
diff --git a/arch/mips/power/Makefile b/arch/mips/power/Makefile
new file mode 100644
index 0000000..73d56b8
--- /dev/null
+++ b/arch/mips/power/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_HIBERNATION) += cpu.o hibernate.o
diff --git a/arch/mips/power/cpu.c b/arch/mips/power/cpu.c
new file mode 100644
index 0000000..7995df4
--- /dev/null
+++ b/arch/mips/power/cpu.c
@@ -0,0 +1,43 @@
+/*
+ * Suspend support specific for mips.
+ *
+ * Licensed under the GPLv2
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Hu Hongbing <huhb@lemote.com>
+ *         Wu Zhangjin <wuzj@lemote.com>
+ */
+#include <asm/suspend.h>
+#include <asm/fpu.h>
+#include <asm/dsp.h>
+
+static u32 saved_status;
+struct pt_regs saved_regs;
+
+void save_processor_state(void)
+{
+	saved_status = read_c0_status();
+
+	if (is_fpu_owner())
+		save_fp(current);
+	if (cpu_has_dsp)
+		save_dsp(current);
+}
+
+void restore_processor_state(void)
+{
+	write_c0_status(saved_status);
+
+	if (is_fpu_owner())
+		restore_fp(current);
+	if (cpu_has_dsp)
+		restore_dsp(current);
+}
+
+int pfn_is_nosave(unsigned long pfn)
+{
+	unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
+	unsigned long nosave_end_pfn = PFN_UP(__pa(&__nosave_end));
+
+	return	(pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn);
+}
diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S
new file mode 100644
index 0000000..486bd3f
--- /dev/null
+++ b/arch/mips/power/hibernate.S
@@ -0,0 +1,70 @@
+/*
+ * Hibernation support specific for mips - temporary page tables
+ *
+ * Licensed under the GPLv2
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Hu Hongbing <huhb@lemote.com>
+ *         Wu Zhangjin <wuzj@lemote.com>
+ */
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+.text
+LEAF(swsusp_arch_suspend)
+	PTR_LA t0, saved_regs
+	PTR_S ra, PT_R31(t0)
+	PTR_S sp, PT_R29(t0)
+	PTR_S fp, PT_R30(t0)
+	PTR_S gp, PT_R28(t0)
+	PTR_S s0, PT_R16(t0)
+	PTR_S s1, PT_R17(t0)
+	PTR_S s2, PT_R18(t0)
+	PTR_S s3, PT_R19(t0)
+	PTR_S s4, PT_R20(t0)
+	PTR_S s5, PT_R21(t0)
+	PTR_S s6, PT_R22(t0)
+	PTR_S s7, PT_R23(t0)
+	j swsusp_save
+END(swsusp_arch_suspend)
+
+LEAF(swsusp_arch_resume)
+	PTR_L t0, restore_pblist
+0:
+	PTR_L t1, PBE_ADDRESS(t0)   /* source */
+	PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */
+	PTR_ADDIU t3, t1, _PAGE_SIZE
+1:
+	REG_L t8, (t1)
+	REG_S t8, (t2)
+	PTR_ADDIU t1, t1, SZREG
+	PTR_ADDIU t2, t2, SZREG
+	bne t1, t3, 1b
+	PTR_L t0, PBE_NEXT(t0)
+	bnez t0, 0b
+	/* flush caches to make sure context is in memory */
+	PTR_L t0, __flush_cache_all
+	jalr t0
+	/* flush tlb entries */
+#ifdef CONFIG_SMP
+	jal	flush_tlb_all
+#else
+	jal	local_flush_tlb_all
+#endif
+	PTR_LA t0, saved_regs
+	PTR_L ra, PT_R31(t0)
+	PTR_L sp, PT_R29(t0)
+	PTR_L fp, PT_R30(t0)
+	PTR_L gp, PT_R28(t0)
+	PTR_L s0, PT_R16(t0)
+	PTR_L s1, PT_R17(t0)
+	PTR_L s2, PT_R18(t0)
+	PTR_L s3, PT_R19(t0)
+	PTR_L s4, PT_R20(t0)
+	PTR_L s5, PT_R21(t0)
+	PTR_L s6, PT_R22(t0)
+	PTR_L s7, PT_R23(t0)
+	PTR_LI v0, 0x0
+	jr ra
+END(swsusp_arch_resume)
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index 53eeb5e..f078820 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -151,7 +151,8 @@
 		mask |= intr_bit;
 		WRITE_MASK(addr, mask);
 
-		if (group == GPIO_MAPPED_IRQ_GROUP)
+		/* There is a maximum of 14 GPIO interrupts */
+		if (group == GPIO_MAPPED_IRQ_GROUP && irq_nr <= (GROUP4_IRQ_BASE + 13))
 			rb532_gpio_set_istat(0, irq_nr - GPIO_MAPPED_IRQ_BASE);
 
 		/*
@@ -174,7 +175,7 @@
 	int gpio = irq_nr - GPIO_MAPPED_IRQ_BASE;
 	int group = irq_to_group(irq_nr);
 
-	if (group != GPIO_MAPPED_IRQ_GROUP)
+	if (group != GPIO_MAPPED_IRQ_GROUP || irq_nr > (GROUP4_IRQ_BASE + 13))
 		return (type == IRQ_TYPE_LEVEL_HIGH) ? 0 : -EINVAL;
 
 	switch (type) {
diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig
index 366b19d..3e639bd 100644
--- a/arch/mips/sibyte/Kconfig
+++ b/arch/mips/sibyte/Kconfig
@@ -75,6 +75,8 @@
 	select SWAP_IO_SPACE
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_64BIT_KERNEL
+	select CFE
+	select SYS_HAS_EARLY_PRINTK
 
 choice
 	prompt "SiByte SOC Stepping"
@@ -128,13 +130,6 @@
 	bool
 	select SIBYTE_HAS_LDT if PCI
 
-config SIMULATION
-	bool "Running under simulation"
-	depends on SIBYTE_SB1xxx_SOC
-	help
-	  Build a kernel suitable for running under the GDB simulator.
-	  Primarily adjusts the kernel's notion of time.
-
 config SB1_CEX_ALWAYS_FATAL
 	bool "All cache exceptions considered fatal (no recovery attempted)"
 	depends on SIBYTE_SB1xxx_SOC
@@ -143,34 +138,14 @@
 	bool "Stall (rather than panic) on fatal cache error"
 	depends on SIBYTE_SB1xxx_SOC
 
-config SIBYTE_CFE
-	bool "Booting from CFE"
-	depends on SIBYTE_SB1xxx_SOC
-	select CFE
-	select SYS_HAS_EARLY_PRINTK
-	help
-	  Make use of the CFE API for enumerating available memory,
-	  controlling secondary CPUs, and possibly console output.
-
 config SIBYTE_CFE_CONSOLE
 	bool "Use firmware console"
-	depends on SIBYTE_CFE
+	depends on SIBYTE_SB1xxx_SOC
 	help
 	  Use the CFE API's console write routines during boot.  Other console
 	  options (VT console, sb1250 duart console, etc.) should not be
 	  configured.
 
-config SIBYTE_STANDALONE
-	bool
-	depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE
-	select SYS_HAS_EARLY_PRINTK
-	default y
-
-config SIBYTE_STANDALONE_RAM_SIZE
-	int "Memory size (in megabytes)"
-	depends on SIBYTE_STANDALONE
-	default "32"
-
 config SIBYTE_BUS_WATCHER
 	bool "Support for Bus Watcher statistics"
 	depends on SIBYTE_SB1xxx_SOC
diff --git a/arch/mips/sibyte/cfe/Makefile b/arch/mips/sibyte/cfe/Makefile
deleted file mode 100644
index 02b32e1..0000000
--- a/arch/mips/sibyte/cfe/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-lib-y					= setup.o
-lib-$(CONFIG_SIBYTE_CFE_CONSOLE)	+= console.o
diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile
index 48a91b9..4f65983 100644
--- a/arch/mips/sibyte/common/Makefile
+++ b/arch/mips/sibyte/common/Makefile
@@ -1,5 +1,5 @@
-obj-y :=
-
+obj-y := cfe.o
+obj-$(CONFIG_SIBYTE_CFE_CONSOLE)	+= cfe_console.o
 obj-$(CONFIG_SIBYTE_TBPROF)		+= sb_tbprof.o
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/common/cfe.c
similarity index 100%
rename from arch/mips/sibyte/cfe/setup.c
rename to arch/mips/sibyte/common/cfe.c
diff --git a/arch/mips/sibyte/cfe/console.c b/arch/mips/sibyte/common/cfe_console.c
similarity index 100%
rename from arch/mips/sibyte/cfe/console.c
rename to arch/mips/sibyte/common/cfe_console.c
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
index 6977937..1896f4e 100644
--- a/arch/mips/sibyte/sb1250/Makefile
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -1,7 +1,6 @@
 obj-y := setup.o irq.o time.o
 
 obj-$(CONFIG_SMP)			+= smp.o
-obj-$(CONFIG_SIBYTE_STANDALONE)		+= prom.o
 obj-$(CONFIG_SIBYTE_BUS_WATCHER)	+= bus_watcher.o
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 409dec7..5e7f201 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -111,11 +111,6 @@
 
 	i = cpumask_first(mask);
 
-	if (cpumask_weight(mask) > 1) {
-		printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
-		return -1;
-	}
-
 	/* Convert logical CPU to physical CPU */
 	cpu = cpu_logical_map(i);
 
diff --git a/arch/mips/sibyte/sb1250/prom.c b/arch/mips/sibyte/sb1250/prom.c
deleted file mode 100644
index 65b1af6..0000000
--- a/arch/mips/sibyte/sb1250/prom.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2000, 2001 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/blkdev.h>
-#include <linux/bootmem.h>
-#include <linux/smp.h>
-#include <linux/initrd.h>
-#include <linux/pm.h>
-
-#include <asm/bootinfo.h>
-#include <asm/reboot.h>
-
-#define MAX_RAM_SIZE ((CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - 1)
-
-static __init void prom_meminit(void)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long initrd_pstart;
-	unsigned long initrd_pend;
-
-	initrd_pstart = __pa(initrd_start);
-	initrd_pend = __pa(initrd_end);
-	if (initrd_start &&
-	    ((initrd_pstart > MAX_RAM_SIZE)
-	     || (initrd_pend > MAX_RAM_SIZE))) {
-		panic("initrd out of addressable memory");
-	}
-
-	add_memory_region(0, initrd_pstart,
-			  BOOT_MEM_RAM);
-	add_memory_region(initrd_pstart, initrd_pend - initrd_pstart,
-			  BOOT_MEM_RESERVED);
-	add_memory_region(initrd_pend,
-			  (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - initrd_pend,
-			  BOOT_MEM_RAM);
-#else
-	add_memory_region(0, CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024,
-			  BOOT_MEM_RAM);
-#endif
-}
-
-void prom_cpu0_exit(void *unused)
-{
-        while (1) ;
-}
-
-static void prom_linux_exit(void)
-{
-#ifdef CONFIG_SMP
-	if (smp_processor_id()) {
-		smp_call_function(prom_cpu0_exit, NULL, 1);
-	}
-#endif
-	while(1);
-}
-
-/*
- * prom_init is called just after the cpu type is determined, from setup_arch()
- */
-void __init prom_init(void)
-{
-	_machine_restart   = (void (*)(char *))prom_linux_exit;
-	_machine_halt      = prom_linux_exit;
-	pm_power_off = prom_linux_exit;
-
-	strcpy(arcs_cmdline, "root=/dev/ram0 ");
-
-	prom_meminit();
-}
-
-void __init prom_free_prom_memory(void)
-{
-	/* Not sure what I'm supposed to do here.  Nothing, I think */
-}
-
-void prom_putchar(char c)
-{
-}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 080c966..672e45d 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -136,20 +136,6 @@
 	if (m41t81_probe())
 		swarm_rtc_type = RTC_M4LT81;
 
-	printk("This kernel optimized for "
-#ifdef CONFIG_SIMULATION
-	       "simulation"
-#else
-	       "board"
-#endif
-	       " runs "
-#ifdef CONFIG_SIBYTE_CFE
-	       "with"
-#else
-	       "without"
-#endif
-	       " CFE\n");
-
 #ifdef CONFIG_VT
 	screen_info = (struct screen_info) {
 		0, 0,           /* orig-x, orig-y */
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 0db7cf3..852ae4b 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -69,6 +69,7 @@
 	select IRQ_TXX9
 	select PCI_TX4927
 	select GPIO_TXX9
+	select HAS_TXX9_ACLC
 
 config SOC_TX4938
 	bool
@@ -78,6 +79,7 @@
 	select IRQ_TXX9
 	select PCI_TX4927
 	select GPIO_TXX9
+	select HAS_TXX9_ACLC
 
 config SOC_TX4939
 	bool
@@ -85,6 +87,7 @@
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
 	select PCI_TX4927
+	select HAS_TXX9_ACLC
 
 config TXX9_7SEGLED
 	bool
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index 8a266c6..3b7d77d 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -24,6 +24,7 @@
 #include <linux/serial_core.h>
 #include <linux/mtd/physmap.h>
 #include <linux/leds.h>
+#include <linux/sysdev.h>
 #include <asm/bootinfo.h>
 #include <asm/time.h>
 #include <asm/reboot.h>
@@ -33,6 +34,7 @@
 #include <asm/txx9/pci.h>
 #include <asm/txx9tmr.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #ifdef CONFIG_CPU_TX49XX
 #include <asm/txx9/tx4938.h>
 #endif
@@ -821,3 +823,176 @@
 {
 }
 #endif /* CONFIG_LEDS_GPIO */
+
+void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
+			   const struct txx9dmac_platform_data *pdata)
+{
+#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
+	struct resource res[] = {
+		{
+			.start = baseaddr,
+			.end = baseaddr + 0x800 - 1,
+			.flags = IORESOURCE_MEM,
+#ifndef CONFIG_MACH_TX49XX
+		}, {
+			.start = irq,
+			.flags = IORESOURCE_IRQ,
+#endif
+		}
+	};
+#ifdef CONFIG_MACH_TX49XX
+	struct resource chan_res[] = {
+		{
+			.flags = IORESOURCE_IRQ,
+		}
+	};
+#endif
+	struct platform_device *pdev = platform_device_alloc("txx9dmac", id);
+	struct txx9dmac_chan_platform_data cpdata;
+	int i;
+
+	if (!pdev ||
+	    platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+	    platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
+	    platform_device_add(pdev)) {
+		platform_device_put(pdev);
+		return;
+	}
+	memset(&cpdata, 0, sizeof(cpdata));
+	cpdata.dmac_dev = pdev;
+	for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+#ifdef CONFIG_MACH_TX49XX
+		chan_res[0].start = irq + i;
+#endif
+		pdev = platform_device_alloc("txx9dmac-chan",
+					     id * TXX9_DMA_MAX_NR_CHANNELS + i);
+		if (!pdev ||
+#ifdef CONFIG_MACH_TX49XX
+		    platform_device_add_resources(pdev, chan_res,
+						  ARRAY_SIZE(chan_res)) ||
+#endif
+		    platform_device_add_data(pdev, &cpdata, sizeof(cpdata)) ||
+		    platform_device_add(pdev))
+			platform_device_put(pdev);
+	}
+#endif
+}
+
+void __init txx9_aclc_init(unsigned long baseaddr, int irq,
+			   unsigned int dmac_id,
+			   unsigned int dma_chan_out,
+			   unsigned int dma_chan_in)
+{
+#if defined(CONFIG_SND_SOC_TXX9ACLC) || \
+	defined(CONFIG_SND_SOC_TXX9ACLC_MODULE)
+	unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS;
+	struct resource res[] = {
+		{
+			.start = baseaddr,
+			.end = baseaddr + 0x100 - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = irq,
+			.flags = IORESOURCE_IRQ,
+		}, {
+			.name = "txx9dmac-chan",
+			.start = dma_base + dma_chan_out,
+			.flags = IORESOURCE_DMA,
+		}, {
+			.name = "txx9dmac-chan",
+			.start = dma_base + dma_chan_in,
+			.flags = IORESOURCE_DMA,
+		}
+	};
+	struct platform_device *pdev =
+		platform_device_alloc("txx9aclc-ac97", -1);
+
+	if (!pdev ||
+	    platform_device_add_resources(pdev, res, ARRAY_SIZE(res)) ||
+	    platform_device_add(pdev))
+		platform_device_put(pdev);
+#endif
+}
+
+static struct sysdev_class txx9_sramc_sysdev_class;
+
+struct txx9_sramc_sysdev {
+	struct sys_device dev;
+	struct bin_attribute bindata_attr;
+	void __iomem *base;
+};
+
+static ssize_t txx9_sram_read(struct kobject *kobj,
+			      struct bin_attribute *bin_attr,
+			      char *buf, loff_t pos, size_t size)
+{
+	struct txx9_sramc_sysdev *dev = bin_attr->private;
+	size_t ramsize = bin_attr->size;
+
+	if (pos >= ramsize)
+		return 0;
+	if (pos + size > ramsize)
+		size = ramsize - pos;
+	memcpy_fromio(buf, dev->base + pos, size);
+	return size;
+}
+
+static ssize_t txx9_sram_write(struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t pos, size_t size)
+{
+	struct txx9_sramc_sysdev *dev = bin_attr->private;
+	size_t ramsize = bin_attr->size;
+
+	if (pos >= ramsize)
+		return 0;
+	if (pos + size > ramsize)
+		size = ramsize - pos;
+	memcpy_toio(dev->base + pos, buf, size);
+	return size;
+}
+
+void __init txx9_sramc_init(struct resource *r)
+{
+	struct txx9_sramc_sysdev *dev;
+	size_t size;
+	int err;
+
+	if (!txx9_sramc_sysdev_class.name) {
+		txx9_sramc_sysdev_class.name = "txx9_sram";
+		err = sysdev_class_register(&txx9_sramc_sysdev_class);
+		if (err) {
+			txx9_sramc_sysdev_class.name = NULL;
+			return;
+		}
+	}
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return;
+	size = resource_size(r);
+	dev->base = ioremap(r->start, size);
+	if (!dev->base)
+		goto exit;
+	dev->dev.cls = &txx9_sramc_sysdev_class;
+	dev->bindata_attr.attr.name = "bindata";
+	dev->bindata_attr.attr.mode = S_IRUSR | S_IWUSR;
+	dev->bindata_attr.read = txx9_sram_read;
+	dev->bindata_attr.write = txx9_sram_write;
+	dev->bindata_attr.size = size;
+	dev->bindata_attr.private = dev;
+	err = sysdev_register(&dev->dev);
+	if (err)
+		goto exit;
+	err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr);
+	if (err) {
+		sysdev_unregister(&dev->dev);
+		goto exit;
+	}
+	return;
+exit:
+	if (dev) {
+		if (dev->base)
+			iounmap(dev->base);
+		kfree(dev);
+	}
+}
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c
index 1093549..3418b2a 100644
--- a/arch/mips/txx9/generic/setup_tx4927.c
+++ b/arch/mips/txx9/generic/setup_tx4927.c
@@ -22,6 +22,7 @@
 #include <asm/txx9tmr.h>
 #include <asm/txx9pio.h>
 #include <asm/txx9/generic.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4927.h>
 
 static void __init tx4927_wdr_init(void)
@@ -253,6 +254,60 @@
 	txx9_physmap_flash_init(ch, start, size, &pdata);
 }
 
+void __init tx4927_dmac_init(int memcpy_chan)
+{
+	struct txx9dmac_platform_data plat_data = {
+		.memcpy_chan = memcpy_chan,
+		.have_64bit_regs = true,
+	};
+
+	txx9_dmac_init(0, TX4927_DMA_REG & 0xfffffffffULL,
+		       TXX9_IRQ_BASE + TX4927_IR_DMA(0), &plat_data);
+}
+
+void __init tx4927_aclc_init(unsigned int dma_chan_out,
+			     unsigned int dma_chan_in)
+{
+	u64 pcfg = __raw_readq(&tx4927_ccfgptr->pcfg);
+	__u64 dmasel_mask = 0, dmasel = 0;
+	unsigned long flags;
+
+	if (!(pcfg & TX4927_PCFG_SEL2))
+		return;
+	/* setup DMASEL (playback:ACLC ch0, capture:ACLC ch1) */
+	switch (dma_chan_out) {
+	case 0:
+		dmasel_mask |= TX4927_PCFG_DMASEL0_MASK;
+		dmasel |= TX4927_PCFG_DMASEL0_ACL0;
+		break;
+	case 2:
+		dmasel_mask |= TX4927_PCFG_DMASEL2_MASK;
+		dmasel |= TX4927_PCFG_DMASEL2_ACL0;
+		break;
+	default:
+		return;
+	}
+	switch (dma_chan_in) {
+	case 1:
+		dmasel_mask |= TX4927_PCFG_DMASEL1_MASK;
+		dmasel |= TX4927_PCFG_DMASEL1_ACL1;
+		break;
+	case 3:
+		dmasel_mask |= TX4927_PCFG_DMASEL3_MASK;
+		dmasel |= TX4927_PCFG_DMASEL3_ACL1;
+		break;
+	default:
+		return;
+	}
+	local_irq_save(flags);
+	txx9_clear64(&tx4927_ccfgptr->pcfg, dmasel_mask);
+	txx9_set64(&tx4927_ccfgptr->pcfg, dmasel);
+	local_irq_restore(flags);
+	txx9_aclc_init(TX4927_ACLC_REG & 0xfffffffffULL,
+		       TXX9_IRQ_BASE + TX4927_IR_ACLC,
+		       0, dma_chan_out, dma_chan_in);
+}
+
 static void __init tx4927_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 3925219..eb20801 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -24,6 +24,7 @@
 #include <asm/txx9pio.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4938.h>
 
 static void __init tx4938_wdr_init(void)
@@ -239,11 +240,6 @@
 	for (i = 0; i < TX4938_NR_TMR; i++)
 		txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
 
-	/* DMA */
-	for (i = 0; i < 2; i++)
-		____raw_writeq(TX4938_DMA_MCR_MSTEN,
-			       (void __iomem *)(TX4938_DMA_REG(i) + 0x50));
-
 	/* PIO */
 	txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO);
 	__raw_writel(0, &tx4938_pioptr->maskcpu);
@@ -403,6 +399,38 @@
 		txx9_ndfmc_init(baseaddr, &plat_data);
 }
 
+void __init tx4938_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+	struct txx9dmac_platform_data plat_data = {
+		.have_64bit_regs = true,
+	};
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+		txx9_dmac_init(i, TX4938_DMA_REG(i) & 0xfffffffffULL,
+			       TXX9_IRQ_BASE + TX4938_IR_DMA(i, 0),
+			       &plat_data);
+	}
+}
+
+void __init tx4938_aclc_init(void)
+{
+	u64 pcfg = __raw_readq(&tx4938_ccfgptr->pcfg);
+
+	if ((pcfg & TX4938_PCFG_SEL2) &&
+	    !(pcfg & TX4938_PCFG_ETH0_SEL))
+		txx9_aclc_init(TX4938_ACLC_REG & 0xfffffffffULL,
+			       TXX9_IRQ_BASE + TX4938_IR_ACLC,
+			       1, 0, 1);
+}
+
+void __init tx4938_sramc_init(void)
+{
+	if (tx4938_sram_resource.start)
+		txx9_sramc_init(&tx4938_sram_resource);
+}
+
 static void __init tx4938_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index c2bf150..3dc19f4 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -28,6 +28,7 @@
 #include <asm/txx9tmr.h>
 #include <asm/txx9/generic.h>
 #include <asm/txx9/ndfmc.h>
+#include <asm/txx9/dmac.h>
 #include <asm/txx9/tx4939.h>
 
 static void __init tx4939_wdr_init(void)
@@ -259,11 +260,6 @@
 	for (i = 0; i < TX4939_NR_TMR; i++)
 		txx9_tmr_init(TX4939_TMR_REG(i) & 0xfffffffffULL);
 
-	/* DMA */
-	for (i = 0; i < 2; i++)
-		____raw_writeq(TX4938_DMA_MCR_MSTEN,
-			       (void __iomem *)(TX4939_DMA_REG(i) + 0x50));
-
 	/* set PCIC1 reset (required to prevent hangup on BIST) */
 	txx9_set64(&tx4939_ccfgptr->clkctr, TX4939_CLKCTR_PCI1RST);
 	pcfg = ____raw_readq(&tx4939_ccfgptr->pcfg);
@@ -474,6 +470,53 @@
 	txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
 }
 
+void __init tx4939_dmac_init(int memcpy_chan0, int memcpy_chan1)
+{
+	struct txx9dmac_platform_data plat_data = {
+		.have_64bit_regs = true,
+	};
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		plat_data.memcpy_chan = i ? memcpy_chan1 : memcpy_chan0;
+		txx9_dmac_init(i, TX4939_DMA_REG(i) & 0xfffffffffULL,
+			       TXX9_IRQ_BASE + TX4939_IR_DMA(i, 0),
+			       &plat_data);
+	}
+}
+
+void __init tx4939_aclc_init(void)
+{
+	u64 pcfg = __raw_readq(&tx4939_ccfgptr->pcfg);
+
+	if ((pcfg & TX4939_PCFG_I2SMODE_MASK) == TX4939_PCFG_I2SMODE_ACLC)
+		txx9_aclc_init(TX4939_ACLC_REG & 0xfffffffffULL,
+			       TXX9_IRQ_BASE + TX4939_IR_ACLC, 1, 0, 1);
+}
+
+void __init tx4939_sramc_init(void)
+{
+	if (tx4939_sram_resource.start)
+		txx9_sramc_init(&tx4939_sram_resource);
+}
+
+void __init tx4939_rng_init(void)
+{
+	static struct resource res = {
+		.start = TX4939_RNG_REG & 0xfffffffffULL,
+		.end = (TX4939_RNG_REG & 0xfffffffffULL) + 0x30 - 1,
+		.flags = IORESOURCE_MEM,
+	};
+	static struct platform_device pdev = {
+		.name = "tx4939-rng",
+		.id = -1,
+		.num_resources = 1,
+		.resource = &res,
+	};
+
+	platform_device_register(&pdev);
+}
+
 static void __init tx4939_stop_unused_modules(void)
 {
 	__u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c
index 01129a9..ee468ea 100644
--- a/arch/mips/txx9/rbtx4927/setup.c
+++ b/arch/mips/txx9/rbtx4927/setup.c
@@ -337,6 +337,14 @@
 	rbtx4927_ne_init();
 	tx4927_wdt_init();
 	rbtx4927_mtd_init();
+	if (TX4927_REV_PCODE() == 0x4927) {
+		tx4927_dmac_init(2);
+		tx4927_aclc_init(0, 1);
+	} else {
+		tx4938_dmac_init(0, 2);
+		tx4938_aclc_init();
+	}
+	platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
 	txx9_iocled_init(RBTX4927_LED_ADDR - IO_BASE, -1, 3, 1, "green", NULL);
 	rbtx4927_gpioled_init();
 }
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 65d13df..d66509b 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -355,6 +355,10 @@
 	/* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
 	tx4938_ndfmc_init(10, 35);
 	tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
+	tx4938_dmac_init(0, 2);
+	tx4938_aclc_init();
+	platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
+	tx4938_sramc_init();
 	txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
 }
 
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 4199c6f..c033ffe 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -498,6 +498,11 @@
 	tx4939_wdt_init();
 	tx4939_ata_init();
 	tx4939_rtc_init();
+	tx4939_dmac_init(0, 2);
+	tx4939_aclc_init();
+	platform_device_register_simple("txx9aclc-generic", -1, NULL, 0);
+	tx4939_sramc_init();
+	tx4939_rng_init();
 }
 
 static void __init rbtx4939_setup(void)
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index f4b3f72..ce66a70 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -149,6 +149,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called virtio-rng.  If unsure, say N.
 
+config HW_RANDOM_TX4939
+	tristate "TX4939 Random Number Generator support"
+	depends on HW_RANDOM && SOC_TX4939
+	default HW_RANDOM
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on TX4939 SoC.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called tx4939-rng.
+
+	  If unsure, say Y.
+
 config HW_RANDOM_MXC_RNGA
 	tristate "Freescale i.MX RNGA Random Number Generator"
 	depends on HW_RANDOM && ARCH_HAS_RNGA
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index fd1ecd2..676828b 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -15,4 +15,5 @@
 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
 obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
+obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
new file mode 100644
index 0000000..544d908
--- /dev/null
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -0,0 +1,184 @@
+/*
+ * RNG driver for TX4939 Random Number Generators (RNG)
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/hw_random.h>
+
+#define TX4939_RNG_RCSR		0x00000000
+#define TX4939_RNG_ROR(n)	(0x00000018 + (n) * 8)
+
+#define TX4939_RNG_RCSR_INTE	0x00000008
+#define TX4939_RNG_RCSR_RST	0x00000004
+#define TX4939_RNG_RCSR_FIN	0x00000002
+#define TX4939_RNG_RCSR_ST	0x00000001
+
+struct tx4939_rng {
+	struct hwrng rng;
+	void __iomem *base;
+	u64 databuf[3];
+	unsigned int data_avail;
+};
+
+static void rng_io_start(void)
+{
+#ifndef CONFIG_64BIT
+	/*
+	 * readq is reading a 64-bit register using a 64-bit load.  On
+	 * a 32-bit kernel however interrupts or any other processor
+	 * exception would clobber the upper 32-bit of the processor
+	 * register so interrupts need to be disabled.
+	 */
+	local_irq_disable();
+#endif
+}
+
+static void rng_io_end(void)
+{
+#ifndef CONFIG_64BIT
+	local_irq_enable();
+#endif
+}
+
+static u64 read_rng(void __iomem *base, unsigned int offset)
+{
+	return ____raw_readq(base + offset);
+}
+
+static void write_rng(u64 val, void __iomem *base, unsigned int offset)
+{
+	return ____raw_writeq(val, base + offset);
+}
+
+static int tx4939_rng_data_present(struct hwrng *rng, int wait)
+{
+	struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
+	int i;
+
+	if (rngdev->data_avail)
+		return rngdev->data_avail;
+	for (i = 0; i < 20; i++) {
+		rng_io_start();
+		if (!(read_rng(rngdev->base, TX4939_RNG_RCSR)
+		      & TX4939_RNG_RCSR_ST)) {
+			rngdev->databuf[0] =
+				read_rng(rngdev->base, TX4939_RNG_ROR(0));
+			rngdev->databuf[1] =
+				read_rng(rngdev->base, TX4939_RNG_ROR(1));
+			rngdev->databuf[2] =
+				read_rng(rngdev->base, TX4939_RNG_ROR(2));
+			rngdev->data_avail =
+				sizeof(rngdev->databuf) / sizeof(u32);
+			/* Start RNG */
+			write_rng(TX4939_RNG_RCSR_ST,
+				  rngdev->base, TX4939_RNG_RCSR);
+			wait = 0;
+		}
+		rng_io_end();
+		if (!wait)
+			break;
+		/* 90 bus clock cycles by default for generation */
+		ndelay(90 * 5);
+	}
+	return rngdev->data_avail;
+}
+
+static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
+{
+	struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
+
+	rngdev->data_avail--;
+	*buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
+	return sizeof(u32);
+}
+
+static int __init tx4939_rng_probe(struct platform_device *dev)
+{
+	struct tx4939_rng *rngdev;
+	struct resource *r;
+	int i;
+
+	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!r)
+		return -EBUSY;
+	rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
+	if (!rngdev)
+		return -ENOMEM;
+	if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
+				     dev_name(&dev->dev)))
+		return -EBUSY;
+	rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
+	if (!rngdev->base)
+		return -EBUSY;
+
+	rngdev->rng.name = dev_name(&dev->dev);
+	rngdev->rng.data_present = tx4939_rng_data_present;
+	rngdev->rng.data_read = tx4939_rng_data_read;
+
+	rng_io_start();
+	/* Reset RNG */
+	write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR);
+	write_rng(0, rngdev->base, TX4939_RNG_RCSR);
+	/* Start RNG */
+	write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
+	rng_io_end();
+	/*
+	 * Drop first two results.  From the datasheet:
+	 * The quality of the random numbers generated immediately
+	 * after reset can be insufficient.  Therefore, do not use
+	 * random numbers obtained from the first and second
+	 * generations; use the ones from the third or subsequent
+	 * generation.
+	 */
+	for (i = 0; i < 2; i++) {
+		rngdev->data_avail = 0;
+		if (!tx4939_rng_data_present(&rngdev->rng, 1))
+			return -EIO;
+	}
+
+	platform_set_drvdata(dev, rngdev);
+	return hwrng_register(&rngdev->rng);
+}
+
+static int __exit tx4939_rng_remove(struct platform_device *dev)
+{
+	struct tx4939_rng *rngdev = platform_get_drvdata(dev);
+
+	hwrng_unregister(&rngdev->rng);
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+static struct platform_driver tx4939_rng_driver = {
+	.driver		= {
+		.name	= "tx4939-rng",
+		.owner	= THIS_MODULE,
+	},
+	.remove = tx4939_rng_remove,
+};
+
+static int __init tx4939rng_init(void)
+{
+	return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe);
+}
+
+static void __exit tx4939rng_exit(void)
+{
+	platform_driver_unregister(&tx4939_rng_driver);
+}
+
+module_init(tx4939rng_init);
+module_exit(tx4939rng_exit);
+
+MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 3b3c01b..070357a 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -81,6 +81,14 @@
 	  To avoid bloating the irq_desc[] array we allocate a sufficient
 	  number of IRQ slots and map them dynamically to specific sources.
 
+config TXX9_DMAC
+	tristate "Toshiba TXx9 SoC DMA support"
+	depends on MACH_TX49XX || MACH_TX39XX
+	select DMA_ENGINE
+	help
+	  Support the TXx9 SoC internal DMA controller.  This can be
+	  integrated in chips such as the Toshiba TX4927/38/39.
+
 config DMA_ENGINE
 	bool
 
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 2e5dc96..a0b6564 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -8,3 +8,4 @@
 obj-$(CONFIG_MV_XOR) += mv_xor.o
 obj-$(CONFIG_DW_DMAC) += dw_dmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
+obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
new file mode 100644
index 0000000..9aa9ea9
--- /dev/null
+++ b/drivers/dma/txx9dmac.c
@@ -0,0 +1,1354 @@
+/*
+ * Driver for the TXx9 SoC DMA Controller
+ *
+ * Copyright (C) 2009 Atsushi Nemoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include "txx9dmac.h"
+
+static struct txx9dmac_chan *to_txx9dmac_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct txx9dmac_chan, chan);
+}
+
+static struct txx9dmac_cregs __iomem *__dma_regs(const struct txx9dmac_chan *dc)
+{
+	return dc->ch_regs;
+}
+
+static struct txx9dmac_cregs32 __iomem *__dma_regs32(
+	const struct txx9dmac_chan *dc)
+{
+	return dc->ch_regs;
+}
+
+#define channel64_readq(dc, name) \
+	__raw_readq(&(__dma_regs(dc)->name))
+#define channel64_writeq(dc, name, val) \
+	__raw_writeq((val), &(__dma_regs(dc)->name))
+#define channel64_readl(dc, name) \
+	__raw_readl(&(__dma_regs(dc)->name))
+#define channel64_writel(dc, name, val) \
+	__raw_writel((val), &(__dma_regs(dc)->name))
+
+#define channel32_readl(dc, name) \
+	__raw_readl(&(__dma_regs32(dc)->name))
+#define channel32_writel(dc, name, val) \
+	__raw_writel((val), &(__dma_regs32(dc)->name))
+
+#define channel_readq(dc, name) channel64_readq(dc, name)
+#define channel_writeq(dc, name, val) channel64_writeq(dc, name, val)
+#define channel_readl(dc, name) \
+	(is_dmac64(dc) ? \
+	 channel64_readl(dc, name) : channel32_readl(dc, name))
+#define channel_writel(dc, name, val) \
+	(is_dmac64(dc) ? \
+	 channel64_writel(dc, name, val) : channel32_writel(dc, name, val))
+
+static dma_addr_t channel64_read_CHAR(const struct txx9dmac_chan *dc)
+{
+	if (sizeof(__dma_regs(dc)->CHAR) == sizeof(u64))
+		return channel64_readq(dc, CHAR);
+	else
+		return channel64_readl(dc, CHAR);
+}
+
+static void channel64_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val)
+{
+	if (sizeof(__dma_regs(dc)->CHAR) == sizeof(u64))
+		channel64_writeq(dc, CHAR, val);
+	else
+		channel64_writel(dc, CHAR, val);
+}
+
+static void channel64_clear_CHAR(const struct txx9dmac_chan *dc)
+{
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+	channel64_writel(dc, CHAR, 0);
+	channel64_writel(dc, __pad_CHAR, 0);
+#else
+	channel64_writeq(dc, CHAR, 0);
+#endif
+}
+
+static dma_addr_t channel_read_CHAR(const struct txx9dmac_chan *dc)
+{
+	if (is_dmac64(dc))
+		return channel64_read_CHAR(dc);
+	else
+		return channel32_readl(dc, CHAR);
+}
+
+static void channel_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val)
+{
+	if (is_dmac64(dc))
+		channel64_write_CHAR(dc, val);
+	else
+		channel32_writel(dc, CHAR, val);
+}
+
+static struct txx9dmac_regs __iomem *__txx9dmac_regs(
+	const struct txx9dmac_dev *ddev)
+{
+	return ddev->regs;
+}
+
+static struct txx9dmac_regs32 __iomem *__txx9dmac_regs32(
+	const struct txx9dmac_dev *ddev)
+{
+	return ddev->regs;
+}
+
+#define dma64_readl(ddev, name) \
+	__raw_readl(&(__txx9dmac_regs(ddev)->name))
+#define dma64_writel(ddev, name, val) \
+	__raw_writel((val), &(__txx9dmac_regs(ddev)->name))
+
+#define dma32_readl(ddev, name) \
+	__raw_readl(&(__txx9dmac_regs32(ddev)->name))
+#define dma32_writel(ddev, name, val) \
+	__raw_writel((val), &(__txx9dmac_regs32(ddev)->name))
+
+#define dma_readl(ddev, name) \
+	(__is_dmac64(ddev) ? \
+	dma64_readl(ddev, name) : dma32_readl(ddev, name))
+#define dma_writel(ddev, name, val) \
+	(__is_dmac64(ddev) ? \
+	dma64_writel(ddev, name, val) : dma32_writel(ddev, name, val))
+
+static struct device *chan2dev(struct dma_chan *chan)
+{
+	return &chan->dev->device;
+}
+static struct device *chan2parent(struct dma_chan *chan)
+{
+	return chan->dev->device.parent;
+}
+
+static struct txx9dmac_desc *
+txd_to_txx9dmac_desc(struct dma_async_tx_descriptor *txd)
+{
+	return container_of(txd, struct txx9dmac_desc, txd);
+}
+
+static dma_addr_t desc_read_CHAR(const struct txx9dmac_chan *dc,
+				 const struct txx9dmac_desc *desc)
+{
+	return is_dmac64(dc) ? desc->hwdesc.CHAR : desc->hwdesc32.CHAR;
+}
+
+static void desc_write_CHAR(const struct txx9dmac_chan *dc,
+			    struct txx9dmac_desc *desc, dma_addr_t val)
+{
+	if (is_dmac64(dc))
+		desc->hwdesc.CHAR = val;
+	else
+		desc->hwdesc32.CHAR = val;
+}
+
+#define TXX9_DMA_MAX_COUNT	0x04000000
+
+#define TXX9_DMA_INITIAL_DESC_COUNT	64
+
+static struct txx9dmac_desc *txx9dmac_first_active(struct txx9dmac_chan *dc)
+{
+	return list_entry(dc->active_list.next,
+			  struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_last_active(struct txx9dmac_chan *dc)
+{
+	return list_entry(dc->active_list.prev,
+			  struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_first_queued(struct txx9dmac_chan *dc)
+{
+	return list_entry(dc->queue.next, struct txx9dmac_desc, desc_node);
+}
+
+static struct txx9dmac_desc *txx9dmac_last_child(struct txx9dmac_desc *desc)
+{
+	if (!list_empty(&desc->txd.tx_list))
+		desc = list_entry(desc->txd.tx_list.prev,
+				  struct txx9dmac_desc, desc_node);
+	return desc;
+}
+
+static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx);
+
+static struct txx9dmac_desc *txx9dmac_desc_alloc(struct txx9dmac_chan *dc,
+						 gfp_t flags)
+{
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *desc;
+
+	desc = kzalloc(sizeof(*desc), flags);
+	if (!desc)
+		return NULL;
+	dma_async_tx_descriptor_init(&desc->txd, &dc->chan);
+	desc->txd.tx_submit = txx9dmac_tx_submit;
+	/* txd.flags will be overwritten in prep funcs */
+	desc->txd.flags = DMA_CTRL_ACK;
+	desc->txd.phys = dma_map_single(chan2parent(&dc->chan), &desc->hwdesc,
+					ddev->descsize, DMA_TO_DEVICE);
+	return desc;
+}
+
+static struct txx9dmac_desc *txx9dmac_desc_get(struct txx9dmac_chan *dc)
+{
+	struct txx9dmac_desc *desc, *_desc;
+	struct txx9dmac_desc *ret = NULL;
+	unsigned int i = 0;
+
+	spin_lock_bh(&dc->lock);
+	list_for_each_entry_safe(desc, _desc, &dc->free_list, desc_node) {
+		if (async_tx_test_ack(&desc->txd)) {
+			list_del(&desc->desc_node);
+			ret = desc;
+			break;
+		}
+		dev_dbg(chan2dev(&dc->chan), "desc %p not ACKed\n", desc);
+		i++;
+	}
+	spin_unlock_bh(&dc->lock);
+
+	dev_vdbg(chan2dev(&dc->chan), "scanned %u descriptors on freelist\n",
+		 i);
+	if (!ret) {
+		ret = txx9dmac_desc_alloc(dc, GFP_ATOMIC);
+		if (ret) {
+			spin_lock_bh(&dc->lock);
+			dc->descs_allocated++;
+			spin_unlock_bh(&dc->lock);
+		} else
+			dev_err(chan2dev(&dc->chan),
+				"not enough descriptors available\n");
+	}
+	return ret;
+}
+
+static void txx9dmac_sync_desc_for_cpu(struct txx9dmac_chan *dc,
+				       struct txx9dmac_desc *desc)
+{
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *child;
+
+	list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+		dma_sync_single_for_cpu(chan2parent(&dc->chan),
+				child->txd.phys, ddev->descsize,
+				DMA_TO_DEVICE);
+	dma_sync_single_for_cpu(chan2parent(&dc->chan),
+			desc->txd.phys, ddev->descsize,
+			DMA_TO_DEVICE);
+}
+
+/*
+ * Move a descriptor, including any children, to the free list.
+ * `desc' must not be on any lists.
+ */
+static void txx9dmac_desc_put(struct txx9dmac_chan *dc,
+			      struct txx9dmac_desc *desc)
+{
+	if (desc) {
+		struct txx9dmac_desc *child;
+
+		txx9dmac_sync_desc_for_cpu(dc, desc);
+
+		spin_lock_bh(&dc->lock);
+		list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+			dev_vdbg(chan2dev(&dc->chan),
+				 "moving child desc %p to freelist\n",
+				 child);
+		list_splice_init(&desc->txd.tx_list, &dc->free_list);
+		dev_vdbg(chan2dev(&dc->chan), "moving desc %p to freelist\n",
+			 desc);
+		list_add(&desc->desc_node, &dc->free_list);
+		spin_unlock_bh(&dc->lock);
+	}
+}
+
+/* Called with dc->lock held and bh disabled */
+static dma_cookie_t
+txx9dmac_assign_cookie(struct txx9dmac_chan *dc, struct txx9dmac_desc *desc)
+{
+	dma_cookie_t cookie = dc->chan.cookie;
+
+	if (++cookie < 0)
+		cookie = 1;
+
+	dc->chan.cookie = cookie;
+	desc->txd.cookie = cookie;
+
+	return cookie;
+}
+
+/*----------------------------------------------------------------------*/
+
+static void txx9dmac_dump_regs(struct txx9dmac_chan *dc)
+{
+	if (is_dmac64(dc))
+		dev_err(chan2dev(&dc->chan),
+			"  CHAR: %#llx SAR: %#llx DAR: %#llx CNTR: %#x"
+			" SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n",
+			(u64)channel64_read_CHAR(dc),
+			channel64_readq(dc, SAR),
+			channel64_readq(dc, DAR),
+			channel64_readl(dc, CNTR),
+			channel64_readl(dc, SAIR),
+			channel64_readl(dc, DAIR),
+			channel64_readl(dc, CCR),
+			channel64_readl(dc, CSR));
+	else
+		dev_err(chan2dev(&dc->chan),
+			"  CHAR: %#x SAR: %#x DAR: %#x CNTR: %#x"
+			" SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n",
+			channel32_readl(dc, CHAR),
+			channel32_readl(dc, SAR),
+			channel32_readl(dc, DAR),
+			channel32_readl(dc, CNTR),
+			channel32_readl(dc, SAIR),
+			channel32_readl(dc, DAIR),
+			channel32_readl(dc, CCR),
+			channel32_readl(dc, CSR));
+}
+
+static void txx9dmac_reset_chan(struct txx9dmac_chan *dc)
+{
+	channel_writel(dc, CCR, TXX9_DMA_CCR_CHRST);
+	if (is_dmac64(dc)) {
+		channel64_clear_CHAR(dc);
+		channel_writeq(dc, SAR, 0);
+		channel_writeq(dc, DAR, 0);
+	} else {
+		channel_writel(dc, CHAR, 0);
+		channel_writel(dc, SAR, 0);
+		channel_writel(dc, DAR, 0);
+	}
+	channel_writel(dc, CNTR, 0);
+	channel_writel(dc, SAIR, 0);
+	channel_writel(dc, DAIR, 0);
+	channel_writel(dc, CCR, 0);
+	mmiowb();
+}
+
+/* Called with dc->lock held and bh disabled */
+static void txx9dmac_dostart(struct txx9dmac_chan *dc,
+			     struct txx9dmac_desc *first)
+{
+	struct txx9dmac_slave *ds = dc->chan.private;
+	u32 sai, dai;
+
+	dev_vdbg(chan2dev(&dc->chan), "dostart %u %p\n",
+		 first->txd.cookie, first);
+	/* ASSERT:  channel is idle */
+	if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) {
+		dev_err(chan2dev(&dc->chan),
+			"BUG: Attempted to start non-idle channel\n");
+		txx9dmac_dump_regs(dc);
+		/* The tasklet will hopefully advance the queue... */
+		return;
+	}
+
+	if (is_dmac64(dc)) {
+		channel64_writel(dc, CNTR, 0);
+		channel64_writel(dc, CSR, 0xffffffff);
+		if (ds) {
+			if (ds->tx_reg) {
+				sai = ds->reg_width;
+				dai = 0;
+			} else {
+				sai = 0;
+				dai = ds->reg_width;
+			}
+		} else {
+			sai = 8;
+			dai = 8;
+		}
+		channel64_writel(dc, SAIR, sai);
+		channel64_writel(dc, DAIR, dai);
+		/* All 64-bit DMAC supports SMPCHN */
+		channel64_writel(dc, CCR, dc->ccr);
+		/* Writing a non zero value to CHAR will assert XFACT */
+		channel64_write_CHAR(dc, first->txd.phys);
+	} else {
+		channel32_writel(dc, CNTR, 0);
+		channel32_writel(dc, CSR, 0xffffffff);
+		if (ds) {
+			if (ds->tx_reg) {
+				sai = ds->reg_width;
+				dai = 0;
+			} else {
+				sai = 0;
+				dai = ds->reg_width;
+			}
+		} else {
+			sai = 4;
+			dai = 4;
+		}
+		channel32_writel(dc, SAIR, sai);
+		channel32_writel(dc, DAIR, dai);
+		if (txx9_dma_have_SMPCHN()) {
+			channel32_writel(dc, CCR, dc->ccr);
+			/* Writing a non zero value to CHAR will assert XFACT */
+			channel32_writel(dc, CHAR, first->txd.phys);
+		} else {
+			channel32_writel(dc, CHAR, first->txd.phys);
+			channel32_writel(dc, CCR, dc->ccr);
+		}
+	}
+}
+
+/*----------------------------------------------------------------------*/
+
+static void
+txx9dmac_descriptor_complete(struct txx9dmac_chan *dc,
+			     struct txx9dmac_desc *desc)
+{
+	dma_async_tx_callback callback;
+	void *param;
+	struct dma_async_tx_descriptor *txd = &desc->txd;
+	struct txx9dmac_slave *ds = dc->chan.private;
+
+	dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n",
+		 txd->cookie, desc);
+
+	dc->completed = txd->cookie;
+	callback = txd->callback;
+	param = txd->callback_param;
+
+	txx9dmac_sync_desc_for_cpu(dc, desc);
+	list_splice_init(&txd->tx_list, &dc->free_list);
+	list_move(&desc->desc_node, &dc->free_list);
+
+	/*
+	 * We use dma_unmap_page() regardless of how the buffers were
+	 * mapped before they were submitted...
+	 */
+	if (!ds) {
+		dma_addr_t dmaaddr;
+		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+			dmaaddr = is_dmac64(dc) ?
+				desc->hwdesc.DAR : desc->hwdesc32.DAR;
+			dma_unmap_page(chan2parent(&dc->chan), dmaaddr,
+				       desc->len, DMA_FROM_DEVICE);
+		}
+		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+			dmaaddr = is_dmac64(dc) ?
+				desc->hwdesc.SAR : desc->hwdesc32.SAR;
+			dma_unmap_page(chan2parent(&dc->chan), dmaaddr,
+				       desc->len, DMA_TO_DEVICE);
+		}
+	}
+
+	/*
+	 * The API requires that no submissions are done from a
+	 * callback, so we don't need to drop the lock here
+	 */
+	if (callback)
+		callback(param);
+	dma_run_dependencies(txd);
+}
+
+static void txx9dmac_dequeue(struct txx9dmac_chan *dc, struct list_head *list)
+{
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *desc;
+	struct txx9dmac_desc *prev = NULL;
+
+	BUG_ON(!list_empty(list));
+	do {
+		desc = txx9dmac_first_queued(dc);
+		if (prev) {
+			desc_write_CHAR(dc, prev, desc->txd.phys);
+			dma_sync_single_for_device(chan2parent(&dc->chan),
+				prev->txd.phys, ddev->descsize,
+				DMA_TO_DEVICE);
+		}
+		prev = txx9dmac_last_child(desc);
+		list_move_tail(&desc->desc_node, list);
+		/* Make chain-completion interrupt happen */
+		if ((desc->txd.flags & DMA_PREP_INTERRUPT) &&
+		    !txx9dmac_chan_INTENT(dc))
+			break;
+	} while (!list_empty(&dc->queue));
+}
+
+static void txx9dmac_complete_all(struct txx9dmac_chan *dc)
+{
+	struct txx9dmac_desc *desc, *_desc;
+	LIST_HEAD(list);
+
+	/*
+	 * Submit queued descriptors ASAP, i.e. before we go through
+	 * the completed ones.
+	 */
+	list_splice_init(&dc->active_list, &list);
+	if (!list_empty(&dc->queue)) {
+		txx9dmac_dequeue(dc, &dc->active_list);
+		txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+	}
+
+	list_for_each_entry_safe(desc, _desc, &list, desc_node)
+		txx9dmac_descriptor_complete(dc, desc);
+}
+
+static void txx9dmac_dump_desc(struct txx9dmac_chan *dc,
+			       struct txx9dmac_hwdesc *desc)
+{
+	if (is_dmac64(dc)) {
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+		dev_crit(chan2dev(&dc->chan),
+			 "  desc: ch%#llx s%#llx d%#llx c%#x\n",
+			 (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR);
+#else
+		dev_crit(chan2dev(&dc->chan),
+			 "  desc: ch%#llx s%#llx d%#llx c%#x"
+			 " si%#x di%#x cc%#x cs%#x\n",
+			 (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR,
+			 desc->SAIR, desc->DAIR, desc->CCR, desc->CSR);
+#endif
+	} else {
+		struct txx9dmac_hwdesc32 *d = (struct txx9dmac_hwdesc32 *)desc;
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+		dev_crit(chan2dev(&dc->chan),
+			 "  desc: ch%#x s%#x d%#x c%#x\n",
+			 d->CHAR, d->SAR, d->DAR, d->CNTR);
+#else
+		dev_crit(chan2dev(&dc->chan),
+			 "  desc: ch%#x s%#x d%#x c%#x"
+			 " si%#x di%#x cc%#x cs%#x\n",
+			 d->CHAR, d->SAR, d->DAR, d->CNTR,
+			 d->SAIR, d->DAIR, d->CCR, d->CSR);
+#endif
+	}
+}
+
+static void txx9dmac_handle_error(struct txx9dmac_chan *dc, u32 csr)
+{
+	struct txx9dmac_desc *bad_desc;
+	struct txx9dmac_desc *child;
+	u32 errors;
+
+	/*
+	 * The descriptor currently at the head of the active list is
+	 * borked. Since we don't have any way to report errors, we'll
+	 * just have to scream loudly and try to carry on.
+	 */
+	dev_crit(chan2dev(&dc->chan), "Abnormal Chain Completion\n");
+	txx9dmac_dump_regs(dc);
+
+	bad_desc = txx9dmac_first_active(dc);
+	list_del_init(&bad_desc->desc_node);
+
+	/* Clear all error flags and try to restart the controller */
+	errors = csr & (TXX9_DMA_CSR_ABCHC |
+			TXX9_DMA_CSR_CFERR | TXX9_DMA_CSR_CHERR |
+			TXX9_DMA_CSR_DESERR | TXX9_DMA_CSR_SORERR);
+	channel_writel(dc, CSR, errors);
+
+	if (list_empty(&dc->active_list) && !list_empty(&dc->queue))
+		txx9dmac_dequeue(dc, &dc->active_list);
+	if (!list_empty(&dc->active_list))
+		txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+
+	dev_crit(chan2dev(&dc->chan),
+		 "Bad descriptor submitted for DMA! (cookie: %d)\n",
+		 bad_desc->txd.cookie);
+	txx9dmac_dump_desc(dc, &bad_desc->hwdesc);
+	list_for_each_entry(child, &bad_desc->txd.tx_list, desc_node)
+		txx9dmac_dump_desc(dc, &child->hwdesc);
+	/* Pretend the descriptor completed successfully */
+	txx9dmac_descriptor_complete(dc, bad_desc);
+}
+
+static void txx9dmac_scan_descriptors(struct txx9dmac_chan *dc)
+{
+	dma_addr_t chain;
+	struct txx9dmac_desc *desc, *_desc;
+	struct txx9dmac_desc *child;
+	u32 csr;
+
+	if (is_dmac64(dc)) {
+		chain = channel64_read_CHAR(dc);
+		csr = channel64_readl(dc, CSR);
+		channel64_writel(dc, CSR, csr);
+	} else {
+		chain = channel32_readl(dc, CHAR);
+		csr = channel32_readl(dc, CSR);
+		channel32_writel(dc, CSR, csr);
+	}
+	/* For dynamic chain, we should look at XFACT instead of NCHNC */
+	if (!(csr & (TXX9_DMA_CSR_XFACT | TXX9_DMA_CSR_ABCHC))) {
+		/* Everything we've submitted is done */
+		txx9dmac_complete_all(dc);
+		return;
+	}
+	if (!(csr & TXX9_DMA_CSR_CHNEN))
+		chain = 0;	/* last descriptor of this chain */
+
+	dev_vdbg(chan2dev(&dc->chan), "scan_descriptors: char=%#llx\n",
+		 (u64)chain);
+
+	list_for_each_entry_safe(desc, _desc, &dc->active_list, desc_node) {
+		if (desc_read_CHAR(dc, desc) == chain) {
+			/* This one is currently in progress */
+			if (csr & TXX9_DMA_CSR_ABCHC)
+				goto scan_done;
+			return;
+		}
+
+		list_for_each_entry(child, &desc->txd.tx_list, desc_node)
+			if (desc_read_CHAR(dc, child) == chain) {
+				/* Currently in progress */
+				if (csr & TXX9_DMA_CSR_ABCHC)
+					goto scan_done;
+				return;
+			}
+
+		/*
+		 * No descriptors so far seem to be in progress, i.e.
+		 * this one must be done.
+		 */
+		txx9dmac_descriptor_complete(dc, desc);
+	}
+scan_done:
+	if (csr & TXX9_DMA_CSR_ABCHC) {
+		txx9dmac_handle_error(dc, csr);
+		return;
+	}
+
+	dev_err(chan2dev(&dc->chan),
+		"BUG: All descriptors done, but channel not idle!\n");
+
+	/* Try to continue after resetting the channel... */
+	txx9dmac_reset_chan(dc);
+
+	if (!list_empty(&dc->queue)) {
+		txx9dmac_dequeue(dc, &dc->active_list);
+		txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+	}
+}
+
+static void txx9dmac_chan_tasklet(unsigned long data)
+{
+	int irq;
+	u32 csr;
+	struct txx9dmac_chan *dc;
+
+	dc = (struct txx9dmac_chan *)data;
+	csr = channel_readl(dc, CSR);
+	dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n", csr);
+
+	spin_lock(&dc->lock);
+	if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC |
+		   TXX9_DMA_CSR_NTRNFC))
+		txx9dmac_scan_descriptors(dc);
+	spin_unlock(&dc->lock);
+	irq = dc->irq;
+
+	enable_irq(irq);
+}
+
+static irqreturn_t txx9dmac_chan_interrupt(int irq, void *dev_id)
+{
+	struct txx9dmac_chan *dc = dev_id;
+
+	dev_vdbg(chan2dev(&dc->chan), "interrupt: status=%#x\n",
+			channel_readl(dc, CSR));
+
+	tasklet_schedule(&dc->tasklet);
+	/*
+	 * Just disable the interrupts. We'll turn them back on in the
+	 * softirq handler.
+	 */
+	disable_irq_nosync(irq);
+
+	return IRQ_HANDLED;
+}
+
+static void txx9dmac_tasklet(unsigned long data)
+{
+	int irq;
+	u32 csr;
+	struct txx9dmac_chan *dc;
+
+	struct txx9dmac_dev *ddev = (struct txx9dmac_dev *)data;
+	u32 mcr;
+	int i;
+
+	mcr = dma_readl(ddev, MCR);
+	dev_vdbg(ddev->chan[0]->dma.dev, "tasklet: mcr=%x\n", mcr);
+	for (i = 0; i < TXX9_DMA_MAX_NR_CHANNELS; i++) {
+		if ((mcr >> (24 + i)) & 0x11) {
+			dc = ddev->chan[i];
+			csr = channel_readl(dc, CSR);
+			dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n",
+				 csr);
+			spin_lock(&dc->lock);
+			if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC |
+				   TXX9_DMA_CSR_NTRNFC))
+				txx9dmac_scan_descriptors(dc);
+			spin_unlock(&dc->lock);
+		}
+	}
+	irq = ddev->irq;
+
+	enable_irq(irq);
+}
+
+static irqreturn_t txx9dmac_interrupt(int irq, void *dev_id)
+{
+	struct txx9dmac_dev *ddev = dev_id;
+
+	dev_vdbg(ddev->chan[0]->dma.dev, "interrupt: status=%#x\n",
+			dma_readl(ddev, MCR));
+
+	tasklet_schedule(&ddev->tasklet);
+	/*
+	 * Just disable the interrupts. We'll turn them back on in the
+	 * softirq handler.
+	 */
+	disable_irq_nosync(irq);
+
+	return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
+static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct txx9dmac_desc *desc = txd_to_txx9dmac_desc(tx);
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(tx->chan);
+	dma_cookie_t cookie;
+
+	spin_lock_bh(&dc->lock);
+	cookie = txx9dmac_assign_cookie(dc, desc);
+
+	dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u %p\n",
+		 desc->txd.cookie, desc);
+
+	list_add_tail(&desc->desc_node, &dc->queue);
+	spin_unlock_bh(&dc->lock);
+
+	return cookie;
+}
+
+static struct dma_async_tx_descriptor *
+txx9dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		size_t len, unsigned long flags)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *desc;
+	struct txx9dmac_desc *first;
+	struct txx9dmac_desc *prev;
+	size_t xfer_count;
+	size_t offset;
+
+	dev_vdbg(chan2dev(chan), "prep_dma_memcpy d%#llx s%#llx l%#zx f%#lx\n",
+		 (u64)dest, (u64)src, len, flags);
+
+	if (unlikely(!len)) {
+		dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n");
+		return NULL;
+	}
+
+	prev = first = NULL;
+
+	for (offset = 0; offset < len; offset += xfer_count) {
+		xfer_count = min_t(size_t, len - offset, TXX9_DMA_MAX_COUNT);
+		/*
+		 * Workaround for ERT-TX49H2-033, ERT-TX49H3-020,
+		 * ERT-TX49H4-016 (slightly conservative)
+		 */
+		if (__is_dmac64(ddev)) {
+			if (xfer_count > 0x100 &&
+			    (xfer_count & 0xff) >= 0xfa &&
+			    (xfer_count & 0xff) <= 0xff)
+				xfer_count -= 0x20;
+		} else {
+			if (xfer_count > 0x80 &&
+			    (xfer_count & 0x7f) >= 0x7e &&
+			    (xfer_count & 0x7f) <= 0x7f)
+				xfer_count -= 0x20;
+		}
+
+		desc = txx9dmac_desc_get(dc);
+		if (!desc) {
+			txx9dmac_desc_put(dc, first);
+			return NULL;
+		}
+
+		if (__is_dmac64(ddev)) {
+			desc->hwdesc.SAR = src + offset;
+			desc->hwdesc.DAR = dest + offset;
+			desc->hwdesc.CNTR = xfer_count;
+			txx9dmac_desc_set_nosimple(ddev, desc, 8, 8,
+					dc->ccr | TXX9_DMA_CCR_XFACT);
+		} else {
+			desc->hwdesc32.SAR = src + offset;
+			desc->hwdesc32.DAR = dest + offset;
+			desc->hwdesc32.CNTR = xfer_count;
+			txx9dmac_desc_set_nosimple(ddev, desc, 4, 4,
+					dc->ccr | TXX9_DMA_CCR_XFACT);
+		}
+
+		/*
+		 * The descriptors on tx_list are not reachable from
+		 * the dc->queue list or dc->active_list after a
+		 * submit.  If we put all descriptors on active_list,
+		 * calling of callback on the completion will be more
+		 * complex.
+		 */
+		if (!first) {
+			first = desc;
+		} else {
+			desc_write_CHAR(dc, prev, desc->txd.phys);
+			dma_sync_single_for_device(chan2parent(&dc->chan),
+					prev->txd.phys, ddev->descsize,
+					DMA_TO_DEVICE);
+			list_add_tail(&desc->desc_node,
+					&first->txd.tx_list);
+		}
+		prev = desc;
+	}
+
+	/* Trigger interrupt after last block */
+	if (flags & DMA_PREP_INTERRUPT)
+		txx9dmac_desc_set_INTENT(ddev, prev);
+
+	desc_write_CHAR(dc, prev, 0);
+	dma_sync_single_for_device(chan2parent(&dc->chan),
+			prev->txd.phys, ddev->descsize,
+			DMA_TO_DEVICE);
+
+	first->txd.flags = flags;
+	first->len = len;
+
+	return &first->txd;
+}
+
+static struct dma_async_tx_descriptor *
+txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_data_direction direction,
+		unsigned long flags)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_slave *ds = chan->private;
+	struct txx9dmac_desc *prev;
+	struct txx9dmac_desc *first;
+	unsigned int i;
+	struct scatterlist *sg;
+
+	dev_vdbg(chan2dev(chan), "prep_dma_slave\n");
+
+	BUG_ON(!ds || !ds->reg_width);
+	if (ds->tx_reg)
+		BUG_ON(direction != DMA_TO_DEVICE);
+	else
+		BUG_ON(direction != DMA_FROM_DEVICE);
+	if (unlikely(!sg_len))
+		return NULL;
+
+	prev = first = NULL;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		struct txx9dmac_desc *desc;
+		dma_addr_t mem;
+		u32 sai, dai;
+
+		desc = txx9dmac_desc_get(dc);
+		if (!desc) {
+			txx9dmac_desc_put(dc, first);
+			return NULL;
+		}
+
+		mem = sg_dma_address(sg);
+
+		if (__is_dmac64(ddev)) {
+			if (direction == DMA_TO_DEVICE) {
+				desc->hwdesc.SAR = mem;
+				desc->hwdesc.DAR = ds->tx_reg;
+			} else {
+				desc->hwdesc.SAR = ds->rx_reg;
+				desc->hwdesc.DAR = mem;
+			}
+			desc->hwdesc.CNTR = sg_dma_len(sg);
+		} else {
+			if (direction == DMA_TO_DEVICE) {
+				desc->hwdesc32.SAR = mem;
+				desc->hwdesc32.DAR = ds->tx_reg;
+			} else {
+				desc->hwdesc32.SAR = ds->rx_reg;
+				desc->hwdesc32.DAR = mem;
+			}
+			desc->hwdesc32.CNTR = sg_dma_len(sg);
+		}
+		if (direction == DMA_TO_DEVICE) {
+			sai = ds->reg_width;
+			dai = 0;
+		} else {
+			sai = 0;
+			dai = ds->reg_width;
+		}
+		txx9dmac_desc_set_nosimple(ddev, desc, sai, dai,
+					dc->ccr | TXX9_DMA_CCR_XFACT);
+
+		if (!first) {
+			first = desc;
+		} else {
+			desc_write_CHAR(dc, prev, desc->txd.phys);
+			dma_sync_single_for_device(chan2parent(&dc->chan),
+					prev->txd.phys,
+					ddev->descsize,
+					DMA_TO_DEVICE);
+			list_add_tail(&desc->desc_node,
+					&first->txd.tx_list);
+		}
+		prev = desc;
+	}
+
+	/* Trigger interrupt after last block */
+	if (flags & DMA_PREP_INTERRUPT)
+		txx9dmac_desc_set_INTENT(ddev, prev);
+
+	desc_write_CHAR(dc, prev, 0);
+	dma_sync_single_for_device(chan2parent(&dc->chan),
+			prev->txd.phys, ddev->descsize,
+			DMA_TO_DEVICE);
+
+	first->txd.flags = flags;
+	first->len = 0;
+
+	return &first->txd;
+}
+
+static void txx9dmac_terminate_all(struct dma_chan *chan)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	struct txx9dmac_desc *desc, *_desc;
+	LIST_HEAD(list);
+
+	dev_vdbg(chan2dev(chan), "terminate_all\n");
+	spin_lock_bh(&dc->lock);
+
+	txx9dmac_reset_chan(dc);
+
+	/* active_list entries will end up before queued entries */
+	list_splice_init(&dc->queue, &list);
+	list_splice_init(&dc->active_list, &list);
+
+	spin_unlock_bh(&dc->lock);
+
+	/* Flush all pending and queued descriptors */
+	list_for_each_entry_safe(desc, _desc, &list, desc_node)
+		txx9dmac_descriptor_complete(dc, desc);
+}
+
+static enum dma_status
+txx9dmac_is_tx_complete(struct dma_chan *chan,
+			dma_cookie_t cookie,
+		dma_cookie_t *done, dma_cookie_t *used)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	dma_cookie_t last_used;
+	dma_cookie_t last_complete;
+	int ret;
+
+	last_complete = dc->completed;
+	last_used = chan->cookie;
+
+	ret = dma_async_is_complete(cookie, last_complete, last_used);
+	if (ret != DMA_SUCCESS) {
+		spin_lock_bh(&dc->lock);
+		txx9dmac_scan_descriptors(dc);
+		spin_unlock_bh(&dc->lock);
+
+		last_complete = dc->completed;
+		last_used = chan->cookie;
+
+		ret = dma_async_is_complete(cookie, last_complete, last_used);
+	}
+
+	if (done)
+		*done = last_complete;
+	if (used)
+		*used = last_used;
+
+	return ret;
+}
+
+static void txx9dmac_chain_dynamic(struct txx9dmac_chan *dc,
+				   struct txx9dmac_desc *prev)
+{
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *desc;
+	LIST_HEAD(list);
+
+	prev = txx9dmac_last_child(prev);
+	txx9dmac_dequeue(dc, &list);
+	desc = list_entry(list.next, struct txx9dmac_desc, desc_node);
+	desc_write_CHAR(dc, prev, desc->txd.phys);
+	dma_sync_single_for_device(chan2parent(&dc->chan),
+				   prev->txd.phys, ddev->descsize,
+				   DMA_TO_DEVICE);
+	mmiowb();
+	if (!(channel_readl(dc, CSR) & TXX9_DMA_CSR_CHNEN) &&
+	    channel_read_CHAR(dc) == prev->txd.phys)
+		/* Restart chain DMA */
+		channel_write_CHAR(dc, desc->txd.phys);
+	list_splice_tail(&list, &dc->active_list);
+}
+
+static void txx9dmac_issue_pending(struct dma_chan *chan)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+
+	spin_lock_bh(&dc->lock);
+
+	if (!list_empty(&dc->active_list))
+		txx9dmac_scan_descriptors(dc);
+	if (!list_empty(&dc->queue)) {
+		if (list_empty(&dc->active_list)) {
+			txx9dmac_dequeue(dc, &dc->active_list);
+			txx9dmac_dostart(dc, txx9dmac_first_active(dc));
+		} else if (txx9_dma_have_SMPCHN()) {
+			struct txx9dmac_desc *prev = txx9dmac_last_active(dc);
+
+			if (!(prev->txd.flags & DMA_PREP_INTERRUPT) ||
+			    txx9dmac_chan_INTENT(dc))
+				txx9dmac_chain_dynamic(dc, prev);
+		}
+	}
+
+	spin_unlock_bh(&dc->lock);
+}
+
+static int txx9dmac_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	struct txx9dmac_slave *ds = chan->private;
+	struct txx9dmac_desc *desc;
+	int i;
+
+	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
+
+	/* ASSERT:  channel is idle */
+	if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) {
+		dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
+		return -EIO;
+	}
+
+	dc->completed = chan->cookie = 1;
+
+	dc->ccr = TXX9_DMA_CCR_IMMCHN | TXX9_DMA_CCR_INTENE | CCR_LE;
+	txx9dmac_chan_set_SMPCHN(dc);
+	if (!txx9_dma_have_SMPCHN() || (dc->ccr & TXX9_DMA_CCR_SMPCHN))
+		dc->ccr |= TXX9_DMA_CCR_INTENC;
+	if (chan->device->device_prep_dma_memcpy) {
+		if (ds)
+			return -EINVAL;
+		dc->ccr |= TXX9_DMA_CCR_XFSZ_X8;
+	} else {
+		if (!ds ||
+		    (ds->tx_reg && ds->rx_reg) || (!ds->tx_reg && !ds->rx_reg))
+			return -EINVAL;
+		dc->ccr |= TXX9_DMA_CCR_EXTRQ |
+			TXX9_DMA_CCR_XFSZ(__ffs(ds->reg_width));
+		txx9dmac_chan_set_INTENT(dc);
+	}
+
+	spin_lock_bh(&dc->lock);
+	i = dc->descs_allocated;
+	while (dc->descs_allocated < TXX9_DMA_INITIAL_DESC_COUNT) {
+		spin_unlock_bh(&dc->lock);
+
+		desc = txx9dmac_desc_alloc(dc, GFP_KERNEL);
+		if (!desc) {
+			dev_info(chan2dev(chan),
+				"only allocated %d descriptors\n", i);
+			spin_lock_bh(&dc->lock);
+			break;
+		}
+		txx9dmac_desc_put(dc, desc);
+
+		spin_lock_bh(&dc->lock);
+		i = ++dc->descs_allocated;
+	}
+	spin_unlock_bh(&dc->lock);
+
+	dev_dbg(chan2dev(chan),
+		"alloc_chan_resources allocated %d descriptors\n", i);
+
+	return i;
+}
+
+static void txx9dmac_free_chan_resources(struct dma_chan *chan)
+{
+	struct txx9dmac_chan *dc = to_txx9dmac_chan(chan);
+	struct txx9dmac_dev *ddev = dc->ddev;
+	struct txx9dmac_desc *desc, *_desc;
+	LIST_HEAD(list);
+
+	dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n",
+			dc->descs_allocated);
+
+	/* ASSERT:  channel is idle */
+	BUG_ON(!list_empty(&dc->active_list));
+	BUG_ON(!list_empty(&dc->queue));
+	BUG_ON(channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT);
+
+	spin_lock_bh(&dc->lock);
+	list_splice_init(&dc->free_list, &list);
+	dc->descs_allocated = 0;
+	spin_unlock_bh(&dc->lock);
+
+	list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+		dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
+		dma_unmap_single(chan2parent(chan), desc->txd.phys,
+				 ddev->descsize, DMA_TO_DEVICE);
+		kfree(desc);
+	}
+
+	dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
+}
+
+/*----------------------------------------------------------------------*/
+
+static void txx9dmac_off(struct txx9dmac_dev *ddev)
+{
+	dma_writel(ddev, MCR, 0);
+	mmiowb();
+}
+
+static int __init txx9dmac_chan_probe(struct platform_device *pdev)
+{
+	struct txx9dmac_chan_platform_data *cpdata = pdev->dev.platform_data;
+	struct platform_device *dmac_dev = cpdata->dmac_dev;
+	struct txx9dmac_platform_data *pdata = dmac_dev->dev.platform_data;
+	struct txx9dmac_chan *dc;
+	int err;
+	int ch = pdev->id % TXX9_DMA_MAX_NR_CHANNELS;
+	int irq;
+
+	dc = devm_kzalloc(&pdev->dev, sizeof(*dc), GFP_KERNEL);
+	if (!dc)
+		return -ENOMEM;
+
+	dc->dma.dev = &pdev->dev;
+	dc->dma.device_alloc_chan_resources = txx9dmac_alloc_chan_resources;
+	dc->dma.device_free_chan_resources = txx9dmac_free_chan_resources;
+	dc->dma.device_terminate_all = txx9dmac_terminate_all;
+	dc->dma.device_is_tx_complete = txx9dmac_is_tx_complete;
+	dc->dma.device_issue_pending = txx9dmac_issue_pending;
+	if (pdata && pdata->memcpy_chan == ch) {
+		dc->dma.device_prep_dma_memcpy = txx9dmac_prep_dma_memcpy;
+		dma_cap_set(DMA_MEMCPY, dc->dma.cap_mask);
+	} else {
+		dc->dma.device_prep_slave_sg = txx9dmac_prep_slave_sg;
+		dma_cap_set(DMA_SLAVE, dc->dma.cap_mask);
+		dma_cap_set(DMA_PRIVATE, dc->dma.cap_mask);
+	}
+
+	INIT_LIST_HEAD(&dc->dma.channels);
+	dc->ddev = platform_get_drvdata(dmac_dev);
+	if (dc->ddev->irq < 0) {
+		irq = platform_get_irq(pdev, 0);
+		if (irq < 0)
+			return irq;
+		tasklet_init(&dc->tasklet, txx9dmac_chan_tasklet,
+				(unsigned long)dc);
+		dc->irq = irq;
+		err = devm_request_irq(&pdev->dev, dc->irq,
+			txx9dmac_chan_interrupt, 0, dev_name(&pdev->dev), dc);
+		if (err)
+			return err;
+	} else
+		dc->irq = -1;
+	dc->ddev->chan[ch] = dc;
+	dc->chan.device = &dc->dma;
+	list_add_tail(&dc->chan.device_node, &dc->chan.device->channels);
+	dc->chan.cookie = dc->completed = 1;
+
+	if (is_dmac64(dc))
+		dc->ch_regs = &__txx9dmac_regs(dc->ddev)->CHAN[ch];
+	else
+		dc->ch_regs = &__txx9dmac_regs32(dc->ddev)->CHAN[ch];
+	spin_lock_init(&dc->lock);
+
+	INIT_LIST_HEAD(&dc->active_list);
+	INIT_LIST_HEAD(&dc->queue);
+	INIT_LIST_HEAD(&dc->free_list);
+
+	txx9dmac_reset_chan(dc);
+
+	platform_set_drvdata(pdev, dc);
+
+	err = dma_async_device_register(&dc->dma);
+	if (err)
+		return err;
+	dev_dbg(&pdev->dev, "TXx9 DMA Channel (dma%d%s%s)\n",
+		dc->dma.dev_id,
+		dma_has_cap(DMA_MEMCPY, dc->dma.cap_mask) ? " memcpy" : "",
+		dma_has_cap(DMA_SLAVE, dc->dma.cap_mask) ? " slave" : "");
+
+	return 0;
+}
+
+static int __exit txx9dmac_chan_remove(struct platform_device *pdev)
+{
+	struct txx9dmac_chan *dc = platform_get_drvdata(pdev);
+
+	dma_async_device_unregister(&dc->dma);
+	if (dc->irq >= 0)
+		tasklet_kill(&dc->tasklet);
+	dc->ddev->chan[pdev->id % TXX9_DMA_MAX_NR_CHANNELS] = NULL;
+	return 0;
+}
+
+static int __init txx9dmac_probe(struct platform_device *pdev)
+{
+	struct txx9dmac_platform_data *pdata = pdev->dev.platform_data;
+	struct resource *io;
+	struct txx9dmac_dev *ddev;
+	u32 mcr;
+	int err;
+
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!io)
+		return -EINVAL;
+
+	ddev = devm_kzalloc(&pdev->dev, sizeof(*ddev), GFP_KERNEL);
+	if (!ddev)
+		return -ENOMEM;
+
+	if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io),
+				     dev_name(&pdev->dev)))
+		return -EBUSY;
+
+	ddev->regs = devm_ioremap(&pdev->dev, io->start, resource_size(io));
+	if (!ddev->regs)
+		return -ENOMEM;
+	ddev->have_64bit_regs = pdata->have_64bit_regs;
+	if (__is_dmac64(ddev))
+		ddev->descsize = sizeof(struct txx9dmac_hwdesc);
+	else
+		ddev->descsize = sizeof(struct txx9dmac_hwdesc32);
+
+	/* force dma off, just in case */
+	txx9dmac_off(ddev);
+
+	ddev->irq = platform_get_irq(pdev, 0);
+	if (ddev->irq >= 0) {
+		tasklet_init(&ddev->tasklet, txx9dmac_tasklet,
+				(unsigned long)ddev);
+		err = devm_request_irq(&pdev->dev, ddev->irq,
+			txx9dmac_interrupt, 0, dev_name(&pdev->dev), ddev);
+		if (err)
+			return err;
+	}
+
+	mcr = TXX9_DMA_MCR_MSTEN | MCR_LE;
+	if (pdata && pdata->memcpy_chan >= 0)
+		mcr |= TXX9_DMA_MCR_FIFUM(pdata->memcpy_chan);
+	dma_writel(ddev, MCR, mcr);
+
+	platform_set_drvdata(pdev, ddev);
+	return 0;
+}
+
+static int __exit txx9dmac_remove(struct platform_device *pdev)
+{
+	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+	txx9dmac_off(ddev);
+	if (ddev->irq >= 0)
+		tasklet_kill(&ddev->tasklet);
+	return 0;
+}
+
+static void txx9dmac_shutdown(struct platform_device *pdev)
+{
+	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+	txx9dmac_off(ddev);
+}
+
+static int txx9dmac_suspend_late(struct platform_device *pdev,
+				 pm_message_t mesg)
+{
+	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+
+	txx9dmac_off(ddev);
+	return 0;
+}
+
+static int txx9dmac_resume_early(struct platform_device *pdev)
+{
+	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
+	struct txx9dmac_platform_data *pdata = pdev->dev.platform_data;
+	u32 mcr;
+
+	mcr = TXX9_DMA_MCR_MSTEN | MCR_LE;
+	if (pdata && pdata->memcpy_chan >= 0)
+		mcr |= TXX9_DMA_MCR_FIFUM(pdata->memcpy_chan);
+	dma_writel(ddev, MCR, mcr);
+	return 0;
+
+}
+
+static struct platform_driver txx9dmac_chan_driver = {
+	.remove		= __exit_p(txx9dmac_chan_remove),
+	.driver = {
+		.name	= "txx9dmac-chan",
+	},
+};
+
+static struct platform_driver txx9dmac_driver = {
+	.remove		= __exit_p(txx9dmac_remove),
+	.shutdown	= txx9dmac_shutdown,
+	.suspend_late	= txx9dmac_suspend_late,
+	.resume_early	= txx9dmac_resume_early,
+	.driver = {
+		.name	= "txx9dmac",
+	},
+};
+
+static int __init txx9dmac_init(void)
+{
+	int rc;
+
+	rc = platform_driver_probe(&txx9dmac_driver, txx9dmac_probe);
+	if (!rc) {
+		rc = platform_driver_probe(&txx9dmac_chan_driver,
+					   txx9dmac_chan_probe);
+		if (rc)
+			platform_driver_unregister(&txx9dmac_driver);
+	}
+	return rc;
+}
+module_init(txx9dmac_init);
+
+static void __exit txx9dmac_exit(void)
+{
+	platform_driver_unregister(&txx9dmac_chan_driver);
+	platform_driver_unregister(&txx9dmac_driver);
+}
+module_exit(txx9dmac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 DMA Controller driver");
+MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h
new file mode 100644
index 0000000..c907ff0
--- /dev/null
+++ b/drivers/dma/txx9dmac.h
@@ -0,0 +1,307 @@
+/*
+ * Driver for the TXx9 SoC DMA Controller
+ *
+ * Copyright (C) 2009 Atsushi Nemoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef TXX9DMAC_H
+#define TXX9DMAC_H
+
+#include <linux/dmaengine.h>
+#include <asm/txx9/dmac.h>
+
+/*
+ * Design Notes:
+ *
+ * This DMAC have four channels and one FIFO buffer.  Each channel can
+ * be configured for memory-memory or device-memory transfer, but only
+ * one channel can do alignment-free memory-memory transfer at a time
+ * while the channel should occupy the FIFO buffer for effective
+ * transfers.
+ *
+ * Instead of dynamically assign the FIFO buffer to channels, I chose
+ * make one dedicated channel for memory-memory transfer.  The
+ * dedicated channel is public.  Other channels are private and used
+ * for slave transfer.  Some devices in the SoC are wired to certain
+ * DMA channel.
+ */
+
+#ifdef CONFIG_MACH_TX49XX
+static inline bool txx9_dma_have_SMPCHN(void)
+{
+	return true;
+}
+#define TXX9_DMA_USE_SIMPLE_CHAIN
+#else
+static inline bool txx9_dma_have_SMPCHN(void)
+{
+	return false;
+}
+#endif
+
+#ifdef __LITTLE_ENDIAN
+#ifdef CONFIG_MACH_TX49XX
+#define CCR_LE	TXX9_DMA_CCR_LE
+#define MCR_LE	0
+#else
+#define CCR_LE	0
+#define MCR_LE	TXX9_DMA_MCR_LE
+#endif
+#else
+#define CCR_LE	0
+#define MCR_LE	0
+#endif
+
+/*
+ * Redefine this macro to handle differences between 32- and 64-bit
+ * addressing, big vs. little endian, etc.
+ */
+#ifdef __BIG_ENDIAN
+#define TXX9_DMA_REG32(name)		u32 __pad_##name; u32 name
+#else
+#define TXX9_DMA_REG32(name)		u32 name; u32 __pad_##name
+#endif
+
+/* Hardware register definitions. */
+struct txx9dmac_cregs {
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+	TXX9_DMA_REG32(CHAR);	/* Chain Address Register */
+#else
+	u64 CHAR;		/* Chain Address Register */
+#endif
+	u64 SAR;		/* Source Address Register */
+	u64 DAR;		/* Destination Address Register */
+	TXX9_DMA_REG32(CNTR);	/* Count Register */
+	TXX9_DMA_REG32(SAIR);	/* Source Address Increment Register */
+	TXX9_DMA_REG32(DAIR);	/* Destination Address Increment Register */
+	TXX9_DMA_REG32(CCR);	/* Channel Control Register */
+	TXX9_DMA_REG32(CSR);	/* Channel Status Register */
+};
+struct txx9dmac_cregs32 {
+	u32 CHAR;
+	u32 SAR;
+	u32 DAR;
+	u32 CNTR;
+	u32 SAIR;
+	u32 DAIR;
+	u32 CCR;
+	u32 CSR;
+};
+
+struct txx9dmac_regs {
+	/* per-channel registers */
+	struct txx9dmac_cregs	CHAN[TXX9_DMA_MAX_NR_CHANNELS];
+	u64	__pad[9];
+	u64	MFDR;		/* Memory Fill Data Register */
+	TXX9_DMA_REG32(MCR);	/* Master Control Register */
+};
+struct txx9dmac_regs32 {
+	struct txx9dmac_cregs32	CHAN[TXX9_DMA_MAX_NR_CHANNELS];
+	u32	__pad[9];
+	u32	MFDR;
+	u32	MCR;
+};
+
+/* bits for MCR */
+#define TXX9_DMA_MCR_EIS(ch)	(0x10000000<<(ch))
+#define TXX9_DMA_MCR_DIS(ch)	(0x01000000<<(ch))
+#define TXX9_DMA_MCR_RSFIF	0x00000080
+#define TXX9_DMA_MCR_FIFUM(ch)	(0x00000008<<(ch))
+#define TXX9_DMA_MCR_LE		0x00000004
+#define TXX9_DMA_MCR_RPRT	0x00000002
+#define TXX9_DMA_MCR_MSTEN	0x00000001
+
+/* bits for CCRn */
+#define TXX9_DMA_CCR_IMMCHN	0x20000000
+#define TXX9_DMA_CCR_USEXFSZ	0x10000000
+#define TXX9_DMA_CCR_LE		0x08000000
+#define TXX9_DMA_CCR_DBINH	0x04000000
+#define TXX9_DMA_CCR_SBINH	0x02000000
+#define TXX9_DMA_CCR_CHRST	0x01000000
+#define TXX9_DMA_CCR_RVBYTE	0x00800000
+#define TXX9_DMA_CCR_ACKPOL	0x00400000
+#define TXX9_DMA_CCR_REQPL	0x00200000
+#define TXX9_DMA_CCR_EGREQ	0x00100000
+#define TXX9_DMA_CCR_CHDN	0x00080000
+#define TXX9_DMA_CCR_DNCTL	0x00060000
+#define TXX9_DMA_CCR_EXTRQ	0x00010000
+#define TXX9_DMA_CCR_INTRQD	0x0000e000
+#define TXX9_DMA_CCR_INTENE	0x00001000
+#define TXX9_DMA_CCR_INTENC	0x00000800
+#define TXX9_DMA_CCR_INTENT	0x00000400
+#define TXX9_DMA_CCR_CHNEN	0x00000200
+#define TXX9_DMA_CCR_XFACT	0x00000100
+#define TXX9_DMA_CCR_SMPCHN	0x00000020
+#define TXX9_DMA_CCR_XFSZ(order)	(((order) << 2) & 0x0000001c)
+#define TXX9_DMA_CCR_XFSZ_1	TXX9_DMA_CCR_XFSZ(0)
+#define TXX9_DMA_CCR_XFSZ_2	TXX9_DMA_CCR_XFSZ(1)
+#define TXX9_DMA_CCR_XFSZ_4	TXX9_DMA_CCR_XFSZ(2)
+#define TXX9_DMA_CCR_XFSZ_8	TXX9_DMA_CCR_XFSZ(3)
+#define TXX9_DMA_CCR_XFSZ_X4	TXX9_DMA_CCR_XFSZ(4)
+#define TXX9_DMA_CCR_XFSZ_X8	TXX9_DMA_CCR_XFSZ(5)
+#define TXX9_DMA_CCR_XFSZ_X16	TXX9_DMA_CCR_XFSZ(6)
+#define TXX9_DMA_CCR_XFSZ_X32	TXX9_DMA_CCR_XFSZ(7)
+#define TXX9_DMA_CCR_MEMIO	0x00000002
+#define TXX9_DMA_CCR_SNGAD	0x00000001
+
+/* bits for CSRn */
+#define TXX9_DMA_CSR_CHNEN	0x00000400
+#define TXX9_DMA_CSR_STLXFER	0x00000200
+#define TXX9_DMA_CSR_XFACT	0x00000100
+#define TXX9_DMA_CSR_ABCHC	0x00000080
+#define TXX9_DMA_CSR_NCHNC	0x00000040
+#define TXX9_DMA_CSR_NTRNFC	0x00000020
+#define TXX9_DMA_CSR_EXTDN	0x00000010
+#define TXX9_DMA_CSR_CFERR	0x00000008
+#define TXX9_DMA_CSR_CHERR	0x00000004
+#define TXX9_DMA_CSR_DESERR	0x00000002
+#define TXX9_DMA_CSR_SORERR	0x00000001
+
+struct txx9dmac_chan {
+	struct dma_chan		chan;
+	struct dma_device	dma;
+	struct txx9dmac_dev	*ddev;
+	void __iomem		*ch_regs;
+	struct tasklet_struct	tasklet;
+	int			irq;
+	u32			ccr;
+
+	spinlock_t		lock;
+
+	/* these other elements are all protected by lock */
+	dma_cookie_t		completed;
+	struct list_head	active_list;
+	struct list_head	queue;
+	struct list_head	free_list;
+
+	unsigned int		descs_allocated;
+};
+
+struct txx9dmac_dev {
+	void __iomem		*regs;
+	struct tasklet_struct	tasklet;
+	int			irq;
+	struct txx9dmac_chan	*chan[TXX9_DMA_MAX_NR_CHANNELS];
+	bool			have_64bit_regs;
+	unsigned int		descsize;
+};
+
+static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
+{
+	return ddev->have_64bit_regs;
+}
+
+static inline bool is_dmac64(const struct txx9dmac_chan *dc)
+{
+	return __is_dmac64(dc->ddev);
+}
+
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+/* Hardware descriptor definition. (for simple-chain) */
+struct txx9dmac_hwdesc {
+#if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR)
+	TXX9_DMA_REG32(CHAR);
+#else
+	u64 CHAR;
+#endif
+	u64 SAR;
+	u64 DAR;
+	TXX9_DMA_REG32(CNTR);
+};
+struct txx9dmac_hwdesc32 {
+	u32 CHAR;
+	u32 SAR;
+	u32 DAR;
+	u32 CNTR;
+};
+#else
+#define txx9dmac_hwdesc txx9dmac_cregs
+#define txx9dmac_hwdesc32 txx9dmac_cregs32
+#endif
+
+struct txx9dmac_desc {
+	/* FIRST values the hardware uses */
+	union {
+		struct txx9dmac_hwdesc hwdesc;
+		struct txx9dmac_hwdesc32 hwdesc32;
+	};
+
+	/* THEN values for driver housekeeping */
+	struct list_head		desc_node ____cacheline_aligned;
+	struct dma_async_tx_descriptor	txd;
+	size_t				len;
+};
+
+#ifdef TXX9_DMA_USE_SIMPLE_CHAIN
+
+static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
+{
+	return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
+}
+
+static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
+{
+	dc->ccr |= TXX9_DMA_CCR_INTENT;
+}
+
+static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
+					    struct txx9dmac_desc *desc)
+{
+}
+
+static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
+{
+	dc->ccr |= TXX9_DMA_CCR_SMPCHN;
+}
+
+static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
+					      struct txx9dmac_desc *desc,
+					      u32 sair, u32 dair, u32 ccr)
+{
+}
+
+#else /* TXX9_DMA_USE_SIMPLE_CHAIN */
+
+static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
+{
+	return true;
+}
+
+static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
+{
+}
+
+static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
+					    struct txx9dmac_desc *desc)
+{
+	if (__is_dmac64(ddev))
+		desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
+	else
+		desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
+}
+
+static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
+{
+}
+
+static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
+					      struct txx9dmac_desc *desc,
+					      u32 sai, u32 dai, u32 ccr)
+{
+	if (__is_dmac64(ddev)) {
+		desc->hwdesc.SAIR = sai;
+		desc->hwdesc.DAIR = dai;
+		desc->hwdesc.CCR = ccr;
+	} else {
+		desc->hwdesc32.SAIR = sai;
+		desc->hwdesc32.DAIR = dai;
+		desc->hwdesc32.CCR = ccr;
+	}
+}
+
+#endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
+
+#endif /* TXX9DMAC_H */
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d0fcf36..9256578 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -117,5 +117,7 @@
 
 source "drivers/gpu/drm/radeon/Kconfig"
 
+source "drivers/staging/octeon/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 47dfd5b4..6da9c74 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -40,3 +40,4 @@
 obj-$(CONFIG_HECI)		+= heci/
 obj-$(CONFIG_LINE6_USB)		+= line6/
 obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100)	+= serqt_usb/
+obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
diff --git a/drivers/staging/octeon/Kconfig b/drivers/staging/octeon/Kconfig
new file mode 100644
index 0000000..536e238
--- /dev/null
+++ b/drivers/staging/octeon/Kconfig
@@ -0,0 +1,12 @@
+config OCTEON_ETHERNET
+	tristate "Cavium Networks Octeon Ethernet support"
+	depends on CPU_CAVIUM_OCTEON
+	select MII
+	help
+	  This driver supports the builtin ethernet ports on Cavium
+	  Networks' products in the Octeon family. This driver supports the
+	  CN3XXX and CN5XXX Octeon processors.
+
+	  To compile this driver as a module, choose M here.  The module
+	  will be called octeon-ethernet.
+
diff --git a/drivers/staging/octeon/Makefile b/drivers/staging/octeon/Makefile
new file mode 100644
index 0000000..3c839e3
--- /dev/null
+++ b/drivers/staging/octeon/Makefile
@@ -0,0 +1,30 @@
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 2005-2009 Cavium Networks
+#
+
+#
+# Makefile for Cavium OCTEON on-board ethernet driver
+#
+
+obj-${CONFIG_OCTEON_ETHERNET} :=  octeon-ethernet.o
+
+octeon-ethernet-objs := ethernet.o
+octeon-ethernet-objs += ethernet-common.o
+octeon-ethernet-objs += ethernet-mdio.o
+octeon-ethernet-objs += ethernet-mem.o
+octeon-ethernet-objs += ethernet-proc.o
+octeon-ethernet-objs += ethernet-rgmii.o
+octeon-ethernet-objs += ethernet-rx.o
+octeon-ethernet-objs += ethernet-sgmii.o
+octeon-ethernet-objs += ethernet-spi.o
+octeon-ethernet-objs += ethernet-tx.o
+octeon-ethernet-objs += ethernet-xaui.o
+octeon-ethernet-objs += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
+	cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
+	cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
+	cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
+	cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
+
diff --git a/drivers/staging/octeon/cvmx-address.h b/drivers/staging/octeon/cvmx-address.h
new file mode 100644
index 0000000..3c74d82
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-address.h
@@ -0,0 +1,274 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2009 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * Typedefs and defines for working with Octeon physical addresses.
+ *
+ */
+#ifndef __CVMX_ADDRESS_H__
+#define __CVMX_ADDRESS_H__
+
+#if 0
+typedef enum {
+	CVMX_MIPS_SPACE_XKSEG = 3LL,
+	CVMX_MIPS_SPACE_XKPHYS = 2LL,
+	CVMX_MIPS_SPACE_XSSEG = 1LL,
+	CVMX_MIPS_SPACE_XUSEG = 0LL
+} cvmx_mips_space_t;
+#endif
+
+typedef enum {
+	CVMX_MIPS_XKSEG_SPACE_KSEG0 = 0LL,
+	CVMX_MIPS_XKSEG_SPACE_KSEG1 = 1LL,
+	CVMX_MIPS_XKSEG_SPACE_SSEG = 2LL,
+	CVMX_MIPS_XKSEG_SPACE_KSEG3 = 3LL
+} cvmx_mips_xkseg_space_t;
+
+/* decodes <14:13> of a kseg3 window address */
+typedef enum {
+	CVMX_ADD_WIN_SCR = 0L,
+	/* see cvmx_add_win_dma_dec_t for further decode */
+	CVMX_ADD_WIN_DMA = 1L,
+	CVMX_ADD_WIN_UNUSED = 2L,
+	CVMX_ADD_WIN_UNUSED2 = 3L
+} cvmx_add_win_dec_t;
+
+/* decode within DMA space */
+typedef enum {
+	/*
+	 * Add store data to the write buffer entry, allocating it if
+	 * necessary.
+	 */
+	CVMX_ADD_WIN_DMA_ADD = 0L,
+	/* send out the write buffer entry to DRAM */
+	CVMX_ADD_WIN_DMA_SENDMEM = 1L,
+	/* store data must be normal DRAM memory space address in this case */
+	/* send out the write buffer entry as an IOBDMA command */
+	CVMX_ADD_WIN_DMA_SENDDMA = 2L,
+	/* see CVMX_ADD_WIN_DMA_SEND_DEC for data contents */
+	/* send out the write buffer entry as an IO write */
+	CVMX_ADD_WIN_DMA_SENDIO = 3L,
+	/* store data must be normal IO space address in this case */
+	/* send out a single-tick command on the NCB bus */
+	CVMX_ADD_WIN_DMA_SENDSINGLE = 4L,
+	/* no write buffer data needed/used */
+} cvmx_add_win_dma_dec_t;
+
+/*
+ *   Physical Address Decode
+ *
+ * Octeon-I HW never interprets this X (<39:36> reserved
+ * for future expansion), software should set to 0.
+ *
+ *  - 0x0 XXX0 0000 0000 to      DRAM         Cached
+ *  - 0x0 XXX0 0FFF FFFF
+ *
+ *  - 0x0 XXX0 1000 0000 to      Boot Bus     Uncached  (Converted to 0x1 00X0 1000 0000
+ *  - 0x0 XXX0 1FFF FFFF         + EJTAG                           to 0x1 00X0 1FFF FFFF)
+ *
+ *  - 0x0 XXX0 2000 0000 to      DRAM         Cached
+ *  - 0x0 XXXF FFFF FFFF
+ *
+ *  - 0x1 00X0 0000 0000 to      Boot Bus     Uncached
+ *  - 0x1 00XF FFFF FFFF
+ *
+ *  - 0x1 01X0 0000 0000 to      Other NCB    Uncached
+ *  - 0x1 FFXF FFFF FFFF         devices
+ *
+ * Decode of all Octeon addresses
+ */
+typedef union {
+
+	uint64_t u64;
+	/* mapped or unmapped virtual address */
+	struct {
+		uint64_t R:2;
+		uint64_t offset:62;
+	} sva;
+
+	/* mapped USEG virtual addresses (typically) */
+	struct {
+		uint64_t zeroes:33;
+		uint64_t offset:31;
+	} suseg;
+
+	/* mapped or unmapped virtual address */
+	struct {
+		uint64_t ones:33;
+		uint64_t sp:2;
+		uint64_t offset:29;
+	} sxkseg;
+
+	/*
+	 * physical address accessed through xkphys unmapped virtual
+	 * address.
+	 */
+	struct {
+		uint64_t R:2;	/* CVMX_MIPS_SPACE_XKPHYS in this case */
+		uint64_t cca:3;	/* ignored by octeon */
+		uint64_t mbz:10;
+		uint64_t pa:49;	/* physical address */
+	} sxkphys;
+
+	/* physical address */
+	struct {
+		uint64_t mbz:15;
+		/* if set, the address is uncached and resides on MCB bus */
+		uint64_t is_io:1;
+		/*
+		 * the hardware ignores this field when is_io==0, else
+		 * device ID.
+		 */
+		uint64_t did:8;
+		/* the hardware ignores <39:36> in Octeon I */
+		uint64_t unaddr:4;
+		uint64_t offset:36;
+	} sphys;
+
+	/* physical mem address */
+	struct {
+		/* techically, <47:40> are dont-cares */
+		uint64_t zeroes:24;
+		/* the hardware ignores <39:36> in Octeon I */
+		uint64_t unaddr:4;
+		uint64_t offset:36;
+	} smem;
+
+	/* physical IO address */
+	struct {
+		uint64_t mem_region:2;
+		uint64_t mbz:13;
+		/* 1 in this case */
+		uint64_t is_io:1;
+		/*
+		 * The hardware ignores this field when is_io==0, else
+		 * device ID.
+		 */
+		uint64_t did:8;
+		/* the hardware ignores <39:36> in Octeon I */
+		uint64_t unaddr:4;
+		uint64_t offset:36;
+	} sio;
+
+	/*
+	 * Scratchpad virtual address - accessed through a window at
+	 * the end of kseg3
+	 */
+	struct {
+		uint64_t ones:49;
+		/* CVMX_ADD_WIN_SCR (0) in this case */
+		cvmx_add_win_dec_t csrdec:2;
+		uint64_t addr:13;
+	} sscr;
+
+	/* there should only be stores to IOBDMA space, no loads */
+	/*
+	 * IOBDMA virtual address - accessed through a window at the
+	 * end of kseg3
+	 */
+	struct {
+		uint64_t ones:49;
+		uint64_t csrdec:2;	/* CVMX_ADD_WIN_DMA (1) in this case */
+		uint64_t unused2:3;
+		uint64_t type:3;
+		uint64_t addr:7;
+	} sdma;
+
+	struct {
+		uint64_t didspace:24;
+		uint64_t unused:40;
+	} sfilldidspace;
+
+} cvmx_addr_t;
+
+/* These macros for used by 32 bit applications */
+
+#define CVMX_MIPS32_SPACE_KSEG0 1l
+#define CVMX_ADD_SEG32(segment, add) \
+	(((int32_t)segment << 31) | (int32_t)(add))
+
+/*
+ * Currently all IOs are performed using XKPHYS addressing. Linux uses
+ * the CvmMemCtl register to enable XKPHYS addressing to IO space from
+ * user mode.  Future OSes may need to change the upper bits of IO
+ * addresses. The following define controls the upper two bits for all
+ * IO addresses generated by the simple executive library.
+ */
+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
+
+/* These macros simplify the process of creating common IO addresses */
+#define CVMX_ADD_SEG(segment, add) ((((uint64_t)segment) << 62) | (add))
+#ifndef CVMX_ADD_IO_SEG
+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
+#endif
+#define CVMX_ADDR_DIDSPACE(did) (((CVMX_IO_SEG) << 22) | ((1ULL) << 8) | (did))
+#define CVMX_ADDR_DID(did) (CVMX_ADDR_DIDSPACE(did) << 40)
+#define CVMX_FULL_DID(did, subdid) (((did) << 3) | (subdid))
+
+  /* from include/ncb_rsl_id.v */
+#define CVMX_OCT_DID_MIS 0ULL	/* misc stuff */
+#define CVMX_OCT_DID_GMX0 1ULL
+#define CVMX_OCT_DID_GMX1 2ULL
+#define CVMX_OCT_DID_PCI 3ULL
+#define CVMX_OCT_DID_KEY 4ULL
+#define CVMX_OCT_DID_FPA 5ULL
+#define CVMX_OCT_DID_DFA 6ULL
+#define CVMX_OCT_DID_ZIP 7ULL
+#define CVMX_OCT_DID_RNG 8ULL
+#define CVMX_OCT_DID_IPD 9ULL
+#define CVMX_OCT_DID_PKT 10ULL
+#define CVMX_OCT_DID_TIM 11ULL
+#define CVMX_OCT_DID_TAG 12ULL
+  /* the rest are not on the IO bus */
+#define CVMX_OCT_DID_L2C 16ULL
+#define CVMX_OCT_DID_LMC 17ULL
+#define CVMX_OCT_DID_SPX0 18ULL
+#define CVMX_OCT_DID_SPX1 19ULL
+#define CVMX_OCT_DID_PIP 20ULL
+#define CVMX_OCT_DID_ASX0 22ULL
+#define CVMX_OCT_DID_ASX1 23ULL
+#define CVMX_OCT_DID_IOB 30ULL
+
+#define CVMX_OCT_DID_PKT_SEND       CVMX_FULL_DID(CVMX_OCT_DID_PKT, 2ULL)
+#define CVMX_OCT_DID_TAG_SWTAG      CVMX_FULL_DID(CVMX_OCT_DID_TAG, 0ULL)
+#define CVMX_OCT_DID_TAG_TAG1       CVMX_FULL_DID(CVMX_OCT_DID_TAG, 1ULL)
+#define CVMX_OCT_DID_TAG_TAG2       CVMX_FULL_DID(CVMX_OCT_DID_TAG, 2ULL)
+#define CVMX_OCT_DID_TAG_TAG3       CVMX_FULL_DID(CVMX_OCT_DID_TAG, 3ULL)
+#define CVMX_OCT_DID_TAG_NULL_RD    CVMX_FULL_DID(CVMX_OCT_DID_TAG, 4ULL)
+#define CVMX_OCT_DID_TAG_CSR        CVMX_FULL_DID(CVMX_OCT_DID_TAG, 7ULL)
+#define CVMX_OCT_DID_FAU_FAI        CVMX_FULL_DID(CVMX_OCT_DID_IOB, 0ULL)
+#define CVMX_OCT_DID_TIM_CSR        CVMX_FULL_DID(CVMX_OCT_DID_TIM, 0ULL)
+#define CVMX_OCT_DID_KEY_RW         CVMX_FULL_DID(CVMX_OCT_DID_KEY, 0ULL)
+#define CVMX_OCT_DID_PCI_6          CVMX_FULL_DID(CVMX_OCT_DID_PCI, 6ULL)
+#define CVMX_OCT_DID_MIS_BOO        CVMX_FULL_DID(CVMX_OCT_DID_MIS, 0ULL)
+#define CVMX_OCT_DID_PCI_RML        CVMX_FULL_DID(CVMX_OCT_DID_PCI, 0ULL)
+#define CVMX_OCT_DID_IPD_CSR        CVMX_FULL_DID(CVMX_OCT_DID_IPD, 7ULL)
+#define CVMX_OCT_DID_DFA_CSR        CVMX_FULL_DID(CVMX_OCT_DID_DFA, 7ULL)
+#define CVMX_OCT_DID_MIS_CSR        CVMX_FULL_DID(CVMX_OCT_DID_MIS, 7ULL)
+#define CVMX_OCT_DID_ZIP_CSR        CVMX_FULL_DID(CVMX_OCT_DID_ZIP, 0ULL)
+
+#endif /* __CVMX_ADDRESS_H__ */
diff --git a/drivers/staging/octeon/cvmx-asxx-defs.h b/drivers/staging/octeon/cvmx-asxx-defs.h
new file mode 100644
index 0000000..91415a8
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-asxx-defs.h
@@ -0,0 +1,475 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_ASXX_DEFS_H__
+#define __CVMX_ASXX_DEFS_H__
+
+#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
+#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
+#define CVMX_ASXX_INT_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_INT_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
+#define CVMX_ASXX_PRT_LOOP(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_BYPASS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_COMP(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RLD_SETTING(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_PRT_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_WOL(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_WOL_MSK(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_RX_WOL_SIG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_TX_COMP_BYP(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_TX_PRT_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_asxx_gmii_rx_clk_set {
+	uint64_t u64;
+	struct cvmx_asxx_gmii_rx_clk_set_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
+	struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
+	struct cvmx_asxx_gmii_rx_clk_set_s cn50xx;
+};
+
+union cvmx_asxx_gmii_rx_dat_set {
+	uint64_t u64;
+	struct cvmx_asxx_gmii_rx_dat_set_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
+	struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
+	struct cvmx_asxx_gmii_rx_dat_set_s cn50xx;
+};
+
+union cvmx_asxx_int_en {
+	uint64_t u64;
+	struct cvmx_asxx_int_en_s {
+		uint64_t reserved_12_63:52;
+		uint64_t txpsh:4;
+		uint64_t txpop:4;
+		uint64_t ovrflw:4;
+	} s;
+	struct cvmx_asxx_int_en_cn30xx {
+		uint64_t reserved_11_63:53;
+		uint64_t txpsh:3;
+		uint64_t reserved_7_7:1;
+		uint64_t txpop:3;
+		uint64_t reserved_3_3:1;
+		uint64_t ovrflw:3;
+	} cn30xx;
+	struct cvmx_asxx_int_en_cn30xx cn31xx;
+	struct cvmx_asxx_int_en_s cn38xx;
+	struct cvmx_asxx_int_en_s cn38xxp2;
+	struct cvmx_asxx_int_en_cn30xx cn50xx;
+	struct cvmx_asxx_int_en_s cn58xx;
+	struct cvmx_asxx_int_en_s cn58xxp1;
+};
+
+union cvmx_asxx_int_reg {
+	uint64_t u64;
+	struct cvmx_asxx_int_reg_s {
+		uint64_t reserved_12_63:52;
+		uint64_t txpsh:4;
+		uint64_t txpop:4;
+		uint64_t ovrflw:4;
+	} s;
+	struct cvmx_asxx_int_reg_cn30xx {
+		uint64_t reserved_11_63:53;
+		uint64_t txpsh:3;
+		uint64_t reserved_7_7:1;
+		uint64_t txpop:3;
+		uint64_t reserved_3_3:1;
+		uint64_t ovrflw:3;
+	} cn30xx;
+	struct cvmx_asxx_int_reg_cn30xx cn31xx;
+	struct cvmx_asxx_int_reg_s cn38xx;
+	struct cvmx_asxx_int_reg_s cn38xxp2;
+	struct cvmx_asxx_int_reg_cn30xx cn50xx;
+	struct cvmx_asxx_int_reg_s cn58xx;
+	struct cvmx_asxx_int_reg_s cn58xxp1;
+};
+
+union cvmx_asxx_mii_rx_dat_set {
+	uint64_t u64;
+	struct cvmx_asxx_mii_rx_dat_set_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
+	struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
+};
+
+union cvmx_asxx_prt_loop {
+	uint64_t u64;
+	struct cvmx_asxx_prt_loop_s {
+		uint64_t reserved_8_63:56;
+		uint64_t ext_loop:4;
+		uint64_t int_loop:4;
+	} s;
+	struct cvmx_asxx_prt_loop_cn30xx {
+		uint64_t reserved_7_63:57;
+		uint64_t ext_loop:3;
+		uint64_t reserved_3_3:1;
+		uint64_t int_loop:3;
+	} cn30xx;
+	struct cvmx_asxx_prt_loop_cn30xx cn31xx;
+	struct cvmx_asxx_prt_loop_s cn38xx;
+	struct cvmx_asxx_prt_loop_s cn38xxp2;
+	struct cvmx_asxx_prt_loop_cn30xx cn50xx;
+	struct cvmx_asxx_prt_loop_s cn58xx;
+	struct cvmx_asxx_prt_loop_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_bypass {
+	uint64_t u64;
+	struct cvmx_asxx_rld_bypass_s {
+		uint64_t reserved_1_63:63;
+		uint64_t bypass:1;
+	} s;
+	struct cvmx_asxx_rld_bypass_s cn38xx;
+	struct cvmx_asxx_rld_bypass_s cn38xxp2;
+	struct cvmx_asxx_rld_bypass_s cn58xx;
+	struct cvmx_asxx_rld_bypass_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_bypass_setting {
+	uint64_t u64;
+	struct cvmx_asxx_rld_bypass_setting_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_rld_bypass_setting_s cn38xx;
+	struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
+	struct cvmx_asxx_rld_bypass_setting_s cn58xx;
+	struct cvmx_asxx_rld_bypass_setting_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_comp {
+	uint64_t u64;
+	struct cvmx_asxx_rld_comp_s {
+		uint64_t reserved_9_63:55;
+		uint64_t pctl:5;
+		uint64_t nctl:4;
+	} s;
+	struct cvmx_asxx_rld_comp_cn38xx {
+		uint64_t reserved_8_63:56;
+		uint64_t pctl:4;
+		uint64_t nctl:4;
+	} cn38xx;
+	struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
+	struct cvmx_asxx_rld_comp_s cn58xx;
+	struct cvmx_asxx_rld_comp_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_data_drv {
+	uint64_t u64;
+	struct cvmx_asxx_rld_data_drv_s {
+		uint64_t reserved_8_63:56;
+		uint64_t pctl:4;
+		uint64_t nctl:4;
+	} s;
+	struct cvmx_asxx_rld_data_drv_s cn38xx;
+	struct cvmx_asxx_rld_data_drv_s cn38xxp2;
+	struct cvmx_asxx_rld_data_drv_s cn58xx;
+	struct cvmx_asxx_rld_data_drv_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_fcram_mode {
+	uint64_t u64;
+	struct cvmx_asxx_rld_fcram_mode_s {
+		uint64_t reserved_1_63:63;
+		uint64_t mode:1;
+	} s;
+	struct cvmx_asxx_rld_fcram_mode_s cn38xx;
+	struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
+};
+
+union cvmx_asxx_rld_nctl_strong {
+	uint64_t u64;
+	struct cvmx_asxx_rld_nctl_strong_s {
+		uint64_t reserved_5_63:59;
+		uint64_t nctl:5;
+	} s;
+	struct cvmx_asxx_rld_nctl_strong_s cn38xx;
+	struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
+	struct cvmx_asxx_rld_nctl_strong_s cn58xx;
+	struct cvmx_asxx_rld_nctl_strong_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_nctl_weak {
+	uint64_t u64;
+	struct cvmx_asxx_rld_nctl_weak_s {
+		uint64_t reserved_5_63:59;
+		uint64_t nctl:5;
+	} s;
+	struct cvmx_asxx_rld_nctl_weak_s cn38xx;
+	struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
+	struct cvmx_asxx_rld_nctl_weak_s cn58xx;
+	struct cvmx_asxx_rld_nctl_weak_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_pctl_strong {
+	uint64_t u64;
+	struct cvmx_asxx_rld_pctl_strong_s {
+		uint64_t reserved_5_63:59;
+		uint64_t pctl:5;
+	} s;
+	struct cvmx_asxx_rld_pctl_strong_s cn38xx;
+	struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
+	struct cvmx_asxx_rld_pctl_strong_s cn58xx;
+	struct cvmx_asxx_rld_pctl_strong_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_pctl_weak {
+	uint64_t u64;
+	struct cvmx_asxx_rld_pctl_weak_s {
+		uint64_t reserved_5_63:59;
+		uint64_t pctl:5;
+	} s;
+	struct cvmx_asxx_rld_pctl_weak_s cn38xx;
+	struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
+	struct cvmx_asxx_rld_pctl_weak_s cn58xx;
+	struct cvmx_asxx_rld_pctl_weak_s cn58xxp1;
+};
+
+union cvmx_asxx_rld_setting {
+	uint64_t u64;
+	struct cvmx_asxx_rld_setting_s {
+		uint64_t reserved_13_63:51;
+		uint64_t dfaset:5;
+		uint64_t dfalag:1;
+		uint64_t dfalead:1;
+		uint64_t dfalock:1;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_rld_setting_cn38xx {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} cn38xx;
+	struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
+	struct cvmx_asxx_rld_setting_s cn58xx;
+	struct cvmx_asxx_rld_setting_s cn58xxp1;
+};
+
+union cvmx_asxx_rx_clk_setx {
+	uint64_t u64;
+	struct cvmx_asxx_rx_clk_setx_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_rx_clk_setx_s cn30xx;
+	struct cvmx_asxx_rx_clk_setx_s cn31xx;
+	struct cvmx_asxx_rx_clk_setx_s cn38xx;
+	struct cvmx_asxx_rx_clk_setx_s cn38xxp2;
+	struct cvmx_asxx_rx_clk_setx_s cn50xx;
+	struct cvmx_asxx_rx_clk_setx_s cn58xx;
+	struct cvmx_asxx_rx_clk_setx_s cn58xxp1;
+};
+
+union cvmx_asxx_rx_prt_en {
+	uint64_t u64;
+	struct cvmx_asxx_rx_prt_en_s {
+		uint64_t reserved_4_63:60;
+		uint64_t prt_en:4;
+	} s;
+	struct cvmx_asxx_rx_prt_en_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t prt_en:3;
+	} cn30xx;
+	struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
+	struct cvmx_asxx_rx_prt_en_s cn38xx;
+	struct cvmx_asxx_rx_prt_en_s cn38xxp2;
+	struct cvmx_asxx_rx_prt_en_cn30xx cn50xx;
+	struct cvmx_asxx_rx_prt_en_s cn58xx;
+	struct cvmx_asxx_rx_prt_en_s cn58xxp1;
+};
+
+union cvmx_asxx_rx_wol {
+	uint64_t u64;
+	struct cvmx_asxx_rx_wol_s {
+		uint64_t reserved_2_63:62;
+		uint64_t status:1;
+		uint64_t enable:1;
+	} s;
+	struct cvmx_asxx_rx_wol_s cn38xx;
+	struct cvmx_asxx_rx_wol_s cn38xxp2;
+};
+
+union cvmx_asxx_rx_wol_msk {
+	uint64_t u64;
+	struct cvmx_asxx_rx_wol_msk_s {
+		uint64_t msk:64;
+	} s;
+	struct cvmx_asxx_rx_wol_msk_s cn38xx;
+	struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
+};
+
+union cvmx_asxx_rx_wol_powok {
+	uint64_t u64;
+	struct cvmx_asxx_rx_wol_powok_s {
+		uint64_t reserved_1_63:63;
+		uint64_t powerok:1;
+	} s;
+	struct cvmx_asxx_rx_wol_powok_s cn38xx;
+	struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
+};
+
+union cvmx_asxx_rx_wol_sig {
+	uint64_t u64;
+	struct cvmx_asxx_rx_wol_sig_s {
+		uint64_t reserved_32_63:32;
+		uint64_t sig:32;
+	} s;
+	struct cvmx_asxx_rx_wol_sig_s cn38xx;
+	struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
+};
+
+union cvmx_asxx_tx_clk_setx {
+	uint64_t u64;
+	struct cvmx_asxx_tx_clk_setx_s {
+		uint64_t reserved_5_63:59;
+		uint64_t setting:5;
+	} s;
+	struct cvmx_asxx_tx_clk_setx_s cn30xx;
+	struct cvmx_asxx_tx_clk_setx_s cn31xx;
+	struct cvmx_asxx_tx_clk_setx_s cn38xx;
+	struct cvmx_asxx_tx_clk_setx_s cn38xxp2;
+	struct cvmx_asxx_tx_clk_setx_s cn50xx;
+	struct cvmx_asxx_tx_clk_setx_s cn58xx;
+	struct cvmx_asxx_tx_clk_setx_s cn58xxp1;
+};
+
+union cvmx_asxx_tx_comp_byp {
+	uint64_t u64;
+	struct cvmx_asxx_tx_comp_byp_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_asxx_tx_comp_byp_cn30xx {
+		uint64_t reserved_9_63:55;
+		uint64_t bypass:1;
+		uint64_t pctl:4;
+		uint64_t nctl:4;
+	} cn30xx;
+	struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
+	struct cvmx_asxx_tx_comp_byp_cn38xx {
+		uint64_t reserved_8_63:56;
+		uint64_t pctl:4;
+		uint64_t nctl:4;
+	} cn38xx;
+	struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
+	struct cvmx_asxx_tx_comp_byp_cn50xx {
+		uint64_t reserved_17_63:47;
+		uint64_t bypass:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t nctl:5;
+	} cn50xx;
+	struct cvmx_asxx_tx_comp_byp_cn58xx {
+		uint64_t reserved_13_63:51;
+		uint64_t pctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t nctl:5;
+	} cn58xx;
+	struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
+};
+
+union cvmx_asxx_tx_hi_waterx {
+	uint64_t u64;
+	struct cvmx_asxx_tx_hi_waterx_s {
+		uint64_t reserved_4_63:60;
+		uint64_t mark:4;
+	} s;
+	struct cvmx_asxx_tx_hi_waterx_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t mark:3;
+	} cn30xx;
+	struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
+	struct cvmx_asxx_tx_hi_waterx_s cn38xx;
+	struct cvmx_asxx_tx_hi_waterx_s cn38xxp2;
+	struct cvmx_asxx_tx_hi_waterx_cn30xx cn50xx;
+	struct cvmx_asxx_tx_hi_waterx_s cn58xx;
+	struct cvmx_asxx_tx_hi_waterx_s cn58xxp1;
+};
+
+union cvmx_asxx_tx_prt_en {
+	uint64_t u64;
+	struct cvmx_asxx_tx_prt_en_s {
+		uint64_t reserved_4_63:60;
+		uint64_t prt_en:4;
+	} s;
+	struct cvmx_asxx_tx_prt_en_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t prt_en:3;
+	} cn30xx;
+	struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
+	struct cvmx_asxx_tx_prt_en_s cn38xx;
+	struct cvmx_asxx_tx_prt_en_s cn38xxp2;
+	struct cvmx_asxx_tx_prt_en_cn30xx cn50xx;
+	struct cvmx_asxx_tx_prt_en_s cn58xx;
+	struct cvmx_asxx_tx_prt_en_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-cmd-queue.c b/drivers/staging/octeon/cvmx-cmd-queue.c
new file mode 100644
index 0000000..976227b
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-cmd-queue.c
@@ -0,0 +1,306 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Support functions for managing command queues used for
+ * various hardware blocks.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+#include "cvmx-fpa.h"
+#include "cvmx-cmd-queue.h"
+
+#include <asm/octeon/cvmx-npei-defs.h>
+#include <asm/octeon/cvmx-pexp-defs.h>
+#include "cvmx-pko-defs.h"
+
+/**
+ * This application uses this pointer to access the global queue
+ * state. It points to a bootmem named block.
+ */
+__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
+
+/**
+ * Initialize the Global queue state pointer.
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+static cvmx_cmd_queue_result_t __cvmx_cmd_queue_init_state_ptr(void)
+{
+	char *alloc_name = "cvmx_cmd_queues";
+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
+	extern uint64_t octeon_reserve32_memory;
+#endif
+
+	if (likely(__cvmx_cmd_queue_state_ptr))
+		return CVMX_CMD_QUEUE_SUCCESS;
+
+#if defined(CONFIG_CAVIUM_RESERVE32) && CONFIG_CAVIUM_RESERVE32
+	if (octeon_reserve32_memory)
+		__cvmx_cmd_queue_state_ptr =
+		    cvmx_bootmem_alloc_named_range(sizeof(*__cvmx_cmd_queue_state_ptr),
+						   octeon_reserve32_memory,
+						   octeon_reserve32_memory +
+						   (CONFIG_CAVIUM_RESERVE32 <<
+						    20) - 1, 128, alloc_name);
+	else
+#endif
+		__cvmx_cmd_queue_state_ptr =
+		    cvmx_bootmem_alloc_named(sizeof(*__cvmx_cmd_queue_state_ptr),
+					    128,
+					    alloc_name);
+	if (__cvmx_cmd_queue_state_ptr)
+		memset(__cvmx_cmd_queue_state_ptr, 0,
+		       sizeof(*__cvmx_cmd_queue_state_ptr));
+	else {
+		struct cvmx_bootmem_named_block_desc *block_desc =
+		    cvmx_bootmem_find_named_block(alloc_name);
+		if (block_desc)
+			__cvmx_cmd_queue_state_ptr =
+			    cvmx_phys_to_ptr(block_desc->base_addr);
+		else {
+			cvmx_dprintf
+			    ("ERROR: cvmx_cmd_queue_initialize: Unable to get named block %s.\n",
+			     alloc_name);
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+	}
+	return CVMX_CMD_QUEUE_SUCCESS;
+}
+
+/**
+ * Initialize a command queue for use. The initial FPA buffer is
+ * allocated and the hardware unit is configured to point to the
+ * new command queue.
+ *
+ * @queue_id:  Hardware command queue to initialize.
+ * @max_depth: Maximum outstanding commands that can be queued.
+ * @fpa_pool:  FPA pool the command queues should come from.
+ * @pool_size: Size of each buffer in the FPA pool (bytes)
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
+						  int max_depth, int fpa_pool,
+						  int pool_size)
+{
+	__cvmx_cmd_queue_state_t *qstate;
+	cvmx_cmd_queue_result_t result = __cvmx_cmd_queue_init_state_ptr();
+	if (result != CVMX_CMD_QUEUE_SUCCESS)
+		return result;
+
+	qstate = __cvmx_cmd_queue_get_state(queue_id);
+	if (qstate == NULL)
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+
+	/*
+	 * We artificially limit max_depth to 1<<20 words. It is an
+	 * arbitrary limit.
+	 */
+	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH) {
+		if ((max_depth < 0) || (max_depth > 1 << 20))
+			return CVMX_CMD_QUEUE_INVALID_PARAM;
+	} else if (max_depth != 0)
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+
+	if ((fpa_pool < 0) || (fpa_pool > 7))
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+	if ((pool_size < 128) || (pool_size > 65536))
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+
+	/* See if someone else has already initialized the queue */
+	if (qstate->base_ptr_div128) {
+		if (max_depth != (int)qstate->max_depth) {
+			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
+				"Queue already initalized with different "
+				"max_depth (%d).\n",
+			     (int)qstate->max_depth);
+			return CVMX_CMD_QUEUE_INVALID_PARAM;
+		}
+		if (fpa_pool != qstate->fpa_pool) {
+			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
+				"Queue already initalized with different "
+				"FPA pool (%u).\n",
+			     qstate->fpa_pool);
+			return CVMX_CMD_QUEUE_INVALID_PARAM;
+		}
+		if ((pool_size >> 3) - 1 != qstate->pool_size_m1) {
+			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
+				"Queue already initalized with different "
+				"FPA pool size (%u).\n",
+			     (qstate->pool_size_m1 + 1) << 3);
+			return CVMX_CMD_QUEUE_INVALID_PARAM;
+		}
+		CVMX_SYNCWS;
+		return CVMX_CMD_QUEUE_ALREADY_SETUP;
+	} else {
+		union cvmx_fpa_ctl_status status;
+		void *buffer;
+
+		status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
+		if (!status.s.enb) {
+			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
+				     "FPA is not enabled.\n");
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+		buffer = cvmx_fpa_alloc(fpa_pool);
+		if (buffer == NULL) {
+			cvmx_dprintf("ERROR: cvmx_cmd_queue_initialize: "
+				     "Unable to allocate initial buffer.\n");
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+
+		memset(qstate, 0, sizeof(*qstate));
+		qstate->max_depth = max_depth;
+		qstate->fpa_pool = fpa_pool;
+		qstate->pool_size_m1 = (pool_size >> 3) - 1;
+		qstate->base_ptr_div128 = cvmx_ptr_to_phys(buffer) / 128;
+		/*
+		 * We zeroed the now serving field so we need to also
+		 * zero the ticket.
+		 */
+		__cvmx_cmd_queue_state_ptr->
+		    ticket[__cvmx_cmd_queue_get_index(queue_id)] = 0;
+		CVMX_SYNCWS;
+		return CVMX_CMD_QUEUE_SUCCESS;
+	}
+}
+
+/**
+ * Shutdown a queue a free it's command buffers to the FPA. The
+ * hardware connected to the queue must be stopped before this
+ * function is called.
+ *
+ * @queue_id: Queue to shutdown
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id)
+{
+	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
+	if (qptr == NULL) {
+		cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Unable to "
+			     "get queue information.\n");
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+	}
+
+	if (cvmx_cmd_queue_length(queue_id) > 0) {
+		cvmx_dprintf("ERROR: cvmx_cmd_queue_shutdown: Queue still "
+			     "has data in it.\n");
+		return CVMX_CMD_QUEUE_FULL;
+	}
+
+	__cvmx_cmd_queue_lock(queue_id, qptr);
+	if (qptr->base_ptr_div128) {
+		cvmx_fpa_free(cvmx_phys_to_ptr
+			      ((uint64_t) qptr->base_ptr_div128 << 7),
+			      qptr->fpa_pool, 0);
+		qptr->base_ptr_div128 = 0;
+	}
+	__cvmx_cmd_queue_unlock(qptr);
+
+	return CVMX_CMD_QUEUE_SUCCESS;
+}
+
+/**
+ * Return the number of command words pending in the queue. This
+ * function may be relatively slow for some hardware units.
+ *
+ * @queue_id: Hardware command queue to query
+ *
+ * Returns Number of outstanding commands
+ */
+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id)
+{
+	if (CVMX_ENABLE_PARAMETER_CHECKING) {
+		if (__cvmx_cmd_queue_get_state(queue_id) == NULL)
+			return CVMX_CMD_QUEUE_INVALID_PARAM;
+	}
+
+	/*
+	 * The cast is here so gcc with check that all values in the
+	 * cvmx_cmd_queue_id_t enumeration are here.
+	 */
+	switch ((cvmx_cmd_queue_id_t) (queue_id & 0xff0000)) {
+	case CVMX_CMD_QUEUE_PKO_BASE:
+		/*
+		 * FIXME: Need atomic lock on
+		 * CVMX_PKO_REG_READ_IDX. Right now we are normally
+		 * called with the queue lock, so that is a SLIGHT
+		 * amount of protection.
+		 */
+		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue_id & 0xffff);
+		if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+			union cvmx_pko_mem_debug9 debug9;
+			debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
+			return debug9.cn38xx.doorbell;
+		} else {
+			union cvmx_pko_mem_debug8 debug8;
+			debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
+			return debug8.cn58xx.doorbell;
+		}
+	case CVMX_CMD_QUEUE_ZIP:
+	case CVMX_CMD_QUEUE_DFA:
+	case CVMX_CMD_QUEUE_RAID:
+		/* FIXME: Implement other lengths */
+		return 0;
+	case CVMX_CMD_QUEUE_DMA_BASE:
+		{
+			union cvmx_npei_dmax_counts dmax_counts;
+			dmax_counts.u64 =
+			    cvmx_read_csr(CVMX_PEXP_NPEI_DMAX_COUNTS
+					  (queue_id & 0x7));
+			return dmax_counts.s.dbell;
+		}
+	case CVMX_CMD_QUEUE_END:
+		return CVMX_CMD_QUEUE_INVALID_PARAM;
+	}
+	return CVMX_CMD_QUEUE_INVALID_PARAM;
+}
+
+/**
+ * Return the command buffer to be written to. The purpose of this
+ * function is to allow CVMX routine access t othe low level buffer
+ * for initial hardware setup. User applications should not call this
+ * function directly.
+ *
+ * @queue_id: Command queue to query
+ *
+ * Returns Command buffer or NULL on failure
+ */
+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id)
+{
+	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
+	if (qptr && qptr->base_ptr_div128)
+		return cvmx_phys_to_ptr((uint64_t) qptr->base_ptr_div128 << 7);
+	else
+		return NULL;
+}
diff --git a/drivers/staging/octeon/cvmx-cmd-queue.h b/drivers/staging/octeon/cvmx-cmd-queue.h
new file mode 100644
index 0000000..f0cb20f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-cmd-queue.h
@@ -0,0 +1,617 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Support functions for managing command queues used for
+ * various hardware blocks.
+ *
+ * The common command queue infrastructure abstracts out the
+ * software necessary for adding to Octeon's chained queue
+ * structures. These structures are used for commands to the
+ * PKO, ZIP, DFA, RAID, and DMA engine blocks. Although each
+ * hardware unit takes commands and CSRs of different types,
+ * they all use basic linked command buffers to store the
+ * pending request. In general, users of the CVMX API don't
+ * call cvmx-cmd-queue functions directly. Instead the hardware
+ * unit specific wrapper should be used. The wrappers perform
+ * unit specific validation and CSR writes to submit the
+ * commands.
+ *
+ * Even though most software will never directly interact with
+ * cvmx-cmd-queue, knowledge of its internal working can help
+ * in diagnosing performance problems and help with debugging.
+ *
+ * Command queue pointers are stored in a global named block
+ * called "cvmx_cmd_queues". Except for the PKO queues, each
+ * hardware queue is stored in its own cache line to reduce SMP
+ * contention on spin locks. The PKO queues are stored such that
+ * every 16th queue is next to each other in memory. This scheme
+ * allows for queues being in separate cache lines when there
+ * are low number of queues per port. With 16 queues per port,
+ * the first queue for each port is in the same cache area. The
+ * second queues for each port are in another area, etc. This
+ * allows software to implement very efficient lockless PKO with
+ * 16 queues per port using a minimum of cache lines per core.
+ * All queues for a given core will be isolated in the same
+ * cache area.
+ *
+ * In addition to the memory pointer layout, cvmx-cmd-queue
+ * provides an optimized fair ll/sc locking mechanism for the
+ * queues. The lock uses a "ticket / now serving" model to
+ * maintain fair order on contended locks. In addition, it uses
+ * predicted locking time to limit cache contention. When a core
+ * know it must wait in line for a lock, it spins on the
+ * internal cycle counter to completely eliminate any causes of
+ * bus traffic.
+ *
+ */
+
+#ifndef __CVMX_CMD_QUEUE_H__
+#define __CVMX_CMD_QUEUE_H__
+
+#include <linux/prefetch.h>
+
+#include "cvmx-fpa.h"
+/**
+ * By default we disable the max depth support. Most programs
+ * don't use it and it slows down the command queue processing
+ * significantly.
+ */
+#ifndef CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH
+#define CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH 0
+#endif
+
+/**
+ * Enumeration representing all hardware blocks that use command
+ * queues. Each hardware block has up to 65536 sub identifiers for
+ * multiple command queues. Not all chips support all hardware
+ * units.
+ */
+typedef enum {
+	CVMX_CMD_QUEUE_PKO_BASE = 0x00000,
+
+#define CVMX_CMD_QUEUE_PKO(queue) \
+	((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_PKO_BASE + (0xffff&(queue))))
+
+	CVMX_CMD_QUEUE_ZIP = 0x10000,
+	CVMX_CMD_QUEUE_DFA = 0x20000,
+	CVMX_CMD_QUEUE_RAID = 0x30000,
+	CVMX_CMD_QUEUE_DMA_BASE = 0x40000,
+
+#define CVMX_CMD_QUEUE_DMA(queue) \
+	((cvmx_cmd_queue_id_t)(CVMX_CMD_QUEUE_DMA_BASE + (0xffff&(queue))))
+
+	CVMX_CMD_QUEUE_END = 0x50000,
+} cvmx_cmd_queue_id_t;
+
+/**
+ * Command write operations can fail if the comamnd queue needs
+ * a new buffer and the associated FPA pool is empty. It can also
+ * fail if the number of queued command words reaches the maximum
+ * set at initialization.
+ */
+typedef enum {
+	CVMX_CMD_QUEUE_SUCCESS = 0,
+	CVMX_CMD_QUEUE_NO_MEMORY = -1,
+	CVMX_CMD_QUEUE_FULL = -2,
+	CVMX_CMD_QUEUE_INVALID_PARAM = -3,
+	CVMX_CMD_QUEUE_ALREADY_SETUP = -4,
+} cvmx_cmd_queue_result_t;
+
+typedef struct {
+	/* You have lock when this is your ticket */
+	uint8_t now_serving;
+	uint64_t unused1:24;
+	/* Maximum outstanding command words */
+	uint32_t max_depth;
+	/* FPA pool buffers come from */
+	uint64_t fpa_pool:3;
+	/* Top of command buffer pointer shifted 7 */
+	uint64_t base_ptr_div128:29;
+	uint64_t unused2:6;
+	/* FPA buffer size in 64bit words minus 1 */
+	uint64_t pool_size_m1:13;
+	/* Number of comamnds already used in buffer */
+	uint64_t index:13;
+} __cvmx_cmd_queue_state_t;
+
+/**
+ * This structure contains the global state of all comamnd queues.
+ * It is stored in a bootmem named block and shared by all
+ * applications running on Octeon. Tickets are stored in a differnet
+ * cahce line that queue information to reduce the contention on the
+ * ll/sc used to get a ticket. If this is not the case, the update
+ * of queue state causes the ll/sc to fail quite often.
+ */
+typedef struct {
+	uint64_t ticket[(CVMX_CMD_QUEUE_END >> 16) * 256];
+	__cvmx_cmd_queue_state_t state[(CVMX_CMD_QUEUE_END >> 16) * 256];
+} __cvmx_cmd_queue_all_state_t;
+
+/**
+ * Initialize a command queue for use. The initial FPA buffer is
+ * allocated and the hardware unit is configured to point to the
+ * new command queue.
+ *
+ * @queue_id:  Hardware command queue to initialize.
+ * @max_depth: Maximum outstanding commands that can be queued.
+ * @fpa_pool:  FPA pool the command queues should come from.
+ * @pool_size: Size of each buffer in the FPA pool (bytes)
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+cvmx_cmd_queue_result_t cvmx_cmd_queue_initialize(cvmx_cmd_queue_id_t queue_id,
+						  int max_depth, int fpa_pool,
+						  int pool_size);
+
+/**
+ * Shutdown a queue a free it's command buffers to the FPA. The
+ * hardware connected to the queue must be stopped before this
+ * function is called.
+ *
+ * @queue_id: Queue to shutdown
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+cvmx_cmd_queue_result_t cvmx_cmd_queue_shutdown(cvmx_cmd_queue_id_t queue_id);
+
+/**
+ * Return the number of command words pending in the queue. This
+ * function may be relatively slow for some hardware units.
+ *
+ * @queue_id: Hardware command queue to query
+ *
+ * Returns Number of outstanding commands
+ */
+int cvmx_cmd_queue_length(cvmx_cmd_queue_id_t queue_id);
+
+/**
+ * Return the command buffer to be written to. The purpose of this
+ * function is to allow CVMX routine access t othe low level buffer
+ * for initial hardware setup. User applications should not call this
+ * function directly.
+ *
+ * @queue_id: Command queue to query
+ *
+ * Returns Command buffer or NULL on failure
+ */
+void *cvmx_cmd_queue_buffer(cvmx_cmd_queue_id_t queue_id);
+
+/**
+ * Get the index into the state arrays for the supplied queue id.
+ *
+ * @queue_id: Queue ID to get an index for
+ *
+ * Returns Index into the state arrays
+ */
+static inline int __cvmx_cmd_queue_get_index(cvmx_cmd_queue_id_t queue_id)
+{
+	/*
+	 * Warning: This code currently only works with devices that
+	 * have 256 queues or less. Devices with more than 16 queues
+	 * are layed out in memory to allow cores quick access to
+	 * every 16th queue. This reduces cache thrashing when you are
+	 * running 16 queues per port to support lockless operation.
+	 */
+	int unit = queue_id >> 16;
+	int q = (queue_id >> 4) & 0xf;
+	int core = queue_id & 0xf;
+	return unit * 256 + core * 16 + q;
+}
+
+/**
+ * Lock the supplied queue so nobody else is updating it at the same
+ * time as us.
+ *
+ * @queue_id: Queue ID to lock
+ * @qptr:     Pointer to the queue's global state
+ */
+static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id,
+					 __cvmx_cmd_queue_state_t *qptr)
+{
+	extern __cvmx_cmd_queue_all_state_t
+	    *__cvmx_cmd_queue_state_ptr;
+	int tmp;
+	int my_ticket;
+	prefetch(qptr);
+	asm volatile (
+		".set push\n"
+		".set noreorder\n"
+		"1:\n"
+		/* Atomic add one to ticket_ptr */
+		"ll     %[my_ticket], %[ticket_ptr]\n"
+		/* and store the original value */
+		"li     %[ticket], 1\n"
+		/* in my_ticket */
+		"baddu  %[ticket], %[my_ticket]\n"
+		"sc     %[ticket], %[ticket_ptr]\n"
+		"beqz   %[ticket], 1b\n"
+		" nop\n"
+		/* Load the current now_serving ticket */
+		"lbu    %[ticket], %[now_serving]\n"
+		"2:\n"
+		/* Jump out if now_serving == my_ticket */
+		"beq    %[ticket], %[my_ticket], 4f\n"
+		/* Find out how many tickets are in front of me */
+		" subu   %[ticket], %[my_ticket], %[ticket]\n"
+		/* Use tickets in front of me minus one to delay */
+		"subu  %[ticket], 1\n"
+		/* Delay will be ((tickets in front)-1)*32 loops */
+		"cins   %[ticket], %[ticket], 5, 7\n"
+		"3:\n"
+		/* Loop here until our ticket might be up */
+		"bnez   %[ticket], 3b\n"
+		" subu  %[ticket], 1\n"
+		/* Jump back up to check out ticket again */
+		"b      2b\n"
+		/* Load the current now_serving ticket */
+		" lbu   %[ticket], %[now_serving]\n"
+		"4:\n"
+		".set pop\n" :
+		[ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]),
+		[now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp),
+		[my_ticket] "=r"(my_ticket)
+	    );
+}
+
+/**
+ * Unlock the queue, flushing all writes.
+ *
+ * @qptr:   Queue to unlock
+ */
+static inline void __cvmx_cmd_queue_unlock(__cvmx_cmd_queue_state_t *qptr)
+{
+	qptr->now_serving++;
+	CVMX_SYNCWS;
+}
+
+/**
+ * Get the queue state structure for the given queue id
+ *
+ * @queue_id: Queue id to get
+ *
+ * Returns Queue structure or NULL on failure
+ */
+static inline __cvmx_cmd_queue_state_t
+    *__cvmx_cmd_queue_get_state(cvmx_cmd_queue_id_t queue_id)
+{
+	extern __cvmx_cmd_queue_all_state_t
+	    *__cvmx_cmd_queue_state_ptr;
+	return &__cvmx_cmd_queue_state_ptr->
+	    state[__cvmx_cmd_queue_get_index(queue_id)];
+}
+
+/**
+ * Write an arbitrary number of command words to a command queue.
+ * This is a generic function; the fixed number of comamnd word
+ * functions yield higher performance.
+ *
+ * @queue_id:  Hardware command queue to write to
+ * @use_locking:
+ *                  Use internal locking to ensure exclusive access for queue
+ *                  updates. If you don't use this locking you must ensure
+ *                  exclusivity some other way. Locking is strongly recommended.
+ * @cmd_count: Number of command words to write
+ * @cmds:      Array of comamnds to write
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write(cvmx_cmd_queue_id_t
+							   queue_id,
+							   int use_locking,
+							   int cmd_count,
+							   uint64_t *cmds)
+{
+	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
+
+	/* Make sure nobody else is updating the same queue */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_lock(queue_id, qptr);
+
+	/*
+	 * If a max queue length was specified then make sure we don't
+	 * exceed it. If any part of the command would be below the
+	 * limit we allow it.
+	 */
+	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
+		if (unlikely
+		    (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_FULL;
+		}
+	}
+
+	/*
+	 * Normally there is plenty of room in the current buffer for
+	 * the command.
+	 */
+	if (likely(qptr->index + cmd_count < qptr->pool_size_m1)) {
+		uint64_t *ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		ptr += qptr->index;
+		qptr->index += cmd_count;
+		while (cmd_count--)
+			*ptr++ = *cmds++;
+	} else {
+		uint64_t *ptr;
+		int count;
+		/*
+		 * We need a new comamnd buffer. Fail if there isn't
+		 * one available.
+		 */
+		uint64_t *new_buffer =
+		    (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
+		if (unlikely(new_buffer == NULL)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+		ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		/*
+		 * Figure out how many command words will fit in this
+		 * buffer. One location will be needed for the next
+		 * buffer pointer.
+		 */
+		count = qptr->pool_size_m1 - qptr->index;
+		ptr += qptr->index;
+		cmd_count -= count;
+		while (count--)
+			*ptr++ = *cmds++;
+		*ptr = cvmx_ptr_to_phys(new_buffer);
+		/*
+		 * The current buffer is full and has a link to the
+		 * next buffer. Time to write the rest of the commands
+		 * into the new buffer.
+		 */
+		qptr->base_ptr_div128 = *ptr >> 7;
+		qptr->index = cmd_count;
+		ptr = new_buffer;
+		while (cmd_count--)
+			*ptr++ = *cmds++;
+	}
+
+	/* All updates are complete. Release the lock and return */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_unlock(qptr);
+	return CVMX_CMD_QUEUE_SUCCESS;
+}
+
+/**
+ * Simple function to write two command words to a command
+ * queue.
+ *
+ * @queue_id: Hardware command queue to write to
+ * @use_locking:
+ *                 Use internal locking to ensure exclusive access for queue
+ *                 updates. If you don't use this locking you must ensure
+ *                 exclusivity some other way. Locking is strongly recommended.
+ * @cmd1:     Command
+ * @cmd2:     Command
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write2(cvmx_cmd_queue_id_t
+							    queue_id,
+							    int use_locking,
+							    uint64_t cmd1,
+							    uint64_t cmd2)
+{
+	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
+
+	/* Make sure nobody else is updating the same queue */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_lock(queue_id, qptr);
+
+	/*
+	 * If a max queue length was specified then make sure we don't
+	 * exceed it. If any part of the command would be below the
+	 * limit we allow it.
+	 */
+	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
+		if (unlikely
+		    (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_FULL;
+		}
+	}
+
+	/*
+	 * Normally there is plenty of room in the current buffer for
+	 * the command.
+	 */
+	if (likely(qptr->index + 2 < qptr->pool_size_m1)) {
+		uint64_t *ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		ptr += qptr->index;
+		qptr->index += 2;
+		ptr[0] = cmd1;
+		ptr[1] = cmd2;
+	} else {
+		uint64_t *ptr;
+		/*
+		 * Figure out how many command words will fit in this
+		 * buffer. One location will be needed for the next
+		 * buffer pointer.
+		 */
+		int count = qptr->pool_size_m1 - qptr->index;
+		/*
+		 * We need a new comamnd buffer. Fail if there isn't
+		 * one available.
+		 */
+		uint64_t *new_buffer =
+		    (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
+		if (unlikely(new_buffer == NULL)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+		count--;
+		ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		ptr += qptr->index;
+		*ptr++ = cmd1;
+		if (likely(count))
+			*ptr++ = cmd2;
+		*ptr = cvmx_ptr_to_phys(new_buffer);
+		/*
+		 * The current buffer is full and has a link to the
+		 * next buffer. Time to write the rest of the commands
+		 * into the new buffer.
+		 */
+		qptr->base_ptr_div128 = *ptr >> 7;
+		qptr->index = 0;
+		if (unlikely(count == 0)) {
+			qptr->index = 1;
+			new_buffer[0] = cmd2;
+		}
+	}
+
+	/* All updates are complete. Release the lock and return */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_unlock(qptr);
+	return CVMX_CMD_QUEUE_SUCCESS;
+}
+
+/**
+ * Simple function to write three command words to a command
+ * queue.
+ *
+ * @queue_id: Hardware command queue to write to
+ * @use_locking:
+ *                 Use internal locking to ensure exclusive access for queue
+ *                 updates. If you don't use this locking you must ensure
+ *                 exclusivity some other way. Locking is strongly recommended.
+ * @cmd1:     Command
+ * @cmd2:     Command
+ * @cmd3:     Command
+ *
+ * Returns CVMX_CMD_QUEUE_SUCCESS or a failure code
+ */
+static inline cvmx_cmd_queue_result_t cvmx_cmd_queue_write3(cvmx_cmd_queue_id_t
+							    queue_id,
+							    int use_locking,
+							    uint64_t cmd1,
+							    uint64_t cmd2,
+							    uint64_t cmd3)
+{
+	__cvmx_cmd_queue_state_t *qptr = __cvmx_cmd_queue_get_state(queue_id);
+
+	/* Make sure nobody else is updating the same queue */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_lock(queue_id, qptr);
+
+	/*
+	 * If a max queue length was specified then make sure we don't
+	 * exceed it. If any part of the command would be below the
+	 * limit we allow it.
+	 */
+	if (CVMX_CMD_QUEUE_ENABLE_MAX_DEPTH && unlikely(qptr->max_depth)) {
+		if (unlikely
+		    (cvmx_cmd_queue_length(queue_id) > (int)qptr->max_depth)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_FULL;
+		}
+	}
+
+	/*
+	 * Normally there is plenty of room in the current buffer for
+	 * the command.
+	 */
+	if (likely(qptr->index + 3 < qptr->pool_size_m1)) {
+		uint64_t *ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		ptr += qptr->index;
+		qptr->index += 3;
+		ptr[0] = cmd1;
+		ptr[1] = cmd2;
+		ptr[2] = cmd3;
+	} else {
+		uint64_t *ptr;
+		/*
+		 * Figure out how many command words will fit in this
+		 * buffer. One location will be needed for the next
+		 * buffer pointer
+		 */
+		int count = qptr->pool_size_m1 - qptr->index;
+		/*
+		 * We need a new comamnd buffer. Fail if there isn't
+		 * one available
+		 */
+		uint64_t *new_buffer =
+		    (uint64_t *) cvmx_fpa_alloc(qptr->fpa_pool);
+		if (unlikely(new_buffer == NULL)) {
+			if (likely(use_locking))
+				__cvmx_cmd_queue_unlock(qptr);
+			return CVMX_CMD_QUEUE_NO_MEMORY;
+		}
+		count--;
+		ptr =
+		    (uint64_t *) cvmx_phys_to_ptr((uint64_t) qptr->
+						  base_ptr_div128 << 7);
+		ptr += qptr->index;
+		*ptr++ = cmd1;
+		if (count) {
+			*ptr++ = cmd2;
+			if (count > 1)
+				*ptr++ = cmd3;
+		}
+		*ptr = cvmx_ptr_to_phys(new_buffer);
+		/*
+		 * The current buffer is full and has a link to the
+		 * next buffer. Time to write the rest of the commands
+		 * into the new buffer.
+		 */
+		qptr->base_ptr_div128 = *ptr >> 7;
+		qptr->index = 0;
+		ptr = new_buffer;
+		if (count == 0) {
+			*ptr++ = cmd2;
+			qptr->index++;
+		}
+		if (count < 2) {
+			*ptr++ = cmd3;
+			qptr->index++;
+		}
+	}
+
+	/* All updates are complete. Release the lock and return */
+	if (likely(use_locking))
+		__cvmx_cmd_queue_unlock(qptr);
+	return CVMX_CMD_QUEUE_SUCCESS;
+}
+
+#endif /* __CVMX_CMD_QUEUE_H__ */
diff --git a/drivers/staging/octeon/cvmx-config.h b/drivers/staging/octeon/cvmx-config.h
new file mode 100644
index 0000000..078a520
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-config.h
@@ -0,0 +1,169 @@
+#ifndef __CVMX_CONFIG_H__
+#define __CVMX_CONFIG_H__
+
+/************************* Config Specific Defines ************************/
+#define CVMX_LLM_NUM_PORTS 1
+#define CVMX_NULL_POINTER_PROTECT 1
+#define CVMX_ENABLE_DEBUG_PRINTS 1
+/* PKO queues per port for interface 0 (ports 0-15) */
+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 1
+/* PKO queues per port for interface 1 (ports 16-31) */
+#define CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 1
+/* Limit on the number of PKO ports enabled for interface 0 */
+#define CVMX_PKO_MAX_PORTS_INTERFACE0 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
+/* Limit on the number of PKO ports enabled for interface 1 */
+#define CVMX_PKO_MAX_PORTS_INTERFACE1 CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
+/* PKO queues per port for PCI (ports 32-35) */
+#define CVMX_PKO_QUEUES_PER_PORT_PCI 1
+/* PKO queues per port for Loop devices (ports 36-39) */
+#define CVMX_PKO_QUEUES_PER_PORT_LOOP 1
+
+/************************* FPA allocation *********************************/
+/* Pool sizes in bytes, must be multiple of a cache line */
+#define CVMX_FPA_POOL_0_SIZE (16 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_1_SIZE (1 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_2_SIZE (8 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_3_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_4_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_5_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_6_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+#define CVMX_FPA_POOL_7_SIZE (0 * CVMX_CACHE_LINE_SIZE)
+
+/* Pools in use */
+/* Packet buffers */
+#define CVMX_FPA_PACKET_POOL                (0)
+#define CVMX_FPA_PACKET_POOL_SIZE           CVMX_FPA_POOL_0_SIZE
+/* Work queue entrys */
+#define CVMX_FPA_WQE_POOL                   (1)
+#define CVMX_FPA_WQE_POOL_SIZE              CVMX_FPA_POOL_1_SIZE
+/* PKO queue command buffers */
+#define CVMX_FPA_OUTPUT_BUFFER_POOL         (2)
+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE    CVMX_FPA_POOL_2_SIZE
+
+/*************************  FAU allocation ********************************/
+/* The fetch and add registers are allocated here.  They are arranged
+ * in order of descending size so that all alignment constraints are
+ * automatically met.  The enums are linked so that the following enum
+ * continues allocating where the previous one left off, so the
+ * numbering within each enum always starts with zero.  The macros
+ * take care of the address increment size, so the values entered
+ * always increase by 1.  FAU registers are accessed with byte
+ * addresses.
+ */
+
+#define CVMX_FAU_REG_64_ADDR(x) ((x << 3) + CVMX_FAU_REG_64_START)
+typedef enum {
+	CVMX_FAU_REG_64_START	= 0,
+	CVMX_FAU_REG_64_END	= CVMX_FAU_REG_64_ADDR(0),
+} cvmx_fau_reg_64_t;
+
+#define CVMX_FAU_REG_32_ADDR(x) ((x << 2) + CVMX_FAU_REG_32_START)
+typedef enum {
+	CVMX_FAU_REG_32_START	= CVMX_FAU_REG_64_END,
+	CVMX_FAU_REG_32_END	= CVMX_FAU_REG_32_ADDR(0),
+} cvmx_fau_reg_32_t;
+
+#define CVMX_FAU_REG_16_ADDR(x) ((x << 1) + CVMX_FAU_REG_16_START)
+typedef enum {
+	CVMX_FAU_REG_16_START	= CVMX_FAU_REG_32_END,
+	CVMX_FAU_REG_16_END	= CVMX_FAU_REG_16_ADDR(0),
+} cvmx_fau_reg_16_t;
+
+#define CVMX_FAU_REG_8_ADDR(x) ((x) + CVMX_FAU_REG_8_START)
+typedef enum {
+	CVMX_FAU_REG_8_START	= CVMX_FAU_REG_16_END,
+	CVMX_FAU_REG_8_END	= CVMX_FAU_REG_8_ADDR(0),
+} cvmx_fau_reg_8_t;
+
+/*
+ * The name CVMX_FAU_REG_AVAIL_BASE is provided to indicate the first
+ * available FAU address that is not allocated in cvmx-config.h. This
+ * is 64 bit aligned.
+ */
+#define CVMX_FAU_REG_AVAIL_BASE ((CVMX_FAU_REG_8_END + 0x7) & (~0x7ULL))
+#define CVMX_FAU_REG_END (2048)
+
+/********************** scratch memory allocation *************************/
+/* Scratchpad memory allocation.  Note that these are byte memory
+ * addresses.  Some uses of scratchpad (IOBDMA for example) require
+ * the use of 8-byte aligned addresses, so proper alignment needs to
+ * be taken into account.
+ */
+/* Generic scratch iobdma area */
+#define CVMX_SCR_SCRATCH               (0)
+/* First location available after cvmx-config.h allocated region. */
+#define CVMX_SCR_REG_AVAIL_BASE        (8)
+
+/*
+ * CVMX_HELPER_FIRST_MBUFF_SKIP is the number of bytes to reserve
+ * before the beginning of the packet. If necessary, override the
+ * default here.  See the IPD section of the hardware manual for MBUFF
+ * SKIP details.
+ */
+#define CVMX_HELPER_FIRST_MBUFF_SKIP 184
+
+/*
+ * CVMX_HELPER_NOT_FIRST_MBUFF_SKIP is the number of bytes to reserve
+ * in each chained packet element. If necessary, override the default
+ * here.
+ */
+#define CVMX_HELPER_NOT_FIRST_MBUFF_SKIP 0
+
+/*
+ * CVMX_HELPER_ENABLE_BACK_PRESSURE controls whether back pressure is
+ * enabled for all input ports. This controls if IPD sends
+ * backpressure to all ports if Octeon's FPA pools don't have enough
+ * packet or work queue entries. Even when this is off, it is still
+ * possible to get backpressure from individual hardware ports. When
+ * configuring backpressure, also check
+ * CVMX_HELPER_DISABLE_*_BACKPRESSURE below. If necessary, override
+ * the default here.
+ */
+#define CVMX_HELPER_ENABLE_BACK_PRESSURE 1
+
+/*
+ * CVMX_HELPER_ENABLE_IPD controls if the IPD is enabled in the helper
+ * function. Once it is enabled the hardware starts accepting
+ * packets. You might want to skip the IPD enable if configuration
+ * changes are need from the default helper setup. If necessary,
+ * override the default here.
+ */
+#define CVMX_HELPER_ENABLE_IPD 0
+
+/*
+ * CVMX_HELPER_INPUT_TAG_TYPE selects the type of tag that the IPD assigns
+ * to incoming packets.
+ */
+#define CVMX_HELPER_INPUT_TAG_TYPE CVMX_POW_TAG_TYPE_ORDERED
+
+#define CVMX_ENABLE_PARAMETER_CHECKING 0
+
+/*
+ * The following select which fields are used by the PIP to generate
+ * the tag on INPUT
+ * 0: don't include
+ * 1: include
+ */
+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP	0
+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_IP   	0
+#define CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT 	0
+#define CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT 	0
+#define CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER 	0
+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP	0
+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_IP   	0
+#define CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT 	0
+#define CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT 	0
+#define CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL	0
+#define CVMX_HELPER_INPUT_TAG_INPUT_PORT	1
+
+/* Select skip mode for input ports */
+#define CVMX_HELPER_INPUT_PORT_SKIP_MODE	CVMX_PIP_PORT_CFG_MODE_SKIPL2
+
+/*
+ * Force backpressure to be disabled.  This overrides all other
+ * backpressure configuration.
+ */
+#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
+
+#endif /* __CVMX_CONFIG_H__ */
+
diff --git a/drivers/staging/octeon/cvmx-dbg-defs.h b/drivers/staging/octeon/cvmx-dbg-defs.h
new file mode 100644
index 0000000..abbf42d
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-dbg-defs.h
@@ -0,0 +1,72 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_DBG_DEFS_H__
+#define __CVMX_DBG_DEFS_H__
+
+#define CVMX_DBG_DATA \
+	 CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
+
+union cvmx_dbg_data {
+	uint64_t u64;
+	struct cvmx_dbg_data_s {
+		uint64_t reserved_23_63:41;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} s;
+	struct cvmx_dbg_data_cn30xx {
+		uint64_t reserved_31_63:33;
+		uint64_t pll_mul:3;
+		uint64_t reserved_23_27:5;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} cn30xx;
+	struct cvmx_dbg_data_cn30xx cn31xx;
+	struct cvmx_dbg_data_cn38xx {
+		uint64_t reserved_29_63:35;
+		uint64_t d_mul:4;
+		uint64_t dclk_mul2:1;
+		uint64_t cclk_div2:1;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} cn38xx;
+	struct cvmx_dbg_data_cn38xx cn38xxp2;
+	struct cvmx_dbg_data_cn30xx cn50xx;
+	struct cvmx_dbg_data_cn58xx {
+		uint64_t reserved_29_63:35;
+		uint64_t rem:6;
+		uint64_t c_mul:5;
+		uint64_t dsel_ext:1;
+		uint64_t data:17;
+	} cn58xx;
+	struct cvmx_dbg_data_cn58xx cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-fau.h b/drivers/staging/octeon/cvmx-fau.h
new file mode 100644
index 0000000..29bdce6
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-fau.h
@@ -0,0 +1,597 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Interface to the hardware Fetch and Add Unit.
+ */
+
+#ifndef __CVMX_FAU_H__
+#define __CVMX_FAU_H__
+
+/*
+ * Octeon Fetch and Add Unit (FAU)
+ */
+
+#define CVMX_FAU_LOAD_IO_ADDRESS    cvmx_build_io_address(0x1e, 0)
+#define CVMX_FAU_BITS_SCRADDR       63, 56
+#define CVMX_FAU_BITS_LEN           55, 48
+#define CVMX_FAU_BITS_INEVAL        35, 14
+#define CVMX_FAU_BITS_TAGWAIT       13, 13
+#define CVMX_FAU_BITS_NOADD         13, 13
+#define CVMX_FAU_BITS_SIZE          12, 11
+#define CVMX_FAU_BITS_REGISTER      10, 0
+
+typedef enum {
+	CVMX_FAU_OP_SIZE_8 = 0,
+	CVMX_FAU_OP_SIZE_16 = 1,
+	CVMX_FAU_OP_SIZE_32 = 2,
+	CVMX_FAU_OP_SIZE_64 = 3
+} cvmx_fau_op_size_t;
+
+/**
+ * Tagwait return definition. If a timeout occurs, the error
+ * bit will be set. Otherwise the value of the register before
+ * the update will be returned.
+ */
+typedef struct {
+	uint64_t error:1;
+	int64_t value:63;
+} cvmx_fau_tagwait64_t;
+
+/**
+ * Tagwait return definition. If a timeout occurs, the error
+ * bit will be set. Otherwise the value of the register before
+ * the update will be returned.
+ */
+typedef struct {
+	uint64_t error:1;
+	int32_t value:31;
+} cvmx_fau_tagwait32_t;
+
+/**
+ * Tagwait return definition. If a timeout occurs, the error
+ * bit will be set. Otherwise the value of the register before
+ * the update will be returned.
+ */
+typedef struct {
+	uint64_t error:1;
+	int16_t value:15;
+} cvmx_fau_tagwait16_t;
+
+/**
+ * Tagwait return definition. If a timeout occurs, the error
+ * bit will be set. Otherwise the value of the register before
+ * the update will be returned.
+ */
+typedef struct {
+	uint64_t error:1;
+	int8_t value:7;
+} cvmx_fau_tagwait8_t;
+
+/**
+ * Asynchronous tagwait return definition. If a timeout occurs,
+ * the error bit will be set. Otherwise the value of the
+ * register before the update will be returned.
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		uint64_t invalid:1;
+		uint64_t data:63;	/* unpredictable if invalid is set */
+	} s;
+} cvmx_fau_async_tagwait_result_t;
+
+/**
+ * Builds a store I/O address for writing to the FAU
+ *
+ * @noadd:  0 = Store value is atomically added to the current value
+ *               1 = Store value is atomically written over the current value
+ * @reg:    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 2 for 16 bit access.
+ *               - Step by 4 for 32 bit access.
+ *               - Step by 8 for 64 bit access.
+ * Returns Address to store for atomic update
+ */
+static inline uint64_t __cvmx_fau_store_address(uint64_t noadd, uint64_t reg)
+{
+	return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
+	       cvmx_build_bits(CVMX_FAU_BITS_NOADD, noadd) |
+	       cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
+}
+
+/**
+ * Builds a I/O address for accessing the FAU
+ *
+ * @tagwait: Should the atomic add wait for the current tag switch
+ *                operation to complete.
+ *                - 0 = Don't wait
+ *                - 1 = Wait for tag switch to complete
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ *                - Step by 4 for 32 bit access.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to add.
+ *                Note: When performing 32 and 64 bit access, only the low
+ *                22 bits are available.
+ * Returns Address to read from for atomic update
+ */
+static inline uint64_t __cvmx_fau_atomic_address(uint64_t tagwait, uint64_t reg,
+						 int64_t value)
+{
+	return CVMX_ADD_IO_SEG(CVMX_FAU_LOAD_IO_ADDRESS) |
+	       cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
+	       cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
+	       cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
+}
+
+/**
+ * Perform an atomic 64 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Value of the register before the update
+ */
+static inline int64_t cvmx_fau_fetch_and_add64(cvmx_fau_reg_64_t reg,
+					       int64_t value)
+{
+	return cvmx_read64_int64(__cvmx_fau_atomic_address(0, reg, value));
+}
+
+/**
+ * Perform an atomic 32 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Value of the register before the update
+ */
+static inline int32_t cvmx_fau_fetch_and_add32(cvmx_fau_reg_32_t reg,
+					       int32_t value)
+{
+	return cvmx_read64_int32(__cvmx_fau_atomic_address(0, reg, value));
+}
+
+/**
+ * Perform an atomic 16 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @value:   Signed value to add.
+ * Returns Value of the register before the update
+ */
+static inline int16_t cvmx_fau_fetch_and_add16(cvmx_fau_reg_16_t reg,
+					       int16_t value)
+{
+	return cvmx_read64_int16(__cvmx_fau_atomic_address(0, reg, value));
+}
+
+/**
+ * Perform an atomic 8 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ * @value:   Signed value to add.
+ * Returns Value of the register before the update
+ */
+static inline int8_t cvmx_fau_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
+{
+	return cvmx_read64_int8(__cvmx_fau_atomic_address(0, reg, value));
+}
+
+/**
+ * Perform an atomic 64 bit add after the current tag switch
+ * completes
+ *
+ * @reg:    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 8 for 64 bit access.
+ * @value:  Signed value to add.
+ *               Note: Only the low 22 bits are available.
+ * Returns If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait64_t
+cvmx_fau_tagwait_fetch_and_add64(cvmx_fau_reg_64_t reg, int64_t value)
+{
+	union {
+		uint64_t i64;
+		cvmx_fau_tagwait64_t t;
+	} result;
+	result.i64 =
+	    cvmx_read64_int64(__cvmx_fau_atomic_address(1, reg, value));
+	return result.t;
+}
+
+/**
+ * Perform an atomic 32 bit add after the current tag switch
+ * completes
+ *
+ * @reg:    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 4 for 32 bit access.
+ * @value:  Signed value to add.
+ *               Note: Only the low 22 bits are available.
+ * Returns If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait32_t
+cvmx_fau_tagwait_fetch_and_add32(cvmx_fau_reg_32_t reg, int32_t value)
+{
+	union {
+		uint64_t i32;
+		cvmx_fau_tagwait32_t t;
+	} result;
+	result.i32 =
+	    cvmx_read64_int32(__cvmx_fau_atomic_address(1, reg, value));
+	return result.t;
+}
+
+/**
+ * Perform an atomic 16 bit add after the current tag switch
+ * completes
+ *
+ * @reg:    FAU atomic register to access. 0 <= reg < 2048.
+ *               - Step by 2 for 16 bit access.
+ * @value:  Signed value to add.
+ * Returns If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait16_t
+cvmx_fau_tagwait_fetch_and_add16(cvmx_fau_reg_16_t reg, int16_t value)
+{
+	union {
+		uint64_t i16;
+		cvmx_fau_tagwait16_t t;
+	} result;
+	result.i16 =
+	    cvmx_read64_int16(__cvmx_fau_atomic_address(1, reg, value));
+	return result.t;
+}
+
+/**
+ * Perform an atomic 8 bit add after the current tag switch
+ * completes
+ *
+ * @reg:    FAU atomic register to access. 0 <= reg < 2048.
+ * @value:  Signed value to add.
+ * Returns If a timeout occurs, the error bit will be set. Otherwise
+ *         the value of the register before the update will be
+ *         returned
+ */
+static inline cvmx_fau_tagwait8_t
+cvmx_fau_tagwait_fetch_and_add8(cvmx_fau_reg_8_t reg, int8_t value)
+{
+	union {
+		uint64_t i8;
+		cvmx_fau_tagwait8_t t;
+	} result;
+	result.i8 = cvmx_read64_int8(__cvmx_fau_atomic_address(1, reg, value));
+	return result.t;
+}
+
+/**
+ * Builds I/O data for async operations
+ *
+ * @scraddr: Scratch pad byte addres to write to.  Must be 8 byte aligned
+ * @value:   Signed value to add.
+ *                Note: When performing 32 and 64 bit access, only the low
+ *                22 bits are available.
+ * @tagwait: Should the atomic add wait for the current tag switch
+ *                operation to complete.
+ *                - 0 = Don't wait
+ *                - 1 = Wait for tag switch to complete
+ * @size:    The size of the operation:
+ *                - CVMX_FAU_OP_SIZE_8  (0) = 8 bits
+ *                - CVMX_FAU_OP_SIZE_16 (1) = 16 bits
+ *                - CVMX_FAU_OP_SIZE_32 (2) = 32 bits
+ *                - CVMX_FAU_OP_SIZE_64 (3) = 64 bits
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ *                - Step by 4 for 32 bit access.
+ *                - Step by 8 for 64 bit access.
+ * Returns Data to write using cvmx_send_single
+ */
+static inline uint64_t __cvmx_fau_iobdma_data(uint64_t scraddr, int64_t value,
+					      uint64_t tagwait,
+					      cvmx_fau_op_size_t size,
+					      uint64_t reg)
+{
+	return CVMX_FAU_LOAD_IO_ADDRESS |
+	       cvmx_build_bits(CVMX_FAU_BITS_SCRADDR, scraddr >> 3) |
+	       cvmx_build_bits(CVMX_FAU_BITS_LEN, 1) |
+	       cvmx_build_bits(CVMX_FAU_BITS_INEVAL, value) |
+	       cvmx_build_bits(CVMX_FAU_BITS_TAGWAIT, tagwait) |
+	       cvmx_build_bits(CVMX_FAU_BITS_SIZE, size) |
+	       cvmx_build_bits(CVMX_FAU_BITS_REGISTER, reg);
+}
+
+/**
+ * Perform an async atomic 64 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @scraddr: Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_fetch_and_add64(uint64_t scraddr,
+						  cvmx_fau_reg_64_t reg,
+						  int64_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 0, CVMX_FAU_OP_SIZE_64, reg));
+}
+
+/**
+ * Perform an async atomic 32 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @scraddr: Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_fetch_and_add32(uint64_t scraddr,
+						  cvmx_fau_reg_32_t reg,
+						  int32_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 0, CVMX_FAU_OP_SIZE_32, reg));
+}
+
+/**
+ * Perform an async atomic 16 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @scraddr: Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @value:   Signed value to add.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_fetch_and_add16(uint64_t scraddr,
+						  cvmx_fau_reg_16_t reg,
+						  int16_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 0, CVMX_FAU_OP_SIZE_16, reg));
+}
+
+/**
+ * Perform an async atomic 8 bit add. The old value is
+ * placed in the scratch memory at byte address scraddr.
+ *
+ * @scraddr: Scratch memory byte address to put response in.
+ *                Must be 8 byte aligned.
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ * @value:   Signed value to add.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_fetch_and_add8(uint64_t scraddr,
+						 cvmx_fau_reg_8_t reg,
+						 int8_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 0, CVMX_FAU_OP_SIZE_8, reg));
+}
+
+/**
+ * Perform an async atomic 64 bit add after the current tag
+ * switch completes.
+ *
+ * @scraddr: Scratch memory byte address to put response in.  Must be
+ *           8 byte aligned.  If a timeout occurs, the error bit (63)
+ *           will be set. Otherwise the value of the register before
+ *           the update will be returned
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add64(uint64_t scraddr,
+							  cvmx_fau_reg_64_t reg,
+							  int64_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 1, CVMX_FAU_OP_SIZE_64, reg));
+}
+
+/**
+ * Perform an async atomic 32 bit add after the current tag
+ * switch completes.
+ *
+ * @scraddr: Scratch memory byte address to put response in.  Must be
+ *           8 byte aligned.  If a timeout occurs, the error bit (63)
+ *           will be set. Otherwise the value of the register before
+ *           the update will be returned
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @value:   Signed value to add.
+ *                Note: Only the low 22 bits are available.
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add32(uint64_t scraddr,
+							  cvmx_fau_reg_32_t reg,
+							  int32_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 1, CVMX_FAU_OP_SIZE_32, reg));
+}
+
+/**
+ * Perform an async atomic 16 bit add after the current tag
+ * switch completes.
+ *
+ * @scraddr: Scratch memory byte address to put response in.  Must be
+ *           8 byte aligned.  If a timeout occurs, the error bit (63)
+ *           will be set. Otherwise the value of the register before
+ *           the update will be returned
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @value:   Signed value to add.
+ *
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add16(uint64_t scraddr,
+							  cvmx_fau_reg_16_t reg,
+							  int16_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 1, CVMX_FAU_OP_SIZE_16, reg));
+}
+
+/**
+ * Perform an async atomic 8 bit add after the current tag
+ * switch completes.
+ *
+ * @scraddr: Scratch memory byte address to put response in.  Must be
+ *           8 byte aligned.  If a timeout occurs, the error bit (63)
+ *           will be set. Otherwise the value of the register before
+ *           the update will be returned
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ * @value:   Signed value to add.
+ *
+ * Returns Placed in the scratch pad register
+ */
+static inline void cvmx_fau_async_tagwait_fetch_and_add8(uint64_t scraddr,
+							 cvmx_fau_reg_8_t reg,
+							 int8_t value)
+{
+	cvmx_send_single(__cvmx_fau_iobdma_data
+			 (scraddr, value, 1, CVMX_FAU_OP_SIZE_8, reg));
+}
+
+/**
+ * Perform an atomic 64 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add64(cvmx_fau_reg_64_t reg, int64_t value)
+{
+	cvmx_write64_int64(__cvmx_fau_store_address(0, reg), value);
+}
+
+/**
+ * Perform an atomic 32 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @value:   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add32(cvmx_fau_reg_32_t reg, int32_t value)
+{
+	cvmx_write64_int32(__cvmx_fau_store_address(0, reg), value);
+}
+
+/**
+ * Perform an atomic 16 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @value:   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add16(cvmx_fau_reg_16_t reg, int16_t value)
+{
+	cvmx_write64_int16(__cvmx_fau_store_address(0, reg), value);
+}
+
+/**
+ * Perform an atomic 8 bit add
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ * @value:   Signed value to add.
+ */
+static inline void cvmx_fau_atomic_add8(cvmx_fau_reg_8_t reg, int8_t value)
+{
+	cvmx_write64_int8(__cvmx_fau_store_address(0, reg), value);
+}
+
+/**
+ * Perform an atomic 64 bit write
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 8 for 64 bit access.
+ * @value:   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write64(cvmx_fau_reg_64_t reg, int64_t value)
+{
+	cvmx_write64_int64(__cvmx_fau_store_address(1, reg), value);
+}
+
+/**
+ * Perform an atomic 32 bit write
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 4 for 32 bit access.
+ * @value:   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write32(cvmx_fau_reg_32_t reg, int32_t value)
+{
+	cvmx_write64_int32(__cvmx_fau_store_address(1, reg), value);
+}
+
+/**
+ * Perform an atomic 16 bit write
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ *                - Step by 2 for 16 bit access.
+ * @value:   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write16(cvmx_fau_reg_16_t reg, int16_t value)
+{
+	cvmx_write64_int16(__cvmx_fau_store_address(1, reg), value);
+}
+
+/**
+ * Perform an atomic 8 bit write
+ *
+ * @reg:     FAU atomic register to access. 0 <= reg < 2048.
+ * @value:   Signed value to write.
+ */
+static inline void cvmx_fau_atomic_write8(cvmx_fau_reg_8_t reg, int8_t value)
+{
+	cvmx_write64_int8(__cvmx_fau_store_address(1, reg), value);
+}
+
+#endif /* __CVMX_FAU_H__ */
diff --git a/drivers/staging/octeon/cvmx-fpa-defs.h b/drivers/staging/octeon/cvmx-fpa-defs.h
new file mode 100644
index 0000000..bf5546b
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-fpa-defs.h
@@ -0,0 +1,403 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_FPA_DEFS_H__
+#define __CVMX_FPA_DEFS_H__
+
+#define CVMX_FPA_BIST_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011800280000E8ull)
+#define CVMX_FPA_CTL_STATUS \
+	 CVMX_ADD_IO_SEG(0x0001180028000050ull)
+#define CVMX_FPA_FPF0_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000000ull)
+#define CVMX_FPA_FPF0_SIZE \
+	 CVMX_ADD_IO_SEG(0x0001180028000058ull)
+#define CVMX_FPA_FPF1_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000008ull)
+#define CVMX_FPA_FPF2_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000010ull)
+#define CVMX_FPA_FPF3_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000018ull)
+#define CVMX_FPA_FPF4_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000020ull)
+#define CVMX_FPA_FPF5_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000028ull)
+#define CVMX_FPA_FPF6_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000030ull)
+#define CVMX_FPA_FPF7_MARKS \
+	 CVMX_ADD_IO_SEG(0x0001180028000038ull)
+#define CVMX_FPA_FPFX_MARKS(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
+#define CVMX_FPA_FPFX_SIZE(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
+#define CVMX_FPA_INT_ENB \
+	 CVMX_ADD_IO_SEG(0x0001180028000048ull)
+#define CVMX_FPA_INT_SUM \
+	 CVMX_ADD_IO_SEG(0x0001180028000040ull)
+#define CVMX_FPA_QUE0_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x00011800280000F0ull)
+#define CVMX_FPA_QUE1_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x00011800280000F8ull)
+#define CVMX_FPA_QUE2_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000100ull)
+#define CVMX_FPA_QUE3_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000108ull)
+#define CVMX_FPA_QUE4_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000110ull)
+#define CVMX_FPA_QUE5_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000118ull)
+#define CVMX_FPA_QUE6_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000120ull)
+#define CVMX_FPA_QUE7_PAGE_INDEX \
+	 CVMX_ADD_IO_SEG(0x0001180028000128ull)
+#define CVMX_FPA_QUEX_AVAILABLE(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
+#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
+#define CVMX_FPA_QUE_ACT \
+	 CVMX_ADD_IO_SEG(0x0001180028000138ull)
+#define CVMX_FPA_QUE_EXP \
+	 CVMX_ADD_IO_SEG(0x0001180028000130ull)
+#define CVMX_FPA_WART_CTL \
+	 CVMX_ADD_IO_SEG(0x00011800280000D8ull)
+#define CVMX_FPA_WART_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011800280000E0ull)
+
+union cvmx_fpa_bist_status {
+	uint64_t u64;
+	struct cvmx_fpa_bist_status_s {
+		uint64_t reserved_5_63:59;
+		uint64_t frd:1;
+		uint64_t fpf0:1;
+		uint64_t fpf1:1;
+		uint64_t ffr:1;
+		uint64_t fdr:1;
+	} s;
+	struct cvmx_fpa_bist_status_s cn30xx;
+	struct cvmx_fpa_bist_status_s cn31xx;
+	struct cvmx_fpa_bist_status_s cn38xx;
+	struct cvmx_fpa_bist_status_s cn38xxp2;
+	struct cvmx_fpa_bist_status_s cn50xx;
+	struct cvmx_fpa_bist_status_s cn52xx;
+	struct cvmx_fpa_bist_status_s cn52xxp1;
+	struct cvmx_fpa_bist_status_s cn56xx;
+	struct cvmx_fpa_bist_status_s cn56xxp1;
+	struct cvmx_fpa_bist_status_s cn58xx;
+	struct cvmx_fpa_bist_status_s cn58xxp1;
+};
+
+union cvmx_fpa_ctl_status {
+	uint64_t u64;
+	struct cvmx_fpa_ctl_status_s {
+		uint64_t reserved_18_63:46;
+		uint64_t reset:1;
+		uint64_t use_ldt:1;
+		uint64_t use_stt:1;
+		uint64_t enb:1;
+		uint64_t mem1_err:7;
+		uint64_t mem0_err:7;
+	} s;
+	struct cvmx_fpa_ctl_status_s cn30xx;
+	struct cvmx_fpa_ctl_status_s cn31xx;
+	struct cvmx_fpa_ctl_status_s cn38xx;
+	struct cvmx_fpa_ctl_status_s cn38xxp2;
+	struct cvmx_fpa_ctl_status_s cn50xx;
+	struct cvmx_fpa_ctl_status_s cn52xx;
+	struct cvmx_fpa_ctl_status_s cn52xxp1;
+	struct cvmx_fpa_ctl_status_s cn56xx;
+	struct cvmx_fpa_ctl_status_s cn56xxp1;
+	struct cvmx_fpa_ctl_status_s cn58xx;
+	struct cvmx_fpa_ctl_status_s cn58xxp1;
+};
+
+union cvmx_fpa_fpfx_marks {
+	uint64_t u64;
+	struct cvmx_fpa_fpfx_marks_s {
+		uint64_t reserved_22_63:42;
+		uint64_t fpf_wr:11;
+		uint64_t fpf_rd:11;
+	} s;
+	struct cvmx_fpa_fpfx_marks_s cn38xx;
+	struct cvmx_fpa_fpfx_marks_s cn38xxp2;
+	struct cvmx_fpa_fpfx_marks_s cn56xx;
+	struct cvmx_fpa_fpfx_marks_s cn56xxp1;
+	struct cvmx_fpa_fpfx_marks_s cn58xx;
+	struct cvmx_fpa_fpfx_marks_s cn58xxp1;
+};
+
+union cvmx_fpa_fpfx_size {
+	uint64_t u64;
+	struct cvmx_fpa_fpfx_size_s {
+		uint64_t reserved_11_63:53;
+		uint64_t fpf_siz:11;
+	} s;
+	struct cvmx_fpa_fpfx_size_s cn38xx;
+	struct cvmx_fpa_fpfx_size_s cn38xxp2;
+	struct cvmx_fpa_fpfx_size_s cn56xx;
+	struct cvmx_fpa_fpfx_size_s cn56xxp1;
+	struct cvmx_fpa_fpfx_size_s cn58xx;
+	struct cvmx_fpa_fpfx_size_s cn58xxp1;
+};
+
+union cvmx_fpa_fpf0_marks {
+	uint64_t u64;
+	struct cvmx_fpa_fpf0_marks_s {
+		uint64_t reserved_24_63:40;
+		uint64_t fpf_wr:12;
+		uint64_t fpf_rd:12;
+	} s;
+	struct cvmx_fpa_fpf0_marks_s cn38xx;
+	struct cvmx_fpa_fpf0_marks_s cn38xxp2;
+	struct cvmx_fpa_fpf0_marks_s cn56xx;
+	struct cvmx_fpa_fpf0_marks_s cn56xxp1;
+	struct cvmx_fpa_fpf0_marks_s cn58xx;
+	struct cvmx_fpa_fpf0_marks_s cn58xxp1;
+};
+
+union cvmx_fpa_fpf0_size {
+	uint64_t u64;
+	struct cvmx_fpa_fpf0_size_s {
+		uint64_t reserved_12_63:52;
+		uint64_t fpf_siz:12;
+	} s;
+	struct cvmx_fpa_fpf0_size_s cn38xx;
+	struct cvmx_fpa_fpf0_size_s cn38xxp2;
+	struct cvmx_fpa_fpf0_size_s cn56xx;
+	struct cvmx_fpa_fpf0_size_s cn56xxp1;
+	struct cvmx_fpa_fpf0_size_s cn58xx;
+	struct cvmx_fpa_fpf0_size_s cn58xxp1;
+};
+
+union cvmx_fpa_int_enb {
+	uint64_t u64;
+	struct cvmx_fpa_int_enb_s {
+		uint64_t reserved_28_63:36;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+	} s;
+	struct cvmx_fpa_int_enb_s cn30xx;
+	struct cvmx_fpa_int_enb_s cn31xx;
+	struct cvmx_fpa_int_enb_s cn38xx;
+	struct cvmx_fpa_int_enb_s cn38xxp2;
+	struct cvmx_fpa_int_enb_s cn50xx;
+	struct cvmx_fpa_int_enb_s cn52xx;
+	struct cvmx_fpa_int_enb_s cn52xxp1;
+	struct cvmx_fpa_int_enb_s cn56xx;
+	struct cvmx_fpa_int_enb_s cn56xxp1;
+	struct cvmx_fpa_int_enb_s cn58xx;
+	struct cvmx_fpa_int_enb_s cn58xxp1;
+};
+
+union cvmx_fpa_int_sum {
+	uint64_t u64;
+	struct cvmx_fpa_int_sum_s {
+		uint64_t reserved_28_63:36;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+	} s;
+	struct cvmx_fpa_int_sum_s cn30xx;
+	struct cvmx_fpa_int_sum_s cn31xx;
+	struct cvmx_fpa_int_sum_s cn38xx;
+	struct cvmx_fpa_int_sum_s cn38xxp2;
+	struct cvmx_fpa_int_sum_s cn50xx;
+	struct cvmx_fpa_int_sum_s cn52xx;
+	struct cvmx_fpa_int_sum_s cn52xxp1;
+	struct cvmx_fpa_int_sum_s cn56xx;
+	struct cvmx_fpa_int_sum_s cn56xxp1;
+	struct cvmx_fpa_int_sum_s cn58xx;
+	struct cvmx_fpa_int_sum_s cn58xxp1;
+};
+
+union cvmx_fpa_quex_available {
+	uint64_t u64;
+	struct cvmx_fpa_quex_available_s {
+		uint64_t reserved_29_63:35;
+		uint64_t que_siz:29;
+	} s;
+	struct cvmx_fpa_quex_available_s cn30xx;
+	struct cvmx_fpa_quex_available_s cn31xx;
+	struct cvmx_fpa_quex_available_s cn38xx;
+	struct cvmx_fpa_quex_available_s cn38xxp2;
+	struct cvmx_fpa_quex_available_s cn50xx;
+	struct cvmx_fpa_quex_available_s cn52xx;
+	struct cvmx_fpa_quex_available_s cn52xxp1;
+	struct cvmx_fpa_quex_available_s cn56xx;
+	struct cvmx_fpa_quex_available_s cn56xxp1;
+	struct cvmx_fpa_quex_available_s cn58xx;
+	struct cvmx_fpa_quex_available_s cn58xxp1;
+};
+
+union cvmx_fpa_quex_page_index {
+	uint64_t u64;
+	struct cvmx_fpa_quex_page_index_s {
+		uint64_t reserved_25_63:39;
+		uint64_t pg_num:25;
+	} s;
+	struct cvmx_fpa_quex_page_index_s cn30xx;
+	struct cvmx_fpa_quex_page_index_s cn31xx;
+	struct cvmx_fpa_quex_page_index_s cn38xx;
+	struct cvmx_fpa_quex_page_index_s cn38xxp2;
+	struct cvmx_fpa_quex_page_index_s cn50xx;
+	struct cvmx_fpa_quex_page_index_s cn52xx;
+	struct cvmx_fpa_quex_page_index_s cn52xxp1;
+	struct cvmx_fpa_quex_page_index_s cn56xx;
+	struct cvmx_fpa_quex_page_index_s cn56xxp1;
+	struct cvmx_fpa_quex_page_index_s cn58xx;
+	struct cvmx_fpa_quex_page_index_s cn58xxp1;
+};
+
+union cvmx_fpa_que_act {
+	uint64_t u64;
+	struct cvmx_fpa_que_act_s {
+		uint64_t reserved_29_63:35;
+		uint64_t act_que:3;
+		uint64_t act_indx:26;
+	} s;
+	struct cvmx_fpa_que_act_s cn30xx;
+	struct cvmx_fpa_que_act_s cn31xx;
+	struct cvmx_fpa_que_act_s cn38xx;
+	struct cvmx_fpa_que_act_s cn38xxp2;
+	struct cvmx_fpa_que_act_s cn50xx;
+	struct cvmx_fpa_que_act_s cn52xx;
+	struct cvmx_fpa_que_act_s cn52xxp1;
+	struct cvmx_fpa_que_act_s cn56xx;
+	struct cvmx_fpa_que_act_s cn56xxp1;
+	struct cvmx_fpa_que_act_s cn58xx;
+	struct cvmx_fpa_que_act_s cn58xxp1;
+};
+
+union cvmx_fpa_que_exp {
+	uint64_t u64;
+	struct cvmx_fpa_que_exp_s {
+		uint64_t reserved_29_63:35;
+		uint64_t exp_que:3;
+		uint64_t exp_indx:26;
+	} s;
+	struct cvmx_fpa_que_exp_s cn30xx;
+	struct cvmx_fpa_que_exp_s cn31xx;
+	struct cvmx_fpa_que_exp_s cn38xx;
+	struct cvmx_fpa_que_exp_s cn38xxp2;
+	struct cvmx_fpa_que_exp_s cn50xx;
+	struct cvmx_fpa_que_exp_s cn52xx;
+	struct cvmx_fpa_que_exp_s cn52xxp1;
+	struct cvmx_fpa_que_exp_s cn56xx;
+	struct cvmx_fpa_que_exp_s cn56xxp1;
+	struct cvmx_fpa_que_exp_s cn58xx;
+	struct cvmx_fpa_que_exp_s cn58xxp1;
+};
+
+union cvmx_fpa_wart_ctl {
+	uint64_t u64;
+	struct cvmx_fpa_wart_ctl_s {
+		uint64_t reserved_16_63:48;
+		uint64_t ctl:16;
+	} s;
+	struct cvmx_fpa_wart_ctl_s cn30xx;
+	struct cvmx_fpa_wart_ctl_s cn31xx;
+	struct cvmx_fpa_wart_ctl_s cn38xx;
+	struct cvmx_fpa_wart_ctl_s cn38xxp2;
+	struct cvmx_fpa_wart_ctl_s cn50xx;
+	struct cvmx_fpa_wart_ctl_s cn52xx;
+	struct cvmx_fpa_wart_ctl_s cn52xxp1;
+	struct cvmx_fpa_wart_ctl_s cn56xx;
+	struct cvmx_fpa_wart_ctl_s cn56xxp1;
+	struct cvmx_fpa_wart_ctl_s cn58xx;
+	struct cvmx_fpa_wart_ctl_s cn58xxp1;
+};
+
+union cvmx_fpa_wart_status {
+	uint64_t u64;
+	struct cvmx_fpa_wart_status_s {
+		uint64_t reserved_32_63:32;
+		uint64_t status:32;
+	} s;
+	struct cvmx_fpa_wart_status_s cn30xx;
+	struct cvmx_fpa_wart_status_s cn31xx;
+	struct cvmx_fpa_wart_status_s cn38xx;
+	struct cvmx_fpa_wart_status_s cn38xxp2;
+	struct cvmx_fpa_wart_status_s cn50xx;
+	struct cvmx_fpa_wart_status_s cn52xx;
+	struct cvmx_fpa_wart_status_s cn52xxp1;
+	struct cvmx_fpa_wart_status_s cn56xx;
+	struct cvmx_fpa_wart_status_s cn56xxp1;
+	struct cvmx_fpa_wart_status_s cn58xx;
+	struct cvmx_fpa_wart_status_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-fpa.c b/drivers/staging/octeon/cvmx-fpa.c
new file mode 100644
index 0000000..55d9147
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-fpa.c
@@ -0,0 +1,183 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Support library for the hardware Free Pool Allocator.
+ *
+ *
+ */
+
+#include "cvmx-config.h"
+#include "cvmx.h"
+#include "cvmx-fpa.h"
+#include "cvmx-ipd.h"
+
+/**
+ * Current state of all the pools. Use access functions
+ * instead of using it directly.
+ */
+CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
+
+/**
+ * Setup a FPA pool to control a new block of memory. The
+ * buffer pointer must be a physical address.
+ *
+ * @pool:       Pool to initialize
+ *                   0 <= pool < 8
+ * @name:       Constant character string to name this pool.
+ *                   String is not copied.
+ * @buffer:     Pointer to the block of memory to use. This must be
+ *                   accessable by all processors and external hardware.
+ * @block_size: Size for each block controlled by the FPA
+ * @num_blocks: Number of blocks
+ *
+ * Returns 0 on Success,
+ *         -1 on failure
+ */
+int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
+			uint64_t block_size, uint64_t num_blocks)
+{
+	char *ptr;
+	if (!buffer) {
+		cvmx_dprintf
+		    ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
+		return -1;
+	}
+	if (pool >= CVMX_FPA_NUM_POOLS) {
+		cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
+		return -1;
+	}
+
+	if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
+		cvmx_dprintf
+		    ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
+		return -1;
+	}
+
+	if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
+		cvmx_dprintf
+		    ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
+		return -1;
+	}
+
+	cvmx_fpa_pool_info[pool].name = name;
+	cvmx_fpa_pool_info[pool].size = block_size;
+	cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
+	cvmx_fpa_pool_info[pool].base = buffer;
+
+	ptr = (char *)buffer;
+	while (num_blocks--) {
+		cvmx_fpa_free(ptr, pool, 0);
+		ptr += block_size;
+	}
+	return 0;
+}
+
+/**
+ * Shutdown a Memory pool and validate that it had all of
+ * the buffers originally placed in it.
+ *
+ * @pool:   Pool to shutdown
+ * Returns Zero on success
+ *         - Positive is count of missing buffers
+ *         - Negative is too many buffers or corrupted pointers
+ */
+uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
+{
+	uint64_t errors = 0;
+	uint64_t count = 0;
+	uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
+	uint64_t finish =
+	    base +
+	    cvmx_fpa_pool_info[pool].size *
+	    cvmx_fpa_pool_info[pool].starting_element_count;
+	void *ptr;
+	uint64_t address;
+
+	count = 0;
+	do {
+		ptr = cvmx_fpa_alloc(pool);
+		if (ptr)
+			address = cvmx_ptr_to_phys(ptr);
+		else
+			address = 0;
+		if (address) {
+			if ((address >= base) && (address < finish) &&
+			    (((address -
+			       base) % cvmx_fpa_pool_info[pool].size) == 0)) {
+				count++;
+			} else {
+				cvmx_dprintf
+				    ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
+				     (unsigned long long)address,
+				     cvmx_fpa_pool_info[pool].name, (int)pool);
+				errors++;
+			}
+		}
+	} while (address);
+
+#ifdef CVMX_ENABLE_PKO_FUNCTIONS
+	if (pool == 0)
+		cvmx_ipd_free_ptr();
+#endif
+
+	if (errors) {
+		cvmx_dprintf
+		    ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
+		     cvmx_fpa_pool_info[pool].name, (int)pool,
+		     (unsigned long long)base, (unsigned long long)finish,
+		     (unsigned long long)cvmx_fpa_pool_info[pool].size);
+		return -errors;
+	} else
+		return 0;
+}
+
+uint64_t cvmx_fpa_get_block_size(uint64_t pool)
+{
+	switch (pool) {
+	case 0:
+		return CVMX_FPA_POOL_0_SIZE;
+	case 1:
+		return CVMX_FPA_POOL_1_SIZE;
+	case 2:
+		return CVMX_FPA_POOL_2_SIZE;
+	case 3:
+		return CVMX_FPA_POOL_3_SIZE;
+	case 4:
+		return CVMX_FPA_POOL_4_SIZE;
+	case 5:
+		return CVMX_FPA_POOL_5_SIZE;
+	case 6:
+		return CVMX_FPA_POOL_6_SIZE;
+	case 7:
+		return CVMX_FPA_POOL_7_SIZE;
+	default:
+		return 0;
+	}
+}
diff --git a/drivers/staging/octeon/cvmx-fpa.h b/drivers/staging/octeon/cvmx-fpa.h
new file mode 100644
index 0000000..1d7788f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-fpa.h
@@ -0,0 +1,299 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Interface to the hardware Free Pool Allocator.
+ *
+ *
+ */
+
+#ifndef __CVMX_FPA_H__
+#define __CVMX_FPA_H__
+
+#include "cvmx-address.h"
+#include "cvmx-fpa-defs.h"
+
+#define CVMX_FPA_NUM_POOLS      8
+#define CVMX_FPA_MIN_BLOCK_SIZE 128
+#define CVMX_FPA_ALIGNMENT      128
+
+/**
+ * Structure describing the data format used for stores to the FPA.
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		/*
+		 * the (64-bit word) location in scratchpad to write
+		 * to (if len != 0)
+		 */
+		uint64_t scraddr:8;
+		/* the number of words in the response (0 => no response) */
+		uint64_t len:8;
+		/* the ID of the device on the non-coherent bus */
+		uint64_t did:8;
+		/*
+		 * the address that will appear in the first tick on
+		 * the NCB bus.
+		 */
+		uint64_t addr:40;
+	} s;
+} cvmx_fpa_iobdma_data_t;
+
+/**
+ * Structure describing the current state of a FPA pool.
+ */
+typedef struct {
+	/* Name it was created under */
+	const char *name;
+	/* Size of each block */
+	uint64_t size;
+	/* The base memory address of whole block */
+	void *base;
+	/* The number of elements in the pool at creation */
+	uint64_t starting_element_count;
+} cvmx_fpa_pool_info_t;
+
+/**
+ * Current state of all the pools. Use access functions
+ * instead of using it directly.
+ */
+extern cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+
+/**
+ * Return the name of the pool
+ *
+ * @pool:   Pool to get the name of
+ * Returns The name
+ */
+static inline const char *cvmx_fpa_get_name(uint64_t pool)
+{
+	return cvmx_fpa_pool_info[pool].name;
+}
+
+/**
+ * Return the base of the pool
+ *
+ * @pool:   Pool to get the base of
+ * Returns The base
+ */
+static inline void *cvmx_fpa_get_base(uint64_t pool)
+{
+	return cvmx_fpa_pool_info[pool].base;
+}
+
+/**
+ * Check if a pointer belongs to an FPA pool. Return non-zero
+ * if the supplied pointer is inside the memory controlled by
+ * an FPA pool.
+ *
+ * @pool:   Pool to check
+ * @ptr:    Pointer to check
+ * Returns Non-zero if pointer is in the pool. Zero if not
+ */
+static inline int cvmx_fpa_is_member(uint64_t pool, void *ptr)
+{
+	return ((ptr >= cvmx_fpa_pool_info[pool].base) &&
+		((char *)ptr <
+		 ((char *)(cvmx_fpa_pool_info[pool].base)) +
+		 cvmx_fpa_pool_info[pool].size *
+		 cvmx_fpa_pool_info[pool].starting_element_count));
+}
+
+/**
+ * Enable the FPA for use. Must be performed after any CSR
+ * configuration but before any other FPA functions.
+ */
+static inline void cvmx_fpa_enable(void)
+{
+	union cvmx_fpa_ctl_status status;
+
+	status.u64 = cvmx_read_csr(CVMX_FPA_CTL_STATUS);
+	if (status.s.enb) {
+		cvmx_dprintf
+		    ("Warning: Enabling FPA when FPA already enabled.\n");
+	}
+
+	/*
+	 * Do runtime check as we allow pass1 compiled code to run on
+	 * pass2 chips.
+	 */
+	if (cvmx_octeon_is_pass1()) {
+		union cvmx_fpa_fpfx_marks marks;
+		int i;
+		for (i = 1; i < 8; i++) {
+			marks.u64 =
+			    cvmx_read_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull);
+			marks.s.fpf_wr = 0xe0;
+			cvmx_write_csr(CVMX_FPA_FPF1_MARKS + (i - 1) * 8ull,
+				       marks.u64);
+		}
+
+		/* Enforce a 10 cycle delay between config and enable */
+		cvmx_wait(10);
+	}
+
+	/* FIXME: CVMX_FPA_CTL_STATUS read is unmodelled */
+	status.u64 = 0;
+	status.s.enb = 1;
+	cvmx_write_csr(CVMX_FPA_CTL_STATUS, status.u64);
+}
+
+/**
+ * Get a new block from the FPA
+ *
+ * @pool:   Pool to get the block from
+ * Returns Pointer to the block or NULL on failure
+ */
+static inline void *cvmx_fpa_alloc(uint64_t pool)
+{
+	uint64_t address =
+	    cvmx_read_csr(CVMX_ADDR_DID(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool)));
+	if (address)
+		return cvmx_phys_to_ptr(address);
+	else
+		return NULL;
+}
+
+/**
+ * Asynchronously get a new block from the FPA
+ *
+ * @scr_addr: Local scratch address to put response in.  This is a byte address,
+ *                  but must be 8 byte aligned.
+ * @pool:      Pool to get the block from
+ */
+static inline void cvmx_fpa_async_alloc(uint64_t scr_addr, uint64_t pool)
+{
+	cvmx_fpa_iobdma_data_t data;
+
+	/*
+	 * Hardware only uses 64 bit alligned locations, so convert
+	 * from byte address to 64-bit index
+	 */
+	data.s.scraddr = scr_addr >> 3;
+	data.s.len = 1;
+	data.s.did = CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool);
+	data.s.addr = 0;
+	cvmx_send_single(data.u64);
+}
+
+/**
+ * Free a block allocated with a FPA pool.  Does NOT provide memory
+ * ordering in cases where the memory block was modified by the core.
+ *
+ * @ptr:    Block to free
+ * @pool:   Pool to put it in
+ * @num_cache_lines:
+ *               Cache lines to invalidate
+ */
+static inline void cvmx_fpa_free_nosync(void *ptr, uint64_t pool,
+					uint64_t num_cache_lines)
+{
+	cvmx_addr_t newptr;
+	newptr.u64 = cvmx_ptr_to_phys(ptr);
+	newptr.sfilldidspace.didspace =
+	    CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
+	/* Prevent GCC from reordering around free */
+	barrier();
+	/* value written is number of cache lines not written back */
+	cvmx_write_io(newptr.u64, num_cache_lines);
+}
+
+/**
+ * Free a block allocated with a FPA pool.  Provides required memory
+ * ordering in cases where memory block was modified by core.
+ *
+ * @ptr:    Block to free
+ * @pool:   Pool to put it in
+ * @num_cache_lines:
+ *               Cache lines to invalidate
+ */
+static inline void cvmx_fpa_free(void *ptr, uint64_t pool,
+				 uint64_t num_cache_lines)
+{
+	cvmx_addr_t newptr;
+	newptr.u64 = cvmx_ptr_to_phys(ptr);
+	newptr.sfilldidspace.didspace =
+	    CVMX_ADDR_DIDSPACE(CVMX_FULL_DID(CVMX_OCT_DID_FPA, pool));
+	/*
+	 * Make sure that any previous writes to memory go out before
+	 * we free this buffer.  This also serves as a barrier to
+	 * prevent GCC from reordering operations to after the
+	 * free.
+	 */
+	CVMX_SYNCWS;
+	/* value written is number of cache lines not written back */
+	cvmx_write_io(newptr.u64, num_cache_lines);
+}
+
+/**
+ * Setup a FPA pool to control a new block of memory.
+ * This can only be called once per pool. Make sure proper
+ * locking enforces this.
+ *
+ * @pool:       Pool to initialize
+ *                   0 <= pool < 8
+ * @name:       Constant character string to name this pool.
+ *                   String is not copied.
+ * @buffer:     Pointer to the block of memory to use. This must be
+ *                   accessable by all processors and external hardware.
+ * @block_size: Size for each block controlled by the FPA
+ * @num_blocks: Number of blocks
+ *
+ * Returns 0 on Success,
+ *         -1 on failure
+ */
+extern int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
+			       uint64_t block_size, uint64_t num_blocks);
+
+/**
+ * Shutdown a Memory pool and validate that it had all of
+ * the buffers originally placed in it. This should only be
+ * called by one processor after all hardware has finished
+ * using the pool.
+ *
+ * @pool:   Pool to shutdown
+ * Returns Zero on success
+ *         - Positive is count of missing buffers
+ *         - Negative is too many buffers or corrupted pointers
+ */
+extern uint64_t cvmx_fpa_shutdown_pool(uint64_t pool);
+
+/**
+ * Get the size of blocks controlled by the pool
+ * This is resolved to a constant at compile time.
+ *
+ * @pool:   Pool to access
+ * Returns Size of the block in bytes
+ */
+uint64_t cvmx_fpa_get_block_size(uint64_t pool);
+
+#endif /*  __CVM_FPA_H__ */
diff --git a/drivers/staging/octeon/cvmx-gmxx-defs.h b/drivers/staging/octeon/cvmx-gmxx-defs.h
new file mode 100644
index 0000000..946a43a
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-gmxx-defs.h
@@ -0,0 +1,2529 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_GMXX_DEFS_H__
+#define __CVMX_GMXX_DEFS_H__
+
+#define CVMX_GMXX_BAD_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_BIST(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_CLK_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_HG2_CONTROL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_INF_MODE(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_NXA_ADR(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_IFG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_PASS_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_PRTS(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_PRT_INFO(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_TX_STATUS(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
+#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_SMACX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_STAT_BP(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_BURST(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_CLK(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_BP(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
+#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_CORRUPT(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_HG2_REG1(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_HG2_REG2(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_IFG(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_INT_EN(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_INT_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_JAM(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_LFSR(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_OVR_BP(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_PRTS(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_SPI_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_SPI_MAX(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_gmxx_bad_reg {
+	uint64_t u64;
+	struct cvmx_gmxx_bad_reg_s {
+		uint64_t reserved_31_63:33;
+		uint64_t inb_nxa:4;
+		uint64_t statovr:1;
+		uint64_t loststat:4;
+		uint64_t reserved_18_21:4;
+		uint64_t out_ovr:16;
+		uint64_t ncb_ovr:1;
+		uint64_t out_col:1;
+	} s;
+	struct cvmx_gmxx_bad_reg_cn30xx {
+		uint64_t reserved_31_63:33;
+		uint64_t inb_nxa:4;
+		uint64_t statovr:1;
+		uint64_t reserved_25_25:1;
+		uint64_t loststat:3;
+		uint64_t reserved_5_21:17;
+		uint64_t out_ovr:3;
+		uint64_t reserved_0_1:2;
+	} cn30xx;
+	struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
+	struct cvmx_gmxx_bad_reg_s cn38xx;
+	struct cvmx_gmxx_bad_reg_s cn38xxp2;
+	struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
+	struct cvmx_gmxx_bad_reg_cn52xx {
+		uint64_t reserved_31_63:33;
+		uint64_t inb_nxa:4;
+		uint64_t statovr:1;
+		uint64_t loststat:4;
+		uint64_t reserved_6_21:16;
+		uint64_t out_ovr:4;
+		uint64_t reserved_0_1:2;
+	} cn52xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
+	struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
+	struct cvmx_gmxx_bad_reg_s cn58xx;
+	struct cvmx_gmxx_bad_reg_s cn58xxp1;
+};
+
+union cvmx_gmxx_bist {
+	uint64_t u64;
+	struct cvmx_gmxx_bist_s {
+		uint64_t reserved_17_63:47;
+		uint64_t status:17;
+	} s;
+	struct cvmx_gmxx_bist_cn30xx {
+		uint64_t reserved_10_63:54;
+		uint64_t status:10;
+	} cn30xx;
+	struct cvmx_gmxx_bist_cn30xx cn31xx;
+	struct cvmx_gmxx_bist_cn30xx cn38xx;
+	struct cvmx_gmxx_bist_cn30xx cn38xxp2;
+	struct cvmx_gmxx_bist_cn50xx {
+		uint64_t reserved_12_63:52;
+		uint64_t status:12;
+	} cn50xx;
+	struct cvmx_gmxx_bist_cn52xx {
+		uint64_t reserved_16_63:48;
+		uint64_t status:16;
+	} cn52xx;
+	struct cvmx_gmxx_bist_cn52xx cn52xxp1;
+	struct cvmx_gmxx_bist_cn52xx cn56xx;
+	struct cvmx_gmxx_bist_cn52xx cn56xxp1;
+	struct cvmx_gmxx_bist_s cn58xx;
+	struct cvmx_gmxx_bist_s cn58xxp1;
+};
+
+union cvmx_gmxx_clk_en {
+	uint64_t u64;
+	struct cvmx_gmxx_clk_en_s {
+		uint64_t reserved_1_63:63;
+		uint64_t clk_en:1;
+	} s;
+	struct cvmx_gmxx_clk_en_s cn52xx;
+	struct cvmx_gmxx_clk_en_s cn52xxp1;
+	struct cvmx_gmxx_clk_en_s cn56xx;
+	struct cvmx_gmxx_clk_en_s cn56xxp1;
+};
+
+union cvmx_gmxx_hg2_control {
+	uint64_t u64;
+	struct cvmx_gmxx_hg2_control_s {
+		uint64_t reserved_19_63:45;
+		uint64_t hg2tx_en:1;
+		uint64_t hg2rx_en:1;
+		uint64_t phys_en:1;
+		uint64_t logl_en:16;
+	} s;
+	struct cvmx_gmxx_hg2_control_s cn52xx;
+	struct cvmx_gmxx_hg2_control_s cn52xxp1;
+	struct cvmx_gmxx_hg2_control_s cn56xx;
+};
+
+union cvmx_gmxx_inf_mode {
+	uint64_t u64;
+	struct cvmx_gmxx_inf_mode_s {
+		uint64_t reserved_10_63:54;
+		uint64_t speed:2;
+		uint64_t reserved_6_7:2;
+		uint64_t mode:2;
+		uint64_t reserved_3_3:1;
+		uint64_t p0mii:1;
+		uint64_t en:1;
+		uint64_t type:1;
+	} s;
+	struct cvmx_gmxx_inf_mode_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t p0mii:1;
+		uint64_t en:1;
+		uint64_t type:1;
+	} cn30xx;
+	struct cvmx_gmxx_inf_mode_cn31xx {
+		uint64_t reserved_2_63:62;
+		uint64_t en:1;
+		uint64_t type:1;
+	} cn31xx;
+	struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
+	struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
+	struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
+	struct cvmx_gmxx_inf_mode_cn52xx {
+		uint64_t reserved_10_63:54;
+		uint64_t speed:2;
+		uint64_t reserved_6_7:2;
+		uint64_t mode:2;
+		uint64_t reserved_2_3:2;
+		uint64_t en:1;
+		uint64_t type:1;
+	} cn52xx;
+	struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
+	struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
+	struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
+	struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
+	struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
+};
+
+union cvmx_gmxx_nxa_adr {
+	uint64_t u64;
+	struct cvmx_gmxx_nxa_adr_s {
+		uint64_t reserved_6_63:58;
+		uint64_t prt:6;
+	} s;
+	struct cvmx_gmxx_nxa_adr_s cn30xx;
+	struct cvmx_gmxx_nxa_adr_s cn31xx;
+	struct cvmx_gmxx_nxa_adr_s cn38xx;
+	struct cvmx_gmxx_nxa_adr_s cn38xxp2;
+	struct cvmx_gmxx_nxa_adr_s cn50xx;
+	struct cvmx_gmxx_nxa_adr_s cn52xx;
+	struct cvmx_gmxx_nxa_adr_s cn52xxp1;
+	struct cvmx_gmxx_nxa_adr_s cn56xx;
+	struct cvmx_gmxx_nxa_adr_s cn56xxp1;
+	struct cvmx_gmxx_nxa_adr_s cn58xx;
+	struct cvmx_gmxx_nxa_adr_s cn58xxp1;
+};
+
+union cvmx_gmxx_prtx_cbfc_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s {
+		uint64_t phys_en:16;
+		uint64_t logl_en:16;
+		uint64_t phys_bp:16;
+		uint64_t reserved_4_15:12;
+		uint64_t bck_en:1;
+		uint64_t drp_en:1;
+		uint64_t tx_en:1;
+		uint64_t rx_en:1;
+	} s;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
+};
+
+union cvmx_gmxx_prtx_cfg {
+	uint64_t u64;
+	struct cvmx_gmxx_prtx_cfg_s {
+		uint64_t reserved_14_63:50;
+		uint64_t tx_idle:1;
+		uint64_t rx_idle:1;
+		uint64_t reserved_9_11:3;
+		uint64_t speed_msb:1;
+		uint64_t reserved_4_7:4;
+		uint64_t slottime:1;
+		uint64_t duplex:1;
+		uint64_t speed:1;
+		uint64_t en:1;
+	} s;
+	struct cvmx_gmxx_prtx_cfg_cn30xx {
+		uint64_t reserved_4_63:60;
+		uint64_t slottime:1;
+		uint64_t duplex:1;
+		uint64_t speed:1;
+		uint64_t en:1;
+	} cn30xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
+	struct cvmx_gmxx_prtx_cfg_s cn52xx;
+	struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
+	struct cvmx_gmxx_prtx_cfg_s cn56xx;
+	struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam0 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam0_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam1 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam1_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam2 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam2_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam3 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam3_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam4 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam4_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam5 {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam5_s {
+		uint64_t adr:64;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_cam_en {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam_en_s {
+		uint64_t reserved_8_63:56;
+		uint64_t en:8;
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_adr_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_ctl_s {
+		uint64_t reserved_4_63:60;
+		uint64_t cam_mode:1;
+		uint64_t mcst:2;
+		uint64_t bcst:1;
+	} s;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn38xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn38xxp2;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn50xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn52xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn52xxp1;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn56xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_decision {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_decision_s {
+		uint64_t reserved_5_63:59;
+		uint64_t cnt:5;
+	} s;
+	struct cvmx_gmxx_rxx_decision_s cn30xx;
+	struct cvmx_gmxx_rxx_decision_s cn31xx;
+	struct cvmx_gmxx_rxx_decision_s cn38xx;
+	struct cvmx_gmxx_rxx_decision_s cn38xxp2;
+	struct cvmx_gmxx_rxx_decision_s cn50xx;
+	struct cvmx_gmxx_rxx_decision_s cn52xx;
+	struct cvmx_gmxx_rxx_decision_s cn52xxp1;
+	struct cvmx_gmxx_rxx_decision_s cn56xx;
+	struct cvmx_gmxx_rxx_decision_s cn56xxp1;
+	struct cvmx_gmxx_rxx_decision_s cn58xx;
+	struct cvmx_gmxx_rxx_decision_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_frm_chk {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_frm_chk_s {
+		uint64_t reserved_10_63:54;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
+	struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
+	struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
+	struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
+	struct cvmx_gmxx_rxx_frm_chk_cn50xx {
+		uint64_t reserved_10_63:54;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn50xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn52xx {
+		uint64_t reserved_9_63:55;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn52xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
+	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
+	struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
+	struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_frm_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_frm_ctl_s {
+		uint64_t reserved_11_63:53;
+		uint64_t null_dis:1;
+		uint64_t pre_align:1;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} s;
+	struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
+		uint64_t reserved_9_63:55;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} cn30xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
+		uint64_t reserved_8_63:56;
+		uint64_t vlan_len:1;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} cn31xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
+	struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
+		uint64_t reserved_11_63:53;
+		uint64_t null_dis:1;
+		uint64_t pre_align:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} cn50xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
+	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
+		uint64_t reserved_10_63:54;
+		uint64_t pre_align:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+	} cn56xxp1;
+	struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_frm_max {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_frm_max_s {
+		uint64_t reserved_16_63:48;
+		uint64_t len:16;
+	} s;
+	struct cvmx_gmxx_rxx_frm_max_s cn30xx;
+	struct cvmx_gmxx_rxx_frm_max_s cn31xx;
+	struct cvmx_gmxx_rxx_frm_max_s cn38xx;
+	struct cvmx_gmxx_rxx_frm_max_s cn38xxp2;
+	struct cvmx_gmxx_rxx_frm_max_s cn58xx;
+	struct cvmx_gmxx_rxx_frm_max_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_frm_min {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_frm_min_s {
+		uint64_t reserved_16_63:48;
+		uint64_t len:16;
+	} s;
+	struct cvmx_gmxx_rxx_frm_min_s cn30xx;
+	struct cvmx_gmxx_rxx_frm_min_s cn31xx;
+	struct cvmx_gmxx_rxx_frm_min_s cn38xx;
+	struct cvmx_gmxx_rxx_frm_min_s cn38xxp2;
+	struct cvmx_gmxx_rxx_frm_min_s cn58xx;
+	struct cvmx_gmxx_rxx_frm_min_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_ifg {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_ifg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t ifg:4;
+	} s;
+	struct cvmx_gmxx_rxx_ifg_s cn30xx;
+	struct cvmx_gmxx_rxx_ifg_s cn31xx;
+	struct cvmx_gmxx_rxx_ifg_s cn38xx;
+	struct cvmx_gmxx_rxx_ifg_s cn38xxp2;
+	struct cvmx_gmxx_rxx_ifg_s cn50xx;
+	struct cvmx_gmxx_rxx_ifg_s cn52xx;
+	struct cvmx_gmxx_rxx_ifg_s cn52xxp1;
+	struct cvmx_gmxx_rxx_ifg_s cn56xx;
+	struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
+	struct cvmx_gmxx_rxx_ifg_s cn58xx;
+	struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_int_en {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_int_en_s {
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_gmxx_rxx_int_en_cn30xx {
+		uint64_t reserved_19_63:45;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} cn30xx;
+	struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
+	struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
+	struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
+	struct cvmx_gmxx_rxx_int_en_cn50xx {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn50xx;
+	struct cvmx_gmxx_rxx_int_en_cn52xx {
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn52xx;
+	struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
+	struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
+	struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
+		uint64_t reserved_27_63:37;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn56xxp1;
+	struct cvmx_gmxx_rxx_int_en_cn58xx {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} cn58xx;
+	struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_int_reg {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_int_reg_s {
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} s;
+	struct cvmx_gmxx_rxx_int_reg_cn30xx {
+		uint64_t reserved_19_63:45;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} cn30xx;
+	struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
+	struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
+	struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
+	struct cvmx_gmxx_rxx_int_reg_cn50xx {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn50xx;
+	struct cvmx_gmxx_rxx_int_reg_cn52xx {
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn52xx;
+	struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
+	struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
+	struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
+		uint64_t reserved_27_63:37;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t reserved_0_0:1;
+	} cn56xxp1;
+	struct cvmx_gmxx_rxx_int_reg_cn58xx {
+		uint64_t reserved_20_63:44;
+		uint64_t pause_drp:1;
+		uint64_t phy_dupx:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_link:1;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t niberr:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t lenerr:1;
+		uint64_t alnerr:1;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t maxerr:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+	} cn58xx;
+	struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_jabber {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_jabber_s {
+		uint64_t reserved_16_63:48;
+		uint64_t cnt:16;
+	} s;
+	struct cvmx_gmxx_rxx_jabber_s cn30xx;
+	struct cvmx_gmxx_rxx_jabber_s cn31xx;
+	struct cvmx_gmxx_rxx_jabber_s cn38xx;
+	struct cvmx_gmxx_rxx_jabber_s cn38xxp2;
+	struct cvmx_gmxx_rxx_jabber_s cn50xx;
+	struct cvmx_gmxx_rxx_jabber_s cn52xx;
+	struct cvmx_gmxx_rxx_jabber_s cn52xxp1;
+	struct cvmx_gmxx_rxx_jabber_s cn56xx;
+	struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
+	struct cvmx_gmxx_rxx_jabber_s cn58xx;
+	struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_pause_drop_time {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_pause_drop_time_s {
+		uint64_t reserved_16_63:48;
+		uint64_t status:16;
+	} s;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn52xxp1;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn56xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_rx_inbnd {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_rx_inbnd_s {
+		uint64_t reserved_4_63:60;
+		uint64_t duplex:1;
+		uint64_t speed:2;
+		uint64_t status:1;
+	} s;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn38xx;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn38xxp2;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn50xx;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn58xx;
+	struct cvmx_gmxx_rxx_rx_inbnd_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rd_clr:1;
+	} s;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_octs {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_octs_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_octs_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_octs_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_octs_dmac {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_octs_drp {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s {
+		uint64_t reserved_48_63:16;
+		uint64_t cnt:48;
+	} s;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_pkts {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_pkts_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_pkts_bad {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_pkts_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_pkts_dmac {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_stats_pkts_drp {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn38xxp2;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn50xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn52xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
+};
+
+union cvmx_gmxx_rxx_udd_skp {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_udd_skp_s {
+		uint64_t reserved_9_63:55;
+		uint64_t fcssel:1;
+		uint64_t reserved_7_7:1;
+		uint64_t len:7;
+	} s;
+	struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn38xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn38xxp2;
+	struct cvmx_gmxx_rxx_udd_skp_s cn50xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn52xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn52xxp1;
+	struct cvmx_gmxx_rxx_udd_skp_s cn56xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
+	struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_bp_dropx {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_bp_dropx_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mark:6;
+	} s;
+	struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn38xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn38xxp2;
+	struct cvmx_gmxx_rx_bp_dropx_s cn50xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn52xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn52xxp1;
+	struct cvmx_gmxx_rx_bp_dropx_s cn56xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
+	struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_bp_offx {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_bp_offx_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mark:6;
+	} s;
+	struct cvmx_gmxx_rx_bp_offx_s cn30xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn31xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn38xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn38xxp2;
+	struct cvmx_gmxx_rx_bp_offx_s cn50xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn52xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn52xxp1;
+	struct cvmx_gmxx_rx_bp_offx_s cn56xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
+	struct cvmx_gmxx_rx_bp_offx_s cn58xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_bp_onx {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_bp_onx_s {
+		uint64_t reserved_9_63:55;
+		uint64_t mark:9;
+	} s;
+	struct cvmx_gmxx_rx_bp_onx_s cn30xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn31xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn38xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
+	struct cvmx_gmxx_rx_bp_onx_s cn50xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn52xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
+	struct cvmx_gmxx_rx_bp_onx_s cn56xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
+	struct cvmx_gmxx_rx_bp_onx_s cn58xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_hg2_status {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_hg2_status_s {
+		uint64_t reserved_48_63:16;
+		uint64_t phtim2go:16;
+		uint64_t xof:16;
+		uint64_t lgtim2go:16;
+	} s;
+	struct cvmx_gmxx_rx_hg2_status_s cn52xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
+	struct cvmx_gmxx_rx_hg2_status_s cn56xx;
+};
+
+union cvmx_gmxx_rx_pass_en {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_pass_en_s {
+		uint64_t reserved_16_63:48;
+		uint64_t en:16;
+	} s;
+	struct cvmx_gmxx_rx_pass_en_s cn38xx;
+	struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
+	struct cvmx_gmxx_rx_pass_en_s cn58xx;
+	struct cvmx_gmxx_rx_pass_en_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_pass_mapx {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_pass_mapx_s {
+		uint64_t reserved_4_63:60;
+		uint64_t dprt:4;
+	} s;
+	struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
+	struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
+	struct cvmx_gmxx_rx_pass_mapx_s cn58xx;
+	struct cvmx_gmxx_rx_pass_mapx_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_prt_info {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_prt_info_s {
+		uint64_t reserved_32_63:32;
+		uint64_t drop:16;
+		uint64_t commit:16;
+	} s;
+	struct cvmx_gmxx_rx_prt_info_cn30xx {
+		uint64_t reserved_19_63:45;
+		uint64_t drop:3;
+		uint64_t reserved_3_15:13;
+		uint64_t commit:3;
+	} cn30xx;
+	struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
+	struct cvmx_gmxx_rx_prt_info_s cn38xx;
+	struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx {
+		uint64_t reserved_20_63:44;
+		uint64_t drop:4;
+		uint64_t reserved_4_15:12;
+		uint64_t commit:4;
+	} cn52xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
+	struct cvmx_gmxx_rx_prt_info_s cn58xx;
+	struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_prts {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_prts_s {
+		uint64_t reserved_3_63:61;
+		uint64_t prts:3;
+	} s;
+	struct cvmx_gmxx_rx_prts_s cn30xx;
+	struct cvmx_gmxx_rx_prts_s cn31xx;
+	struct cvmx_gmxx_rx_prts_s cn38xx;
+	struct cvmx_gmxx_rx_prts_s cn38xxp2;
+	struct cvmx_gmxx_rx_prts_s cn50xx;
+	struct cvmx_gmxx_rx_prts_s cn52xx;
+	struct cvmx_gmxx_rx_prts_s cn52xxp1;
+	struct cvmx_gmxx_rx_prts_s cn56xx;
+	struct cvmx_gmxx_rx_prts_s cn56xxp1;
+	struct cvmx_gmxx_rx_prts_s cn58xx;
+	struct cvmx_gmxx_rx_prts_s cn58xxp1;
+};
+
+union cvmx_gmxx_rx_tx_status {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_tx_status_s {
+		uint64_t reserved_7_63:57;
+		uint64_t tx:3;
+		uint64_t reserved_3_3:1;
+		uint64_t rx:3;
+	} s;
+	struct cvmx_gmxx_rx_tx_status_s cn30xx;
+	struct cvmx_gmxx_rx_tx_status_s cn31xx;
+	struct cvmx_gmxx_rx_tx_status_s cn50xx;
+};
+
+union cvmx_gmxx_rx_xaui_bad_col {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_xaui_bad_col_s {
+		uint64_t reserved_40_63:24;
+		uint64_t val:1;
+		uint64_t state:3;
+		uint64_t lane_rxc:4;
+		uint64_t lane_rxd:32;
+	} s;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
+};
+
+union cvmx_gmxx_rx_xaui_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rx_xaui_ctl_s {
+		uint64_t reserved_2_63:62;
+		uint64_t status:2;
+	} s;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
+};
+
+union cvmx_gmxx_smacx {
+	uint64_t u64;
+	struct cvmx_gmxx_smacx_s {
+		uint64_t reserved_48_63:16;
+		uint64_t smac:48;
+	} s;
+	struct cvmx_gmxx_smacx_s cn30xx;
+	struct cvmx_gmxx_smacx_s cn31xx;
+	struct cvmx_gmxx_smacx_s cn38xx;
+	struct cvmx_gmxx_smacx_s cn38xxp2;
+	struct cvmx_gmxx_smacx_s cn50xx;
+	struct cvmx_gmxx_smacx_s cn52xx;
+	struct cvmx_gmxx_smacx_s cn52xxp1;
+	struct cvmx_gmxx_smacx_s cn56xx;
+	struct cvmx_gmxx_smacx_s cn56xxp1;
+	struct cvmx_gmxx_smacx_s cn58xx;
+	struct cvmx_gmxx_smacx_s cn58xxp1;
+};
+
+union cvmx_gmxx_stat_bp {
+	uint64_t u64;
+	struct cvmx_gmxx_stat_bp_s {
+		uint64_t reserved_17_63:47;
+		uint64_t bp:1;
+		uint64_t cnt:16;
+	} s;
+	struct cvmx_gmxx_stat_bp_s cn30xx;
+	struct cvmx_gmxx_stat_bp_s cn31xx;
+	struct cvmx_gmxx_stat_bp_s cn38xx;
+	struct cvmx_gmxx_stat_bp_s cn38xxp2;
+	struct cvmx_gmxx_stat_bp_s cn50xx;
+	struct cvmx_gmxx_stat_bp_s cn52xx;
+	struct cvmx_gmxx_stat_bp_s cn52xxp1;
+	struct cvmx_gmxx_stat_bp_s cn56xx;
+	struct cvmx_gmxx_stat_bp_s cn56xxp1;
+	struct cvmx_gmxx_stat_bp_s cn58xx;
+	struct cvmx_gmxx_stat_bp_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_append {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_append_s {
+		uint64_t reserved_4_63:60;
+		uint64_t force_fcs:1;
+		uint64_t fcs:1;
+		uint64_t pad:1;
+		uint64_t preamble:1;
+	} s;
+	struct cvmx_gmxx_txx_append_s cn30xx;
+	struct cvmx_gmxx_txx_append_s cn31xx;
+	struct cvmx_gmxx_txx_append_s cn38xx;
+	struct cvmx_gmxx_txx_append_s cn38xxp2;
+	struct cvmx_gmxx_txx_append_s cn50xx;
+	struct cvmx_gmxx_txx_append_s cn52xx;
+	struct cvmx_gmxx_txx_append_s cn52xxp1;
+	struct cvmx_gmxx_txx_append_s cn56xx;
+	struct cvmx_gmxx_txx_append_s cn56xxp1;
+	struct cvmx_gmxx_txx_append_s cn58xx;
+	struct cvmx_gmxx_txx_append_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_burst {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_burst_s {
+		uint64_t reserved_16_63:48;
+		uint64_t burst:16;
+	} s;
+	struct cvmx_gmxx_txx_burst_s cn30xx;
+	struct cvmx_gmxx_txx_burst_s cn31xx;
+	struct cvmx_gmxx_txx_burst_s cn38xx;
+	struct cvmx_gmxx_txx_burst_s cn38xxp2;
+	struct cvmx_gmxx_txx_burst_s cn50xx;
+	struct cvmx_gmxx_txx_burst_s cn52xx;
+	struct cvmx_gmxx_txx_burst_s cn52xxp1;
+	struct cvmx_gmxx_txx_burst_s cn56xx;
+	struct cvmx_gmxx_txx_burst_s cn56xxp1;
+	struct cvmx_gmxx_txx_burst_s cn58xx;
+	struct cvmx_gmxx_txx_burst_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_cbfc_xoff {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_cbfc_xoff_s {
+		uint64_t reserved_16_63:48;
+		uint64_t xoff:16;
+	} s;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
+};
+
+union cvmx_gmxx_txx_cbfc_xon {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_cbfc_xon_s {
+		uint64_t reserved_16_63:48;
+		uint64_t xon:16;
+	} s;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
+};
+
+union cvmx_gmxx_txx_clk {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_clk_s {
+		uint64_t reserved_6_63:58;
+		uint64_t clk_cnt:6;
+	} s;
+	struct cvmx_gmxx_txx_clk_s cn30xx;
+	struct cvmx_gmxx_txx_clk_s cn31xx;
+	struct cvmx_gmxx_txx_clk_s cn38xx;
+	struct cvmx_gmxx_txx_clk_s cn38xxp2;
+	struct cvmx_gmxx_txx_clk_s cn50xx;
+	struct cvmx_gmxx_txx_clk_s cn58xx;
+	struct cvmx_gmxx_txx_clk_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_ctl_s {
+		uint64_t reserved_2_63:62;
+		uint64_t xsdef_en:1;
+		uint64_t xscol_en:1;
+	} s;
+	struct cvmx_gmxx_txx_ctl_s cn30xx;
+	struct cvmx_gmxx_txx_ctl_s cn31xx;
+	struct cvmx_gmxx_txx_ctl_s cn38xx;
+	struct cvmx_gmxx_txx_ctl_s cn38xxp2;
+	struct cvmx_gmxx_txx_ctl_s cn50xx;
+	struct cvmx_gmxx_txx_ctl_s cn52xx;
+	struct cvmx_gmxx_txx_ctl_s cn52xxp1;
+	struct cvmx_gmxx_txx_ctl_s cn56xx;
+	struct cvmx_gmxx_txx_ctl_s cn56xxp1;
+	struct cvmx_gmxx_txx_ctl_s cn58xx;
+	struct cvmx_gmxx_txx_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_min_pkt {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_min_pkt_s {
+		uint64_t reserved_8_63:56;
+		uint64_t min_size:8;
+	} s;
+	struct cvmx_gmxx_txx_min_pkt_s cn30xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn31xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn38xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn38xxp2;
+	struct cvmx_gmxx_txx_min_pkt_s cn50xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn52xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn52xxp1;
+	struct cvmx_gmxx_txx_min_pkt_s cn56xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
+	struct cvmx_gmxx_txx_min_pkt_s cn58xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_pause_pkt_interval {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s {
+		uint64_t reserved_16_63:48;
+		uint64_t interval:16;
+	} s;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn38xxp2;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn50xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn52xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_pause_pkt_time {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_pause_pkt_time_s {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} s;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn38xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn38xxp2;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn50xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn52xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn52xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn56xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_pause_togo {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_pause_togo_s {
+		uint64_t reserved_32_63:32;
+		uint64_t msg_time:16;
+		uint64_t time:16;
+	} s;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} cn30xx;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xxp2;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn50xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn52xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn52xxp1;
+	struct cvmx_gmxx_txx_pause_togo_s cn56xx;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
+	struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
+};
+
+union cvmx_gmxx_txx_pause_zero {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_pause_zero_s {
+		uint64_t reserved_1_63:63;
+		uint64_t send:1;
+	} s;
+	struct cvmx_gmxx_txx_pause_zero_s cn30xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn31xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn38xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn38xxp2;
+	struct cvmx_gmxx_txx_pause_zero_s cn50xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn52xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn52xxp1;
+	struct cvmx_gmxx_txx_pause_zero_s cn56xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
+	struct cvmx_gmxx_txx_pause_zero_s cn58xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_sgmii_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_sgmii_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t align:1;
+	} s;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
+};
+
+union cvmx_gmxx_txx_slot {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_slot_s {
+		uint64_t reserved_10_63:54;
+		uint64_t slot:10;
+	} s;
+	struct cvmx_gmxx_txx_slot_s cn30xx;
+	struct cvmx_gmxx_txx_slot_s cn31xx;
+	struct cvmx_gmxx_txx_slot_s cn38xx;
+	struct cvmx_gmxx_txx_slot_s cn38xxp2;
+	struct cvmx_gmxx_txx_slot_s cn50xx;
+	struct cvmx_gmxx_txx_slot_s cn52xx;
+	struct cvmx_gmxx_txx_slot_s cn52xxp1;
+	struct cvmx_gmxx_txx_slot_s cn56xx;
+	struct cvmx_gmxx_txx_slot_s cn56xxp1;
+	struct cvmx_gmxx_txx_slot_s cn58xx;
+	struct cvmx_gmxx_txx_slot_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_soft_pause {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_soft_pause_s {
+		uint64_t reserved_16_63:48;
+		uint64_t time:16;
+	} s;
+	struct cvmx_gmxx_txx_soft_pause_s cn30xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn31xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn38xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn38xxp2;
+	struct cvmx_gmxx_txx_soft_pause_s cn50xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn52xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn52xxp1;
+	struct cvmx_gmxx_txx_soft_pause_s cn56xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
+	struct cvmx_gmxx_txx_soft_pause_s cn58xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat0 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat0_s {
+		uint64_t xsdef:32;
+		uint64_t xscol:32;
+	} s;
+	struct cvmx_gmxx_txx_stat0_s cn30xx;
+	struct cvmx_gmxx_txx_stat0_s cn31xx;
+	struct cvmx_gmxx_txx_stat0_s cn38xx;
+	struct cvmx_gmxx_txx_stat0_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat0_s cn50xx;
+	struct cvmx_gmxx_txx_stat0_s cn52xx;
+	struct cvmx_gmxx_txx_stat0_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat0_s cn56xx;
+	struct cvmx_gmxx_txx_stat0_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat0_s cn58xx;
+	struct cvmx_gmxx_txx_stat0_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat1 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat1_s {
+		uint64_t scol:32;
+		uint64_t mcol:32;
+	} s;
+	struct cvmx_gmxx_txx_stat1_s cn30xx;
+	struct cvmx_gmxx_txx_stat1_s cn31xx;
+	struct cvmx_gmxx_txx_stat1_s cn38xx;
+	struct cvmx_gmxx_txx_stat1_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat1_s cn50xx;
+	struct cvmx_gmxx_txx_stat1_s cn52xx;
+	struct cvmx_gmxx_txx_stat1_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat1_s cn56xx;
+	struct cvmx_gmxx_txx_stat1_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat1_s cn58xx;
+	struct cvmx_gmxx_txx_stat1_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat2 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat2_s {
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+	} s;
+	struct cvmx_gmxx_txx_stat2_s cn30xx;
+	struct cvmx_gmxx_txx_stat2_s cn31xx;
+	struct cvmx_gmxx_txx_stat2_s cn38xx;
+	struct cvmx_gmxx_txx_stat2_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat2_s cn50xx;
+	struct cvmx_gmxx_txx_stat2_s cn52xx;
+	struct cvmx_gmxx_txx_stat2_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat2_s cn56xx;
+	struct cvmx_gmxx_txx_stat2_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat2_s cn58xx;
+	struct cvmx_gmxx_txx_stat2_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat3 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat3_s {
+		uint64_t reserved_32_63:32;
+		uint64_t pkts:32;
+	} s;
+	struct cvmx_gmxx_txx_stat3_s cn30xx;
+	struct cvmx_gmxx_txx_stat3_s cn31xx;
+	struct cvmx_gmxx_txx_stat3_s cn38xx;
+	struct cvmx_gmxx_txx_stat3_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat3_s cn50xx;
+	struct cvmx_gmxx_txx_stat3_s cn52xx;
+	struct cvmx_gmxx_txx_stat3_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat3_s cn56xx;
+	struct cvmx_gmxx_txx_stat3_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat3_s cn58xx;
+	struct cvmx_gmxx_txx_stat3_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat4 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat4_s {
+		uint64_t hist1:32;
+		uint64_t hist0:32;
+	} s;
+	struct cvmx_gmxx_txx_stat4_s cn30xx;
+	struct cvmx_gmxx_txx_stat4_s cn31xx;
+	struct cvmx_gmxx_txx_stat4_s cn38xx;
+	struct cvmx_gmxx_txx_stat4_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat4_s cn50xx;
+	struct cvmx_gmxx_txx_stat4_s cn52xx;
+	struct cvmx_gmxx_txx_stat4_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat4_s cn56xx;
+	struct cvmx_gmxx_txx_stat4_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat4_s cn58xx;
+	struct cvmx_gmxx_txx_stat4_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat5 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat5_s {
+		uint64_t hist3:32;
+		uint64_t hist2:32;
+	} s;
+	struct cvmx_gmxx_txx_stat5_s cn30xx;
+	struct cvmx_gmxx_txx_stat5_s cn31xx;
+	struct cvmx_gmxx_txx_stat5_s cn38xx;
+	struct cvmx_gmxx_txx_stat5_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat5_s cn50xx;
+	struct cvmx_gmxx_txx_stat5_s cn52xx;
+	struct cvmx_gmxx_txx_stat5_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat5_s cn56xx;
+	struct cvmx_gmxx_txx_stat5_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat5_s cn58xx;
+	struct cvmx_gmxx_txx_stat5_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat6 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat6_s {
+		uint64_t hist5:32;
+		uint64_t hist4:32;
+	} s;
+	struct cvmx_gmxx_txx_stat6_s cn30xx;
+	struct cvmx_gmxx_txx_stat6_s cn31xx;
+	struct cvmx_gmxx_txx_stat6_s cn38xx;
+	struct cvmx_gmxx_txx_stat6_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat6_s cn50xx;
+	struct cvmx_gmxx_txx_stat6_s cn52xx;
+	struct cvmx_gmxx_txx_stat6_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat6_s cn56xx;
+	struct cvmx_gmxx_txx_stat6_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat6_s cn58xx;
+	struct cvmx_gmxx_txx_stat6_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat7 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat7_s {
+		uint64_t hist7:32;
+		uint64_t hist6:32;
+	} s;
+	struct cvmx_gmxx_txx_stat7_s cn30xx;
+	struct cvmx_gmxx_txx_stat7_s cn31xx;
+	struct cvmx_gmxx_txx_stat7_s cn38xx;
+	struct cvmx_gmxx_txx_stat7_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat7_s cn50xx;
+	struct cvmx_gmxx_txx_stat7_s cn52xx;
+	struct cvmx_gmxx_txx_stat7_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat7_s cn56xx;
+	struct cvmx_gmxx_txx_stat7_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat7_s cn58xx;
+	struct cvmx_gmxx_txx_stat7_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat8 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat8_s {
+		uint64_t mcst:32;
+		uint64_t bcst:32;
+	} s;
+	struct cvmx_gmxx_txx_stat8_s cn30xx;
+	struct cvmx_gmxx_txx_stat8_s cn31xx;
+	struct cvmx_gmxx_txx_stat8_s cn38xx;
+	struct cvmx_gmxx_txx_stat8_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat8_s cn50xx;
+	struct cvmx_gmxx_txx_stat8_s cn52xx;
+	struct cvmx_gmxx_txx_stat8_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat8_s cn56xx;
+	struct cvmx_gmxx_txx_stat8_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat8_s cn58xx;
+	struct cvmx_gmxx_txx_stat8_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stat9 {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stat9_s {
+		uint64_t undflw:32;
+		uint64_t ctl:32;
+	} s;
+	struct cvmx_gmxx_txx_stat9_s cn30xx;
+	struct cvmx_gmxx_txx_stat9_s cn31xx;
+	struct cvmx_gmxx_txx_stat9_s cn38xx;
+	struct cvmx_gmxx_txx_stat9_s cn38xxp2;
+	struct cvmx_gmxx_txx_stat9_s cn50xx;
+	struct cvmx_gmxx_txx_stat9_s cn52xx;
+	struct cvmx_gmxx_txx_stat9_s cn52xxp1;
+	struct cvmx_gmxx_txx_stat9_s cn56xx;
+	struct cvmx_gmxx_txx_stat9_s cn56xxp1;
+	struct cvmx_gmxx_txx_stat9_s cn58xx;
+	struct cvmx_gmxx_txx_stat9_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_stats_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_stats_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rd_clr:1;
+	} s;
+	struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn38xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn38xxp2;
+	struct cvmx_gmxx_txx_stats_ctl_s cn50xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn52xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn52xxp1;
+	struct cvmx_gmxx_txx_stats_ctl_s cn56xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
+	struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_txx_thresh {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_thresh_s {
+		uint64_t reserved_9_63:55;
+		uint64_t cnt:9;
+	} s;
+	struct cvmx_gmxx_txx_thresh_cn30xx {
+		uint64_t reserved_7_63:57;
+		uint64_t cnt:7;
+	} cn30xx;
+	struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
+	struct cvmx_gmxx_txx_thresh_s cn38xx;
+	struct cvmx_gmxx_txx_thresh_s cn38xxp2;
+	struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
+	struct cvmx_gmxx_txx_thresh_s cn52xx;
+	struct cvmx_gmxx_txx_thresh_s cn52xxp1;
+	struct cvmx_gmxx_txx_thresh_s cn56xx;
+	struct cvmx_gmxx_txx_thresh_s cn56xxp1;
+	struct cvmx_gmxx_txx_thresh_s cn58xx;
+	struct cvmx_gmxx_txx_thresh_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_bp {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_bp_s {
+		uint64_t reserved_4_63:60;
+		uint64_t bp:4;
+	} s;
+	struct cvmx_gmxx_tx_bp_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t bp:3;
+	} cn30xx;
+	struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
+	struct cvmx_gmxx_tx_bp_s cn38xx;
+	struct cvmx_gmxx_tx_bp_s cn38xxp2;
+	struct cvmx_gmxx_tx_bp_cn30xx cn50xx;
+	struct cvmx_gmxx_tx_bp_s cn52xx;
+	struct cvmx_gmxx_tx_bp_s cn52xxp1;
+	struct cvmx_gmxx_tx_bp_s cn56xx;
+	struct cvmx_gmxx_tx_bp_s cn56xxp1;
+	struct cvmx_gmxx_tx_bp_s cn58xx;
+	struct cvmx_gmxx_tx_bp_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_clk_mskx {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_clk_mskx_s {
+		uint64_t reserved_1_63:63;
+		uint64_t msk:1;
+	} s;
+	struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
+	struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
+};
+
+union cvmx_gmxx_tx_col_attempt {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_col_attempt_s {
+		uint64_t reserved_5_63:59;
+		uint64_t limit:5;
+	} s;
+	struct cvmx_gmxx_tx_col_attempt_s cn30xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn31xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn38xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn38xxp2;
+	struct cvmx_gmxx_tx_col_attempt_s cn50xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn52xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn52xxp1;
+	struct cvmx_gmxx_tx_col_attempt_s cn56xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
+	struct cvmx_gmxx_tx_col_attempt_s cn58xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_corrupt {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_corrupt_s {
+		uint64_t reserved_4_63:60;
+		uint64_t corrupt:4;
+	} s;
+	struct cvmx_gmxx_tx_corrupt_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t corrupt:3;
+	} cn30xx;
+	struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
+	struct cvmx_gmxx_tx_corrupt_s cn38xx;
+	struct cvmx_gmxx_tx_corrupt_s cn38xxp2;
+	struct cvmx_gmxx_tx_corrupt_cn30xx cn50xx;
+	struct cvmx_gmxx_tx_corrupt_s cn52xx;
+	struct cvmx_gmxx_tx_corrupt_s cn52xxp1;
+	struct cvmx_gmxx_tx_corrupt_s cn56xx;
+	struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
+	struct cvmx_gmxx_tx_corrupt_s cn58xx;
+	struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_hg2_reg1 {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_hg2_reg1_s {
+		uint64_t reserved_16_63:48;
+		uint64_t tx_xof:16;
+	} s;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
+};
+
+union cvmx_gmxx_tx_hg2_reg2 {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_hg2_reg2_s {
+		uint64_t reserved_16_63:48;
+		uint64_t tx_xon:16;
+	} s;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
+};
+
+union cvmx_gmxx_tx_ifg {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_ifg_s {
+		uint64_t reserved_8_63:56;
+		uint64_t ifg2:4;
+		uint64_t ifg1:4;
+	} s;
+	struct cvmx_gmxx_tx_ifg_s cn30xx;
+	struct cvmx_gmxx_tx_ifg_s cn31xx;
+	struct cvmx_gmxx_tx_ifg_s cn38xx;
+	struct cvmx_gmxx_tx_ifg_s cn38xxp2;
+	struct cvmx_gmxx_tx_ifg_s cn50xx;
+	struct cvmx_gmxx_tx_ifg_s cn52xx;
+	struct cvmx_gmxx_tx_ifg_s cn52xxp1;
+	struct cvmx_gmxx_tx_ifg_s cn56xx;
+	struct cvmx_gmxx_tx_ifg_s cn56xxp1;
+	struct cvmx_gmxx_tx_ifg_s cn58xx;
+	struct cvmx_gmxx_tx_ifg_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_int_en {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_int_en_s {
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+	} s;
+	struct cvmx_gmxx_tx_int_en_cn30xx {
+		uint64_t reserved_19_63:45;
+		uint64_t late_col:3;
+		uint64_t reserved_15_15:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xscol:3;
+		uint64_t reserved_5_7:3;
+		uint64_t undflw:3;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn30xx;
+	struct cvmx_gmxx_tx_int_en_cn31xx {
+		uint64_t reserved_15_63:49;
+		uint64_t xsdef:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xscol:3;
+		uint64_t reserved_5_7:3;
+		uint64_t undflw:3;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn31xx;
+	struct cvmx_gmxx_tx_int_en_s cn38xx;
+	struct cvmx_gmxx_tx_int_en_cn38xxp2 {
+		uint64_t reserved_16_63:48;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+	} cn38xxp2;
+	struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
+	struct cvmx_gmxx_tx_int_en_cn52xx {
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn52xx;
+	struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
+	struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
+	struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
+	struct cvmx_gmxx_tx_int_en_s cn58xx;
+	struct cvmx_gmxx_tx_int_en_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_int_reg {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_int_reg_s {
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+	} s;
+	struct cvmx_gmxx_tx_int_reg_cn30xx {
+		uint64_t reserved_19_63:45;
+		uint64_t late_col:3;
+		uint64_t reserved_15_15:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xscol:3;
+		uint64_t reserved_5_7:3;
+		uint64_t undflw:3;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn30xx;
+	struct cvmx_gmxx_tx_int_reg_cn31xx {
+		uint64_t reserved_15_63:49;
+		uint64_t xsdef:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xscol:3;
+		uint64_t reserved_5_7:3;
+		uint64_t undflw:3;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn31xx;
+	struct cvmx_gmxx_tx_int_reg_s cn38xx;
+	struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
+		uint64_t reserved_16_63:48;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+	} cn38xxp2;
+	struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
+	struct cvmx_gmxx_tx_int_reg_cn52xx {
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+	} cn52xx;
+	struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
+	struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
+	struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
+	struct cvmx_gmxx_tx_int_reg_s cn58xx;
+	struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_jam {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_jam_s {
+		uint64_t reserved_8_63:56;
+		uint64_t jam:8;
+	} s;
+	struct cvmx_gmxx_tx_jam_s cn30xx;
+	struct cvmx_gmxx_tx_jam_s cn31xx;
+	struct cvmx_gmxx_tx_jam_s cn38xx;
+	struct cvmx_gmxx_tx_jam_s cn38xxp2;
+	struct cvmx_gmxx_tx_jam_s cn50xx;
+	struct cvmx_gmxx_tx_jam_s cn52xx;
+	struct cvmx_gmxx_tx_jam_s cn52xxp1;
+	struct cvmx_gmxx_tx_jam_s cn56xx;
+	struct cvmx_gmxx_tx_jam_s cn56xxp1;
+	struct cvmx_gmxx_tx_jam_s cn58xx;
+	struct cvmx_gmxx_tx_jam_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_lfsr {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_lfsr_s {
+		uint64_t reserved_16_63:48;
+		uint64_t lfsr:16;
+	} s;
+	struct cvmx_gmxx_tx_lfsr_s cn30xx;
+	struct cvmx_gmxx_tx_lfsr_s cn31xx;
+	struct cvmx_gmxx_tx_lfsr_s cn38xx;
+	struct cvmx_gmxx_tx_lfsr_s cn38xxp2;
+	struct cvmx_gmxx_tx_lfsr_s cn50xx;
+	struct cvmx_gmxx_tx_lfsr_s cn52xx;
+	struct cvmx_gmxx_tx_lfsr_s cn52xxp1;
+	struct cvmx_gmxx_tx_lfsr_s cn56xx;
+	struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
+	struct cvmx_gmxx_tx_lfsr_s cn58xx;
+	struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_ovr_bp {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_ovr_bp_s {
+		uint64_t reserved_48_63:16;
+		uint64_t tx_prt_bp:16;
+		uint64_t reserved_12_31:20;
+		uint64_t en:4;
+		uint64_t bp:4;
+		uint64_t ign_full:4;
+	} s;
+	struct cvmx_gmxx_tx_ovr_bp_cn30xx {
+		uint64_t reserved_11_63:53;
+		uint64_t en:3;
+		uint64_t reserved_7_7:1;
+		uint64_t bp:3;
+		uint64_t reserved_3_3:1;
+		uint64_t ign_full:3;
+	} cn30xx;
+	struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
+	struct cvmx_gmxx_tx_ovr_bp_cn38xx {
+		uint64_t reserved_12_63:52;
+		uint64_t en:4;
+		uint64_t bp:4;
+		uint64_t ign_full:4;
+	} cn38xx;
+	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
+	struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn52xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn52xxp1;
+	struct cvmx_gmxx_tx_ovr_bp_s cn56xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
+	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
+	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
+};
+
+union cvmx_gmxx_tx_pause_pkt_dmac {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s {
+		uint64_t reserved_48_63:16;
+		uint64_t dmac:48;
+	} s;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn38xxp2;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn50xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn52xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_pause_pkt_type {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_pause_pkt_type_s {
+		uint64_t reserved_16_63:48;
+		uint64_t type:16;
+	} s;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn38xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn38xxp2;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn50xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn52xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn52xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn56xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_prts {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_prts_s {
+		uint64_t reserved_5_63:59;
+		uint64_t prts:5;
+	} s;
+	struct cvmx_gmxx_tx_prts_s cn30xx;
+	struct cvmx_gmxx_tx_prts_s cn31xx;
+	struct cvmx_gmxx_tx_prts_s cn38xx;
+	struct cvmx_gmxx_tx_prts_s cn38xxp2;
+	struct cvmx_gmxx_tx_prts_s cn50xx;
+	struct cvmx_gmxx_tx_prts_s cn52xx;
+	struct cvmx_gmxx_tx_prts_s cn52xxp1;
+	struct cvmx_gmxx_tx_prts_s cn56xx;
+	struct cvmx_gmxx_tx_prts_s cn56xxp1;
+	struct cvmx_gmxx_tx_prts_s cn58xx;
+	struct cvmx_gmxx_tx_prts_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_spi_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_spi_ctl_s {
+		uint64_t reserved_2_63:62;
+		uint64_t tpa_clr:1;
+		uint64_t cont_pkt:1;
+	} s;
+	struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
+	struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
+	struct cvmx_gmxx_tx_spi_ctl_s cn58xx;
+	struct cvmx_gmxx_tx_spi_ctl_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_spi_drain {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_spi_drain_s {
+		uint64_t reserved_16_63:48;
+		uint64_t drain:16;
+	} s;
+	struct cvmx_gmxx_tx_spi_drain_s cn38xx;
+	struct cvmx_gmxx_tx_spi_drain_s cn58xx;
+	struct cvmx_gmxx_tx_spi_drain_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_spi_max {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_spi_max_s {
+		uint64_t reserved_23_63:41;
+		uint64_t slice:7;
+		uint64_t max2:8;
+		uint64_t max1:8;
+	} s;
+	struct cvmx_gmxx_tx_spi_max_cn38xx {
+		uint64_t reserved_16_63:48;
+		uint64_t max2:8;
+		uint64_t max1:8;
+	} cn38xx;
+	struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
+	struct cvmx_gmxx_tx_spi_max_s cn58xx;
+	struct cvmx_gmxx_tx_spi_max_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_spi_roundx {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_spi_roundx_s {
+		uint64_t reserved_16_63:48;
+		uint64_t round:16;
+	} s;
+	struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
+	struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_spi_thresh {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_spi_thresh_s {
+		uint64_t reserved_6_63:58;
+		uint64_t thresh:6;
+	} s;
+	struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
+	struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
+	struct cvmx_gmxx_tx_spi_thresh_s cn58xx;
+	struct cvmx_gmxx_tx_spi_thresh_s cn58xxp1;
+};
+
+union cvmx_gmxx_tx_xaui_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_tx_xaui_ctl_s {
+		uint64_t reserved_11_63:53;
+		uint64_t hg_pause_hgi:2;
+		uint64_t hg_en:1;
+		uint64_t reserved_7_7:1;
+		uint64_t ls_byp:1;
+		uint64_t ls:2;
+		uint64_t reserved_2_3:2;
+		uint64_t uni_en:1;
+		uint64_t dic_en:1;
+	} s;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
+};
+
+union cvmx_gmxx_xaui_ext_loopback {
+	uint64_t u64;
+	struct cvmx_gmxx_xaui_ext_loopback_s {
+		uint64_t reserved_5_63:59;
+		uint64_t en:1;
+		uint64_t thresh:4;
+	} s;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-board.c b/drivers/staging/octeon/cvmx-helper-board.c
new file mode 100644
index 0000000..3085e38
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-board.c
@@ -0,0 +1,706 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Helper functions to abstract board specific data about
+ * network ports from the rest of the cvmx-helper files.
+ */
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-bootinfo.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-mdio.h"
+
+#include "cvmx-helper.h"
+#include "cvmx-helper-util.h"
+#include "cvmx-helper-board.h"
+
+#include "cvmx-gmxx-defs.h"
+#include "cvmx-asxx-defs.h"
+
+/**
+ * cvmx_override_board_link_get(int ipd_port) is a function
+ * pointer. It is meant to allow customization of the process of
+ * talking to a PHY to determine link speed. It is called every
+ * time a PHY must be polled for link status. Users should set
+ * this pointer to a function before calling any cvmx-helper
+ * operations.
+ */
+cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) =
+    NULL;
+
+/**
+ * Return the MII PHY address associated with the given IPD
+ * port. A result of -1 means there isn't a MII capable PHY
+ * connected to this port. On chips supporting multiple MII
+ * busses the bus number is encoded in bits <15:8>.
+ *
+ * This function must be modified for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It replies on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @ipd_port: Octeon IPD port to get the MII address for.
+ *
+ * Returns MII PHY address and bus number or -1.
+ */
+int cvmx_helper_board_get_mii_address(int ipd_port)
+{
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_SIM:
+		/* Simulator doesn't have MII */
+		return -1;
+	case CVMX_BOARD_TYPE_EBT3000:
+	case CVMX_BOARD_TYPE_EBT5800:
+	case CVMX_BOARD_TYPE_THUNDER:
+	case CVMX_BOARD_TYPE_NICPRO2:
+		/* Interface 0 is SPI4, interface 1 is RGMII */
+		if ((ipd_port >= 16) && (ipd_port < 20))
+			return ipd_port - 16;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_KODAMA:
+	case CVMX_BOARD_TYPE_EBH3100:
+	case CVMX_BOARD_TYPE_HIKARI:
+	case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+	case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
+		/*
+		 * Port 0 is WAN connected to a PHY, Port 1 is GMII
+		 * connected to a switch
+		 */
+		if (ipd_port == 0)
+			return 4;
+		else if (ipd_port == 1)
+			return 9;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_NAC38:
+		/* Board has 8 RGMII ports PHYs are 0-7 */
+		if ((ipd_port >= 0) && (ipd_port < 4))
+			return ipd_port;
+		else if ((ipd_port >= 16) && (ipd_port < 20))
+			return ipd_port - 16 + 4;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_EBH3000:
+		/* Board has dual SPI4 and no PHYs */
+		return -1;
+	case CVMX_BOARD_TYPE_EBH5200:
+	case CVMX_BOARD_TYPE_EBH5201:
+	case CVMX_BOARD_TYPE_EBT5200:
+		/*
+		 * Board has 4 SGMII ports. The PHYs start right after the MII
+		 * ports MII0 = 0, MII1 = 1, SGMII = 2-5.
+		 */
+		if ((ipd_port >= 0) && (ipd_port < 4))
+			return ipd_port + 2;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_EBH5600:
+	case CVMX_BOARD_TYPE_EBH5601:
+	case CVMX_BOARD_TYPE_EBH5610:
+		/*
+		 * Board has 8 SGMII ports. 4 connect out, two connect
+		 * to a switch, and 2 loop to each other
+		 */
+		if ((ipd_port >= 0) && (ipd_port < 4))
+			return ipd_port + 1;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_CUST_NB5:
+		if (ipd_port == 2)
+			return 4;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_NIC_XLE_4G:
+		/* Board has 4 SGMII ports. connected QLM3(interface 1) */
+		if ((ipd_port >= 16) && (ipd_port < 20))
+			return ipd_port - 16 + 1;
+		else
+			return -1;
+	case CVMX_BOARD_TYPE_BBGW_REF:
+		/*
+		 * No PHYs are connected to Octeon, everything is
+		 * through switch.
+		 */
+		return -1;
+	}
+
+	/* Some unknown board. Somebody forgot to update this function... */
+	cvmx_dprintf
+	    ("cvmx_helper_board_get_mii_address: Unknown board type %d\n",
+	     cvmx_sysinfo_get()->board_type);
+	return -1;
+}
+
+/**
+ * This function is the board specific method of determining an
+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs
+ * and are handled by the fall through case. This function must be
+ * updated for boards that don't have the normal Marvell PHYs.
+ *
+ * This function must be modified for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It relies on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @ipd_port: IPD input port associated with the port we want to get link
+ *                 status for.
+ *
+ * Returns The ports link status. If the link isn't fully resolved, this must
+ *         return zero.
+ */
+cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port)
+{
+	cvmx_helper_link_info_t result;
+	int phy_addr;
+	int is_broadcom_phy = 0;
+
+	/* Give the user a chance to override the processing of this function */
+	if (cvmx_override_board_link_get)
+		return cvmx_override_board_link_get(ipd_port);
+
+	/* Unless we fix it later, all links are defaulted to down */
+	result.u64 = 0;
+
+	/*
+	 * This switch statement should handle all ports that either don't use
+	 * Marvell PHYS, or don't support in-band status.
+	 */
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_SIM:
+		/* The simulator gives you a simulated 1Gbps full duplex link */
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 1000;
+		return result;
+	case CVMX_BOARD_TYPE_EBH3100:
+	case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
+	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+	case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
+		/* Port 1 on these boards is always Gigabit */
+		if (ipd_port == 1) {
+			result.s.link_up = 1;
+			result.s.full_duplex = 1;
+			result.s.speed = 1000;
+			return result;
+		}
+		/* Fall through to the generic code below */
+		break;
+	case CVMX_BOARD_TYPE_CUST_NB5:
+		/* Port 1 on these boards is always Gigabit */
+		if (ipd_port == 1) {
+			result.s.link_up = 1;
+			result.s.full_duplex = 1;
+			result.s.speed = 1000;
+			return result;
+		} else		/* The other port uses a broadcom PHY */
+			is_broadcom_phy = 1;
+		break;
+	case CVMX_BOARD_TYPE_BBGW_REF:
+		/* Port 1 on these boards is always Gigabit */
+		if (ipd_port == 2) {
+			/* Port 2 is not hooked up */
+			result.u64 = 0;
+			return result;
+		} else {
+			/* Ports 0 and 1 connect to the switch */
+			result.s.link_up = 1;
+			result.s.full_duplex = 1;
+			result.s.speed = 1000;
+			return result;
+		}
+		break;
+	}
+
+	phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
+	if (phy_addr != -1) {
+		if (is_broadcom_phy) {
+			/*
+			 * Below we are going to read SMI/MDIO
+			 * register 0x19 which works on Broadcom
+			 * parts
+			 */
+			int phy_status =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+					   0x19);
+			switch ((phy_status >> 8) & 0x7) {
+			case 0:
+				result.u64 = 0;
+				break;
+			case 1:
+				result.s.link_up = 1;
+				result.s.full_duplex = 0;
+				result.s.speed = 10;
+				break;
+			case 2:
+				result.s.link_up = 1;
+				result.s.full_duplex = 1;
+				result.s.speed = 10;
+				break;
+			case 3:
+				result.s.link_up = 1;
+				result.s.full_duplex = 0;
+				result.s.speed = 100;
+				break;
+			case 4:
+				result.s.link_up = 1;
+				result.s.full_duplex = 1;
+				result.s.speed = 100;
+				break;
+			case 5:
+				result.s.link_up = 1;
+				result.s.full_duplex = 1;
+				result.s.speed = 100;
+				break;
+			case 6:
+				result.s.link_up = 1;
+				result.s.full_duplex = 0;
+				result.s.speed = 1000;
+				break;
+			case 7:
+				result.s.link_up = 1;
+				result.s.full_duplex = 1;
+				result.s.speed = 1000;
+				break;
+			}
+		} else {
+			/*
+			 * This code assumes we are using a Marvell
+			 * Gigabit PHY. All the speed information can
+			 * be read from register 17 in one
+			 * go. Somebody using a different PHY will
+			 * need to handle it above in the board
+			 * specific area.
+			 */
+			int phy_status =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17);
+
+			/*
+			 * If the resolve bit 11 isn't set, see if
+			 * autoneg is turned off (bit 12, reg 0). The
+			 * resolve bit doesn't get set properly when
+			 * autoneg is off, so force it.
+			 */
+			if ((phy_status & (1 << 11)) == 0) {
+				int auto_status =
+				    cvmx_mdio_read(phy_addr >> 8,
+						   phy_addr & 0xff, 0);
+				if ((auto_status & (1 << 12)) == 0)
+					phy_status |= 1 << 11;
+			}
+
+			/*
+			 * Only return a link if the PHY has finished
+			 * auto negotiation and set the resolved bit
+			 * (bit 11)
+			 */
+			if (phy_status & (1 << 11)) {
+				result.s.link_up = 1;
+				result.s.full_duplex = ((phy_status >> 13) & 1);
+				switch ((phy_status >> 14) & 3) {
+				case 0:	/* 10 Mbps */
+					result.s.speed = 10;
+					break;
+				case 1:	/* 100 Mbps */
+					result.s.speed = 100;
+					break;
+				case 2:	/* 1 Gbps */
+					result.s.speed = 1000;
+					break;
+				case 3:	/* Illegal */
+					result.u64 = 0;
+					break;
+				}
+			}
+		}
+	} else if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
+		   || OCTEON_IS_MODEL(OCTEON_CN58XX)
+		   || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		/*
+		 * We don't have a PHY address, so attempt to use
+		 * in-band status. It is really important that boards
+		 * not supporting in-band status never get
+		 * here. Reading broken in-band status tends to do bad
+		 * things
+		 */
+		union cvmx_gmxx_rxx_rx_inbnd inband_status;
+		int interface = cvmx_helper_get_interface_num(ipd_port);
+		int index = cvmx_helper_get_interface_index_num(ipd_port);
+		inband_status.u64 =
+		    cvmx_read_csr(CVMX_GMXX_RXX_RX_INBND(index, interface));
+
+		result.s.link_up = inband_status.s.status;
+		result.s.full_duplex = inband_status.s.duplex;
+		switch (inband_status.s.speed) {
+		case 0:	/* 10 Mbps */
+			result.s.speed = 10;
+			break;
+		case 1:	/* 100 Mbps */
+			result.s.speed = 100;
+			break;
+		case 2:	/* 1 Gbps */
+			result.s.speed = 1000;
+			break;
+		case 3:	/* Illegal */
+			result.u64 = 0;
+			break;
+		}
+	} else {
+		/*
+		 * We don't have a PHY address and we don't have
+		 * in-band status. There is no way to determine the
+		 * link speed. Return down assuming this port isn't
+		 * wired
+		 */
+		result.u64 = 0;
+	}
+
+	/* If link is down, return all fields as zero. */
+	if (!result.s.link_up)
+		result.u64 = 0;
+
+	return result;
+}
+
+/**
+ * This function as a board specific method of changing the PHY
+ * speed, duplex, and auto-negotiation. This programs the PHY and
+ * not Octeon. This can be used to force Octeon's links to
+ * specific settings.
+ *
+ * @phy_addr:  The address of the PHY to program
+ * @enable_autoneg:
+ *                  Non zero if you want to enable auto-negotiation.
+ * @link_info: Link speed to program. If the speed is zero and auto-negotiation
+ *                  is enabled, all possible negotiation speeds are advertised.
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_board_link_set_phy(int phy_addr,
+				   cvmx_helper_board_set_phy_link_flags_types_t
+				   link_flags,
+				   cvmx_helper_link_info_t link_info)
+{
+
+	/* Set the flow control settings based on link_flags */
+	if ((link_flags & set_phy_link_flags_flow_control_mask) !=
+	    set_phy_link_flags_flow_control_dont_touch) {
+		cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
+		reg_autoneg_adver.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
+		reg_autoneg_adver.s.asymmetric_pause =
+		    (link_flags & set_phy_link_flags_flow_control_mask) ==
+		    set_phy_link_flags_flow_control_enable;
+		reg_autoneg_adver.s.pause =
+		    (link_flags & set_phy_link_flags_flow_control_mask) ==
+		    set_phy_link_flags_flow_control_enable;
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
+				reg_autoneg_adver.u16);
+	}
+
+	/* If speed isn't set and autoneg is on advertise all supported modes */
+	if ((link_flags & set_phy_link_flags_autoneg)
+	    && (link_info.s.speed == 0)) {
+		cvmx_mdio_phy_reg_control_t reg_control;
+		cvmx_mdio_phy_reg_status_t reg_status;
+		cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
+		cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
+		cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
+
+		reg_status.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_STATUS);
+		reg_autoneg_adver.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
+		reg_autoneg_adver.s.advert_100base_t4 =
+		    reg_status.s.capable_100base_t4;
+		reg_autoneg_adver.s.advert_10base_tx_full =
+		    reg_status.s.capable_10_full;
+		reg_autoneg_adver.s.advert_10base_tx_half =
+		    reg_status.s.capable_10_half;
+		reg_autoneg_adver.s.advert_100base_tx_full =
+		    reg_status.s.capable_100base_x_full;
+		reg_autoneg_adver.s.advert_100base_tx_half =
+		    reg_status.s.capable_100base_x_half;
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
+				reg_autoneg_adver.u16);
+		if (reg_status.s.capable_extended_status) {
+			reg_extended_status.u16 =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+					   CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
+			reg_control_1000.u16 =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+					   CVMX_MDIO_PHY_REG_CONTROL_1000);
+			reg_control_1000.s.advert_1000base_t_full =
+			    reg_extended_status.s.capable_1000base_t_full;
+			reg_control_1000.s.advert_1000base_t_half =
+			    reg_extended_status.s.capable_1000base_t_half;
+			cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+					CVMX_MDIO_PHY_REG_CONTROL_1000,
+					reg_control_1000.u16);
+		}
+		reg_control.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_CONTROL);
+		reg_control.s.autoneg_enable = 1;
+		reg_control.s.restart_autoneg = 1;
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
+	} else if ((link_flags & set_phy_link_flags_autoneg)) {
+		cvmx_mdio_phy_reg_control_t reg_control;
+		cvmx_mdio_phy_reg_status_t reg_status;
+		cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
+		cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
+		cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
+
+		reg_status.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_STATUS);
+		reg_autoneg_adver.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_AUTONEG_ADVER);
+		reg_autoneg_adver.s.advert_100base_t4 = 0;
+		reg_autoneg_adver.s.advert_10base_tx_full = 0;
+		reg_autoneg_adver.s.advert_10base_tx_half = 0;
+		reg_autoneg_adver.s.advert_100base_tx_full = 0;
+		reg_autoneg_adver.s.advert_100base_tx_half = 0;
+		if (reg_status.s.capable_extended_status) {
+			reg_extended_status.u16 =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+					   CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
+			reg_control_1000.u16 =
+			    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+					   CVMX_MDIO_PHY_REG_CONTROL_1000);
+			reg_control_1000.s.advert_1000base_t_full = 0;
+			reg_control_1000.s.advert_1000base_t_half = 0;
+		}
+		switch (link_info.s.speed) {
+		case 10:
+			reg_autoneg_adver.s.advert_10base_tx_full =
+			    link_info.s.full_duplex;
+			reg_autoneg_adver.s.advert_10base_tx_half =
+			    !link_info.s.full_duplex;
+			break;
+		case 100:
+			reg_autoneg_adver.s.advert_100base_tx_full =
+			    link_info.s.full_duplex;
+			reg_autoneg_adver.s.advert_100base_tx_half =
+			    !link_info.s.full_duplex;
+			break;
+		case 1000:
+			reg_control_1000.s.advert_1000base_t_full =
+			    link_info.s.full_duplex;
+			reg_control_1000.s.advert_1000base_t_half =
+			    !link_info.s.full_duplex;
+			break;
+		}
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_AUTONEG_ADVER,
+				reg_autoneg_adver.u16);
+		if (reg_status.s.capable_extended_status)
+			cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+					CVMX_MDIO_PHY_REG_CONTROL_1000,
+					reg_control_1000.u16);
+		reg_control.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_CONTROL);
+		reg_control.s.autoneg_enable = 1;
+		reg_control.s.restart_autoneg = 1;
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
+	} else {
+		cvmx_mdio_phy_reg_control_t reg_control;
+		reg_control.u16 =
+		    cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
+				   CVMX_MDIO_PHY_REG_CONTROL);
+		reg_control.s.autoneg_enable = 0;
+		reg_control.s.restart_autoneg = 1;
+		reg_control.s.duplex = link_info.s.full_duplex;
+		if (link_info.s.speed == 1000) {
+			reg_control.s.speed_msb = 1;
+			reg_control.s.speed_lsb = 0;
+		} else if (link_info.s.speed == 100) {
+			reg_control.s.speed_msb = 0;
+			reg_control.s.speed_lsb = 1;
+		} else if (link_info.s.speed == 10) {
+			reg_control.s.speed_msb = 0;
+			reg_control.s.speed_lsb = 0;
+		}
+		cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff,
+				CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16);
+	}
+	return 0;
+}
+
+/**
+ * This function is called by cvmx_helper_interface_probe() after it
+ * determines the number of ports Octeon can support on a specific
+ * interface. This function is the per board location to override
+ * this value. It is called with the number of ports Octeon might
+ * support and should return the number of actual ports on the
+ * board.
+ *
+ * This function must be modifed for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It relys on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @interface: Interface to probe
+ * @supported_ports:
+ *                  Number of ports Octeon supports.
+ *
+ * Returns Number of ports the actual board supports. Many times this will
+ *         simple be "support_ports".
+ */
+int __cvmx_helper_board_interface_probe(int interface, int supported_ports)
+{
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
+		if (interface == 0)
+			return 2;
+		break;
+	case CVMX_BOARD_TYPE_BBGW_REF:
+		if (interface == 0)
+			return 2;
+		break;
+	case CVMX_BOARD_TYPE_NIC_XLE_4G:
+		if (interface == 0)
+			return 0;
+		break;
+		/* The 2nd interface on the EBH5600 is connected to the Marvel switch,
+		   which we don't support. Disable ports connected to it */
+	case CVMX_BOARD_TYPE_EBH5600:
+		if (interface == 1)
+			return 0;
+		break;
+	}
+	return supported_ports;
+}
+
+/**
+ * Enable packet input/output from the hardware. This function is
+ * called after by cvmx_helper_packet_hardware_enable() to
+ * perform board specific initialization. For most boards
+ * nothing is needed.
+ *
+ * @interface: Interface to enable
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_board_hardware_enable(int interface)
+{
+	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) {
+		if (interface == 0) {
+			/* Different config for switch port */
+			cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0);
+			cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
+			/*
+			 * Boards with gigabit WAN ports need a
+			 * different setting that is compatible with
+			 * 100 Mbit settings
+			 */
+			cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface),
+				       0xc);
+			cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface),
+				       0xc);
+		}
+	} else if (cvmx_sysinfo_get()->board_type ==
+		   CVMX_BOARD_TYPE_CN3010_EVB_HS5) {
+		/*
+		 * Broadcom PHYs require differnet ASX
+		 * clocks. Unfortunately many boards don't define a
+		 * new board Id and simply mangle the
+		 * CN3010_EVB_HS5
+		 */
+		if (interface == 0) {
+			/*
+			 * Some boards use a hacked up bootloader that
+			 * identifies them as CN3010_EVB_HS5
+			 * evaluation boards.  This leads to all kinds
+			 * of configuration problems.  Detect one
+			 * case, and print warning, while trying to do
+			 * the right thing.
+			 */
+			int phy_addr = cvmx_helper_board_get_mii_address(0);
+			if (phy_addr != -1) {
+				int phy_identifier =
+				    cvmx_mdio_read(phy_addr >> 8,
+						   phy_addr & 0xff, 0x2);
+				/* Is it a Broadcom PHY? */
+				if (phy_identifier == 0x0143) {
+					cvmx_dprintf("\n");
+					cvmx_dprintf("ERROR:\n");
+					cvmx_dprintf
+					    ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n");
+					cvmx_dprintf
+					    ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n");
+					cvmx_dprintf
+					    ("ERROR: All boards require a unique board type to identify them.\n");
+					cvmx_dprintf("ERROR:\n");
+					cvmx_dprintf("\n");
+					cvmx_wait(1000000000);
+					cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX
+						       (0, interface), 5);
+					cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX
+						       (0, interface), 5);
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
+{
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_BBGW_REF:
+		return USB_CLOCK_TYPE_CRYSTAL_12;
+	}
+	return USB_CLOCK_TYPE_REF_48;
+}
+
+int __cvmx_helper_board_usb_get_num_ports(int supported_ports)
+{
+	switch (cvmx_sysinfo_get()->board_type) {
+	case CVMX_BOARD_TYPE_NIC_XLE_4G:
+		return 0;
+	}
+
+	return supported_ports;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-board.h b/drivers/staging/octeon/cvmx-helper-board.h
new file mode 100644
index 0000000..dc20b01
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-board.h
@@ -0,0 +1,180 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Helper functions to abstract board specific data about
+ * network ports from the rest of the cvmx-helper files.
+ *
+ */
+#ifndef __CVMX_HELPER_BOARD_H__
+#define __CVMX_HELPER_BOARD_H__
+
+#include "cvmx-helper.h"
+
+typedef enum {
+	USB_CLOCK_TYPE_REF_12,
+	USB_CLOCK_TYPE_REF_24,
+	USB_CLOCK_TYPE_REF_48,
+	USB_CLOCK_TYPE_CRYSTAL_12,
+} cvmx_helper_board_usb_clock_types_t;
+
+typedef enum {
+	set_phy_link_flags_autoneg = 0x1,
+	set_phy_link_flags_flow_control_dont_touch = 0x0 << 1,
+	set_phy_link_flags_flow_control_enable = 0x1 << 1,
+	set_phy_link_flags_flow_control_disable = 0x2 << 1,
+	set_phy_link_flags_flow_control_mask = 0x3 << 1,	/* Mask for 2 bit wide flow control field */
+} cvmx_helper_board_set_phy_link_flags_types_t;
+
+/**
+ * cvmx_override_board_link_get(int ipd_port) is a function
+ * pointer. It is meant to allow customization of the process of
+ * talking to a PHY to determine link speed. It is called every
+ * time a PHY must be polled for link status. Users should set
+ * this pointer to a function before calling any cvmx-helper
+ * operations.
+ */
+extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port);
+
+/**
+ * Return the MII PHY address associated with the given IPD
+ * port. A result of -1 means there isn't a MII capable PHY
+ * connected to this port. On chips supporting multiple MII
+ * busses the bus number is encoded in bits <15:8>.
+ *
+ * This function must be modifed for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It relys on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @ipd_port: Octeon IPD port to get the MII address for.
+ *
+ * Returns MII PHY address and bus number or -1.
+ */
+extern int cvmx_helper_board_get_mii_address(int ipd_port);
+
+/**
+ * This function as a board specific method of changing the PHY
+ * speed, duplex, and autonegotiation. This programs the PHY and
+ * not Octeon. This can be used to force Octeon's links to
+ * specific settings.
+ *
+ * @phy_addr:  The address of the PHY to program
+ * @link_flags:
+ *                  Flags to control autonegotiation.  Bit 0 is autonegotiation
+ *                  enable/disable to maintain backware compatability.
+ * @link_info: Link speed to program. If the speed is zero and autonegotiation
+ *                  is enabled, all possible negotiation speeds are advertised.
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_board_link_set_phy(int phy_addr,
+				   cvmx_helper_board_set_phy_link_flags_types_t
+				   link_flags,
+				   cvmx_helper_link_info_t link_info);
+
+/**
+ * This function is the board specific method of determining an
+ * ethernet ports link speed. Most Octeon boards have Marvell PHYs
+ * and are handled by the fall through case. This function must be
+ * updated for boards that don't have the normal Marvell PHYs.
+ *
+ * This function must be modifed for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It relys on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @ipd_port: IPD input port associated with the port we want to get link
+ *                 status for.
+ *
+ * Returns The ports link status. If the link isn't fully resolved, this must
+ *         return zero.
+ */
+extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port);
+
+/**
+ * This function is called by cvmx_helper_interface_probe() after it
+ * determines the number of ports Octeon can support on a specific
+ * interface. This function is the per board location to override
+ * this value. It is called with the number of ports Octeon might
+ * support and should return the number of actual ports on the
+ * board.
+ *
+ * This function must be modifed for every new Octeon board.
+ * Internally it uses switch statements based on the cvmx_sysinfo
+ * data to determine board types and revisions. It relys on the
+ * fact that every Octeon board receives a unique board type
+ * enumeration from the bootloader.
+ *
+ * @interface: Interface to probe
+ * @supported_ports:
+ *                  Number of ports Octeon supports.
+ *
+ * Returns Number of ports the actual board supports. Many times this will
+ *         simple be "support_ports".
+ */
+extern int __cvmx_helper_board_interface_probe(int interface,
+					       int supported_ports);
+
+/**
+ * Enable packet input/output from the hardware. This function is
+ * called after by cvmx_helper_packet_hardware_enable() to
+ * perform board specific initialization. For most boards
+ * nothing is needed.
+ *
+ * @interface: Interface to enable
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_board_hardware_enable(int interface);
+
+/**
+ * Gets the clock type used for the USB block based on board type.
+ * Used by the USB code for auto configuration of clock type.
+ *
+ * Returns USB clock type enumeration
+ */
+cvmx_helper_board_usb_clock_types_t
+__cvmx_helper_board_usb_get_clock_type(void);
+
+/**
+ * Adjusts the number of available USB ports on Octeon based on board
+ * specifics.
+ *
+ * @supported_ports: expected number of ports based on chip type;
+ *
+ *
+ * Returns number of available usb ports, based on board specifics.
+ *         Return value is supported_ports if function does not
+ *         override.
+ */
+int __cvmx_helper_board_usb_get_num_ports(int supported_ports);
+
+#endif /* __CVMX_HELPER_BOARD_H__ */
diff --git a/drivers/staging/octeon/cvmx-helper-fpa.c b/drivers/staging/octeon/cvmx-helper-fpa.c
new file mode 100644
index 0000000..c239e5f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-fpa.c
@@ -0,0 +1,243 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Helper functions for FPA setup.
+ *
+ */
+#include "executive-config.h"
+#include "cvmx-config.h"
+#include "cvmx.h"
+#include "cvmx-bootmem.h"
+#include "cvmx-fpa.h"
+#include "cvmx-helper-fpa.h"
+
+/**
+ * Allocate memory for and initialize a single FPA pool.
+ *
+ * @pool:    Pool to initialize
+ * @buffer_size:  Size of buffers to allocate in bytes
+ * @buffers: Number of buffers to put in the pool. Zero is allowed
+ * @name:    String name of the pool for debugging purposes
+ * Returns Zero on success, non-zero on failure
+ */
+static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
+					     uint64_t buffers, const char *name)
+{
+	uint64_t current_num;
+	void *memory;
+	uint64_t align = CVMX_CACHE_LINE_SIZE;
+
+	/*
+	 * Align the allocation so that power of 2 size buffers are
+	 * naturally aligned.
+	 */
+	while (align < buffer_size)
+		align = align << 1;
+
+	if (buffers == 0)
+		return 0;
+
+	current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
+	if (current_num) {
+		cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
+			     "Skipping setup.\n",
+		     pool, name, (unsigned long long)current_num);
+		return 0;
+	}
+
+	memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
+	if (memory == NULL) {
+		cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
+			     pool, name);
+		return -1;
+	}
+	cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
+	return 0;
+}
+
+/**
+ * Allocate memory and initialize the FPA pools using memory
+ * from cvmx-bootmem. Specifying zero for the number of
+ * buffers will cause that FPA pool to not be setup. This is
+ * useful if you aren't using some of the hardware and want
+ * to save memory. Use cvmx_helper_initialize_fpa instead of
+ * this function directly.
+ *
+ * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
+ * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
+ * @pip_buffers:
+ *                 Number of packet buffers.
+ * @wqe_pool: Should always be CVMX_FPA_WQE_POOL
+ * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
+ * @wqe_entries:
+ *                 Number of work queue entries
+ * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
+ * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
+ * @pko_buffers:
+ *                 PKO Command buffers. You should at minimum have two per
+ *                 each PKO queue.
+ * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
+ * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
+ * @tim_buffers:
+ *                 TIM ring buffer command queues. At least two per timer bucket
+ *                 is recommened.
+ * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
+ * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
+ * @dfa_buffers:
+ *                 DFA command buffer. A relatively small (32 for example)
+ *                 number should work.
+ * Returns Zero on success, non-zero if out of memory
+ */
+static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
+					int pip_buffers, int wqe_pool,
+					int wqe_size, int wqe_entries,
+					int pko_pool, int pko_size,
+					int pko_buffers, int tim_pool,
+					int tim_size, int tim_buffers,
+					int dfa_pool, int dfa_size,
+					int dfa_buffers)
+{
+	int status;
+
+	cvmx_fpa_enable();
+
+	if ((pip_buffers > 0) && (pip_buffers <= 64))
+		cvmx_dprintf
+		    ("Warning: %d packet buffers may not be enough for hardware"
+		     " prefetch. 65 or more is recommended.\n", pip_buffers);
+
+	if (pip_pool >= 0) {
+		status =
+		    __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
+						      pip_buffers,
+						      "Packet Buffers");
+		if (status)
+			return status;
+	}
+
+	if (wqe_pool >= 0) {
+		status =
+		    __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
+						      wqe_entries,
+						      "Work Queue Entries");
+		if (status)
+			return status;
+	}
+
+	if (pko_pool >= 0) {
+		status =
+		    __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
+						      pko_buffers,
+						      "PKO Command Buffers");
+		if (status)
+			return status;
+	}
+
+	if (tim_pool >= 0) {
+		status =
+		    __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
+						      tim_buffers,
+						      "TIM Command Buffers");
+		if (status)
+			return status;
+	}
+
+	if (dfa_pool >= 0) {
+		status =
+		    __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
+						      dfa_buffers,
+						      "DFA Command Buffers");
+		if (status)
+			return status;
+	}
+
+	return 0;
+}
+
+/**
+ * Allocate memory and initialize the FPA pools using memory
+ * from cvmx-bootmem. Sizes of each element in the pools is
+ * controlled by the cvmx-config.h header file. Specifying
+ * zero for any parameter will cause that FPA pool to not be
+ * setup. This is useful if you aren't using some of the
+ * hardware and want to save memory.
+ *
+ * @packet_buffers:
+ *               Number of packet buffers to allocate
+ * @work_queue_entries:
+ *               Number of work queue entries
+ * @pko_buffers:
+ *               PKO Command buffers. You should at minimum have two per
+ *               each PKO queue.
+ * @tim_buffers:
+ *               TIM ring buffer command queues. At least two per timer bucket
+ *               is recommened.
+ * @dfa_buffers:
+ *               DFA command buffer. A relatively small (32 for example)
+ *               number should work.
+ * Returns Zero on success, non-zero if out of memory
+ */
+int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
+			       int pko_buffers, int tim_buffers,
+			       int dfa_buffers)
+{
+#ifndef CVMX_FPA_PACKET_POOL
+#define CVMX_FPA_PACKET_POOL -1
+#define CVMX_FPA_PACKET_POOL_SIZE 0
+#endif
+#ifndef CVMX_FPA_WQE_POOL
+#define CVMX_FPA_WQE_POOL -1
+#define CVMX_FPA_WQE_POOL_SIZE 0
+#endif
+#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
+#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
+#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
+#endif
+#ifndef CVMX_FPA_TIMER_POOL
+#define CVMX_FPA_TIMER_POOL -1
+#define CVMX_FPA_TIMER_POOL_SIZE 0
+#endif
+#ifndef CVMX_FPA_DFA_POOL
+#define CVMX_FPA_DFA_POOL -1
+#define CVMX_FPA_DFA_POOL_SIZE 0
+#endif
+	return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
+					    CVMX_FPA_PACKET_POOL_SIZE,
+					    packet_buffers, CVMX_FPA_WQE_POOL,
+					    CVMX_FPA_WQE_POOL_SIZE,
+					    work_queue_entries,
+					    CVMX_FPA_OUTPUT_BUFFER_POOL,
+					    CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
+					    pko_buffers, CVMX_FPA_TIMER_POOL,
+					    CVMX_FPA_TIMER_POOL_SIZE,
+					    tim_buffers, CVMX_FPA_DFA_POOL,
+					    CVMX_FPA_DFA_POOL_SIZE,
+					    dfa_buffers);
+}
diff --git a/drivers/staging/octeon/cvmx-helper-fpa.h b/drivers/staging/octeon/cvmx-helper-fpa.h
new file mode 100644
index 0000000..5ff8c93
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-fpa.h
@@ -0,0 +1,64 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Helper functions for FPA setup.
+ *
+ */
+#ifndef __CVMX_HELPER_H_FPA__
+#define __CVMX_HELPER_H_FPA__
+
+/**
+ * Allocate memory and initialize the FPA pools using memory
+ * from cvmx-bootmem. Sizes of each element in the pools is
+ * controlled by the cvmx-config.h header file. Specifying
+ * zero for any parameter will cause that FPA pool to not be
+ * setup. This is useful if you aren't using some of the
+ * hardware and want to save memory.
+ *
+ * @packet_buffers:
+ *               Number of packet buffers to allocate
+ * @work_queue_entries:
+ *               Number of work queue entries
+ * @pko_buffers:
+ *               PKO Command buffers. You should at minimum have two per
+ *               each PKO queue.
+ * @tim_buffers:
+ *               TIM ring buffer command queues. At least two per timer bucket
+ *               is recommened.
+ * @dfa_buffers:
+ *               DFA command buffer. A relatively small (32 for example)
+ *               number should work.
+ * Returns Zero on success, non-zero if out of memory
+ */
+extern int cvmx_helper_initialize_fpa(int packet_buffers,
+				      int work_queue_entries, int pko_buffers,
+				      int tim_buffers, int dfa_buffers);
+
+#endif /* __CVMX_HELPER_H__ */
diff --git a/drivers/staging/octeon/cvmx-helper-loop.c b/drivers/staging/octeon/cvmx-helper-loop.c
new file mode 100644
index 0000000..55a571a
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-loop.c
@@ -0,0 +1,85 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for LOOP initialization, configuration,
+ * and monitoring.
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-helper.h"
+#include "cvmx-pip-defs.h"
+
+/**
+ * Probe a LOOP interface and determine the number of ports
+ * connected to it. The LOOP interface should still be down
+ * after this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+int __cvmx_helper_loop_probe(int interface)
+{
+	union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
+	int num_ports = 4;
+	int port;
+
+	/* We need to disable length checking so packet < 64 bytes and jumbo
+	   frames don't get errors */
+	for (port = 0; port < num_ports; port++) {
+		union cvmx_pip_prt_cfgx port_cfg;
+		int ipd_port = cvmx_helper_get_ipd_port(interface, port);
+		port_cfg.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
+		port_cfg.s.maxerr_en = 0;
+		port_cfg.s.minerr_en = 0;
+		cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_cfg.u64);
+	}
+
+	/* Disable FCS stripping for loopback ports */
+	ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
+	ipd_sub_port_fcs.s.port_bit2 = 0;
+	cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
+	return num_ports;
+}
+
+/**
+ * Bringup and enable a LOOP interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_loop_enable(int interface)
+{
+	/* Do nothing. */
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-loop.h b/drivers/staging/octeon/cvmx-helper-loop.h
new file mode 100644
index 0000000..e646a6c
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-loop.h
@@ -0,0 +1,59 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as published by
+ * the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Functions for LOOP initialization, configuration,
+ * and monitoring.
+ *
+ */
+#ifndef __CVMX_HELPER_LOOP_H__
+#define __CVMX_HELPER_LOOP_H__
+
+/**
+ * Probe a LOOP interface and determine the number of ports
+ * connected to it. The LOOP interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+extern int __cvmx_helper_loop_probe(int interface);
+
+/**
+ * Bringup and enable a LOOP interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_loop_enable(int interface);
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-npi.c b/drivers/staging/octeon/cvmx-helper-npi.c
new file mode 100644
index 0000000..7388a1e
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-npi.c
@@ -0,0 +1,113 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for NPI initialization, configuration,
+ * and monitoring.
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-helper.h"
+
+#include "cvmx-pip-defs.h"
+
+/**
+ * Probe a NPI interface and determine the number of ports
+ * connected to it. The NPI interface should still be down
+ * after this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+int __cvmx_helper_npi_probe(int interface)
+{
+#if CVMX_PKO_QUEUES_PER_PORT_PCI > 0
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
+		return 4;
+	else if (OCTEON_IS_MODEL(OCTEON_CN56XX)
+		 && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X))
+		/* The packet engines didn't exist before pass 2 */
+		return 4;
+	else if (OCTEON_IS_MODEL(OCTEON_CN52XX)
+		 && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X))
+		/* The packet engines didn't exist before pass 2 */
+		return 4;
+#if 0
+	/*
+	 * Technically CN30XX, CN31XX, and CN50XX contain packet
+	 * engines, but nobody ever uses them. Since this is the case,
+	 * we disable them here.
+	 */
+	else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+		 || OCTEON_IS_MODEL(OCTEON_CN50XX))
+		return 2;
+	else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
+		return 1;
+#endif
+#endif
+	return 0;
+}
+
+/**
+ * Bringup and enable a NPI interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_npi_enable(int interface)
+{
+	/*
+	 * On CN50XX, CN52XX, and CN56XX we need to disable length
+	 * checking so packet < 64 bytes and jumbo frames don't get
+	 * errors.
+	 */
+	if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
+	    !OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+		int num_ports = cvmx_helper_ports_on_interface(interface);
+		int port;
+		for (port = 0; port < num_ports; port++) {
+			union cvmx_pip_prt_cfgx port_cfg;
+			int ipd_port =
+			    cvmx_helper_get_ipd_port(interface, port);
+			port_cfg.u64 =
+			    cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
+			port_cfg.s.maxerr_en = 0;
+			port_cfg.s.minerr_en = 0;
+			cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port),
+				       port_cfg.u64);
+		}
+	}
+
+	/* Enables are controlled by the remote host, so nothing to do here */
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-npi.h b/drivers/staging/octeon/cvmx-helper-npi.h
new file mode 100644
index 0000000..908e7b0
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-npi.h
@@ -0,0 +1,60 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Functions for NPI initialization, configuration,
+ * and monitoring.
+ *
+ */
+#ifndef __CVMX_HELPER_NPI_H__
+#define __CVMX_HELPER_NPI_H__
+
+/**
+ * Probe a NPI interface and determine the number of ports
+ * connected to it. The NPI interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+extern int __cvmx_helper_npi_probe(int interface);
+
+/**
+ * Bringup and enable a NPI interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_npi_enable(int interface);
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.c b/drivers/staging/octeon/cvmx-helper-rgmii.c
new file mode 100644
index 0000000..aa2d5d7
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-rgmii.c
@@ -0,0 +1,525 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for RGMII/GMII/MII initialization, configuration,
+ * and monitoring.
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+
+#include "cvmx-mdio.h"
+#include "cvmx-pko.h"
+#include "cvmx-helper.h"
+#include "cvmx-helper-board.h"
+
+#include <asm/octeon/cvmx-npi-defs.h>
+#include "cvmx-gmxx-defs.h"
+#include "cvmx-asxx-defs.h"
+#include "cvmx-dbg-defs.h"
+
+void __cvmx_interrupt_gmxx_enable(int interface);
+void __cvmx_interrupt_asxx_enable(int block);
+
+/**
+ * Probe RGMII ports and determine the number present
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of RGMII/GMII/MII ports (0-4).
+ */
+int __cvmx_helper_rgmii_probe(int interface)
+{
+	int num_ports = 0;
+	union cvmx_gmxx_inf_mode mode;
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+	if (mode.s.type) {
+		if (OCTEON_IS_MODEL(OCTEON_CN38XX)
+		    || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+			cvmx_dprintf("ERROR: RGMII initialize called in "
+				     "SPI interface\n");
+		} else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+			   || OCTEON_IS_MODEL(OCTEON_CN30XX)
+			   || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+			/*
+			 * On these chips "type" says we're in
+			 * GMII/MII mode. This limits us to 2 ports
+			 */
+			num_ports = 2;
+		} else {
+			cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
+				     __func__);
+		}
+	} else {
+		if (OCTEON_IS_MODEL(OCTEON_CN38XX)
+		    || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+			num_ports = 4;
+		} else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+			   || OCTEON_IS_MODEL(OCTEON_CN30XX)
+			   || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+			num_ports = 3;
+		} else {
+			cvmx_dprintf("ERROR: Unsupported Octeon model in %s\n",
+				     __func__);
+		}
+	}
+	return num_ports;
+}
+
+/**
+ * Put an RGMII interface in loopback mode. Internal packets sent
+ * out will be received back again on the same port. Externally
+ * received packets will echo back out.
+ *
+ * @port:   IPD port number to loop.
+ */
+void cvmx_helper_rgmii_internal_loopback(int port)
+{
+	int interface = (port >> 4) & 1;
+	int index = port & 0xf;
+	uint64_t tmp;
+
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	gmx_cfg.u64 = 0;
+	gmx_cfg.s.duplex = 1;
+	gmx_cfg.s.slottime = 1;
+	gmx_cfg.s.speed = 1;
+	cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
+	cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
+	cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+	tmp = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
+	cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), (1 << index) | tmp);
+	tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
+	cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), (1 << index) | tmp);
+	tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), (1 << index) | tmp);
+	gmx_cfg.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+}
+
+/**
+ * Workaround ASX setup errata with CN38XX pass1
+ *
+ * @interface: Interface to setup
+ * @port:      Port to setup (0..3)
+ * @cpu_clock_hz:
+ *                  Chip frequency in Hertz
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_errata_asx_pass1(int interface, int port,
+					  int cpu_clock_hz)
+{
+	/* Set hi water mark as per errata GMX-4 */
+	if (cpu_clock_hz >= 325000000 && cpu_clock_hz < 375000000)
+		cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 12);
+	else if (cpu_clock_hz >= 375000000 && cpu_clock_hz < 437000000)
+		cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 11);
+	else if (cpu_clock_hz >= 437000000 && cpu_clock_hz < 550000000)
+		cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 10);
+	else if (cpu_clock_hz >= 550000000 && cpu_clock_hz < 687000000)
+		cvmx_write_csr(CVMX_ASXX_TX_HI_WATERX(port, interface), 9);
+	else
+		cvmx_dprintf("Illegal clock frequency (%d). "
+			"CVMX_ASXX_TX_HI_WATERX not set\n", cpu_clock_hz);
+	return 0;
+}
+
+/**
+ * Configure all of the ASX, GMX, and PKO regsiters required
+ * to get RGMII to function on the supplied interface.
+ *
+ * @interface: PKO Interface to configure (0 or 1)
+ *
+ * Returns Zero on success
+ */
+int __cvmx_helper_rgmii_enable(int interface)
+{
+	int num_ports = cvmx_helper_ports_on_interface(interface);
+	int port;
+	struct cvmx_sysinfo *sys_info_ptr = cvmx_sysinfo_get();
+	union cvmx_gmxx_inf_mode mode;
+	union cvmx_asxx_tx_prt_en asx_tx;
+	union cvmx_asxx_rx_prt_en asx_rx;
+
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+	if (mode.s.en == 0)
+		return -1;
+	if ((OCTEON_IS_MODEL(OCTEON_CN38XX) ||
+	     OCTEON_IS_MODEL(OCTEON_CN58XX)) && mode.s.type == 1)
+		/* Ignore SPI interfaces */
+		return -1;
+
+	/* Configure the ASX registers needed to use the RGMII ports */
+	asx_tx.u64 = 0;
+	asx_tx.s.prt_en = cvmx_build_mask(num_ports);
+	cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface), asx_tx.u64);
+
+	asx_rx.u64 = 0;
+	asx_rx.s.prt_en = cvmx_build_mask(num_ports);
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface), asx_rx.u64);
+
+	/* Configure the GMX registers needed to use the RGMII ports */
+	for (port = 0; port < num_ports; port++) {
+		/* Setting of CVMX_GMXX_TXX_THRESH has been moved to
+		   __cvmx_helper_setup_gmx() */
+
+		if (cvmx_octeon_is_pass1())
+			__cvmx_helper_errata_asx_pass1(interface, port,
+						       sys_info_ptr->
+						       cpu_clock_hz);
+		else {
+			/*
+			 * Configure more flexible RGMII preamble
+			 * checking. Pass 1 doesn't support this
+			 * feature.
+			 */
+			union cvmx_gmxx_rxx_frm_ctl frm_ctl;
+			frm_ctl.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
+					  (port, interface));
+			/* New field, so must be compile time */
+			frm_ctl.s.pre_free = 1;
+			cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(port, interface),
+				       frm_ctl.u64);
+		}
+
+		/*
+		 * Each pause frame transmitted will ask for about 10M
+		 * bit times before resume.  If buffer space comes
+		 * available before that time has expired, an XON
+		 * pause frame (0 time) will be transmitted to restart
+		 * the flow.
+		 */
+		cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_TIME(port, interface),
+			       20000);
+		cvmx_write_csr(CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL
+			       (port, interface), 19000);
+
+		if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+			cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
+				       16);
+			cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
+				       16);
+		} else {
+			cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, interface),
+				       24);
+			cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, interface),
+				       24);
+		}
+	}
+
+	__cvmx_helper_setup_gmx(interface, num_ports);
+
+	/* enable the ports now */
+	for (port = 0; port < num_ports; port++) {
+		union cvmx_gmxx_prtx_cfg gmx_cfg;
+		cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port
+					  (interface, port));
+		gmx_cfg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface));
+		gmx_cfg.s.en = 1;
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(port, interface),
+			       gmx_cfg.u64);
+	}
+	__cvmx_interrupt_asxx_enable(interface);
+	__cvmx_interrupt_gmxx_enable(interface);
+
+	return 0;
+}
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	union cvmx_asxx_prt_loop asxx_prt_loop;
+
+	asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
+	if (asxx_prt_loop.s.int_loop & (1 << index)) {
+		/* Force 1Gbps full duplex on internal loopback */
+		cvmx_helper_link_info_t result;
+		result.u64 = 0;
+		result.s.full_duplex = 1;
+		result.s.link_up = 1;
+		result.s.speed = 1000;
+		return result;
+	} else
+		return __cvmx_helper_board_link_get(ipd_port);
+}
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_rgmii_link_set(int ipd_port,
+				 cvmx_helper_link_info_t link_info)
+{
+	int result = 0;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	union cvmx_gmxx_prtx_cfg original_gmx_cfg;
+	union cvmx_gmxx_prtx_cfg new_gmx_cfg;
+	union cvmx_pko_mem_queue_qos pko_mem_queue_qos;
+	union cvmx_pko_mem_queue_qos pko_mem_queue_qos_save[16];
+	union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp;
+	union cvmx_gmxx_tx_ovr_bp gmx_tx_ovr_bp_save;
+	int i;
+
+	/* Ignore speed sets in the simulator */
+	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM)
+		return 0;
+
+	/* Read the current settings so we know the current enable state */
+	original_gmx_cfg.u64 =
+	    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	new_gmx_cfg = original_gmx_cfg;
+
+	/* Disable the lowest level RX */
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
+		       cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) &
+				     ~(1 << index));
+
+	/* Disable all queues so that TX should become idle */
+	for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
+		int queue = cvmx_pko_get_base_queue(ipd_port) + i;
+		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
+		pko_mem_queue_qos.u64 = cvmx_read_csr(CVMX_PKO_MEM_QUEUE_QOS);
+		pko_mem_queue_qos.s.pid = ipd_port;
+		pko_mem_queue_qos.s.qid = queue;
+		pko_mem_queue_qos_save[i] = pko_mem_queue_qos;
+		pko_mem_queue_qos.s.qos_mask = 0;
+		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS, pko_mem_queue_qos.u64);
+	}
+
+	/* Disable backpressure */
+	gmx_tx_ovr_bp.u64 = cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
+	gmx_tx_ovr_bp_save = gmx_tx_ovr_bp;
+	gmx_tx_ovr_bp.s.bp &= ~(1 << index);
+	gmx_tx_ovr_bp.s.en |= 1 << index;
+	cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp.u64);
+	cvmx_read_csr(CVMX_GMXX_TX_OVR_BP(interface));
+
+	/*
+	 * Poll the GMX state machine waiting for it to become
+	 * idle. Preferably we should only change speed when it is
+	 * idle. If it doesn't become idle we will still do the speed
+	 * change, but there is a slight chance that GMX will
+	 * lockup.
+	 */
+	cvmx_write_csr(CVMX_NPI_DBG_SELECT,
+		       interface * 0x800 + index * 0x100 + 0x880);
+	CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 7,
+			==, 0, 10000);
+	CVMX_WAIT_FOR_FIELD64(CVMX_DBG_DATA, union cvmx_dbg_data, data & 0xf,
+			==, 0, 10000);
+
+	/* Disable the port before we make any changes */
+	new_gmx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
+	cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+
+	/* Set full/half duplex */
+	if (cvmx_octeon_is_pass1())
+		/* Half duplex is broken for 38XX Pass 1 */
+		new_gmx_cfg.s.duplex = 1;
+	else if (!link_info.s.link_up)
+		/* Force full duplex on down links */
+		new_gmx_cfg.s.duplex = 1;
+	else
+		new_gmx_cfg.s.duplex = link_info.s.full_duplex;
+
+	/* Set the link speed. Anything unknown is set to 1Gbps */
+	if (link_info.s.speed == 10) {
+		new_gmx_cfg.s.slottime = 0;
+		new_gmx_cfg.s.speed = 0;
+	} else if (link_info.s.speed == 100) {
+		new_gmx_cfg.s.slottime = 0;
+		new_gmx_cfg.s.speed = 0;
+	} else {
+		new_gmx_cfg.s.slottime = 1;
+		new_gmx_cfg.s.speed = 1;
+	}
+
+	/* Adjust the clocks */
+	if (link_info.s.speed == 10) {
+		cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 50);
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
+	} else if (link_info.s.speed == 100) {
+		cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 5);
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x40);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
+	} else {
+		cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
+	}
+
+	if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		if ((link_info.s.speed == 10) || (link_info.s.speed == 100)) {
+			union cvmx_gmxx_inf_mode mode;
+			mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+	/*
+	 * Port  .en  .type  .p0mii  Configuration
+	 * ----  ---  -----  ------  -----------------------------------------
+	 *  X      0     X      X    All links are disabled.
+	 *  0      1     X      0    Port 0 is RGMII
+	 *  0      1     X      1    Port 0 is MII
+	 *  1      1     0      X    Ports 1 and 2 are configured as RGMII ports.
+	 *  1      1     1      X    Port 1: GMII/MII; Port 2: disabled. GMII or
+	 *                           MII port is selected by GMX_PRT1_CFG[SPEED].
+	 */
+
+			/* In MII mode, CLK_CNT = 1. */
+			if (((index == 0) && (mode.s.p0mii == 1))
+			    || ((index != 0) && (mode.s.type == 1))) {
+				cvmx_write_csr(CVMX_GMXX_TXX_CLK
+					       (index, interface), 1);
+			}
+		}
+	}
+
+	/* Do a read to make sure all setup stuff is complete */
+	cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+
+	/* Save the new GMX setting without enabling the port */
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
+
+	/* Enable the lowest level RX */
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
+		       cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) | (1 <<
+									index));
+
+	/* Re-enable the TX path */
+	for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
+		int queue = cvmx_pko_get_base_queue(ipd_port) + i;
+		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, queue);
+		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_QOS,
+			       pko_mem_queue_qos_save[i].u64);
+	}
+
+	/* Restore backpressure */
+	cvmx_write_csr(CVMX_GMXX_TX_OVR_BP(interface), gmx_tx_ovr_bp_save.u64);
+
+	/* Restore the GMX enable state. Port config is complete */
+	new_gmx_cfg.s.en = original_gmx_cfg.s.en;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), new_gmx_cfg.u64);
+
+	return result;
+}
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+int __cvmx_helper_rgmii_configure_loopback(int ipd_port, int enable_internal,
+					   int enable_external)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	int original_enable;
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	union cvmx_asxx_prt_loop asxx_prt_loop;
+
+	/* Read the current enable state and save it */
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	original_enable = gmx_cfg.s.en;
+	/* Force port to be disabled */
+	gmx_cfg.s.en = 0;
+	if (enable_internal) {
+		/* Force speed if we're doing internal loopback */
+		gmx_cfg.s.duplex = 1;
+		gmx_cfg.s.slottime = 1;
+		gmx_cfg.s.speed = 1;
+		cvmx_write_csr(CVMX_GMXX_TXX_CLK(index, interface), 1);
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 0x200);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0x2000);
+	}
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+	/* Set the loopback bits */
+	asxx_prt_loop.u64 = cvmx_read_csr(CVMX_ASXX_PRT_LOOP(interface));
+	if (enable_internal)
+		asxx_prt_loop.s.int_loop |= 1 << index;
+	else
+		asxx_prt_loop.s.int_loop &= ~(1 << index);
+	if (enable_external)
+		asxx_prt_loop.s.ext_loop |= 1 << index;
+	else
+		asxx_prt_loop.s.ext_loop &= ~(1 << index);
+	cvmx_write_csr(CVMX_ASXX_PRT_LOOP(interface), asxx_prt_loop.u64);
+
+	/* Force enables in internal loopback */
+	if (enable_internal) {
+		uint64_t tmp;
+		tmp = cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(interface));
+		cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(interface),
+			       (1 << index) | tmp);
+		tmp = cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface));
+		cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(interface),
+			       (1 << index) | tmp);
+		original_enable = 1;
+	}
+
+	/* Restore the enable state */
+	gmx_cfg.s.en = original_enable;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.h b/drivers/staging/octeon/cvmx-helper-rgmii.h
new file mode 100644
index 0000000..ea26526
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-rgmii.h
@@ -0,0 +1,110 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Functions for RGMII/GMII/MII initialization, configuration,
+ * and monitoring.
+ *
+ */
+#ifndef __CVMX_HELPER_RGMII_H__
+#define __CVMX_HELPER_RGMII_H__
+
+/**
+ * Probe RGMII ports and determine the number present
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of RGMII/GMII/MII ports (0-4).
+ */
+extern int __cvmx_helper_rgmii_probe(int interface);
+
+/**
+ * Put an RGMII interface in loopback mode. Internal packets sent
+ * out will be received back again on the same port. Externally
+ * received packets will echo back out.
+ *
+ * @port:   IPD port number to loop.
+ */
+extern void cvmx_helper_rgmii_internal_loopback(int port);
+
+/**
+ * Configure all of the ASX, GMX, and PKO regsiters required
+ * to get RGMII to function on the supplied interface.
+ *
+ * @interface: PKO Interface to configure (0 or 1)
+ *
+ * Returns Zero on success
+ */
+extern int __cvmx_helper_rgmii_enable(int interface);
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+extern cvmx_helper_link_info_t __cvmx_helper_rgmii_link_get(int ipd_port);
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_rgmii_link_set(int ipd_port,
+					cvmx_helper_link_info_t link_info);
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+extern int __cvmx_helper_rgmii_configure_loopback(int ipd_port,
+						  int enable_internal,
+						  int enable_external);
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.c b/drivers/staging/octeon/cvmx-helper-sgmii.c
new file mode 100644
index 0000000..6214e3b
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-sgmii.c
@@ -0,0 +1,550 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for SGMII initialization, configuration,
+ * and monitoring.
+ */
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-mdio.h"
+#include "cvmx-helper.h"
+#include "cvmx-helper-board.h"
+
+#include "cvmx-gmxx-defs.h"
+#include "cvmx-pcsx-defs.h"
+
+void __cvmx_interrupt_gmxx_enable(int interface);
+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
+
+/**
+ * Perform initialization required only once for an SGMII port.
+ *
+ * @interface: Interface to init
+ * @index:     Index of prot on the interface
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_sgmii_hardware_init_one_time(int interface, int index)
+{
+	const uint64_t clock_mhz = cvmx_sysinfo_get()->cpu_clock_hz / 1000000;
+	union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
+	union cvmx_pcsx_linkx_timer_count_reg pcsx_linkx_timer_count_reg;
+	union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
+
+	/* Disable GMX */
+	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmxx_prtx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
+
+	/*
+	 * Write PCS*_LINK*_TIMER_COUNT_REG[COUNT] with the
+	 * appropriate value. 1000BASE-X specifies a 10ms
+	 * interval. SGMII specifies a 1.6ms interval.
+	 */
+	pcs_misc_ctl_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+	pcsx_linkx_timer_count_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface));
+	if (pcs_misc_ctl_reg.s.mode) {
+		/* 1000BASE-X */
+		pcsx_linkx_timer_count_reg.s.count =
+		    (10000ull * clock_mhz) >> 10;
+	} else {
+		/* SGMII */
+		pcsx_linkx_timer_count_reg.s.count =
+		    (1600ull * clock_mhz) >> 10;
+	}
+	cvmx_write_csr(CVMX_PCSX_LINKX_TIMER_COUNT_REG(index, interface),
+		       pcsx_linkx_timer_count_reg.u64);
+
+	/*
+	 * Write the advertisement register to be used as the
+	 * tx_Config_Reg<D15:D0> of the autonegotiation.  In
+	 * 1000BASE-X mode, tx_Config_Reg<D15:D0> is PCS*_AN*_ADV_REG.
+	 * In SGMII PHY mode, tx_Config_Reg<D15:D0> is
+	 * PCS*_SGM*_AN_ADV_REG.  In SGMII MAC mode,
+	 * tx_Config_Reg<D15:D0> is the fixed value 0x4001, so this
+	 * step can be skipped.
+	 */
+	if (pcs_misc_ctl_reg.s.mode) {
+		/* 1000BASE-X */
+		union cvmx_pcsx_anx_adv_reg pcsx_anx_adv_reg;
+		pcsx_anx_adv_reg.u64 =
+		    cvmx_read_csr(CVMX_PCSX_ANX_ADV_REG(index, interface));
+		pcsx_anx_adv_reg.s.rem_flt = 0;
+		pcsx_anx_adv_reg.s.pause = 3;
+		pcsx_anx_adv_reg.s.hfd = 1;
+		pcsx_anx_adv_reg.s.fd = 1;
+		cvmx_write_csr(CVMX_PCSX_ANX_ADV_REG(index, interface),
+			       pcsx_anx_adv_reg.u64);
+	} else {
+		union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
+		pcsx_miscx_ctl_reg.u64 =
+		    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+		if (pcsx_miscx_ctl_reg.s.mac_phy) {
+			/* PHY Mode */
+			union cvmx_pcsx_sgmx_an_adv_reg pcsx_sgmx_an_adv_reg;
+			pcsx_sgmx_an_adv_reg.u64 =
+			    cvmx_read_csr(CVMX_PCSX_SGMX_AN_ADV_REG
+					  (index, interface));
+			pcsx_sgmx_an_adv_reg.s.link = 1;
+			pcsx_sgmx_an_adv_reg.s.dup = 1;
+			pcsx_sgmx_an_adv_reg.s.speed = 2;
+			cvmx_write_csr(CVMX_PCSX_SGMX_AN_ADV_REG
+				       (index, interface),
+				       pcsx_sgmx_an_adv_reg.u64);
+		} else {
+			/* MAC Mode - Nothing to do */
+		}
+	}
+	return 0;
+}
+
+/**
+ * Initialize the SERTES link for the first time or after a loss
+ * of link.
+ *
+ * @interface: Interface to init
+ * @index:     Index of prot on the interface
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_sgmii_hardware_init_link(int interface, int index)
+{
+	union cvmx_pcsx_mrx_control_reg control_reg;
+
+	/*
+	 * Take PCS through a reset sequence.
+	 * PCS*_MR*_CONTROL_REG[PWR_DN] should be cleared to zero.
+	 * Write PCS*_MR*_CONTROL_REG[RESET]=1 (while not changing the
+	 * value of the other PCS*_MR*_CONTROL_REG bits).  Read
+	 * PCS*_MR*_CONTROL_REG[RESET] until it changes value to
+	 * zero.
+	 */
+	control_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
+	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
+		control_reg.s.reset = 1;
+		cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
+			       control_reg.u64);
+		if (CVMX_WAIT_FOR_FIELD64
+		    (CVMX_PCSX_MRX_CONTROL_REG(index, interface),
+		     union cvmx_pcsx_mrx_control_reg, reset, ==, 0, 10000)) {
+			cvmx_dprintf("SGMII%d: Timeout waiting for port %d "
+				     "to finish reset\n",
+			     interface, index);
+			return -1;
+		}
+	}
+
+	/*
+	 * Write PCS*_MR*_CONTROL_REG[RST_AN]=1 to ensure a fresh
+	 * sgmii negotiation starts.
+	 */
+	control_reg.s.rst_an = 1;
+	control_reg.s.an_en = 1;
+	control_reg.s.pwr_dn = 0;
+	cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
+		       control_reg.u64);
+
+	/*
+	 * Wait for PCS*_MR*_STATUS_REG[AN_CPT] to be set, indicating
+	 * that sgmii autonegotiation is complete. In MAC mode this
+	 * isn't an ethernet link, but a link between Octeon and the
+	 * PHY.
+	 */
+	if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
+	    CVMX_WAIT_FOR_FIELD64(CVMX_PCSX_MRX_STATUS_REG(index, interface),
+				  union cvmx_pcsx_mrx_status_reg, an_cpt, ==, 1,
+				  10000)) {
+		/* cvmx_dprintf("SGMII%d: Port %d link timeout\n", interface, index); */
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Configure an SGMII link to the specified speed after the SERTES
+ * link is up.
+ *
+ * @interface: Interface to init
+ * @index:     Index of prot on the interface
+ * @link_info: Link state to configure
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_sgmii_hardware_init_link_speed(int interface,
+							int index,
+							cvmx_helper_link_info_t
+							link_info)
+{
+	int is_enabled;
+	union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
+	union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
+
+	/* Disable GMX before we make any changes. Remember the enable state */
+	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	is_enabled = gmxx_prtx_cfg.s.en;
+	gmxx_prtx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
+
+	/* Wait for GMX to be idle */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_GMXX_PRTX_CFG(index, interface), union cvmx_gmxx_prtx_cfg,
+	     rx_idle, ==, 1, 10000)
+	    || CVMX_WAIT_FOR_FIELD64(CVMX_GMXX_PRTX_CFG(index, interface),
+				     union cvmx_gmxx_prtx_cfg, tx_idle, ==, 1,
+				     10000)) {
+		cvmx_dprintf
+		    ("SGMII%d: Timeout waiting for port %d to be idle\n",
+		     interface, index);
+		return -1;
+	}
+
+	/* Read GMX CFG again to make sure the disable completed */
+	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+
+	/*
+	 * Get the misc control for PCS. We will need to set the
+	 * duplication amount.
+	 */
+	pcsx_miscx_ctl_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+
+	/*
+	 * Use GMXENO to force the link down if the status we get says
+	 * it should be down.
+	 */
+	pcsx_miscx_ctl_reg.s.gmxeno = !link_info.s.link_up;
+
+	/* Only change the duplex setting if the link is up */
+	if (link_info.s.link_up)
+		gmxx_prtx_cfg.s.duplex = link_info.s.full_duplex;
+
+	/* Do speed based setting for GMX */
+	switch (link_info.s.speed) {
+	case 10:
+		gmxx_prtx_cfg.s.speed = 0;
+		gmxx_prtx_cfg.s.speed_msb = 1;
+		gmxx_prtx_cfg.s.slottime = 0;
+		/* Setting from GMX-603 */
+		pcsx_miscx_ctl_reg.s.samp_pt = 25;
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
+		break;
+	case 100:
+		gmxx_prtx_cfg.s.speed = 0;
+		gmxx_prtx_cfg.s.speed_msb = 0;
+		gmxx_prtx_cfg.s.slottime = 0;
+		pcsx_miscx_ctl_reg.s.samp_pt = 0x5;
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 64);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 0);
+		break;
+	case 1000:
+		gmxx_prtx_cfg.s.speed = 1;
+		gmxx_prtx_cfg.s.speed_msb = 0;
+		gmxx_prtx_cfg.s.slottime = 1;
+		pcsx_miscx_ctl_reg.s.samp_pt = 1;
+		cvmx_write_csr(CVMX_GMXX_TXX_SLOT(index, interface), 512);
+		cvmx_write_csr(CVMX_GMXX_TXX_BURST(index, interface), 8192);
+		break;
+	default:
+		break;
+	}
+
+	/* Write the new misc control for PCS */
+	cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
+		       pcsx_miscx_ctl_reg.u64);
+
+	/* Write the new GMX settings with the port still disabled */
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
+
+	/* Read GMX CFG again to make sure the config completed */
+	gmxx_prtx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+
+	/* Restore the enabled / disabled state */
+	gmxx_prtx_cfg.s.en = is_enabled;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmxx_prtx_cfg.u64);
+
+	return 0;
+}
+
+/**
+ * Bring up the SGMII interface to be ready for packet I/O but
+ * leave I/O disabled using the GMX override. This function
+ * follows the bringup documented in 10.6.3 of the manual.
+ *
+ * @interface: Interface to bringup
+ * @num_ports: Number of ports on the interface
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
+{
+	int index;
+
+	__cvmx_helper_setup_gmx(interface, num_ports);
+
+	for (index = 0; index < num_ports; index++) {
+		int ipd_port = cvmx_helper_get_ipd_port(interface, index);
+		__cvmx_helper_sgmii_hardware_init_one_time(interface, index);
+		__cvmx_helper_sgmii_link_set(ipd_port,
+					     __cvmx_helper_sgmii_link_get
+					     (ipd_port));
+
+	}
+
+	return 0;
+}
+
+/**
+ * Probe a SGMII interface and determine the number of ports
+ * connected to it. The SGMII interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+int __cvmx_helper_sgmii_probe(int interface)
+{
+	union cvmx_gmxx_inf_mode mode;
+
+	/*
+	 * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
+	 * interface needs to be enabled before IPD otherwise per port
+	 * backpressure may not work properly
+	 */
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+	mode.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
+	return 4;
+}
+
+/**
+ * Bringup and enable a SGMII interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_sgmii_enable(int interface)
+{
+	int num_ports = cvmx_helper_ports_on_interface(interface);
+	int index;
+
+	__cvmx_helper_sgmii_hardware_init(interface, num_ports);
+
+	for (index = 0; index < num_ports; index++) {
+		union cvmx_gmxx_prtx_cfg gmxx_prtx_cfg;
+		gmxx_prtx_cfg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+		gmxx_prtx_cfg.s.en = 1;
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
+			       gmxx_prtx_cfg.u64);
+		__cvmx_interrupt_pcsx_intx_en_reg_enable(index, interface);
+	}
+	__cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
+	__cvmx_interrupt_gmxx_enable(interface);
+	return 0;
+}
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port)
+{
+	cvmx_helper_link_info_t result;
+	union cvmx_pcsx_miscx_ctl_reg pcs_misc_ctl_reg;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
+
+	result.u64 = 0;
+
+	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
+		/* The simulator gives you a simulated 1Gbps full duplex link */
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 1000;
+		return result;
+	}
+
+	pcsx_mrx_control_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
+	if (pcsx_mrx_control_reg.s.loopbck1) {
+		/* Force 1Gbps full duplex link for internal loopback */
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 1000;
+		return result;
+	}
+
+	pcs_misc_ctl_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+	if (pcs_misc_ctl_reg.s.mode) {
+		/* 1000BASE-X */
+		/* FIXME */
+	} else {
+		union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
+		pcsx_miscx_ctl_reg.u64 =
+		    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+		if (pcsx_miscx_ctl_reg.s.mac_phy) {
+			/* PHY Mode */
+			union cvmx_pcsx_mrx_status_reg pcsx_mrx_status_reg;
+			union cvmx_pcsx_anx_results_reg pcsx_anx_results_reg;
+
+			/*
+			 * Don't bother continuing if the SERTES low
+			 * level link is down
+			 */
+			pcsx_mrx_status_reg.u64 =
+			    cvmx_read_csr(CVMX_PCSX_MRX_STATUS_REG
+					  (index, interface));
+			if (pcsx_mrx_status_reg.s.lnk_st == 0) {
+				if (__cvmx_helper_sgmii_hardware_init_link
+				    (interface, index) != 0)
+					return result;
+			}
+
+			/* Read the autoneg results */
+			pcsx_anx_results_reg.u64 =
+			    cvmx_read_csr(CVMX_PCSX_ANX_RESULTS_REG
+					  (index, interface));
+			if (pcsx_anx_results_reg.s.an_cpt) {
+				/*
+				 * Auto negotiation is complete. Set
+				 * status accordingly.
+				 */
+				result.s.full_duplex =
+				    pcsx_anx_results_reg.s.dup;
+				result.s.link_up =
+				    pcsx_anx_results_reg.s.link_ok;
+				switch (pcsx_anx_results_reg.s.spd) {
+				case 0:
+					result.s.speed = 10;
+					break;
+				case 1:
+					result.s.speed = 100;
+					break;
+				case 2:
+					result.s.speed = 1000;
+					break;
+				default:
+					result.s.speed = 0;
+					result.s.link_up = 0;
+					break;
+				}
+			} else {
+				/*
+				 * Auto negotiation isn't
+				 * complete. Return link down.
+				 */
+				result.s.speed = 0;
+				result.s.link_up = 0;
+			}
+		} else {	/* MAC Mode */
+
+			result = __cvmx_helper_board_link_get(ipd_port);
+		}
+	}
+	return result;
+}
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_sgmii_link_set(int ipd_port,
+				 cvmx_helper_link_info_t link_info)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	__cvmx_helper_sgmii_hardware_init_link(interface, index);
+	return __cvmx_helper_sgmii_hardware_init_link_speed(interface, index,
+							    link_info);
+}
+
+/**
+ * Configure a port for internal and/or external loopback. Internal
+ * loopback causes packets sent by the port to be received by
+ * Octeon. External loopback causes packets received from the wire to
+ * sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+int __cvmx_helper_sgmii_configure_loopback(int ipd_port, int enable_internal,
+					   int enable_external)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	union cvmx_pcsx_mrx_control_reg pcsx_mrx_control_reg;
+	union cvmx_pcsx_miscx_ctl_reg pcsx_miscx_ctl_reg;
+
+	pcsx_mrx_control_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface));
+	pcsx_mrx_control_reg.s.loopbck1 = enable_internal;
+	cvmx_write_csr(CVMX_PCSX_MRX_CONTROL_REG(index, interface),
+		       pcsx_mrx_control_reg.u64);
+
+	pcsx_miscx_ctl_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface));
+	pcsx_miscx_ctl_reg.s.loopbck2 = enable_external;
+	cvmx_write_csr(CVMX_PCSX_MISCX_CTL_REG(index, interface),
+		       pcsx_miscx_ctl_reg.u64);
+
+	__cvmx_helper_sgmii_hardware_init_link(interface, index);
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.h b/drivers/staging/octeon/cvmx-helper-sgmii.h
new file mode 100644
index 0000000..19b48d6
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-sgmii.h
@@ -0,0 +1,104 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Functions for SGMII initialization, configuration,
+ * and monitoring.
+ *
+ */
+#ifndef __CVMX_HELPER_SGMII_H__
+#define __CVMX_HELPER_SGMII_H__
+
+/**
+ * Probe a SGMII interface and determine the number of ports
+ * connected to it. The SGMII interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+extern int __cvmx_helper_sgmii_probe(int interface);
+
+/**
+ * Bringup and enable a SGMII interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_sgmii_enable(int interface);
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+extern cvmx_helper_link_info_t __cvmx_helper_sgmii_link_get(int ipd_port);
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_sgmii_link_set(int ipd_port,
+					cvmx_helper_link_info_t link_info);
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+extern int __cvmx_helper_sgmii_configure_loopback(int ipd_port,
+						  int enable_internal,
+						  int enable_external);
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-spi.c b/drivers/staging/octeon/cvmx-helper-spi.c
new file mode 100644
index 0000000..8ba6c83
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-spi.c
@@ -0,0 +1,195 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+void __cvmx_interrupt_gmxx_enable(int interface);
+void __cvmx_interrupt_spxx_int_msk_enable(int index);
+void __cvmx_interrupt_stxx_int_msk_enable(int index);
+
+/*
+ * Functions for SPI initialization, configuration,
+ * and monitoring.
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+#include "cvmx-spi.h"
+#include "cvmx-helper.h"
+
+#include "cvmx-pip-defs.h"
+#include "cvmx-pko-defs.h"
+
+/*
+ * CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI
+ * initialization routines wait for SPI training. You can override the
+ * value using executive-config.h if necessary.
+ */
+#ifndef CVMX_HELPER_SPI_TIMEOUT
+#define CVMX_HELPER_SPI_TIMEOUT 10
+#endif
+
+/**
+ * Probe a SPI interface and determine the number of ports
+ * connected to it. The SPI interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+int __cvmx_helper_spi_probe(int interface)
+{
+	int num_ports = 0;
+
+	if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
+	    cvmx_spi4000_is_present(interface)) {
+		num_ports = 10;
+	} else {
+		union cvmx_pko_reg_crc_enable enable;
+		num_ports = 16;
+		/*
+		 * Unlike the SPI4000, most SPI devices don't
+		 * automatically put on the L2 CRC. For everything
+		 * except for the SPI4000 have PKO append the L2 CRC
+		 * to the packet.
+		 */
+		enable.u64 = cvmx_read_csr(CVMX_PKO_REG_CRC_ENABLE);
+		enable.s.enable |= 0xffff << (interface * 16);
+		cvmx_write_csr(CVMX_PKO_REG_CRC_ENABLE, enable.u64);
+	}
+	__cvmx_helper_setup_gmx(interface, num_ports);
+	return num_ports;
+}
+
+/**
+ * Bringup and enable a SPI interface. After this call packet I/O
+ * should be fully functional. This is called with IPD enabled but
+ * PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_spi_enable(int interface)
+{
+	/*
+	 * Normally the ethernet L2 CRC is checked and stripped in the
+	 * GMX block.  When you are using SPI, this isn' the case and
+	 * IPD needs to check the L2 CRC.
+	 */
+	int num_ports = cvmx_helper_ports_on_interface(interface);
+	int ipd_port;
+	for (ipd_port = interface * 16; ipd_port < interface * 16 + num_ports;
+	     ipd_port++) {
+		union cvmx_pip_prt_cfgx port_config;
+		port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
+		port_config.s.crc_en = 1;
+		cvmx_write_csr(CVMX_PIP_PRT_CFGX(ipd_port), port_config.u64);
+	}
+
+	if (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) {
+		cvmx_spi_start_interface(interface, CVMX_SPI_MODE_DUPLEX,
+					 CVMX_HELPER_SPI_TIMEOUT, num_ports);
+		if (cvmx_spi4000_is_present(interface))
+			cvmx_spi4000_initialize(interface);
+	}
+	__cvmx_interrupt_spxx_int_msk_enable(interface);
+	__cvmx_interrupt_stxx_int_msk_enable(interface);
+	__cvmx_interrupt_gmxx_enable(interface);
+	return 0;
+}
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port)
+{
+	cvmx_helper_link_info_t result;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+	result.u64 = 0;
+
+	if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_SIM) {
+		/* The simulator gives you a simulated full duplex link */
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 10000;
+	} else if (cvmx_spi4000_is_present(interface)) {
+		union cvmx_gmxx_rxx_rx_inbnd inband =
+		    cvmx_spi4000_check_speed(interface, index);
+		result.s.link_up = inband.s.status;
+		result.s.full_duplex = inband.s.duplex;
+		switch (inband.s.speed) {
+		case 0:	/* 10 Mbps */
+			result.s.speed = 10;
+			break;
+		case 1:	/* 100 Mbps */
+			result.s.speed = 100;
+			break;
+		case 2:	/* 1 Gbps */
+			result.s.speed = 1000;
+			break;
+		case 3:	/* Illegal */
+			result.s.speed = 0;
+			result.s.link_up = 0;
+			break;
+		}
+	} else {
+		/* For generic SPI we can't determine the link, just return some
+		   sane results */
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 10000;
+	}
+	return result;
+}
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_spi_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
+{
+	/* Nothing to do. If we have a SPI4000 then the setup was already performed
+	   by cvmx_spi4000_check_speed(). If not then there isn't any link
+	   info */
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-spi.h b/drivers/staging/octeon/cvmx-helper-spi.h
new file mode 100644
index 0000000..69bac03
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-spi.h
@@ -0,0 +1,84 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for SPI initialization, configuration,
+ * and monitoring.
+ */
+#ifndef __CVMX_HELPER_SPI_H__
+#define __CVMX_HELPER_SPI_H__
+
+/**
+ * Probe a SPI interface and determine the number of ports
+ * connected to it. The SPI interface should still be down after
+ * this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+extern int __cvmx_helper_spi_probe(int interface);
+
+/**
+ * Bringup and enable a SPI interface. After this call packet I/O
+ * should be fully functional. This is called with IPD enabled but
+ * PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_spi_enable(int interface);
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+extern cvmx_helper_link_info_t __cvmx_helper_spi_link_get(int ipd_port);
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_spi_link_set(int ipd_port,
+				      cvmx_helper_link_info_t link_info);
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper-util.c b/drivers/staging/octeon/cvmx-helper-util.c
new file mode 100644
index 0000000..41ef8a4
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-util.c
@@ -0,0 +1,433 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Small helper utilities.
+ */
+#include <linux/kernel.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-fpa.h"
+#include "cvmx-pip.h"
+#include "cvmx-pko.h"
+#include "cvmx-ipd.h"
+#include "cvmx-spi.h"
+
+#include "cvmx-helper.h"
+#include "cvmx-helper-util.h"
+
+#include <asm/octeon/cvmx-ipd-defs.h>
+
+/**
+ * Convert a interface mode into a human readable string
+ *
+ * @mode:   Mode to convert
+ *
+ * Returns String
+ */
+const char *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t
+						 mode)
+{
+	switch (mode) {
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+		return "DISABLED";
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+		return "RGMII";
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		return "GMII";
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+		return "SPI";
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		return "PCIE";
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		return "XAUI";
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+		return "SGMII";
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		return "PICMG";
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+		return "NPI";
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		return "LOOP";
+	}
+	return "UNKNOWN";
+}
+
+/**
+ * Debug routine to dump the packet structure to the console
+ *
+ * @work:   Work queue entry containing the packet to dump
+ * Returns
+ */
+int cvmx_helper_dump_packet(cvmx_wqe_t *work)
+{
+	uint64_t count;
+	uint64_t remaining_bytes;
+	union cvmx_buf_ptr buffer_ptr;
+	uint64_t start_of_buffer;
+	uint8_t *data_address;
+	uint8_t *end_of_data;
+
+	cvmx_dprintf("Packet Length:   %u\n", work->len);
+	cvmx_dprintf("    Input Port:  %u\n", work->ipprt);
+	cvmx_dprintf("    QoS:         %u\n", work->qos);
+	cvmx_dprintf("    Buffers:     %u\n", work->word2.s.bufs);
+
+	if (work->word2.s.bufs == 0) {
+		union cvmx_ipd_wqe_fpa_queue wqe_pool;
+		wqe_pool.u64 = cvmx_read_csr(CVMX_IPD_WQE_FPA_QUEUE);
+		buffer_ptr.u64 = 0;
+		buffer_ptr.s.pool = wqe_pool.s.wqe_pool;
+		buffer_ptr.s.size = 128;
+		buffer_ptr.s.addr = cvmx_ptr_to_phys(work->packet_data);
+		if (likely(!work->word2.s.not_IP)) {
+			union cvmx_pip_ip_offset pip_ip_offset;
+			pip_ip_offset.u64 = cvmx_read_csr(CVMX_PIP_IP_OFFSET);
+			buffer_ptr.s.addr +=
+			    (pip_ip_offset.s.offset << 3) -
+			    work->word2.s.ip_offset;
+			buffer_ptr.s.addr += (work->word2.s.is_v6 ^ 1) << 2;
+		} else {
+			/*
+			 * WARNING: This code assumes that the packet
+			 * is not RAW. If it was, we would use
+			 * PIP_GBL_CFG[RAW_SHF] instead of
+			 * PIP_GBL_CFG[NIP_SHF].
+			 */
+			union cvmx_pip_gbl_cfg pip_gbl_cfg;
+			pip_gbl_cfg.u64 = cvmx_read_csr(CVMX_PIP_GBL_CFG);
+			buffer_ptr.s.addr += pip_gbl_cfg.s.nip_shf;
+		}
+	} else
+		buffer_ptr = work->packet_ptr;
+	remaining_bytes = work->len;
+
+	while (remaining_bytes) {
+		start_of_buffer =
+		    ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
+		cvmx_dprintf("    Buffer Start:%llx\n",
+			     (unsigned long long)start_of_buffer);
+		cvmx_dprintf("    Buffer I   : %u\n", buffer_ptr.s.i);
+		cvmx_dprintf("    Buffer Back: %u\n", buffer_ptr.s.back);
+		cvmx_dprintf("    Buffer Pool: %u\n", buffer_ptr.s.pool);
+		cvmx_dprintf("    Buffer Data: %llx\n",
+			     (unsigned long long)buffer_ptr.s.addr);
+		cvmx_dprintf("    Buffer Size: %u\n", buffer_ptr.s.size);
+
+		cvmx_dprintf("\t\t");
+		data_address = (uint8_t *) cvmx_phys_to_ptr(buffer_ptr.s.addr);
+		end_of_data = data_address + buffer_ptr.s.size;
+		count = 0;
+		while (data_address < end_of_data) {
+			if (remaining_bytes == 0)
+				break;
+			else
+				remaining_bytes--;
+			cvmx_dprintf("%02x", (unsigned int)*data_address);
+			data_address++;
+			if (remaining_bytes && (count == 7)) {
+				cvmx_dprintf("\n\t\t");
+				count = 0;
+			} else
+				count++;
+		}
+		cvmx_dprintf("\n");
+
+		if (remaining_bytes)
+			buffer_ptr = *(union cvmx_buf_ptr *)
+				cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
+	}
+	return 0;
+}
+
+/**
+ * Setup Random Early Drop on a specific input queue
+ *
+ * @queue:  Input queue to setup RED on (0-7)
+ * @pass_thresh:
+ *               Packets will begin slowly dropping when there are less than
+ *               this many packet buffers free in FPA 0.
+ * @drop_thresh:
+ *               All incomming packets will be dropped when there are less
+ *               than this many free packet buffers in FPA 0.
+ * Returns Zero on success. Negative on failure
+ */
+int cvmx_helper_setup_red_queue(int queue, int pass_thresh, int drop_thresh)
+{
+	union cvmx_ipd_qosx_red_marks red_marks;
+	union cvmx_ipd_red_quex_param red_param;
+
+	/* Set RED to begin dropping packets when there are pass_thresh buffers
+	   left. It will linearly drop more packets until reaching drop_thresh
+	   buffers */
+	red_marks.u64 = 0;
+	red_marks.s.drop = drop_thresh;
+	red_marks.s.pass = pass_thresh;
+	cvmx_write_csr(CVMX_IPD_QOSX_RED_MARKS(queue), red_marks.u64);
+
+	/* Use the actual queue 0 counter, not the average */
+	red_param.u64 = 0;
+	red_param.s.prb_con =
+	    (255ul << 24) / (red_marks.s.pass - red_marks.s.drop);
+	red_param.s.avg_con = 1;
+	red_param.s.new_con = 255;
+	red_param.s.use_pcnt = 1;
+	cvmx_write_csr(CVMX_IPD_RED_QUEX_PARAM(queue), red_param.u64);
+	return 0;
+}
+
+/**
+ * Setup Random Early Drop to automatically begin dropping packets.
+ *
+ * @pass_thresh:
+ *               Packets will begin slowly dropping when there are less than
+ *               this many packet buffers free in FPA 0.
+ * @drop_thresh:
+ *               All incomming packets will be dropped when there are less
+ *               than this many free packet buffers in FPA 0.
+ * Returns Zero on success. Negative on failure
+ */
+int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
+{
+	union cvmx_ipd_portx_bp_page_cnt page_cnt;
+	union cvmx_ipd_bp_prt_red_end ipd_bp_prt_red_end;
+	union cvmx_ipd_red_port_enable red_port_enable;
+	int queue;
+	int interface;
+	int port;
+
+	/* Disable backpressure based on queued buffers. It needs SW support */
+	page_cnt.u64 = 0;
+	page_cnt.s.bp_enb = 0;
+	page_cnt.s.page_cnt = 100;
+	for (interface = 0; interface < 2; interface++) {
+		for (port = cvmx_helper_get_first_ipd_port(interface);
+		     port < cvmx_helper_get_last_ipd_port(interface); port++)
+			cvmx_write_csr(CVMX_IPD_PORTX_BP_PAGE_CNT(port),
+				       page_cnt.u64);
+	}
+
+	for (queue = 0; queue < 8; queue++)
+		cvmx_helper_setup_red_queue(queue, pass_thresh, drop_thresh);
+
+	/* Shutoff the dropping based on the per port page count. SW isn't
+	   decrementing it right now */
+	ipd_bp_prt_red_end.u64 = 0;
+	ipd_bp_prt_red_end.s.prt_enb = 0;
+	cvmx_write_csr(CVMX_IPD_BP_PRT_RED_END, ipd_bp_prt_red_end.u64);
+
+	red_port_enable.u64 = 0;
+	red_port_enable.s.prt_enb = 0xfffffffffull;
+	red_port_enable.s.avg_dly = 10000;
+	red_port_enable.s.prb_dly = 10000;
+	cvmx_write_csr(CVMX_IPD_RED_PORT_ENABLE, red_port_enable.u64);
+
+	return 0;
+}
+
+/**
+ * Setup the common GMX settings that determine the number of
+ * ports. These setting apply to almost all configurations of all
+ * chips.
+ *
+ * @interface: Interface to configure
+ * @num_ports: Number of ports on the interface
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_setup_gmx(int interface, int num_ports)
+{
+	union cvmx_gmxx_tx_prts gmx_tx_prts;
+	union cvmx_gmxx_rx_prts gmx_rx_prts;
+	union cvmx_pko_reg_gmx_port_mode pko_mode;
+	union cvmx_gmxx_txx_thresh gmx_tx_thresh;
+	int index;
+
+	/* Tell GMX the number of TX ports on this interface */
+	gmx_tx_prts.u64 = cvmx_read_csr(CVMX_GMXX_TX_PRTS(interface));
+	gmx_tx_prts.s.prts = num_ports;
+	cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), gmx_tx_prts.u64);
+
+	/* Tell GMX the number of RX ports on this interface.  This only
+	 ** applies to *GMII and XAUI ports */
+	if (cvmx_helper_interface_get_mode(interface) ==
+	    CVMX_HELPER_INTERFACE_MODE_RGMII
+	    || cvmx_helper_interface_get_mode(interface) ==
+	    CVMX_HELPER_INTERFACE_MODE_SGMII
+	    || cvmx_helper_interface_get_mode(interface) ==
+	    CVMX_HELPER_INTERFACE_MODE_GMII
+	    || cvmx_helper_interface_get_mode(interface) ==
+	    CVMX_HELPER_INTERFACE_MODE_XAUI) {
+		if (num_ports > 4) {
+			cvmx_dprintf("__cvmx_helper_setup_gmx: Illegal "
+				     "num_ports\n");
+			return -1;
+		}
+
+		gmx_rx_prts.u64 = cvmx_read_csr(CVMX_GMXX_RX_PRTS(interface));
+		gmx_rx_prts.s.prts = num_ports;
+		cvmx_write_csr(CVMX_GMXX_RX_PRTS(interface), gmx_rx_prts.u64);
+	}
+
+	/* Skip setting CVMX_PKO_REG_GMX_PORT_MODE on 30XX, 31XX, and 50XX */
+	if (!OCTEON_IS_MODEL(OCTEON_CN30XX) && !OCTEON_IS_MODEL(OCTEON_CN31XX)
+	    && !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		/* Tell PKO the number of ports on this interface */
+		pko_mode.u64 = cvmx_read_csr(CVMX_PKO_REG_GMX_PORT_MODE);
+		if (interface == 0) {
+			if (num_ports == 1)
+				pko_mode.s.mode0 = 4;
+			else if (num_ports == 2)
+				pko_mode.s.mode0 = 3;
+			else if (num_ports <= 4)
+				pko_mode.s.mode0 = 2;
+			else if (num_ports <= 8)
+				pko_mode.s.mode0 = 1;
+			else
+				pko_mode.s.mode0 = 0;
+		} else {
+			if (num_ports == 1)
+				pko_mode.s.mode1 = 4;
+			else if (num_ports == 2)
+				pko_mode.s.mode1 = 3;
+			else if (num_ports <= 4)
+				pko_mode.s.mode1 = 2;
+			else if (num_ports <= 8)
+				pko_mode.s.mode1 = 1;
+			else
+				pko_mode.s.mode1 = 0;
+		}
+		cvmx_write_csr(CVMX_PKO_REG_GMX_PORT_MODE, pko_mode.u64);
+	}
+
+	/*
+	 * Set GMX to buffer as much data as possible before starting
+	 * transmit.  This reduces the chances that we have a TX under
+	 * run due to memory contention. Any packet that fits entirely
+	 * in the GMX FIFO can never have an under run regardless of
+	 * memory load.
+	 */
+	gmx_tx_thresh.u64 = cvmx_read_csr(CVMX_GMXX_TXX_THRESH(0, interface));
+	if (OCTEON_IS_MODEL(OCTEON_CN30XX) || OCTEON_IS_MODEL(OCTEON_CN31XX)
+	    || OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		/* These chips have a fixed max threshold of 0x40 */
+		gmx_tx_thresh.s.cnt = 0x40;
+	} else {
+		/* Choose the max value for the number of ports */
+		if (num_ports <= 1)
+			gmx_tx_thresh.s.cnt = 0x100 / 1;
+		else if (num_ports == 2)
+			gmx_tx_thresh.s.cnt = 0x100 / 2;
+		else
+			gmx_tx_thresh.s.cnt = 0x100 / 4;
+	}
+	/*
+	 * SPI and XAUI can have lots of ports but the GMX hardware
+	 * only ever has a max of 4.
+	 */
+	if (num_ports > 4)
+		num_ports = 4;
+	for (index = 0; index < num_ports; index++)
+		cvmx_write_csr(CVMX_GMXX_TXX_THRESH(index, interface),
+			       gmx_tx_thresh.u64);
+
+	return 0;
+}
+
+/**
+ * Returns the IPD/PKO port number for a port on teh given
+ * interface.
+ *
+ * @interface: Interface to use
+ * @port:      Port on the interface
+ *
+ * Returns IPD/PKO port number
+ */
+int cvmx_helper_get_ipd_port(int interface, int port)
+{
+	switch (interface) {
+	case 0:
+		return port;
+	case 1:
+		return port + 16;
+	case 2:
+		return port + 32;
+	case 3:
+		return port + 36;
+	}
+	return -1;
+}
+
+/**
+ * Returns the interface number for an IPD/PKO port number.
+ *
+ * @ipd_port: IPD/PKO port number
+ *
+ * Returns Interface number
+ */
+int cvmx_helper_get_interface_num(int ipd_port)
+{
+	if (ipd_port < 16)
+		return 0;
+	else if (ipd_port < 32)
+		return 1;
+	else if (ipd_port < 36)
+		return 2;
+	else if (ipd_port < 40)
+		return 3;
+	else
+		cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
+			     "port number\n");
+
+	return -1;
+}
+
+/**
+ * Returns the interface index number for an IPD/PKO port
+ * number.
+ *
+ * @ipd_port: IPD/PKO port number
+ *
+ * Returns Interface index number
+ */
+int cvmx_helper_get_interface_index_num(int ipd_port)
+{
+	if (ipd_port < 32)
+		return ipd_port & 15;
+	else if (ipd_port < 36)
+		return ipd_port & 3;
+	else if (ipd_port < 40)
+		return ipd_port & 3;
+	else
+		cvmx_dprintf("cvmx_helper_get_interface_index_num: "
+			     "Illegal IPD port number\n");
+
+	return -1;
+}
diff --git a/drivers/staging/octeon/cvmx-helper-util.h b/drivers/staging/octeon/cvmx-helper-util.h
new file mode 100644
index 0000000..6a6e52f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-util.h
@@ -0,0 +1,215 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Small helper utilities.
+ *
+ */
+
+#ifndef __CVMX_HELPER_UTIL_H__
+#define __CVMX_HELPER_UTIL_H__
+
+/**
+ * Convert a interface mode into a human readable string
+ *
+ * @mode:   Mode to convert
+ *
+ * Returns String
+ */
+extern const char
+    *cvmx_helper_interface_mode_to_string(cvmx_helper_interface_mode_t mode);
+
+/**
+ * Debug routine to dump the packet structure to the console
+ *
+ * @work:   Work queue entry containing the packet to dump
+ * Returns
+ */
+extern int cvmx_helper_dump_packet(cvmx_wqe_t *work);
+
+/**
+ * Setup Random Early Drop on a specific input queue
+ *
+ * @queue:  Input queue to setup RED on (0-7)
+ * @pass_thresh:
+ *               Packets will begin slowly dropping when there are less than
+ *               this many packet buffers free in FPA 0.
+ * @drop_thresh:
+ *               All incomming packets will be dropped when there are less
+ *               than this many free packet buffers in FPA 0.
+ * Returns Zero on success. Negative on failure
+ */
+extern int cvmx_helper_setup_red_queue(int queue, int pass_thresh,
+				       int drop_thresh);
+
+/**
+ * Setup Random Early Drop to automatically begin dropping packets.
+ *
+ * @pass_thresh:
+ *               Packets will begin slowly dropping when there are less than
+ *               this many packet buffers free in FPA 0.
+ * @drop_thresh:
+ *               All incomming packets will be dropped when there are less
+ *               than this many free packet buffers in FPA 0.
+ * Returns Zero on success. Negative on failure
+ */
+extern int cvmx_helper_setup_red(int pass_thresh, int drop_thresh);
+
+/**
+ * Get the version of the CVMX libraries.
+ *
+ * Returns Version string. Note this buffer is allocated statically
+ *         and will be shared by all callers.
+ */
+extern const char *cvmx_helper_get_version(void);
+
+/**
+ * Setup the common GMX settings that determine the number of
+ * ports. These setting apply to almost all configurations of all
+ * chips.
+ *
+ * @interface: Interface to configure
+ * @num_ports: Number of ports on the interface
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_setup_gmx(int interface, int num_ports);
+
+/**
+ * Returns the IPD/PKO port number for a port on the given
+ * interface.
+ *
+ * @interface: Interface to use
+ * @port:      Port on the interface
+ *
+ * Returns IPD/PKO port number
+ */
+extern int cvmx_helper_get_ipd_port(int interface, int port);
+
+/**
+ * Returns the IPD/PKO port number for the first port on the given
+ * interface.
+ *
+ * @interface: Interface to use
+ *
+ * Returns IPD/PKO port number
+ */
+static inline int cvmx_helper_get_first_ipd_port(int interface)
+{
+	return cvmx_helper_get_ipd_port(interface, 0);
+}
+
+/**
+ * Returns the IPD/PKO port number for the last port on the given
+ * interface.
+ *
+ * @interface: Interface to use
+ *
+ * Returns IPD/PKO port number
+ */
+static inline int cvmx_helper_get_last_ipd_port(int interface)
+{
+	extern int cvmx_helper_ports_on_interface(int interface);
+
+	return cvmx_helper_get_first_ipd_port(interface) +
+	       cvmx_helper_ports_on_interface(interface) - 1;
+}
+
+/**
+ * Free the packet buffers contained in a work queue entry.
+ * The work queue entry is not freed.
+ *
+ * @work:   Work queue entry with packet to free
+ */
+static inline void cvmx_helper_free_packet_data(cvmx_wqe_t *work)
+{
+	uint64_t number_buffers;
+	union cvmx_buf_ptr buffer_ptr;
+	union cvmx_buf_ptr next_buffer_ptr;
+	uint64_t start_of_buffer;
+
+	number_buffers = work->word2.s.bufs;
+	if (number_buffers == 0)
+		return;
+	buffer_ptr = work->packet_ptr;
+
+	/*
+	 * Since the number of buffers is not zero, we know this is
+	 * not a dynamic short packet. We need to check if it is a
+	 * packet received with IPD_CTL_STATUS[NO_WPTR]. If this is
+	 * true, we need to free all buffers except for the first
+	 * one. The caller doesn't expect their WQE pointer to be
+	 * freed
+	 */
+	start_of_buffer = ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
+	if (cvmx_ptr_to_phys(work) == start_of_buffer) {
+		next_buffer_ptr =
+		    *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
+		buffer_ptr = next_buffer_ptr;
+		number_buffers--;
+	}
+
+	while (number_buffers--) {
+		/*
+		 * Remember the back pointer is in cache lines, not
+		 * 64bit words
+		 */
+		start_of_buffer =
+		    ((buffer_ptr.s.addr >> 7) - buffer_ptr.s.back) << 7;
+		/*
+		 * Read pointer to next buffer before we free the
+		 * current buffer.
+		 */
+		next_buffer_ptr =
+		    *(union cvmx_buf_ptr *) cvmx_phys_to_ptr(buffer_ptr.s.addr - 8);
+		cvmx_fpa_free(cvmx_phys_to_ptr(start_of_buffer),
+			      buffer_ptr.s.pool, 0);
+		buffer_ptr = next_buffer_ptr;
+	}
+}
+
+/**
+ * Returns the interface number for an IPD/PKO port number.
+ *
+ * @ipd_port: IPD/PKO port number
+ *
+ * Returns Interface number
+ */
+extern int cvmx_helper_get_interface_num(int ipd_port);
+
+/**
+ * Returns the interface index number for an IPD/PKO port
+ * number.
+ *
+ * @ipd_port: IPD/PKO port number
+ *
+ * Returns Interface index number
+ */
+extern int cvmx_helper_get_interface_index_num(int ipd_port);
+
+#endif /* __CVMX_HELPER_H__ */
diff --git a/drivers/staging/octeon/cvmx-helper-xaui.c b/drivers/staging/octeon/cvmx-helper-xaui.c
new file mode 100644
index 0000000..a11e676
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-xaui.c
@@ -0,0 +1,348 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Functions for XAUI initialization, configuration,
+ * and monitoring.
+ *
+ */
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-helper.h"
+
+#include "cvmx-pko-defs.h"
+#include "cvmx-gmxx-defs.h"
+#include "cvmx-pcsxx-defs.h"
+
+void __cvmx_interrupt_gmxx_enable(int interface);
+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
+/**
+ * Probe a XAUI interface and determine the number of ports
+ * connected to it. The XAUI interface should still be down
+ * after this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+int __cvmx_helper_xaui_probe(int interface)
+{
+	int i;
+	union cvmx_gmxx_hg2_control gmx_hg2_control;
+	union cvmx_gmxx_inf_mode mode;
+
+	/*
+	 * Due to errata GMX-700 on CN56XXp1.x and CN52XXp1.x, the
+	 * interface needs to be enabled before IPD otherwise per port
+	 * backpressure may not work properly.
+	 */
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+	mode.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
+
+	__cvmx_helper_setup_gmx(interface, 1);
+
+	/*
+	 * Setup PKO to support 16 ports for HiGig2 virtual
+	 * ports. We're pointing all of the PKO packet ports for this
+	 * interface to the XAUI. This allows us to use HiGig2
+	 * backpressure per port.
+	 */
+	for (i = 0; i < 16; i++) {
+		union cvmx_pko_mem_port_ptrs pko_mem_port_ptrs;
+		pko_mem_port_ptrs.u64 = 0;
+		/*
+		 * We set each PKO port to have equal priority in a
+		 * round robin fashion.
+		 */
+		pko_mem_port_ptrs.s.static_p = 0;
+		pko_mem_port_ptrs.s.qos_mask = 0xff;
+		/* All PKO ports map to the same XAUI hardware port */
+		pko_mem_port_ptrs.s.eid = interface * 4;
+		pko_mem_port_ptrs.s.pid = interface * 16 + i;
+		cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
+	}
+
+	/* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
+	gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
+	if (gmx_hg2_control.s.hg2tx_en)
+		return 16;
+	else
+		return 1;
+}
+
+/**
+ * Bringup and enable a XAUI interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_xaui_enable(int interface)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	union cvmx_pcsxx_control1_reg xauiCtl;
+	union cvmx_pcsxx_misc_ctl_reg xauiMiscCtl;
+	union cvmx_gmxx_tx_xaui_ctl gmxXauiTxCtl;
+	union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
+	union cvmx_gmxx_tx_int_en gmx_tx_int_en;
+	union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
+
+	/* (1) Interface has already been enabled. */
+
+	/* (2) Disable GMX. */
+	xauiMiscCtl.u64 = cvmx_read_csr(CVMX_PCSXX_MISC_CTL_REG(interface));
+	xauiMiscCtl.s.gmxeno = 1;
+	cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
+
+	/* (3) Disable GMX and PCSX interrupts. */
+	gmx_rx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_RXX_INT_EN(0, interface));
+	cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
+	gmx_tx_int_en.u64 = cvmx_read_csr(CVMX_GMXX_TX_INT_EN(interface));
+	cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
+	pcsx_int_en_reg.u64 = cvmx_read_csr(CVMX_PCSXX_INT_EN_REG(interface));
+	cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
+
+	/* (4) Bring up the PCSX and GMX reconciliation layer. */
+	/* (4)a Set polarity and lane swapping. */
+	/* (4)b */
+	gmxXauiTxCtl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
+	/* Enable better IFG packing and improves performance */
+	gmxXauiTxCtl.s.dic_en = 1;
+	gmxXauiTxCtl.s.uni_en = 0;
+	cvmx_write_csr(CVMX_GMXX_TX_XAUI_CTL(interface), gmxXauiTxCtl.u64);
+
+	/* (4)c Aply reset sequence */
+	xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
+	xauiCtl.s.lo_pwr = 0;
+	xauiCtl.s.reset = 1;
+	cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
+
+	/* Wait for PCS to come out of reset */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_PCSXX_CONTROL1_REG(interface), union cvmx_pcsxx_control1_reg,
+	     reset, ==, 0, 10000))
+		return -1;
+	/* Wait for PCS to be aligned */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_PCSXX_10GBX_STATUS_REG(interface),
+	     union cvmx_pcsxx_10gbx_status_reg, alignd, ==, 1, 10000))
+		return -1;
+	/* Wait for RX to be ready */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_GMXX_RX_XAUI_CTL(interface), union cvmx_gmxx_rx_xaui_ctl,
+		    status, ==, 0, 10000))
+		return -1;
+
+	/* (6) Configure GMX */
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
+	gmx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
+
+	/* Wait for GMX RX to be idle */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
+		    rx_idle, ==, 1, 10000))
+		return -1;
+	/* Wait for GMX TX to be idle */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_GMXX_PRTX_CFG(0, interface), union cvmx_gmxx_prtx_cfg,
+		    tx_idle, ==, 1, 10000))
+		return -1;
+
+	/* GMX configure */
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
+	gmx_cfg.s.speed = 1;
+	gmx_cfg.s.speed_msb = 0;
+	gmx_cfg.s.slottime = 1;
+	cvmx_write_csr(CVMX_GMXX_TX_PRTS(interface), 1);
+	cvmx_write_csr(CVMX_GMXX_TXX_SLOT(0, interface), 512);
+	cvmx_write_csr(CVMX_GMXX_TXX_BURST(0, interface), 8192);
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
+
+	/* (7) Clear out any error state */
+	cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(0, interface),
+		       cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(0, interface)));
+	cvmx_write_csr(CVMX_GMXX_TX_INT_REG(interface),
+		       cvmx_read_csr(CVMX_GMXX_TX_INT_REG(interface)));
+	cvmx_write_csr(CVMX_PCSXX_INT_REG(interface),
+		       cvmx_read_csr(CVMX_PCSXX_INT_REG(interface)));
+
+	/* Wait for receive link */
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_PCSXX_STATUS1_REG(interface), union cvmx_pcsxx_status1_reg,
+	     rcv_lnk, ==, 1, 10000))
+		return -1;
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
+	     xmtflt, ==, 0, 10000))
+		return -1;
+	if (CVMX_WAIT_FOR_FIELD64
+	    (CVMX_PCSXX_STATUS2_REG(interface), union cvmx_pcsxx_status2_reg,
+	     rcvflt, ==, 0, 10000))
+		return -1;
+
+	cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), gmx_rx_int_en.u64);
+	cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
+	cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64);
+
+	cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0));
+
+	/* (8) Enable packet reception */
+	xauiMiscCtl.s.gmxeno = 0;
+	cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64);
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
+	gmx_cfg.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
+
+	__cvmx_interrupt_pcsx_intx_en_reg_enable(0, interface);
+	__cvmx_interrupt_pcsx_intx_en_reg_enable(1, interface);
+	__cvmx_interrupt_pcsx_intx_en_reg_enable(2, interface);
+	__cvmx_interrupt_pcsx_intx_en_reg_enable(3, interface);
+	__cvmx_interrupt_pcsxx_int_en_reg_enable(interface);
+	__cvmx_interrupt_gmxx_enable(interface);
+
+	return 0;
+}
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
+	union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
+	union cvmx_pcsxx_status1_reg pcsxx_status1_reg;
+	cvmx_helper_link_info_t result;
+
+	gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
+	gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
+	pcsxx_status1_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSXX_STATUS1_REG(interface));
+	result.u64 = 0;
+
+	/* Only return a link if both RX and TX are happy */
+	if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0) &&
+	    (pcsxx_status1_reg.s.rcv_lnk == 1)) {
+		result.s.link_up = 1;
+		result.s.full_duplex = 1;
+		result.s.speed = 10000;
+	} else {
+		/* Disable GMX and PCSX interrupts. */
+		cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(0, interface), 0x0);
+		cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), 0x0);
+		cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), 0x0);
+	}
+	return result;
+}
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+int __cvmx_helper_xaui_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	union cvmx_gmxx_tx_xaui_ctl gmxx_tx_xaui_ctl;
+	union cvmx_gmxx_rx_xaui_ctl gmxx_rx_xaui_ctl;
+
+	gmxx_tx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_TX_XAUI_CTL(interface));
+	gmxx_rx_xaui_ctl.u64 = cvmx_read_csr(CVMX_GMXX_RX_XAUI_CTL(interface));
+
+	/* If the link shouldn't be up, then just return */
+	if (!link_info.s.link_up)
+		return 0;
+
+	/* Do nothing if both RX and TX are happy */
+	if ((gmxx_tx_xaui_ctl.s.ls == 0) && (gmxx_rx_xaui_ctl.s.status == 0))
+		return 0;
+
+	/* Bring the link up */
+	return __cvmx_helper_xaui_enable(interface);
+}
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
+						 int enable_internal,
+						 int enable_external)
+{
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	union cvmx_pcsxx_control1_reg pcsxx_control1_reg;
+	union cvmx_gmxx_xaui_ext_loopback gmxx_xaui_ext_loopback;
+
+	/* Set the internal loop */
+	pcsxx_control1_reg.u64 =
+	    cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
+	pcsxx_control1_reg.s.loopbck1 = enable_internal;
+	cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface),
+		       pcsxx_control1_reg.u64);
+
+	/* Set the external loop */
+	gmxx_xaui_ext_loopback.u64 =
+	    cvmx_read_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface));
+	gmxx_xaui_ext_loopback.s.en = enable_external;
+	cvmx_write_csr(CVMX_GMXX_XAUI_EXT_LOOPBACK(interface),
+		       gmxx_xaui_ext_loopback.u64);
+
+	/* Take the link through a reset */
+	return __cvmx_helper_xaui_enable(interface);
+}
diff --git a/drivers/staging/octeon/cvmx-helper-xaui.h b/drivers/staging/octeon/cvmx-helper-xaui.h
new file mode 100644
index 0000000..4b4db2f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper-xaui.h
@@ -0,0 +1,103 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * @file
+ *
+ * Functions for XAUI initialization, configuration,
+ * and monitoring.
+ *
+ */
+#ifndef __CVMX_HELPER_XAUI_H__
+#define __CVMX_HELPER_XAUI_H__
+
+/**
+ * Probe a XAUI interface and determine the number of ports
+ * connected to it. The XAUI interface should still be down
+ * after this call.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Number of ports on the interface. Zero to disable.
+ */
+extern int __cvmx_helper_xaui_probe(int interface);
+
+/**
+ * Bringup and enable a XAUI interface. After this call packet
+ * I/O should be fully functional. This is called with IPD
+ * enabled but PKO disabled.
+ *
+ * @interface: Interface to bring up
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_xaui_enable(int interface);
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+extern cvmx_helper_link_info_t __cvmx_helper_xaui_link_get(int ipd_port);
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int __cvmx_helper_xaui_link_set(int ipd_port,
+				       cvmx_helper_link_info_t link_info);
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+extern int __cvmx_helper_xaui_configure_loopback(int ipd_port,
+						 int enable_internal,
+						 int enable_external);
+#endif
diff --git a/drivers/staging/octeon/cvmx-helper.c b/drivers/staging/octeon/cvmx-helper.c
new file mode 100644
index 0000000..5915066
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper.c
@@ -0,0 +1,1058 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Helper functions for common, but complicated tasks.
+ *
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-fpa.h"
+#include "cvmx-pip.h"
+#include "cvmx-pko.h"
+#include "cvmx-ipd.h"
+#include "cvmx-spi.h"
+#include "cvmx-helper.h"
+#include "cvmx-helper-board.h"
+
+#include "cvmx-pip-defs.h"
+#include "cvmx-smix-defs.h"
+#include "cvmx-asxx-defs.h"
+
+/**
+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
+ * priorities[16]) is a function pointer. It is meant to allow
+ * customization of the PKO queue priorities based on the port
+ * number. Users should set this pointer to a function before
+ * calling any cvmx-helper operations.
+ */
+void (*cvmx_override_pko_queue_priority) (int pko_port,
+					  uint64_t priorities[16]);
+
+/**
+ * cvmx_override_ipd_port_setup(int ipd_port) is a function
+ * pointer. It is meant to allow customization of the IPD port
+ * setup before packet input/output comes online. It is called
+ * after cvmx-helper does the default IPD configuration, but
+ * before IPD is enabled. Users should set this pointer to a
+ * function before calling any cvmx-helper operations.
+ */
+void (*cvmx_override_ipd_port_setup) (int ipd_port);
+
+/* Port count per interface */
+static int interface_port_count[4] = { 0, 0, 0, 0 };
+
+/* Port last configured link info index by IPD/PKO port */
+static cvmx_helper_link_info_t
+    port_link_info[CVMX_PIP_NUM_INPUT_PORTS];
+
+/**
+ * Return the number of interfaces the chip has. Each interface
+ * may have multiple ports. Most chips support two interfaces,
+ * but the CNX0XX and CNX1XX are exceptions. These only support
+ * one interface.
+ *
+ * Returns Number of interfaces on chip
+ */
+int cvmx_helper_get_number_of_interfaces(void)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
+		return 4;
+	else
+		return 3;
+}
+
+/**
+ * Return the number of ports on an interface. Depending on the
+ * chip and configuration, this can be 1-16. A value of 0
+ * specifies that the interface doesn't exist or isn't usable.
+ *
+ * @interface: Interface to get the port count for
+ *
+ * Returns Number of ports on interface. Can be Zero.
+ */
+int cvmx_helper_ports_on_interface(int interface)
+{
+	return interface_port_count[interface];
+}
+
+/**
+ * Get the operating mode of an interface. Depending on the Octeon
+ * chip and configuration, this function returns an enumeration
+ * of the type of packet I/O supported by an interface.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Mode of the interface. Unknown or unsupported interfaces return
+ *         DISABLED.
+ */
+cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
+{
+	union cvmx_gmxx_inf_mode mode;
+	if (interface == 2)
+		return CVMX_HELPER_INTERFACE_MODE_NPI;
+
+	if (interface == 3) {
+		if (OCTEON_IS_MODEL(OCTEON_CN56XX)
+		    || OCTEON_IS_MODEL(OCTEON_CN52XX))
+			return CVMX_HELPER_INTERFACE_MODE_LOOP;
+		else
+			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+	}
+
+	if (interface == 0
+	    && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5
+	    && cvmx_sysinfo_get()->board_rev_major == 1) {
+		/*
+		 * Lie about interface type of CN3005 board.  This
+		 * board has a switch on port 1 like the other
+		 * evaluation boards, but it is connected over RGMII
+		 * instead of GMII.  Report GMII mode so that the
+		 * speed is forced to 1 Gbit full duplex.  Other than
+		 * some initial configuration (which does not use the
+		 * output of this function) there is no difference in
+		 * setup between GMII and RGMII modes.
+		 */
+		return CVMX_HELPER_INTERFACE_MODE_GMII;
+	}
+
+	/* Interface 1 is always disabled on CN31XX and CN30XX */
+	if ((interface == 1)
+	    && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX)
+		|| OCTEON_IS_MODEL(OCTEON_CN50XX)
+		|| OCTEON_IS_MODEL(OCTEON_CN52XX)))
+		return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		switch (mode.cn56xx.mode) {
+		case 0:
+			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+		case 1:
+			return CVMX_HELPER_INTERFACE_MODE_XAUI;
+		case 2:
+			return CVMX_HELPER_INTERFACE_MODE_SGMII;
+		case 3:
+			return CVMX_HELPER_INTERFACE_MODE_PICMG;
+		default:
+			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+		}
+	} else {
+		if (!mode.s.en)
+			return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+		if (mode.s.type) {
+			if (OCTEON_IS_MODEL(OCTEON_CN38XX)
+			    || OCTEON_IS_MODEL(OCTEON_CN58XX))
+				return CVMX_HELPER_INTERFACE_MODE_SPI;
+			else
+				return CVMX_HELPER_INTERFACE_MODE_GMII;
+		} else
+			return CVMX_HELPER_INTERFACE_MODE_RGMII;
+	}
+}
+
+/**
+ * Configure the IPD/PIP tagging and QoS options for a specific
+ * port. This function determines the POW work queue entry
+ * contents for a port. The setup performed here is controlled by
+ * the defines in executive-config.h.
+ *
+ * @ipd_port: Port to configure. This follows the IPD numbering, not the
+ *                 per interface numbering
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_port_setup_ipd(int ipd_port)
+{
+	union cvmx_pip_prt_cfgx port_config;
+	union cvmx_pip_prt_tagx tag_config;
+
+	port_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_CFGX(ipd_port));
+	tag_config.u64 = cvmx_read_csr(CVMX_PIP_PRT_TAGX(ipd_port));
+
+	/* Have each port go to a different POW queue */
+	port_config.s.qos = ipd_port & 0x7;
+
+	/* Process the headers and place the IP header in the work queue */
+	port_config.s.mode = CVMX_HELPER_INPUT_PORT_SKIP_MODE;
+
+	tag_config.s.ip6_src_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_IP;
+	tag_config.s.ip6_dst_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_IP;
+	tag_config.s.ip6_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_SRC_PORT;
+	tag_config.s.ip6_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV6_DST_PORT;
+	tag_config.s.ip6_nxth_flag = CVMX_HELPER_INPUT_TAG_IPV6_NEXT_HEADER;
+	tag_config.s.ip4_src_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_IP;
+	tag_config.s.ip4_dst_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_IP;
+	tag_config.s.ip4_sprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_SRC_PORT;
+	tag_config.s.ip4_dprt_flag = CVMX_HELPER_INPUT_TAG_IPV4_DST_PORT;
+	tag_config.s.ip4_pctl_flag = CVMX_HELPER_INPUT_TAG_IPV4_PROTOCOL;
+	tag_config.s.inc_prt_flag = CVMX_HELPER_INPUT_TAG_INPUT_PORT;
+	tag_config.s.tcp6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	tag_config.s.tcp4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	tag_config.s.ip6_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	tag_config.s.ip4_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	tag_config.s.non_tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	/* Put all packets in group 0. Other groups can be used by the app */
+	tag_config.s.grp = 0;
+
+	cvmx_pip_config_port(ipd_port, port_config, tag_config);
+
+	/* Give the user a chance to override our setting for each port */
+	if (cvmx_override_ipd_port_setup)
+		cvmx_override_ipd_port_setup(ipd_port);
+
+	return 0;
+}
+
+/**
+ * This function probes an interface to determine the actual
+ * number of hardware ports connected to it. It doesn't setup the
+ * ports or enable them. The main goal here is to set the global
+ * interface_port_count[interface] correctly. Hardware setup of the
+ * ports will be performed later.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_interface_probe(int interface)
+{
+	/* At this stage in the game we don't want packets to be moving yet.
+	   The following probe calls should perform hardware setup
+	   needed to determine port counts. Receive must still be disabled */
+	switch (cvmx_helper_interface_get_mode(interface)) {
+		/* These types don't support ports to IPD/PKO */
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		interface_port_count[interface] = 0;
+		break;
+		/* XAUI is a single high speed port */
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		interface_port_count[interface] =
+		    __cvmx_helper_xaui_probe(interface);
+		break;
+		/*
+		 * RGMII/GMII/MII are all treated about the same. Most
+		 * functions refer to these ports as RGMII.
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		interface_port_count[interface] =
+		    __cvmx_helper_rgmii_probe(interface);
+		break;
+		/*
+		 * SPI4 can have 1-16 ports depending on the device at
+		 * the other end.
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+		interface_port_count[interface] =
+		    __cvmx_helper_spi_probe(interface);
+		break;
+		/*
+		 * SGMII can have 1-4 ports depending on how many are
+		 * hooked up.
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		interface_port_count[interface] =
+		    __cvmx_helper_sgmii_probe(interface);
+		break;
+		/* PCI target Network Packet Interface */
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+		interface_port_count[interface] =
+		    __cvmx_helper_npi_probe(interface);
+		break;
+		/*
+		 * Special loopback only ports. These are not the same
+		 * as other ports in loopback mode.
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		interface_port_count[interface] =
+		    __cvmx_helper_loop_probe(interface);
+		break;
+	}
+
+	interface_port_count[interface] =
+	    __cvmx_helper_board_interface_probe(interface,
+						interface_port_count
+						[interface]);
+
+	/* Make sure all global variables propagate to other cores */
+	CVMX_SYNCWS;
+
+	return 0;
+}
+
+/**
+ * Setup the IPD/PIP for the ports on an interface. Packet
+ * classification and tagging are set for every port on the
+ * interface. The number of ports on the interface must already
+ * have been probed.
+ *
+ * @interface: Interface to setup IPD/PIP for
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_interface_setup_ipd(int interface)
+{
+	int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
+	int num_ports = interface_port_count[interface];
+
+	while (num_ports--) {
+		__cvmx_helper_port_setup_ipd(ipd_port);
+		ipd_port++;
+	}
+	return 0;
+}
+
+/**
+ * Setup global setting for IPD/PIP not related to a specific
+ * interface or port. This must be called before IPD is enabled.
+ *
+ * Returns Zero on success, negative on failure.
+ */
+static int __cvmx_helper_global_setup_ipd(void)
+{
+	/* Setup the global packet input options */
+	cvmx_ipd_config(CVMX_FPA_PACKET_POOL_SIZE / 8,
+			CVMX_HELPER_FIRST_MBUFF_SKIP / 8,
+			CVMX_HELPER_NOT_FIRST_MBUFF_SKIP / 8,
+			/* The +8 is to account for the next ptr */
+			(CVMX_HELPER_FIRST_MBUFF_SKIP + 8) / 128,
+			/* The +8 is to account for the next ptr */
+			(CVMX_HELPER_NOT_FIRST_MBUFF_SKIP + 8) / 128,
+			CVMX_FPA_WQE_POOL,
+			CVMX_IPD_OPC_MODE_STT,
+			CVMX_HELPER_ENABLE_BACK_PRESSURE);
+	return 0;
+}
+
+/**
+ * Setup the PKO for the ports on an interface. The number of
+ * queues per port and the priority of each PKO output queue
+ * is set here. PKO must be disabled when this function is called.
+ *
+ * @interface: Interface to setup PKO for
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_interface_setup_pko(int interface)
+{
+	/*
+	 * Each packet output queue has an associated priority. The
+	 * higher the priority, the more often it can send a packet. A
+	 * priority of 8 means it can send in all 8 rounds of
+	 * contention. We're going to make each queue one less than
+	 * the last.  The vector of priorities has been extended to
+	 * support CN5xxx CPUs, where up to 16 queues can be
+	 * associated to a port.  To keep backward compatibility we
+	 * don't change the initial 8 priorities and replicate them in
+	 * the second half.  With per-core PKO queues (PKO lockless
+	 * operation) all queues have the same priority.
+	 */
+	uint64_t priorities[16] =
+	    { 8, 7, 6, 5, 4, 3, 2, 1, 8, 7, 6, 5, 4, 3, 2, 1 };
+
+	/*
+	 * Setup the IPD/PIP and PKO for the ports discovered
+	 * above. Here packet classification, tagging and output
+	 * priorities are set.
+	 */
+	int ipd_port = cvmx_helper_get_ipd_port(interface, 0);
+	int num_ports = interface_port_count[interface];
+	while (num_ports--) {
+		/*
+		 * Give the user a chance to override the per queue
+		 * priorities.
+		 */
+		if (cvmx_override_pko_queue_priority)
+			cvmx_override_pko_queue_priority(ipd_port, priorities);
+
+		cvmx_pko_config_port(ipd_port,
+				     cvmx_pko_get_base_queue_per_core(ipd_port,
+								      0),
+				     cvmx_pko_get_num_queues(ipd_port),
+				     priorities);
+		ipd_port++;
+	}
+	return 0;
+}
+
+/**
+ * Setup global setting for PKO not related to a specific
+ * interface or port. This must be called before PKO is enabled.
+ *
+ * Returns Zero on success, negative on failure.
+ */
+static int __cvmx_helper_global_setup_pko(void)
+{
+	/*
+	 * Disable tagwait FAU timeout. This needs to be done before
+	 * anyone might start packet output using tags.
+	 */
+	union cvmx_iob_fau_timeout fau_to;
+	fau_to.u64 = 0;
+	fau_to.s.tout_val = 0xfff;
+	fau_to.s.tout_enb = 0;
+	cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
+	return 0;
+}
+
+/**
+ * Setup global backpressure setting.
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_global_setup_backpressure(void)
+{
+#if CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE
+	/* Disable backpressure if configured to do so */
+	/* Disable backpressure (pause frame) generation */
+	int num_interfaces = cvmx_helper_get_number_of_interfaces();
+	int interface;
+	for (interface = 0; interface < num_interfaces; interface++) {
+		switch (cvmx_helper_interface_get_mode(interface)) {
+		case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+		case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		case CVMX_HELPER_INTERFACE_MODE_NPI:
+		case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		case CVMX_HELPER_INTERFACE_MODE_XAUI:
+			break;
+		case CVMX_HELPER_INTERFACE_MODE_RGMII:
+		case CVMX_HELPER_INTERFACE_MODE_GMII:
+		case CVMX_HELPER_INTERFACE_MODE_SPI:
+		case CVMX_HELPER_INTERFACE_MODE_SGMII:
+		case CVMX_HELPER_INTERFACE_MODE_PICMG:
+			cvmx_gmx_set_backpressure_override(interface, 0xf);
+			break;
+		}
+	}
+#endif
+
+	return 0;
+}
+
+/**
+ * Enable packet input/output from the hardware. This function is
+ * called after all internal setup is complete and IPD is enabled.
+ * After this function completes, packets will be accepted from the
+ * hardware ports. PKO should still be disabled to make sure packets
+ * aren't sent out partially setup hardware.
+ *
+ * @interface: Interface to enable
+ *
+ * Returns Zero on success, negative on failure
+ */
+static int __cvmx_helper_packet_hardware_enable(int interface)
+{
+	int result = 0;
+	switch (cvmx_helper_interface_get_mode(interface)) {
+		/* These types don't support ports to IPD/PKO */
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		/* Nothing to do */
+		break;
+		/* XAUI is a single high speed port */
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		result = __cvmx_helper_xaui_enable(interface);
+		break;
+		/*
+		 * RGMII/GMII/MII are all treated about the same. Most
+		 * functions refer to these ports as RGMII
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		result = __cvmx_helper_rgmii_enable(interface);
+		break;
+		/*
+		 * SPI4 can have 1-16 ports depending on the device at
+		 * the other end
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+		result = __cvmx_helper_spi_enable(interface);
+		break;
+		/*
+		 * SGMII can have 1-4 ports depending on how many are
+		 * hooked up
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		result = __cvmx_helper_sgmii_enable(interface);
+		break;
+		/* PCI target Network Packet Interface */
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+		result = __cvmx_helper_npi_enable(interface);
+		break;
+		/*
+		 * Special loopback only ports. These are not the same
+		 * as other ports in loopback mode
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		result = __cvmx_helper_loop_enable(interface);
+		break;
+	}
+	result |= __cvmx_helper_board_hardware_enable(interface);
+	return result;
+}
+
+/**
+ * Function to adjust internal IPD pointer alignments
+ *
+ * Returns 0 on success
+ *         !0 on failure
+ */
+int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
+{
+#define FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES \
+     (CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_FIRST_MBUFF_SKIP)
+#define FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES \
+	(CVMX_FPA_PACKET_POOL_SIZE-8-CVMX_HELPER_NOT_FIRST_MBUFF_SKIP)
+#define FIX_IPD_OUTPORT 0
+	/* Ports 0-15 are interface 0, 16-31 are interface 1 */
+#define INTERFACE(port) (port >> 4)
+#define INDEX(port) (port & 0xf)
+	uint64_t *p64;
+	cvmx_pko_command_word0_t pko_command;
+	union cvmx_buf_ptr g_buffer, pkt_buffer;
+	cvmx_wqe_t *work;
+	int size, num_segs = 0, wqe_pcnt, pkt_pcnt;
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	int retry_cnt;
+	int retry_loop_cnt;
+	int mtu;
+	int i;
+	cvmx_helper_link_info_t link_info;
+
+	/* Save values for restore at end */
+	uint64_t prtx_cfg =
+	    cvmx_read_csr(CVMX_GMXX_PRTX_CFG
+			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
+	uint64_t tx_ptr_en =
+	    cvmx_read_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
+	uint64_t rx_ptr_en =
+	    cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)));
+	uint64_t rxx_jabber =
+	    cvmx_read_csr(CVMX_GMXX_RXX_JABBER
+			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
+	uint64_t frame_max =
+	    cvmx_read_csr(CVMX_GMXX_RXX_FRM_MAX
+			  (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)));
+
+	/* Configure port to gig FDX as required for loopback mode */
+	cvmx_helper_rgmii_internal_loopback(FIX_IPD_OUTPORT);
+
+	/*
+	 * Disable reception on all ports so if traffic is present it
+	 * will not interfere.
+	 */
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)), 0);
+
+	cvmx_wait(100000000ull);
+
+	for (retry_loop_cnt = 0; retry_loop_cnt < 10; retry_loop_cnt++) {
+		retry_cnt = 100000;
+		wqe_pcnt = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
+		pkt_pcnt = (wqe_pcnt >> 7) & 0x7f;
+		wqe_pcnt &= 0x7f;
+
+		num_segs = (2 + pkt_pcnt - wqe_pcnt) & 3;
+
+		if (num_segs == 0)
+			goto fix_ipd_exit;
+
+		num_segs += 1;
+
+		size =
+		    FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES +
+		    ((num_segs - 1) * FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES) -
+		    (FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES / 2);
+
+		cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)),
+			       1 << INDEX(FIX_IPD_OUTPORT));
+		CVMX_SYNC;
+
+		g_buffer.u64 = 0;
+		g_buffer.s.addr =
+		    cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_WQE_POOL));
+		if (g_buffer.s.addr == 0) {
+			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
+				     "buffer allocation failure.\n");
+			goto fix_ipd_exit;
+		}
+
+		g_buffer.s.pool = CVMX_FPA_WQE_POOL;
+		g_buffer.s.size = num_segs;
+
+		pkt_buffer.u64 = 0;
+		pkt_buffer.s.addr =
+		    cvmx_ptr_to_phys(cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL));
+		if (pkt_buffer.s.addr == 0) {
+			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
+				     "buffer allocation failure.\n");
+			goto fix_ipd_exit;
+		}
+		pkt_buffer.s.i = 1;
+		pkt_buffer.s.pool = CVMX_FPA_PACKET_POOL;
+		pkt_buffer.s.size = FIX_IPD_FIRST_BUFF_PAYLOAD_BYTES;
+
+		p64 = (uint64_t *) cvmx_phys_to_ptr(pkt_buffer.s.addr);
+		p64[0] = 0xffffffffffff0000ull;
+		p64[1] = 0x08004510ull;
+		p64[2] = ((uint64_t) (size - 14) << 48) | 0x5ae740004000ull;
+		p64[3] = 0x3a5fc0a81073c0a8ull;
+
+		for (i = 0; i < num_segs; i++) {
+			if (i > 0)
+				pkt_buffer.s.size =
+				    FIX_IPD_NON_FIRST_BUFF_PAYLOAD_BYTES;
+
+			if (i == (num_segs - 1))
+				pkt_buffer.s.i = 0;
+
+			*(uint64_t *) cvmx_phys_to_ptr(g_buffer.s.addr +
+						       8 * i) = pkt_buffer.u64;
+		}
+
+		/* Build the PKO command */
+		pko_command.u64 = 0;
+		pko_command.s.segs = num_segs;
+		pko_command.s.total_bytes = size;
+		pko_command.s.dontfree = 0;
+		pko_command.s.gather = 1;
+
+		gmx_cfg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG
+				  (INDEX(FIX_IPD_OUTPORT),
+				   INTERFACE(FIX_IPD_OUTPORT)));
+		gmx_cfg.s.en = 1;
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG
+			       (INDEX(FIX_IPD_OUTPORT),
+				INTERFACE(FIX_IPD_OUTPORT)), gmx_cfg.u64);
+		cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
+			       1 << INDEX(FIX_IPD_OUTPORT));
+		cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
+			       1 << INDEX(FIX_IPD_OUTPORT));
+
+		mtu =
+		    cvmx_read_csr(CVMX_GMXX_RXX_JABBER
+				  (INDEX(FIX_IPD_OUTPORT),
+				   INTERFACE(FIX_IPD_OUTPORT)));
+		cvmx_write_csr(CVMX_GMXX_RXX_JABBER
+			       (INDEX(FIX_IPD_OUTPORT),
+				INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
+		cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
+			       (INDEX(FIX_IPD_OUTPORT),
+				INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
+
+		cvmx_pko_send_packet_prepare(FIX_IPD_OUTPORT,
+					     cvmx_pko_get_base_queue
+					     (FIX_IPD_OUTPORT),
+					     CVMX_PKO_LOCK_CMD_QUEUE);
+		cvmx_pko_send_packet_finish(FIX_IPD_OUTPORT,
+					    cvmx_pko_get_base_queue
+					    (FIX_IPD_OUTPORT), pko_command,
+					    g_buffer, CVMX_PKO_LOCK_CMD_QUEUE);
+
+		CVMX_SYNC;
+
+		do {
+			work = cvmx_pow_work_request_sync(CVMX_POW_WAIT);
+			retry_cnt--;
+		} while ((work == NULL) && (retry_cnt > 0));
+
+		if (!retry_cnt)
+			cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT "
+				     "get_work() timeout occured.\n");
+
+		/* Free packet */
+		if (work)
+			cvmx_helper_free_packet_data(work);
+	}
+
+fix_ipd_exit:
+
+	/* Return CSR configs to saved values */
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG
+		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
+		       prtx_cfg);
+	cvmx_write_csr(CVMX_ASXX_TX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
+		       tx_ptr_en);
+	cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
+		       rx_ptr_en);
+	cvmx_write_csr(CVMX_GMXX_RXX_JABBER
+		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
+		       rxx_jabber);
+	cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX
+		       (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)),
+		       frame_max);
+	cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0);
+	/* Set link to down so autonegotiation will set it up again */
+	link_info.u64 = 0;
+	cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info);
+
+	/*
+	 * Bring the link back up as autonegotiation is not done in
+	 * user applications.
+	 */
+	cvmx_helper_link_autoconf(FIX_IPD_OUTPORT);
+
+	CVMX_SYNC;
+	if (num_segs)
+		cvmx_dprintf("WARNING: FIX_IPD_PTR_ALIGNMENT failed.\n");
+
+	return !!num_segs;
+
+}
+
+/**
+ * Called after all internal packet IO paths are setup. This
+ * function enables IPD/PIP and begins packet input and output.
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_ipd_and_packet_input_enable(void)
+{
+	int num_interfaces;
+	int interface;
+
+	/* Enable IPD */
+	cvmx_ipd_enable();
+
+	/*
+	 * Time to enable hardware ports packet input and output. Note
+	 * that at this point IPD/PIP must be fully functional and PKO
+	 * must be disabled
+	 */
+	num_interfaces = cvmx_helper_get_number_of_interfaces();
+	for (interface = 0; interface < num_interfaces; interface++) {
+		if (cvmx_helper_ports_on_interface(interface) > 0)
+			__cvmx_helper_packet_hardware_enable(interface);
+	}
+
+	/* Finally enable PKO now that the entire path is up and running */
+	cvmx_pko_enable();
+
+	if ((OCTEON_IS_MODEL(OCTEON_CN31XX_PASS1)
+	     || OCTEON_IS_MODEL(OCTEON_CN30XX_PASS1))
+	    && (cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM))
+		__cvmx_helper_errata_fix_ipd_ptr_alignment();
+	return 0;
+}
+
+/**
+ * Initialize the PIP, IPD, and PKO hardware to support
+ * simple priority based queues for the ethernet ports. Each
+ * port is configured with a number of priority queues based
+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
+ * priority than the previous.
+ *
+ * Returns Zero on success, non-zero on failure
+ */
+int cvmx_helper_initialize_packet_io_global(void)
+{
+	int result = 0;
+	int interface;
+	union cvmx_l2c_cfg l2c_cfg;
+	union cvmx_smix_en smix_en;
+	const int num_interfaces = cvmx_helper_get_number_of_interfaces();
+
+	/*
+	 * CN52XX pass 1: Due to a bug in 2nd order CDR, it needs to
+	 * be disabled.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_0))
+		__cvmx_helper_errata_qlm_disable_2nd_order_cdr(1);
+
+	/*
+	 * Tell L2 to give the IOB statically higher priority compared
+	 * to the cores. This avoids conditions where IO blocks might
+	 * be starved under very high L2 loads.
+	 */
+	l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+	l2c_cfg.s.lrf_arb_mode = 0;
+	l2c_cfg.s.rfb_arb_mode = 0;
+	cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64);
+
+	/* Make sure SMI/MDIO is enabled so we can query PHYs */
+	smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0));
+	if (!smix_en.s.en) {
+		smix_en.s.en = 1;
+		cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64);
+	}
+
+	/* Newer chips actually have two SMI/MDIO interfaces */
+	if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) &&
+	    !OCTEON_IS_MODEL(OCTEON_CN58XX) &&
+	    !OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1));
+		if (!smix_en.s.en) {
+			smix_en.s.en = 1;
+			cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64);
+		}
+	}
+
+	cvmx_pko_initialize_global();
+	for (interface = 0; interface < num_interfaces; interface++) {
+		result |= cvmx_helper_interface_probe(interface);
+		if (cvmx_helper_ports_on_interface(interface) > 0)
+			cvmx_dprintf("Interface %d has %d ports (%s)\n",
+				     interface,
+				     cvmx_helper_ports_on_interface(interface),
+				     cvmx_helper_interface_mode_to_string
+				     (cvmx_helper_interface_get_mode
+				      (interface)));
+		result |= __cvmx_helper_interface_setup_ipd(interface);
+		result |= __cvmx_helper_interface_setup_pko(interface);
+	}
+
+	result |= __cvmx_helper_global_setup_ipd();
+	result |= __cvmx_helper_global_setup_pko();
+
+	/* Enable any flow control and backpressure */
+	result |= __cvmx_helper_global_setup_backpressure();
+
+#if CVMX_HELPER_ENABLE_IPD
+	result |= cvmx_helper_ipd_and_packet_input_enable();
+#endif
+	return result;
+}
+
+/**
+ * Does core local initialization for packet io
+ *
+ * Returns Zero on success, non-zero on failure
+ */
+int cvmx_helper_initialize_packet_io_local(void)
+{
+	return cvmx_pko_initialize_local();
+}
+
+/**
+ * Auto configure an IPD/PKO port link state and speed. This
+ * function basically does the equivalent of:
+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
+ *
+ * @ipd_port: IPD/PKO port to auto configure
+ *
+ * Returns Link state after configure
+ */
+cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
+{
+	cvmx_helper_link_info_t link_info;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+
+	if (index >= cvmx_helper_ports_on_interface(interface)) {
+		link_info.u64 = 0;
+		return link_info;
+	}
+
+	link_info = cvmx_helper_link_get(ipd_port);
+	if (link_info.u64 == port_link_info[ipd_port].u64)
+		return link_info;
+
+	/* If we fail to set the link speed, port_link_info will not change */
+	cvmx_helper_link_set(ipd_port, link_info);
+
+	/*
+	 * port_link_info should be the current value, which will be
+	 * different than expect if cvmx_helper_link_set() failed.
+	 */
+	return port_link_info[ipd_port];
+}
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
+{
+	cvmx_helper_link_info_t result;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+
+	/* The default result will be a down link unless the code below
+	   changes it */
+	result.u64 = 0;
+
+	if (index >= cvmx_helper_ports_on_interface(interface))
+		return result;
+
+	switch (cvmx_helper_interface_get_mode(interface)) {
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		/* Network links are not supported */
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		result = __cvmx_helper_xaui_link_get(ipd_port);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		if (index == 0)
+			result = __cvmx_helper_rgmii_link_get(ipd_port);
+		else {
+			result.s.full_duplex = 1;
+			result.s.link_up = 1;
+			result.s.speed = 1000;
+		}
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+		result = __cvmx_helper_rgmii_link_get(ipd_port);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+		result = __cvmx_helper_spi_link_get(ipd_port);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		result = __cvmx_helper_sgmii_link_get(ipd_port);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		/* Network links are not supported */
+		break;
+	}
+	return result;
+}
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
+{
+	int result = -1;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+
+	if (index >= cvmx_helper_ports_on_interface(interface))
+		return -1;
+
+	switch (cvmx_helper_interface_get_mode(interface)) {
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		result = __cvmx_helper_xaui_link_set(ipd_port, link_info);
+		break;
+		/*
+		 * RGMII/GMII/MII are all treated about the same. Most
+		 * functions refer to these ports as RGMII.
+		 */
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		result = __cvmx_helper_rgmii_link_set(ipd_port, link_info);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+		result = __cvmx_helper_spi_link_set(ipd_port, link_info);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		result = __cvmx_helper_sgmii_link_set(ipd_port, link_info);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		break;
+	}
+	/* Set the port_link_info here so that the link status is updated
+	   no matter how cvmx_helper_link_set is called. We don't change
+	   the value if link_set failed */
+	if (result == 0)
+		port_link_info[ipd_port].u64 = link_info.u64;
+	return result;
+}
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
+				   int enable_external)
+{
+	int result = -1;
+	int interface = cvmx_helper_get_interface_num(ipd_port);
+	int index = cvmx_helper_get_interface_index_num(ipd_port);
+
+	if (index >= cvmx_helper_ports_on_interface(interface))
+		return -1;
+
+	switch (cvmx_helper_interface_get_mode(interface)) {
+	case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+	case CVMX_HELPER_INTERFACE_MODE_PCIE:
+	case CVMX_HELPER_INTERFACE_MODE_SPI:
+	case CVMX_HELPER_INTERFACE_MODE_NPI:
+	case CVMX_HELPER_INTERFACE_MODE_LOOP:
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_XAUI:
+		result =
+		    __cvmx_helper_xaui_configure_loopback(ipd_port,
+							  enable_internal,
+							  enable_external);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_RGMII:
+	case CVMX_HELPER_INTERFACE_MODE_GMII:
+		result =
+		    __cvmx_helper_rgmii_configure_loopback(ipd_port,
+							   enable_internal,
+							   enable_external);
+		break;
+	case CVMX_HELPER_INTERFACE_MODE_SGMII:
+	case CVMX_HELPER_INTERFACE_MODE_PICMG:
+		result =
+		    __cvmx_helper_sgmii_configure_loopback(ipd_port,
+							   enable_internal,
+							   enable_external);
+		break;
+	}
+	return result;
+}
diff --git a/drivers/staging/octeon/cvmx-helper.h b/drivers/staging/octeon/cvmx-helper.h
new file mode 100644
index 0000000..51916f3
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-helper.h
@@ -0,0 +1,227 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Helper functions for common, but complicated tasks.
+ *
+ */
+
+#ifndef __CVMX_HELPER_H__
+#define __CVMX_HELPER_H__
+
+#include "cvmx-config.h"
+#include "cvmx-fpa.h"
+#include "cvmx-wqe.h"
+
+typedef enum {
+	CVMX_HELPER_INTERFACE_MODE_DISABLED,
+	CVMX_HELPER_INTERFACE_MODE_RGMII,
+	CVMX_HELPER_INTERFACE_MODE_GMII,
+	CVMX_HELPER_INTERFACE_MODE_SPI,
+	CVMX_HELPER_INTERFACE_MODE_PCIE,
+	CVMX_HELPER_INTERFACE_MODE_XAUI,
+	CVMX_HELPER_INTERFACE_MODE_SGMII,
+	CVMX_HELPER_INTERFACE_MODE_PICMG,
+	CVMX_HELPER_INTERFACE_MODE_NPI,
+	CVMX_HELPER_INTERFACE_MODE_LOOP,
+} cvmx_helper_interface_mode_t;
+
+typedef union {
+	uint64_t u64;
+	struct {
+		uint64_t reserved_20_63:44;
+		uint64_t link_up:1;	    /**< Is the physical link up? */
+		uint64_t full_duplex:1;	    /**< 1 if the link is full duplex */
+		uint64_t speed:18;	    /**< Speed of the link in Mbps */
+	} s;
+} cvmx_helper_link_info_t;
+
+#include "cvmx-helper-fpa.h"
+
+#include <asm/octeon/cvmx-helper-errata.h>
+#include "cvmx-helper-loop.h"
+#include "cvmx-helper-npi.h"
+#include "cvmx-helper-rgmii.h"
+#include "cvmx-helper-sgmii.h"
+#include "cvmx-helper-spi.h"
+#include "cvmx-helper-util.h"
+#include "cvmx-helper-xaui.h"
+
+/**
+ * cvmx_override_pko_queue_priority(int ipd_port, uint64_t
+ * priorities[16]) is a function pointer. It is meant to allow
+ * customization of the PKO queue priorities based on the port
+ * number. Users should set this pointer to a function before
+ * calling any cvmx-helper operations.
+ */
+extern void (*cvmx_override_pko_queue_priority) (int pko_port,
+						 uint64_t priorities[16]);
+
+/**
+ * cvmx_override_ipd_port_setup(int ipd_port) is a function
+ * pointer. It is meant to allow customization of the IPD port
+ * setup before packet input/output comes online. It is called
+ * after cvmx-helper does the default IPD configuration, but
+ * before IPD is enabled. Users should set this pointer to a
+ * function before calling any cvmx-helper operations.
+ */
+extern void (*cvmx_override_ipd_port_setup) (int ipd_port);
+
+/**
+ * This function enables the IPD and also enables the packet interfaces.
+ * The packet interfaces (RGMII and SPI) must be enabled after the
+ * IPD.  This should be called by the user program after any additional
+ * IPD configuration changes are made if CVMX_HELPER_ENABLE_IPD
+ * is not set in the executive-config.h file.
+ *
+ * Returns 0 on success
+ *         -1 on failure
+ */
+extern int cvmx_helper_ipd_and_packet_input_enable(void);
+
+/**
+ * Initialize the PIP, IPD, and PKO hardware to support
+ * simple priority based queues for the ethernet ports. Each
+ * port is configured with a number of priority queues based
+ * on CVMX_PKO_QUEUES_PER_PORT_* where each queue is lower
+ * priority than the previous.
+ *
+ * Returns Zero on success, non-zero on failure
+ */
+extern int cvmx_helper_initialize_packet_io_global(void);
+
+/**
+ * Does core local initialization for packet io
+ *
+ * Returns Zero on success, non-zero on failure
+ */
+extern int cvmx_helper_initialize_packet_io_local(void);
+
+/**
+ * Returns the number of ports on the given interface.
+ * The interface must be initialized before the port count
+ * can be returned.
+ *
+ * @interface: Which interface to return port count for.
+ *
+ * Returns Port count for interface
+ *         -1 for uninitialized interface
+ */
+extern int cvmx_helper_ports_on_interface(int interface);
+
+/**
+ * Return the number of interfaces the chip has. Each interface
+ * may have multiple ports. Most chips support two interfaces,
+ * but the CNX0XX and CNX1XX are exceptions. These only support
+ * one interface.
+ *
+ * Returns Number of interfaces on chip
+ */
+extern int cvmx_helper_get_number_of_interfaces(void);
+
+/**
+ * Get the operating mode of an interface. Depending on the Octeon
+ * chip and configuration, this function returns an enumeration
+ * of the type of packet I/O supported by an interface.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Mode of the interface. Unknown or unsupported interfaces return
+ *         DISABLED.
+ */
+extern cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int
+								   interface);
+
+/**
+ * Auto configure an IPD/PKO port link state and speed. This
+ * function basically does the equivalent of:
+ * cvmx_helper_link_set(ipd_port, cvmx_helper_link_get(ipd_port));
+ *
+ * @ipd_port: IPD/PKO port to auto configure
+ *
+ * Returns Link state after configure
+ */
+extern cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port);
+
+/**
+ * Return the link state of an IPD/PKO port as returned by
+ * auto negotiation. The result of this function may not match
+ * Octeon's link config if auto negotiation has changed since
+ * the last call to cvmx_helper_link_set().
+ *
+ * @ipd_port: IPD/PKO port to query
+ *
+ * Returns Link state
+ */
+extern cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port);
+
+/**
+ * Configure an IPD/PKO port for the specified link state. This
+ * function does not influence auto negotiation at the PHY level.
+ * The passed link state must always match the link state returned
+ * by cvmx_helper_link_get(). It is normally best to use
+ * cvmx_helper_link_autoconf() instead.
+ *
+ * @ipd_port:  IPD/PKO port to configure
+ * @link_info: The new link state
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int cvmx_helper_link_set(int ipd_port,
+				cvmx_helper_link_info_t link_info);
+
+/**
+ * This function probes an interface to determine the actual
+ * number of hardware ports connected to it. It doesn't setup the
+ * ports or enable them. The main goal here is to set the global
+ * interface_port_count[interface] correctly. Hardware setup of the
+ * ports will be performed later.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int cvmx_helper_interface_probe(int interface);
+
+/**
+ * Configure a port for internal and/or external loopback. Internal loopback
+ * causes packets sent by the port to be received by Octeon. External loopback
+ * causes packets received from the wire to sent out again.
+ *
+ * @ipd_port: IPD/PKO port to loopback.
+ * @enable_internal:
+ *                 Non zero if you want internal loopback
+ * @enable_external:
+ *                 Non zero if you want external loopback
+ *
+ * Returns Zero on success, negative on failure.
+ */
+extern int cvmx_helper_configure_loopback(int ipd_port, int enable_internal,
+					  int enable_external);
+
+#endif /* __CVMX_HELPER_H__ */
diff --git a/drivers/staging/octeon/cvmx-interrupt-decodes.c b/drivers/staging/octeon/cvmx-interrupt-decodes.c
new file mode 100644
index 0000000..a3337e3
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-interrupt-decodes.c
@@ -0,0 +1,371 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2009 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Automatically generated functions useful for enabling
+ * and decoding RSL_INT_BLOCKS interrupts.
+ *
+ */
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-gmxx-defs.h"
+#include "cvmx-pcsx-defs.h"
+#include "cvmx-pcsxx-defs.h"
+#include "cvmx-spxx-defs.h"
+#include "cvmx-stxx-defs.h"
+
+#ifndef PRINT_ERROR
+#define PRINT_ERROR(format, ...)
+#endif
+
+
+/**
+ * __cvmx_interrupt_gmxx_rxx_int_en_enable enables all interrupt bits in cvmx_gmxx_rxx_int_en_t
+ */
+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block)
+{
+	union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
+	cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, block),
+		       cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, block)));
+	gmx_rx_int_en.u64 = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_29_63 */
+		gmx_rx_int_en.s.hg2cc = 1;
+		gmx_rx_int_en.s.hg2fld = 1;
+		gmx_rx_int_en.s.undat = 1;
+		gmx_rx_int_en.s.uneop = 1;
+		gmx_rx_int_en.s.unsop = 1;
+		gmx_rx_int_en.s.bad_term = 1;
+		gmx_rx_int_en.s.bad_seq = 1;
+		gmx_rx_int_en.s.rem_fault = 1;
+		gmx_rx_int_en.s.loc_fault = 1;
+		gmx_rx_int_en.s.pause_drp = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_16_18 */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_9_9 */
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_5_6 */
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_2_2 */
+		gmx_rx_int_en.s.carext = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_0_0 */
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_19_63 */
+		/*gmx_rx_int_en.s.phy_dupx = 1; */
+		/*gmx_rx_int_en.s.phy_spd = 1; */
+		/*gmx_rx_int_en.s.phy_link = 1; */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		gmx_rx_int_en.s.niberr = 1;
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
+		gmx_rx_int_en.s.alnerr = 1;
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		gmx_rx_int_en.s.maxerr = 1;
+		gmx_rx_int_en.s.carext = 1;
+		gmx_rx_int_en.s.minerr = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_20_63 */
+		gmx_rx_int_en.s.pause_drp = 1;
+		/*gmx_rx_int_en.s.phy_dupx = 1; */
+		/*gmx_rx_int_en.s.phy_spd = 1; */
+		/*gmx_rx_int_en.s.phy_link = 1; */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		gmx_rx_int_en.s.niberr = 1;
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_6_6 */
+		gmx_rx_int_en.s.alnerr = 1;
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_2_2 */
+		gmx_rx_int_en.s.carext = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_0_0 */
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_19_63 */
+		/*gmx_rx_int_en.s.phy_dupx = 1; */
+		/*gmx_rx_int_en.s.phy_spd = 1; */
+		/*gmx_rx_int_en.s.phy_link = 1; */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		gmx_rx_int_en.s.niberr = 1;
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
+		gmx_rx_int_en.s.alnerr = 1;
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		gmx_rx_int_en.s.maxerr = 1;
+		gmx_rx_int_en.s.carext = 1;
+		gmx_rx_int_en.s.minerr = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN31XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_19_63 */
+		/*gmx_rx_int_en.s.phy_dupx = 1; */
+		/*gmx_rx_int_en.s.phy_spd = 1; */
+		/*gmx_rx_int_en.s.phy_link = 1; */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		gmx_rx_int_en.s.niberr = 1;
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
+		gmx_rx_int_en.s.alnerr = 1;
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		gmx_rx_int_en.s.maxerr = 1;
+		gmx_rx_int_en.s.carext = 1;
+		gmx_rx_int_en.s.minerr = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_20_63 */
+		gmx_rx_int_en.s.pause_drp = 1;
+		/*gmx_rx_int_en.s.phy_dupx = 1; */
+		/*gmx_rx_int_en.s.phy_spd = 1; */
+		/*gmx_rx_int_en.s.phy_link = 1; */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		gmx_rx_int_en.s.niberr = 1;
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/*gmx_rx_int_en.s.lenerr = 1; // Length errors are handled when we get work */
+		gmx_rx_int_en.s.alnerr = 1;
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		gmx_rx_int_en.s.maxerr = 1;
+		gmx_rx_int_en.s.carext = 1;
+		gmx_rx_int_en.s.minerr = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		/* Skipping gmx_rx_int_en.s.reserved_29_63 */
+		gmx_rx_int_en.s.hg2cc = 1;
+		gmx_rx_int_en.s.hg2fld = 1;
+		gmx_rx_int_en.s.undat = 1;
+		gmx_rx_int_en.s.uneop = 1;
+		gmx_rx_int_en.s.unsop = 1;
+		gmx_rx_int_en.s.bad_term = 1;
+		gmx_rx_int_en.s.bad_seq = 0;
+		gmx_rx_int_en.s.rem_fault = 1;
+		gmx_rx_int_en.s.loc_fault = 0;
+		gmx_rx_int_en.s.pause_drp = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_16_18 */
+		/*gmx_rx_int_en.s.ifgerr = 1; */
+		/*gmx_rx_int_en.s.coldet = 1; // Collsion detect */
+		/*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */
+		/*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */
+		/*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */
+		gmx_rx_int_en.s.ovrerr = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_9_9 */
+		gmx_rx_int_en.s.skperr = 1;
+		gmx_rx_int_en.s.rcverr = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_5_6 */
+		/*gmx_rx_int_en.s.fcserr = 1; // FCS errors are handled when we get work */
+		gmx_rx_int_en.s.jabber = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_2_2 */
+		gmx_rx_int_en.s.carext = 1;
+		/* Skipping gmx_rx_int_en.s.reserved_0_0 */
+	}
+	cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, block), gmx_rx_int_en.u64);
+}
+/**
+ * __cvmx_interrupt_pcsx_intx_en_reg_enable enables all interrupt bits in cvmx_pcsx_intx_en_reg_t
+ */
+void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block)
+{
+	union cvmx_pcsx_intx_en_reg pcs_int_en_reg;
+	cvmx_write_csr(CVMX_PCSX_INTX_REG(index, block),
+		       cvmx_read_csr(CVMX_PCSX_INTX_REG(index, block)));
+	pcs_int_en_reg.u64 = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+		/* Skipping pcs_int_en_reg.s.reserved_12_63 */
+		/*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
+		pcs_int_en_reg.s.sync_bad_en = 1;
+		pcs_int_en_reg.s.an_bad_en = 1;
+		pcs_int_en_reg.s.rxlock_en = 1;
+		pcs_int_en_reg.s.rxbad_en = 1;
+		/*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
+		pcs_int_en_reg.s.txbad_en = 1;
+		pcs_int_en_reg.s.txfifo_en = 1;
+		pcs_int_en_reg.s.txfifu_en = 1;
+		pcs_int_en_reg.s.an_err_en = 1;
+		/*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
+		/*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		/* Skipping pcs_int_en_reg.s.reserved_12_63 */
+		/*pcs_int_en_reg.s.dup = 1; // This happens during normal operation */
+		pcs_int_en_reg.s.sync_bad_en = 1;
+		pcs_int_en_reg.s.an_bad_en = 1;
+		pcs_int_en_reg.s.rxlock_en = 1;
+		pcs_int_en_reg.s.rxbad_en = 1;
+		/*pcs_int_en_reg.s.rxerr_en = 1; // This happens during normal operation */
+		pcs_int_en_reg.s.txbad_en = 1;
+		pcs_int_en_reg.s.txfifo_en = 1;
+		pcs_int_en_reg.s.txfifu_en = 1;
+		pcs_int_en_reg.s.an_err_en = 1;
+		/*pcs_int_en_reg.s.xmit_en = 1; // This happens during normal operation */
+		/*pcs_int_en_reg.s.lnkspd_en = 1; // This happens during normal operation */
+	}
+	cvmx_write_csr(CVMX_PCSX_INTX_EN_REG(index, block), pcs_int_en_reg.u64);
+}
+/**
+ * __cvmx_interrupt_pcsxx_int_en_reg_enable enables all interrupt bits in cvmx_pcsxx_int_en_reg_t
+ */
+void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index)
+{
+	union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
+	cvmx_write_csr(CVMX_PCSXX_INT_REG(index),
+		       cvmx_read_csr(CVMX_PCSXX_INT_REG(index)));
+	pcsx_int_en_reg.u64 = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+		/* Skipping pcsx_int_en_reg.s.reserved_6_63 */
+		pcsx_int_en_reg.s.algnlos_en = 1;
+		pcsx_int_en_reg.s.synlos_en = 1;
+		pcsx_int_en_reg.s.bitlckls_en = 1;
+		pcsx_int_en_reg.s.rxsynbad_en = 1;
+		pcsx_int_en_reg.s.rxbad_en = 1;
+		pcsx_int_en_reg.s.txflt_en = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		/* Skipping pcsx_int_en_reg.s.reserved_6_63 */
+		pcsx_int_en_reg.s.algnlos_en = 1;
+		pcsx_int_en_reg.s.synlos_en = 1;
+		pcsx_int_en_reg.s.bitlckls_en = 0;	/* Happens if XAUI module is not installed */
+		pcsx_int_en_reg.s.rxsynbad_en = 1;
+		pcsx_int_en_reg.s.rxbad_en = 1;
+		pcsx_int_en_reg.s.txflt_en = 1;
+	}
+	cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(index), pcsx_int_en_reg.u64);
+}
+
+/**
+ * __cvmx_interrupt_spxx_int_msk_enable enables all interrupt bits in cvmx_spxx_int_msk_t
+ */
+void __cvmx_interrupt_spxx_int_msk_enable(int index)
+{
+	union cvmx_spxx_int_msk spx_int_msk;
+	cvmx_write_csr(CVMX_SPXX_INT_REG(index),
+		       cvmx_read_csr(CVMX_SPXX_INT_REG(index)));
+	spx_int_msk.u64 = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+		/* Skipping spx_int_msk.s.reserved_12_63 */
+		spx_int_msk.s.calerr = 1;
+		spx_int_msk.s.syncerr = 1;
+		spx_int_msk.s.diperr = 1;
+		spx_int_msk.s.tpaovr = 1;
+		spx_int_msk.s.rsverr = 1;
+		spx_int_msk.s.drwnng = 1;
+		spx_int_msk.s.clserr = 1;
+		spx_int_msk.s.spiovr = 1;
+		/* Skipping spx_int_msk.s.reserved_2_3 */
+		spx_int_msk.s.abnorm = 1;
+		spx_int_msk.s.prtnxa = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+		/* Skipping spx_int_msk.s.reserved_12_63 */
+		spx_int_msk.s.calerr = 1;
+		spx_int_msk.s.syncerr = 1;
+		spx_int_msk.s.diperr = 1;
+		spx_int_msk.s.tpaovr = 1;
+		spx_int_msk.s.rsverr = 1;
+		spx_int_msk.s.drwnng = 1;
+		spx_int_msk.s.clserr = 1;
+		spx_int_msk.s.spiovr = 1;
+		/* Skipping spx_int_msk.s.reserved_2_3 */
+		spx_int_msk.s.abnorm = 1;
+		spx_int_msk.s.prtnxa = 1;
+	}
+	cvmx_write_csr(CVMX_SPXX_INT_MSK(index), spx_int_msk.u64);
+}
+/**
+ * __cvmx_interrupt_stxx_int_msk_enable enables all interrupt bits in cvmx_stxx_int_msk_t
+ */
+void __cvmx_interrupt_stxx_int_msk_enable(int index)
+{
+	union cvmx_stxx_int_msk stx_int_msk;
+	cvmx_write_csr(CVMX_STXX_INT_REG(index),
+		       cvmx_read_csr(CVMX_STXX_INT_REG(index)));
+	stx_int_msk.u64 = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+		/* Skipping stx_int_msk.s.reserved_8_63 */
+		stx_int_msk.s.frmerr = 1;
+		stx_int_msk.s.unxfrm = 1;
+		stx_int_msk.s.nosync = 1;
+		stx_int_msk.s.diperr = 1;
+		stx_int_msk.s.datovr = 1;
+		stx_int_msk.s.ovrbst = 1;
+		stx_int_msk.s.calpar1 = 1;
+		stx_int_msk.s.calpar0 = 1;
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+		/* Skipping stx_int_msk.s.reserved_8_63 */
+		stx_int_msk.s.frmerr = 1;
+		stx_int_msk.s.unxfrm = 1;
+		stx_int_msk.s.nosync = 1;
+		stx_int_msk.s.diperr = 1;
+		stx_int_msk.s.datovr = 1;
+		stx_int_msk.s.ovrbst = 1;
+		stx_int_msk.s.calpar1 = 1;
+		stx_int_msk.s.calpar0 = 1;
+	}
+	cvmx_write_csr(CVMX_STXX_INT_MSK(index), stx_int_msk.u64);
+}
diff --git a/drivers/staging/octeon/cvmx-interrupt-rsl.c b/drivers/staging/octeon/cvmx-interrupt-rsl.c
new file mode 100644
index 0000000..df50048
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-interrupt-rsl.c
@@ -0,0 +1,140 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Utility functions to decode Octeon's RSL_INT_BLOCKS
+ * interrupts into error messages.
+ */
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-asxx-defs.h"
+#include "cvmx-gmxx-defs.h"
+
+#ifndef PRINT_ERROR
+#define PRINT_ERROR(format, ...)
+#endif
+
+void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block);
+
+/**
+ * Enable ASX error interrupts that exist on CN3XXX, CN50XX, and
+ * CN58XX.
+ *
+ * @block:  Interface to enable 0-1
+ */
+void __cvmx_interrupt_asxx_enable(int block)
+{
+	int mask;
+	union cvmx_asxx_int_en csr;
+	/*
+	 * CN38XX and CN58XX have two interfaces with 4 ports per
+	 * interface. All other chips have a max of 3 ports on
+	 * interface 0
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
+		mask = 0xf;	/* Set enables for 4 ports */
+	else
+		mask = 0x7;	/* Set enables for 3 ports */
+
+	/* Enable interface interrupts */
+	csr.u64 = cvmx_read_csr(CVMX_ASXX_INT_EN(block));
+	csr.s.txpsh = mask;
+	csr.s.txpop = mask;
+	csr.s.ovrflw = mask;
+	cvmx_write_csr(CVMX_ASXX_INT_EN(block), csr.u64);
+}
+/**
+ * Enable GMX error reporting for the supplied interface
+ *
+ * @interface: Interface to enable
+ */
+void __cvmx_interrupt_gmxx_enable(int interface)
+{
+	union cvmx_gmxx_inf_mode mode;
+	union cvmx_gmxx_tx_int_en gmx_tx_int_en;
+	int num_ports;
+	int index;
+
+	mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		if (mode.s.en) {
+			switch (mode.cn56xx.mode) {
+			case 1:	/* XAUI */
+				num_ports = 1;
+				break;
+			case 2:	/* SGMII */
+			case 3:	/* PICMG */
+				num_ports = 4;
+				break;
+			default:	/* Disabled */
+				num_ports = 0;
+				break;
+			}
+		} else
+			num_ports = 0;
+	} else {
+		if (mode.s.en) {
+			if (OCTEON_IS_MODEL(OCTEON_CN38XX)
+			    || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+				/*
+				 * SPI on CN38XX and CN58XX report all
+				 * errors through port 0.  RGMII needs
+				 * to check all 4 ports
+				 */
+				if (mode.s.type)
+					num_ports = 1;
+				else
+					num_ports = 4;
+			} else {
+				/*
+				 * CN30XX, CN31XX, and CN50XX have two
+				 * or three ports. GMII and MII has 2,
+				 * RGMII has three
+				 */
+				if (mode.s.type)
+					num_ports = 2;
+				else
+					num_ports = 3;
+			}
+		} else
+			num_ports = 0;
+	}
+
+	gmx_tx_int_en.u64 = 0;
+	if (num_ports) {
+		if (OCTEON_IS_MODEL(OCTEON_CN38XX)
+		    || OCTEON_IS_MODEL(OCTEON_CN58XX))
+			gmx_tx_int_en.s.ncb_nxa = 1;
+		gmx_tx_int_en.s.pko_nxa = 1;
+	}
+	gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
+	cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64);
+	for (index = 0; index < num_ports; index++)
+		__cvmx_interrupt_gmxx_rxx_int_en_enable(index, interface);
+}
diff --git a/drivers/staging/octeon/cvmx-ipd.h b/drivers/staging/octeon/cvmx-ipd.h
new file mode 100644
index 0000000..115a552
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-ipd.h
@@ -0,0 +1,338 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Interface to the hardware Input Packet Data unit.
+ */
+
+#ifndef __CVMX_IPD_H__
+#define __CVMX_IPD_H__
+
+#include <asm/octeon/octeon-feature.h>
+
+#include <asm/octeon/cvmx-ipd-defs.h>
+
+enum cvmx_ipd_mode {
+   CVMX_IPD_OPC_MODE_STT = 0LL,   /* All blocks DRAM, not cached in L2 */
+   CVMX_IPD_OPC_MODE_STF = 1LL,   /* All bloccks into  L2 */
+   CVMX_IPD_OPC_MODE_STF1_STT = 2LL,   /* 1st block L2, rest DRAM */
+   CVMX_IPD_OPC_MODE_STF2_STT = 3LL    /* 1st, 2nd blocks L2, rest DRAM */
+};
+
+#ifndef CVMX_ENABLE_LEN_M8_FIX
+#define CVMX_ENABLE_LEN_M8_FIX 0
+#endif
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t;
+typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t;
+
+typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t;
+typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t;
+
+/**
+ * Configure IPD
+ *
+ * @mbuff_size: Packets buffer size in 8 byte words
+ * @first_mbuff_skip:
+ *                   Number of 8 byte words to skip in the first buffer
+ * @not_first_mbuff_skip:
+ *                   Number of 8 byte words to skip in each following buffer
+ * @first_back: Must be same as first_mbuff_skip / 128
+ * @second_back:
+ *                   Must be same as not_first_mbuff_skip / 128
+ * @wqe_fpa_pool:
+ *                   FPA pool to get work entries from
+ * @cache_mode:
+ * @back_pres_enable_flag:
+ *                   Enable or disable port back pressure
+ */
+static inline void cvmx_ipd_config(uint64_t mbuff_size,
+				   uint64_t first_mbuff_skip,
+				   uint64_t not_first_mbuff_skip,
+				   uint64_t first_back,
+				   uint64_t second_back,
+				   uint64_t wqe_fpa_pool,
+				   enum cvmx_ipd_mode cache_mode,
+				   uint64_t back_pres_enable_flag)
+{
+	cvmx_ipd_mbuff_first_skip_t first_skip;
+	cvmx_ipd_mbuff_not_first_skip_t not_first_skip;
+	union cvmx_ipd_packet_mbuff_size size;
+	cvmx_ipd_first_next_ptr_back_t first_back_struct;
+	cvmx_ipd_second_next_ptr_back_t second_back_struct;
+	union cvmx_ipd_wqe_fpa_queue wqe_pool;
+	union cvmx_ipd_ctl_status ipd_ctl_reg;
+
+	first_skip.u64 = 0;
+	first_skip.s.skip_sz = first_mbuff_skip;
+	cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64);
+
+	not_first_skip.u64 = 0;
+	not_first_skip.s.skip_sz = not_first_mbuff_skip;
+	cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64);
+
+	size.u64 = 0;
+	size.s.mb_size = mbuff_size;
+	cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
+
+	first_back_struct.u64 = 0;
+	first_back_struct.s.back = first_back;
+	cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64);
+
+	second_back_struct.u64 = 0;
+	second_back_struct.s.back = second_back;
+	cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64);
+
+	wqe_pool.u64 = 0;
+	wqe_pool.s.wqe_pool = wqe_fpa_pool;
+	cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64);
+
+	ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+	ipd_ctl_reg.s.opc_mode = cache_mode;
+	ipd_ctl_reg.s.pbp_en = back_pres_enable_flag;
+	cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64);
+
+	/* Note: the example RED code that used to be here has been moved to
+	   cvmx_helper_setup_red */
+}
+
+/**
+ * Enable IPD
+ */
+static inline void cvmx_ipd_enable(void)
+{
+	union cvmx_ipd_ctl_status ipd_reg;
+	ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+	if (ipd_reg.s.ipd_en) {
+		cvmx_dprintf
+		    ("Warning: Enabling IPD when IPD already enabled.\n");
+	}
+	ipd_reg.s.ipd_en = 1;
+#if  CVMX_ENABLE_LEN_M8_FIX
+	if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
+		ipd_reg.s.len_m8 = TRUE;
+#endif
+	cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
+}
+
+/**
+ * Disable IPD
+ */
+static inline void cvmx_ipd_disable(void)
+{
+	union cvmx_ipd_ctl_status ipd_reg;
+	ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+	ipd_reg.s.ipd_en = 0;
+	cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
+}
+
+/**
+ * Supportive function for cvmx_fpa_shutdown_pool.
+ */
+static inline void cvmx_ipd_free_ptr(void)
+{
+	/* Only CN38XXp{1,2} cannot read pointer out of the IPD */
+	if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
+	    && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
+		int no_wptr = 0;
+		union cvmx_ipd_ptr_count ipd_ptr_count;
+		ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
+
+		/* Handle Work Queue Entry in cn56xx and cn52xx */
+		if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
+			union cvmx_ipd_ctl_status ipd_ctl_status;
+			ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+			if (ipd_ctl_status.s.no_wptr)
+				no_wptr = 1;
+		}
+
+		/* Free the prefetched WQE */
+		if (ipd_ptr_count.s.wqev_cnt) {
+			union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid;
+			ipd_wqe_ptr_valid.u64 =
+			    cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
+			if (no_wptr)
+				cvmx_fpa_free(cvmx_phys_to_ptr
+					      ((uint64_t) ipd_wqe_ptr_valid.s.
+					       ptr << 7), CVMX_FPA_PACKET_POOL,
+					      0);
+			else
+				cvmx_fpa_free(cvmx_phys_to_ptr
+					      ((uint64_t) ipd_wqe_ptr_valid.s.
+					       ptr << 7), CVMX_FPA_WQE_POOL, 0);
+		}
+
+		/* Free all WQE in the fifo */
+		if (ipd_ptr_count.s.wqe_pcnt) {
+			int i;
+			union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
+			ipd_pwp_ptr_fifo_ctl.u64 =
+			    cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
+			for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
+				ipd_pwp_ptr_fifo_ctl.s.cena = 0;
+				ipd_pwp_ptr_fifo_ctl.s.raddr =
+				    ipd_pwp_ptr_fifo_ctl.s.max_cnts +
+				    (ipd_pwp_ptr_fifo_ctl.s.wraddr +
+				     i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
+				cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
+					       ipd_pwp_ptr_fifo_ctl.u64);
+				ipd_pwp_ptr_fifo_ctl.u64 =
+				    cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
+				if (no_wptr)
+					cvmx_fpa_free(cvmx_phys_to_ptr
+						      ((uint64_t)
+						       ipd_pwp_ptr_fifo_ctl.s.
+						       ptr << 7),
+						      CVMX_FPA_PACKET_POOL, 0);
+				else
+					cvmx_fpa_free(cvmx_phys_to_ptr
+						      ((uint64_t)
+						       ipd_pwp_ptr_fifo_ctl.s.
+						       ptr << 7),
+						      CVMX_FPA_WQE_POOL, 0);
+			}
+			ipd_pwp_ptr_fifo_ctl.s.cena = 1;
+			cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
+				       ipd_pwp_ptr_fifo_ctl.u64);
+		}
+
+		/* Free the prefetched packet */
+		if (ipd_ptr_count.s.pktv_cnt) {
+			union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid;
+			ipd_pkt_ptr_valid.u64 =
+			    cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
+			cvmx_fpa_free(cvmx_phys_to_ptr
+				      (ipd_pkt_ptr_valid.s.ptr << 7),
+				      CVMX_FPA_PACKET_POOL, 0);
+		}
+
+		/* Free the per port prefetched packets */
+		if (1) {
+			int i;
+			union cvmx_ipd_prc_port_ptr_fifo_ctl
+			    ipd_prc_port_ptr_fifo_ctl;
+			ipd_prc_port_ptr_fifo_ctl.u64 =
+			    cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
+
+			for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
+			     i++) {
+				ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
+				ipd_prc_port_ptr_fifo_ctl.s.raddr =
+				    i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
+				cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
+					       ipd_prc_port_ptr_fifo_ctl.u64);
+				ipd_prc_port_ptr_fifo_ctl.u64 =
+				    cvmx_read_csr
+				    (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
+				cvmx_fpa_free(cvmx_phys_to_ptr
+					      ((uint64_t)
+					       ipd_prc_port_ptr_fifo_ctl.s.
+					       ptr << 7), CVMX_FPA_PACKET_POOL,
+					      0);
+			}
+			ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
+			cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
+				       ipd_prc_port_ptr_fifo_ctl.u64);
+		}
+
+		/* Free all packets in the holding fifo */
+		if (ipd_ptr_count.s.pfif_cnt) {
+			int i;
+			union cvmx_ipd_prc_hold_ptr_fifo_ctl
+			    ipd_prc_hold_ptr_fifo_ctl;
+
+			ipd_prc_hold_ptr_fifo_ctl.u64 =
+			    cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
+
+			for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
+				ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
+				ipd_prc_hold_ptr_fifo_ctl.s.raddr =
+				    (ipd_prc_hold_ptr_fifo_ctl.s.praddr +
+				     i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
+				cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
+					       ipd_prc_hold_ptr_fifo_ctl.u64);
+				ipd_prc_hold_ptr_fifo_ctl.u64 =
+				    cvmx_read_csr
+				    (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
+				cvmx_fpa_free(cvmx_phys_to_ptr
+					      ((uint64_t)
+					       ipd_prc_hold_ptr_fifo_ctl.s.
+					       ptr << 7), CVMX_FPA_PACKET_POOL,
+					      0);
+			}
+			ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
+			cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
+				       ipd_prc_hold_ptr_fifo_ctl.u64);
+		}
+
+		/* Free all packets in the fifo */
+		if (ipd_ptr_count.s.pkt_pcnt) {
+			int i;
+			union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
+			ipd_pwp_ptr_fifo_ctl.u64 =
+			    cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
+
+			for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
+				ipd_pwp_ptr_fifo_ctl.s.cena = 0;
+				ipd_pwp_ptr_fifo_ctl.s.raddr =
+				    (ipd_pwp_ptr_fifo_ctl.s.praddr +
+				     i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
+				cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
+					       ipd_pwp_ptr_fifo_ctl.u64);
+				ipd_pwp_ptr_fifo_ctl.u64 =
+				    cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
+				cvmx_fpa_free(cvmx_phys_to_ptr
+					      ((uint64_t) ipd_pwp_ptr_fifo_ctl.
+					       s.ptr << 7),
+					      CVMX_FPA_PACKET_POOL, 0);
+			}
+			ipd_pwp_ptr_fifo_ctl.s.cena = 1;
+			cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
+				       ipd_pwp_ptr_fifo_ctl.u64);
+		}
+
+		/* Reset the IPD to get all buffers out of it */
+		{
+			union cvmx_ipd_ctl_status ipd_ctl_status;
+			ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
+			ipd_ctl_status.s.reset = 1;
+			cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
+		}
+
+		/* Reset the PIP */
+		{
+			union cvmx_pip_sft_rst pip_sft_rst;
+			pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
+			pip_sft_rst.s.rst = 1;
+			cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64);
+		}
+	}
+}
+
+#endif /*  __CVMX_IPD_H__ */
diff --git a/drivers/staging/octeon/cvmx-mdio.h b/drivers/staging/octeon/cvmx-mdio.h
new file mode 100644
index 0000000..c987a75
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-mdio.h
@@ -0,0 +1,506 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3
+ * clause 22 and clause 45 operations.
+ *
+ */
+
+#ifndef __CVMX_MIO_H__
+#define __CVMX_MIO_H__
+
+#include "cvmx-smix-defs.h"
+
+/**
+ * PHY register 0 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_CONTROL 0
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t reset:1;
+		uint16_t loopback:1;
+		uint16_t speed_lsb:1;
+		uint16_t autoneg_enable:1;
+		uint16_t power_down:1;
+		uint16_t isolate:1;
+		uint16_t restart_autoneg:1;
+		uint16_t duplex:1;
+		uint16_t collision_test:1;
+		uint16_t speed_msb:1;
+		uint16_t unidirectional_enable:1;
+		uint16_t reserved_0_4:5;
+	} s;
+} cvmx_mdio_phy_reg_control_t;
+
+/**
+ * PHY register 1 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_STATUS 1
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t capable_100base_t4:1;
+		uint16_t capable_100base_x_full:1;
+		uint16_t capable_100base_x_half:1;
+		uint16_t capable_10_full:1;
+		uint16_t capable_10_half:1;
+		uint16_t capable_100base_t2_full:1;
+		uint16_t capable_100base_t2_half:1;
+		uint16_t capable_extended_status:1;
+		uint16_t capable_unidirectional:1;
+		uint16_t capable_mf_preamble_suppression:1;
+		uint16_t autoneg_complete:1;
+		uint16_t remote_fault:1;
+		uint16_t capable_autoneg:1;
+		uint16_t link_status:1;
+		uint16_t jabber_detect:1;
+		uint16_t capable_extended_registers:1;
+
+	} s;
+} cvmx_mdio_phy_reg_status_t;
+
+/**
+ * PHY register 2 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_ID1 2
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t oui_bits_3_18;
+	} s;
+} cvmx_mdio_phy_reg_id1_t;
+
+/**
+ * PHY register 3 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_ID2 3
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t oui_bits_19_24:6;
+		uint16_t model:6;
+		uint16_t revision:4;
+	} s;
+} cvmx_mdio_phy_reg_id2_t;
+
+/**
+ * PHY register 4 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t next_page:1;
+		uint16_t reserved_14:1;
+		uint16_t remote_fault:1;
+		uint16_t reserved_12:1;
+		uint16_t asymmetric_pause:1;
+		uint16_t pause:1;
+		uint16_t advert_100base_t4:1;
+		uint16_t advert_100base_tx_full:1;
+		uint16_t advert_100base_tx_half:1;
+		uint16_t advert_10base_tx_full:1;
+		uint16_t advert_10base_tx_half:1;
+		uint16_t selector:5;
+	} s;
+} cvmx_mdio_phy_reg_autoneg_adver_t;
+
+/**
+ * PHY register 5 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t next_page:1;
+		uint16_t ack:1;
+		uint16_t remote_fault:1;
+		uint16_t reserved_12:1;
+		uint16_t asymmetric_pause:1;
+		uint16_t pause:1;
+		uint16_t advert_100base_t4:1;
+		uint16_t advert_100base_tx_full:1;
+		uint16_t advert_100base_tx_half:1;
+		uint16_t advert_10base_tx_full:1;
+		uint16_t advert_10base_tx_half:1;
+		uint16_t selector:5;
+	} s;
+} cvmx_mdio_phy_reg_link_partner_ability_t;
+
+/**
+ * PHY register 6 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t reserved_5_15:11;
+		uint16_t parallel_detection_fault:1;
+		uint16_t link_partner_next_page_capable:1;
+		uint16_t local_next_page_capable:1;
+		uint16_t page_received:1;
+		uint16_t link_partner_autoneg_capable:1;
+
+	} s;
+} cvmx_mdio_phy_reg_autoneg_expansion_t;
+
+/**
+ * PHY register 9 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_CONTROL_1000 9
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t test_mode:3;
+		uint16_t manual_master_slave:1;
+		uint16_t master:1;
+		uint16_t port_type:1;
+		uint16_t advert_1000base_t_full:1;
+		uint16_t advert_1000base_t_half:1;
+		uint16_t reserved_0_7:8;
+	} s;
+} cvmx_mdio_phy_reg_control_1000_t;
+
+/**
+ * PHY register 10 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_STATUS_1000 10
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t master_slave_fault:1;
+		uint16_t is_master:1;
+		uint16_t local_receiver_ok:1;
+		uint16_t remote_receiver_ok:1;
+		uint16_t remote_capable_1000base_t_full:1;
+		uint16_t remote_capable_1000base_t_half:1;
+		uint16_t reserved_8_9:2;
+		uint16_t idle_error_count:8;
+	} s;
+} cvmx_mdio_phy_reg_status_1000_t;
+
+/**
+ * PHY register 15 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t capable_1000base_x_full:1;
+		uint16_t capable_1000base_x_half:1;
+		uint16_t capable_1000base_t_full:1;
+		uint16_t capable_1000base_t_half:1;
+		uint16_t reserved_0_11:12;
+	} s;
+} cvmx_mdio_phy_reg_extended_status_t;
+
+/**
+ * PHY register 13 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t function:2;
+		uint16_t reserved_5_13:9;
+		uint16_t devad:5;
+	} s;
+} cvmx_mdio_phy_reg_mmd_control_t;
+
+/**
+ * PHY register 14 from the 802.3 spec
+ */
+#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14
+typedef union {
+	uint16_t u16;
+	struct {
+		uint16_t address_data:16;
+	} s;
+} cvmx_mdio_phy_reg_mmd_address_data_t;
+
+/* Operating request encodings. */
+#define MDIO_CLAUSE_22_WRITE    0
+#define MDIO_CLAUSE_22_READ     1
+
+#define MDIO_CLAUSE_45_ADDRESS  0
+#define MDIO_CLAUSE_45_WRITE    1
+#define MDIO_CLAUSE_45_READ_INC 2
+#define MDIO_CLAUSE_45_READ     3
+
+/* MMD identifiers, mostly for accessing devices withing XENPAK modules. */
+#define CVMX_MMD_DEVICE_PMA_PMD      1
+#define CVMX_MMD_DEVICE_WIS          2
+#define CVMX_MMD_DEVICE_PCS          3
+#define CVMX_MMD_DEVICE_PHY_XS       4
+#define CVMX_MMD_DEVICE_DTS_XS       5
+#define CVMX_MMD_DEVICE_TC           6
+#define CVMX_MMD_DEVICE_CL22_EXT     29
+#define CVMX_MMD_DEVICE_VENDOR_1     30
+#define CVMX_MMD_DEVICE_VENDOR_2     31
+
+/* Helper function to put MDIO interface into clause 45 mode */
+static inline void __cvmx_mdio_set_clause45_mode(int bus_id)
+{
+	union cvmx_smix_clk smi_clk;
+	/* Put bus into clause 45 mode */
+	smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
+	smi_clk.s.mode = 1;
+	smi_clk.s.preamble = 1;
+	cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
+}
+
+/* Helper function to put MDIO interface into clause 22 mode */
+static inline void __cvmx_mdio_set_clause22_mode(int bus_id)
+{
+	union cvmx_smix_clk smi_clk;
+	/* Put bus into clause 22 mode */
+	smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id));
+	smi_clk.s.mode = 0;
+	cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64);
+}
+
+/**
+ * Perform an MII read. This function is used to read PHY
+ * registers controlling auto negotiation.
+ *
+ * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @phy_id:   The MII phy id
+ * @location: Register location to read
+ *
+ * Returns Result from the read or -1 on failure
+ */
+static inline int cvmx_mdio_read(int bus_id, int phy_id, int location)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_rd_dat smi_rd;
+	int timeout = 1000;
+
+	if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		__cvmx_mdio_set_clause22_mode(bus_id);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
+	} while (smi_rd.s.pending && timeout--);
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else
+		return -1;
+}
+
+/**
+ * Perform an MII write. This function is used to write PHY
+ * registers controlling auto negotiation.
+ *
+ * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @phy_id:   The MII phy id
+ * @location: Register location to write
+ * @val:      Value to write
+ *
+ * Returns -1 on error
+ *         0 on success
+ */
+static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+	int timeout = 1000;
+
+	if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		__cvmx_mdio_set_clause22_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
+	} while (smi_wr.s.pending && --timeout);
+	if (timeout <= 0)
+		return -1;
+
+	return 0;
+}
+
+/**
+ * Perform an IEEE 802.3 clause 45 MII read. This function is used to
+ * read PHY registers controlling auto negotiation.
+ *
+ * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @phy_id:   The MII phy id
+ * @device:   MDIO Managable Device (MMD) id
+ * @location: Register location to read
+ *
+ * Returns Result from the read or -1 on failure
+ */
+
+static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
+				    int location)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_rd_dat smi_rd;
+	union cvmx_smix_wr_dat smi_wr;
+	int timeout = 1000;
+
+	if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		return -1;
+
+	__cvmx_mdio_set_clause45_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = location;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
+	} while (smi_wr.s.pending && --timeout);
+	if (timeout <= 0) {
+		cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
+			     "device %2d register %2d   TIME OUT(address)\n",
+		     bus_id, phy_id, device, location);
+		return -1;
+	}
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
+	} while (smi_rd.s.pending && timeout--);
+
+	if (timeout <= 0) {
+		cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
+			     "device %2d register %2d   TIME OUT(data)\n",
+		     bus_id, phy_id, device, location);
+		return -1;
+	}
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else {
+		cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
+			     "device %2d register %2d   INVALID READ\n",
+		     bus_id, phy_id, device, location);
+		return -1;
+	}
+}
+
+/**
+ * Perform an IEEE 802.3 clause 45 MII write. This function is used to
+ * write PHY registers controlling auto negotiation.
+ *
+ * @bus_id:   MDIO bus number. Zero on most chips, but some chips (ex CN56XX)
+ *                 support multiple busses.
+ * @phy_id:   The MII phy id
+ * @device:   MDIO Managable Device (MMD) id
+ * @location: Register location to write
+ * @val:      Value to write
+ *
+ * Returns -1 on error
+ *         0 on success
+ */
+static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device,
+				     int location, int val)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+	int timeout = 1000;
+
+	if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45))
+		return -1;
+
+	__cvmx_mdio_set_clause45_mode(bus_id);
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = location;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
+	} while (smi_wr.s.pending && --timeout);
+	if (timeout <= 0)
+		return -1;
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = device;
+	cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64);
+
+	do {
+		cvmx_wait(1000);
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id));
+	} while (smi_wr.s.pending && --timeout);
+	if (timeout <= 0)
+		return -1;
+
+	return 0;
+}
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-packet.h b/drivers/staging/octeon/cvmx-packet.h
new file mode 100644
index 0000000..62ffe78a
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-packet.h
@@ -0,0 +1,65 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Packet buffer defines.
+ */
+
+#ifndef __CVMX_PACKET_H__
+#define __CVMX_PACKET_H__
+
+/**
+ * This structure defines a buffer pointer on Octeon
+ */
+union cvmx_buf_ptr {
+	void *ptr;
+	uint64_t u64;
+	struct {
+		/*
+		 * if set, invert the "free" pick of the overall
+		 * packet. HW always sets this bit to 0 on inbound
+		 * packet
+		 */
+		uint64_t i:1;
+		/*
+		 * Indicates the amount to back up to get to the
+		 * buffer start in cache lines. In most cases this is
+		 * less than one complete cache line, so the value is
+		 * zero.
+		 */
+		uint64_t back:4;
+		/* The pool that the buffer came from / goes to */
+		uint64_t pool:3;
+		/* The size of the segment pointed to by addr (in bytes) */
+		uint64_t size:16;
+		/* Pointer to the first byte of the data, NOT buffer */
+		uint64_t addr:40;
+	} s;
+};
+
+#endif /*  __CVMX_PACKET_H__ */
diff --git a/drivers/staging/octeon/cvmx-pcsx-defs.h b/drivers/staging/octeon/cvmx-pcsx-defs.h
new file mode 100644
index 0000000..d45952d
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pcsx-defs.h
@@ -0,0 +1,370 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCSX_DEFS_H__
+#define __CVMX_PCSX_DEFS_H__
+
+#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_INTX_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_pcsx_anx_adv_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_anx_adv_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t np:1;
+		uint64_t reserved_14_14:1;
+		uint64_t rem_flt:2;
+		uint64_t reserved_9_11:3;
+		uint64_t pause:2;
+		uint64_t hfd:1;
+		uint64_t fd:1;
+		uint64_t reserved_0_4:5;
+	} s;
+	struct cvmx_pcsx_anx_adv_reg_s cn52xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
+	struct cvmx_pcsx_anx_adv_reg_s cn56xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_anx_ext_st_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_anx_ext_st_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t thou_xfd:1;
+		uint64_t thou_xhd:1;
+		uint64_t thou_tfd:1;
+		uint64_t thou_thd:1;
+		uint64_t reserved_0_11:12;
+	} s;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_anx_lp_abil_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_anx_lp_abil_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t np:1;
+		uint64_t ack:1;
+		uint64_t rem_flt:2;
+		uint64_t reserved_9_11:3;
+		uint64_t pause:2;
+		uint64_t hfd:1;
+		uint64_t fd:1;
+		uint64_t reserved_0_4:5;
+	} s;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_anx_results_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_anx_results_reg_s {
+		uint64_t reserved_7_63:57;
+		uint64_t pause:2;
+		uint64_t spd:2;
+		uint64_t an_cpt:1;
+		uint64_t dup:1;
+		uint64_t link_ok:1;
+	} s;
+	struct cvmx_pcsx_anx_results_reg_s cn52xx;
+	struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
+	struct cvmx_pcsx_anx_results_reg_s cn56xx;
+	struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_intx_en_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_intx_en_reg_s {
+		uint64_t reserved_12_63:52;
+		uint64_t dup:1;
+		uint64_t sync_bad_en:1;
+		uint64_t an_bad_en:1;
+		uint64_t rxlock_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxerr_en:1;
+		uint64_t txbad_en:1;
+		uint64_t txfifo_en:1;
+		uint64_t txfifu_en:1;
+		uint64_t an_err_en:1;
+		uint64_t xmit_en:1;
+		uint64_t lnkspd_en:1;
+	} s;
+	struct cvmx_pcsx_intx_en_reg_s cn52xx;
+	struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
+	struct cvmx_pcsx_intx_en_reg_s cn56xx;
+	struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_intx_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_intx_reg_s {
+		uint64_t reserved_12_63:52;
+		uint64_t dup:1;
+		uint64_t sync_bad:1;
+		uint64_t an_bad:1;
+		uint64_t rxlock:1;
+		uint64_t rxbad:1;
+		uint64_t rxerr:1;
+		uint64_t txbad:1;
+		uint64_t txfifo:1;
+		uint64_t txfifu:1;
+		uint64_t an_err:1;
+		uint64_t xmit:1;
+		uint64_t lnkspd:1;
+	} s;
+	struct cvmx_pcsx_intx_reg_s cn52xx;
+	struct cvmx_pcsx_intx_reg_s cn52xxp1;
+	struct cvmx_pcsx_intx_reg_s cn56xx;
+	struct cvmx_pcsx_intx_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_linkx_timer_count_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_linkx_timer_count_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t count:16;
+	} s;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_log_anlx_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_log_anlx_reg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t lafifovfl:1;
+		uint64_t la_en:1;
+		uint64_t pkt_sz:2;
+	} s;
+	struct cvmx_pcsx_log_anlx_reg_s cn52xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
+	struct cvmx_pcsx_log_anlx_reg_s cn56xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_miscx_ctl_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_miscx_ctl_reg_s {
+		uint64_t reserved_13_63:51;
+		uint64_t sgmii:1;
+		uint64_t gmxeno:1;
+		uint64_t loopbck2:1;
+		uint64_t mac_phy:1;
+		uint64_t mode:1;
+		uint64_t an_ovrd:1;
+		uint64_t samp_pt:7;
+	} s;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_mrx_control_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_mrx_control_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t reset:1;
+		uint64_t loopbck1:1;
+		uint64_t spdlsb:1;
+		uint64_t an_en:1;
+		uint64_t pwr_dn:1;
+		uint64_t reserved_10_10:1;
+		uint64_t rst_an:1;
+		uint64_t dup:1;
+		uint64_t coltst:1;
+		uint64_t spdmsb:1;
+		uint64_t uni:1;
+		uint64_t reserved_0_4:5;
+	} s;
+	struct cvmx_pcsx_mrx_control_reg_s cn52xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
+	struct cvmx_pcsx_mrx_control_reg_s cn56xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_mrx_status_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_mrx_status_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t hun_t4:1;
+		uint64_t hun_xfd:1;
+		uint64_t hun_xhd:1;
+		uint64_t ten_fd:1;
+		uint64_t ten_hd:1;
+		uint64_t hun_t2fd:1;
+		uint64_t hun_t2hd:1;
+		uint64_t ext_st:1;
+		uint64_t reserved_7_7:1;
+		uint64_t prb_sup:1;
+		uint64_t an_cpt:1;
+		uint64_t rm_flt:1;
+		uint64_t an_abil:1;
+		uint64_t lnk_st:1;
+		uint64_t reserved_1_1:1;
+		uint64_t extnd:1;
+	} s;
+	struct cvmx_pcsx_mrx_status_reg_s cn52xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
+	struct cvmx_pcsx_mrx_status_reg_s cn56xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_rxx_states_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_rxx_states_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t rx_bad:1;
+		uint64_t rx_st:5;
+		uint64_t sync_bad:1;
+		uint64_t sync:4;
+		uint64_t an_bad:1;
+		uint64_t an_st:4;
+	} s;
+	struct cvmx_pcsx_rxx_states_reg_s cn52xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
+	struct cvmx_pcsx_rxx_states_reg_s cn56xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_rxx_sync_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_rxx_sync_reg_s {
+		uint64_t reserved_2_63:62;
+		uint64_t sync:1;
+		uint64_t bit_lock:1;
+	} s;
+	struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
+	struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_sgmx_an_adv_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t link:1;
+		uint64_t ack:1;
+		uint64_t reserved_13_13:1;
+		uint64_t dup:1;
+		uint64_t speed:2;
+		uint64_t reserved_1_9:9;
+		uint64_t one:1;
+	} s;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_sgmx_lp_adv_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t link:1;
+		uint64_t reserved_13_14:2;
+		uint64_t dup:1;
+		uint64_t speed:2;
+		uint64_t reserved_1_9:9;
+		uint64_t one:1;
+	} s;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_txx_states_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_txx_states_reg_s {
+		uint64_t reserved_7_63:57;
+		uint64_t xmit:2;
+		uint64_t tx_bad:1;
+		uint64_t ord_st:4;
+	} s;
+	struct cvmx_pcsx_txx_states_reg_s cn52xx;
+	struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
+	struct cvmx_pcsx_txx_states_reg_s cn56xx;
+	struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
+};
+
+union cvmx_pcsx_tx_rxx_polarity_reg {
+	uint64_t u64;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t rxovrd:1;
+		uint64_t autorxpl:1;
+		uint64_t rxplrt:1;
+		uint64_t txplrt:1;
+	} s;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-pcsxx-defs.h b/drivers/staging/octeon/cvmx-pcsxx-defs.h
new file mode 100644
index 0000000..55d120f
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pcsxx-defs.h
@@ -0,0 +1,316 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PCSXX_DEFS_H__
+#define __CVMX_PCSXX_DEFS_H__
+
+#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_CONTROL1_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_CONTROL2_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_INT_EN_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_INT_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_STATUS1_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_STATUS2_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_pcsxx_10gbx_status_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_10gbx_status_reg_s {
+		uint64_t reserved_13_63:51;
+		uint64_t alignd:1;
+		uint64_t pattst:1;
+		uint64_t reserved_4_10:7;
+		uint64_t l3sync:1;
+		uint64_t l2sync:1;
+		uint64_t l1sync:1;
+		uint64_t l0sync:1;
+	} s;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_bist_status_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_bist_status_reg_s {
+		uint64_t reserved_1_63:63;
+		uint64_t bist_status:1;
+	} s;
+	struct cvmx_pcsxx_bist_status_reg_s cn52xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
+	struct cvmx_pcsxx_bist_status_reg_s cn56xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_bit_lock_status_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_bit_lock_status_reg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t bitlck3:1;
+		uint64_t bitlck2:1;
+		uint64_t bitlck1:1;
+		uint64_t bitlck0:1;
+	} s;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_control1_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_control1_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t reset:1;
+		uint64_t loopbck1:1;
+		uint64_t spdsel1:1;
+		uint64_t reserved_12_12:1;
+		uint64_t lo_pwr:1;
+		uint64_t reserved_7_10:4;
+		uint64_t spdsel0:1;
+		uint64_t spd:4;
+		uint64_t reserved_0_1:2;
+	} s;
+	struct cvmx_pcsxx_control1_reg_s cn52xx;
+	struct cvmx_pcsxx_control1_reg_s cn52xxp1;
+	struct cvmx_pcsxx_control1_reg_s cn56xx;
+	struct cvmx_pcsxx_control1_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_control2_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_control2_reg_s {
+		uint64_t reserved_2_63:62;
+		uint64_t type:2;
+	} s;
+	struct cvmx_pcsxx_control2_reg_s cn52xx;
+	struct cvmx_pcsxx_control2_reg_s cn52xxp1;
+	struct cvmx_pcsxx_control2_reg_s cn56xx;
+	struct cvmx_pcsxx_control2_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_int_en_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_int_en_reg_s {
+		uint64_t reserved_6_63:58;
+		uint64_t algnlos_en:1;
+		uint64_t synlos_en:1;
+		uint64_t bitlckls_en:1;
+		uint64_t rxsynbad_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t txflt_en:1;
+	} s;
+	struct cvmx_pcsxx_int_en_reg_s cn52xx;
+	struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
+	struct cvmx_pcsxx_int_en_reg_s cn56xx;
+	struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_int_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_int_reg_s {
+		uint64_t reserved_6_63:58;
+		uint64_t algnlos:1;
+		uint64_t synlos:1;
+		uint64_t bitlckls:1;
+		uint64_t rxsynbad:1;
+		uint64_t rxbad:1;
+		uint64_t txflt:1;
+	} s;
+	struct cvmx_pcsxx_int_reg_s cn52xx;
+	struct cvmx_pcsxx_int_reg_s cn52xxp1;
+	struct cvmx_pcsxx_int_reg_s cn56xx;
+	struct cvmx_pcsxx_int_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_log_anl_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_log_anl_reg_s {
+		uint64_t reserved_7_63:57;
+		uint64_t enc_mode:1;
+		uint64_t drop_ln:2;
+		uint64_t lafifovfl:1;
+		uint64_t la_en:1;
+		uint64_t pkt_sz:2;
+	} s;
+	struct cvmx_pcsxx_log_anl_reg_s cn52xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
+	struct cvmx_pcsxx_log_anl_reg_s cn56xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_misc_ctl_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_misc_ctl_reg_s {
+		uint64_t reserved_4_63:60;
+		uint64_t tx_swap:1;
+		uint64_t rx_swap:1;
+		uint64_t xaui:1;
+		uint64_t gmxeno:1;
+	} s;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_rx_sync_states_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_rx_sync_states_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t sync3st:4;
+		uint64_t sync2st:4;
+		uint64_t sync1st:4;
+		uint64_t sync0st:4;
+	} s;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_spd_abil_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_spd_abil_reg_s {
+		uint64_t reserved_2_63:62;
+		uint64_t tenpasst:1;
+		uint64_t tengb:1;
+	} s;
+	struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
+	struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_status1_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_status1_reg_s {
+		uint64_t reserved_8_63:56;
+		uint64_t flt:1;
+		uint64_t reserved_3_6:4;
+		uint64_t rcv_lnk:1;
+		uint64_t lpable:1;
+		uint64_t reserved_0_0:1;
+	} s;
+	struct cvmx_pcsxx_status1_reg_s cn52xx;
+	struct cvmx_pcsxx_status1_reg_s cn52xxp1;
+	struct cvmx_pcsxx_status1_reg_s cn56xx;
+	struct cvmx_pcsxx_status1_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_status2_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_status2_reg_s {
+		uint64_t reserved_16_63:48;
+		uint64_t dev:2;
+		uint64_t reserved_12_13:2;
+		uint64_t xmtflt:1;
+		uint64_t rcvflt:1;
+		uint64_t reserved_3_9:7;
+		uint64_t tengb_w:1;
+		uint64_t tengb_x:1;
+		uint64_t tengb_r:1;
+	} s;
+	struct cvmx_pcsxx_status2_reg_s cn52xx;
+	struct cvmx_pcsxx_status2_reg_s cn52xxp1;
+	struct cvmx_pcsxx_status2_reg_s cn56xx;
+	struct cvmx_pcsxx_status2_reg_s cn56xxp1;
+};
+
+union cvmx_pcsxx_tx_rx_polarity_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s {
+		uint64_t reserved_10_63:54;
+		uint64_t xor_rxplrt:4;
+		uint64_t xor_txplrt:4;
+		uint64_t rxplrt:1;
+		uint64_t txplrt:1;
+	} s;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
+		uint64_t reserved_2_63:62;
+		uint64_t rxplrt:1;
+		uint64_t txplrt:1;
+	} cn52xxp1;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
+};
+
+union cvmx_pcsxx_tx_rx_states_reg {
+	uint64_t u64;
+	struct cvmx_pcsxx_tx_rx_states_reg_s {
+		uint64_t reserved_14_63:50;
+		uint64_t term_err:1;
+		uint64_t syn3bad:1;
+		uint64_t syn2bad:1;
+		uint64_t syn1bad:1;
+		uint64_t syn0bad:1;
+		uint64_t rxbad:1;
+		uint64_t algn_st:3;
+		uint64_t rx_st:2;
+		uint64_t tx_st:3;
+	} s;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
+		uint64_t reserved_13_63:51;
+		uint64_t syn3bad:1;
+		uint64_t syn2bad:1;
+		uint64_t syn1bad:1;
+		uint64_t syn0bad:1;
+		uint64_t rxbad:1;
+		uint64_t algn_st:3;
+		uint64_t rx_st:2;
+		uint64_t tx_st:3;
+	} cn52xxp1;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-pip-defs.h b/drivers/staging/octeon/cvmx-pip-defs.h
new file mode 100644
index 0000000..5a36910
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pip-defs.h
@@ -0,0 +1,1267 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PIP_DEFS_H__
+#define __CVMX_PIP_DEFS_H__
+
+/*
+ * Enumeration representing the amount of packet processing
+ * and validation performed by the input hardware.
+ */
+enum cvmx_pip_port_parse_mode {
+	/*
+	 * Packet input doesn't perform any processing of the input
+	 * packet.
+	 */
+	CVMX_PIP_PORT_CFG_MODE_NONE = 0ull,
+	/*
+	 * Full packet processing is performed with pointer starting
+	 * at the L2 (ethernet MAC) header.
+	 */
+	CVMX_PIP_PORT_CFG_MODE_SKIPL2 = 1ull,
+	/*
+	 * Input packets are assumed to be IP.  Results from non IP
+	 * packets is undefined. Pointers reference the beginning of
+	 * the IP header.
+	 */
+	CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
+};
+
+#define CVMX_PIP_BCK_PRS \
+	 CVMX_ADD_IO_SEG(0x00011800A0000038ull)
+#define CVMX_PIP_BIST_STATUS \
+	 CVMX_ADD_IO_SEG(0x00011800A0000000ull)
+#define CVMX_PIP_CRC_CTLX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
+#define CVMX_PIP_CRC_IVX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
+#define CVMX_PIP_DEC_IPSECX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
+#define CVMX_PIP_DSA_SRC_GRP \
+	 CVMX_ADD_IO_SEG(0x00011800A0000190ull)
+#define CVMX_PIP_DSA_VID_GRP \
+	 CVMX_ADD_IO_SEG(0x00011800A0000198ull)
+#define CVMX_PIP_FRM_LEN_CHKX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
+#define CVMX_PIP_GBL_CFG \
+	 CVMX_ADD_IO_SEG(0x00011800A0000028ull)
+#define CVMX_PIP_GBL_CTL \
+	 CVMX_ADD_IO_SEG(0x00011800A0000020ull)
+#define CVMX_PIP_HG_PRI_QOS \
+	 CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
+#define CVMX_PIP_INT_EN \
+	 CVMX_ADD_IO_SEG(0x00011800A0000010ull)
+#define CVMX_PIP_INT_REG \
+	 CVMX_ADD_IO_SEG(0x00011800A0000008ull)
+#define CVMX_PIP_IP_OFFSET \
+	 CVMX_ADD_IO_SEG(0x00011800A0000060ull)
+#define CVMX_PIP_PRT_CFGX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
+#define CVMX_PIP_PRT_TAGX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
+#define CVMX_PIP_QOS_DIFFX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
+#define CVMX_PIP_QOS_VLANX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
+#define CVMX_PIP_QOS_WATCHX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
+#define CVMX_PIP_RAW_WORD \
+	 CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
+#define CVMX_PIP_SFT_RST \
+	 CVMX_ADD_IO_SEG(0x00011800A0000030ull)
+#define CVMX_PIP_STAT0_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT1_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT2_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT3_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT4_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT5_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT6_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT7_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT8_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT9_PRTX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
+#define CVMX_PIP_STAT_CTL \
+	 CVMX_ADD_IO_SEG(0x00011800A0000018ull)
+#define CVMX_PIP_STAT_INB_ERRSX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
+#define CVMX_PIP_STAT_INB_OCTSX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
+#define CVMX_PIP_STAT_INB_PKTSX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
+#define CVMX_PIP_TAG_INCX(offset) \
+	 CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
+#define CVMX_PIP_TAG_MASK \
+	 CVMX_ADD_IO_SEG(0x00011800A0000070ull)
+#define CVMX_PIP_TAG_SECRET \
+	 CVMX_ADD_IO_SEG(0x00011800A0000068ull)
+#define CVMX_PIP_TODO_ENTRY \
+	 CVMX_ADD_IO_SEG(0x00011800A0000078ull)
+
+union cvmx_pip_bck_prs {
+	uint64_t u64;
+	struct cvmx_pip_bck_prs_s {
+		uint64_t bckprs:1;
+		uint64_t reserved_13_62:50;
+		uint64_t hiwater:5;
+		uint64_t reserved_5_7:3;
+		uint64_t lowater:5;
+	} s;
+	struct cvmx_pip_bck_prs_s cn38xx;
+	struct cvmx_pip_bck_prs_s cn38xxp2;
+	struct cvmx_pip_bck_prs_s cn56xx;
+	struct cvmx_pip_bck_prs_s cn56xxp1;
+	struct cvmx_pip_bck_prs_s cn58xx;
+	struct cvmx_pip_bck_prs_s cn58xxp1;
+};
+
+union cvmx_pip_bist_status {
+	uint64_t u64;
+	struct cvmx_pip_bist_status_s {
+		uint64_t reserved_18_63:46;
+		uint64_t bist:18;
+	} s;
+	struct cvmx_pip_bist_status_s cn30xx;
+	struct cvmx_pip_bist_status_s cn31xx;
+	struct cvmx_pip_bist_status_s cn38xx;
+	struct cvmx_pip_bist_status_s cn38xxp2;
+	struct cvmx_pip_bist_status_cn50xx {
+		uint64_t reserved_17_63:47;
+		uint64_t bist:17;
+	} cn50xx;
+	struct cvmx_pip_bist_status_s cn52xx;
+	struct cvmx_pip_bist_status_s cn52xxp1;
+	struct cvmx_pip_bist_status_s cn56xx;
+	struct cvmx_pip_bist_status_s cn56xxp1;
+	struct cvmx_pip_bist_status_s cn58xx;
+	struct cvmx_pip_bist_status_s cn58xxp1;
+};
+
+union cvmx_pip_crc_ctlx {
+	uint64_t u64;
+	struct cvmx_pip_crc_ctlx_s {
+		uint64_t reserved_2_63:62;
+		uint64_t invres:1;
+		uint64_t reflect:1;
+	} s;
+	struct cvmx_pip_crc_ctlx_s cn38xx;
+	struct cvmx_pip_crc_ctlx_s cn38xxp2;
+	struct cvmx_pip_crc_ctlx_s cn58xx;
+	struct cvmx_pip_crc_ctlx_s cn58xxp1;
+};
+
+union cvmx_pip_crc_ivx {
+	uint64_t u64;
+	struct cvmx_pip_crc_ivx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t iv:32;
+	} s;
+	struct cvmx_pip_crc_ivx_s cn38xx;
+	struct cvmx_pip_crc_ivx_s cn38xxp2;
+	struct cvmx_pip_crc_ivx_s cn58xx;
+	struct cvmx_pip_crc_ivx_s cn58xxp1;
+};
+
+union cvmx_pip_dec_ipsecx {
+	uint64_t u64;
+	struct cvmx_pip_dec_ipsecx_s {
+		uint64_t reserved_18_63:46;
+		uint64_t tcp:1;
+		uint64_t udp:1;
+		uint64_t dprt:16;
+	} s;
+	struct cvmx_pip_dec_ipsecx_s cn30xx;
+	struct cvmx_pip_dec_ipsecx_s cn31xx;
+	struct cvmx_pip_dec_ipsecx_s cn38xx;
+	struct cvmx_pip_dec_ipsecx_s cn38xxp2;
+	struct cvmx_pip_dec_ipsecx_s cn50xx;
+	struct cvmx_pip_dec_ipsecx_s cn52xx;
+	struct cvmx_pip_dec_ipsecx_s cn52xxp1;
+	struct cvmx_pip_dec_ipsecx_s cn56xx;
+	struct cvmx_pip_dec_ipsecx_s cn56xxp1;
+	struct cvmx_pip_dec_ipsecx_s cn58xx;
+	struct cvmx_pip_dec_ipsecx_s cn58xxp1;
+};
+
+union cvmx_pip_dsa_src_grp {
+	uint64_t u64;
+	struct cvmx_pip_dsa_src_grp_s {
+		uint64_t map15:4;
+		uint64_t map14:4;
+		uint64_t map13:4;
+		uint64_t map12:4;
+		uint64_t map11:4;
+		uint64_t map10:4;
+		uint64_t map9:4;
+		uint64_t map8:4;
+		uint64_t map7:4;
+		uint64_t map6:4;
+		uint64_t map5:4;
+		uint64_t map4:4;
+		uint64_t map3:4;
+		uint64_t map2:4;
+		uint64_t map1:4;
+		uint64_t map0:4;
+	} s;
+	struct cvmx_pip_dsa_src_grp_s cn52xx;
+	struct cvmx_pip_dsa_src_grp_s cn52xxp1;
+	struct cvmx_pip_dsa_src_grp_s cn56xx;
+};
+
+union cvmx_pip_dsa_vid_grp {
+	uint64_t u64;
+	struct cvmx_pip_dsa_vid_grp_s {
+		uint64_t map15:4;
+		uint64_t map14:4;
+		uint64_t map13:4;
+		uint64_t map12:4;
+		uint64_t map11:4;
+		uint64_t map10:4;
+		uint64_t map9:4;
+		uint64_t map8:4;
+		uint64_t map7:4;
+		uint64_t map6:4;
+		uint64_t map5:4;
+		uint64_t map4:4;
+		uint64_t map3:4;
+		uint64_t map2:4;
+		uint64_t map1:4;
+		uint64_t map0:4;
+	} s;
+	struct cvmx_pip_dsa_vid_grp_s cn52xx;
+	struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
+	struct cvmx_pip_dsa_vid_grp_s cn56xx;
+};
+
+union cvmx_pip_frm_len_chkx {
+	uint64_t u64;
+	struct cvmx_pip_frm_len_chkx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t maxlen:16;
+		uint64_t minlen:16;
+	} s;
+	struct cvmx_pip_frm_len_chkx_s cn50xx;
+	struct cvmx_pip_frm_len_chkx_s cn52xx;
+	struct cvmx_pip_frm_len_chkx_s cn52xxp1;
+	struct cvmx_pip_frm_len_chkx_s cn56xx;
+	struct cvmx_pip_frm_len_chkx_s cn56xxp1;
+};
+
+union cvmx_pip_gbl_cfg {
+	uint64_t u64;
+	struct cvmx_pip_gbl_cfg_s {
+		uint64_t reserved_19_63:45;
+		uint64_t tag_syn:1;
+		uint64_t ip6_udp:1;
+		uint64_t max_l2:1;
+		uint64_t reserved_11_15:5;
+		uint64_t raw_shf:3;
+		uint64_t reserved_3_7:5;
+		uint64_t nip_shf:3;
+	} s;
+	struct cvmx_pip_gbl_cfg_s cn30xx;
+	struct cvmx_pip_gbl_cfg_s cn31xx;
+	struct cvmx_pip_gbl_cfg_s cn38xx;
+	struct cvmx_pip_gbl_cfg_s cn38xxp2;
+	struct cvmx_pip_gbl_cfg_s cn50xx;
+	struct cvmx_pip_gbl_cfg_s cn52xx;
+	struct cvmx_pip_gbl_cfg_s cn52xxp1;
+	struct cvmx_pip_gbl_cfg_s cn56xx;
+	struct cvmx_pip_gbl_cfg_s cn56xxp1;
+	struct cvmx_pip_gbl_cfg_s cn58xx;
+	struct cvmx_pip_gbl_cfg_s cn58xxp1;
+};
+
+union cvmx_pip_gbl_ctl {
+	uint64_t u64;
+	struct cvmx_pip_gbl_ctl_s {
+		uint64_t reserved_27_63:37;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_sid:1;
+		uint64_t reserved_21_23:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+	} s;
+	struct cvmx_pip_gbl_ctl_cn30xx {
+		uint64_t reserved_17_63:47;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+	} cn30xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
+	struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
+	struct cvmx_pip_gbl_ctl_s cn52xx;
+	struct cvmx_pip_gbl_ctl_s cn52xxp1;
+	struct cvmx_pip_gbl_ctl_s cn56xx;
+	struct cvmx_pip_gbl_ctl_cn56xxp1 {
+		uint64_t reserved_21_63:43;
+		uint64_t ring_en:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+	} cn56xxp1;
+	struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_hg_pri_qos {
+	uint64_t u64;
+	struct cvmx_pip_hg_pri_qos_s {
+		uint64_t reserved_11_63:53;
+		uint64_t qos:3;
+		uint64_t reserved_6_7:2;
+		uint64_t pri:6;
+	} s;
+	struct cvmx_pip_hg_pri_qos_s cn52xx;
+	struct cvmx_pip_hg_pri_qos_s cn52xxp1;
+	struct cvmx_pip_hg_pri_qos_s cn56xx;
+};
+
+union cvmx_pip_int_en {
+	uint64_t u64;
+	struct cvmx_pip_int_en_s {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} s;
+	struct cvmx_pip_int_en_cn30xx {
+		uint64_t reserved_9_63:55;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn30xx;
+	struct cvmx_pip_int_en_cn30xx cn31xx;
+	struct cvmx_pip_int_en_cn30xx cn38xx;
+	struct cvmx_pip_int_en_cn30xx cn38xxp2;
+	struct cvmx_pip_int_en_cn50xx {
+		uint64_t reserved_12_63:52;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pktdrp:1;
+	} cn50xx;
+	struct cvmx_pip_int_en_cn52xx {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pktdrp:1;
+	} cn52xx;
+	struct cvmx_pip_int_en_cn52xx cn52xxp1;
+	struct cvmx_pip_int_en_s cn56xx;
+	struct cvmx_pip_int_en_cn56xxp1 {
+		uint64_t reserved_12_63:52;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn56xxp1;
+	struct cvmx_pip_int_en_cn58xx {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t reserved_9_11:3;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn58xx;
+	struct cvmx_pip_int_en_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_int_reg {
+	uint64_t u64;
+	struct cvmx_pip_int_reg_s {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} s;
+	struct cvmx_pip_int_reg_cn30xx {
+		uint64_t reserved_9_63:55;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn30xx;
+	struct cvmx_pip_int_reg_cn30xx cn31xx;
+	struct cvmx_pip_int_reg_cn30xx cn38xx;
+	struct cvmx_pip_int_reg_cn30xx cn38xxp2;
+	struct cvmx_pip_int_reg_cn50xx {
+		uint64_t reserved_12_63:52;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pktdrp:1;
+	} cn50xx;
+	struct cvmx_pip_int_reg_cn52xx {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t reserved_1_1:1;
+		uint64_t pktdrp:1;
+	} cn52xx;
+	struct cvmx_pip_int_reg_cn52xx cn52xxp1;
+	struct cvmx_pip_int_reg_s cn56xx;
+	struct cvmx_pip_int_reg_cn56xxp1 {
+		uint64_t reserved_12_63:52;
+		uint64_t lenerr:1;
+		uint64_t maxerr:1;
+		uint64_t minerr:1;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn56xxp1;
+	struct cvmx_pip_int_reg_cn58xx {
+		uint64_t reserved_13_63:51;
+		uint64_t punyerr:1;
+		uint64_t reserved_9_11:3;
+		uint64_t beperr:1;
+		uint64_t feperr:1;
+		uint64_t todoovr:1;
+		uint64_t skprunt:1;
+		uint64_t badtag:1;
+		uint64_t prtnxa:1;
+		uint64_t bckprs:1;
+		uint64_t crcerr:1;
+		uint64_t pktdrp:1;
+	} cn58xx;
+	struct cvmx_pip_int_reg_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_ip_offset {
+	uint64_t u64;
+	struct cvmx_pip_ip_offset_s {
+		uint64_t reserved_3_63:61;
+		uint64_t offset:3;
+	} s;
+	struct cvmx_pip_ip_offset_s cn30xx;
+	struct cvmx_pip_ip_offset_s cn31xx;
+	struct cvmx_pip_ip_offset_s cn38xx;
+	struct cvmx_pip_ip_offset_s cn38xxp2;
+	struct cvmx_pip_ip_offset_s cn50xx;
+	struct cvmx_pip_ip_offset_s cn52xx;
+	struct cvmx_pip_ip_offset_s cn52xxp1;
+	struct cvmx_pip_ip_offset_s cn56xx;
+	struct cvmx_pip_ip_offset_s cn56xxp1;
+	struct cvmx_pip_ip_offset_s cn58xx;
+	struct cvmx_pip_ip_offset_s cn58xxp1;
+};
+
+union cvmx_pip_prt_cfgx {
+	uint64_t u64;
+	struct cvmx_pip_prt_cfgx_s {
+		uint64_t reserved_53_63:11;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t lenerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t minerr_en:1;
+		uint64_t grp_wat_47:4;
+		uint64_t qos_wat_47:4;
+		uint64_t reserved_37_39:3;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t hg_qos:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t qos_vsel:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t higig_en:1;
+		uint64_t dsa_en:1;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+	} s;
+	struct cvmx_pip_prt_cfgx_cn30xx {
+		uint64_t reserved_37_63:27;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_10_15:6;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+	} cn30xx;
+	struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
+	struct cvmx_pip_prt_cfgx_cn38xx {
+		uint64_t reserved_37_63:27;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t reserved_10_11:2;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+	} cn38xx;
+	struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
+	struct cvmx_pip_prt_cfgx_cn50xx {
+		uint64_t reserved_53_63:11;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t lenerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t minerr_en:1;
+		uint64_t grp_wat_47:4;
+		uint64_t qos_wat_47:4;
+		uint64_t reserved_37_39:3;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t reserved_10_11:2;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+	} cn50xx;
+	struct cvmx_pip_prt_cfgx_s cn52xx;
+	struct cvmx_pip_prt_cfgx_s cn52xxp1;
+	struct cvmx_pip_prt_cfgx_s cn56xx;
+	struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
+	struct cvmx_pip_prt_cfgx_cn58xx {
+		uint64_t reserved_37_63:27;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t reserved_10_11:2;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+	} cn58xx;
+	struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
+};
+
+union cvmx_pip_prt_tagx {
+	uint64_t u64;
+	struct cvmx_pip_prt_tagx_s {
+		uint64_t reserved_40_63:24;
+		uint64_t grptagbase:4;
+		uint64_t grptagmask:4;
+		uint64_t grptag:1;
+		uint64_t grptag_mskip:1;
+		uint64_t tag_mode:2;
+		uint64_t inc_vs:2;
+		uint64_t inc_vlan:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_src_flag:1;
+		uint64_t tcp6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t non_tag_type:2;
+		uint64_t grp:4;
+	} s;
+	struct cvmx_pip_prt_tagx_cn30xx {
+		uint64_t reserved_40_63:24;
+		uint64_t grptagbase:4;
+		uint64_t grptagmask:4;
+		uint64_t grptag:1;
+		uint64_t reserved_30_30:1;
+		uint64_t tag_mode:2;
+		uint64_t inc_vs:2;
+		uint64_t inc_vlan:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_src_flag:1;
+		uint64_t tcp6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t non_tag_type:2;
+		uint64_t grp:4;
+	} cn30xx;
+	struct cvmx_pip_prt_tagx_cn30xx cn31xx;
+	struct cvmx_pip_prt_tagx_cn30xx cn38xx;
+	struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
+	struct cvmx_pip_prt_tagx_s cn50xx;
+	struct cvmx_pip_prt_tagx_s cn52xx;
+	struct cvmx_pip_prt_tagx_s cn52xxp1;
+	struct cvmx_pip_prt_tagx_s cn56xx;
+	struct cvmx_pip_prt_tagx_s cn56xxp1;
+	struct cvmx_pip_prt_tagx_cn30xx cn58xx;
+	struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_qos_diffx {
+	uint64_t u64;
+	struct cvmx_pip_qos_diffx_s {
+		uint64_t reserved_3_63:61;
+		uint64_t qos:3;
+	} s;
+	struct cvmx_pip_qos_diffx_s cn30xx;
+	struct cvmx_pip_qos_diffx_s cn31xx;
+	struct cvmx_pip_qos_diffx_s cn38xx;
+	struct cvmx_pip_qos_diffx_s cn38xxp2;
+	struct cvmx_pip_qos_diffx_s cn50xx;
+	struct cvmx_pip_qos_diffx_s cn52xx;
+	struct cvmx_pip_qos_diffx_s cn52xxp1;
+	struct cvmx_pip_qos_diffx_s cn56xx;
+	struct cvmx_pip_qos_diffx_s cn56xxp1;
+	struct cvmx_pip_qos_diffx_s cn58xx;
+	struct cvmx_pip_qos_diffx_s cn58xxp1;
+};
+
+union cvmx_pip_qos_vlanx {
+	uint64_t u64;
+	struct cvmx_pip_qos_vlanx_s {
+		uint64_t reserved_7_63:57;
+		uint64_t qos1:3;
+		uint64_t reserved_3_3:1;
+		uint64_t qos:3;
+	} s;
+	struct cvmx_pip_qos_vlanx_cn30xx {
+		uint64_t reserved_3_63:61;
+		uint64_t qos:3;
+	} cn30xx;
+	struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
+	struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
+	struct cvmx_pip_qos_vlanx_cn30xx cn38xxp2;
+	struct cvmx_pip_qos_vlanx_cn30xx cn50xx;
+	struct cvmx_pip_qos_vlanx_s cn52xx;
+	struct cvmx_pip_qos_vlanx_s cn52xxp1;
+	struct cvmx_pip_qos_vlanx_s cn56xx;
+	struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
+	struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
+	struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_qos_watchx {
+	uint64_t u64;
+	struct cvmx_pip_qos_watchx_s {
+		uint64_t reserved_48_63:16;
+		uint64_t mask:16;
+		uint64_t reserved_28_31:4;
+		uint64_t grp:4;
+		uint64_t reserved_23_23:1;
+		uint64_t qos:3;
+		uint64_t reserved_19_19:1;
+		uint64_t match_type:3;
+		uint64_t match_value:16;
+	} s;
+	struct cvmx_pip_qos_watchx_cn30xx {
+		uint64_t reserved_48_63:16;
+		uint64_t mask:16;
+		uint64_t reserved_28_31:4;
+		uint64_t grp:4;
+		uint64_t reserved_23_23:1;
+		uint64_t qos:3;
+		uint64_t reserved_18_19:2;
+		uint64_t match_type:2;
+		uint64_t match_value:16;
+	} cn30xx;
+	struct cvmx_pip_qos_watchx_cn30xx cn31xx;
+	struct cvmx_pip_qos_watchx_cn30xx cn38xx;
+	struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
+	struct cvmx_pip_qos_watchx_s cn50xx;
+	struct cvmx_pip_qos_watchx_s cn52xx;
+	struct cvmx_pip_qos_watchx_s cn52xxp1;
+	struct cvmx_pip_qos_watchx_s cn56xx;
+	struct cvmx_pip_qos_watchx_s cn56xxp1;
+	struct cvmx_pip_qos_watchx_cn30xx cn58xx;
+	struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
+};
+
+union cvmx_pip_raw_word {
+	uint64_t u64;
+	struct cvmx_pip_raw_word_s {
+		uint64_t reserved_56_63:8;
+		uint64_t word:56;
+	} s;
+	struct cvmx_pip_raw_word_s cn30xx;
+	struct cvmx_pip_raw_word_s cn31xx;
+	struct cvmx_pip_raw_word_s cn38xx;
+	struct cvmx_pip_raw_word_s cn38xxp2;
+	struct cvmx_pip_raw_word_s cn50xx;
+	struct cvmx_pip_raw_word_s cn52xx;
+	struct cvmx_pip_raw_word_s cn52xxp1;
+	struct cvmx_pip_raw_word_s cn56xx;
+	struct cvmx_pip_raw_word_s cn56xxp1;
+	struct cvmx_pip_raw_word_s cn58xx;
+	struct cvmx_pip_raw_word_s cn58xxp1;
+};
+
+union cvmx_pip_sft_rst {
+	uint64_t u64;
+	struct cvmx_pip_sft_rst_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rst:1;
+	} s;
+	struct cvmx_pip_sft_rst_s cn30xx;
+	struct cvmx_pip_sft_rst_s cn31xx;
+	struct cvmx_pip_sft_rst_s cn38xx;
+	struct cvmx_pip_sft_rst_s cn50xx;
+	struct cvmx_pip_sft_rst_s cn52xx;
+	struct cvmx_pip_sft_rst_s cn52xxp1;
+	struct cvmx_pip_sft_rst_s cn56xx;
+	struct cvmx_pip_sft_rst_s cn56xxp1;
+	struct cvmx_pip_sft_rst_s cn58xx;
+	struct cvmx_pip_sft_rst_s cn58xxp1;
+};
+
+union cvmx_pip_stat0_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat0_prtx_s {
+		uint64_t drp_pkts:32;
+		uint64_t drp_octs:32;
+	} s;
+	struct cvmx_pip_stat0_prtx_s cn30xx;
+	struct cvmx_pip_stat0_prtx_s cn31xx;
+	struct cvmx_pip_stat0_prtx_s cn38xx;
+	struct cvmx_pip_stat0_prtx_s cn38xxp2;
+	struct cvmx_pip_stat0_prtx_s cn50xx;
+	struct cvmx_pip_stat0_prtx_s cn52xx;
+	struct cvmx_pip_stat0_prtx_s cn52xxp1;
+	struct cvmx_pip_stat0_prtx_s cn56xx;
+	struct cvmx_pip_stat0_prtx_s cn56xxp1;
+	struct cvmx_pip_stat0_prtx_s cn58xx;
+	struct cvmx_pip_stat0_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat1_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat1_prtx_s {
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+	} s;
+	struct cvmx_pip_stat1_prtx_s cn30xx;
+	struct cvmx_pip_stat1_prtx_s cn31xx;
+	struct cvmx_pip_stat1_prtx_s cn38xx;
+	struct cvmx_pip_stat1_prtx_s cn38xxp2;
+	struct cvmx_pip_stat1_prtx_s cn50xx;
+	struct cvmx_pip_stat1_prtx_s cn52xx;
+	struct cvmx_pip_stat1_prtx_s cn52xxp1;
+	struct cvmx_pip_stat1_prtx_s cn56xx;
+	struct cvmx_pip_stat1_prtx_s cn56xxp1;
+	struct cvmx_pip_stat1_prtx_s cn58xx;
+	struct cvmx_pip_stat1_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat2_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat2_prtx_s {
+		uint64_t pkts:32;
+		uint64_t raw:32;
+	} s;
+	struct cvmx_pip_stat2_prtx_s cn30xx;
+	struct cvmx_pip_stat2_prtx_s cn31xx;
+	struct cvmx_pip_stat2_prtx_s cn38xx;
+	struct cvmx_pip_stat2_prtx_s cn38xxp2;
+	struct cvmx_pip_stat2_prtx_s cn50xx;
+	struct cvmx_pip_stat2_prtx_s cn52xx;
+	struct cvmx_pip_stat2_prtx_s cn52xxp1;
+	struct cvmx_pip_stat2_prtx_s cn56xx;
+	struct cvmx_pip_stat2_prtx_s cn56xxp1;
+	struct cvmx_pip_stat2_prtx_s cn58xx;
+	struct cvmx_pip_stat2_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat3_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat3_prtx_s {
+		uint64_t bcst:32;
+		uint64_t mcst:32;
+	} s;
+	struct cvmx_pip_stat3_prtx_s cn30xx;
+	struct cvmx_pip_stat3_prtx_s cn31xx;
+	struct cvmx_pip_stat3_prtx_s cn38xx;
+	struct cvmx_pip_stat3_prtx_s cn38xxp2;
+	struct cvmx_pip_stat3_prtx_s cn50xx;
+	struct cvmx_pip_stat3_prtx_s cn52xx;
+	struct cvmx_pip_stat3_prtx_s cn52xxp1;
+	struct cvmx_pip_stat3_prtx_s cn56xx;
+	struct cvmx_pip_stat3_prtx_s cn56xxp1;
+	struct cvmx_pip_stat3_prtx_s cn58xx;
+	struct cvmx_pip_stat3_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat4_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat4_prtx_s {
+		uint64_t h65to127:32;
+		uint64_t h64:32;
+	} s;
+	struct cvmx_pip_stat4_prtx_s cn30xx;
+	struct cvmx_pip_stat4_prtx_s cn31xx;
+	struct cvmx_pip_stat4_prtx_s cn38xx;
+	struct cvmx_pip_stat4_prtx_s cn38xxp2;
+	struct cvmx_pip_stat4_prtx_s cn50xx;
+	struct cvmx_pip_stat4_prtx_s cn52xx;
+	struct cvmx_pip_stat4_prtx_s cn52xxp1;
+	struct cvmx_pip_stat4_prtx_s cn56xx;
+	struct cvmx_pip_stat4_prtx_s cn56xxp1;
+	struct cvmx_pip_stat4_prtx_s cn58xx;
+	struct cvmx_pip_stat4_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat5_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat5_prtx_s {
+		uint64_t h256to511:32;
+		uint64_t h128to255:32;
+	} s;
+	struct cvmx_pip_stat5_prtx_s cn30xx;
+	struct cvmx_pip_stat5_prtx_s cn31xx;
+	struct cvmx_pip_stat5_prtx_s cn38xx;
+	struct cvmx_pip_stat5_prtx_s cn38xxp2;
+	struct cvmx_pip_stat5_prtx_s cn50xx;
+	struct cvmx_pip_stat5_prtx_s cn52xx;
+	struct cvmx_pip_stat5_prtx_s cn52xxp1;
+	struct cvmx_pip_stat5_prtx_s cn56xx;
+	struct cvmx_pip_stat5_prtx_s cn56xxp1;
+	struct cvmx_pip_stat5_prtx_s cn58xx;
+	struct cvmx_pip_stat5_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat6_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat6_prtx_s {
+		uint64_t h1024to1518:32;
+		uint64_t h512to1023:32;
+	} s;
+	struct cvmx_pip_stat6_prtx_s cn30xx;
+	struct cvmx_pip_stat6_prtx_s cn31xx;
+	struct cvmx_pip_stat6_prtx_s cn38xx;
+	struct cvmx_pip_stat6_prtx_s cn38xxp2;
+	struct cvmx_pip_stat6_prtx_s cn50xx;
+	struct cvmx_pip_stat6_prtx_s cn52xx;
+	struct cvmx_pip_stat6_prtx_s cn52xxp1;
+	struct cvmx_pip_stat6_prtx_s cn56xx;
+	struct cvmx_pip_stat6_prtx_s cn56xxp1;
+	struct cvmx_pip_stat6_prtx_s cn58xx;
+	struct cvmx_pip_stat6_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat7_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat7_prtx_s {
+		uint64_t fcs:32;
+		uint64_t h1519:32;
+	} s;
+	struct cvmx_pip_stat7_prtx_s cn30xx;
+	struct cvmx_pip_stat7_prtx_s cn31xx;
+	struct cvmx_pip_stat7_prtx_s cn38xx;
+	struct cvmx_pip_stat7_prtx_s cn38xxp2;
+	struct cvmx_pip_stat7_prtx_s cn50xx;
+	struct cvmx_pip_stat7_prtx_s cn52xx;
+	struct cvmx_pip_stat7_prtx_s cn52xxp1;
+	struct cvmx_pip_stat7_prtx_s cn56xx;
+	struct cvmx_pip_stat7_prtx_s cn56xxp1;
+	struct cvmx_pip_stat7_prtx_s cn58xx;
+	struct cvmx_pip_stat7_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat8_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat8_prtx_s {
+		uint64_t frag:32;
+		uint64_t undersz:32;
+	} s;
+	struct cvmx_pip_stat8_prtx_s cn30xx;
+	struct cvmx_pip_stat8_prtx_s cn31xx;
+	struct cvmx_pip_stat8_prtx_s cn38xx;
+	struct cvmx_pip_stat8_prtx_s cn38xxp2;
+	struct cvmx_pip_stat8_prtx_s cn50xx;
+	struct cvmx_pip_stat8_prtx_s cn52xx;
+	struct cvmx_pip_stat8_prtx_s cn52xxp1;
+	struct cvmx_pip_stat8_prtx_s cn56xx;
+	struct cvmx_pip_stat8_prtx_s cn56xxp1;
+	struct cvmx_pip_stat8_prtx_s cn58xx;
+	struct cvmx_pip_stat8_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat9_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat9_prtx_s {
+		uint64_t jabber:32;
+		uint64_t oversz:32;
+	} s;
+	struct cvmx_pip_stat9_prtx_s cn30xx;
+	struct cvmx_pip_stat9_prtx_s cn31xx;
+	struct cvmx_pip_stat9_prtx_s cn38xx;
+	struct cvmx_pip_stat9_prtx_s cn38xxp2;
+	struct cvmx_pip_stat9_prtx_s cn50xx;
+	struct cvmx_pip_stat9_prtx_s cn52xx;
+	struct cvmx_pip_stat9_prtx_s cn52xxp1;
+	struct cvmx_pip_stat9_prtx_s cn56xx;
+	struct cvmx_pip_stat9_prtx_s cn56xxp1;
+	struct cvmx_pip_stat9_prtx_s cn58xx;
+	struct cvmx_pip_stat9_prtx_s cn58xxp1;
+};
+
+union cvmx_pip_stat_ctl {
+	uint64_t u64;
+	struct cvmx_pip_stat_ctl_s {
+		uint64_t reserved_1_63:63;
+		uint64_t rdclr:1;
+	} s;
+	struct cvmx_pip_stat_ctl_s cn30xx;
+	struct cvmx_pip_stat_ctl_s cn31xx;
+	struct cvmx_pip_stat_ctl_s cn38xx;
+	struct cvmx_pip_stat_ctl_s cn38xxp2;
+	struct cvmx_pip_stat_ctl_s cn50xx;
+	struct cvmx_pip_stat_ctl_s cn52xx;
+	struct cvmx_pip_stat_ctl_s cn52xxp1;
+	struct cvmx_pip_stat_ctl_s cn56xx;
+	struct cvmx_pip_stat_ctl_s cn56xxp1;
+	struct cvmx_pip_stat_ctl_s cn58xx;
+	struct cvmx_pip_stat_ctl_s cn58xxp1;
+};
+
+union cvmx_pip_stat_inb_errsx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_errsx_s {
+		uint64_t reserved_16_63:48;
+		uint64_t errs:16;
+	} s;
+	struct cvmx_pip_stat_inb_errsx_s cn30xx;
+	struct cvmx_pip_stat_inb_errsx_s cn31xx;
+	struct cvmx_pip_stat_inb_errsx_s cn38xx;
+	struct cvmx_pip_stat_inb_errsx_s cn38xxp2;
+	struct cvmx_pip_stat_inb_errsx_s cn50xx;
+	struct cvmx_pip_stat_inb_errsx_s cn52xx;
+	struct cvmx_pip_stat_inb_errsx_s cn52xxp1;
+	struct cvmx_pip_stat_inb_errsx_s cn56xx;
+	struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
+	struct cvmx_pip_stat_inb_errsx_s cn58xx;
+	struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
+};
+
+union cvmx_pip_stat_inb_octsx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_octsx_s {
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+	} s;
+	struct cvmx_pip_stat_inb_octsx_s cn30xx;
+	struct cvmx_pip_stat_inb_octsx_s cn31xx;
+	struct cvmx_pip_stat_inb_octsx_s cn38xx;
+	struct cvmx_pip_stat_inb_octsx_s cn38xxp2;
+	struct cvmx_pip_stat_inb_octsx_s cn50xx;
+	struct cvmx_pip_stat_inb_octsx_s cn52xx;
+	struct cvmx_pip_stat_inb_octsx_s cn52xxp1;
+	struct cvmx_pip_stat_inb_octsx_s cn56xx;
+	struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
+	struct cvmx_pip_stat_inb_octsx_s cn58xx;
+	struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
+};
+
+union cvmx_pip_stat_inb_pktsx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_pktsx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t pkts:32;
+	} s;
+	struct cvmx_pip_stat_inb_pktsx_s cn30xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn31xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn38xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn38xxp2;
+	struct cvmx_pip_stat_inb_pktsx_s cn50xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn52xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn52xxp1;
+	struct cvmx_pip_stat_inb_pktsx_s cn56xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
+	struct cvmx_pip_stat_inb_pktsx_s cn58xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
+};
+
+union cvmx_pip_tag_incx {
+	uint64_t u64;
+	struct cvmx_pip_tag_incx_s {
+		uint64_t reserved_8_63:56;
+		uint64_t en:8;
+	} s;
+	struct cvmx_pip_tag_incx_s cn30xx;
+	struct cvmx_pip_tag_incx_s cn31xx;
+	struct cvmx_pip_tag_incx_s cn38xx;
+	struct cvmx_pip_tag_incx_s cn38xxp2;
+	struct cvmx_pip_tag_incx_s cn50xx;
+	struct cvmx_pip_tag_incx_s cn52xx;
+	struct cvmx_pip_tag_incx_s cn52xxp1;
+	struct cvmx_pip_tag_incx_s cn56xx;
+	struct cvmx_pip_tag_incx_s cn56xxp1;
+	struct cvmx_pip_tag_incx_s cn58xx;
+	struct cvmx_pip_tag_incx_s cn58xxp1;
+};
+
+union cvmx_pip_tag_mask {
+	uint64_t u64;
+	struct cvmx_pip_tag_mask_s {
+		uint64_t reserved_16_63:48;
+		uint64_t mask:16;
+	} s;
+	struct cvmx_pip_tag_mask_s cn30xx;
+	struct cvmx_pip_tag_mask_s cn31xx;
+	struct cvmx_pip_tag_mask_s cn38xx;
+	struct cvmx_pip_tag_mask_s cn38xxp2;
+	struct cvmx_pip_tag_mask_s cn50xx;
+	struct cvmx_pip_tag_mask_s cn52xx;
+	struct cvmx_pip_tag_mask_s cn52xxp1;
+	struct cvmx_pip_tag_mask_s cn56xx;
+	struct cvmx_pip_tag_mask_s cn56xxp1;
+	struct cvmx_pip_tag_mask_s cn58xx;
+	struct cvmx_pip_tag_mask_s cn58xxp1;
+};
+
+union cvmx_pip_tag_secret {
+	uint64_t u64;
+	struct cvmx_pip_tag_secret_s {
+		uint64_t reserved_32_63:32;
+		uint64_t dst:16;
+		uint64_t src:16;
+	} s;
+	struct cvmx_pip_tag_secret_s cn30xx;
+	struct cvmx_pip_tag_secret_s cn31xx;
+	struct cvmx_pip_tag_secret_s cn38xx;
+	struct cvmx_pip_tag_secret_s cn38xxp2;
+	struct cvmx_pip_tag_secret_s cn50xx;
+	struct cvmx_pip_tag_secret_s cn52xx;
+	struct cvmx_pip_tag_secret_s cn52xxp1;
+	struct cvmx_pip_tag_secret_s cn56xx;
+	struct cvmx_pip_tag_secret_s cn56xxp1;
+	struct cvmx_pip_tag_secret_s cn58xx;
+	struct cvmx_pip_tag_secret_s cn58xxp1;
+};
+
+union cvmx_pip_todo_entry {
+	uint64_t u64;
+	struct cvmx_pip_todo_entry_s {
+		uint64_t val:1;
+		uint64_t reserved_62_62:1;
+		uint64_t entry:62;
+	} s;
+	struct cvmx_pip_todo_entry_s cn30xx;
+	struct cvmx_pip_todo_entry_s cn31xx;
+	struct cvmx_pip_todo_entry_s cn38xx;
+	struct cvmx_pip_todo_entry_s cn38xxp2;
+	struct cvmx_pip_todo_entry_s cn50xx;
+	struct cvmx_pip_todo_entry_s cn52xx;
+	struct cvmx_pip_todo_entry_s cn52xxp1;
+	struct cvmx_pip_todo_entry_s cn56xx;
+	struct cvmx_pip_todo_entry_s cn56xxp1;
+	struct cvmx_pip_todo_entry_s cn58xx;
+	struct cvmx_pip_todo_entry_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-pip.h b/drivers/staging/octeon/cvmx-pip.h
new file mode 100644
index 0000000..78dbce8
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pip.h
@@ -0,0 +1,524 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Interface to the hardware Packet Input Processing unit.
+ *
+ */
+
+#ifndef __CVMX_PIP_H__
+#define __CVMX_PIP_H__
+
+#include "cvmx-wqe.h"
+#include "cvmx-fpa.h"
+#include "cvmx-pip-defs.h"
+
+#define CVMX_PIP_NUM_INPUT_PORTS                40
+#define CVMX_PIP_NUM_WATCHERS                   4
+
+/*
+ * Encodes the different error and exception codes
+ */
+typedef enum {
+	CVMX_PIP_L4_NO_ERR = 0ull,
+	/*
+	 * 1 = TCP (UDP) packet not long enough to cover TCP (UDP)
+	 * header
+	 */
+	CVMX_PIP_L4_MAL_ERR = 1ull,
+	/* 2  = TCP/UDP checksum failure */
+	CVMX_PIP_CHK_ERR = 2ull,
+	/*
+	 * 3 = TCP/UDP length check (TCP/UDP length does not match IP
+	 * length).
+	 */
+	CVMX_PIP_L4_LENGTH_ERR = 3ull,
+	/* 4  = illegal TCP/UDP port (either source or dest port is zero) */
+	CVMX_PIP_BAD_PRT_ERR = 4ull,
+	/* 8  = TCP flags = FIN only */
+	CVMX_PIP_TCP_FLG8_ERR = 8ull,
+	/* 9  = TCP flags = 0 */
+	CVMX_PIP_TCP_FLG9_ERR = 9ull,
+	/* 10 = TCP flags = FIN+RST+* */
+	CVMX_PIP_TCP_FLG10_ERR = 10ull,
+	/* 11 = TCP flags = SYN+URG+* */
+	CVMX_PIP_TCP_FLG11_ERR = 11ull,
+	/* 12 = TCP flags = SYN+RST+* */
+	CVMX_PIP_TCP_FLG12_ERR = 12ull,
+	/* 13 = TCP flags = SYN+FIN+* */
+	CVMX_PIP_TCP_FLG13_ERR = 13ull
+} cvmx_pip_l4_err_t;
+
+typedef enum {
+
+	CVMX_PIP_IP_NO_ERR = 0ull,
+	/* 1 = not IPv4 or IPv6 */
+	CVMX_PIP_NOT_IP = 1ull,
+	/* 2 = IPv4 header checksum violation */
+	CVMX_PIP_IPV4_HDR_CHK = 2ull,
+	/* 3 = malformed (packet not long enough to cover IP hdr) */
+	CVMX_PIP_IP_MAL_HDR = 3ull,
+	/* 4 = malformed (packet not long enough to cover len in IP hdr) */
+	CVMX_PIP_IP_MAL_PKT = 4ull,
+	/* 5 = TTL / hop count equal zero */
+	CVMX_PIP_TTL_HOP = 5ull,
+	/* 6 = IPv4 options / IPv6 early extension headers */
+	CVMX_PIP_OPTS = 6ull
+} cvmx_pip_ip_exc_t;
+
+/**
+ * NOTES
+ *       late collision (data received before collision)
+ *            late collisions cannot be detected by the receiver
+ *            they would appear as JAM bits which would appear as bad FCS
+ *            or carrier extend error which is CVMX_PIP_EXTEND_ERR
+ */
+typedef enum {
+	/* No error */
+	CVMX_PIP_RX_NO_ERR = 0ull,
+	/* RGM+SPI 1 = partially received packet (buffering/bandwidth
+	 * not adequate) */
+	CVMX_PIP_PARTIAL_ERR = 1ull,
+	/* RGM+SPI 2 = receive packet too large and truncated */
+	CVMX_PIP_JABBER_ERR = 2ull,
+	/*
+	 * RGM 3 = max frame error (pkt len > max frame len) (with FCS
+	 * error)
+	 */
+	CVMX_PIP_OVER_FCS_ERR = 3ull,
+	/* RGM+SPI 4 = max frame error (pkt len > max frame len) */
+	CVMX_PIP_OVER_ERR = 4ull,
+	/*
+	 * RGM 5 = nibble error (data not byte multiple - 100M and 10M
+	 * only)
+	 */
+	CVMX_PIP_ALIGN_ERR = 5ull,
+	/*
+	 * RGM 6 = min frame error (pkt len < min frame len) (with FCS
+	 * error)
+	 */
+	CVMX_PIP_UNDER_FCS_ERR = 6ull,
+	/* RGM     7 = FCS error */
+	CVMX_PIP_GMX_FCS_ERR = 7ull,
+	/* RGM+SPI 8 = min frame error (pkt len < min frame len) */
+	CVMX_PIP_UNDER_ERR = 8ull,
+	/* RGM     9 = Frame carrier extend error */
+	CVMX_PIP_EXTEND_ERR = 9ull,
+	/*
+	 * RGM 10 = length mismatch (len did not match len in L2
+	 * length/type)
+	 */
+	CVMX_PIP_LENGTH_ERR = 10ull,
+	/* RGM 11 = Frame error (some or all data bits marked err) */
+	CVMX_PIP_DAT_ERR = 11ull,
+	/*     SPI 11 = DIP4 error */
+	CVMX_PIP_DIP_ERR = 11ull,
+	/*
+	 * RGM 12 = packet was not large enough to pass the skipper -
+	 * no inspection could occur.
+	 */
+	CVMX_PIP_SKIP_ERR = 12ull,
+	/*
+	 * RGM 13 = studder error (data not repeated - 100M and 10M
+	 * only)
+	 */
+	CVMX_PIP_NIBBLE_ERR = 13ull,
+	/* RGM+SPI 16 = FCS error */
+	CVMX_PIP_PIP_FCS = 16L,
+	/*
+	 * RGM+SPI+PCI 17 = packet was not large enough to pass the
+	 * skipper - no inspection could occur.
+	 */
+	CVMX_PIP_PIP_SKIP_ERR = 17L,
+	/*
+	 * RGM+SPI+PCI 18 = malformed l2 (packet not long enough to
+	 * cover L2 hdr).
+	 */
+	CVMX_PIP_PIP_L2_MAL_HDR = 18L
+	/*
+	 * NOTES: xx = late collision (data received before collision)
+	 *       late collisions cannot be detected by the receiver
+	 *       they would appear as JAM bits which would appear as
+	 *       bad FCS or carrier extend error which is
+	 *       CVMX_PIP_EXTEND_ERR
+	 */
+} cvmx_pip_rcv_err_t;
+
+/**
+ * This defines the err_code field errors in the work Q entry
+ */
+typedef union {
+	cvmx_pip_l4_err_t l4_err;
+	cvmx_pip_ip_exc_t ip_exc;
+	cvmx_pip_rcv_err_t rcv_err;
+} cvmx_pip_err_t;
+
+/**
+ * Status statistics for a port
+ */
+typedef struct {
+	/* Inbound octets marked to be dropped by the IPD */
+	uint32_t dropped_octets;
+	/* Inbound packets marked to be dropped by the IPD */
+	uint32_t dropped_packets;
+	/* RAW PCI Packets received by PIP per port */
+	uint32_t pci_raw_packets;
+	/* Number of octets processed by PIP */
+	uint32_t octets;
+	/* Number of packets processed by PIP */
+	uint32_t packets;
+	/*
+	 * Number of indentified L2 multicast packets.  Does not
+	 * include broadcast packets.  Only includes packets whose
+	 * parse mode is SKIP_TO_L2
+	 */
+	uint32_t multicast_packets;
+	/*
+	 * Number of indentified L2 broadcast packets.  Does not
+	 * include multicast packets.  Only includes packets whose
+	 * parse mode is SKIP_TO_L2
+	 */
+	uint32_t broadcast_packets;
+	/* Number of 64B packets */
+	uint32_t len_64_packets;
+	/* Number of 65-127B packets */
+	uint32_t len_65_127_packets;
+	/* Number of 128-255B packets */
+	uint32_t len_128_255_packets;
+	/* Number of 256-511B packets */
+	uint32_t len_256_511_packets;
+	/* Number of 512-1023B packets */
+	uint32_t len_512_1023_packets;
+	/* Number of 1024-1518B packets */
+	uint32_t len_1024_1518_packets;
+	/* Number of 1519-max packets */
+	uint32_t len_1519_max_packets;
+	/* Number of packets with FCS or Align opcode errors */
+	uint32_t fcs_align_err_packets;
+	/* Number of packets with length < min */
+	uint32_t runt_packets;
+	/* Number of packets with length < min and FCS error */
+	uint32_t runt_crc_packets;
+	/* Number of packets with length > max */
+	uint32_t oversize_packets;
+	/* Number of packets with length > max and FCS error */
+	uint32_t oversize_crc_packets;
+	/* Number of packets without GMX/SPX/PCI errors received by PIP */
+	uint32_t inb_packets;
+	/*
+	 * Total number of octets from all packets received by PIP,
+	 * including CRC
+	 */
+	uint64_t inb_octets;
+	/* Number of packets with GMX/SPX/PCI errors received by PIP */
+	uint16_t inb_errors;
+} cvmx_pip_port_status_t;
+
+/**
+ * Definition of the PIP custom header that can be prepended
+ * to a packet by external hardware.
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		/*
+		 * Documented as R - Set if the Packet is RAWFULL. If
+		 * set, this header must be the full 8 bytes.
+		 */
+		uint64_t rawfull:1;
+		/* Must be zero */
+		uint64_t reserved0:5;
+		/* PIP parse mode for this packet */
+		uint64_t parse_mode:2;
+		/* Must be zero */
+		uint64_t reserved1:1;
+		/*
+		 * Skip amount, including this header, to the
+		 * beginning of the packet
+		 */
+		uint64_t skip_len:7;
+		/* Must be zero */
+		uint64_t reserved2:6;
+		/* POW input queue for this packet */
+		uint64_t qos:3;
+		/* POW input group for this packet */
+		uint64_t grp:4;
+		/*
+		 * Flag to store this packet in the work queue entry,
+		 * if possible
+		 */
+		uint64_t rs:1;
+		/* POW input tag type */
+		uint64_t tag_type:2;
+		/* POW input tag */
+		uint64_t tag:32;
+	} s;
+} cvmx_pip_pkt_inst_hdr_t;
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+
+/**
+ * Configure an ethernet input port
+ *
+ * @port_num: Port number to configure
+ * @port_cfg: Port hardware configuration
+ * @port_tag_cfg:
+ *                 Port POW tagging configuration
+ */
+static inline void cvmx_pip_config_port(uint64_t port_num,
+					union cvmx_pip_prt_cfgx port_cfg,
+					union cvmx_pip_prt_tagx port_tag_cfg)
+{
+	cvmx_write_csr(CVMX_PIP_PRT_CFGX(port_num), port_cfg.u64);
+	cvmx_write_csr(CVMX_PIP_PRT_TAGX(port_num), port_tag_cfg.u64);
+}
+#if 0
+/**
+ * @deprecated      This function is a thin wrapper around the Pass1 version
+ *                  of the CVMX_PIP_QOS_WATCHX CSR; Pass2 has added a field for
+ *                  setting the group that is incompatible with this function,
+ *                  the preferred upgrade path is to use the CSR directly.
+ *
+ * Configure the global QoS packet watchers. Each watcher is
+ * capable of matching a field in a packet to determine the
+ * QoS queue for scheduling.
+ *
+ * @watcher:    Watcher number to configure (0 - 3).
+ * @match_type: Watcher match type
+ * @match_value:
+ *                   Value the watcher will match against
+ * @qos:        QoS queue for packets matching this watcher
+ */
+static inline void cvmx_pip_config_watcher(uint64_t watcher,
+					   cvmx_pip_qos_watch_types match_type,
+					   uint64_t match_value, uint64_t qos)
+{
+	cvmx_pip_port_watcher_cfg_t watcher_config;
+
+	watcher_config.u64 = 0;
+	watcher_config.s.match_type = match_type;
+	watcher_config.s.match_value = match_value;
+	watcher_config.s.qos = qos;
+
+	cvmx_write_csr(CVMX_PIP_QOS_WATCHX(watcher), watcher_config.u64);
+}
+#endif
+/**
+ * Configure the VLAN priority to QoS queue mapping.
+ *
+ * @vlan_priority:
+ *               VLAN priority (0-7)
+ * @qos:    QoS queue for packets matching this watcher
+ */
+static inline void cvmx_pip_config_vlan_qos(uint64_t vlan_priority,
+					    uint64_t qos)
+{
+	union cvmx_pip_qos_vlanx pip_qos_vlanx;
+	pip_qos_vlanx.u64 = 0;
+	pip_qos_vlanx.s.qos = qos;
+	cvmx_write_csr(CVMX_PIP_QOS_VLANX(vlan_priority), pip_qos_vlanx.u64);
+}
+
+/**
+ * Configure the Diffserv to QoS queue mapping.
+ *
+ * @diffserv: Diffserv field value (0-63)
+ * @qos:      QoS queue for packets matching this watcher
+ */
+static inline void cvmx_pip_config_diffserv_qos(uint64_t diffserv, uint64_t qos)
+{
+	union cvmx_pip_qos_diffx pip_qos_diffx;
+	pip_qos_diffx.u64 = 0;
+	pip_qos_diffx.s.qos = qos;
+	cvmx_write_csr(CVMX_PIP_QOS_DIFFX(diffserv), pip_qos_diffx.u64);
+}
+
+/**
+ * Get the status counters for a port.
+ *
+ * @port_num: Port number to get statistics for.
+ * @clear:    Set to 1 to clear the counters after they are read
+ * @status:   Where to put the results.
+ */
+static inline void cvmx_pip_get_port_status(uint64_t port_num, uint64_t clear,
+					    cvmx_pip_port_status_t *status)
+{
+	union cvmx_pip_stat_ctl pip_stat_ctl;
+	union cvmx_pip_stat0_prtx stat0;
+	union cvmx_pip_stat1_prtx stat1;
+	union cvmx_pip_stat2_prtx stat2;
+	union cvmx_pip_stat3_prtx stat3;
+	union cvmx_pip_stat4_prtx stat4;
+	union cvmx_pip_stat5_prtx stat5;
+	union cvmx_pip_stat6_prtx stat6;
+	union cvmx_pip_stat7_prtx stat7;
+	union cvmx_pip_stat8_prtx stat8;
+	union cvmx_pip_stat9_prtx stat9;
+	union cvmx_pip_stat_inb_pktsx pip_stat_inb_pktsx;
+	union cvmx_pip_stat_inb_octsx pip_stat_inb_octsx;
+	union cvmx_pip_stat_inb_errsx pip_stat_inb_errsx;
+
+	pip_stat_ctl.u64 = 0;
+	pip_stat_ctl.s.rdclr = clear;
+	cvmx_write_csr(CVMX_PIP_STAT_CTL, pip_stat_ctl.u64);
+
+	stat0.u64 = cvmx_read_csr(CVMX_PIP_STAT0_PRTX(port_num));
+	stat1.u64 = cvmx_read_csr(CVMX_PIP_STAT1_PRTX(port_num));
+	stat2.u64 = cvmx_read_csr(CVMX_PIP_STAT2_PRTX(port_num));
+	stat3.u64 = cvmx_read_csr(CVMX_PIP_STAT3_PRTX(port_num));
+	stat4.u64 = cvmx_read_csr(CVMX_PIP_STAT4_PRTX(port_num));
+	stat5.u64 = cvmx_read_csr(CVMX_PIP_STAT5_PRTX(port_num));
+	stat6.u64 = cvmx_read_csr(CVMX_PIP_STAT6_PRTX(port_num));
+	stat7.u64 = cvmx_read_csr(CVMX_PIP_STAT7_PRTX(port_num));
+	stat8.u64 = cvmx_read_csr(CVMX_PIP_STAT8_PRTX(port_num));
+	stat9.u64 = cvmx_read_csr(CVMX_PIP_STAT9_PRTX(port_num));
+	pip_stat_inb_pktsx.u64 =
+	    cvmx_read_csr(CVMX_PIP_STAT_INB_PKTSX(port_num));
+	pip_stat_inb_octsx.u64 =
+	    cvmx_read_csr(CVMX_PIP_STAT_INB_OCTSX(port_num));
+	pip_stat_inb_errsx.u64 =
+	    cvmx_read_csr(CVMX_PIP_STAT_INB_ERRSX(port_num));
+
+	status->dropped_octets = stat0.s.drp_octs;
+	status->dropped_packets = stat0.s.drp_pkts;
+	status->octets = stat1.s.octs;
+	status->pci_raw_packets = stat2.s.raw;
+	status->packets = stat2.s.pkts;
+	status->multicast_packets = stat3.s.mcst;
+	status->broadcast_packets = stat3.s.bcst;
+	status->len_64_packets = stat4.s.h64;
+	status->len_65_127_packets = stat4.s.h65to127;
+	status->len_128_255_packets = stat5.s.h128to255;
+	status->len_256_511_packets = stat5.s.h256to511;
+	status->len_512_1023_packets = stat6.s.h512to1023;
+	status->len_1024_1518_packets = stat6.s.h1024to1518;
+	status->len_1519_max_packets = stat7.s.h1519;
+	status->fcs_align_err_packets = stat7.s.fcs;
+	status->runt_packets = stat8.s.undersz;
+	status->runt_crc_packets = stat8.s.frag;
+	status->oversize_packets = stat9.s.oversz;
+	status->oversize_crc_packets = stat9.s.jabber;
+	status->inb_packets = pip_stat_inb_pktsx.s.pkts;
+	status->inb_octets = pip_stat_inb_octsx.s.octs;
+	status->inb_errors = pip_stat_inb_errsx.s.errs;
+
+	if (cvmx_octeon_is_pass1()) {
+		/*
+		 * Kludge to fix Octeon Pass 1 errata - Drop counts
+		 * don't work.
+		 */
+		if (status->inb_packets > status->packets)
+			status->dropped_packets =
+			    status->inb_packets - status->packets;
+		else
+			status->dropped_packets = 0;
+		if (status->inb_octets - status->inb_packets * 4 >
+		    status->octets)
+			status->dropped_octets =
+			    status->inb_octets - status->inb_packets * 4 -
+			    status->octets;
+		else
+			status->dropped_octets = 0;
+	}
+}
+
+/**
+ * Configure the hardware CRC engine
+ *
+ * @interface: Interface to configure (0 or 1)
+ * @invert_result:
+ *                 Invert the result of the CRC
+ * @reflect:  Reflect
+ * @initialization_vector:
+ *                 CRC initialization vector
+ */
+static inline void cvmx_pip_config_crc(uint64_t interface,
+				       uint64_t invert_result, uint64_t reflect,
+				       uint32_t initialization_vector)
+{
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+		union cvmx_pip_crc_ctlx config;
+		union cvmx_pip_crc_ivx pip_crc_ivx;
+
+		config.u64 = 0;
+		config.s.invres = invert_result;
+		config.s.reflect = reflect;
+		cvmx_write_csr(CVMX_PIP_CRC_CTLX(interface), config.u64);
+
+		pip_crc_ivx.u64 = 0;
+		pip_crc_ivx.s.iv = initialization_vector;
+		cvmx_write_csr(CVMX_PIP_CRC_IVX(interface), pip_crc_ivx.u64);
+	}
+}
+
+/**
+ * Clear all bits in a tag mask. This should be called on
+ * startup before any calls to cvmx_pip_tag_mask_set. Each bit
+ * set in the final mask represent a byte used in the packet for
+ * tag generation.
+ *
+ * @mask_index: Which tag mask to clear (0..3)
+ */
+static inline void cvmx_pip_tag_mask_clear(uint64_t mask_index)
+{
+	uint64_t index;
+	union cvmx_pip_tag_incx pip_tag_incx;
+	pip_tag_incx.u64 = 0;
+	pip_tag_incx.s.en = 0;
+	for (index = mask_index * 16; index < (mask_index + 1) * 16; index++)
+		cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
+}
+
+/**
+ * Sets a range of bits in the tag mask. The tag mask is used
+ * when the cvmx_pip_port_tag_cfg_t tag_mode is non zero.
+ * There are four separate masks that can be configured.
+ *
+ * @mask_index: Which tag mask to modify (0..3)
+ * @offset: Offset into the bitmask to set bits at. Use the GCC macro
+ *          offsetof() to determine the offsets into packet headers.
+ *          For example, offsetof(ethhdr, protocol) returns the offset
+ *          of the ethernet protocol field.  The bitmask selects which
+ *          bytes to include the the tag, with bit offset X selecting
+ *          byte at offset X from the beginning of the packet data.
+ * @len:    Number of bytes to include. Usually this is the sizeof()
+ *          the field.
+ */
+static inline void cvmx_pip_tag_mask_set(uint64_t mask_index, uint64_t offset,
+					 uint64_t len)
+{
+	while (len--) {
+		union cvmx_pip_tag_incx pip_tag_incx;
+		uint64_t index = mask_index * 16 + offset / 8;
+		pip_tag_incx.u64 = cvmx_read_csr(CVMX_PIP_TAG_INCX(index));
+		pip_tag_incx.s.en |= 0x80 >> (offset & 0x7);
+		cvmx_write_csr(CVMX_PIP_TAG_INCX(index), pip_tag_incx.u64);
+		offset++;
+	}
+}
+
+#endif /*  __CVMX_PIP_H__ */
diff --git a/drivers/staging/octeon/cvmx-pko-defs.h b/drivers/staging/octeon/cvmx-pko-defs.h
new file mode 100644
index 0000000..50e779c
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pko-defs.h
@@ -0,0 +1,1133 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PKO_DEFS_H__
+#define __CVMX_PKO_DEFS_H__
+
+#define CVMX_PKO_MEM_COUNT0 \
+	 CVMX_ADD_IO_SEG(0x0001180050001080ull)
+#define CVMX_PKO_MEM_COUNT1 \
+	 CVMX_ADD_IO_SEG(0x0001180050001088ull)
+#define CVMX_PKO_MEM_DEBUG0 \
+	 CVMX_ADD_IO_SEG(0x0001180050001100ull)
+#define CVMX_PKO_MEM_DEBUG1 \
+	 CVMX_ADD_IO_SEG(0x0001180050001108ull)
+#define CVMX_PKO_MEM_DEBUG10 \
+	 CVMX_ADD_IO_SEG(0x0001180050001150ull)
+#define CVMX_PKO_MEM_DEBUG11 \
+	 CVMX_ADD_IO_SEG(0x0001180050001158ull)
+#define CVMX_PKO_MEM_DEBUG12 \
+	 CVMX_ADD_IO_SEG(0x0001180050001160ull)
+#define CVMX_PKO_MEM_DEBUG13 \
+	 CVMX_ADD_IO_SEG(0x0001180050001168ull)
+#define CVMX_PKO_MEM_DEBUG14 \
+	 CVMX_ADD_IO_SEG(0x0001180050001170ull)
+#define CVMX_PKO_MEM_DEBUG2 \
+	 CVMX_ADD_IO_SEG(0x0001180050001110ull)
+#define CVMX_PKO_MEM_DEBUG3 \
+	 CVMX_ADD_IO_SEG(0x0001180050001118ull)
+#define CVMX_PKO_MEM_DEBUG4 \
+	 CVMX_ADD_IO_SEG(0x0001180050001120ull)
+#define CVMX_PKO_MEM_DEBUG5 \
+	 CVMX_ADD_IO_SEG(0x0001180050001128ull)
+#define CVMX_PKO_MEM_DEBUG6 \
+	 CVMX_ADD_IO_SEG(0x0001180050001130ull)
+#define CVMX_PKO_MEM_DEBUG7 \
+	 CVMX_ADD_IO_SEG(0x0001180050001138ull)
+#define CVMX_PKO_MEM_DEBUG8 \
+	 CVMX_ADD_IO_SEG(0x0001180050001140ull)
+#define CVMX_PKO_MEM_DEBUG9 \
+	 CVMX_ADD_IO_SEG(0x0001180050001148ull)
+#define CVMX_PKO_MEM_PORT_PTRS \
+	 CVMX_ADD_IO_SEG(0x0001180050001010ull)
+#define CVMX_PKO_MEM_PORT_QOS \
+	 CVMX_ADD_IO_SEG(0x0001180050001018ull)
+#define CVMX_PKO_MEM_PORT_RATE0 \
+	 CVMX_ADD_IO_SEG(0x0001180050001020ull)
+#define CVMX_PKO_MEM_PORT_RATE1 \
+	 CVMX_ADD_IO_SEG(0x0001180050001028ull)
+#define CVMX_PKO_MEM_QUEUE_PTRS \
+	 CVMX_ADD_IO_SEG(0x0001180050001000ull)
+#define CVMX_PKO_MEM_QUEUE_QOS \
+	 CVMX_ADD_IO_SEG(0x0001180050001008ull)
+#define CVMX_PKO_REG_BIST_RESULT \
+	 CVMX_ADD_IO_SEG(0x0001180050000080ull)
+#define CVMX_PKO_REG_CMD_BUF \
+	 CVMX_ADD_IO_SEG(0x0001180050000010ull)
+#define CVMX_PKO_REG_CRC_CTLX(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
+#define CVMX_PKO_REG_CRC_ENABLE \
+	 CVMX_ADD_IO_SEG(0x0001180050000020ull)
+#define CVMX_PKO_REG_CRC_IVX(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
+#define CVMX_PKO_REG_DEBUG0 \
+	 CVMX_ADD_IO_SEG(0x0001180050000098ull)
+#define CVMX_PKO_REG_DEBUG1 \
+	 CVMX_ADD_IO_SEG(0x00011800500000A0ull)
+#define CVMX_PKO_REG_DEBUG2 \
+	 CVMX_ADD_IO_SEG(0x00011800500000A8ull)
+#define CVMX_PKO_REG_DEBUG3 \
+	 CVMX_ADD_IO_SEG(0x00011800500000B0ull)
+#define CVMX_PKO_REG_ENGINE_INFLIGHT \
+	 CVMX_ADD_IO_SEG(0x0001180050000050ull)
+#define CVMX_PKO_REG_ENGINE_THRESH \
+	 CVMX_ADD_IO_SEG(0x0001180050000058ull)
+#define CVMX_PKO_REG_ERROR \
+	 CVMX_ADD_IO_SEG(0x0001180050000088ull)
+#define CVMX_PKO_REG_FLAGS \
+	 CVMX_ADD_IO_SEG(0x0001180050000000ull)
+#define CVMX_PKO_REG_GMX_PORT_MODE \
+	 CVMX_ADD_IO_SEG(0x0001180050000018ull)
+#define CVMX_PKO_REG_INT_MASK \
+	 CVMX_ADD_IO_SEG(0x0001180050000090ull)
+#define CVMX_PKO_REG_QUEUE_MODE \
+	 CVMX_ADD_IO_SEG(0x0001180050000048ull)
+#define CVMX_PKO_REG_QUEUE_PTRS1 \
+	 CVMX_ADD_IO_SEG(0x0001180050000100ull)
+#define CVMX_PKO_REG_READ_IDX \
+	 CVMX_ADD_IO_SEG(0x0001180050000008ull)
+
+union cvmx_pko_mem_count0 {
+	uint64_t u64;
+	struct cvmx_pko_mem_count0_s {
+		uint64_t reserved_32_63:32;
+		uint64_t count:32;
+	} s;
+	struct cvmx_pko_mem_count0_s cn30xx;
+	struct cvmx_pko_mem_count0_s cn31xx;
+	struct cvmx_pko_mem_count0_s cn38xx;
+	struct cvmx_pko_mem_count0_s cn38xxp2;
+	struct cvmx_pko_mem_count0_s cn50xx;
+	struct cvmx_pko_mem_count0_s cn52xx;
+	struct cvmx_pko_mem_count0_s cn52xxp1;
+	struct cvmx_pko_mem_count0_s cn56xx;
+	struct cvmx_pko_mem_count0_s cn56xxp1;
+	struct cvmx_pko_mem_count0_s cn58xx;
+	struct cvmx_pko_mem_count0_s cn58xxp1;
+};
+
+union cvmx_pko_mem_count1 {
+	uint64_t u64;
+	struct cvmx_pko_mem_count1_s {
+		uint64_t reserved_48_63:16;
+		uint64_t count:48;
+	} s;
+	struct cvmx_pko_mem_count1_s cn30xx;
+	struct cvmx_pko_mem_count1_s cn31xx;
+	struct cvmx_pko_mem_count1_s cn38xx;
+	struct cvmx_pko_mem_count1_s cn38xxp2;
+	struct cvmx_pko_mem_count1_s cn50xx;
+	struct cvmx_pko_mem_count1_s cn52xx;
+	struct cvmx_pko_mem_count1_s cn52xxp1;
+	struct cvmx_pko_mem_count1_s cn56xx;
+	struct cvmx_pko_mem_count1_s cn56xxp1;
+	struct cvmx_pko_mem_count1_s cn58xx;
+	struct cvmx_pko_mem_count1_s cn58xxp1;
+};
+
+union cvmx_pko_mem_debug0 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug0_s {
+		uint64_t fau:28;
+		uint64_t cmd:14;
+		uint64_t segs:6;
+		uint64_t size:16;
+	} s;
+	struct cvmx_pko_mem_debug0_s cn30xx;
+	struct cvmx_pko_mem_debug0_s cn31xx;
+	struct cvmx_pko_mem_debug0_s cn38xx;
+	struct cvmx_pko_mem_debug0_s cn38xxp2;
+	struct cvmx_pko_mem_debug0_s cn50xx;
+	struct cvmx_pko_mem_debug0_s cn52xx;
+	struct cvmx_pko_mem_debug0_s cn52xxp1;
+	struct cvmx_pko_mem_debug0_s cn56xx;
+	struct cvmx_pko_mem_debug0_s cn56xxp1;
+	struct cvmx_pko_mem_debug0_s cn58xx;
+	struct cvmx_pko_mem_debug0_s cn58xxp1;
+};
+
+union cvmx_pko_mem_debug1 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug1_s {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t ptr:40;
+	} s;
+	struct cvmx_pko_mem_debug1_s cn30xx;
+	struct cvmx_pko_mem_debug1_s cn31xx;
+	struct cvmx_pko_mem_debug1_s cn38xx;
+	struct cvmx_pko_mem_debug1_s cn38xxp2;
+	struct cvmx_pko_mem_debug1_s cn50xx;
+	struct cvmx_pko_mem_debug1_s cn52xx;
+	struct cvmx_pko_mem_debug1_s cn52xxp1;
+	struct cvmx_pko_mem_debug1_s cn56xx;
+	struct cvmx_pko_mem_debug1_s cn56xxp1;
+	struct cvmx_pko_mem_debug1_s cn58xx;
+	struct cvmx_pko_mem_debug1_s cn58xxp1;
+};
+
+union cvmx_pko_mem_debug10 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug10_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug10_cn30xx {
+		uint64_t fau:28;
+		uint64_t cmd:14;
+		uint64_t segs:6;
+		uint64_t size:16;
+	} cn30xx;
+	struct cvmx_pko_mem_debug10_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug10_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug10_cn50xx {
+		uint64_t reserved_49_63:15;
+		uint64_t ptrs1:17;
+		uint64_t reserved_17_31:15;
+		uint64_t ptrs2:17;
+	} cn50xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug10_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug10_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug11 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug11_s {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t reserved_0_39:40;
+	} s;
+	struct cvmx_pko_mem_debug11_cn30xx {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t ptr:40;
+	} cn30xx;
+	struct cvmx_pko_mem_debug11_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug11_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug11_cn50xx {
+		uint64_t reserved_23_63:41;
+		uint64_t maj:1;
+		uint64_t uid:3;
+		uint64_t sop:1;
+		uint64_t len:1;
+		uint64_t chk:1;
+		uint64_t cnt:13;
+		uint64_t mod:3;
+	} cn50xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug11_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug11_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug12 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug12_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug12_cn30xx {
+		uint64_t data:64;
+	} cn30xx;
+	struct cvmx_pko_mem_debug12_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug12_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug12_cn50xx {
+		uint64_t fau:28;
+		uint64_t cmd:14;
+		uint64_t segs:6;
+		uint64_t size:16;
+	} cn50xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug12_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug12_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug13 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug13_s {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t reserved_0_55:56;
+	} s;
+	struct cvmx_pko_mem_debug13_cn30xx {
+		uint64_t reserved_51_63:13;
+		uint64_t widx:17;
+		uint64_t ridx2:17;
+		uint64_t widx2:17;
+	} cn30xx;
+	struct cvmx_pko_mem_debug13_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug13_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug13_cn50xx {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t ptr:40;
+	} cn50xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug13_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug13_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug14 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug14_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug14_cn30xx {
+		uint64_t reserved_17_63:47;
+		uint64_t ridx:17;
+	} cn30xx;
+	struct cvmx_pko_mem_debug14_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug14_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug14_cn52xx {
+		uint64_t data:64;
+	} cn52xx;
+	struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_debug14_cn52xx cn56xx;
+	struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
+};
+
+union cvmx_pko_mem_debug2 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug2_s {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t ptr:40;
+	} s;
+	struct cvmx_pko_mem_debug2_s cn30xx;
+	struct cvmx_pko_mem_debug2_s cn31xx;
+	struct cvmx_pko_mem_debug2_s cn38xx;
+	struct cvmx_pko_mem_debug2_s cn38xxp2;
+	struct cvmx_pko_mem_debug2_s cn50xx;
+	struct cvmx_pko_mem_debug2_s cn52xx;
+	struct cvmx_pko_mem_debug2_s cn52xxp1;
+	struct cvmx_pko_mem_debug2_s cn56xx;
+	struct cvmx_pko_mem_debug2_s cn56xxp1;
+	struct cvmx_pko_mem_debug2_s cn58xx;
+	struct cvmx_pko_mem_debug2_s cn58xxp1;
+};
+
+union cvmx_pko_mem_debug3 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug3_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug3_cn30xx {
+		uint64_t i:1;
+		uint64_t back:4;
+		uint64_t pool:3;
+		uint64_t size:16;
+		uint64_t ptr:40;
+	} cn30xx;
+	struct cvmx_pko_mem_debug3_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug3_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug3_cn50xx {
+		uint64_t data:64;
+	} cn50xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug3_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug3_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug4 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug4_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug4_cn30xx {
+		uint64_t data:64;
+	} cn30xx;
+	struct cvmx_pko_mem_debug4_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug4_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug4_cn50xx {
+		uint64_t cmnd_segs:3;
+		uint64_t cmnd_siz:16;
+		uint64_t cmnd_off:6;
+		uint64_t uid:3;
+		uint64_t dread_sop:1;
+		uint64_t init_dwrite:1;
+		uint64_t chk_once:1;
+		uint64_t chk_mode:1;
+		uint64_t active:1;
+		uint64_t static_p:1;
+		uint64_t qos:3;
+		uint64_t qcb_ridx:5;
+		uint64_t qid_off_max:4;
+		uint64_t qid_off:4;
+		uint64_t qid_base:8;
+		uint64_t wait:1;
+		uint64_t minor:2;
+		uint64_t major:3;
+	} cn50xx;
+	struct cvmx_pko_mem_debug4_cn52xx {
+		uint64_t curr_siz:8;
+		uint64_t curr_off:16;
+		uint64_t cmnd_segs:6;
+		uint64_t cmnd_siz:16;
+		uint64_t cmnd_off:6;
+		uint64_t uid:2;
+		uint64_t dread_sop:1;
+		uint64_t init_dwrite:1;
+		uint64_t chk_once:1;
+		uint64_t chk_mode:1;
+		uint64_t wait:1;
+		uint64_t minor:2;
+		uint64_t major:3;
+	} cn52xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_debug4_cn52xx cn56xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_debug4_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug5 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug5_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_mem_debug5_cn30xx {
+		uint64_t dwri_mod:1;
+		uint64_t dwri_sop:1;
+		uint64_t dwri_len:1;
+		uint64_t dwri_cnt:13;
+		uint64_t cmnd_siz:16;
+		uint64_t uid:1;
+		uint64_t xfer_wor:1;
+		uint64_t xfer_dwr:1;
+		uint64_t cbuf_fre:1;
+		uint64_t reserved_27_27:1;
+		uint64_t chk_mode:1;
+		uint64_t active:1;
+		uint64_t qos:3;
+		uint64_t qcb_ridx:5;
+		uint64_t qid_off:3;
+		uint64_t qid_base:7;
+		uint64_t wait:1;
+		uint64_t minor:2;
+		uint64_t major:4;
+	} cn30xx;
+	struct cvmx_pko_mem_debug5_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug5_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug5_cn50xx {
+		uint64_t curr_ptr:29;
+		uint64_t curr_siz:16;
+		uint64_t curr_off:16;
+		uint64_t cmnd_segs:3;
+	} cn50xx;
+	struct cvmx_pko_mem_debug5_cn52xx {
+		uint64_t reserved_54_63:10;
+		uint64_t nxt_inflt:6;
+		uint64_t curr_ptr:40;
+		uint64_t curr_siz:8;
+	} cn52xx;
+	struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_debug5_cn52xx cn56xx;
+	struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_debug5_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug6 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug6_s {
+		uint64_t reserved_37_63:27;
+		uint64_t qid_offres:4;
+		uint64_t qid_offths:4;
+		uint64_t preempter:1;
+		uint64_t preemptee:1;
+		uint64_t preempted:1;
+		uint64_t active:1;
+		uint64_t statc:1;
+		uint64_t qos:3;
+		uint64_t qcb_ridx:5;
+		uint64_t qid_offmax:4;
+		uint64_t reserved_0_11:12;
+	} s;
+	struct cvmx_pko_mem_debug6_cn30xx {
+		uint64_t reserved_11_63:53;
+		uint64_t qid_offm:3;
+		uint64_t static_p:1;
+		uint64_t work_min:3;
+		uint64_t dwri_chk:1;
+		uint64_t dwri_uid:1;
+		uint64_t dwri_mod:2;
+	} cn30xx;
+	struct cvmx_pko_mem_debug6_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug6_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug6_cn50xx {
+		uint64_t reserved_11_63:53;
+		uint64_t curr_ptr:11;
+	} cn50xx;
+	struct cvmx_pko_mem_debug6_cn52xx {
+		uint64_t reserved_37_63:27;
+		uint64_t qid_offres:4;
+		uint64_t qid_offths:4;
+		uint64_t preempter:1;
+		uint64_t preemptee:1;
+		uint64_t preempted:1;
+		uint64_t active:1;
+		uint64_t statc:1;
+		uint64_t qos:3;
+		uint64_t qcb_ridx:5;
+		uint64_t qid_offmax:4;
+		uint64_t qid_off:4;
+		uint64_t qid_base:8;
+	} cn52xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_debug6_cn52xx cn56xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_debug6_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug7 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug7_s {
+		uint64_t qos:5;
+		uint64_t tail:1;
+		uint64_t reserved_0_57:58;
+	} s;
+	struct cvmx_pko_mem_debug7_cn30xx {
+		uint64_t reserved_58_63:6;
+		uint64_t dwb:9;
+		uint64_t start:33;
+		uint64_t size:16;
+	} cn30xx;
+	struct cvmx_pko_mem_debug7_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug7_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug7_cn50xx {
+		uint64_t qos:5;
+		uint64_t tail:1;
+		uint64_t buf_siz:13;
+		uint64_t buf_ptr:33;
+		uint64_t qcb_widx:6;
+		uint64_t qcb_ridx:6;
+	} cn50xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug7_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug7_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug8 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug8_s {
+		uint64_t reserved_59_63:5;
+		uint64_t tail:1;
+		uint64_t buf_siz:13;
+		uint64_t reserved_0_44:45;
+	} s;
+	struct cvmx_pko_mem_debug8_cn30xx {
+		uint64_t qos:5;
+		uint64_t tail:1;
+		uint64_t buf_siz:13;
+		uint64_t buf_ptr:33;
+		uint64_t qcb_widx:6;
+		uint64_t qcb_ridx:6;
+	} cn30xx;
+	struct cvmx_pko_mem_debug8_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug8_cn30xx cn38xx;
+	struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
+	struct cvmx_pko_mem_debug8_cn50xx {
+		uint64_t reserved_28_63:36;
+		uint64_t doorbell:20;
+		uint64_t reserved_6_7:2;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:3;
+	} cn50xx;
+	struct cvmx_pko_mem_debug8_cn52xx {
+		uint64_t reserved_29_63:35;
+		uint64_t preempter:1;
+		uint64_t doorbell:20;
+		uint64_t reserved_7_7:1;
+		uint64_t preemptee:1;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:3;
+	} cn52xx;
+	struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_debug8_cn52xx cn56xx;
+	struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_debug8_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_debug9 {
+	uint64_t u64;
+	struct cvmx_pko_mem_debug9_s {
+		uint64_t reserved_49_63:15;
+		uint64_t ptrs0:17;
+		uint64_t reserved_0_31:32;
+	} s;
+	struct cvmx_pko_mem_debug9_cn30xx {
+		uint64_t reserved_28_63:36;
+		uint64_t doorbell:20;
+		uint64_t reserved_5_7:3;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:3;
+	} cn30xx;
+	struct cvmx_pko_mem_debug9_cn30xx cn31xx;
+	struct cvmx_pko_mem_debug9_cn38xx {
+		uint64_t reserved_28_63:36;
+		uint64_t doorbell:20;
+		uint64_t reserved_6_7:2;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:3;
+	} cn38xx;
+	struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
+	struct cvmx_pko_mem_debug9_cn50xx {
+		uint64_t reserved_49_63:15;
+		uint64_t ptrs0:17;
+		uint64_t reserved_17_31:15;
+		uint64_t ptrs3:17;
+	} cn50xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn52xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
+	struct cvmx_pko_mem_debug9_cn50xx cn56xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
+	struct cvmx_pko_mem_debug9_cn50xx cn58xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_mem_port_ptrs {
+	uint64_t u64;
+	struct cvmx_pko_mem_port_ptrs_s {
+		uint64_t reserved_62_63:2;
+		uint64_t static_p:1;
+		uint64_t qos_mask:8;
+		uint64_t reserved_16_52:37;
+		uint64_t bp_port:6;
+		uint64_t eid:4;
+		uint64_t pid:6;
+	} s;
+	struct cvmx_pko_mem_port_ptrs_s cn52xx;
+	struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
+	struct cvmx_pko_mem_port_ptrs_s cn56xx;
+	struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
+};
+
+union cvmx_pko_mem_port_qos {
+	uint64_t u64;
+	struct cvmx_pko_mem_port_qos_s {
+		uint64_t reserved_61_63:3;
+		uint64_t qos_mask:8;
+		uint64_t reserved_10_52:43;
+		uint64_t eid:4;
+		uint64_t pid:6;
+	} s;
+	struct cvmx_pko_mem_port_qos_s cn52xx;
+	struct cvmx_pko_mem_port_qos_s cn52xxp1;
+	struct cvmx_pko_mem_port_qos_s cn56xx;
+	struct cvmx_pko_mem_port_qos_s cn56xxp1;
+};
+
+union cvmx_pko_mem_port_rate0 {
+	uint64_t u64;
+	struct cvmx_pko_mem_port_rate0_s {
+		uint64_t reserved_51_63:13;
+		uint64_t rate_word:19;
+		uint64_t rate_pkt:24;
+		uint64_t reserved_6_7:2;
+		uint64_t pid:6;
+	} s;
+	struct cvmx_pko_mem_port_rate0_s cn52xx;
+	struct cvmx_pko_mem_port_rate0_s cn52xxp1;
+	struct cvmx_pko_mem_port_rate0_s cn56xx;
+	struct cvmx_pko_mem_port_rate0_s cn56xxp1;
+};
+
+union cvmx_pko_mem_port_rate1 {
+	uint64_t u64;
+	struct cvmx_pko_mem_port_rate1_s {
+		uint64_t reserved_32_63:32;
+		uint64_t rate_lim:24;
+		uint64_t reserved_6_7:2;
+		uint64_t pid:6;
+	} s;
+	struct cvmx_pko_mem_port_rate1_s cn52xx;
+	struct cvmx_pko_mem_port_rate1_s cn52xxp1;
+	struct cvmx_pko_mem_port_rate1_s cn56xx;
+	struct cvmx_pko_mem_port_rate1_s cn56xxp1;
+};
+
+union cvmx_pko_mem_queue_ptrs {
+	uint64_t u64;
+	struct cvmx_pko_mem_queue_ptrs_s {
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t static_q:1;
+		uint64_t qos_mask:8;
+		uint64_t buf_ptr:36;
+		uint64_t tail:1;
+		uint64_t index:3;
+		uint64_t port:6;
+		uint64_t queue:7;
+	} s;
+	struct cvmx_pko_mem_queue_ptrs_s cn30xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn31xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn38xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn38xxp2;
+	struct cvmx_pko_mem_queue_ptrs_s cn50xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn52xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn52xxp1;
+	struct cvmx_pko_mem_queue_ptrs_s cn56xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
+	struct cvmx_pko_mem_queue_ptrs_s cn58xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
+};
+
+union cvmx_pko_mem_queue_qos {
+	uint64_t u64;
+	struct cvmx_pko_mem_queue_qos_s {
+		uint64_t reserved_61_63:3;
+		uint64_t qos_mask:8;
+		uint64_t reserved_13_52:40;
+		uint64_t pid:6;
+		uint64_t qid:7;
+	} s;
+	struct cvmx_pko_mem_queue_qos_s cn30xx;
+	struct cvmx_pko_mem_queue_qos_s cn31xx;
+	struct cvmx_pko_mem_queue_qos_s cn38xx;
+	struct cvmx_pko_mem_queue_qos_s cn38xxp2;
+	struct cvmx_pko_mem_queue_qos_s cn50xx;
+	struct cvmx_pko_mem_queue_qos_s cn52xx;
+	struct cvmx_pko_mem_queue_qos_s cn52xxp1;
+	struct cvmx_pko_mem_queue_qos_s cn56xx;
+	struct cvmx_pko_mem_queue_qos_s cn56xxp1;
+	struct cvmx_pko_mem_queue_qos_s cn58xx;
+	struct cvmx_pko_mem_queue_qos_s cn58xxp1;
+};
+
+union cvmx_pko_reg_bist_result {
+	uint64_t u64;
+	struct cvmx_pko_reg_bist_result_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_pko_reg_bist_result_cn30xx {
+		uint64_t reserved_27_63:37;
+		uint64_t psb2:5;
+		uint64_t count:1;
+		uint64_t rif:1;
+		uint64_t wif:1;
+		uint64_t ncb:1;
+		uint64_t out:1;
+		uint64_t crc:1;
+		uint64_t chk:1;
+		uint64_t qsb:2;
+		uint64_t qcb:2;
+		uint64_t pdb:4;
+		uint64_t psb:7;
+	} cn30xx;
+	struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
+	struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
+	struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
+	struct cvmx_pko_reg_bist_result_cn50xx {
+		uint64_t reserved_33_63:31;
+		uint64_t csr:1;
+		uint64_t iob:1;
+		uint64_t out_crc:1;
+		uint64_t out_ctl:3;
+		uint64_t out_sta:1;
+		uint64_t out_wif:1;
+		uint64_t prt_chk:3;
+		uint64_t prt_nxt:1;
+		uint64_t prt_psb:6;
+		uint64_t ncb_inb:2;
+		uint64_t prt_qcb:2;
+		uint64_t prt_qsb:3;
+		uint64_t dat_dat:4;
+		uint64_t dat_ptr:4;
+	} cn50xx;
+	struct cvmx_pko_reg_bist_result_cn52xx {
+		uint64_t reserved_35_63:29;
+		uint64_t csr:1;
+		uint64_t iob:1;
+		uint64_t out_dat:1;
+		uint64_t out_ctl:3;
+		uint64_t out_sta:1;
+		uint64_t out_wif:1;
+		uint64_t prt_chk:3;
+		uint64_t prt_nxt:1;
+		uint64_t prt_psb:8;
+		uint64_t ncb_inb:2;
+		uint64_t prt_qcb:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_ctl:2;
+		uint64_t dat_dat:2;
+		uint64_t dat_ptr:4;
+	} cn52xx;
+	struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
+	struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
+	struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
+	struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
+	struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
+};
+
+union cvmx_pko_reg_cmd_buf {
+	uint64_t u64;
+	struct cvmx_pko_reg_cmd_buf_s {
+		uint64_t reserved_23_63:41;
+		uint64_t pool:3;
+		uint64_t reserved_13_19:7;
+		uint64_t size:13;
+	} s;
+	struct cvmx_pko_reg_cmd_buf_s cn30xx;
+	struct cvmx_pko_reg_cmd_buf_s cn31xx;
+	struct cvmx_pko_reg_cmd_buf_s cn38xx;
+	struct cvmx_pko_reg_cmd_buf_s cn38xxp2;
+	struct cvmx_pko_reg_cmd_buf_s cn50xx;
+	struct cvmx_pko_reg_cmd_buf_s cn52xx;
+	struct cvmx_pko_reg_cmd_buf_s cn52xxp1;
+	struct cvmx_pko_reg_cmd_buf_s cn56xx;
+	struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
+	struct cvmx_pko_reg_cmd_buf_s cn58xx;
+	struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
+};
+
+union cvmx_pko_reg_crc_ctlx {
+	uint64_t u64;
+	struct cvmx_pko_reg_crc_ctlx_s {
+		uint64_t reserved_2_63:62;
+		uint64_t invres:1;
+		uint64_t refin:1;
+	} s;
+	struct cvmx_pko_reg_crc_ctlx_s cn38xx;
+	struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
+	struct cvmx_pko_reg_crc_ctlx_s cn58xx;
+	struct cvmx_pko_reg_crc_ctlx_s cn58xxp1;
+};
+
+union cvmx_pko_reg_crc_enable {
+	uint64_t u64;
+	struct cvmx_pko_reg_crc_enable_s {
+		uint64_t reserved_32_63:32;
+		uint64_t enable:32;
+	} s;
+	struct cvmx_pko_reg_crc_enable_s cn38xx;
+	struct cvmx_pko_reg_crc_enable_s cn38xxp2;
+	struct cvmx_pko_reg_crc_enable_s cn58xx;
+	struct cvmx_pko_reg_crc_enable_s cn58xxp1;
+};
+
+union cvmx_pko_reg_crc_ivx {
+	uint64_t u64;
+	struct cvmx_pko_reg_crc_ivx_s {
+		uint64_t reserved_32_63:32;
+		uint64_t iv:32;
+	} s;
+	struct cvmx_pko_reg_crc_ivx_s cn38xx;
+	struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
+	struct cvmx_pko_reg_crc_ivx_s cn58xx;
+	struct cvmx_pko_reg_crc_ivx_s cn58xxp1;
+};
+
+union cvmx_pko_reg_debug0 {
+	uint64_t u64;
+	struct cvmx_pko_reg_debug0_s {
+		uint64_t asserts:64;
+	} s;
+	struct cvmx_pko_reg_debug0_cn30xx {
+		uint64_t reserved_17_63:47;
+		uint64_t asserts:17;
+	} cn30xx;
+	struct cvmx_pko_reg_debug0_cn30xx cn31xx;
+	struct cvmx_pko_reg_debug0_cn30xx cn38xx;
+	struct cvmx_pko_reg_debug0_cn30xx cn38xxp2;
+	struct cvmx_pko_reg_debug0_s cn50xx;
+	struct cvmx_pko_reg_debug0_s cn52xx;
+	struct cvmx_pko_reg_debug0_s cn52xxp1;
+	struct cvmx_pko_reg_debug0_s cn56xx;
+	struct cvmx_pko_reg_debug0_s cn56xxp1;
+	struct cvmx_pko_reg_debug0_s cn58xx;
+	struct cvmx_pko_reg_debug0_s cn58xxp1;
+};
+
+union cvmx_pko_reg_debug1 {
+	uint64_t u64;
+	struct cvmx_pko_reg_debug1_s {
+		uint64_t asserts:64;
+	} s;
+	struct cvmx_pko_reg_debug1_s cn50xx;
+	struct cvmx_pko_reg_debug1_s cn52xx;
+	struct cvmx_pko_reg_debug1_s cn52xxp1;
+	struct cvmx_pko_reg_debug1_s cn56xx;
+	struct cvmx_pko_reg_debug1_s cn56xxp1;
+	struct cvmx_pko_reg_debug1_s cn58xx;
+	struct cvmx_pko_reg_debug1_s cn58xxp1;
+};
+
+union cvmx_pko_reg_debug2 {
+	uint64_t u64;
+	struct cvmx_pko_reg_debug2_s {
+		uint64_t asserts:64;
+	} s;
+	struct cvmx_pko_reg_debug2_s cn50xx;
+	struct cvmx_pko_reg_debug2_s cn52xx;
+	struct cvmx_pko_reg_debug2_s cn52xxp1;
+	struct cvmx_pko_reg_debug2_s cn56xx;
+	struct cvmx_pko_reg_debug2_s cn56xxp1;
+	struct cvmx_pko_reg_debug2_s cn58xx;
+	struct cvmx_pko_reg_debug2_s cn58xxp1;
+};
+
+union cvmx_pko_reg_debug3 {
+	uint64_t u64;
+	struct cvmx_pko_reg_debug3_s {
+		uint64_t asserts:64;
+	} s;
+	struct cvmx_pko_reg_debug3_s cn50xx;
+	struct cvmx_pko_reg_debug3_s cn52xx;
+	struct cvmx_pko_reg_debug3_s cn52xxp1;
+	struct cvmx_pko_reg_debug3_s cn56xx;
+	struct cvmx_pko_reg_debug3_s cn56xxp1;
+	struct cvmx_pko_reg_debug3_s cn58xx;
+	struct cvmx_pko_reg_debug3_s cn58xxp1;
+};
+
+union cvmx_pko_reg_engine_inflight {
+	uint64_t u64;
+	struct cvmx_pko_reg_engine_inflight_s {
+		uint64_t reserved_40_63:24;
+		uint64_t engine9:4;
+		uint64_t engine8:4;
+		uint64_t engine7:4;
+		uint64_t engine6:4;
+		uint64_t engine5:4;
+		uint64_t engine4:4;
+		uint64_t engine3:4;
+		uint64_t engine2:4;
+		uint64_t engine1:4;
+		uint64_t engine0:4;
+	} s;
+	struct cvmx_pko_reg_engine_inflight_s cn52xx;
+	struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
+	struct cvmx_pko_reg_engine_inflight_s cn56xx;
+	struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
+};
+
+union cvmx_pko_reg_engine_thresh {
+	uint64_t u64;
+	struct cvmx_pko_reg_engine_thresh_s {
+		uint64_t reserved_10_63:54;
+		uint64_t mask:10;
+	} s;
+	struct cvmx_pko_reg_engine_thresh_s cn52xx;
+	struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
+	struct cvmx_pko_reg_engine_thresh_s cn56xx;
+	struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
+};
+
+union cvmx_pko_reg_error {
+	uint64_t u64;
+	struct cvmx_pko_reg_error_s {
+		uint64_t reserved_3_63:61;
+		uint64_t currzero:1;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+	} s;
+	struct cvmx_pko_reg_error_cn30xx {
+		uint64_t reserved_2_63:62;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+	} cn30xx;
+	struct cvmx_pko_reg_error_cn30xx cn31xx;
+	struct cvmx_pko_reg_error_cn30xx cn38xx;
+	struct cvmx_pko_reg_error_cn30xx cn38xxp2;
+	struct cvmx_pko_reg_error_s cn50xx;
+	struct cvmx_pko_reg_error_s cn52xx;
+	struct cvmx_pko_reg_error_s cn52xxp1;
+	struct cvmx_pko_reg_error_s cn56xx;
+	struct cvmx_pko_reg_error_s cn56xxp1;
+	struct cvmx_pko_reg_error_s cn58xx;
+	struct cvmx_pko_reg_error_s cn58xxp1;
+};
+
+union cvmx_pko_reg_flags {
+	uint64_t u64;
+	struct cvmx_pko_reg_flags_s {
+		uint64_t reserved_4_63:60;
+		uint64_t reset:1;
+		uint64_t store_be:1;
+		uint64_t ena_dwb:1;
+		uint64_t ena_pko:1;
+	} s;
+	struct cvmx_pko_reg_flags_s cn30xx;
+	struct cvmx_pko_reg_flags_s cn31xx;
+	struct cvmx_pko_reg_flags_s cn38xx;
+	struct cvmx_pko_reg_flags_s cn38xxp2;
+	struct cvmx_pko_reg_flags_s cn50xx;
+	struct cvmx_pko_reg_flags_s cn52xx;
+	struct cvmx_pko_reg_flags_s cn52xxp1;
+	struct cvmx_pko_reg_flags_s cn56xx;
+	struct cvmx_pko_reg_flags_s cn56xxp1;
+	struct cvmx_pko_reg_flags_s cn58xx;
+	struct cvmx_pko_reg_flags_s cn58xxp1;
+};
+
+union cvmx_pko_reg_gmx_port_mode {
+	uint64_t u64;
+	struct cvmx_pko_reg_gmx_port_mode_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mode1:3;
+		uint64_t mode0:3;
+	} s;
+	struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn38xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn38xxp2;
+	struct cvmx_pko_reg_gmx_port_mode_s cn50xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn52xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn52xxp1;
+	struct cvmx_pko_reg_gmx_port_mode_s cn56xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
+	struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
+};
+
+union cvmx_pko_reg_int_mask {
+	uint64_t u64;
+	struct cvmx_pko_reg_int_mask_s {
+		uint64_t reserved_3_63:61;
+		uint64_t currzero:1;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+	} s;
+	struct cvmx_pko_reg_int_mask_cn30xx {
+		uint64_t reserved_2_63:62;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+	} cn30xx;
+	struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
+	struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
+	struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
+	struct cvmx_pko_reg_int_mask_s cn50xx;
+	struct cvmx_pko_reg_int_mask_s cn52xx;
+	struct cvmx_pko_reg_int_mask_s cn52xxp1;
+	struct cvmx_pko_reg_int_mask_s cn56xx;
+	struct cvmx_pko_reg_int_mask_s cn56xxp1;
+	struct cvmx_pko_reg_int_mask_s cn58xx;
+	struct cvmx_pko_reg_int_mask_s cn58xxp1;
+};
+
+union cvmx_pko_reg_queue_mode {
+	uint64_t u64;
+	struct cvmx_pko_reg_queue_mode_s {
+		uint64_t reserved_2_63:62;
+		uint64_t mode:2;
+	} s;
+	struct cvmx_pko_reg_queue_mode_s cn30xx;
+	struct cvmx_pko_reg_queue_mode_s cn31xx;
+	struct cvmx_pko_reg_queue_mode_s cn38xx;
+	struct cvmx_pko_reg_queue_mode_s cn38xxp2;
+	struct cvmx_pko_reg_queue_mode_s cn50xx;
+	struct cvmx_pko_reg_queue_mode_s cn52xx;
+	struct cvmx_pko_reg_queue_mode_s cn52xxp1;
+	struct cvmx_pko_reg_queue_mode_s cn56xx;
+	struct cvmx_pko_reg_queue_mode_s cn56xxp1;
+	struct cvmx_pko_reg_queue_mode_s cn58xx;
+	struct cvmx_pko_reg_queue_mode_s cn58xxp1;
+};
+
+union cvmx_pko_reg_queue_ptrs1 {
+	uint64_t u64;
+	struct cvmx_pko_reg_queue_ptrs1_s {
+		uint64_t reserved_2_63:62;
+		uint64_t idx3:1;
+		uint64_t qid7:1;
+	} s;
+	struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn52xxp1;
+	struct cvmx_pko_reg_queue_ptrs1_s cn56xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
+	struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
+};
+
+union cvmx_pko_reg_read_idx {
+	uint64_t u64;
+	struct cvmx_pko_reg_read_idx_s {
+		uint64_t reserved_16_63:48;
+		uint64_t inc:8;
+		uint64_t index:8;
+	} s;
+	struct cvmx_pko_reg_read_idx_s cn30xx;
+	struct cvmx_pko_reg_read_idx_s cn31xx;
+	struct cvmx_pko_reg_read_idx_s cn38xx;
+	struct cvmx_pko_reg_read_idx_s cn38xxp2;
+	struct cvmx_pko_reg_read_idx_s cn50xx;
+	struct cvmx_pko_reg_read_idx_s cn52xx;
+	struct cvmx_pko_reg_read_idx_s cn52xxp1;
+	struct cvmx_pko_reg_read_idx_s cn56xx;
+	struct cvmx_pko_reg_read_idx_s cn56xxp1;
+	struct cvmx_pko_reg_read_idx_s cn58xx;
+	struct cvmx_pko_reg_read_idx_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-pko.c b/drivers/staging/octeon/cvmx-pko.c
new file mode 100644
index 0000000..00db915
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pko.c
@@ -0,0 +1,506 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Support library for the hardware Packet Output unit.
+ */
+
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+#include "cvmx-pko.h"
+#include "cvmx-helper.h"
+
+/**
+ * Internal state of packet output
+ */
+
+/**
+ * Call before any other calls to initialize the packet
+ * output system.  This does chip global config, and should only be
+ * done by one core.
+ */
+
+void cvmx_pko_initialize_global(void)
+{
+	int i;
+	uint64_t priority = 8;
+	union cvmx_pko_reg_cmd_buf config;
+
+	/*
+	 * Set the size of the PKO command buffers to an odd number of
+	 * 64bit words. This allows the normal two word send to stay
+	 * aligned and never span a comamnd word buffer.
+	 */
+	config.u64 = 0;
+	config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
+	config.s.size = CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE / 8 - 1;
+
+	cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
+
+	for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)
+		cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
+				     &priority);
+
+	/*
+	 * If we aren't using all of the queues optimize PKO's
+	 * internal memory.
+	 */
+	if (OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)
+	    || OCTEON_IS_MODEL(OCTEON_CN56XX)
+	    || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+		int num_interfaces = cvmx_helper_get_number_of_interfaces();
+		int last_port =
+		    cvmx_helper_get_last_ipd_port(num_interfaces - 1);
+		int max_queues =
+		    cvmx_pko_get_base_queue(last_port) +
+		    cvmx_pko_get_num_queues(last_port);
+		if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+			if (max_queues <= 32)
+				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
+			else if (max_queues <= 64)
+				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
+		} else {
+			if (max_queues <= 64)
+				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 2);
+			else if (max_queues <= 128)
+				cvmx_write_csr(CVMX_PKO_REG_QUEUE_MODE, 1);
+		}
+	}
+}
+
+/**
+ * This function does per-core initialization required by the PKO routines.
+ * This must be called on all cores that will do packet output, and must
+ * be called after the FPA has been initialized and filled with pages.
+ *
+ * Returns 0 on success
+ *         !0 on failure
+ */
+int cvmx_pko_initialize_local(void)
+{
+	/* Nothing to do */
+	return 0;
+}
+
+/**
+ * Enables the packet output hardware. It must already be
+ * configured.
+ */
+void cvmx_pko_enable(void)
+{
+	union cvmx_pko_reg_flags flags;
+
+	flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
+	if (flags.s.ena_pko)
+		cvmx_dprintf
+		    ("Warning: Enabling PKO when PKO already enabled.\n");
+
+	flags.s.ena_dwb = 1;
+	flags.s.ena_pko = 1;
+	/*
+	 * always enable big endian for 3-word command. Does nothing
+	 * for 2-word.
+	 */
+	flags.s.store_be = 1;
+	cvmx_write_csr(CVMX_PKO_REG_FLAGS, flags.u64);
+}
+
+/**
+ * Disables the packet output. Does not affect any configuration.
+ */
+void cvmx_pko_disable(void)
+{
+	union cvmx_pko_reg_flags pko_reg_flags;
+	pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
+	pko_reg_flags.s.ena_pko = 0;
+	cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
+}
+
+
+/**
+ * Reset the packet output.
+ */
+static void __cvmx_pko_reset(void)
+{
+	union cvmx_pko_reg_flags pko_reg_flags;
+	pko_reg_flags.u64 = cvmx_read_csr(CVMX_PKO_REG_FLAGS);
+	pko_reg_flags.s.reset = 1;
+	cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
+}
+
+/**
+ * Shutdown and free resources required by packet output.
+ */
+void cvmx_pko_shutdown(void)
+{
+	union cvmx_pko_mem_queue_ptrs config;
+	int queue;
+
+	cvmx_pko_disable();
+
+	for (queue = 0; queue < CVMX_PKO_MAX_OUTPUT_QUEUES; queue++) {
+		config.u64 = 0;
+		config.s.tail = 1;
+		config.s.index = 0;
+		config.s.port = CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID;
+		config.s.queue = queue & 0x7f;
+		config.s.qos_mask = 0;
+		config.s.buf_ptr = 0;
+		if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+			union cvmx_pko_reg_queue_ptrs1 config1;
+			config1.u64 = 0;
+			config1.s.qid7 = queue >> 7;
+			cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
+		}
+		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
+		cvmx_cmd_queue_shutdown(CVMX_CMD_QUEUE_PKO(queue));
+	}
+	__cvmx_pko_reset();
+}
+
+/**
+ * Configure a output port and the associated queues for use.
+ *
+ * @port:       Port to configure.
+ * @base_queue: First queue number to associate with this port.
+ * @num_queues: Number of queues to associate with this port
+ * @priority:   Array of priority levels for each queue. Values are
+ *                   allowed to be 0-8. A value of 8 get 8 times the traffic
+ *                   of a value of 1.  A value of 0 indicates that no rounds
+ *                   will be participated in. These priorities can be changed
+ *                   on the fly while the pko is enabled. A priority of 9
+ *                   indicates that static priority should be used.  If static
+ *                   priority is used all queues with static priority must be
+ *                   contiguous starting at the base_queue, and lower numbered
+ *                   queues have higher priority than higher numbered queues.
+ *                   There must be num_queues elements in the array.
+ */
+cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue,
+				       uint64_t num_queues,
+				       const uint64_t priority[])
+{
+	cvmx_pko_status_t result_code;
+	uint64_t queue;
+	union cvmx_pko_mem_queue_ptrs config;
+	union cvmx_pko_reg_queue_ptrs1 config1;
+	int static_priority_base = -1;
+	int static_priority_end = -1;
+
+	if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
+	    && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
+		cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
+			     (unsigned long long)port);
+		return CVMX_PKO_INVALID_PORT;
+	}
+
+	if (base_queue + num_queues > CVMX_PKO_MAX_OUTPUT_QUEUES) {
+		cvmx_dprintf
+		    ("ERROR: cvmx_pko_config_port: Invalid queue range %llu\n",
+		     (unsigned long long)(base_queue + num_queues));
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+
+	if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
+		/*
+		 * Validate the static queue priority setup and set
+		 * static_priority_base and static_priority_end
+		 * accordingly.
+		 */
+		for (queue = 0; queue < num_queues; queue++) {
+			/* Find first queue of static priority */
+			if (static_priority_base == -1
+			    && priority[queue] ==
+			    CVMX_PKO_QUEUE_STATIC_PRIORITY)
+				static_priority_base = queue;
+			/* Find last queue of static priority */
+			if (static_priority_base != -1
+			    && static_priority_end == -1
+			    && priority[queue] != CVMX_PKO_QUEUE_STATIC_PRIORITY
+			    && queue)
+				static_priority_end = queue - 1;
+			else if (static_priority_base != -1
+				 && static_priority_end == -1
+				 && queue == num_queues - 1)
+				/* all queues are static priority */
+				static_priority_end = queue;
+			/*
+			 * Check to make sure all static priority
+			 * queues are contiguous.  Also catches some
+			 * cases of static priorites not starting at
+			 * queue 0.
+			 */
+			if (static_priority_end != -1
+			    && (int)queue > static_priority_end
+			    && priority[queue] ==
+			    CVMX_PKO_QUEUE_STATIC_PRIORITY) {
+				cvmx_dprintf("ERROR: cvmx_pko_config_port: "
+					     "Static priority queues aren't "
+					     "contiguous or don't start at "
+					     "base queue. q: %d, eq: %d\n",
+					(int)queue, static_priority_end);
+				return CVMX_PKO_INVALID_PRIORITY;
+			}
+		}
+		if (static_priority_base > 0) {
+			cvmx_dprintf("ERROR: cvmx_pko_config_port: Static "
+				     "priority queues don't start at base "
+				     "queue. sq: %d\n",
+				static_priority_base);
+			return CVMX_PKO_INVALID_PRIORITY;
+		}
+#if 0
+		cvmx_dprintf("Port %d: Static priority queue base: %d, "
+			     "end: %d\n", port,
+			static_priority_base, static_priority_end);
+#endif
+	}
+	/*
+	 * At this point, static_priority_base and static_priority_end
+	 * are either both -1, or are valid start/end queue
+	 * numbers.
+	 */
+
+	result_code = CVMX_PKO_SUCCESS;
+
+#ifdef PKO_DEBUG
+	cvmx_dprintf("num queues: %d (%lld,%lld)\n", num_queues,
+		     CVMX_PKO_QUEUES_PER_PORT_INTERFACE0,
+		     CVMX_PKO_QUEUES_PER_PORT_INTERFACE1);
+#endif
+
+	for (queue = 0; queue < num_queues; queue++) {
+		uint64_t *buf_ptr = NULL;
+
+		config1.u64 = 0;
+		config1.s.idx3 = queue >> 3;
+		config1.s.qid7 = (base_queue + queue) >> 7;
+
+		config.u64 = 0;
+		config.s.tail = queue == (num_queues - 1);
+		config.s.index = queue;
+		config.s.port = port;
+		config.s.queue = base_queue + queue;
+
+		if (!cvmx_octeon_is_pass1()) {
+			config.s.static_p = static_priority_base >= 0;
+			config.s.static_q = (int)queue <= static_priority_end;
+			config.s.s_tail = (int)queue == static_priority_end;
+		}
+		/*
+		 * Convert the priority into an enable bit field. Try
+		 * to space the bits out evenly so the packet don't
+		 * get grouped up
+		 */
+		switch ((int)priority[queue]) {
+		case 0:
+			config.s.qos_mask = 0x00;
+			break;
+		case 1:
+			config.s.qos_mask = 0x01;
+			break;
+		case 2:
+			config.s.qos_mask = 0x11;
+			break;
+		case 3:
+			config.s.qos_mask = 0x49;
+			break;
+		case 4:
+			config.s.qos_mask = 0x55;
+			break;
+		case 5:
+			config.s.qos_mask = 0x57;
+			break;
+		case 6:
+			config.s.qos_mask = 0x77;
+			break;
+		case 7:
+			config.s.qos_mask = 0x7f;
+			break;
+		case 8:
+			config.s.qos_mask = 0xff;
+			break;
+		case CVMX_PKO_QUEUE_STATIC_PRIORITY:
+			/* Pass 1 will fall through to the error case */
+			if (!cvmx_octeon_is_pass1()) {
+				config.s.qos_mask = 0xff;
+				break;
+			}
+		default:
+			cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid "
+				     "priority %llu\n",
+				(unsigned long long)priority[queue]);
+			config.s.qos_mask = 0xff;
+			result_code = CVMX_PKO_INVALID_PRIORITY;
+			break;
+		}
+
+		if (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID) {
+			cvmx_cmd_queue_result_t cmd_res =
+			    cvmx_cmd_queue_initialize(CVMX_CMD_QUEUE_PKO
+						      (base_queue + queue),
+						      CVMX_PKO_MAX_QUEUE_DEPTH,
+						      CVMX_FPA_OUTPUT_BUFFER_POOL,
+						      CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
+						      -
+						      CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST
+						      * 8);
+			if (cmd_res != CVMX_CMD_QUEUE_SUCCESS) {
+				switch (cmd_res) {
+				case CVMX_CMD_QUEUE_NO_MEMORY:
+					cvmx_dprintf("ERROR: "
+						     "cvmx_pko_config_port: "
+						     "Unable to allocate "
+						     "output buffer.\n");
+					return CVMX_PKO_NO_MEMORY;
+				case CVMX_CMD_QUEUE_ALREADY_SETUP:
+					cvmx_dprintf
+					    ("ERROR: cvmx_pko_config_port: Port already setup.\n");
+					return CVMX_PKO_PORT_ALREADY_SETUP;
+				case CVMX_CMD_QUEUE_INVALID_PARAM:
+				default:
+					cvmx_dprintf
+					    ("ERROR: cvmx_pko_config_port: Command queue initialization failed.\n");
+					return CVMX_PKO_CMD_QUEUE_INIT_ERROR;
+				}
+			}
+
+			buf_ptr =
+			    (uint64_t *)
+			    cvmx_cmd_queue_buffer(CVMX_CMD_QUEUE_PKO
+						  (base_queue + queue));
+			config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr);
+		} else
+			config.s.buf_ptr = 0;
+
+		CVMX_SYNCWS;
+
+		if (!OCTEON_IS_MODEL(OCTEON_CN3XXX))
+			cvmx_write_csr(CVMX_PKO_REG_QUEUE_PTRS1, config1.u64);
+		cvmx_write_csr(CVMX_PKO_MEM_QUEUE_PTRS, config.u64);
+	}
+
+	return result_code;
+}
+
+#ifdef PKO_DEBUG
+/**
+ * Show map of ports -> queues for different cores.
+ */
+void cvmx_pko_show_queue_map()
+{
+	int core, port;
+	int pko_output_ports = 36;
+
+	cvmx_dprintf("port");
+	for (port = 0; port < pko_output_ports; port++)
+		cvmx_dprintf("%3d ", port);
+	cvmx_dprintf("\n");
+
+	for (core = 0; core < CVMX_MAX_CORES; core++) {
+		cvmx_dprintf("\n%2d: ", core);
+		for (port = 0; port < pko_output_ports; port++) {
+			cvmx_dprintf("%3d ",
+				     cvmx_pko_get_base_queue_per_core(port,
+								      core));
+		}
+	}
+	cvmx_dprintf("\n");
+}
+#endif
+
+/**
+ * Rate limit a PKO port to a max packets/sec. This function is only
+ * supported on CN51XX and higher, excluding CN58XX.
+ *
+ * @port:      Port to rate limit
+ * @packets_s: Maximum packet/sec
+ * @burst:     Maximum number of packets to burst in a row before rate
+ *                  limiting cuts in.
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst)
+{
+	union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
+	union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
+
+	pko_mem_port_rate0.u64 = 0;
+	pko_mem_port_rate0.s.pid = port;
+	pko_mem_port_rate0.s.rate_pkt =
+	    cvmx_sysinfo_get()->cpu_clock_hz / packets_s / 16;
+	/* No cost per word since we are limited by packets/sec, not bits/sec */
+	pko_mem_port_rate0.s.rate_word = 0;
+
+	pko_mem_port_rate1.u64 = 0;
+	pko_mem_port_rate1.s.pid = port;
+	pko_mem_port_rate1.s.rate_lim =
+	    ((uint64_t) pko_mem_port_rate0.s.rate_pkt * burst) >> 8;
+
+	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
+	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
+	return 0;
+}
+
+/**
+ * Rate limit a PKO port to a max bits/sec. This function is only
+ * supported on CN51XX and higher, excluding CN58XX.
+ *
+ * @port:   Port to rate limit
+ * @bits_s: PKO rate limit in bits/sec
+ * @burst:  Maximum number of bits to burst before rate
+ *               limiting cuts in.
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst)
+{
+	union cvmx_pko_mem_port_rate0 pko_mem_port_rate0;
+	union cvmx_pko_mem_port_rate1 pko_mem_port_rate1;
+	uint64_t clock_rate = cvmx_sysinfo_get()->cpu_clock_hz;
+	uint64_t tokens_per_bit = clock_rate * 16 / bits_s;
+
+	pko_mem_port_rate0.u64 = 0;
+	pko_mem_port_rate0.s.pid = port;
+	/*
+	 * Each packet has a 12 bytes of interframe gap, an 8 byte
+	 * preamble, and a 4 byte CRC. These are not included in the
+	 * per word count. Multiply by 8 to covert to bits and divide
+	 * by 256 for limit granularity.
+	 */
+	pko_mem_port_rate0.s.rate_pkt = (12 + 8 + 4) * 8 * tokens_per_bit / 256;
+	/* Each 8 byte word has 64bits */
+	pko_mem_port_rate0.s.rate_word = 64 * tokens_per_bit;
+
+	pko_mem_port_rate1.u64 = 0;
+	pko_mem_port_rate1.s.pid = port;
+	pko_mem_port_rate1.s.rate_lim = tokens_per_bit * burst / 256;
+
+	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE0, pko_mem_port_rate0.u64);
+	cvmx_write_csr(CVMX_PKO_MEM_PORT_RATE1, pko_mem_port_rate1.u64);
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-pko.h b/drivers/staging/octeon/cvmx-pko.h
new file mode 100644
index 0000000..f068c19
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pko.h
@@ -0,0 +1,610 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * Interface to the hardware Packet Output unit.
+ *
+ * Starting with SDK 1.7.0, the PKO output functions now support
+ * two types of locking. CVMX_PKO_LOCK_ATOMIC_TAG continues to
+ * function similarly to previous SDKs by using POW atomic tags
+ * to preserve ordering and exclusivity. As a new option, you
+ * can now pass CVMX_PKO_LOCK_CMD_QUEUE which uses a ll/sc
+ * memory based locking instead. This locking has the advantage
+ * of not affecting the tag state but doesn't preserve packet
+ * ordering. CVMX_PKO_LOCK_CMD_QUEUE is appropriate in most
+ * generic code while CVMX_PKO_LOCK_CMD_QUEUE should be used
+ * with hand tuned fast path code.
+ *
+ * Some of other SDK differences visible to the command command
+ * queuing:
+ * - PKO indexes are no longer stored in the FAU. A large
+ *   percentage of the FAU register block used to be tied up
+ *   maintaining PKO queue pointers. These are now stored in a
+ *   global named block.
+ * - The PKO <b>use_locking</b> parameter can now have a global
+ *   effect. Since all application use the same named block,
+ *   queue locking correctly applies across all operating
+ *   systems when using CVMX_PKO_LOCK_CMD_QUEUE.
+ * - PKO 3 word commands are now supported. Use
+ *   cvmx_pko_send_packet_finish3().
+ *
+ */
+
+#ifndef __CVMX_PKO_H__
+#define __CVMX_PKO_H__
+
+#include "cvmx-fpa.h"
+#include "cvmx-pow.h"
+#include "cvmx-cmd-queue.h"
+#include "cvmx-pko-defs.h"
+
+/* Adjust the command buffer size by 1 word so that in the case of using only
+ * two word PKO commands no command words stradle buffers.  The useful values
+ * for this are 0 and 1. */
+#define CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST (1)
+
+#define CVMX_PKO_MAX_OUTPUT_QUEUES_STATIC 256
+#define CVMX_PKO_MAX_OUTPUT_QUEUES      ((OCTEON_IS_MODEL(OCTEON_CN31XX) || \
+	OCTEON_IS_MODEL(OCTEON_CN3010) || OCTEON_IS_MODEL(OCTEON_CN3005) || \
+	OCTEON_IS_MODEL(OCTEON_CN50XX)) ? 32 : \
+		(OCTEON_IS_MODEL(OCTEON_CN58XX) || \
+		OCTEON_IS_MODEL(OCTEON_CN56XX)) ? 256 : 128)
+#define CVMX_PKO_NUM_OUTPUT_PORTS       40
+/* use this for queues that are not used */
+#define CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID 63
+#define CVMX_PKO_QUEUE_STATIC_PRIORITY  9
+#define CVMX_PKO_ILLEGAL_QUEUE  0xFFFF
+#define CVMX_PKO_MAX_QUEUE_DEPTH 0
+
+typedef enum {
+	CVMX_PKO_SUCCESS,
+	CVMX_PKO_INVALID_PORT,
+	CVMX_PKO_INVALID_QUEUE,
+	CVMX_PKO_INVALID_PRIORITY,
+	CVMX_PKO_NO_MEMORY,
+	CVMX_PKO_PORT_ALREADY_SETUP,
+	CVMX_PKO_CMD_QUEUE_INIT_ERROR
+} cvmx_pko_status_t;
+
+/**
+ * This enumeration represents the differnet locking modes supported by PKO.
+ */
+typedef enum {
+	/*
+	 * PKO doesn't do any locking. It is the responsibility of the
+	 * application to make sure that no other core is accessing
+	 * the same queue at the smae time
+	 */
+	CVMX_PKO_LOCK_NONE = 0,
+	/*
+	 * PKO performs an atomic tagswitch to insure exclusive access
+	 * to the output queue. This will maintain packet ordering on
+	 * output.
+	 */
+	CVMX_PKO_LOCK_ATOMIC_TAG = 1,
+	/*
+	 * PKO uses the common command queue locks to insure exclusive
+	 * access to the output queue. This is a memory based
+	 * ll/sc. This is the most portable locking mechanism.
+	 */
+	CVMX_PKO_LOCK_CMD_QUEUE = 2,
+} cvmx_pko_lock_t;
+
+typedef struct {
+	uint32_t packets;
+	uint64_t octets;
+	uint64_t doorbell;
+} cvmx_pko_port_status_t;
+
+/**
+ * This structure defines the address to use on a packet enqueue
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		/* Must CVMX_IO_SEG */
+		uint64_t mem_space:2;
+		/* Must be zero */
+		uint64_t reserved:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* The ID of the device on the non-coherent bus */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved2:4;
+		/* Must be zero */
+		uint64_t reserved3:18;
+		/*
+		 * The hardware likes to have the output port in
+		 * addition to the output queue,
+		 */
+		uint64_t port:6;
+		/*
+		 * The output queue to send the packet to (0-127 are
+		 * legal)
+		 */
+		uint64_t queue:9;
+		/* Must be zero */
+		uint64_t reserved4:3;
+	} s;
+} cvmx_pko_doorbell_address_t;
+
+/**
+ * Structure of the first packet output command word.
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		/*
+		 * The size of the reg1 operation - could be 8, 16,
+		 * 32, or 64 bits.
+		 */
+		uint64_t size1:2;
+		/*
+		 * The size of the reg0 operation - could be 8, 16,
+		 * 32, or 64 bits.
+		 */
+		uint64_t size0:2;
+		/*
+		 * If set, subtract 1, if clear, subtract packet
+		 * size.
+		 */
+		uint64_t subone1:1;
+		/*
+		 * The register, subtract will be done if reg1 is
+		 * non-zero.
+		 */
+		uint64_t reg1:11;
+		/* If set, subtract 1, if clear, subtract packet size */
+		uint64_t subone0:1;
+		/* The register, subtract will be done if reg0 is non-zero */
+		uint64_t reg0:11;
+		/*
+		 * When set, interpret segment pointer and segment
+		 * bytes in little endian order.
+		 */
+		uint64_t le:1;
+		/*
+		 * When set, packet data not allocated in L2 cache by
+		 * PKO.
+		 */
+		uint64_t n2:1;
+		/*
+		 * If set and rsp is set, word3 contains a pointer to
+		 * a work queue entry.
+		 */
+		uint64_t wqp:1;
+		/* If set, the hardware will send a response when done */
+		uint64_t rsp:1;
+		/*
+		 * If set, the supplied pkt_ptr is really a pointer to
+		 * a list of pkt_ptr's.
+		 */
+		uint64_t gather:1;
+		/*
+		 * If ipoffp1 is non zero, (ipoffp1-1) is the number
+		 * of bytes to IP header, and the hardware will
+		 * calculate and insert the UDP/TCP checksum.
+		 */
+		uint64_t ipoffp1:7;
+		/*
+		 * If set, ignore the I bit (force to zero) from all
+		 * pointer structures.
+		 */
+		uint64_t ignore_i:1;
+		/*
+		 * If clear, the hardware will attempt to free the
+		 * buffers containing the packet.
+		 */
+		uint64_t dontfree:1;
+		/*
+		 * The total number of segs in the packet, if gather
+		 * set, also gather list length.
+		 */
+		uint64_t segs:6;
+		/* Including L2, but no trailing CRC */
+		uint64_t total_bytes:16;
+	} s;
+} cvmx_pko_command_word0_t;
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+
+/**
+ * Definition of internal state for Packet output processing
+ */
+typedef struct {
+	/* ptr to start of buffer, offset kept in FAU reg */
+	uint64_t *start_ptr;
+} cvmx_pko_state_elem_t;
+
+/**
+ * Call before any other calls to initialize the packet
+ * output system.
+ */
+extern void cvmx_pko_initialize_global(void);
+extern int cvmx_pko_initialize_local(void);
+
+/**
+ * Enables the packet output hardware. It must already be
+ * configured.
+ */
+extern void cvmx_pko_enable(void);
+
+/**
+ * Disables the packet output. Does not affect any configuration.
+ */
+extern void cvmx_pko_disable(void);
+
+/**
+ * Shutdown and free resources required by packet output.
+ */
+
+extern void cvmx_pko_shutdown(void);
+
+/**
+ * Configure a output port and the associated queues for use.
+ *
+ * @port:       Port to configure.
+ * @base_queue: First queue number to associate with this port.
+ * @num_queues: Number of queues t oassociate with this port
+ * @priority:   Array of priority levels for each queue. Values are
+ *                   allowed to be 1-8. A value of 8 get 8 times the traffic
+ *                   of a value of 1. There must be num_queues elements in the
+ *                   array.
+ */
+extern cvmx_pko_status_t cvmx_pko_config_port(uint64_t port,
+					      uint64_t base_queue,
+					      uint64_t num_queues,
+					      const uint64_t priority[]);
+
+/**
+ * Ring the packet output doorbell. This tells the packet
+ * output hardware that "len" command words have been added
+ * to its pending list.  This command includes the required
+ * CVMX_SYNCWS before the doorbell ring.
+ *
+ * @port:   Port the packet is for
+ * @queue:  Queue the packet is for
+ * @len:    Length of the command in 64 bit words
+ */
+static inline void cvmx_pko_doorbell(uint64_t port, uint64_t queue,
+				     uint64_t len)
+{
+	cvmx_pko_doorbell_address_t ptr;
+
+	ptr.u64 = 0;
+	ptr.s.mem_space = CVMX_IO_SEG;
+	ptr.s.did = CVMX_OCT_DID_PKT_SEND;
+	ptr.s.is_io = 1;
+	ptr.s.port = port;
+	ptr.s.queue = queue;
+	/*
+	 * Need to make sure output queue data is in DRAM before
+	 * doorbell write.
+	 */
+	CVMX_SYNCWS;
+	cvmx_write_io(ptr.u64, len);
+}
+
+/**
+ * Prepare to send a packet.  This may initiate a tag switch to
+ * get exclusive access to the output queue structure, and
+ * performs other prep work for the packet send operation.
+ *
+ * cvmx_pko_send_packet_finish() MUST be called after this function is called,
+ * and must be called with the same port/queue/use_locking arguments.
+ *
+ * The use_locking parameter allows the caller to use three
+ * possible locking modes.
+ * - CVMX_PKO_LOCK_NONE
+ *      - PKO doesn't do any locking. It is the responsibility
+ *          of the application to make sure that no other core
+ *          is accessing the same queue at the smae time.
+ * - CVMX_PKO_LOCK_ATOMIC_TAG
+ *      - PKO performs an atomic tagswitch to insure exclusive
+ *          access to the output queue. This will maintain
+ *          packet ordering on output.
+ * - CVMX_PKO_LOCK_CMD_QUEUE
+ *      - PKO uses the common command queue locks to insure
+ *          exclusive access to the output queue. This is a
+ *          memory based ll/sc. This is the most portable
+ *          locking mechanism.
+ *
+ * NOTE: If atomic locking is used, the POW entry CANNOT be
+ * descheduled, as it does not contain a valid WQE pointer.
+ *
+ * @port:   Port to send it on
+ * @queue:  Queue to use
+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
+ *               CVMX_PKO_LOCK_CMD_QUEUE
+ */
+
+static inline void cvmx_pko_send_packet_prepare(uint64_t port, uint64_t queue,
+						cvmx_pko_lock_t use_locking)
+{
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG) {
+		/*
+		 * Must do a full switch here to handle all cases.  We
+		 * use a fake WQE pointer, as the POW does not access
+		 * this memory.  The WQE pointer and group are only
+		 * used if this work is descheduled, which is not
+		 * supported by the
+		 * cvmx_pko_send_packet_prepare/cvmx_pko_send_packet_finish
+		 * combination.  Note that this is a special case in
+		 * which these fake values can be used - this is not a
+		 * general technique.
+		 */
+		uint32_t tag =
+		    CVMX_TAG_SW_BITS_INTERNAL << CVMX_TAG_SW_SHIFT |
+		    CVMX_TAG_SUBGROUP_PKO << CVMX_TAG_SUBGROUP_SHIFT |
+		    (CVMX_TAG_SUBGROUP_MASK & queue);
+		cvmx_pow_tag_sw_full((cvmx_wqe_t *) cvmx_phys_to_ptr(0x80), tag,
+				     CVMX_POW_TAG_TYPE_ATOMIC, 0);
+	}
+}
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be
+ * called exactly once before this, and the same parameters must be
+ * passed to both cvmx_pko_send_packet_prepare() and
+ * cvmx_pko_send_packet_finish().
+ *
+ * @port:   Port to send it on
+ * @queue:  Queue to use
+ * @pko_command:
+ *               PKO HW command word
+ * @packet: Packet to send
+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
+ *               CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on
+ * failure of output
+ */
+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish(
+	uint64_t port,
+	uint64_t queue,
+	cvmx_pko_command_word0_t pko_command,
+	union cvmx_buf_ptr packet,
+	cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+	result = cvmx_cmd_queue_write2(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64);
+	if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell(port, queue, 2);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
+		   || (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+/**
+ * Complete packet output. cvmx_pko_send_packet_prepare() must be
+ * called exactly once before this, and the same parameters must be
+ * passed to both cvmx_pko_send_packet_prepare() and
+ * cvmx_pko_send_packet_finish().
+ *
+ * @port:   Port to send it on
+ * @queue:  Queue to use
+ * @pko_command:
+ *               PKO HW command word
+ * @packet: Packet to send
+ * @addr: Plysical address of a work queue entry or physical address
+ *        to zero on complete.
+ * @use_locking: CVMX_PKO_LOCK_NONE, CVMX_PKO_LOCK_ATOMIC_TAG, or
+ *               CVMX_PKO_LOCK_CMD_QUEUE
+ *
+ * Returns returns CVMX_PKO_SUCCESS on success, or error code on
+ * failure of output
+ */
+static inline cvmx_pko_status_t cvmx_pko_send_packet_finish3(
+	uint64_t port,
+	uint64_t queue,
+	cvmx_pko_command_word0_t pko_command,
+	union cvmx_buf_ptr packet,
+	uint64_t addr,
+	cvmx_pko_lock_t use_locking)
+{
+	cvmx_cmd_queue_result_t result;
+	if (use_locking == CVMX_PKO_LOCK_ATOMIC_TAG)
+		cvmx_pow_tag_sw_wait();
+	result = cvmx_cmd_queue_write3(CVMX_CMD_QUEUE_PKO(queue),
+				       (use_locking == CVMX_PKO_LOCK_CMD_QUEUE),
+				       pko_command.u64, packet.u64, addr);
+	if (likely(result == CVMX_CMD_QUEUE_SUCCESS)) {
+		cvmx_pko_doorbell(port, queue, 3);
+		return CVMX_PKO_SUCCESS;
+	} else if ((result == CVMX_CMD_QUEUE_NO_MEMORY)
+		   || (result == CVMX_CMD_QUEUE_FULL)) {
+		return CVMX_PKO_NO_MEMORY;
+	} else {
+		return CVMX_PKO_INVALID_QUEUE;
+	}
+}
+
+/**
+ * Return the pko output queue associated with a port and a specific core.
+ * In normal mode (PKO lockless operation is disabled), the value returned
+ * is the base queue.
+ *
+ * @port:   Port number
+ * @core:   Core to get queue for
+ *
+ * Returns Core-specific output queue
+ */
+static inline int cvmx_pko_get_base_queue_per_core(int port, int core)
+{
+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0
+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE0 16
+#endif
+#ifndef CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1
+#define CVMX_HELPER_PKO_MAX_PORTS_INTERFACE1 16
+#endif
+
+	if (port < CVMX_PKO_MAX_PORTS_INTERFACE0)
+		return port * CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + core;
+	else if (port >= 16 && port < 16 + CVMX_PKO_MAX_PORTS_INTERFACE1)
+		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 + (port -
+							   16) *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + core;
+	else if ((port >= 32) && (port < 36))
+		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
+		    CVMX_PKO_MAX_PORTS_INTERFACE1 *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 + (port -
+							   32) *
+		    CVMX_PKO_QUEUES_PER_PORT_PCI;
+	else if ((port >= 36) && (port < 40))
+		return CVMX_PKO_MAX_PORTS_INTERFACE0 *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 +
+		    CVMX_PKO_MAX_PORTS_INTERFACE1 *
+		    CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 +
+		    4 * CVMX_PKO_QUEUES_PER_PORT_PCI + (port -
+							36) *
+		    CVMX_PKO_QUEUES_PER_PORT_LOOP;
+	else
+		/* Given the limit on the number of ports we can map to
+		 * CVMX_MAX_OUTPUT_QUEUES_STATIC queues (currently 256,
+		 * divided among all cores), the remaining unmapped ports
+		 * are assigned an illegal queue number */
+		return CVMX_PKO_ILLEGAL_QUEUE;
+}
+
+/**
+ * For a given port number, return the base pko output queue
+ * for the port.
+ *
+ * @port:   Port number
+ * Returns Base output queue
+ */
+static inline int cvmx_pko_get_base_queue(int port)
+{
+	return cvmx_pko_get_base_queue_per_core(port, 0);
+}
+
+/**
+ * For a given port number, return the number of pko output queues.
+ *
+ * @port:   Port number
+ * Returns Number of output queues
+ */
+static inline int cvmx_pko_get_num_queues(int port)
+{
+	if (port < 16)
+		return CVMX_PKO_QUEUES_PER_PORT_INTERFACE0;
+	else if (port < 32)
+		return CVMX_PKO_QUEUES_PER_PORT_INTERFACE1;
+	else if (port < 36)
+		return CVMX_PKO_QUEUES_PER_PORT_PCI;
+	else if (port < 40)
+		return CVMX_PKO_QUEUES_PER_PORT_LOOP;
+	else
+		return 0;
+}
+
+/**
+ * Get the status counters for a port.
+ *
+ * @port_num: Port number to get statistics for.
+ * @clear:    Set to 1 to clear the counters after they are read
+ * @status:   Where to put the results.
+ */
+static inline void cvmx_pko_get_port_status(uint64_t port_num, uint64_t clear,
+					    cvmx_pko_port_status_t *status)
+{
+	union cvmx_pko_reg_read_idx pko_reg_read_idx;
+	union cvmx_pko_mem_count0 pko_mem_count0;
+	union cvmx_pko_mem_count1 pko_mem_count1;
+
+	pko_reg_read_idx.u64 = 0;
+	pko_reg_read_idx.s.index = port_num;
+	cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
+
+	pko_mem_count0.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT0);
+	status->packets = pko_mem_count0.s.count;
+	if (clear) {
+		pko_mem_count0.s.count = port_num;
+		cvmx_write_csr(CVMX_PKO_MEM_COUNT0, pko_mem_count0.u64);
+	}
+
+	pko_mem_count1.u64 = cvmx_read_csr(CVMX_PKO_MEM_COUNT1);
+	status->octets = pko_mem_count1.s.count;
+	if (clear) {
+		pko_mem_count1.s.count = port_num;
+		cvmx_write_csr(CVMX_PKO_MEM_COUNT1, pko_mem_count1.u64);
+	}
+
+	if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+		union cvmx_pko_mem_debug9 debug9;
+		pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
+		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
+		debug9.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG9);
+		status->doorbell = debug9.cn38xx.doorbell;
+	} else {
+		union cvmx_pko_mem_debug8 debug8;
+		pko_reg_read_idx.s.index = cvmx_pko_get_base_queue(port_num);
+		cvmx_write_csr(CVMX_PKO_REG_READ_IDX, pko_reg_read_idx.u64);
+		debug8.u64 = cvmx_read_csr(CVMX_PKO_MEM_DEBUG8);
+		status->doorbell = debug8.cn58xx.doorbell;
+	}
+}
+
+/**
+ * Rate limit a PKO port to a max packets/sec. This function is only
+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
+ *
+ * @port:      Port to rate limit
+ * @packets_s: Maximum packet/sec
+ * @burst:     Maximum number of packets to burst in a row before rate
+ *                  limiting cuts in.
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int cvmx_pko_rate_limit_packets(int port, int packets_s, int burst);
+
+/**
+ * Rate limit a PKO port to a max bits/sec. This function is only
+ * supported on CN57XX, CN56XX, CN55XX, and CN54XX.
+ *
+ * @port:   Port to rate limit
+ * @bits_s: PKO rate limit in bits/sec
+ * @burst:  Maximum number of bits to burst before rate
+ *               limiting cuts in.
+ *
+ * Returns Zero on success, negative on failure
+ */
+extern int cvmx_pko_rate_limit_bits(int port, uint64_t bits_s, int burst);
+
+#endif /* __CVMX_PKO_H__ */
diff --git a/drivers/staging/octeon/cvmx-pow.h b/drivers/staging/octeon/cvmx-pow.h
new file mode 100644
index 0000000..c5d66f2
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-pow.h
@@ -0,0 +1,1982 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * Interface to the hardware Packet Order / Work unit.
+ *
+ * New, starting with SDK 1.7.0, cvmx-pow supports a number of
+ * extended consistency checks. The define
+ * CVMX_ENABLE_POW_CHECKS controls the runtime insertion of POW
+ * internal state checks to find common programming errors. If
+ * CVMX_ENABLE_POW_CHECKS is not defined, checks are by default
+ * enabled. For example, cvmx-pow will check for the following
+ * program errors or POW state inconsistency.
+ * - Requesting a POW operation with an active tag switch in
+ *   progress.
+ * - Waiting for a tag switch to complete for an excessively
+ *   long period. This is normally a sign of an error in locking
+ *   causing deadlock.
+ * - Illegal tag switches from NULL_NULL.
+ * - Illegal tag switches from NULL.
+ * - Illegal deschedule request.
+ * - WQE pointer not matching the one attached to the core by
+ *   the POW.
+ *
+ */
+
+#ifndef __CVMX_POW_H__
+#define __CVMX_POW_H__
+
+#include <asm/octeon/cvmx-pow-defs.h>
+
+#include "cvmx-scratch.h"
+#include "cvmx-wqe.h"
+
+/* Default to having all POW constancy checks turned on */
+#ifndef CVMX_ENABLE_POW_CHECKS
+#define CVMX_ENABLE_POW_CHECKS 1
+#endif
+
+enum cvmx_pow_tag_type {
+	/* Tag ordering is maintained */
+	CVMX_POW_TAG_TYPE_ORDERED   = 0L,
+	/* Tag ordering is maintained, and at most one PP has the tag */
+	CVMX_POW_TAG_TYPE_ATOMIC    = 1L,
+	/*
+	 * The work queue entry from the order - NEVER tag switch from
+	 * NULL to NULL
+	 */
+	CVMX_POW_TAG_TYPE_NULL      = 2L,
+	/* A tag switch to NULL, and there is no space reserved in POW
+	 * - NEVER tag switch to NULL_NULL
+	 * - NEVER tag switch from NULL_NULL
+	 * - NULL_NULL is entered at the beginning of time and on a deschedule.
+	 * - NULL_NULL can be exited by a new work request. A NULL_SWITCH
+	 * load can also switch the state to NULL
+	 */
+	CVMX_POW_TAG_TYPE_NULL_NULL = 3L
+};
+
+/**
+ * Wait flag values for pow functions.
+ */
+typedef enum {
+	CVMX_POW_WAIT = 1,
+	CVMX_POW_NO_WAIT = 0,
+} cvmx_pow_wait_t;
+
+/**
+ *  POW tag operations.  These are used in the data stored to the POW.
+ */
+typedef enum {
+	/*
+	 * switch the tag (only) for this PP
+	 * - the previous tag should be non-NULL in this case
+	 * - tag switch response required
+	 * - fields used: op, type, tag
+	 */
+	CVMX_POW_TAG_OP_SWTAG = 0L,
+	/*
+	 * switch the tag for this PP, with full information
+	 * - this should be used when the previous tag is NULL
+	 * - tag switch response required
+	 * - fields used: address, op, grp, type, tag
+	 */
+	CVMX_POW_TAG_OP_SWTAG_FULL = 1L,
+	/*
+	 * switch the tag (and/or group) for this PP and de-schedule
+	 * - OK to keep the tag the same and only change the group
+	 * - fields used: op, no_sched, grp, type, tag
+	 */
+	CVMX_POW_TAG_OP_SWTAG_DESCH = 2L,
+	/*
+	 * just de-schedule
+	 * - fields used: op, no_sched
+	 */
+	CVMX_POW_TAG_OP_DESCH = 3L,
+	/*
+	 * create an entirely new work queue entry
+	 * - fields used: address, op, qos, grp, type, tag
+	 */
+	CVMX_POW_TAG_OP_ADDWQ = 4L,
+	/*
+	 * just update the work queue pointer and grp for this PP
+	 * - fields used: address, op, grp
+	 */
+	CVMX_POW_TAG_OP_UPDATE_WQP_GRP = 5L,
+	/*
+	 * set the no_sched bit on the de-schedule list
+	 *
+	 * - does nothing if the selected entry is not on the
+	 *   de-schedule list
+	 *
+	 * - does nothing if the stored work queue pointer does not
+	 *   match the address field
+	 *
+	 * - fields used: address, index, op
+	 *
+	 *  Before issuing a *_NSCHED operation, SW must guarantee
+	 *  that all prior deschedules and set/clr NSCHED operations
+	 *  are complete and all prior switches are complete. The
+	 *  hardware provides the opsdone bit and swdone bit for SW
+	 *  polling. After issuing a *_NSCHED operation, SW must
+	 *  guarantee that the set/clr NSCHED is complete before any
+	 *  subsequent operations.
+	 */
+	CVMX_POW_TAG_OP_SET_NSCHED = 6L,
+	/*
+	 * clears the no_sched bit on the de-schedule list
+	 *
+	 * - does nothing if the selected entry is not on the
+	 *   de-schedule list
+	 *
+	 * - does nothing if the stored work queue pointer does not
+	 *   match the address field
+	 *
+	 * - fields used: address, index, op
+	 *
+	 * Before issuing a *_NSCHED operation, SW must guarantee that
+	 * all prior deschedules and set/clr NSCHED operations are
+	 * complete and all prior switches are complete. The hardware
+	 * provides the opsdone bit and swdone bit for SW
+	 * polling. After issuing a *_NSCHED operation, SW must
+	 * guarantee that the set/clr NSCHED is complete before any
+	 * subsequent operations.
+	 */
+	CVMX_POW_TAG_OP_CLR_NSCHED = 7L,
+	/* do nothing */
+	CVMX_POW_TAG_OP_NOP = 15L
+} cvmx_pow_tag_op_t;
+
+/**
+ * This structure defines the store data on a store to POW
+ */
+typedef union {
+	uint64_t u64;
+	struct {
+		/*
+		 * Don't reschedule this entry. no_sched is used for
+		 * CVMX_POW_TAG_OP_SWTAG_DESCH and
+		 * CVMX_POW_TAG_OP_DESCH
+		 */
+		uint64_t no_sched:1;
+		uint64_t unused:2;
+		/* Tontains index of entry for a CVMX_POW_TAG_OP_*_NSCHED */
+		uint64_t index:13;
+		/* The operation to perform */
+		cvmx_pow_tag_op_t op:4;
+		uint64_t unused2:2;
+		/*
+		 * The QOS level for the packet. qos is only used for
+		 * CVMX_POW_TAG_OP_ADDWQ
+		 */
+		uint64_t qos:3;
+		/*
+		 * The group that the work queue entry will be
+		 * scheduled to grp is used for CVMX_POW_TAG_OP_ADDWQ,
+		 * CVMX_POW_TAG_OP_SWTAG_FULL,
+		 * CVMX_POW_TAG_OP_SWTAG_DESCH, and
+		 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP
+		 */
+		uint64_t grp:4;
+		/*
+		 * The type of the tag. type is used for everything
+		 * except CVMX_POW_TAG_OP_DESCH,
+		 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
+		 * CVMX_POW_TAG_OP_*_NSCHED
+		 */
+		uint64_t type:3;
+		/*
+		 * The actual tag. tag is used for everything except
+		 * CVMX_POW_TAG_OP_DESCH,
+		 * CVMX_POW_TAG_OP_UPDATE_WQP_GRP, and
+		 * CVMX_POW_TAG_OP_*_NSCHED
+		 */
+		uint64_t tag:32;
+	} s;
+} cvmx_pow_tag_req_t;
+
+/**
+ * This structure describes the address to load stuff from POW
+ */
+typedef union {
+	uint64_t u64;
+
+    /**
+     * Address for new work request loads (did<2:0> == 0)
+     */
+	struct {
+		/* Mips64 address region. Should be CVMX_IO_SEG */
+		uint64_t mem_region:2;
+		/* Must be zero */
+		uint64_t reserved_49_61:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* the ID of POW -- did<2:0> == 0 in this case */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved_4_39:36;
+		/*
+		 * If set, don't return load response until work is
+		 * available.
+		 */
+		uint64_t wait:1;
+		/* Must be zero */
+		uint64_t reserved_0_2:3;
+	} swork;
+
+    /**
+     * Address for loads to get POW internal status
+     */
+	struct {
+		/* Mips64 address region. Should be CVMX_IO_SEG */
+		uint64_t mem_region:2;
+		/* Must be zero */
+		uint64_t reserved_49_61:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* the ID of POW -- did<2:0> == 1 in this case */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved_10_39:30;
+		/* The core id to get status for */
+		uint64_t coreid:4;
+		/*
+		 * If set and get_cur is set, return reverse tag-list
+		 * pointer rather than forward tag-list pointer.
+		 */
+		uint64_t get_rev:1;
+		/*
+		 * If set, return current status rather than pending
+		 * status.
+		 */
+		uint64_t get_cur:1;
+		/*
+		 * If set, get the work-queue pointer rather than
+		 * tag/type.
+		 */
+		uint64_t get_wqp:1;
+		/* Must be zero */
+		uint64_t reserved_0_2:3;
+	} sstatus;
+
+    /**
+     * Address for memory loads to get POW internal state
+     */
+	struct {
+		/* Mips64 address region. Should be CVMX_IO_SEG */
+		uint64_t mem_region:2;
+		/* Must be zero */
+		uint64_t reserved_49_61:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* the ID of POW -- did<2:0> == 2 in this case */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved_16_39:24;
+		/* POW memory index */
+		uint64_t index:11;
+		/*
+		 * If set, return deschedule information rather than
+		 * the standard response for work-queue index (invalid
+		 * if the work-queue entry is not on the deschedule
+		 * list).
+		 */
+		uint64_t get_des:1;
+		/*
+		 * If set, get the work-queue pointer rather than
+		 * tag/type (no effect when get_des set).
+		 */
+		uint64_t get_wqp:1;
+		/* Must be zero */
+		uint64_t reserved_0_2:3;
+	} smemload;
+
+    /**
+     * Address for index/pointer loads
+     */
+	struct {
+		/* Mips64 address region. Should be CVMX_IO_SEG */
+		uint64_t mem_region:2;
+		/* Must be zero */
+		uint64_t reserved_49_61:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* the ID of POW -- did<2:0> == 3 in this case */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved_9_39:31;
+		/*
+		 * when {get_rmt ==0 AND get_des_get_tail == 0}, this
+		 * field selects one of eight POW internal-input
+		 * queues (0-7), one per QOS level; values 8-15 are
+		 * illegal in this case; when {get_rmt ==0 AND
+		 * get_des_get_tail == 1}, this field selects one of
+		 * 16 deschedule lists (per group); when get_rmt ==1,
+		 * this field selects one of 16 memory-input queue
+		 * lists.  The two memory-input queue lists associated
+		 * with each QOS level are:
+		 *
+		 * - qosgrp = 0, qosgrp = 8:      QOS0
+		 * - qosgrp = 1, qosgrp = 9:      QOS1
+		 * - qosgrp = 2, qosgrp = 10:     QOS2
+		 * - qosgrp = 3, qosgrp = 11:     QOS3
+		 * - qosgrp = 4, qosgrp = 12:     QOS4
+		 * - qosgrp = 5, qosgrp = 13:     QOS5
+		 * - qosgrp = 6, qosgrp = 14:     QOS6
+		 * - qosgrp = 7, qosgrp = 15:     QOS7
+		 */
+		uint64_t qosgrp:4;
+		/*
+		 * If set and get_rmt is clear, return deschedule list
+		 * indexes rather than indexes for the specified qos
+		 * level; if set and get_rmt is set, return the tail
+		 * pointer rather than the head pointer for the
+		 * specified qos level.
+		 */
+		uint64_t get_des_get_tail:1;
+		/*
+		 * If set, return remote pointers rather than the
+		 * local indexes for the specified qos level.
+		 */
+		uint64_t get_rmt:1;
+		/* Must be zero */
+		uint64_t reserved_0_2:3;
+	} sindexload;
+
+    /**
+     * address for NULL_RD request (did<2:0> == 4) when this is read,
+     * HW attempts to change the state to NULL if it is NULL_NULL (the
+     * hardware cannot switch from NULL_NULL to NULL if a POW entry is
+     * not available - software may need to recover by finishing
+     * another piece of work before a POW entry can ever become
+     * available.)
+     */
+	struct {
+		/* Mips64 address region. Should be CVMX_IO_SEG */
+		uint64_t mem_region:2;
+		/* Must be zero */
+		uint64_t reserved_49_61:13;
+		/* Must be one */
+		uint64_t is_io:1;
+		/* the ID of POW -- did<2:0> == 4 in this case */
+		uint64_t did:8;
+		/* Must be zero */
+		uint64_t reserved_0_39:40;
+	} snull_rd;
+} cvmx_pow_load_addr_t;
+
+/**
+ * This structure defines the response to a load/SENDSINGLE to POW
+ * (except CSR reads)
+ */
+typedef union {
+	uint64_t u64;
+
+    /**
+     * Response to new work request loads
+     */
+	struct {
+		/*
+		 * Set when no new work queue entry was returned.  *
+		 * If there was de-scheduled work, the HW will
+		 * definitely return it. When this bit is set, it
+		 * could mean either mean:
+		 *
+		 * - There was no work, or
+		 *
+		 * - There was no work that the HW could find. This
+		 *   case can happen, regardless of the wait bit value
+		 *   in the original request, when there is work in
+		 *   the IQ's that is too deep down the list.
+		 */
+		uint64_t no_work:1;
+		/* Must be zero */
+		uint64_t reserved_40_62:23;
+		/* 36 in O1 -- the work queue pointer */
+		uint64_t addr:40;
+	} s_work;
+
+    /**
+     * Result for a POW Status Load (when get_cur==0 and get_wqp==0)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/* Set when there is a pending non-NULL SWTAG or
+		 * SWTAG_FULL, and the POW entry has not left the list
+		 * for the original tag. */
+		uint64_t pend_switch:1;
+		/* Set when SWTAG_FULL and pend_switch is set. */
+		uint64_t pend_switch_full:1;
+		/*
+		 * Set when there is a pending NULL SWTAG, or an
+		 * implicit switch to NULL.
+		 */
+		uint64_t pend_switch_null:1;
+		/* Set when there is a pending DESCHED or SWTAG_DESCHED. */
+		uint64_t pend_desched:1;
+		/*
+		 * Set when there is a pending SWTAG_DESCHED and
+		 * pend_desched is set.
+		 */
+		uint64_t pend_desched_switch:1;
+		/* Set when nosched is desired and pend_desched is set. */
+		uint64_t pend_nosched:1;
+		/* Set when there is a pending GET_WORK. */
+		uint64_t pend_new_work:1;
+		/*
+		 * When pend_new_work is set, this bit indicates that
+		 * the wait bit was set.
+		 */
+		uint64_t pend_new_work_wait:1;
+		/* Set when there is a pending NULL_RD. */
+		uint64_t pend_null_rd:1;
+		/* Set when there is a pending CLR_NSCHED. */
+		uint64_t pend_nosched_clr:1;
+		uint64_t reserved_51:1;
+		/* This is the index when pend_nosched_clr is set. */
+		uint64_t pend_index:11;
+		/*
+		 * This is the new_grp when (pend_desched AND
+		 * pend_desched_switch) is set.
+		 */
+		uint64_t pend_grp:4;
+		uint64_t reserved_34_35:2;
+		/*
+		 * This is the tag type when pend_switch or
+		 * (pend_desched AND pend_desched_switch) are set.
+		 */
+		uint64_t pend_type:2;
+		/*
+		 * - this is the tag when pend_switch or (pend_desched
+		 *    AND pend_desched_switch) are set.
+		 */
+		uint64_t pend_tag:32;
+	} s_sstatus0;
+
+    /**
+     * Result for a POW Status Load (when get_cur==0 and get_wqp==1)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/*
+		 * Set when there is a pending non-NULL SWTAG or
+		 * SWTAG_FULL, and the POW entry has not left the list
+		 * for the original tag.
+		 */
+		uint64_t pend_switch:1;
+		/* Set when SWTAG_FULL and pend_switch is set. */
+		uint64_t pend_switch_full:1;
+		/*
+		 * Set when there is a pending NULL SWTAG, or an
+		 * implicit switch to NULL.
+		 */
+		uint64_t pend_switch_null:1;
+		/*
+		 * Set when there is a pending DESCHED or
+		 * SWTAG_DESCHED.
+		 */
+		uint64_t pend_desched:1;
+		/*
+		 * Set when there is a pending SWTAG_DESCHED and
+		 * pend_desched is set.
+		 */
+		uint64_t pend_desched_switch:1;
+		/* Set when nosched is desired and pend_desched is set. */
+		uint64_t pend_nosched:1;
+		/* Set when there is a pending GET_WORK. */
+		uint64_t pend_new_work:1;
+		/*
+		 * When pend_new_work is set, this bit indicates that
+		 * the wait bit was set.
+		 */
+		uint64_t pend_new_work_wait:1;
+		/* Set when there is a pending NULL_RD. */
+		uint64_t pend_null_rd:1;
+		/* Set when there is a pending CLR_NSCHED. */
+		uint64_t pend_nosched_clr:1;
+		uint64_t reserved_51:1;
+		/* This is the index when pend_nosched_clr is set. */
+		uint64_t pend_index:11;
+		/*
+		 * This is the new_grp when (pend_desched AND
+		 * pend_desched_switch) is set.
+		 */
+		uint64_t pend_grp:4;
+		/* This is the wqp when pend_nosched_clr is set. */
+		uint64_t pend_wqp:36;
+	} s_sstatus1;
+
+    /**
+     * Result for a POW Status Load (when get_cur==1, get_wqp==0, and
+     * get_rev==0)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/*
+		 * Points to the next POW entry in the tag list when
+		 * tail == 0 (and tag_type is not NULL or NULL_NULL).
+		 */
+		uint64_t link_index:11;
+		/* The POW entry attached to the core. */
+		uint64_t index:11;
+		/*
+		 * The group attached to the core (updated when new
+		 * tag list entered on SWTAG_FULL).
+		 */
+		uint64_t grp:4;
+		/*
+		 * Set when this POW entry is at the head of its tag
+		 * list (also set when in the NULL or NULL_NULL
+		 * state).
+		 */
+		uint64_t head:1;
+		/*
+		 * Set when this POW entry is at the tail of its tag
+		 * list (also set when in the NULL or NULL_NULL
+		 * state).
+		 */
+		uint64_t tail:1;
+		/*
+		 * The tag type attached to the core (updated when new
+		 * tag list entered on SWTAG, SWTAG_FULL, or
+		 * SWTAG_DESCHED).
+		 */
+		uint64_t tag_type:2;
+		/*
+		 * The tag attached to the core (updated when new tag
+		 * list entered on SWTAG, SWTAG_FULL, or
+		 * SWTAG_DESCHED).
+		 */
+		uint64_t tag:32;
+	} s_sstatus2;
+
+    /**
+     * Result for a POW Status Load (when get_cur==1, get_wqp==0, and get_rev==1)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/*
+		 * Points to the prior POW entry in the tag list when
+		 * head == 0 (and tag_type is not NULL or
+		 * NULL_NULL). This field is unpredictable when the
+		 * core's state is NULL or NULL_NULL.
+		 */
+		uint64_t revlink_index:11;
+		/* The POW entry attached to the core. */
+		uint64_t index:11;
+		/*
+		 * The group attached to the core (updated when new
+		 * tag list entered on SWTAG_FULL).
+		 */
+		uint64_t grp:4;
+		/* Set when this POW entry is at the head of its tag
+		 * list (also set when in the NULL or NULL_NULL
+		 * state).
+		 */
+		uint64_t head:1;
+		/*
+		 * Set when this POW entry is at the tail of its tag
+		 * list (also set when in the NULL or NULL_NULL
+		 * state).
+		 */
+		uint64_t tail:1;
+		/*
+		 * The tag type attached to the core (updated when new
+		 * tag list entered on SWTAG, SWTAG_FULL, or
+		 * SWTAG_DESCHED).
+		 */
+		uint64_t tag_type:2;
+		/*
+		 * The tag attached to the core (updated when new tag
+		 * list entered on SWTAG, SWTAG_FULL, or
+		 * SWTAG_DESCHED).
+		 */
+		uint64_t tag:32;
+	} s_sstatus3;
+
+    /**
+     * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
+     * get_rev==0)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/*
+		 * Points to the next POW entry in the tag list when
+		 * tail == 0 (and tag_type is not NULL or NULL_NULL).
+		 */
+		uint64_t link_index:11;
+		/* The POW entry attached to the core. */
+		uint64_t index:11;
+		/*
+		 * The group attached to the core (updated when new
+		 * tag list entered on SWTAG_FULL).
+		 */
+		uint64_t grp:4;
+		/*
+		 * The wqp attached to the core (updated when new tag
+		 * list entered on SWTAG_FULL).
+		 */
+		uint64_t wqp:36;
+	} s_sstatus4;
+
+    /**
+     * Result for a POW Status Load (when get_cur==1, get_wqp==1, and
+     * get_rev==1)
+     */
+	struct {
+		uint64_t reserved_62_63:2;
+		/*
+		 * Points to the prior POW entry in the tag list when
+		 * head == 0 (and tag_type is not NULL or
+		 * NULL_NULL). This field is unpredictable when the
+		 * core's state is NULL or NULL_NULL.
+		 */
+		uint64_t revlink_index:11;
+		/* The POW entry attached to the core. */
+		uint64_t index:11;
+		/*
+		 * The group attached to the core (updated when new
+		 * tag list entered on SWTAG_FULL).
+		 */
+		uint64_t grp:4;
+		/*
+		 * The wqp attached to the core (updated when new tag
+		 * list entered on SWTAG_FULL).
+		 */
+		uint64_t wqp:36;
+	} s_sstatus5;
+
+    /**
+     * Result For POW Memory Load (get_des == 0 and get_wqp == 0)
+     */
+	struct {
+		uint64_t reserved_51_63:13;
+		/*
+		 * The next entry in the input, free, descheduled_head
+		 * list (unpredictable if entry is the tail of the
+		 * list).
+		 */
+		uint64_t next_index:11;
+		/* The group of the POW entry. */
+		uint64_t grp:4;
+		uint64_t reserved_35:1;
+		/*
+		 * Set when this POW entry is at the tail of its tag
+		 * list (also set when in the NULL or NULL_NULL
+		 * state).
+		 */
+		uint64_t tail:1;
+		/* The tag type of the POW entry. */
+		uint64_t tag_type:2;
+		/* The tag of the POW entry. */
+		uint64_t tag:32;
+	} s_smemload0;
+
+    /**
+     * Result For POW Memory Load (get_des == 0 and get_wqp == 1)
+     */
+	struct {
+		uint64_t reserved_51_63:13;
+		/*
+		 * The next entry in the input, free, descheduled_head
+		 * list (unpredictable if entry is the tail of the
+		 * list).
+		 */
+		uint64_t next_index:11;
+		/* The group of the POW entry. */
+		uint64_t grp:4;
+		/* The WQP held in the POW entry. */
+		uint64_t wqp:36;
+	} s_smemload1;
+
+    /**
+     * Result For POW Memory Load (get_des == 1)
+     */
+	struct {
+		uint64_t reserved_51_63:13;
+		/*
+		 * The next entry in the tag list connected to the
+		 * descheduled head.
+		 */
+		uint64_t fwd_index:11;
+		/* The group of the POW entry. */
+		uint64_t grp:4;
+		/* The nosched bit for the POW entry. */
+		uint64_t nosched:1;
+		/* There is a pending tag switch */
+		uint64_t pend_switch:1;
+		/*
+		 * The next tag type for the new tag list when
+		 * pend_switch is set.
+		 */
+		uint64_t pend_type:2;
+		/*
+		 * The next tag for the new tag list when pend_switch
+		 * is set.
+		 */
+		uint64_t pend_tag:32;
+	} s_smemload2;
+
+    /**
+     * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 0)
+     */
+	struct {
+		uint64_t reserved_52_63:12;
+		/*
+		 * set when there is one or more POW entries on the
+		 * free list.
+		 */
+		uint64_t free_val:1;
+		/*
+		 * set when there is exactly one POW entry on the free
+		 * list.
+		 */
+		uint64_t free_one:1;
+		uint64_t reserved_49:1;
+		/*
+		 * when free_val is set, indicates the first entry on
+		 * the free list.
+		 */
+		uint64_t free_head:11;
+		uint64_t reserved_37:1;
+		/*
+		 * when free_val is set, indicates the last entry on
+		 * the free list.
+		 */
+		uint64_t free_tail:11;
+		/*
+		 * set when there is one or more POW entries on the
+		 * input Q list selected by qosgrp.
+		 */
+		uint64_t loc_val:1;
+		/*
+		 * set when there is exactly one POW entry on the
+		 * input Q list selected by qosgrp.
+		 */
+		uint64_t loc_one:1;
+		uint64_t reserved_23:1;
+		/*
+		 * when loc_val is set, indicates the first entry on
+		 * the input Q list selected by qosgrp.
+		 */
+		uint64_t loc_head:11;
+		uint64_t reserved_11:1;
+		/*
+		 * when loc_val is set, indicates the last entry on
+		 * the input Q list selected by qosgrp.
+		 */
+		uint64_t loc_tail:11;
+	} sindexload0;
+
+    /**
+     * Result For POW Index/Pointer Load (get_rmt == 0/get_des_get_tail == 1)
+     */
+	struct {
+		uint64_t reserved_52_63:12;
+		/*
+		 * set when there is one or more POW entries on the
+		 * nosched list.
+		 */
+		uint64_t nosched_val:1;
+		/*
+		 * set when there is exactly one POW entry on the
+		 * nosched list.
+		 */
+		uint64_t nosched_one:1;
+		uint64_t reserved_49:1;
+		/*
+		 * when nosched_val is set, indicates the first entry
+		 * on the nosched list.
+		 */
+		uint64_t nosched_head:11;
+		uint64_t reserved_37:1;
+		/*
+		 * when nosched_val is set, indicates the last entry
+		 * on the nosched list.
+		 */
+		uint64_t nosched_tail:11;
+		/*
+		 * set when there is one or more descheduled heads on
+		 * the descheduled list selected by qosgrp.
+		 */
+		uint64_t des_val:1;
+		/*
+		 * set when there is exactly one descheduled head on
+		 * the descheduled list selected by qosgrp.
+		 */
+		uint64_t des_one:1;
+		uint64_t reserved_23:1;
+		/*
+		 * when des_val is set, indicates the first
+		 * descheduled head on the descheduled list selected
+		 * by qosgrp.
+		 */
+		uint64_t des_head:11;
+		uint64_t reserved_11:1;
+		/*
+		 * when des_val is set, indicates the last descheduled
+		 * head on the descheduled list selected by qosgrp.
+		 */
+		uint64_t des_tail:11;
+	} sindexload1;
+
+    /**
+     * Result For POW Index/Pointer Load (get_rmt == 1/get_des_get_tail == 0)
+     */
+	struct {
+		uint64_t reserved_39_63:25;
+		/*
+		 * Set when this DRAM list is the current head
+		 * (i.e. is the next to be reloaded when the POW
+		 * hardware reloads a POW entry from DRAM). The POW
+		 * hardware alternates between the two DRAM lists
+		 * associated with a QOS level when it reloads work
+		 * from DRAM into the POW unit.
+		 */
+		uint64_t rmt_is_head:1;
+		/*
+		 * Set when the DRAM portion of the input Q list
+		 * selected by qosgrp contains one or more pieces of
+		 * work.
+		 */
+		uint64_t rmt_val:1;
+		/*
+		 * Set when the DRAM portion of the input Q list
+		 * selected by qosgrp contains exactly one piece of
+		 * work.
+		 */
+		uint64_t rmt_one:1;
+		/*
+		 * When rmt_val is set, indicates the first piece of
+		 * work on the DRAM input Q list selected by
+		 * qosgrp.
+		 */
+		uint64_t rmt_head:36;
+	} sindexload2;
+
+    /**
+     * Result For POW Index/Pointer Load (get_rmt ==
+     * 1/get_des_get_tail == 1)
+     */
+	struct {
+		uint64_t reserved_39_63:25;
+		/*
+		 * set when this DRAM list is the current head
+		 * (i.e. is the next to be reloaded when the POW
+		 * hardware reloads a POW entry from DRAM). The POW
+		 * hardware alternates between the two DRAM lists
+		 * associated with a QOS level when it reloads work
+		 * from DRAM into the POW unit.
+		 */
+		uint64_t rmt_is_head:1;
+		/*
+		 * set when the DRAM portion of the input Q list
+		 * selected by qosgrp contains one or more pieces of
+		 * work.
+		 */
+		uint64_t rmt_val:1;
+		/*
+		 * set when the DRAM portion of the input Q list
+		 * selected by qosgrp contains exactly one piece of
+		 * work.
+		 */
+		uint64_t rmt_one:1;
+		/*
+		 * when rmt_val is set, indicates the last piece of
+		 * work on the DRAM input Q list selected by
+		 * qosgrp.
+		 */
+		uint64_t rmt_tail:36;
+	} sindexload3;
+
+    /**
+     * Response to NULL_RD request loads
+     */
+	struct {
+		uint64_t unused:62;
+		/* of type cvmx_pow_tag_type_t. state is one of the
+		 * following:
+		 *
+		 * - CVMX_POW_TAG_TYPE_ORDERED
+		 * - CVMX_POW_TAG_TYPE_ATOMIC
+		 * - CVMX_POW_TAG_TYPE_NULL
+		 * - CVMX_POW_TAG_TYPE_NULL_NULL
+		 */
+		uint64_t state:2;
+	} s_null_rd;
+
+} cvmx_pow_tag_load_resp_t;
+
+/**
+ * This structure describes the address used for stores to the POW.
+ *  The store address is meaningful on stores to the POW.  The
+ *  hardware assumes that an aligned 64-bit store was used for all
+ *  these stores.  Note the assumption that the work queue entry is
+ *  aligned on an 8-byte boundary (since the low-order 3 address bits
+ *  must be zero).  Note that not all fields are used by all
+ *  operations.
+ *
+ *  NOTE: The following is the behavior of the pending switch bit at the PP
+ *       for POW stores (i.e. when did<7:3> == 0xc)
+ *     - did<2:0> == 0      => pending switch bit is set
+ *     - did<2:0> == 1      => no affect on the pending switch bit
+ *     - did<2:0> == 3      => pending switch bit is cleared
+ *     - did<2:0> == 7      => no affect on the pending switch bit
+ *     - did<2:0> == others => must not be used
+ *     - No other loads/stores have an affect on the pending switch bit
+ *     - The switch bus from POW can clear the pending switch bit
+ *
+ *  NOTE: did<2:0> == 2 is used by the HW for a special single-cycle
+ *  ADDWQ command that only contains the pointer). SW must never use
+ *  did<2:0> == 2.
+ */
+typedef union {
+    /**
+     * Unsigned 64 bit integer representation of store address
+     */
+	uint64_t u64;
+
+	struct {
+		/* Memory region.  Should be CVMX_IO_SEG in most cases */
+		uint64_t mem_reg:2;
+		uint64_t reserved_49_61:13;	/* Must be zero */
+		uint64_t is_io:1;	/* Must be one */
+		/* Device ID of POW.  Note that different sub-dids are used. */
+		uint64_t did:8;
+		uint64_t reserved_36_39:4;	/* Must be zero */
+		/* Address field. addr<2:0> must be zero */
+		uint64_t addr:36;
+	} stag;
+} cvmx_pow_tag_store_addr_t;
+
+/**
+ * decode of the store data when an IOBDMA SENDSINGLE is sent to POW
+ */
+typedef union {
+	uint64_t u64;
+
+	struct {
+		/*
+		 * the (64-bit word) location in scratchpad to write
+		 * to (if len != 0)
+		 */
+		uint64_t scraddr:8;
+		/* the number of words in the response (0 => no response) */
+		uint64_t len:8;
+		/* the ID of the device on the non-coherent bus */
+		uint64_t did:8;
+		uint64_t unused:36;
+		/* if set, don't return load response until work is available */
+		uint64_t wait:1;
+		uint64_t unused2:3;
+	} s;
+
+} cvmx_pow_iobdma_store_t;
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+
+/**
+ * Get the POW tag for this core. This returns the current
+ * tag type, tag, group, and POW entry index associated with
+ * this core. Index is only valid if the tag type isn't NULL_NULL.
+ * If a tag switch is pending this routine returns the tag before
+ * the tag switch, not after.
+ *
+ * Returns Current tag
+ */
+static inline cvmx_pow_tag_req_t cvmx_pow_get_current_tag(void)
+{
+	cvmx_pow_load_addr_t load_addr;
+	cvmx_pow_tag_load_resp_t load_resp;
+	cvmx_pow_tag_req_t result;
+
+	load_addr.u64 = 0;
+	load_addr.sstatus.mem_region = CVMX_IO_SEG;
+	load_addr.sstatus.is_io = 1;
+	load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
+	load_addr.sstatus.coreid = cvmx_get_core_num();
+	load_addr.sstatus.get_cur = 1;
+	load_resp.u64 = cvmx_read_csr(load_addr.u64);
+	result.u64 = 0;
+	result.s.grp = load_resp.s_sstatus2.grp;
+	result.s.index = load_resp.s_sstatus2.index;
+	result.s.type = load_resp.s_sstatus2.tag_type;
+	result.s.tag = load_resp.s_sstatus2.tag;
+	return result;
+}
+
+/**
+ * Get the POW WQE for this core. This returns the work queue
+ * entry currently associated with this core.
+ *
+ * Returns WQE pointer
+ */
+static inline cvmx_wqe_t *cvmx_pow_get_current_wqp(void)
+{
+	cvmx_pow_load_addr_t load_addr;
+	cvmx_pow_tag_load_resp_t load_resp;
+
+	load_addr.u64 = 0;
+	load_addr.sstatus.mem_region = CVMX_IO_SEG;
+	load_addr.sstatus.is_io = 1;
+	load_addr.sstatus.did = CVMX_OCT_DID_TAG_TAG1;
+	load_addr.sstatus.coreid = cvmx_get_core_num();
+	load_addr.sstatus.get_cur = 1;
+	load_addr.sstatus.get_wqp = 1;
+	load_resp.u64 = cvmx_read_csr(load_addr.u64);
+	return (cvmx_wqe_t *) cvmx_phys_to_ptr(load_resp.s_sstatus4.wqp);
+}
+
+#ifndef CVMX_MF_CHORD
+#define CVMX_MF_CHORD(dest)         CVMX_RDHWR(dest, 30)
+#endif
+
+/**
+ * Print a warning if a tag switch is pending for this core
+ *
+ * @function: Function name checking for a pending tag switch
+ */
+static inline void __cvmx_pow_warn_if_pending_switch(const char *function)
+{
+	uint64_t switch_complete;
+	CVMX_MF_CHORD(switch_complete);
+	if (!switch_complete)
+		pr_warning("%s called with tag switch in progress\n", function);
+}
+
+/**
+ * Waits for a tag switch to complete by polling the completion bit.
+ * Note that switches to NULL complete immediately and do not need
+ * to be waited for.
+ */
+static inline void cvmx_pow_tag_sw_wait(void)
+{
+	const uint64_t MAX_CYCLES = 1ull << 31;
+	uint64_t switch_complete;
+	uint64_t start_cycle = cvmx_get_cycle();
+	while (1) {
+		CVMX_MF_CHORD(switch_complete);
+		if (unlikely(switch_complete))
+			break;
+		if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) {
+			pr_warning("Tag switch is taking a long time, "
+				   "possible deadlock\n");
+			start_cycle = -MAX_CYCLES - 1;
+		}
+	}
+}
+
+/**
+ * Synchronous work request.  Requests work from the POW.
+ * This function does NOT wait for previous tag switches to complete,
+ * so the caller must ensure that there is not a pending tag switch.
+ *
+ * @wait:   When set, call stalls until work becomes avaiable, or times out.
+ *               If not set, returns immediately.
+ *
+ * Returns Returns the WQE pointer from POW. Returns NULL if no work
+ * was available.
+ */
+static inline cvmx_wqe_t *cvmx_pow_work_request_sync_nocheck(cvmx_pow_wait_t
+							     wait)
+{
+	cvmx_pow_load_addr_t ptr;
+	cvmx_pow_tag_load_resp_t result;
+
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	ptr.u64 = 0;
+	ptr.swork.mem_region = CVMX_IO_SEG;
+	ptr.swork.is_io = 1;
+	ptr.swork.did = CVMX_OCT_DID_TAG_SWTAG;
+	ptr.swork.wait = wait;
+
+	result.u64 = cvmx_read_csr(ptr.u64);
+
+	if (result.s_work.no_work)
+		return NULL;
+	else
+		return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
+}
+
+/**
+ * Synchronous work request.  Requests work from the POW.
+ * This function waits for any previous tag switch to complete before
+ * requesting the new work.
+ *
+ * @wait:   When set, call stalls until work becomes avaiable, or times out.
+ *               If not set, returns immediately.
+ *
+ * Returns Returns the WQE pointer from POW. Returns NULL if no work
+ * was available.
+ */
+static inline cvmx_wqe_t *cvmx_pow_work_request_sync(cvmx_pow_wait_t wait)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/* Must not have a switch pending when requesting work */
+	cvmx_pow_tag_sw_wait();
+	return cvmx_pow_work_request_sync_nocheck(wait);
+
+}
+
+/**
+ * Synchronous null_rd request.  Requests a switch out of NULL_NULL POW state.
+ * This function waits for any previous tag switch to complete before
+ * requesting the null_rd.
+ *
+ * Returns Returns the POW state of type cvmx_pow_tag_type_t.
+ */
+static inline enum cvmx_pow_tag_type cvmx_pow_work_request_null_rd(void)
+{
+	cvmx_pow_load_addr_t ptr;
+	cvmx_pow_tag_load_resp_t result;
+
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/* Must not have a switch pending when requesting work */
+	cvmx_pow_tag_sw_wait();
+
+	ptr.u64 = 0;
+	ptr.snull_rd.mem_region = CVMX_IO_SEG;
+	ptr.snull_rd.is_io = 1;
+	ptr.snull_rd.did = CVMX_OCT_DID_TAG_NULL_RD;
+
+	result.u64 = cvmx_read_csr(ptr.u64);
+
+	return (enum cvmx_pow_tag_type) result.s_null_rd.state;
+}
+
+/**
+ * Asynchronous work request.  Work is requested from the POW unit,
+ * and should later be checked with function
+ * cvmx_pow_work_response_async.  This function does NOT wait for
+ * previous tag switches to complete, so the caller must ensure that
+ * there is not a pending tag switch.
+ *
+ * @scr_addr: Scratch memory address that response will be returned
+ *            to, which is either a valid WQE, or a response with the
+ *            invalid bit set.  Byte address, must be 8 byte aligned.
+ *
+ * @wait: 1 to cause response to wait for work to become available (or
+ *        timeout), 0 to cause response to return immediately
+ */
+static inline void cvmx_pow_work_request_async_nocheck(int scr_addr,
+						       cvmx_pow_wait_t wait)
+{
+	cvmx_pow_iobdma_store_t data;
+
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/* scr_addr must be 8 byte aligned */
+	data.s.scraddr = scr_addr >> 3;
+	data.s.len = 1;
+	data.s.did = CVMX_OCT_DID_TAG_SWTAG;
+	data.s.wait = wait;
+	cvmx_send_single(data.u64);
+}
+
+/**
+ * Asynchronous work request.  Work is requested from the POW unit,
+ * and should later be checked with function
+ * cvmx_pow_work_response_async.  This function waits for any previous
+ * tag switch to complete before requesting the new work.
+ *
+ * @scr_addr: Scratch memory address that response will be returned
+ *            to, which is either a valid WQE, or a response with the
+ *            invalid bit set.  Byte address, must be 8 byte aligned.
+ *
+ * @wait: 1 to cause response to wait for work to become available (or
+ *                  timeout), 0 to cause response to return immediately
+ */
+static inline void cvmx_pow_work_request_async(int scr_addr,
+					       cvmx_pow_wait_t wait)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/* Must not have a switch pending when requesting work */
+	cvmx_pow_tag_sw_wait();
+	cvmx_pow_work_request_async_nocheck(scr_addr, wait);
+}
+
+/**
+ * Gets result of asynchronous work request.  Performs a IOBDMA sync
+ * to wait for the response.
+ *
+ * @scr_addr: Scratch memory address to get result from Byte address,
+ *            must be 8 byte aligned.
+ *
+ * Returns Returns the WQE from the scratch register, or NULL if no
+ * work was available.
+ */
+static inline cvmx_wqe_t *cvmx_pow_work_response_async(int scr_addr)
+{
+	cvmx_pow_tag_load_resp_t result;
+
+	CVMX_SYNCIOBDMA;
+	result.u64 = cvmx_scratch_read64(scr_addr);
+
+	if (result.s_work.no_work)
+		return NULL;
+	else
+		return (cvmx_wqe_t *) cvmx_phys_to_ptr(result.s_work.addr);
+}
+
+/**
+ * Checks if a work queue entry pointer returned by a work
+ * request is valid.  It may be invalid due to no work
+ * being available or due to a timeout.
+ *
+ * @wqe_ptr: pointer to a work queue entry returned by the POW
+ *
+ * Returns 0 if pointer is valid
+ *         1 if invalid (no work was returned)
+ */
+static inline uint64_t cvmx_pow_work_invalid(cvmx_wqe_t *wqe_ptr)
+{
+	return wqe_ptr == NULL;
+}
+
+/**
+ * Starts a tag switch to the provided tag value and tag type.
+ * Completion for the tag switch must be checked for separately.  This
+ * function does NOT update the work queue entry in dram to match tag
+ * value and type, so the application must keep track of these if they
+ * are important to the application.  This tag switch command must not
+ * be used for switches to NULL, as the tag switch pending bit will be
+ * set by the switch request, but never cleared by the hardware.
+ *
+ * NOTE: This should not be used when switching from a NULL tag.  Use
+ * cvmx_pow_tag_sw_full() instead.
+ *
+ * This function does no checks, so the caller must ensure that any
+ * previous tag switch has completed.
+ *
+ * @tag:      new tag value
+ * @tag_type: new tag type (ordered or atomic)
+ */
+static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag,
+					   enum cvmx_pow_tag_type tag_type)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	if (CVMX_ENABLE_POW_CHECKS) {
+		cvmx_pow_tag_req_t current_tag;
+		__cvmx_pow_warn_if_pending_switch(__func__);
+		current_tag = cvmx_pow_get_current_tag();
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
+			pr_warning("%s called with NULL_NULL tag\n",
+				   __func__);
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called with NULL tag\n", __func__);
+		if ((current_tag.s.type == tag_type)
+		   && (current_tag.s.tag == tag))
+			pr_warning("%s called to perform a tag switch to the "
+				   "same tag\n",
+			     __func__);
+		if (tag_type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called to perform a tag switch to "
+				   "NULL. Use cvmx_pow_tag_sw_null() instead\n",
+			     __func__);
+	}
+
+	/*
+	 * Note that WQE in DRAM is not updated here, as the POW does
+	 * not read from DRAM once the WQE is in flight.  See hardware
+	 * manual for complete details.  It is the application's
+	 * responsibility to keep track of the current tag value if
+	 * that is important.
+	 */
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
+	tag_req.s.tag = tag;
+	tag_req.s.type = tag_type;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
+
+	/* once this store arrives at POW, it will attempt the switch
+	   software must wait for the switch to complete separately */
+	cvmx_write_io(ptr.u64, tag_req.u64);
+}
+
+/**
+ * Starts a tag switch to the provided tag value and tag type.
+ * Completion for the tag switch must be checked for separately.  This
+ * function does NOT update the work queue entry in dram to match tag
+ * value and type, so the application must keep track of these if they
+ * are important to the application.  This tag switch command must not
+ * be used for switches to NULL, as the tag switch pending bit will be
+ * set by the switch request, but never cleared by the hardware.
+ *
+ * NOTE: This should not be used when switching from a NULL tag.  Use
+ * cvmx_pow_tag_sw_full() instead.
+ *
+ * This function waits for any previous tag switch to complete, and also
+ * displays an error on tag switches to NULL.
+ *
+ * @tag:      new tag value
+ * @tag_type: new tag type (ordered or atomic)
+ */
+static inline void cvmx_pow_tag_sw(uint32_t tag,
+				   enum cvmx_pow_tag_type tag_type)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/*
+	 * Note that WQE in DRAM is not updated here, as the POW does
+	 * not read from DRAM once the WQE is in flight.  See hardware
+	 * manual for complete details.  It is the application's
+	 * responsibility to keep track of the current tag value if
+	 * that is important.
+	 */
+
+	/*
+	 * Ensure that there is not a pending tag switch, as a tag
+	 * switch cannot be started if a previous switch is still
+	 * pending.
+	 */
+	cvmx_pow_tag_sw_wait();
+	cvmx_pow_tag_sw_nocheck(tag, tag_type);
+}
+
+/**
+ * Starts a tag switch to the provided tag value and tag type.
+ * Completion for the tag switch must be checked for separately.  This
+ * function does NOT update the work queue entry in dram to match tag
+ * value and type, so the application must keep track of these if they
+ * are important to the application.  This tag switch command must not
+ * be used for switches to NULL, as the tag switch pending bit will be
+ * set by the switch request, but never cleared by the hardware.
+ *
+ * This function must be used for tag switches from NULL.
+ *
+ * This function does no checks, so the caller must ensure that any
+ * previous tag switch has completed.
+ *
+ * @wqp:      pointer to work queue entry to submit.  This entry is
+ *            updated to match the other parameters
+ * @tag:      tag value to be assigned to work queue entry
+ * @tag_type: type of tag
+ * @group:    group value for the work queue entry.
+ */
+static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag,
+						enum cvmx_pow_tag_type tag_type,
+						uint64_t group)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	if (CVMX_ENABLE_POW_CHECKS) {
+		cvmx_pow_tag_req_t current_tag;
+		__cvmx_pow_warn_if_pending_switch(__func__);
+		current_tag = cvmx_pow_get_current_tag();
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
+			pr_warning("%s called with NULL_NULL tag\n",
+				   __func__);
+		if ((current_tag.s.type == tag_type)
+		   && (current_tag.s.tag == tag))
+			pr_warning("%s called to perform a tag switch to "
+				   "the same tag\n",
+			     __func__);
+		if (tag_type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called to perform a tag switch to "
+				   "NULL. Use cvmx_pow_tag_sw_null() instead\n",
+			     __func__);
+		if (wqp != cvmx_phys_to_ptr(0x80))
+			if (wqp != cvmx_pow_get_current_wqp())
+				pr_warning("%s passed WQE(%p) doesn't match "
+					   "the address in the POW(%p)\n",
+				     __func__, wqp,
+				     cvmx_pow_get_current_wqp());
+	}
+
+	/*
+	 * Note that WQE in DRAM is not updated here, as the POW does
+	 * not read from DRAM once the WQE is in flight.  See hardware
+	 * manual for complete details.  It is the application's
+	 * responsibility to keep track of the current tag value if
+	 * that is important.
+	 */
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_FULL;
+	tag_req.s.tag = tag;
+	tag_req.s.type = tag_type;
+	tag_req.s.grp = group;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_SWTAG;
+	ptr.sio.offset = CAST64(wqp);
+
+	/*
+	 * once this store arrives at POW, it will attempt the switch
+	 * software must wait for the switch to complete separately.
+	 */
+	cvmx_write_io(ptr.u64, tag_req.u64);
+}
+
+/**
+ * Starts a tag switch to the provided tag value and tag type.
+ * Completion for the tag switch must be checked for separately.  This
+ * function does NOT update the work queue entry in dram to match tag
+ * value and type, so the application must keep track of these if they
+ * are important to the application.  This tag switch command must not
+ * be used for switches to NULL, as the tag switch pending bit will be
+ * set by the switch request, but never cleared by the hardware.
+ *
+ * This function must be used for tag switches from NULL.
+ *
+ * This function waits for any pending tag switches to complete
+ * before requesting the tag switch.
+ *
+ * @wqp:      pointer to work queue entry to submit.  This entry is updated
+ *            to match the other parameters
+ * @tag:      tag value to be assigned to work queue entry
+ * @tag_type: type of tag
+ * @group:      group value for the work queue entry.
+ */
+static inline void cvmx_pow_tag_sw_full(cvmx_wqe_t *wqp, uint32_t tag,
+					enum cvmx_pow_tag_type tag_type,
+					uint64_t group)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/*
+	 * Ensure that there is not a pending tag switch, as a tag
+	 * switch cannot be started if a previous switch is still
+	 * pending.
+	 */
+	cvmx_pow_tag_sw_wait();
+	cvmx_pow_tag_sw_full_nocheck(wqp, tag, tag_type, group);
+}
+
+/**
+ * Switch to a NULL tag, which ends any ordering or
+ * synchronization provided by the POW for the current
+ * work queue entry.  This operation completes immediatly,
+ * so completetion should not be waited for.
+ * This function does NOT wait for previous tag switches to complete,
+ * so the caller must ensure that any previous tag switches have completed.
+ */
+static inline void cvmx_pow_tag_sw_null_nocheck(void)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	if (CVMX_ENABLE_POW_CHECKS) {
+		cvmx_pow_tag_req_t current_tag;
+		__cvmx_pow_warn_if_pending_switch(__func__);
+		current_tag = cvmx_pow_get_current_tag();
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
+			pr_warning("%s called with NULL_NULL tag\n",
+				   __func__);
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called when we already have a "
+				   "NULL tag\n",
+			     __func__);
+	}
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_SWTAG;
+	tag_req.s.type = CVMX_POW_TAG_TYPE_NULL;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
+
+	cvmx_write_io(ptr.u64, tag_req.u64);
+
+	/* switch to NULL completes immediately */
+}
+
+/**
+ * Switch to a NULL tag, which ends any ordering or
+ * synchronization provided by the POW for the current
+ * work queue entry.  This operation completes immediatly,
+ * so completetion should not be waited for.
+ * This function waits for any pending tag switches to complete
+ * before requesting the switch to NULL.
+ */
+static inline void cvmx_pow_tag_sw_null(void)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/*
+	 * Ensure that there is not a pending tag switch, as a tag
+	 * switch cannot be started if a previous switch is still
+	 * pending.
+	 */
+	cvmx_pow_tag_sw_wait();
+	cvmx_pow_tag_sw_null_nocheck();
+
+	/* switch to NULL completes immediately */
+}
+
+/**
+ * Submits work to an input queue.  This function updates the work
+ * queue entry in DRAM to match the arguments given.  Note that the
+ * tag provided is for the work queue entry submitted, and is
+ * unrelated to the tag that the core currently holds.
+ *
+ * @wqp:      pointer to work queue entry to submit.  This entry is
+ *            updated to match the other parameters
+ * @tag:      tag value to be assigned to work queue entry
+ * @tag_type: type of tag
+ * @qos:      Input queue to add to.
+ * @grp:      group value for the work queue entry.
+ */
+static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,
+					enum cvmx_pow_tag_type tag_type,
+					uint64_t qos, uint64_t grp)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	wqp->qos = qos;
+	wqp->tag = tag;
+	wqp->tag_type = tag_type;
+	wqp->grp = grp;
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
+	tag_req.s.type = tag_type;
+	tag_req.s.tag = tag;
+	tag_req.s.qos = qos;
+	tag_req.s.grp = grp;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_TAG1;
+	ptr.sio.offset = cvmx_ptr_to_phys(wqp);
+
+	/*
+	 * SYNC write to memory before the work submit.  This is
+	 * necessary as POW may read values from DRAM at this time.
+	 */
+	CVMX_SYNCWS;
+	cvmx_write_io(ptr.u64, tag_req.u64);
+}
+
+/**
+ * This function sets the group mask for a core.  The group mask
+ * indicates which groups each core will accept work from. There are
+ * 16 groups.
+ *
+ * @core_num:   core to apply mask to
+ * @mask:   Group mask. There are 16 groups, so only bits 0-15 are valid,
+ *               representing groups 0-15.
+ *               Each 1 bit in the mask enables the core to accept work from
+ *               the corresponding group.
+ */
+static inline void cvmx_pow_set_group_mask(uint64_t core_num, uint64_t mask)
+{
+	union cvmx_pow_pp_grp_mskx grp_msk;
+
+	grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
+	grp_msk.s.grp_msk = mask;
+	cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
+}
+
+/**
+ * This function sets POW static priorities for a core. Each input queue has
+ * an associated priority value.
+ *
+ * @core_num:   core to apply priorities to
+ * @priority:   Vector of 8 priorities, one per POW Input Queue (0-7).
+ *                   Highest priority is 0 and lowest is 7. A priority value
+ *                   of 0xF instructs POW to skip the Input Queue when
+ *                   scheduling to this specific core.
+ *                   NOTE: priorities should not have gaps in values, meaning
+ *                         {0,1,1,1,1,1,1,1} is a valid configuration while
+ *                         {0,2,2,2,2,2,2,2} is not.
+ */
+static inline void cvmx_pow_set_priority(uint64_t core_num,
+					 const uint8_t priority[])
+{
+	/* POW priorities are supported on CN5xxx and later */
+	if (!OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+		union cvmx_pow_pp_grp_mskx grp_msk;
+
+		grp_msk.u64 = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(core_num));
+		grp_msk.s.qos0_pri = priority[0];
+		grp_msk.s.qos1_pri = priority[1];
+		grp_msk.s.qos2_pri = priority[2];
+		grp_msk.s.qos3_pri = priority[3];
+		grp_msk.s.qos4_pri = priority[4];
+		grp_msk.s.qos5_pri = priority[5];
+		grp_msk.s.qos6_pri = priority[6];
+		grp_msk.s.qos7_pri = priority[7];
+
+		/* Detect gaps between priorities and flag error */
+		{
+			int i;
+			uint32_t prio_mask = 0;
+
+			for (i = 0; i < 8; i++)
+				if (priority[i] != 0xF)
+					prio_mask |= 1 << priority[i];
+
+			if (prio_mask ^ ((1 << cvmx_pop(prio_mask)) - 1)) {
+				pr_err("POW static priorities should be "
+				       "contiguous (0x%llx)\n",
+				     (unsigned long long)prio_mask);
+				return;
+			}
+		}
+
+		cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(core_num), grp_msk.u64);
+	}
+}
+
+/**
+ * Performs a tag switch and then an immediate deschedule. This completes
+ * immediatly, so completion must not be waited for.  This function does NOT
+ * update the wqe in DRAM to match arguments.
+ *
+ * This function does NOT wait for any prior tag switches to complete, so the
+ * calling code must do this.
+ *
+ * Note the following CAVEAT of the Octeon HW behavior when
+ * re-scheduling DE-SCHEDULEd items whose (next) state is
+ * ORDERED:
+ *   - If there are no switches pending at the time that the
+ *     HW executes the de-schedule, the HW will only re-schedule
+ *     the head of the FIFO associated with the given tag. This
+ *     means that in many respects, the HW treats this ORDERED
+ *     tag as an ATOMIC tag. Note that in the SWTAG_DESCH
+ *     case (to an ORDERED tag), the HW will do the switch
+ *     before the deschedule whenever it is possible to do
+ *     the switch immediately, so it may often look like
+ *     this case.
+ *   - If there is a pending switch to ORDERED at the time
+ *     the HW executes the de-schedule, the HW will perform
+ *     the switch at the time it re-schedules, and will be
+ *     able to reschedule any/all of the entries with the
+ *     same tag.
+ * Due to this behavior, the RECOMMENDATION to software is
+ * that they have a (next) state of ATOMIC when they
+ * DE-SCHEDULE. If an ORDERED tag is what was really desired,
+ * SW can choose to immediately switch to an ORDERED tag
+ * after the work (that has an ATOMIC tag) is re-scheduled.
+ * Note that since there are never any tag switches pending
+ * when the HW re-schedules, this switch can be IMMEDIATE upon
+ * the reception of the pointer during the re-schedule.
+ *
+ * @tag:      New tag value
+ * @tag_type: New tag type
+ * @group:    New group value
+ * @no_sched: Control whether this work queue entry will be rescheduled.
+ *                 - 1 : don't schedule this work
+ *                 - 0 : allow this work to be scheduled.
+ */
+static inline void cvmx_pow_tag_sw_desched_nocheck(
+	uint32_t tag,
+	enum cvmx_pow_tag_type tag_type,
+	uint64_t group,
+	uint64_t no_sched)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	if (CVMX_ENABLE_POW_CHECKS) {
+		cvmx_pow_tag_req_t current_tag;
+		__cvmx_pow_warn_if_pending_switch(__func__);
+		current_tag = cvmx_pow_get_current_tag();
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
+			pr_warning("%s called with NULL_NULL tag\n",
+				   __func__);
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called with NULL tag. Deschedule not "
+				   "allowed from NULL state\n",
+			     __func__);
+		if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC)
+			&& (tag_type != CVMX_POW_TAG_TYPE_ATOMIC))
+			pr_warning("%s called where neither the before or "
+				   "after tag is ATOMIC\n",
+			     __func__);
+	}
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_SWTAG_DESCH;
+	tag_req.s.tag = tag;
+	tag_req.s.type = tag_type;
+	tag_req.s.grp = group;
+	tag_req.s.no_sched = no_sched;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
+	/*
+	 * since TAG3 is used, this store will clear the local pending
+	 * switch bit.
+	 */
+	cvmx_write_io(ptr.u64, tag_req.u64);
+}
+
+/**
+ * Performs a tag switch and then an immediate deschedule. This completes
+ * immediatly, so completion must not be waited for.  This function does NOT
+ * update the wqe in DRAM to match arguments.
+ *
+ * This function waits for any prior tag switches to complete, so the
+ * calling code may call this function with a pending tag switch.
+ *
+ * Note the following CAVEAT of the Octeon HW behavior when
+ * re-scheduling DE-SCHEDULEd items whose (next) state is
+ * ORDERED:
+ *   - If there are no switches pending at the time that the
+ *     HW executes the de-schedule, the HW will only re-schedule
+ *     the head of the FIFO associated with the given tag. This
+ *     means that in many respects, the HW treats this ORDERED
+ *     tag as an ATOMIC tag. Note that in the SWTAG_DESCH
+ *     case (to an ORDERED tag), the HW will do the switch
+ *     before the deschedule whenever it is possible to do
+ *     the switch immediately, so it may often look like
+ *     this case.
+ *   - If there is a pending switch to ORDERED at the time
+ *     the HW executes the de-schedule, the HW will perform
+ *     the switch at the time it re-schedules, and will be
+ *     able to reschedule any/all of the entries with the
+ *     same tag.
+ * Due to this behavior, the RECOMMENDATION to software is
+ * that they have a (next) state of ATOMIC when they
+ * DE-SCHEDULE. If an ORDERED tag is what was really desired,
+ * SW can choose to immediately switch to an ORDERED tag
+ * after the work (that has an ATOMIC tag) is re-scheduled.
+ * Note that since there are never any tag switches pending
+ * when the HW re-schedules, this switch can be IMMEDIATE upon
+ * the reception of the pointer during the re-schedule.
+ *
+ * @tag:      New tag value
+ * @tag_type: New tag type
+ * @group:    New group value
+ * @no_sched: Control whether this work queue entry will be rescheduled.
+ *                 - 1 : don't schedule this work
+ *                 - 0 : allow this work to be scheduled.
+ */
+static inline void cvmx_pow_tag_sw_desched(uint32_t tag,
+					   enum cvmx_pow_tag_type tag_type,
+					   uint64_t group, uint64_t no_sched)
+{
+	if (CVMX_ENABLE_POW_CHECKS)
+		__cvmx_pow_warn_if_pending_switch(__func__);
+
+	/* Need to make sure any writes to the work queue entry are complete */
+	CVMX_SYNCWS;
+	/*
+	 * Ensure that there is not a pending tag switch, as a tag
+	 * switch cannot be started if a previous switch is still
+	 * pending.
+	 */
+	cvmx_pow_tag_sw_wait();
+	cvmx_pow_tag_sw_desched_nocheck(tag, tag_type, group, no_sched);
+}
+
+/**
+ * Descchedules the current work queue entry.
+ *
+ * @no_sched: no schedule flag value to be set on the work queue
+ *            entry.  If this is set the entry will not be
+ *            rescheduled.
+ */
+static inline void cvmx_pow_desched(uint64_t no_sched)
+{
+	cvmx_addr_t ptr;
+	cvmx_pow_tag_req_t tag_req;
+
+	if (CVMX_ENABLE_POW_CHECKS) {
+		cvmx_pow_tag_req_t current_tag;
+		__cvmx_pow_warn_if_pending_switch(__func__);
+		current_tag = cvmx_pow_get_current_tag();
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL)
+			pr_warning("%s called with NULL_NULL tag\n",
+				   __func__);
+		if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL)
+			pr_warning("%s called with NULL tag. Deschedule not "
+				   "expected from NULL state\n",
+			     __func__);
+	}
+
+	/* Need to make sure any writes to the work queue entry are complete */
+	CVMX_SYNCWS;
+
+	tag_req.u64 = 0;
+	tag_req.s.op = CVMX_POW_TAG_OP_DESCH;
+	tag_req.s.no_sched = no_sched;
+
+	ptr.u64 = 0;
+	ptr.sio.mem_region = CVMX_IO_SEG;
+	ptr.sio.is_io = 1;
+	ptr.sio.did = CVMX_OCT_DID_TAG_TAG3;
+	/*
+	 * since TAG3 is used, this store will clear the local pending
+	 * switch bit.
+	 */
+	cvmx_write_io(ptr.u64, tag_req.u64);
+}
+
+/****************************************************
+* Define usage of bits within the 32 bit tag values.
+*****************************************************/
+
+/*
+ * Number of bits of the tag used by software.  The SW bits are always
+ * a contiguous block of the high starting at bit 31.  The hardware
+ * bits are always the low bits.  By default, the top 8 bits of the
+ * tag are reserved for software, and the low 24 are set by the IPD
+ * unit.
+ */
+#define CVMX_TAG_SW_BITS    (8)
+#define CVMX_TAG_SW_SHIFT   (32 - CVMX_TAG_SW_BITS)
+
+/* Below is the list of values for the top 8 bits of the tag. */
+/*
+ * Tag values with top byte of this value are reserved for internal
+ * executive uses.
+ */
+#define CVMX_TAG_SW_BITS_INTERNAL  0x1
+/* The executive divides the remaining 24 bits as follows:
+ *  - the upper 8 bits (bits 23 - 16 of the tag) define a subgroup
+ *
+ *  - the lower 16 bits (bits 15 - 0 of the tag) define are the value
+ *    with the subgroup
+ *
+ * Note that this section describes the format of tags generated by
+ * software - refer to the hardware documentation for a description of
+ * the tags values generated by the packet input hardware.  Subgroups
+ * are defined here.
+ */
+/* Mask for the value portion of the tag */
+#define CVMX_TAG_SUBGROUP_MASK  0xFFFF
+#define CVMX_TAG_SUBGROUP_SHIFT 16
+#define CVMX_TAG_SUBGROUP_PKO  0x1
+
+/* End of executive tag subgroup definitions */
+
+/*
+ * The remaining values software bit values 0x2 - 0xff are available
+ * for application use.
+ */
+
+/**
+ * This function creates a 32 bit tag value from the two values provided.
+ *
+ * @sw_bits: The upper bits (number depends on configuration) are set
+ *           to this value.  The remainder of bits are set by the
+ *           hw_bits parameter.
+ *
+ * @hw_bits: The lower bits (number depends on configuration) are set
+ *           to this value.  The remainder of bits are set by the
+ *           sw_bits parameter.
+ *
+ * Returns 32 bit value of the combined hw and sw bits.
+ */
+static inline uint32_t cvmx_pow_tag_compose(uint64_t sw_bits, uint64_t hw_bits)
+{
+	return ((sw_bits & cvmx_build_mask(CVMX_TAG_SW_BITS)) <<
+			CVMX_TAG_SW_SHIFT) |
+		(hw_bits & cvmx_build_mask(32 - CVMX_TAG_SW_BITS));
+}
+
+/**
+ * Extracts the bits allocated for software use from the tag
+ *
+ * @tag:    32 bit tag value
+ *
+ * Returns N bit software tag value, where N is configurable with the
+ * CVMX_TAG_SW_BITS define
+ */
+static inline uint32_t cvmx_pow_tag_get_sw_bits(uint64_t tag)
+{
+	return (tag >> (32 - CVMX_TAG_SW_BITS)) &
+		cvmx_build_mask(CVMX_TAG_SW_BITS);
+}
+
+/**
+ *
+ * Extracts the bits allocated for hardware use from the tag
+ *
+ * @tag:    32 bit tag value
+ *
+ * Returns (32 - N) bit software tag value, where N is configurable
+ * with the CVMX_TAG_SW_BITS define
+ */
+static inline uint32_t cvmx_pow_tag_get_hw_bits(uint64_t tag)
+{
+	return tag & cvmx_build_mask(32 - CVMX_TAG_SW_BITS);
+}
+
+/**
+ * Store the current POW internal state into the supplied
+ * buffer. It is recommended that you pass a buffer of at least
+ * 128KB. The format of the capture may change based on SDK
+ * version and Octeon chip.
+ *
+ * @buffer: Buffer to store capture into
+ * @buffer_size:
+ *               The size of the supplied buffer
+ *
+ * Returns Zero on sucess, negative on failure
+ */
+extern int cvmx_pow_capture(void *buffer, int buffer_size);
+
+/**
+ * Dump a POW capture to the console in a human readable format.
+ *
+ * @buffer: POW capture from cvmx_pow_capture()
+ * @buffer_size:
+ *               Size of the buffer
+ */
+extern void cvmx_pow_display(void *buffer, int buffer_size);
+
+/**
+ * Return the number of POW entries supported by this chip
+ *
+ * Returns Number of POW entries
+ */
+extern int cvmx_pow_get_num_entries(void);
+
+#endif /* __CVMX_POW_H__ */
diff --git a/drivers/staging/octeon/cvmx-scratch.h b/drivers/staging/octeon/cvmx-scratch.h
new file mode 100644
index 0000000..96b70cf
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-scratch.h
@@ -0,0 +1,139 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * This file provides support for the processor local scratch memory.
+ * Scratch memory is byte addressable - all addresses are byte addresses.
+ *
+ */
+
+#ifndef __CVMX_SCRATCH_H__
+#define __CVMX_SCRATCH_H__
+
+/*
+ * Note: This define must be a long, not a long long in order to
+ * compile without warnings for both 32bit and 64bit.
+ */
+#define CVMX_SCRATCH_BASE       (-32768l)	/* 0xffffffffffff8000 */
+
+/**
+ * Reads an 8 bit value from the processor local scratchpad memory.
+ *
+ * @address: byte address to read from
+ *
+ * Returns value read
+ */
+static inline uint8_t cvmx_scratch_read8(uint64_t address)
+{
+	return *CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address);
+}
+
+/**
+ * Reads a 16 bit value from the processor local scratchpad memory.
+ *
+ * @address: byte address to read from
+ *
+ * Returns value read
+ */
+static inline uint16_t cvmx_scratch_read16(uint64_t address)
+{
+	return *CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address);
+}
+
+/**
+ * Reads a 32 bit value from the processor local scratchpad memory.
+ *
+ * @address: byte address to read from
+ *
+ * Returns value read
+ */
+static inline uint32_t cvmx_scratch_read32(uint64_t address)
+{
+	return *CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address);
+}
+
+/**
+ * Reads a 64 bit value from the processor local scratchpad memory.
+ *
+ * @address: byte address to read from
+ *
+ * Returns value read
+ */
+static inline uint64_t cvmx_scratch_read64(uint64_t address)
+{
+	return *CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address);
+}
+
+/**
+ * Writes an 8 bit value to the processor local scratchpad memory.
+ *
+ * @address: byte address to write to
+ * @value:   value to write
+ */
+static inline void cvmx_scratch_write8(uint64_t address, uint64_t value)
+{
+	*CASTPTR(volatile uint8_t, CVMX_SCRATCH_BASE + address) =
+	    (uint8_t) value;
+}
+
+/**
+ * Writes a 32 bit value to the processor local scratchpad memory.
+ *
+ * @address: byte address to write to
+ * @value:   value to write
+ */
+static inline void cvmx_scratch_write16(uint64_t address, uint64_t value)
+{
+	*CASTPTR(volatile uint16_t, CVMX_SCRATCH_BASE + address) =
+	    (uint16_t) value;
+}
+
+/**
+ * Writes a 16 bit value to the processor local scratchpad memory.
+ *
+ * @address: byte address to write to
+ * @value:   value to write
+ */
+static inline void cvmx_scratch_write32(uint64_t address, uint64_t value)
+{
+	*CASTPTR(volatile uint32_t, CVMX_SCRATCH_BASE + address) =
+	    (uint32_t) value;
+}
+
+/**
+ * Writes a 64 bit value to the processor local scratchpad memory.
+ *
+ * @address: byte address to write to
+ * @value:   value to write
+ */
+static inline void cvmx_scratch_write64(uint64_t address, uint64_t value)
+{
+	*CASTPTR(volatile uint64_t, CVMX_SCRATCH_BASE + address) = value;
+}
+
+#endif /* __CVMX_SCRATCH_H__ */
diff --git a/drivers/staging/octeon/cvmx-smix-defs.h b/drivers/staging/octeon/cvmx-smix-defs.h
new file mode 100644
index 0000000..9ae45fc
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-smix-defs.h
@@ -0,0 +1,178 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SMIX_DEFS_H__
+#define __CVMX_SMIX_DEFS_H__
+
+#define CVMX_SMIX_CLK(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_CMD(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_EN(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_RD_DAT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
+#define CVMX_SMIX_WR_DAT(offset) \
+	 CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
+
+union cvmx_smix_clk {
+	uint64_t u64;
+	struct cvmx_smix_clk_s {
+		uint64_t reserved_25_63:39;
+		uint64_t mode:1;
+		uint64_t reserved_21_23:3;
+		uint64_t sample_hi:5;
+		uint64_t sample_mode:1;
+		uint64_t reserved_14_14:1;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} s;
+	struct cvmx_smix_clk_cn30xx {
+		uint64_t reserved_21_63:43;
+		uint64_t sample_hi:5;
+		uint64_t reserved_14_15:2;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} cn30xx;
+	struct cvmx_smix_clk_cn30xx cn31xx;
+	struct cvmx_smix_clk_cn30xx cn38xx;
+	struct cvmx_smix_clk_cn30xx cn38xxp2;
+	struct cvmx_smix_clk_cn50xx {
+		uint64_t reserved_25_63:39;
+		uint64_t mode:1;
+		uint64_t reserved_21_23:3;
+		uint64_t sample_hi:5;
+		uint64_t reserved_14_15:2;
+		uint64_t clk_idle:1;
+		uint64_t preamble:1;
+		uint64_t sample:4;
+		uint64_t phase:8;
+	} cn50xx;
+	struct cvmx_smix_clk_s cn52xx;
+	struct cvmx_smix_clk_cn50xx cn52xxp1;
+	struct cvmx_smix_clk_s cn56xx;
+	struct cvmx_smix_clk_cn50xx cn56xxp1;
+	struct cvmx_smix_clk_cn30xx cn58xx;
+	struct cvmx_smix_clk_cn30xx cn58xxp1;
+};
+
+union cvmx_smix_cmd {
+	uint64_t u64;
+	struct cvmx_smix_cmd_s {
+		uint64_t reserved_18_63:46;
+		uint64_t phy_op:2;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t reg_adr:5;
+	} s;
+	struct cvmx_smix_cmd_cn30xx {
+		uint64_t reserved_17_63:47;
+		uint64_t phy_op:1;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t reg_adr:5;
+	} cn30xx;
+	struct cvmx_smix_cmd_cn30xx cn31xx;
+	struct cvmx_smix_cmd_cn30xx cn38xx;
+	struct cvmx_smix_cmd_cn30xx cn38xxp2;
+	struct cvmx_smix_cmd_s cn50xx;
+	struct cvmx_smix_cmd_s cn52xx;
+	struct cvmx_smix_cmd_s cn52xxp1;
+	struct cvmx_smix_cmd_s cn56xx;
+	struct cvmx_smix_cmd_s cn56xxp1;
+	struct cvmx_smix_cmd_cn30xx cn58xx;
+	struct cvmx_smix_cmd_cn30xx cn58xxp1;
+};
+
+union cvmx_smix_en {
+	uint64_t u64;
+	struct cvmx_smix_en_s {
+		uint64_t reserved_1_63:63;
+		uint64_t en:1;
+	} s;
+	struct cvmx_smix_en_s cn30xx;
+	struct cvmx_smix_en_s cn31xx;
+	struct cvmx_smix_en_s cn38xx;
+	struct cvmx_smix_en_s cn38xxp2;
+	struct cvmx_smix_en_s cn50xx;
+	struct cvmx_smix_en_s cn52xx;
+	struct cvmx_smix_en_s cn52xxp1;
+	struct cvmx_smix_en_s cn56xx;
+	struct cvmx_smix_en_s cn56xxp1;
+	struct cvmx_smix_en_s cn58xx;
+	struct cvmx_smix_en_s cn58xxp1;
+};
+
+union cvmx_smix_rd_dat {
+	uint64_t u64;
+	struct cvmx_smix_rd_dat_s {
+		uint64_t reserved_18_63:46;
+		uint64_t pending:1;
+		uint64_t val:1;
+		uint64_t dat:16;
+	} s;
+	struct cvmx_smix_rd_dat_s cn30xx;
+	struct cvmx_smix_rd_dat_s cn31xx;
+	struct cvmx_smix_rd_dat_s cn38xx;
+	struct cvmx_smix_rd_dat_s cn38xxp2;
+	struct cvmx_smix_rd_dat_s cn50xx;
+	struct cvmx_smix_rd_dat_s cn52xx;
+	struct cvmx_smix_rd_dat_s cn52xxp1;
+	struct cvmx_smix_rd_dat_s cn56xx;
+	struct cvmx_smix_rd_dat_s cn56xxp1;
+	struct cvmx_smix_rd_dat_s cn58xx;
+	struct cvmx_smix_rd_dat_s cn58xxp1;
+};
+
+union cvmx_smix_wr_dat {
+	uint64_t u64;
+	struct cvmx_smix_wr_dat_s {
+		uint64_t reserved_18_63:46;
+		uint64_t pending:1;
+		uint64_t val:1;
+		uint64_t dat:16;
+	} s;
+	struct cvmx_smix_wr_dat_s cn30xx;
+	struct cvmx_smix_wr_dat_s cn31xx;
+	struct cvmx_smix_wr_dat_s cn38xx;
+	struct cvmx_smix_wr_dat_s cn38xxp2;
+	struct cvmx_smix_wr_dat_s cn50xx;
+	struct cvmx_smix_wr_dat_s cn52xx;
+	struct cvmx_smix_wr_dat_s cn52xxp1;
+	struct cvmx_smix_wr_dat_s cn56xx;
+	struct cvmx_smix_wr_dat_s cn56xxp1;
+	struct cvmx_smix_wr_dat_s cn58xx;
+	struct cvmx_smix_wr_dat_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-spi.c b/drivers/staging/octeon/cvmx-spi.c
new file mode 100644
index 0000000..82794d9
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-spi.c
@@ -0,0 +1,667 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Support library for the SPI
+ */
+#include <asm/octeon/octeon.h>
+
+#include "cvmx-config.h"
+
+#include "cvmx-pko.h"
+#include "cvmx-spi.h"
+
+#include "cvmx-spxx-defs.h"
+#include "cvmx-stxx-defs.h"
+#include "cvmx-srxx-defs.h"
+
+#define INVOKE_CB(function_p, args...)		\
+	do {					\
+		if (function_p) {		\
+			res = function_p(args); \
+			if (res)		\
+				return res;	\
+		}				\
+	} while (0)
+
+#if CVMX_ENABLE_DEBUG_PRINTS
+static const char *modes[] =
+    { "UNKNOWN", "TX Halfplex", "Rx Halfplex", "Duplex" };
+#endif
+
+/* Default callbacks, can be overridden
+ *  using cvmx_spi_get_callbacks/cvmx_spi_set_callbacks
+ */
+static cvmx_spi_callbacks_t cvmx_spi_callbacks = {
+	.reset_cb = cvmx_spi_reset_cb,
+	.calendar_setup_cb = cvmx_spi_calendar_setup_cb,
+	.clock_detect_cb = cvmx_spi_clock_detect_cb,
+	.training_cb = cvmx_spi_training_cb,
+	.calendar_sync_cb = cvmx_spi_calendar_sync_cb,
+	.interface_up_cb = cvmx_spi_interface_up_cb
+};
+
+/**
+ * Get current SPI4 initialization callbacks
+ *
+ * @callbacks:  Pointer to the callbacks structure.to fill
+ *
+ * Returns Pointer to cvmx_spi_callbacks_t structure.
+ */
+void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks)
+{
+	memcpy(callbacks, &cvmx_spi_callbacks, sizeof(cvmx_spi_callbacks));
+}
+
+/**
+ * Set new SPI4 initialization callbacks
+ *
+ * @new_callbacks:  Pointer to an updated callbacks structure.
+ */
+void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks)
+{
+	memcpy(&cvmx_spi_callbacks, new_callbacks, sizeof(cvmx_spi_callbacks));
+}
+
+/**
+ * Initialize and start the SPI interface.
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ * @num_ports: Number of SPI ports to configure
+ *
+ * Returns Zero on success, negative of failure.
+ */
+int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode, int timeout,
+			     int num_ports)
+{
+	int res = -1;
+
+	if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
+		return res;
+
+	/* Callback to perform SPI4 reset */
+	INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
+
+	/* Callback to perform calendar setup */
+	INVOKE_CB(cvmx_spi_callbacks.calendar_setup_cb, interface, mode,
+		  num_ports);
+
+	/* Callback to perform clock detection */
+	INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
+
+	/* Callback to perform SPI4 link training */
+	INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
+
+	/* Callback to perform calendar sync */
+	INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
+		  timeout);
+
+	/* Callback to handle interface coming up */
+	INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
+
+	return res;
+}
+
+/**
+ * This routine restarts the SPI interface after it has lost synchronization
+ * with its correspondent system.
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ *
+ * Returns Zero on success, negative of failure.
+ */
+int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
+{
+	int res = -1;
+
+	if (!(OCTEON_IS_MODEL(OCTEON_CN38XX) || OCTEON_IS_MODEL(OCTEON_CN58XX)))
+		return res;
+
+	cvmx_dprintf("SPI%d: Restart %s\n", interface, modes[mode]);
+
+	/* Callback to perform SPI4 reset */
+	INVOKE_CB(cvmx_spi_callbacks.reset_cb, interface, mode);
+
+	/* NOTE: Calendar setup is not performed during restart */
+	/*       Refer to cvmx_spi_start_interface() for the full sequence */
+
+	/* Callback to perform clock detection */
+	INVOKE_CB(cvmx_spi_callbacks.clock_detect_cb, interface, mode, timeout);
+
+	/* Callback to perform SPI4 link training */
+	INVOKE_CB(cvmx_spi_callbacks.training_cb, interface, mode, timeout);
+
+	/* Callback to perform calendar sync */
+	INVOKE_CB(cvmx_spi_callbacks.calendar_sync_cb, interface, mode,
+		  timeout);
+
+	/* Callback to handle interface coming up */
+	INVOKE_CB(cvmx_spi_callbacks.interface_up_cb, interface, mode);
+
+	return res;
+}
+
+/**
+ * Callback to perform SPI4 reset
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode)
+{
+	union cvmx_spxx_dbg_deskew_ctl spxx_dbg_deskew_ctl;
+	union cvmx_spxx_clk_ctl spxx_clk_ctl;
+	union cvmx_spxx_bist_stat spxx_bist_stat;
+	union cvmx_spxx_int_msk spxx_int_msk;
+	union cvmx_stxx_int_msk stxx_int_msk;
+	union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
+	int index;
+	uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
+
+	/* Disable SPI error events while we run BIST */
+	spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
+	cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
+	stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
+	cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
+
+	/* Run BIST in the SPI interface */
+	cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), 0);
+	cvmx_write_csr(CVMX_STXX_COM_CTL(interface), 0);
+	spxx_clk_ctl.u64 = 0;
+	spxx_clk_ctl.s.runbist = 1;
+	cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
+	cvmx_wait(10 * MS);
+	spxx_bist_stat.u64 = cvmx_read_csr(CVMX_SPXX_BIST_STAT(interface));
+	if (spxx_bist_stat.s.stat0)
+		cvmx_dprintf
+		    ("ERROR SPI%d: BIST failed on receive datapath FIFO\n",
+		     interface);
+	if (spxx_bist_stat.s.stat1)
+		cvmx_dprintf("ERROR SPI%d: BIST failed on RX calendar table\n",
+			     interface);
+	if (spxx_bist_stat.s.stat2)
+		cvmx_dprintf("ERROR SPI%d: BIST failed on TX calendar table\n",
+			     interface);
+
+	/* Clear the calendar table after BIST to fix parity errors */
+	for (index = 0; index < 32; index++) {
+		union cvmx_srxx_spi4_calx srxx_spi4_calx;
+		union cvmx_stxx_spi4_calx stxx_spi4_calx;
+
+		srxx_spi4_calx.u64 = 0;
+		srxx_spi4_calx.s.oddpar = 1;
+		cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
+			       srxx_spi4_calx.u64);
+
+		stxx_spi4_calx.u64 = 0;
+		stxx_spi4_calx.s.oddpar = 1;
+		cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
+			       stxx_spi4_calx.u64);
+	}
+
+	/* Re enable reporting of error interrupts */
+	cvmx_write_csr(CVMX_SPXX_INT_REG(interface),
+		       cvmx_read_csr(CVMX_SPXX_INT_REG(interface)));
+	cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
+	cvmx_write_csr(CVMX_STXX_INT_REG(interface),
+		       cvmx_read_csr(CVMX_STXX_INT_REG(interface)));
+	cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
+
+	/* Setup the CLKDLY right in the middle */
+	spxx_clk_ctl.u64 = 0;
+	spxx_clk_ctl.s.seetrn = 0;
+	spxx_clk_ctl.s.clkdly = 0x10;
+	spxx_clk_ctl.s.runbist = 0;
+	spxx_clk_ctl.s.statdrv = 0;
+	/* This should always be on the opposite edge as statdrv */
+	spxx_clk_ctl.s.statrcv = 1;
+	spxx_clk_ctl.s.sndtrn = 0;
+	spxx_clk_ctl.s.drptrn = 0;
+	spxx_clk_ctl.s.rcvtrn = 0;
+	spxx_clk_ctl.s.srxdlck = 0;
+	cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
+	cvmx_wait(100 * MS);
+
+	/* Reset SRX0 DLL */
+	spxx_clk_ctl.s.srxdlck = 1;
+	cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
+
+	/* Waiting for Inf0 Spi4 RX DLL to lock */
+	cvmx_wait(100 * MS);
+
+	/* Enable dynamic alignment */
+	spxx_trn4_ctl.s.trntest = 0;
+	spxx_trn4_ctl.s.jitter = 1;
+	spxx_trn4_ctl.s.clr_boot = 1;
+	spxx_trn4_ctl.s.set_boot = 0;
+	if (OCTEON_IS_MODEL(OCTEON_CN58XX))
+		spxx_trn4_ctl.s.maxdist = 3;
+	else
+		spxx_trn4_ctl.s.maxdist = 8;
+	spxx_trn4_ctl.s.macro_en = 1;
+	spxx_trn4_ctl.s.mux_en = 1;
+	cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
+
+	spxx_dbg_deskew_ctl.u64 = 0;
+	cvmx_write_csr(CVMX_SPXX_DBG_DESKEW_CTL(interface),
+		       spxx_dbg_deskew_ctl.u64);
+
+	return 0;
+}
+
+/**
+ * Callback to setup calendar and miscellaneous settings before clock detection
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @num_ports: Number of ports to configure on SPI
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
+			       int num_ports)
+{
+	int port;
+	int index;
+	if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
+		union cvmx_srxx_com_ctl srxx_com_ctl;
+		union cvmx_srxx_spi4_stat srxx_spi4_stat;
+
+		/* SRX0 number of Ports */
+		srxx_com_ctl.u64 = 0;
+		srxx_com_ctl.s.prts = num_ports - 1;
+		srxx_com_ctl.s.st_en = 0;
+		srxx_com_ctl.s.inf_en = 0;
+		cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
+
+		/* SRX0 Calendar Table. This round robbins through all ports */
+		port = 0;
+		index = 0;
+		while (port < num_ports) {
+			union cvmx_srxx_spi4_calx srxx_spi4_calx;
+			srxx_spi4_calx.u64 = 0;
+			srxx_spi4_calx.s.prt0 = port++;
+			srxx_spi4_calx.s.prt1 = port++;
+			srxx_spi4_calx.s.prt2 = port++;
+			srxx_spi4_calx.s.prt3 = port++;
+			srxx_spi4_calx.s.oddpar =
+			    ~(cvmx_dpop(srxx_spi4_calx.u64) & 1);
+			cvmx_write_csr(CVMX_SRXX_SPI4_CALX(index, interface),
+				       srxx_spi4_calx.u64);
+			index++;
+		}
+		srxx_spi4_stat.u64 = 0;
+		srxx_spi4_stat.s.len = num_ports;
+		srxx_spi4_stat.s.m = 1;
+		cvmx_write_csr(CVMX_SRXX_SPI4_STAT(interface),
+			       srxx_spi4_stat.u64);
+	}
+
+	if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
+		union cvmx_stxx_arb_ctl stxx_arb_ctl;
+		union cvmx_gmxx_tx_spi_max gmxx_tx_spi_max;
+		union cvmx_gmxx_tx_spi_thresh gmxx_tx_spi_thresh;
+		union cvmx_gmxx_tx_spi_ctl gmxx_tx_spi_ctl;
+		union cvmx_stxx_spi4_stat stxx_spi4_stat;
+		union cvmx_stxx_spi4_dat stxx_spi4_dat;
+
+		/* STX0 Config */
+		stxx_arb_ctl.u64 = 0;
+		stxx_arb_ctl.s.igntpa = 0;
+		stxx_arb_ctl.s.mintrn = 0;
+		cvmx_write_csr(CVMX_STXX_ARB_CTL(interface), stxx_arb_ctl.u64);
+
+		gmxx_tx_spi_max.u64 = 0;
+		gmxx_tx_spi_max.s.max1 = 8;
+		gmxx_tx_spi_max.s.max2 = 4;
+		gmxx_tx_spi_max.s.slice = 0;
+		cvmx_write_csr(CVMX_GMXX_TX_SPI_MAX(interface),
+			       gmxx_tx_spi_max.u64);
+
+		gmxx_tx_spi_thresh.u64 = 0;
+		gmxx_tx_spi_thresh.s.thresh = 4;
+		cvmx_write_csr(CVMX_GMXX_TX_SPI_THRESH(interface),
+			       gmxx_tx_spi_thresh.u64);
+
+		gmxx_tx_spi_ctl.u64 = 0;
+		gmxx_tx_spi_ctl.s.tpa_clr = 0;
+		gmxx_tx_spi_ctl.s.cont_pkt = 0;
+		cvmx_write_csr(CVMX_GMXX_TX_SPI_CTL(interface),
+			       gmxx_tx_spi_ctl.u64);
+
+		/* STX0 Training Control */
+		stxx_spi4_dat.u64 = 0;
+		/*Minimum needed by dynamic alignment */
+		stxx_spi4_dat.s.alpha = 32;
+		stxx_spi4_dat.s.max_t = 0xFFFF;	/*Minimum interval is 0x20 */
+		cvmx_write_csr(CVMX_STXX_SPI4_DAT(interface),
+			       stxx_spi4_dat.u64);
+
+		/* STX0 Calendar Table. This round robbins through all ports */
+		port = 0;
+		index = 0;
+		while (port < num_ports) {
+			union cvmx_stxx_spi4_calx stxx_spi4_calx;
+			stxx_spi4_calx.u64 = 0;
+			stxx_spi4_calx.s.prt0 = port++;
+			stxx_spi4_calx.s.prt1 = port++;
+			stxx_spi4_calx.s.prt2 = port++;
+			stxx_spi4_calx.s.prt3 = port++;
+			stxx_spi4_calx.s.oddpar =
+			    ~(cvmx_dpop(stxx_spi4_calx.u64) & 1);
+			cvmx_write_csr(CVMX_STXX_SPI4_CALX(index, interface),
+				       stxx_spi4_calx.u64);
+			index++;
+		}
+		stxx_spi4_stat.u64 = 0;
+		stxx_spi4_stat.s.len = num_ports;
+		stxx_spi4_stat.s.m = 1;
+		cvmx_write_csr(CVMX_STXX_SPI4_STAT(interface),
+			       stxx_spi4_stat.u64);
+	}
+
+	return 0;
+}
+
+/**
+ * Callback to perform clock detection
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+{
+	int clock_transitions;
+	union cvmx_spxx_clk_stat stat;
+	uint64_t timeout_time;
+	uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
+
+	/*
+	 * Regardless of operating mode, both Tx and Rx clocks must be
+	 * present for the SPI interface to operate.
+	 */
+	cvmx_dprintf("SPI%d: Waiting to see TsClk...\n", interface);
+	timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
+	/*
+	 * Require 100 clock transitions in order to avoid any noise
+	 * in the beginning.
+	 */
+	clock_transitions = 100;
+	do {
+		stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
+		if (stat.s.s4clk0 && stat.s.s4clk1 && clock_transitions) {
+			/*
+			 * We've seen a clock transition, so decrement
+			 * the number we still need.
+			 */
+			clock_transitions--;
+			cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
+			stat.s.s4clk0 = 0;
+			stat.s.s4clk1 = 0;
+		}
+		if (cvmx_get_cycle() > timeout_time) {
+			cvmx_dprintf("SPI%d: Timeout\n", interface);
+			return -1;
+		}
+	} while (stat.s.s4clk0 == 0 || stat.s.s4clk1 == 0);
+
+	cvmx_dprintf("SPI%d: Waiting to see RsClk...\n", interface);
+	timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
+	/*
+	 * Require 100 clock transitions in order to avoid any noise in the
+	 * beginning.
+	 */
+	clock_transitions = 100;
+	do {
+		stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
+		if (stat.s.d4clk0 && stat.s.d4clk1 && clock_transitions) {
+			/*
+			 * We've seen a clock transition, so decrement
+			 * the number we still need
+			 */
+			clock_transitions--;
+			cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
+			stat.s.d4clk0 = 0;
+			stat.s.d4clk1 = 0;
+		}
+		if (cvmx_get_cycle() > timeout_time) {
+			cvmx_dprintf("SPI%d: Timeout\n", interface);
+			return -1;
+		}
+	} while (stat.s.d4clk0 == 0 || stat.s.d4clk1 == 0);
+
+	return 0;
+}
+
+/**
+ * Callback to perform link training
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for link to be trained (in seconds)
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+{
+	union cvmx_spxx_trn4_ctl spxx_trn4_ctl;
+	union cvmx_spxx_clk_stat stat;
+	uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
+	uint64_t timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
+	int rx_training_needed;
+
+	/* SRX0 & STX0 Inf0 Links are configured - begin training */
+	union cvmx_spxx_clk_ctl spxx_clk_ctl;
+	spxx_clk_ctl.u64 = 0;
+	spxx_clk_ctl.s.seetrn = 0;
+	spxx_clk_ctl.s.clkdly = 0x10;
+	spxx_clk_ctl.s.runbist = 0;
+	spxx_clk_ctl.s.statdrv = 0;
+	/* This should always be on the opposite edge as statdrv */
+	spxx_clk_ctl.s.statrcv = 1;
+	spxx_clk_ctl.s.sndtrn = 1;
+	spxx_clk_ctl.s.drptrn = 1;
+	spxx_clk_ctl.s.rcvtrn = 1;
+	spxx_clk_ctl.s.srxdlck = 1;
+	cvmx_write_csr(CVMX_SPXX_CLK_CTL(interface), spxx_clk_ctl.u64);
+	cvmx_wait(1000 * MS);
+
+	/* SRX0 clear the boot bit */
+	spxx_trn4_ctl.u64 = cvmx_read_csr(CVMX_SPXX_TRN4_CTL(interface));
+	spxx_trn4_ctl.s.clr_boot = 1;
+	cvmx_write_csr(CVMX_SPXX_TRN4_CTL(interface), spxx_trn4_ctl.u64);
+
+	/* Wait for the training sequence to complete */
+	cvmx_dprintf("SPI%d: Waiting for training\n", interface);
+	cvmx_wait(1000 * MS);
+	/* Wait a really long time here */
+	timeout_time = cvmx_get_cycle() + 1000ull * MS * 600;
+	/*
+	 * The HRM says we must wait for 34 + 16 * MAXDIST training sequences.
+	 * We'll be pessimistic and wait for a lot more.
+	 */
+	rx_training_needed = 500;
+	do {
+		stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
+		if (stat.s.srxtrn && rx_training_needed) {
+			rx_training_needed--;
+			cvmx_write_csr(CVMX_SPXX_CLK_STAT(interface), stat.u64);
+			stat.s.srxtrn = 0;
+		}
+		if (cvmx_get_cycle() > timeout_time) {
+			cvmx_dprintf("SPI%d: Timeout\n", interface);
+			return -1;
+		}
+	} while (stat.s.srxtrn == 0);
+
+	return 0;
+}
+
+/**
+ * Callback to perform calendar data synchronization
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for calendar data in seconds
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode, int timeout)
+{
+	uint64_t MS = cvmx_sysinfo_get()->cpu_clock_hz / 1000;
+	if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
+		/* SRX0 interface should be good, send calendar data */
+		union cvmx_srxx_com_ctl srxx_com_ctl;
+		cvmx_dprintf
+		    ("SPI%d: Rx is synchronized, start sending calendar data\n",
+		     interface);
+		srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
+		srxx_com_ctl.s.inf_en = 1;
+		srxx_com_ctl.s.st_en = 1;
+		cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
+	}
+
+	if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
+		/* STX0 has achieved sync */
+		/* The corespondant board should be sending calendar data */
+		/* Enable the STX0 STAT receiver. */
+		union cvmx_spxx_clk_stat stat;
+		uint64_t timeout_time;
+		union cvmx_stxx_com_ctl stxx_com_ctl;
+		stxx_com_ctl.u64 = 0;
+		stxx_com_ctl.s.st_en = 1;
+		cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
+
+		/* Waiting for calendar sync on STX0 STAT */
+		cvmx_dprintf("SPI%d: Waiting to sync on STX[%d] STAT\n",
+			     interface, interface);
+		timeout_time = cvmx_get_cycle() + 1000ull * MS * timeout;
+		/* SPX0_CLK_STAT - SPX0_CLK_STAT[STXCAL] should be 1 (bit10) */
+		do {
+			stat.u64 = cvmx_read_csr(CVMX_SPXX_CLK_STAT(interface));
+			if (cvmx_get_cycle() > timeout_time) {
+				cvmx_dprintf("SPI%d: Timeout\n", interface);
+				return -1;
+			}
+		} while (stat.s.stxcal == 0);
+	}
+
+	return 0;
+}
+
+/**
+ * Callback to handle interface up
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode)
+{
+	union cvmx_gmxx_rxx_frm_min gmxx_rxx_frm_min;
+	union cvmx_gmxx_rxx_frm_max gmxx_rxx_frm_max;
+	union cvmx_gmxx_rxx_jabber gmxx_rxx_jabber;
+
+	if (mode & CVMX_SPI_MODE_RX_HALFPLEX) {
+		union cvmx_srxx_com_ctl srxx_com_ctl;
+		srxx_com_ctl.u64 = cvmx_read_csr(CVMX_SRXX_COM_CTL(interface));
+		srxx_com_ctl.s.inf_en = 1;
+		cvmx_write_csr(CVMX_SRXX_COM_CTL(interface), srxx_com_ctl.u64);
+		cvmx_dprintf("SPI%d: Rx is now up\n", interface);
+	}
+
+	if (mode & CVMX_SPI_MODE_TX_HALFPLEX) {
+		union cvmx_stxx_com_ctl stxx_com_ctl;
+		stxx_com_ctl.u64 = cvmx_read_csr(CVMX_STXX_COM_CTL(interface));
+		stxx_com_ctl.s.inf_en = 1;
+		cvmx_write_csr(CVMX_STXX_COM_CTL(interface), stxx_com_ctl.u64);
+		cvmx_dprintf("SPI%d: Tx is now up\n", interface);
+	}
+
+	gmxx_rxx_frm_min.u64 = 0;
+	gmxx_rxx_frm_min.s.len = 64;
+	cvmx_write_csr(CVMX_GMXX_RXX_FRM_MIN(0, interface),
+		       gmxx_rxx_frm_min.u64);
+	gmxx_rxx_frm_max.u64 = 0;
+	gmxx_rxx_frm_max.s.len = 64 * 1024 - 4;
+	cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(0, interface),
+		       gmxx_rxx_frm_max.u64);
+	gmxx_rxx_jabber.u64 = 0;
+	gmxx_rxx_jabber.s.cnt = 64 * 1024 - 4;
+	cvmx_write_csr(CVMX_GMXX_RXX_JABBER(0, interface), gmxx_rxx_jabber.u64);
+
+	return 0;
+}
diff --git a/drivers/staging/octeon/cvmx-spi.h b/drivers/staging/octeon/cvmx-spi.h
new file mode 100644
index 0000000..e814648
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-spi.h
@@ -0,0 +1,269 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * This file contains defines for the SPI interface
+ */
+#ifndef __CVMX_SPI_H__
+#define __CVMX_SPI_H__
+
+#include "cvmx-gmxx-defs.h"
+
+/* CSR typedefs have been moved to cvmx-csr-*.h */
+
+typedef enum {
+	CVMX_SPI_MODE_UNKNOWN = 0,
+	CVMX_SPI_MODE_TX_HALFPLEX = 1,
+	CVMX_SPI_MODE_RX_HALFPLEX = 2,
+	CVMX_SPI_MODE_DUPLEX = 3
+} cvmx_spi_mode_t;
+
+/** Callbacks structure to customize SPI4 initialization sequence */
+typedef struct {
+    /** Called to reset SPI4 DLL */
+	int (*reset_cb) (int interface, cvmx_spi_mode_t mode);
+
+    /** Called to setup calendar */
+	int (*calendar_setup_cb) (int interface, cvmx_spi_mode_t mode,
+				  int num_ports);
+
+    /** Called for Tx and Rx clock detection */
+	int (*clock_detect_cb) (int interface, cvmx_spi_mode_t mode,
+				int timeout);
+
+    /** Called to perform link training */
+	int (*training_cb) (int interface, cvmx_spi_mode_t mode, int timeout);
+
+    /** Called for calendar data synchronization */
+	int (*calendar_sync_cb) (int interface, cvmx_spi_mode_t mode,
+				 int timeout);
+
+    /** Called when interface is up */
+	int (*interface_up_cb) (int interface, cvmx_spi_mode_t mode);
+
+} cvmx_spi_callbacks_t;
+
+/**
+ * Return true if the supplied interface is configured for SPI
+ *
+ * @interface: Interface to check
+ * Returns True if interface is SPI
+ */
+static inline int cvmx_spi_is_spi_interface(int interface)
+{
+	uint64_t gmxState = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+	return (gmxState & 0x2) && (gmxState & 0x1);
+}
+
+/**
+ * Initialize and start the SPI interface.
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ * @num_ports: Number of SPI ports to configure
+ *
+ * Returns Zero on success, negative of failure.
+ */
+extern int cvmx_spi_start_interface(int interface, cvmx_spi_mode_t mode,
+				    int timeout, int num_ports);
+
+/**
+ * This routine restarts the SPI interface after it has lost synchronization
+ * with its corespondant system.
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ * Returns Zero on success, negative of failure.
+ */
+extern int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode,
+				      int timeout);
+
+/**
+ * Return non-zero if the SPI interface has a SPI4000 attached
+ *
+ * @interface: SPI interface the SPI4000 is connected to
+ *
+ * Returns
+ */
+static inline int cvmx_spi4000_is_present(int interface)
+{
+	return 0;
+}
+
+/**
+ * Initialize the SPI4000 for use
+ *
+ * @interface: SPI interface the SPI4000 is connected to
+ */
+static inline int cvmx_spi4000_initialize(int interface)
+{
+	return 0;
+}
+
+/**
+ * Poll all the SPI4000 port and check its speed
+ *
+ * @interface: Interface the SPI4000 is on
+ * @port:      Port to poll (0-9)
+ * Returns Status of the port. 0=down. All other values the port is up.
+ */
+static inline union cvmx_gmxx_rxx_rx_inbnd cvmx_spi4000_check_speed(
+	int interface,
+	int port)
+{
+	union cvmx_gmxx_rxx_rx_inbnd r;
+	r.u64 = 0;
+	return r;
+}
+
+/**
+ * Get current SPI4 initialization callbacks
+ *
+ * @callbacks:  Pointer to the callbacks structure.to fill
+ *
+ * Returns Pointer to cvmx_spi_callbacks_t structure.
+ */
+extern void cvmx_spi_get_callbacks(cvmx_spi_callbacks_t *callbacks);
+
+/**
+ * Set new SPI4 initialization callbacks
+ *
+ * @new_callbacks:  Pointer to an updated callbacks structure.
+ */
+extern void cvmx_spi_set_callbacks(cvmx_spi_callbacks_t *new_callbacks);
+
+/**
+ * Callback to perform SPI4 reset
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_reset_cb(int interface, cvmx_spi_mode_t mode);
+
+/**
+ * Callback to setup calendar and miscellaneous settings before clock
+ * detection
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @num_ports: Number of ports to configure on SPI
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_calendar_setup_cb(int interface, cvmx_spi_mode_t mode,
+				      int num_ports);
+
+/**
+ * Callback to perform clock detection
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for clock synchronization in seconds
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_clock_detect_cb(int interface, cvmx_spi_mode_t mode,
+				    int timeout);
+
+/**
+ * Callback to perform link training
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for link to be trained (in seconds)
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_training_cb(int interface, cvmx_spi_mode_t mode,
+				int timeout);
+
+/**
+ * Callback to perform calendar data synchronization
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ * @timeout:   Timeout to wait for calendar data in seconds
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_calendar_sync_cb(int interface, cvmx_spi_mode_t mode,
+				     int timeout);
+
+/**
+ * Callback to handle interface up
+ *
+ * @interface: The identifier of the packet interface to configure and
+ *                  use as a SPI interface.
+ * @mode:      The operating mode for the SPI interface. The interface
+ *                  can operate as a full duplex (both Tx and Rx data paths
+ *                  active) or as a halfplex (either the Tx data path is
+ *                  active or the Rx data path is active, but not both).
+ *
+ * Returns Zero on success, non-zero error code on failure (will cause
+ * SPI initialization to abort)
+ */
+extern int cvmx_spi_interface_up_cb(int interface, cvmx_spi_mode_t mode);
+
+#endif /* __CVMX_SPI_H__ */
diff --git a/drivers/staging/octeon/cvmx-spxx-defs.h b/drivers/staging/octeon/cvmx-spxx-defs.h
new file mode 100644
index 0000000..b16940e
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-spxx-defs.h
@@ -0,0 +1,347 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SPXX_DEFS_H__
+#define __CVMX_SPXX_DEFS_H__
+
+#define CVMX_SPXX_BCKPRS_CNT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_BIST_STAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_CLK_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_CLK_STAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_DRV_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_ERR_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_INT_DAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_INT_MSK(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_INT_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_INT_SYNC(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_TPA_ACC(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_TPA_MAX(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_TPA_SEL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_TRN4_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_spxx_bckprs_cnt {
+	uint64_t u64;
+	struct cvmx_spxx_bckprs_cnt_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_spxx_bckprs_cnt_s cn38xx;
+	struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
+	struct cvmx_spxx_bckprs_cnt_s cn58xx;
+	struct cvmx_spxx_bckprs_cnt_s cn58xxp1;
+};
+
+union cvmx_spxx_bist_stat {
+	uint64_t u64;
+	struct cvmx_spxx_bist_stat_s {
+		uint64_t reserved_3_63:61;
+		uint64_t stat2:1;
+		uint64_t stat1:1;
+		uint64_t stat0:1;
+	} s;
+	struct cvmx_spxx_bist_stat_s cn38xx;
+	struct cvmx_spxx_bist_stat_s cn38xxp2;
+	struct cvmx_spxx_bist_stat_s cn58xx;
+	struct cvmx_spxx_bist_stat_s cn58xxp1;
+};
+
+union cvmx_spxx_clk_ctl {
+	uint64_t u64;
+	struct cvmx_spxx_clk_ctl_s {
+		uint64_t reserved_17_63:47;
+		uint64_t seetrn:1;
+		uint64_t reserved_12_15:4;
+		uint64_t clkdly:5;
+		uint64_t runbist:1;
+		uint64_t statdrv:1;
+		uint64_t statrcv:1;
+		uint64_t sndtrn:1;
+		uint64_t drptrn:1;
+		uint64_t rcvtrn:1;
+		uint64_t srxdlck:1;
+	} s;
+	struct cvmx_spxx_clk_ctl_s cn38xx;
+	struct cvmx_spxx_clk_ctl_s cn38xxp2;
+	struct cvmx_spxx_clk_ctl_s cn58xx;
+	struct cvmx_spxx_clk_ctl_s cn58xxp1;
+};
+
+union cvmx_spxx_clk_stat {
+	uint64_t u64;
+	struct cvmx_spxx_clk_stat_s {
+		uint64_t reserved_11_63:53;
+		uint64_t stxcal:1;
+		uint64_t reserved_9_9:1;
+		uint64_t srxtrn:1;
+		uint64_t s4clk1:1;
+		uint64_t s4clk0:1;
+		uint64_t d4clk1:1;
+		uint64_t d4clk0:1;
+		uint64_t reserved_0_3:4;
+	} s;
+	struct cvmx_spxx_clk_stat_s cn38xx;
+	struct cvmx_spxx_clk_stat_s cn38xxp2;
+	struct cvmx_spxx_clk_stat_s cn58xx;
+	struct cvmx_spxx_clk_stat_s cn58xxp1;
+};
+
+union cvmx_spxx_dbg_deskew_ctl {
+	uint64_t u64;
+	struct cvmx_spxx_dbg_deskew_ctl_s {
+		uint64_t reserved_30_63:34;
+		uint64_t fallnop:1;
+		uint64_t fall8:1;
+		uint64_t reserved_26_27:2;
+		uint64_t sstep_go:1;
+		uint64_t sstep:1;
+		uint64_t reserved_22_23:2;
+		uint64_t clrdly:1;
+		uint64_t dec:1;
+		uint64_t inc:1;
+		uint64_t mux:1;
+		uint64_t offset:5;
+		uint64_t bitsel:5;
+		uint64_t offdly:6;
+		uint64_t dllfrc:1;
+		uint64_t dlldis:1;
+	} s;
+	struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
+	struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
+	struct cvmx_spxx_dbg_deskew_ctl_s cn58xx;
+	struct cvmx_spxx_dbg_deskew_ctl_s cn58xxp1;
+};
+
+union cvmx_spxx_dbg_deskew_state {
+	uint64_t u64;
+	struct cvmx_spxx_dbg_deskew_state_s {
+		uint64_t reserved_9_63:55;
+		uint64_t testres:1;
+		uint64_t unxterm:1;
+		uint64_t muxsel:2;
+		uint64_t offset:5;
+	} s;
+	struct cvmx_spxx_dbg_deskew_state_s cn38xx;
+	struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
+	struct cvmx_spxx_dbg_deskew_state_s cn58xx;
+	struct cvmx_spxx_dbg_deskew_state_s cn58xxp1;
+};
+
+union cvmx_spxx_drv_ctl {
+	uint64_t u64;
+	struct cvmx_spxx_drv_ctl_s {
+		uint64_t reserved_0_63:64;
+	} s;
+	struct cvmx_spxx_drv_ctl_cn38xx {
+		uint64_t reserved_16_63:48;
+		uint64_t stx4ncmp:4;
+		uint64_t stx4pcmp:4;
+		uint64_t srx4cmp:8;
+	} cn38xx;
+	struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
+	struct cvmx_spxx_drv_ctl_cn58xx {
+		uint64_t reserved_24_63:40;
+		uint64_t stx4ncmp:4;
+		uint64_t stx4pcmp:4;
+		uint64_t reserved_10_15:6;
+		uint64_t srx4cmp:10;
+	} cn58xx;
+	struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
+};
+
+union cvmx_spxx_err_ctl {
+	uint64_t u64;
+	struct cvmx_spxx_err_ctl_s {
+		uint64_t reserved_9_63:55;
+		uint64_t prtnxa:1;
+		uint64_t dipcls:1;
+		uint64_t dippay:1;
+		uint64_t reserved_4_5:2;
+		uint64_t errcnt:4;
+	} s;
+	struct cvmx_spxx_err_ctl_s cn38xx;
+	struct cvmx_spxx_err_ctl_s cn38xxp2;
+	struct cvmx_spxx_err_ctl_s cn58xx;
+	struct cvmx_spxx_err_ctl_s cn58xxp1;
+};
+
+union cvmx_spxx_int_dat {
+	uint64_t u64;
+	struct cvmx_spxx_int_dat_s {
+		uint64_t reserved_32_63:32;
+		uint64_t mul:1;
+		uint64_t reserved_14_30:17;
+		uint64_t calbnk:2;
+		uint64_t rsvop:4;
+		uint64_t prt:8;
+	} s;
+	struct cvmx_spxx_int_dat_s cn38xx;
+	struct cvmx_spxx_int_dat_s cn38xxp2;
+	struct cvmx_spxx_int_dat_s cn58xx;
+	struct cvmx_spxx_int_dat_s cn58xxp1;
+};
+
+union cvmx_spxx_int_msk {
+	uint64_t u64;
+	struct cvmx_spxx_int_msk_s {
+		uint64_t reserved_12_63:52;
+		uint64_t calerr:1;
+		uint64_t syncerr:1;
+		uint64_t diperr:1;
+		uint64_t tpaovr:1;
+		uint64_t rsverr:1;
+		uint64_t drwnng:1;
+		uint64_t clserr:1;
+		uint64_t spiovr:1;
+		uint64_t reserved_2_3:2;
+		uint64_t abnorm:1;
+		uint64_t prtnxa:1;
+	} s;
+	struct cvmx_spxx_int_msk_s cn38xx;
+	struct cvmx_spxx_int_msk_s cn38xxp2;
+	struct cvmx_spxx_int_msk_s cn58xx;
+	struct cvmx_spxx_int_msk_s cn58xxp1;
+};
+
+union cvmx_spxx_int_reg {
+	uint64_t u64;
+	struct cvmx_spxx_int_reg_s {
+		uint64_t reserved_32_63:32;
+		uint64_t spf:1;
+		uint64_t reserved_12_30:19;
+		uint64_t calerr:1;
+		uint64_t syncerr:1;
+		uint64_t diperr:1;
+		uint64_t tpaovr:1;
+		uint64_t rsverr:1;
+		uint64_t drwnng:1;
+		uint64_t clserr:1;
+		uint64_t spiovr:1;
+		uint64_t reserved_2_3:2;
+		uint64_t abnorm:1;
+		uint64_t prtnxa:1;
+	} s;
+	struct cvmx_spxx_int_reg_s cn38xx;
+	struct cvmx_spxx_int_reg_s cn38xxp2;
+	struct cvmx_spxx_int_reg_s cn58xx;
+	struct cvmx_spxx_int_reg_s cn58xxp1;
+};
+
+union cvmx_spxx_int_sync {
+	uint64_t u64;
+	struct cvmx_spxx_int_sync_s {
+		uint64_t reserved_12_63:52;
+		uint64_t calerr:1;
+		uint64_t syncerr:1;
+		uint64_t diperr:1;
+		uint64_t tpaovr:1;
+		uint64_t rsverr:1;
+		uint64_t drwnng:1;
+		uint64_t clserr:1;
+		uint64_t spiovr:1;
+		uint64_t reserved_2_3:2;
+		uint64_t abnorm:1;
+		uint64_t prtnxa:1;
+	} s;
+	struct cvmx_spxx_int_sync_s cn38xx;
+	struct cvmx_spxx_int_sync_s cn38xxp2;
+	struct cvmx_spxx_int_sync_s cn58xx;
+	struct cvmx_spxx_int_sync_s cn58xxp1;
+};
+
+union cvmx_spxx_tpa_acc {
+	uint64_t u64;
+	struct cvmx_spxx_tpa_acc_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_spxx_tpa_acc_s cn38xx;
+	struct cvmx_spxx_tpa_acc_s cn38xxp2;
+	struct cvmx_spxx_tpa_acc_s cn58xx;
+	struct cvmx_spxx_tpa_acc_s cn58xxp1;
+};
+
+union cvmx_spxx_tpa_max {
+	uint64_t u64;
+	struct cvmx_spxx_tpa_max_s {
+		uint64_t reserved_32_63:32;
+		uint64_t max:32;
+	} s;
+	struct cvmx_spxx_tpa_max_s cn38xx;
+	struct cvmx_spxx_tpa_max_s cn38xxp2;
+	struct cvmx_spxx_tpa_max_s cn58xx;
+	struct cvmx_spxx_tpa_max_s cn58xxp1;
+};
+
+union cvmx_spxx_tpa_sel {
+	uint64_t u64;
+	struct cvmx_spxx_tpa_sel_s {
+		uint64_t reserved_4_63:60;
+		uint64_t prtsel:4;
+	} s;
+	struct cvmx_spxx_tpa_sel_s cn38xx;
+	struct cvmx_spxx_tpa_sel_s cn38xxp2;
+	struct cvmx_spxx_tpa_sel_s cn58xx;
+	struct cvmx_spxx_tpa_sel_s cn58xxp1;
+};
+
+union cvmx_spxx_trn4_ctl {
+	uint64_t u64;
+	struct cvmx_spxx_trn4_ctl_s {
+		uint64_t reserved_13_63:51;
+		uint64_t trntest:1;
+		uint64_t jitter:3;
+		uint64_t clr_boot:1;
+		uint64_t set_boot:1;
+		uint64_t maxdist:5;
+		uint64_t macro_en:1;
+		uint64_t mux_en:1;
+	} s;
+	struct cvmx_spxx_trn4_ctl_s cn38xx;
+	struct cvmx_spxx_trn4_ctl_s cn38xxp2;
+	struct cvmx_spxx_trn4_ctl_s cn58xx;
+	struct cvmx_spxx_trn4_ctl_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-srxx-defs.h b/drivers/staging/octeon/cvmx-srxx-defs.h
new file mode 100644
index 0000000..d82b366
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-srxx-defs.h
@@ -0,0 +1,126 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SRXX_DEFS_H__
+#define __CVMX_SRXX_DEFS_H__
+
+#define CVMX_SRXX_COM_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_IGN_RX_FULL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_SPI4_STAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_SW_TICK_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_SW_TICK_DAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_srxx_com_ctl {
+	uint64_t u64;
+	struct cvmx_srxx_com_ctl_s {
+		uint64_t reserved_8_63:56;
+		uint64_t prts:4;
+		uint64_t st_en:1;
+		uint64_t reserved_1_2:2;
+		uint64_t inf_en:1;
+	} s;
+	struct cvmx_srxx_com_ctl_s cn38xx;
+	struct cvmx_srxx_com_ctl_s cn38xxp2;
+	struct cvmx_srxx_com_ctl_s cn58xx;
+	struct cvmx_srxx_com_ctl_s cn58xxp1;
+};
+
+union cvmx_srxx_ign_rx_full {
+	uint64_t u64;
+	struct cvmx_srxx_ign_rx_full_s {
+		uint64_t reserved_16_63:48;
+		uint64_t ignore:16;
+	} s;
+	struct cvmx_srxx_ign_rx_full_s cn38xx;
+	struct cvmx_srxx_ign_rx_full_s cn38xxp2;
+	struct cvmx_srxx_ign_rx_full_s cn58xx;
+	struct cvmx_srxx_ign_rx_full_s cn58xxp1;
+};
+
+union cvmx_srxx_spi4_calx {
+	uint64_t u64;
+	struct cvmx_srxx_spi4_calx_s {
+		uint64_t reserved_17_63:47;
+		uint64_t oddpar:1;
+		uint64_t prt3:4;
+		uint64_t prt2:4;
+		uint64_t prt1:4;
+		uint64_t prt0:4;
+	} s;
+	struct cvmx_srxx_spi4_calx_s cn38xx;
+	struct cvmx_srxx_spi4_calx_s cn38xxp2;
+	struct cvmx_srxx_spi4_calx_s cn58xx;
+	struct cvmx_srxx_spi4_calx_s cn58xxp1;
+};
+
+union cvmx_srxx_spi4_stat {
+	uint64_t u64;
+	struct cvmx_srxx_spi4_stat_s {
+		uint64_t reserved_16_63:48;
+		uint64_t m:8;
+		uint64_t reserved_7_7:1;
+		uint64_t len:7;
+	} s;
+	struct cvmx_srxx_spi4_stat_s cn38xx;
+	struct cvmx_srxx_spi4_stat_s cn38xxp2;
+	struct cvmx_srxx_spi4_stat_s cn58xx;
+	struct cvmx_srxx_spi4_stat_s cn58xxp1;
+};
+
+union cvmx_srxx_sw_tick_ctl {
+	uint64_t u64;
+	struct cvmx_srxx_sw_tick_ctl_s {
+		uint64_t reserved_14_63:50;
+		uint64_t eop:1;
+		uint64_t sop:1;
+		uint64_t mod:4;
+		uint64_t opc:4;
+		uint64_t adr:4;
+	} s;
+	struct cvmx_srxx_sw_tick_ctl_s cn38xx;
+	struct cvmx_srxx_sw_tick_ctl_s cn58xx;
+	struct cvmx_srxx_sw_tick_ctl_s cn58xxp1;
+};
+
+union cvmx_srxx_sw_tick_dat {
+	uint64_t u64;
+	struct cvmx_srxx_sw_tick_dat_s {
+		uint64_t dat:64;
+	} s;
+	struct cvmx_srxx_sw_tick_dat_s cn38xx;
+	struct cvmx_srxx_sw_tick_dat_s cn58xx;
+	struct cvmx_srxx_sw_tick_dat_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-stxx-defs.h b/drivers/staging/octeon/cvmx-stxx-defs.h
new file mode 100644
index 0000000..4f209b6
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-stxx-defs.h
@@ -0,0 +1,292 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_STXX_DEFS_H__
+#define __CVMX_STXX_DEFS_H__
+
+#define CVMX_STXX_ARB_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_BCKPRS_CNT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_COM_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_DIP_CNT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_IGN_CAL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_INT_MSK(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_INT_REG(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_INT_SYNC(block_id) \
+	 CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_MIN_BST(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_SPI4_CALX(offset, block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_SPI4_DAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_SPI4_STAT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_STAT_BYTES_HI(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_STAT_BYTES_LO(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_STAT_CTL(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_STAT_PKT_XMT(block_id) \
+	 CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
+
+union cvmx_stxx_arb_ctl {
+	uint64_t u64;
+	struct cvmx_stxx_arb_ctl_s {
+		uint64_t reserved_6_63:58;
+		uint64_t mintrn:1;
+		uint64_t reserved_4_4:1;
+		uint64_t igntpa:1;
+		uint64_t reserved_0_2:3;
+	} s;
+	struct cvmx_stxx_arb_ctl_s cn38xx;
+	struct cvmx_stxx_arb_ctl_s cn38xxp2;
+	struct cvmx_stxx_arb_ctl_s cn58xx;
+	struct cvmx_stxx_arb_ctl_s cn58xxp1;
+};
+
+union cvmx_stxx_bckprs_cnt {
+	uint64_t u64;
+	struct cvmx_stxx_bckprs_cnt_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_stxx_bckprs_cnt_s cn38xx;
+	struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
+	struct cvmx_stxx_bckprs_cnt_s cn58xx;
+	struct cvmx_stxx_bckprs_cnt_s cn58xxp1;
+};
+
+union cvmx_stxx_com_ctl {
+	uint64_t u64;
+	struct cvmx_stxx_com_ctl_s {
+		uint64_t reserved_4_63:60;
+		uint64_t st_en:1;
+		uint64_t reserved_1_2:2;
+		uint64_t inf_en:1;
+	} s;
+	struct cvmx_stxx_com_ctl_s cn38xx;
+	struct cvmx_stxx_com_ctl_s cn38xxp2;
+	struct cvmx_stxx_com_ctl_s cn58xx;
+	struct cvmx_stxx_com_ctl_s cn58xxp1;
+};
+
+union cvmx_stxx_dip_cnt {
+	uint64_t u64;
+	struct cvmx_stxx_dip_cnt_s {
+		uint64_t reserved_8_63:56;
+		uint64_t frmmax:4;
+		uint64_t dipmax:4;
+	} s;
+	struct cvmx_stxx_dip_cnt_s cn38xx;
+	struct cvmx_stxx_dip_cnt_s cn38xxp2;
+	struct cvmx_stxx_dip_cnt_s cn58xx;
+	struct cvmx_stxx_dip_cnt_s cn58xxp1;
+};
+
+union cvmx_stxx_ign_cal {
+	uint64_t u64;
+	struct cvmx_stxx_ign_cal_s {
+		uint64_t reserved_16_63:48;
+		uint64_t igntpa:16;
+	} s;
+	struct cvmx_stxx_ign_cal_s cn38xx;
+	struct cvmx_stxx_ign_cal_s cn38xxp2;
+	struct cvmx_stxx_ign_cal_s cn58xx;
+	struct cvmx_stxx_ign_cal_s cn58xxp1;
+};
+
+union cvmx_stxx_int_msk {
+	uint64_t u64;
+	struct cvmx_stxx_int_msk_s {
+		uint64_t reserved_8_63:56;
+		uint64_t frmerr:1;
+		uint64_t unxfrm:1;
+		uint64_t nosync:1;
+		uint64_t diperr:1;
+		uint64_t datovr:1;
+		uint64_t ovrbst:1;
+		uint64_t calpar1:1;
+		uint64_t calpar0:1;
+	} s;
+	struct cvmx_stxx_int_msk_s cn38xx;
+	struct cvmx_stxx_int_msk_s cn38xxp2;
+	struct cvmx_stxx_int_msk_s cn58xx;
+	struct cvmx_stxx_int_msk_s cn58xxp1;
+};
+
+union cvmx_stxx_int_reg {
+	uint64_t u64;
+	struct cvmx_stxx_int_reg_s {
+		uint64_t reserved_9_63:55;
+		uint64_t syncerr:1;
+		uint64_t frmerr:1;
+		uint64_t unxfrm:1;
+		uint64_t nosync:1;
+		uint64_t diperr:1;
+		uint64_t datovr:1;
+		uint64_t ovrbst:1;
+		uint64_t calpar1:1;
+		uint64_t calpar0:1;
+	} s;
+	struct cvmx_stxx_int_reg_s cn38xx;
+	struct cvmx_stxx_int_reg_s cn38xxp2;
+	struct cvmx_stxx_int_reg_s cn58xx;
+	struct cvmx_stxx_int_reg_s cn58xxp1;
+};
+
+union cvmx_stxx_int_sync {
+	uint64_t u64;
+	struct cvmx_stxx_int_sync_s {
+		uint64_t reserved_8_63:56;
+		uint64_t frmerr:1;
+		uint64_t unxfrm:1;
+		uint64_t nosync:1;
+		uint64_t diperr:1;
+		uint64_t datovr:1;
+		uint64_t ovrbst:1;
+		uint64_t calpar1:1;
+		uint64_t calpar0:1;
+	} s;
+	struct cvmx_stxx_int_sync_s cn38xx;
+	struct cvmx_stxx_int_sync_s cn38xxp2;
+	struct cvmx_stxx_int_sync_s cn58xx;
+	struct cvmx_stxx_int_sync_s cn58xxp1;
+};
+
+union cvmx_stxx_min_bst {
+	uint64_t u64;
+	struct cvmx_stxx_min_bst_s {
+		uint64_t reserved_9_63:55;
+		uint64_t minb:9;
+	} s;
+	struct cvmx_stxx_min_bst_s cn38xx;
+	struct cvmx_stxx_min_bst_s cn38xxp2;
+	struct cvmx_stxx_min_bst_s cn58xx;
+	struct cvmx_stxx_min_bst_s cn58xxp1;
+};
+
+union cvmx_stxx_spi4_calx {
+	uint64_t u64;
+	struct cvmx_stxx_spi4_calx_s {
+		uint64_t reserved_17_63:47;
+		uint64_t oddpar:1;
+		uint64_t prt3:4;
+		uint64_t prt2:4;
+		uint64_t prt1:4;
+		uint64_t prt0:4;
+	} s;
+	struct cvmx_stxx_spi4_calx_s cn38xx;
+	struct cvmx_stxx_spi4_calx_s cn38xxp2;
+	struct cvmx_stxx_spi4_calx_s cn58xx;
+	struct cvmx_stxx_spi4_calx_s cn58xxp1;
+};
+
+union cvmx_stxx_spi4_dat {
+	uint64_t u64;
+	struct cvmx_stxx_spi4_dat_s {
+		uint64_t reserved_32_63:32;
+		uint64_t alpha:16;
+		uint64_t max_t:16;
+	} s;
+	struct cvmx_stxx_spi4_dat_s cn38xx;
+	struct cvmx_stxx_spi4_dat_s cn38xxp2;
+	struct cvmx_stxx_spi4_dat_s cn58xx;
+	struct cvmx_stxx_spi4_dat_s cn58xxp1;
+};
+
+union cvmx_stxx_spi4_stat {
+	uint64_t u64;
+	struct cvmx_stxx_spi4_stat_s {
+		uint64_t reserved_16_63:48;
+		uint64_t m:8;
+		uint64_t reserved_7_7:1;
+		uint64_t len:7;
+	} s;
+	struct cvmx_stxx_spi4_stat_s cn38xx;
+	struct cvmx_stxx_spi4_stat_s cn38xxp2;
+	struct cvmx_stxx_spi4_stat_s cn58xx;
+	struct cvmx_stxx_spi4_stat_s cn58xxp1;
+};
+
+union cvmx_stxx_stat_bytes_hi {
+	uint64_t u64;
+	struct cvmx_stxx_stat_bytes_hi_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_stxx_stat_bytes_hi_s cn38xx;
+	struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
+	struct cvmx_stxx_stat_bytes_hi_s cn58xx;
+	struct cvmx_stxx_stat_bytes_hi_s cn58xxp1;
+};
+
+union cvmx_stxx_stat_bytes_lo {
+	uint64_t u64;
+	struct cvmx_stxx_stat_bytes_lo_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_stxx_stat_bytes_lo_s cn38xx;
+	struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
+	struct cvmx_stxx_stat_bytes_lo_s cn58xx;
+	struct cvmx_stxx_stat_bytes_lo_s cn58xxp1;
+};
+
+union cvmx_stxx_stat_ctl {
+	uint64_t u64;
+	struct cvmx_stxx_stat_ctl_s {
+		uint64_t reserved_5_63:59;
+		uint64_t clr:1;
+		uint64_t bckprs:4;
+	} s;
+	struct cvmx_stxx_stat_ctl_s cn38xx;
+	struct cvmx_stxx_stat_ctl_s cn38xxp2;
+	struct cvmx_stxx_stat_ctl_s cn58xx;
+	struct cvmx_stxx_stat_ctl_s cn58xxp1;
+};
+
+union cvmx_stxx_stat_pkt_xmt {
+	uint64_t u64;
+	struct cvmx_stxx_stat_pkt_xmt_s {
+		uint64_t reserved_32_63:32;
+		uint64_t cnt:32;
+	} s;
+	struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
+	struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
+	struct cvmx_stxx_stat_pkt_xmt_s cn58xx;
+	struct cvmx_stxx_stat_pkt_xmt_s cn58xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-wqe.h b/drivers/staging/octeon/cvmx-wqe.h
new file mode 100644
index 0000000..6536109
--- /dev/null
+++ b/drivers/staging/octeon/cvmx-wqe.h
@@ -0,0 +1,397 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ *
+ * This header file defines the work queue entry (wqe) data structure.
+ * Since this is a commonly used structure that depends on structures
+ * from several hardware blocks, those definitions have been placed
+ * in this file to create a single point of definition of the wqe
+ * format.
+ * Data structures are still named according to the block that they
+ * relate to.
+ *
+ */
+
+#ifndef __CVMX_WQE_H__
+#define __CVMX_WQE_H__
+
+#include "cvmx-packet.h"
+
+
+#define OCT_TAG_TYPE_STRING(x)						\
+	(((x) == CVMX_POW_TAG_TYPE_ORDERED) ?  "ORDERED" :		\
+		(((x) == CVMX_POW_TAG_TYPE_ATOMIC) ?  "ATOMIC" :	\
+			(((x) == CVMX_POW_TAG_TYPE_NULL) ?  "NULL" :	\
+				"NULL_NULL")))
+
+/**
+ * HW decode / err_code in work queue entry
+ */
+typedef union {
+	uint64_t u64;
+
+	/* Use this struct if the hardware determines that the packet is IP */
+	struct {
+		/* HW sets this to the number of buffers used by this packet */
+		uint64_t bufs:8;
+		/* HW sets to the number of L2 bytes prior to the IP */
+		uint64_t ip_offset:8;
+		/* set to 1 if we found DSA/VLAN in the L2 */
+		uint64_t vlan_valid:1;
+		/* Set to 1 if the DSA/VLAN tag is stacked */
+		uint64_t vlan_stacked:1;
+		uint64_t unassigned:1;
+		/* HW sets to the DSA/VLAN CFI flag (valid when vlan_valid) */
+		uint64_t vlan_cfi:1;
+		/* HW sets to the DSA/VLAN_ID field (valid when vlan_valid) */
+		uint64_t vlan_id:12;
+		/* Ring Identifier (if PCIe). Requires PIP_GBL_CTL[RING_EN]=1 */
+		uint64_t pr:4;
+		uint64_t unassigned2:8;
+		/* the packet needs to be decompressed */
+		uint64_t dec_ipcomp:1;
+		/* the packet is either TCP or UDP */
+		uint64_t tcp_or_udp:1;
+		/* the packet needs to be decrypted (ESP or AH) */
+		uint64_t dec_ipsec:1;
+		/* the packet is IPv6 */
+		uint64_t is_v6:1;
+
+		/*
+		 * (rcv_error, not_IP, IP_exc, is_frag, L4_error,
+		 * software, etc.).
+		 */
+
+		/*
+		 * reserved for software use, hardware will clear on
+		 * packet creation.
+		 */
+		uint64_t software:1;
+		/* exceptional conditions below */
+		/* the receive interface hardware detected an L4 error
+		 * (only applies if !is_frag) (only applies if
+		 * !rcv_error && !not_IP && !IP_exc && !is_frag)
+		 * failure indicated in err_code below, decode:
+		 *
+		 * - 1 = Malformed L4
+		 * - 2 = L4 Checksum Error: the L4 checksum value is
+		 * - 3 = UDP Length Error: The UDP length field would
+		 *       make the UDP data longer than what remains in
+		 *       the IP packet (as defined by the IP header
+		 *       length field).
+		 * - 4 = Bad L4 Port: either the source or destination
+		 *       TCP/UDP port is 0.
+		 * - 8 = TCP FIN Only: the packet is TCP and only the
+		 *       FIN flag set.
+		 * - 9 = TCP No Flags: the packet is TCP and no flags
+		 *       are set.
+		 * - 10 = TCP FIN RST: the packet is TCP and both FIN
+		 *        and RST are set.
+		 * - 11 = TCP SYN URG: the packet is TCP and both SYN
+		 *        and URG are set.
+		 * - 12 = TCP SYN RST: the packet is TCP and both SYN
+		 *        and RST are set.
+		 * - 13 = TCP SYN FIN: the packet is TCP and both SYN
+		 *        and FIN are set.
+		 */
+		uint64_t L4_error:1;
+		/* set if the packet is a fragment */
+		uint64_t is_frag:1;
+		/* the receive interface hardware detected an IP error
+		 * / exception (only applies if !rcv_error && !not_IP)
+		 * failure indicated in err_code below, decode:
+		 *
+		 * - 1 = Not IP: the IP version field is neither 4 nor
+		 *       6.
+		 * - 2 = IPv4 Header Checksum Error: the IPv4 header
+		 *       has a checksum violation.
+		 * - 3 = IP Malformed Header: the packet is not long
+		 *       enough to contain the IP header.
+		 * - 4 = IP Malformed: the packet is not long enough
+		 *	 to contain the bytes indicated by the IP
+		 *	 header. Pad is allowed.
+		 * - 5 = IP TTL Hop: the IPv4 TTL field or the IPv6
+		 *       Hop Count field are zero.
+		 * - 6 = IP Options
+		 */
+		uint64_t IP_exc:1;
+		/*
+		 * Set if the hardware determined that the packet is a
+		 * broadcast.
+		 */
+		uint64_t is_bcast:1;
+		/*
+		 * St if the hardware determined that the packet is a
+		 * multi-cast.
+		 */
+		uint64_t is_mcast:1;
+		/*
+		 * Set if the packet may not be IP (must be zero in
+		 * this case).
+		 */
+		uint64_t not_IP:1;
+		/*
+		 * The receive interface hardware detected a receive
+		 * error (must be zero in this case).
+		 */
+		uint64_t rcv_error:1;
+		/* lower err_code = first-level descriptor of the
+		 * work */
+		/* zero for packet submitted by hardware that isn't on
+		 * the slow path */
+		/* type is cvmx_pip_err_t */
+		uint64_t err_code:8;
+	} s;
+
+	/* use this to get at the 16 vlan bits */
+	struct {
+		uint64_t unused1:16;
+		uint64_t vlan:16;
+		uint64_t unused2:32;
+	} svlan;
+
+	/*
+	 * use this struct if the hardware could not determine that
+	 * the packet is ip.
+	 */
+	struct {
+		/*
+		 * HW sets this to the number of buffers used by this
+		 * packet.
+		 */
+		uint64_t bufs:8;
+		uint64_t unused:8;
+		/* set to 1 if we found DSA/VLAN in the L2 */
+		uint64_t vlan_valid:1;
+		/* Set to 1 if the DSA/VLAN tag is stacked */
+		uint64_t vlan_stacked:1;
+		uint64_t unassigned:1;
+		/*
+		 * HW sets to the DSA/VLAN CFI flag (valid when
+		 * vlan_valid)
+		 */
+		uint64_t vlan_cfi:1;
+		/*
+		 * HW sets to the DSA/VLAN_ID field (valid when
+		 * vlan_valid).
+		 */
+		uint64_t vlan_id:12;
+		/*
+		 * Ring Identifier (if PCIe). Requires
+		 * PIP_GBL_CTL[RING_EN]=1
+		 */
+		uint64_t pr:4;
+		uint64_t unassigned2:12;
+		/*
+		 * reserved for software use, hardware will clear on
+		 * packet creation.
+		 */
+		uint64_t software:1;
+		uint64_t unassigned3:1;
+		/*
+		 * set if the hardware determined that the packet is
+		 * rarp.
+		 */
+		uint64_t is_rarp:1;
+		/*
+		 * set if the hardware determined that the packet is
+		 * arp
+		 */
+		uint64_t is_arp:1;
+		/*
+		 * set if the hardware determined that the packet is a
+		 * broadcast.
+		 */
+		uint64_t is_bcast:1;
+		/*
+		 * set if the hardware determined that the packet is a
+		 * multi-cast
+		 */
+		uint64_t is_mcast:1;
+		/*
+		 * set if the packet may not be IP (must be one in
+		 * this case)
+		 */
+		uint64_t not_IP:1;
+		/* The receive interface hardware detected a receive
+		 * error.  Failure indicated in err_code below,
+		 * decode:
+		 *
+		 * - 1 = partial error: a packet was partially
+		 *       received, but internal buffering / bandwidth
+		 *       was not adequate to receive the entire
+		 *       packet.
+		 * - 2 = jabber error: the RGMII packet was too large
+		 *       and is truncated.
+		 * - 3 = overrun error: the RGMII packet is longer
+		 *       than allowed and had an FCS error.
+		 * - 4 = oversize error: the RGMII packet is longer
+		 *       than allowed.
+		 * - 5 = alignment error: the RGMII packet is not an
+		 *       integer number of bytes
+		 *       and had an FCS error (100M and 10M only).
+		 * - 6 = fragment error: the RGMII packet is shorter
+		 *       than allowed and had an FCS error.
+		 * - 7 = GMX FCS error: the RGMII packet had an FCS
+		 *       error.
+		 * - 8 = undersize error: the RGMII packet is shorter
+		 *       than allowed.
+		 * - 9 = extend error: the RGMII packet had an extend
+		 *       error.
+		 * - 10 = length mismatch error: the RGMII packet had
+		 *        a length that did not match the length field
+		 *        in the L2 HDR.
+		 * - 11 = RGMII RX error/SPI4 DIP4 Error: the RGMII
+		 * 	  packet had one or more data reception errors
+		 * 	  (RXERR) or the SPI4 packet had one or more
+		 * 	  DIP4 errors.
+		 * - 12 = RGMII skip error/SPI4 Abort Error: the RGMII
+		 *        packet was not large enough to cover the
+		 *        skipped bytes or the SPI4 packet was
+		 *        terminated with an About EOPS.
+		 * - 13 = RGMII nibble error/SPI4 Port NXA Error: the
+		 *        RGMII packet had a studder error (data not
+		 *        repeated - 10/100M only) or the SPI4 packet
+		 *        was sent to an NXA.
+		 * - 16 = FCS error: a SPI4.2 packet had an FCS error.
+		 * - 17 = Skip error: a packet was not large enough to
+		 *        cover the skipped bytes.
+		 * - 18 = L2 header malformed: the packet is not long
+		 *        enough to contain the L2.
+		 */
+
+		uint64_t rcv_error:1;
+		/*
+		 * lower err_code = first-level descriptor of the
+		 * work
+		 */
+		/*
+		 * zero for packet submitted by hardware that isn't on
+		 * the slow path
+		 */
+		/* type is cvmx_pip_err_t (union, so can't use directly */
+		uint64_t err_code:8;
+	} snoip;
+
+} cvmx_pip_wqe_word2;
+
+/**
+ * Work queue entry format
+ *
+ * must be 8-byte aligned
+ */
+typedef struct {
+
+    /*****************************************************************
+     * WORD 0
+     *  HW WRITE: the following 64 bits are filled by HW when a packet arrives
+     */
+
+    /**
+     * raw chksum result generated by the HW
+     */
+	uint16_t hw_chksum;
+    /**
+     * Field unused by hardware - available for software
+     */
+	uint8_t unused;
+    /**
+     * Next pointer used by hardware for list maintenance.
+     * May be written/read by HW before the work queue
+     *           entry is scheduled to a PP
+     * (Only 36 bits used in Octeon 1)
+     */
+	uint64_t next_ptr:40;
+
+    /*****************************************************************
+     * WORD 1
+     *  HW WRITE: the following 64 bits are filled by HW when a packet arrives
+     */
+
+    /**
+     * HW sets to the total number of bytes in the packet
+     */
+	uint64_t len:16;
+    /**
+     * HW sets this to input physical port
+     */
+	uint64_t ipprt:6;
+
+    /**
+     * HW sets this to what it thought the priority of the input packet was
+     */
+	uint64_t qos:3;
+
+    /**
+     * the group that the work queue entry will be scheduled to
+     */
+	uint64_t grp:4;
+    /**
+     * the type of the tag (ORDERED, ATOMIC, NULL)
+     */
+	uint64_t tag_type:3;
+    /**
+     * the synchronization/ordering tag
+     */
+	uint64_t tag:32;
+
+    /**
+     * WORD 2 HW WRITE: the following 64-bits are filled in by
+     *   hardware when a packet arrives This indicates a variety of
+     *   status and error conditions.
+     */
+	cvmx_pip_wqe_word2 word2;
+
+    /**
+     * Pointer to the first segment of the packet.
+     */
+	union cvmx_buf_ptr packet_ptr;
+
+    /**
+     *   HW WRITE: octeon will fill in a programmable amount from the
+     *             packet, up to (at most, but perhaps less) the amount
+     *             needed to fill the work queue entry to 128 bytes
+     *
+     *   If the packet is recognized to be IP, the hardware starts
+     *   (except that the IPv4 header is padded for appropriate
+     *   alignment) writing here where the IP header starts.  If the
+     *   packet is not recognized to be IP, the hardware starts
+     *   writing the beginning of the packet here.
+     */
+	uint8_t packet_data[96];
+
+    /**
+     * If desired, SW can make the work Q entry any length. For the
+     * purposes of discussion here, Assume 128B always, as this is all that
+     * the hardware deals with.
+     *
+     */
+
+} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
+
+#endif /* __CVMX_WQE_H__ */
diff --git a/drivers/staging/octeon/ethernet-common.c b/drivers/staging/octeon/ethernet-common.c
new file mode 100644
index 0000000..3e6f5b8
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-common.c
@@ -0,0 +1,328 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/atomic.h>
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "ethernet-tx.h"
+#include "ethernet-mdio.h"
+#include "ethernet-util.h"
+#include "octeon-ethernet.h"
+#include "ethernet-common.h"
+
+#include "cvmx-pip.h"
+#include "cvmx-pko.h"
+#include "cvmx-fau.h"
+#include "cvmx-helper.h"
+
+#include "cvmx-gmxx-defs.h"
+
+/**
+ * Get the low level ethernet statistics
+ *
+ * @dev:    Device to get the statistics from
+ * Returns Pointer to the statistics
+ */
+static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
+{
+	cvmx_pip_port_status_t rx_status;
+	cvmx_pko_port_status_t tx_status;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+
+	if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
+		if (octeon_is_simulation()) {
+			/* The simulator doesn't support statistics */
+			memset(&rx_status, 0, sizeof(rx_status));
+			memset(&tx_status, 0, sizeof(tx_status));
+		} else {
+			cvmx_pip_get_port_status(priv->port, 1, &rx_status);
+			cvmx_pko_get_port_status(priv->port, 1, &tx_status);
+		}
+
+		priv->stats.rx_packets += rx_status.inb_packets;
+		priv->stats.tx_packets += tx_status.packets;
+		priv->stats.rx_bytes += rx_status.inb_octets;
+		priv->stats.tx_bytes += tx_status.octets;
+		priv->stats.multicast += rx_status.multicast_packets;
+		priv->stats.rx_crc_errors += rx_status.inb_errors;
+		priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
+
+		/*
+		 * The drop counter must be incremented atomically
+		 * since the RX tasklet also increments it.
+		 */
+#ifdef CONFIG_64BIT
+		atomic64_add(rx_status.dropped_packets,
+			     (atomic64_t *)&priv->stats.rx_dropped);
+#else
+		atomic_add(rx_status.dropped_packets,
+			     (atomic_t *)&priv->stats.rx_dropped);
+#endif
+	}
+
+	return &priv->stats;
+}
+
+/**
+ * Set the multicast list. Currently unimplemented.
+ *
+ * @dev:    Device to work on
+ */
+static void cvm_oct_common_set_multicast_list(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+
+	if ((interface < 2)
+	    && (cvmx_helper_interface_get_mode(interface) !=
+		CVMX_HELPER_INTERFACE_MODE_SPI)) {
+		union cvmx_gmxx_rxx_adr_ctl control;
+		control.u64 = 0;
+		control.s.bcst = 1;	/* Allow broadcast MAC addresses */
+
+		if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
+		    (dev->flags & IFF_PROMISC))
+			/* Force accept multicast packets */
+			control.s.mcst = 2;
+		else
+			/* Force reject multicat packets */
+			control.s.mcst = 1;
+
+		if (dev->flags & IFF_PROMISC)
+			/*
+			 * Reject matches if promisc. Since CAM is
+			 * shut off, should accept everything.
+			 */
+			control.s.cam_mode = 0;
+		else
+			/* Filter packets based on the CAM */
+			control.s.cam_mode = 1;
+
+		gmx_cfg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
+			       gmx_cfg.u64 & ~1ull);
+
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
+			       control.u64);
+		if (dev->flags & IFF_PROMISC)
+			cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
+				       (index, interface), 0);
+		else
+			cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
+				       (index, interface), 1);
+
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
+			       gmx_cfg.u64);
+	}
+}
+
+/**
+ * Set the hardware MAC address for a device
+ *
+ * @dev:    Device to change the MAC address for
+ * @addr:   Address structure to change it too. MAC address is addr + 2.
+ * Returns Zero on success
+ */
+static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+
+	memcpy(dev->dev_addr, addr + 2, 6);
+
+	if ((interface < 2)
+	    && (cvmx_helper_interface_get_mode(interface) !=
+		CVMX_HELPER_INTERFACE_MODE_SPI)) {
+		int i;
+		uint8_t *ptr = addr;
+		uint64_t mac = 0;
+		for (i = 0; i < 6; i++)
+			mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
+
+		gmx_cfg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
+			       gmx_cfg.u64 & ~1ull);
+
+		cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
+			       ptr[2]);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
+			       ptr[3]);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
+			       ptr[4]);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
+			       ptr[5]);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
+			       ptr[6]);
+		cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
+			       ptr[7]);
+		cvm_oct_common_set_multicast_list(dev);
+		cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
+			       gmx_cfg.u64);
+	}
+	return 0;
+}
+
+/**
+ * Change the link MTU. Unimplemented
+ *
+ * @dev:     Device to change
+ * @new_mtu: The new MTU
+ *
+ * Returns Zero on success
+ */
+static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+	int vlan_bytes = 4;
+#else
+	int vlan_bytes = 0;
+#endif
+
+	/*
+	 * Limit the MTU to make sure the ethernet packets are between
+	 * 64 bytes and 65535 bytes.
+	 */
+	if ((new_mtu + 14 + 4 + vlan_bytes < 64)
+	    || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
+		pr_err("MTU must be between %d and %d.\n",
+		       64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
+		return -EINVAL;
+	}
+	dev->mtu = new_mtu;
+
+	if ((interface < 2)
+	    && (cvmx_helper_interface_get_mode(interface) !=
+		CVMX_HELPER_INTERFACE_MODE_SPI)) {
+		/* Add ethernet header and FCS, and VLAN if configured. */
+		int max_packet = new_mtu + 14 + 4 + vlan_bytes;
+
+		if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
+		    || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
+			/* Signal errors on packets larger than the MTU */
+			cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
+				       max_packet);
+		} else {
+			/*
+			 * Set the hardware to truncate packets larger
+			 * than the MTU and smaller the 64 bytes.
+			 */
+			union cvmx_pip_frm_len_chkx frm_len_chk;
+			frm_len_chk.u64 = 0;
+			frm_len_chk.s.minlen = 64;
+			frm_len_chk.s.maxlen = max_packet;
+			cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
+				       frm_len_chk.u64);
+		}
+		/*
+		 * Set the hardware to truncate packets larger than
+		 * the MTU. The jabber register must be set to a
+		 * multiple of 8 bytes, so round up.
+		 */
+		cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
+			       (max_packet + 7) & ~7u);
+	}
+	return 0;
+}
+
+/**
+ * Per network device initialization
+ *
+ * @dev:    Device to initialize
+ * Returns Zero on success
+ */
+int cvm_oct_common_init(struct net_device *dev)
+{
+	static int count;
+	char mac[8] = { 0x00, 0x00,
+		octeon_bootinfo->mac_addr_base[0],
+		octeon_bootinfo->mac_addr_base[1],
+		octeon_bootinfo->mac_addr_base[2],
+		octeon_bootinfo->mac_addr_base[3],
+		octeon_bootinfo->mac_addr_base[4],
+		octeon_bootinfo->mac_addr_base[5] + count
+	};
+	struct octeon_ethernet *priv = netdev_priv(dev);
+
+	/*
+	 * Force the interface to use the POW send if always_use_pow
+	 * was specified or it is in the pow send list.
+	 */
+	if ((pow_send_group != -1)
+	    && (always_use_pow || strstr(pow_send_list, dev->name)))
+		priv->queue = -1;
+
+	if (priv->queue != -1) {
+		dev->hard_start_xmit = cvm_oct_xmit;
+		if (USE_HW_TCPUDP_CHECKSUM)
+			dev->features |= NETIF_F_IP_CSUM;
+	} else
+		dev->hard_start_xmit = cvm_oct_xmit_pow;
+	count++;
+
+	dev->get_stats = cvm_oct_common_get_stats;
+	dev->set_mac_address = cvm_oct_common_set_mac_address;
+	dev->set_multicast_list = cvm_oct_common_set_multicast_list;
+	dev->change_mtu = cvm_oct_common_change_mtu;
+	dev->do_ioctl = cvm_oct_ioctl;
+	/* We do our own locking, Linux doesn't need to */
+	dev->features |= NETIF_F_LLTX;
+	SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = cvm_oct_poll_controller;
+#endif
+
+	cvm_oct_mdio_setup_device(dev);
+	dev->set_mac_address(dev, mac);
+	dev->change_mtu(dev, dev->mtu);
+
+	/*
+	 * Zero out stats for port so we won't mistakenly show
+	 * counters from the bootloader.
+	 */
+	memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
+
+	return 0;
+}
+
+void cvm_oct_common_uninit(struct net_device *dev)
+{
+	/* Currently nothing to do */
+}
diff --git a/drivers/staging/octeon/ethernet-common.h b/drivers/staging/octeon/ethernet-common.h
new file mode 100644
index 0000000..2bd9cd7
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-common.h
@@ -0,0 +1,29 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+
+int cvm_oct_common_init(struct net_device *dev);
+void cvm_oct_common_uninit(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h
new file mode 100644
index 0000000..8f7374e
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-defines.h
@@ -0,0 +1,134 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+
+/*
+ * A few defines are used to control the operation of this driver:
+ *  CONFIG_CAVIUM_RESERVE32
+ *      This kernel config options controls the amount of memory configured
+ *      in a wired TLB entry for all processes to share. If this is set, the
+ *      driver will use this memory instead of kernel memory for pools. This
+ *      allows 32bit userspace application to access the buffers, but also
+ *      requires all received packets to be copied.
+ *  CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
+ *      This kernel config option allows the user to control the number of
+ *      packet and work queue buffers allocated by the driver. If this is zero,
+ *      the driver uses the default from below.
+ *  USE_SKBUFFS_IN_HW
+ *      Tells the driver to populate the packet buffers with kernel skbuffs.
+ *      This allows the driver to receive packets without copying them. It also
+ *      means that 32bit userspace can't access the packet buffers.
+ *  USE_32BIT_SHARED
+ *      This define tells the driver to allocate memory for buffers from the
+ *      32bit sahred region instead of the kernel memory space.
+ *  USE_HW_TCPUDP_CHECKSUM
+ *      Controls if the Octeon TCP/UDP checksum engine is used for packet
+ *      output. If this is zero, the kernel will perform the checksum in
+ *      software.
+ *  USE_MULTICORE_RECEIVE
+ *      Process receive interrupts on multiple cores. This spreads the network
+ *      load across the first 8 processors. If ths is zero, only one core
+ *      processes incomming packets.
+ *  USE_ASYNC_IOBDMA
+ *      Use asynchronous IO access to hardware. This uses Octeon's asynchronous
+ *      IOBDMAs to issue IO accesses without stalling. Set this to zero
+ *      to disable this. Note that IOBDMAs require CVMSEG.
+ *  REUSE_SKBUFFS_WITHOUT_FREE
+ *      Allows the TX path to free an skbuff into the FPA hardware pool. This
+ *      can significantly improve performance for forwarding and bridging, but
+ *      may be somewhat dangerous. Checks are made, but if any buffer is reused
+ *      without the proper Linux cleanup, the networking stack may have very
+ *      bizarre bugs.
+ */
+#ifndef __ETHERNET_DEFINES_H__
+#define __ETHERNET_DEFINES_H__
+
+#include "cvmx-config.h"
+
+
+#define OCTEON_ETHERNET_VERSION "1.9"
+
+#ifndef CONFIG_CAVIUM_RESERVE32
+#define CONFIG_CAVIUM_RESERVE32 0
+#endif
+
+#if CONFIG_CAVIUM_RESERVE32
+#define USE_32BIT_SHARED            1
+#define USE_SKBUFFS_IN_HW           0
+#define REUSE_SKBUFFS_WITHOUT_FREE  0
+#else
+#define USE_32BIT_SHARED            0
+#define USE_SKBUFFS_IN_HW           1
+#ifdef CONFIG_NETFILTER
+#define REUSE_SKBUFFS_WITHOUT_FREE  0
+#else
+#define REUSE_SKBUFFS_WITHOUT_FREE  1
+#endif
+#endif
+
+/* Max interrupts per second per core */
+#define INTERRUPT_LIMIT             10000
+
+/* Don't limit the number of interrupts */
+/*#define INTERRUPT_LIMIT             0     */
+#define USE_HW_TCPUDP_CHECKSUM      1
+
+#define USE_MULTICORE_RECEIVE       1
+
+/* Enable Random Early Dropping under load */
+#define USE_RED                     1
+#define USE_ASYNC_IOBDMA            (CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0)
+
+/*
+ * Allow SW based preamble removal at 10Mbps to workaround PHYs giving
+ * us bad preambles.
+ */
+#define USE_10MBPS_PREAMBLE_WORKAROUND 1
+/*
+ * Use this to have all FPA frees also tell the L2 not to write data
+ * to memory.
+ */
+#define DONT_WRITEBACK(x)           (x)
+/* Use this to not have FPA frees control L2 */
+/*#define DONT_WRITEBACK(x)         0   */
+
+/* Maximum number of packets to process per interrupt. */
+#define MAX_RX_PACKETS 120
+#define MAX_OUT_QUEUE_DEPTH 1000
+
+#ifndef CONFIG_SMP
+#undef USE_MULTICORE_RECEIVE
+#define USE_MULTICORE_RECEIVE 0
+#endif
+
+#define IP_PROTOCOL_TCP             6
+#define IP_PROTOCOL_UDP             0x11
+
+#define FAU_NUM_PACKET_BUFFERS_TO_FREE (CVMX_FAU_REG_END - sizeof(uint32_t))
+#define TOTAL_NUMBER_OF_PORTS       (CVMX_PIP_NUM_INPUT_PORTS+1)
+
+
+#endif /* __ETHERNET_DEFINES_H__ */
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
new file mode 100644
index 0000000..93cab0a
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -0,0 +1,231 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-mdio.h"
+
+#include "cvmx-helper-board.h"
+
+#include "cvmx-smix-defs.h"
+
+DECLARE_MUTEX(mdio_sem);
+
+/**
+ * Perform an MII read. Called by the generic MII routines
+ *
+ * @dev:      Device to perform read for
+ * @phy_id:   The MII phy id
+ * @location: Register location to read
+ * Returns Result from the read or zero on failure
+ */
+static int cvm_oct_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_rd_dat smi_rd;
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = 1;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
+
+	do {
+		if (!in_interrupt())
+			yield();
+		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(0));
+	} while (smi_rd.s.pending);
+
+	if (smi_rd.s.val)
+		return smi_rd.s.dat;
+	else
+		return 0;
+}
+
+static int cvm_oct_mdio_dummy_read(struct net_device *dev, int phy_id,
+				   int location)
+{
+	return 0xffff;
+}
+
+/**
+ * Perform an MII write. Called by the generic MII routines
+ *
+ * @dev:      Device to perform write for
+ * @phy_id:   The MII phy id
+ * @location: Register location to write
+ * @val:      Value to write
+ */
+static void cvm_oct_mdio_write(struct net_device *dev, int phy_id, int location,
+			       int val)
+{
+	union cvmx_smix_cmd smi_cmd;
+	union cvmx_smix_wr_dat smi_wr;
+
+	smi_wr.u64 = 0;
+	smi_wr.s.dat = val;
+	cvmx_write_csr(CVMX_SMIX_WR_DAT(0), smi_wr.u64);
+
+	smi_cmd.u64 = 0;
+	smi_cmd.s.phy_op = 0;
+	smi_cmd.s.phy_adr = phy_id;
+	smi_cmd.s.reg_adr = location;
+	cvmx_write_csr(CVMX_SMIX_CMD(0), smi_cmd.u64);
+
+	do {
+		if (!in_interrupt())
+			yield();
+		smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(0));
+	} while (smi_wr.s.pending);
+}
+
+static void cvm_oct_mdio_dummy_write(struct net_device *dev, int phy_id,
+				     int location, int val)
+{
+}
+
+static void cvm_oct_get_drvinfo(struct net_device *dev,
+				struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "cavium-ethernet");
+	strcpy(info->version, OCTEON_ETHERNET_VERSION);
+	strcpy(info->bus_info, "Builtin");
+}
+
+static int cvm_oct_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int ret;
+
+	down(&mdio_sem);
+	ret = mii_ethtool_gset(&priv->mii_info, cmd);
+	up(&mdio_sem);
+
+	return ret;
+}
+
+static int cvm_oct_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int ret;
+
+	down(&mdio_sem);
+	ret = mii_ethtool_sset(&priv->mii_info, cmd);
+	up(&mdio_sem);
+
+	return ret;
+}
+
+static int cvm_oct_nway_reset(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int ret;
+
+	down(&mdio_sem);
+	ret = mii_nway_restart(&priv->mii_info);
+	up(&mdio_sem);
+
+	return ret;
+}
+
+static u32 cvm_oct_get_link(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	u32 ret;
+
+	down(&mdio_sem);
+	ret = mii_link_ok(&priv->mii_info);
+	up(&mdio_sem);
+
+	return ret;
+}
+
+struct ethtool_ops cvm_oct_ethtool_ops = {
+	.get_drvinfo = cvm_oct_get_drvinfo,
+	.get_settings = cvm_oct_get_settings,
+	.set_settings = cvm_oct_set_settings,
+	.nway_reset = cvm_oct_nway_reset,
+	.get_link = cvm_oct_get_link,
+	.get_sg = ethtool_op_get_sg,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+};
+
+/**
+ * IOCTL support for PHY control
+ *
+ * @dev:    Device to change
+ * @rq:     the request
+ * @cmd:    the command
+ * Returns Zero on success
+ */
+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	struct mii_ioctl_data *data = if_mii(rq);
+	unsigned int duplex_chg;
+	int ret;
+
+	down(&mdio_sem);
+	ret = generic_mii_ioctl(&priv->mii_info, data, cmd, &duplex_chg);
+	up(&mdio_sem);
+
+	return ret;
+}
+
+/**
+ * Setup the MDIO device structures
+ *
+ * @dev:    Device to setup
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvm_oct_mdio_setup_device(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int phy_id = cvmx_helper_board_get_mii_address(priv->port);
+	if (phy_id != -1) {
+		priv->mii_info.dev = dev;
+		priv->mii_info.phy_id = phy_id;
+		priv->mii_info.phy_id_mask = 0xff;
+		priv->mii_info.supports_gmii = 1;
+		priv->mii_info.reg_num_mask = 0x1f;
+		priv->mii_info.mdio_read = cvm_oct_mdio_read;
+		priv->mii_info.mdio_write = cvm_oct_mdio_write;
+	} else {
+		/* Supply dummy MDIO routines so the kernel won't crash
+		   if the user tries to read them */
+		priv->mii_info.mdio_read = cvm_oct_mdio_dummy_read;
+		priv->mii_info.mdio_write = cvm_oct_mdio_dummy_write;
+	}
+	return 0;
+}
diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
new file mode 100644
index 0000000..6314141
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-mdio.h
@@ -0,0 +1,46 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/string.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+#ifdef CONFIG_XFRM
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#endif /* CONFIG_XFRM */
+
+extern struct ethtool_ops cvm_oct_ethtool_ops;
+int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+int cvm_oct_mdio_setup_device(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
new file mode 100644
index 0000000..b595903
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-mem.c
@@ -0,0 +1,198 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+
+#include "cvmx-fpa.h"
+
+/**
+ * Fill the supplied hardware pool with skbuffs
+ *
+ * @pool:     Pool to allocate an skbuff for
+ * @size:     Size of the buffer needed for the pool
+ * @elements: Number of buffers to allocate
+ */
+static int cvm_oct_fill_hw_skbuff(int pool, int size, int elements)
+{
+	int freed = elements;
+	while (freed) {
+
+		struct sk_buff *skb = dev_alloc_skb(size + 128);
+		if (unlikely(skb == NULL)) {
+			pr_warning
+			    ("Failed to allocate skb for hardware pool %d\n",
+			     pool);
+			break;
+		}
+
+		skb_reserve(skb, 128 - (((unsigned long)skb->data) & 0x7f));
+		*(struct sk_buff **)(skb->data - sizeof(void *)) = skb;
+		cvmx_fpa_free(skb->data, pool, DONT_WRITEBACK(size / 128));
+		freed--;
+	}
+	return elements - freed;
+}
+
+/**
+ * Free the supplied hardware pool of skbuffs
+ *
+ * @pool:     Pool to allocate an skbuff for
+ * @size:     Size of the buffer needed for the pool
+ * @elements: Number of buffers to allocate
+ */
+static void cvm_oct_free_hw_skbuff(int pool, int size, int elements)
+{
+	char *memory;
+
+	do {
+		memory = cvmx_fpa_alloc(pool);
+		if (memory) {
+			struct sk_buff *skb =
+			    *(struct sk_buff **)(memory - sizeof(void *));
+			elements--;
+			dev_kfree_skb(skb);
+		}
+	} while (memory);
+
+	if (elements < 0)
+		pr_warning("Freeing of pool %u had too many skbuffs (%d)\n",
+		     pool, elements);
+	else if (elements > 0)
+		pr_warning("Freeing of pool %u is missing %d skbuffs\n",
+		       pool, elements);
+}
+
+/**
+ * This function fills a hardware pool with memory. Depending
+ * on the config defines, this memory might come from the
+ * kernel or global 32bit memory allocated with
+ * cvmx_bootmem_alloc.
+ *
+ * @pool:     Pool to populate
+ * @size:     Size of each buffer in the pool
+ * @elements: Number of buffers to allocate
+ */
+static int cvm_oct_fill_hw_memory(int pool, int size, int elements)
+{
+	char *memory;
+	int freed = elements;
+
+	if (USE_32BIT_SHARED) {
+		extern uint64_t octeon_reserve32_memory;
+
+		memory =
+		    cvmx_bootmem_alloc_range(elements * size, 128,
+					     octeon_reserve32_memory,
+					     octeon_reserve32_memory +
+					     (CONFIG_CAVIUM_RESERVE32 << 20) -
+					     1);
+		if (memory == NULL)
+			panic("Unable to allocate %u bytes for FPA pool %d\n",
+			      elements * size, pool);
+
+		pr_notice("Memory range %p - %p reserved for "
+			  "hardware\n", memory,
+			  memory + elements * size - 1);
+
+		while (freed) {
+			cvmx_fpa_free(memory, pool, 0);
+			memory += size;
+			freed--;
+		}
+	} else {
+		while (freed) {
+			/* We need to force alignment to 128 bytes here */
+			memory = kmalloc(size + 127, GFP_ATOMIC);
+			if (unlikely(memory == NULL)) {
+				pr_warning("Unable to allocate %u bytes for "
+					   "FPA pool %d\n",
+				     elements * size, pool);
+				break;
+			}
+			memory = (char *)(((unsigned long)memory + 127) & -128);
+			cvmx_fpa_free(memory, pool, 0);
+			freed--;
+		}
+	}
+	return elements - freed;
+}
+
+/**
+ * Free memory previously allocated with cvm_oct_fill_hw_memory
+ *
+ * @pool:     FPA pool to free
+ * @size:     Size of each buffer in the pool
+ * @elements: Number of buffers that should be in the pool
+ */
+static void cvm_oct_free_hw_memory(int pool, int size, int elements)
+{
+	if (USE_32BIT_SHARED) {
+		pr_warning("Warning: 32 shared memory is not freeable\n");
+	} else {
+		char *memory;
+		do {
+			memory = cvmx_fpa_alloc(pool);
+			if (memory) {
+				elements--;
+				kfree(phys_to_virt(cvmx_ptr_to_phys(memory)));
+			}
+		} while (memory);
+
+		if (elements < 0)
+			pr_warning("Freeing of pool %u had too many "
+				   "buffers (%d)\n",
+			       pool, elements);
+		else if (elements > 0)
+			pr_warning("Warning: Freeing of pool %u is "
+				"missing %d buffers\n",
+			     pool, elements);
+	}
+}
+
+int cvm_oct_mem_fill_fpa(int pool, int size, int elements)
+{
+	int freed;
+	if (USE_SKBUFFS_IN_HW)
+		freed = cvm_oct_fill_hw_skbuff(pool, size, elements);
+	else
+		freed = cvm_oct_fill_hw_memory(pool, size, elements);
+	return freed;
+}
+
+void cvm_oct_mem_empty_fpa(int pool, int size, int elements)
+{
+	if (USE_SKBUFFS_IN_HW)
+		cvm_oct_free_hw_skbuff(pool, size, elements);
+	else
+		cvm_oct_free_hw_memory(pool, size, elements);
+}
diff --git a/drivers/staging/octeon/ethernet-mem.h b/drivers/staging/octeon/ethernet-mem.h
new file mode 100644
index 0000000..713f2ed
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-mem.h
@@ -0,0 +1,29 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+********************************************************************/
+
+int cvm_oct_mem_fill_fpa(int pool, int size, int elements);
+void cvm_oct_mem_empty_fpa(int pool, int size, int elements);
diff --git a/drivers/staging/octeon/ethernet-proc.c b/drivers/staging/octeon/ethernet-proc.c
new file mode 100644
index 0000000..8fa88fc
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-proc.c
@@ -0,0 +1,256 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "octeon-ethernet.h"
+#include "ethernet-defines.h"
+
+#include "cvmx-helper.h"
+#include "cvmx-pip.h"
+
+static unsigned long long cvm_oct_stats_read_switch(struct net_device *dev,
+						    int phy_id, int offset)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+
+	priv->mii_info.mdio_write(dev, phy_id, 0x1d, 0xcc00 | offset);
+	return ((uint64_t) priv->mii_info.
+		mdio_read(dev, phy_id,
+			  0x1e) << 16) | (uint64_t) priv->mii_info.
+	    mdio_read(dev, phy_id, 0x1f);
+}
+
+static int cvm_oct_stats_switch_show(struct seq_file *m, void *v)
+{
+	static const int ports[] = { 0, 1, 2, 3, 9, -1 };
+	struct net_device *dev = cvm_oct_device[0];
+	int index = 0;
+
+	while (ports[index] != -1) {
+
+		/* Latch port */
+		struct octeon_ethernet *priv = netdev_priv(dev);
+
+		priv->mii_info.mdio_write(dev, 0x1b, 0x1d,
+					  0xdc00 | ports[index]);
+		seq_printf(m, "\nSwitch Port %d\n", ports[index]);
+		seq_printf(m, "InGoodOctets:   %12llu\t"
+			   "OutOctets:      %12llu\t"
+			   "64 Octets:      %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b,
+						     0x00) |
+			   (cvm_oct_stats_read_switch(dev, 0x1b, 0x01) << 32),
+			   cvm_oct_stats_read_switch(dev, 0x1b,
+						     0x0E) |
+			   (cvm_oct_stats_read_switch(dev, 0x1b, 0x0F) << 32),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x08));
+
+		seq_printf(m, "InBadOctets:    %12llu\t"
+			   "OutUnicast:     %12llu\t"
+			   "65-127 Octets:  %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x02),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x10),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x09));
+
+		seq_printf(m, "InUnicast:      %12llu\t"
+			   "OutBroadcasts:  %12llu\t"
+			   "128-255 Octets: %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x04),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x13),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x0A));
+
+		seq_printf(m, "InBroadcasts:   %12llu\t"
+			   "OutMulticasts:  %12llu\t"
+			   "256-511 Octets: %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x06),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x12),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x0B));
+
+		seq_printf(m, "InMulticasts:   %12llu\t"
+			   "OutPause:       %12llu\t"
+			   "512-1023 Octets:%12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x07),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x15),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x0C));
+
+		seq_printf(m, "InPause:        %12llu\t"
+			   "Excessive:      %12llu\t"
+			   "1024-Max Octets:%12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x16),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x11),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x0D));
+
+		seq_printf(m, "InUndersize:    %12llu\t"
+			   "Collisions:     %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x18),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1E));
+
+		seq_printf(m, "InFragments:    %12llu\t"
+			   "Deferred:       %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x19),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x05));
+
+		seq_printf(m, "InOversize:     %12llu\t"
+			   "Single:         %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1A),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x14));
+
+		seq_printf(m, "InJabber:       %12llu\t"
+			   "Multiple:       %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1B),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x17));
+
+		seq_printf(m, "In RxErr:       %12llu\t"
+			   "OutFCSErr:      %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1C),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x03));
+
+		seq_printf(m, "InFCSErr:       %12llu\t"
+			   "Late:           %12llu\n",
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1D),
+			   cvm_oct_stats_read_switch(dev, 0x1b, 0x1F));
+		index++;
+	}
+	return 0;
+}
+
+/**
+ * User is reading /proc/octeon_ethernet_stats
+ *
+ * @m:
+ * @v:
+ * Returns
+ */
+static int cvm_oct_stats_show(struct seq_file *m, void *v)
+{
+	struct octeon_ethernet *priv;
+	int port;
+
+	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
+
+		if (cvm_oct_device[port]) {
+			priv = netdev_priv(cvm_oct_device[port]);
+
+			seq_printf(m, "\nOcteon Port %d (%s)\n", port,
+				   cvm_oct_device[port]->name);
+			seq_printf(m,
+				   "rx_packets:             %12lu\t"
+				   "tx_packets:             %12lu\n",
+				   priv->stats.rx_packets,
+				   priv->stats.tx_packets);
+			seq_printf(m,
+				   "rx_bytes:               %12lu\t"
+				   "tx_bytes:               %12lu\n",
+				   priv->stats.rx_bytes, priv->stats.tx_bytes);
+			seq_printf(m,
+				   "rx_errors:              %12lu\t"
+				   "tx_errors:              %12lu\n",
+				   priv->stats.rx_errors,
+				   priv->stats.tx_errors);
+			seq_printf(m,
+				   "rx_dropped:             %12lu\t"
+				   "tx_dropped:             %12lu\n",
+				   priv->stats.rx_dropped,
+				   priv->stats.tx_dropped);
+			seq_printf(m,
+				   "rx_length_errors:       %12lu\t"
+				   "tx_aborted_errors:      %12lu\n",
+				   priv->stats.rx_length_errors,
+				   priv->stats.tx_aborted_errors);
+			seq_printf(m,
+				   "rx_over_errors:         %12lu\t"
+				   "tx_carrier_errors:      %12lu\n",
+				   priv->stats.rx_over_errors,
+				   priv->stats.tx_carrier_errors);
+			seq_printf(m,
+				   "rx_crc_errors:          %12lu\t"
+				   "tx_fifo_errors:         %12lu\n",
+				   priv->stats.rx_crc_errors,
+				   priv->stats.tx_fifo_errors);
+			seq_printf(m,
+				   "rx_frame_errors:        %12lu\t"
+				   "tx_heartbeat_errors:    %12lu\n",
+				   priv->stats.rx_frame_errors,
+				   priv->stats.tx_heartbeat_errors);
+			seq_printf(m,
+				   "rx_fifo_errors:         %12lu\t"
+				   "tx_window_errors:       %12lu\n",
+				   priv->stats.rx_fifo_errors,
+				   priv->stats.tx_window_errors);
+			seq_printf(m,
+				   "rx_missed_errors:       %12lu\t"
+				   "multicast:              %12lu\n",
+				   priv->stats.rx_missed_errors,
+				   priv->stats.multicast);
+		}
+	}
+
+	if (cvm_oct_device[0]) {
+		priv = netdev_priv(cvm_oct_device[0]);
+		if (priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
+			cvm_oct_stats_switch_show(m, v);
+	}
+	return 0;
+}
+
+/**
+ * /proc/octeon_ethernet_stats was openned. Use the single_open iterator
+ *
+ * @inode:
+ * @file:
+ * Returns
+ */
+static int cvm_oct_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, cvm_oct_stats_show, NULL);
+}
+
+static const struct file_operations cvm_oct_stats_operations = {
+	.open = cvm_oct_stats_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+void cvm_oct_proc_initialize(void)
+{
+	struct proc_dir_entry *entry =
+	    create_proc_entry("octeon_ethernet_stats", 0, NULL);
+	if (entry)
+		entry->proc_fops = &cvm_oct_stats_operations;
+}
+
+void cvm_oct_proc_shutdown(void)
+{
+	remove_proc_entry("octeon_ethernet_stats", NULL);
+}
diff --git a/drivers/staging/octeon/ethernet-proc.h b/drivers/staging/octeon/ethernet-proc.h
new file mode 100644
index 0000000..82c7d9f
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-proc.h
@@ -0,0 +1,29 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+
+void cvm_oct_proc_initialize(void);
+void cvm_oct_proc_shutdown(void);
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
new file mode 100644
index 0000000..8579f16
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -0,0 +1,397 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-common.h"
+#include "ethernet-util.h"
+
+#include "cvmx-helper.h"
+
+#include <asm/octeon/cvmx-ipd-defs.h>
+#include <asm/octeon/cvmx-npi-defs.h>
+#include "cvmx-gmxx-defs.h"
+
+DEFINE_SPINLOCK(global_register_lock);
+
+static int number_rgmii_ports;
+
+static void cvm_oct_rgmii_poll(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	unsigned long flags;
+	cvmx_helper_link_info_t link_info;
+
+	/*
+	 * Take the global register lock since we are going to touch
+	 * registers that affect more than one port.
+	 */
+	spin_lock_irqsave(&global_register_lock, flags);
+
+	link_info = cvmx_helper_link_get(priv->port);
+	if (link_info.u64 == priv->link_info) {
+
+		/*
+		 * If the 10Mbps preamble workaround is supported and we're
+		 * at 10Mbps we may need to do some special checking.
+		 */
+		if (USE_10MBPS_PREAMBLE_WORKAROUND && (link_info.s.speed == 10)) {
+
+			/*
+			 * Read the GMXX_RXX_INT_REG[PCTERR] bit and
+			 * see if we are getting preamble errors.
+			 */
+			int interface = INTERFACE(priv->port);
+			int index = INDEX(priv->port);
+			union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
+			gmxx_rxx_int_reg.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
+					  (index, interface));
+			if (gmxx_rxx_int_reg.s.pcterr) {
+
+				/*
+				 * We are getting preamble errors at
+				 * 10Mbps.  Most likely the PHY is
+				 * giving us packets with mis aligned
+				 * preambles. In order to get these
+				 * packets we need to disable preamble
+				 * checking and do it in software.
+				 */
+				union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
+				union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
+
+				/* Disable preamble checking */
+				gmxx_rxx_frm_ctl.u64 =
+				    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL
+						  (index, interface));
+				gmxx_rxx_frm_ctl.s.pre_chk = 0;
+				cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL
+					       (index, interface),
+					       gmxx_rxx_frm_ctl.u64);
+
+				/* Disable FCS stripping */
+				ipd_sub_port_fcs.u64 =
+				    cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
+				ipd_sub_port_fcs.s.port_bit &=
+				    0xffffffffull ^ (1ull << priv->port);
+				cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS,
+					       ipd_sub_port_fcs.u64);
+
+				/* Clear any error bits */
+				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
+					       (index, interface),
+					       gmxx_rxx_int_reg.u64);
+				DEBUGPRINT("%s: Using 10Mbps with software "
+					   "preamble removal\n",
+				     dev->name);
+			}
+		}
+		spin_unlock_irqrestore(&global_register_lock, flags);
+		return;
+	}
+
+	/* If the 10Mbps preamble workaround is allowed we need to on
+	   preamble checking, FCS stripping, and clear error bits on
+	   every speed change. If errors occur during 10Mbps operation
+	   the above code will change this stuff */
+	if (USE_10MBPS_PREAMBLE_WORKAROUND) {
+
+		union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
+		union cvmx_ipd_sub_port_fcs ipd_sub_port_fcs;
+		union cvmx_gmxx_rxx_int_reg gmxx_rxx_int_reg;
+		int interface = INTERFACE(priv->port);
+		int index = INDEX(priv->port);
+
+		/* Enable preamble checking */
+		gmxx_rxx_frm_ctl.u64 =
+		    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
+		gmxx_rxx_frm_ctl.s.pre_chk = 1;
+		cvmx_write_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface),
+			       gmxx_rxx_frm_ctl.u64);
+		/* Enable FCS stripping */
+		ipd_sub_port_fcs.u64 = cvmx_read_csr(CVMX_IPD_SUB_PORT_FCS);
+		ipd_sub_port_fcs.s.port_bit |= 1ull << priv->port;
+		cvmx_write_csr(CVMX_IPD_SUB_PORT_FCS, ipd_sub_port_fcs.u64);
+		/* Clear any error bits */
+		gmxx_rxx_int_reg.u64 =
+		    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG(index, interface));
+		cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface),
+			       gmxx_rxx_int_reg.u64);
+	}
+
+	link_info = cvmx_helper_link_autoconf(priv->port);
+	priv->link_info = link_info.u64;
+	spin_unlock_irqrestore(&global_register_lock, flags);
+
+	/* Tell Linux */
+	if (link_info.s.link_up) {
+
+		if (!netif_carrier_ok(dev))
+			netif_carrier_on(dev);
+		if (priv->queue != -1)
+			DEBUGPRINT
+			    ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
+			     dev->name, link_info.s.speed,
+			     (link_info.s.full_duplex) ? "Full" : "Half",
+			     priv->port, priv->queue);
+		else
+			DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
+				   dev->name, link_info.s.speed,
+				   (link_info.s.full_duplex) ? "Full" : "Half",
+				   priv->port);
+	} else {
+
+		if (netif_carrier_ok(dev))
+			netif_carrier_off(dev);
+		DEBUGPRINT("%s: Link down\n", dev->name);
+	}
+}
+
+static irqreturn_t cvm_oct_rgmii_rml_interrupt(int cpl, void *dev_id)
+{
+	union cvmx_npi_rsl_int_blocks rsl_int_blocks;
+	int index;
+	irqreturn_t return_status = IRQ_NONE;
+
+	rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
+
+	/* Check and see if this interrupt was caused by the GMX0 block */
+	if (rsl_int_blocks.s.gmx0) {
+
+		int interface = 0;
+		/* Loop through every port of this interface */
+		for (index = 0;
+		     index < cvmx_helper_ports_on_interface(interface);
+		     index++) {
+
+			/* Read the GMX interrupt status bits */
+			union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
+			gmx_rx_int_reg.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
+					  (index, interface));
+			gmx_rx_int_reg.u64 &=
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
+					  (index, interface));
+			/* Poll the port if inband status changed */
+			if (gmx_rx_int_reg.s.phy_dupx
+			    || gmx_rx_int_reg.s.phy_link
+			    || gmx_rx_int_reg.s.phy_spd) {
+
+				struct net_device *dev =
+				    cvm_oct_device[cvmx_helper_get_ipd_port
+						   (interface, index)];
+				if (dev)
+					cvm_oct_rgmii_poll(dev);
+				gmx_rx_int_reg.u64 = 0;
+				gmx_rx_int_reg.s.phy_dupx = 1;
+				gmx_rx_int_reg.s.phy_link = 1;
+				gmx_rx_int_reg.s.phy_spd = 1;
+				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
+					       (index, interface),
+					       gmx_rx_int_reg.u64);
+				return_status = IRQ_HANDLED;
+			}
+		}
+	}
+
+	/* Check and see if this interrupt was caused by the GMX1 block */
+	if (rsl_int_blocks.s.gmx1) {
+
+		int interface = 1;
+		/* Loop through every port of this interface */
+		for (index = 0;
+		     index < cvmx_helper_ports_on_interface(interface);
+		     index++) {
+
+			/* Read the GMX interrupt status bits */
+			union cvmx_gmxx_rxx_int_reg gmx_rx_int_reg;
+			gmx_rx_int_reg.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_REG
+					  (index, interface));
+			gmx_rx_int_reg.u64 &=
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
+					  (index, interface));
+			/* Poll the port if inband status changed */
+			if (gmx_rx_int_reg.s.phy_dupx
+			    || gmx_rx_int_reg.s.phy_link
+			    || gmx_rx_int_reg.s.phy_spd) {
+
+				struct net_device *dev =
+				    cvm_oct_device[cvmx_helper_get_ipd_port
+						   (interface, index)];
+				if (dev)
+					cvm_oct_rgmii_poll(dev);
+				gmx_rx_int_reg.u64 = 0;
+				gmx_rx_int_reg.s.phy_dupx = 1;
+				gmx_rx_int_reg.s.phy_link = 1;
+				gmx_rx_int_reg.s.phy_spd = 1;
+				cvmx_write_csr(CVMX_GMXX_RXX_INT_REG
+					       (index, interface),
+					       gmx_rx_int_reg.u64);
+				return_status = IRQ_HANDLED;
+			}
+		}
+	}
+	return return_status;
+}
+
+static int cvm_oct_rgmii_open(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+	cvmx_helper_link_info_t link_info;
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+	if (!octeon_is_simulation()) {
+		link_info = cvmx_helper_link_get(priv->port);
+		if (!link_info.s.link_up)
+			netif_carrier_off(dev);
+	}
+
+	return 0;
+}
+
+static int cvm_oct_rgmii_stop(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+	return 0;
+}
+
+int cvm_oct_rgmii_init(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int r;
+
+	cvm_oct_common_init(dev);
+	dev->open = cvm_oct_rgmii_open;
+	dev->stop = cvm_oct_rgmii_stop;
+	dev->stop(dev);
+
+	/*
+	 * Due to GMX errata in CN3XXX series chips, it is necessary
+	 * to take the link down immediately whne the PHY changes
+	 * state. In order to do this we call the poll function every
+	 * time the RGMII inband status changes.  This may cause
+	 * problems if the PHY doesn't implement inband status
+	 * properly.
+	 */
+	if (number_rgmii_ports == 0) {
+		r = request_irq(OCTEON_IRQ_RML, cvm_oct_rgmii_rml_interrupt,
+				IRQF_SHARED, "RGMII", &number_rgmii_ports);
+	}
+	number_rgmii_ports++;
+
+	/*
+	 * Only true RGMII ports need to be polled. In GMII mode, port
+	 * 0 is really a RGMII port.
+	 */
+	if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
+	     && (priv->port == 0))
+	    || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
+
+		if (!octeon_is_simulation()) {
+
+			union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
+			int interface = INTERFACE(priv->port);
+			int index = INDEX(priv->port);
+
+			/*
+			 * Enable interrupts on inband status changes
+			 * for this port.
+			 */
+			gmx_rx_int_en.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
+					  (index, interface));
+			gmx_rx_int_en.s.phy_dupx = 1;
+			gmx_rx_int_en.s.phy_link = 1;
+			gmx_rx_int_en.s.phy_spd = 1;
+			cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
+				       gmx_rx_int_en.u64);
+			priv->poll = cvm_oct_rgmii_poll;
+		}
+	}
+
+	return 0;
+}
+
+void cvm_oct_rgmii_uninit(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvm_oct_common_uninit(dev);
+
+	/*
+	 * Only true RGMII ports need to be polled. In GMII mode, port
+	 * 0 is really a RGMII port.
+	 */
+	if (((priv->imode == CVMX_HELPER_INTERFACE_MODE_GMII)
+	     && (priv->port == 0))
+	    || (priv->imode == CVMX_HELPER_INTERFACE_MODE_RGMII)) {
+
+		if (!octeon_is_simulation()) {
+
+			union cvmx_gmxx_rxx_int_en gmx_rx_int_en;
+			int interface = INTERFACE(priv->port);
+			int index = INDEX(priv->port);
+
+			/*
+			 * Disable interrupts on inband status changes
+			 * for this port.
+			 */
+			gmx_rx_int_en.u64 =
+			    cvmx_read_csr(CVMX_GMXX_RXX_INT_EN
+					  (index, interface));
+			gmx_rx_int_en.s.phy_dupx = 0;
+			gmx_rx_int_en.s.phy_link = 0;
+			gmx_rx_int_en.s.phy_spd = 0;
+			cvmx_write_csr(CVMX_GMXX_RXX_INT_EN(index, interface),
+				       gmx_rx_int_en.u64);
+		}
+	}
+
+	/* Remove the interrupt handler when the last port is removed. */
+	number_rgmii_ports--;
+	if (number_rgmii_ports == 0)
+		free_irq(OCTEON_IRQ_RML, &number_rgmii_ports);
+}
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
new file mode 100644
index 0000000..1b237b7
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -0,0 +1,505 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/cache.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/string.h>
+#include <linux/prefetch.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+#ifdef CONFIG_XFRM
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#endif /* CONFIG_XFRM */
+
+#include <asm/atomic.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-mem.h"
+#include "ethernet-util.h"
+
+#include "cvmx-helper.h"
+#include "cvmx-wqe.h"
+#include "cvmx-fau.h"
+#include "cvmx-pow.h"
+#include "cvmx-pip.h"
+#include "cvmx-scratch.h"
+
+#include "cvmx-gmxx-defs.h"
+
+struct cvm_tasklet_wrapper {
+	struct tasklet_struct t;
+};
+
+/*
+ * Aligning the tasklet_struct on cachline boundries seems to decrease
+ * throughput even though in theory it would reduce contantion on the
+ * cache lines containing the locks.
+ */
+
+static struct cvm_tasklet_wrapper cvm_oct_tasklet[NR_CPUS];
+
+/**
+ * Interrupt handler. The interrupt occurs whenever the POW
+ * transitions from 0->1 packets in our group.
+ *
+ * @cpl:
+ * @dev_id:
+ * @regs:
+ * Returns
+ */
+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
+{
+	/* Acknowledge the interrupt */
+	if (INTERRUPT_LIMIT)
+		cvmx_write_csr(CVMX_POW_WQ_INT, 1 << pow_receive_group);
+	else
+		cvmx_write_csr(CVMX_POW_WQ_INT, 0x10001 << pow_receive_group);
+	preempt_disable();
+	tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
+	preempt_enable();
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * This is called when the kernel needs to manually poll the
+ * device. For Octeon, this is simply calling the interrupt
+ * handler. We actually poll all the devices, not just the
+ * one supplied.
+ *
+ * @dev:    Device to poll. Unused
+ */
+void cvm_oct_poll_controller(struct net_device *dev)
+{
+	preempt_disable();
+	tasklet_schedule(&cvm_oct_tasklet[smp_processor_id()].t);
+	preempt_enable();
+}
+#endif
+
+/**
+ * This is called on receive errors, and determines if the packet
+ * can be dropped early-on in cvm_oct_tasklet_rx().
+ *
+ * @work: Work queue entry pointing to the packet.
+ * Returns Non-zero if the packet can be dropped, zero otherwise.
+ */
+static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
+{
+	if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
+		/*
+		 * Ignore length errors on min size packets. Some
+		 * equipment incorrectly pads packets to 64+4FCS
+		 * instead of 60+4FCS.  Note these packets still get
+		 * counted as frame errors.
+		 */
+	} else
+	    if (USE_10MBPS_PREAMBLE_WORKAROUND
+		&& ((work->word2.snoip.err_code == 5)
+		    || (work->word2.snoip.err_code == 7))) {
+
+		/*
+		 * We received a packet with either an alignment error
+		 * or a FCS error. This may be signalling that we are
+		 * running 10Mbps with GMXX_RXX_FRM_CTL[PRE_CHK}
+		 * off. If this is the case we need to parse the
+		 * packet to determine if we can remove a non spec
+		 * preamble and generate a correct packet.
+		 */
+		int interface = cvmx_helper_get_interface_num(work->ipprt);
+		int index = cvmx_helper_get_interface_index_num(work->ipprt);
+		union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
+		gmxx_rxx_frm_ctl.u64 =
+		    cvmx_read_csr(CVMX_GMXX_RXX_FRM_CTL(index, interface));
+		if (gmxx_rxx_frm_ctl.s.pre_chk == 0) {
+
+			uint8_t *ptr =
+			    cvmx_phys_to_ptr(work->packet_ptr.s.addr);
+			int i = 0;
+
+			while (i < work->len - 1) {
+				if (*ptr != 0x55)
+					break;
+				ptr++;
+				i++;
+			}
+
+			if (*ptr == 0xd5) {
+				/*
+				   DEBUGPRINT("Port %d received 0xd5 preamble\n", work->ipprt);
+				 */
+				work->packet_ptr.s.addr += i + 1;
+				work->len -= i + 5;
+			} else if ((*ptr & 0xf) == 0xd) {
+				/*
+				   DEBUGPRINT("Port %d received 0x?d preamble\n", work->ipprt);
+				 */
+				work->packet_ptr.s.addr += i;
+				work->len -= i + 4;
+				for (i = 0; i < work->len; i++) {
+					*ptr =
+					    ((*ptr & 0xf0) >> 4) |
+					    ((*(ptr + 1) & 0xf) << 4);
+					ptr++;
+				}
+			} else {
+				DEBUGPRINT("Port %d unknown preamble, packet "
+					   "dropped\n",
+				     work->ipprt);
+				/*
+				   cvmx_helper_dump_packet(work);
+				 */
+				cvm_oct_free_work(work);
+				return 1;
+			}
+		}
+	} else {
+		DEBUGPRINT("Port %d receive error code %d, packet dropped\n",
+			   work->ipprt, work->word2.snoip.err_code);
+		cvm_oct_free_work(work);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * Tasklet function that is scheduled on a core when an interrupt occurs.
+ *
+ * @unused:
+ */
+void cvm_oct_tasklet_rx(unsigned long unused)
+{
+	const int coreid = cvmx_get_core_num();
+	uint64_t old_group_mask;
+	uint64_t old_scratch;
+	int rx_count = 0;
+	int number_to_free;
+	int num_freed;
+	int packet_not_copied;
+
+	/* Prefetch cvm_oct_device since we know we need it soon */
+	prefetch(cvm_oct_device);
+
+	if (USE_ASYNC_IOBDMA) {
+		/* Save scratch in case userspace is using it */
+		CVMX_SYNCIOBDMA;
+		old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+	}
+
+	/* Only allow work for our group (and preserve priorities) */
+	old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
+	cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
+		       (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
+
+	if (USE_ASYNC_IOBDMA)
+		cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
+
+	while (1) {
+		struct sk_buff *skb = NULL;
+		int skb_in_hw;
+		cvmx_wqe_t *work;
+
+		if (USE_ASYNC_IOBDMA) {
+			work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
+		} else {
+			if ((INTERRUPT_LIMIT == 0)
+			    || likely(rx_count < MAX_RX_PACKETS))
+				work =
+				    cvmx_pow_work_request_sync
+				    (CVMX_POW_NO_WAIT);
+			else
+				work = NULL;
+		}
+		prefetch(work);
+		if (work == NULL)
+			break;
+
+		/*
+		 * Limit each core to processing MAX_RX_PACKETS
+		 * packets without a break.  This way the RX can't
+		 * starve the TX task.
+		 */
+		if (USE_ASYNC_IOBDMA) {
+
+			if ((INTERRUPT_LIMIT == 0)
+			    || likely(rx_count < MAX_RX_PACKETS))
+				cvmx_pow_work_request_async_nocheck
+				    (CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
+			else {
+				cvmx_scratch_write64(CVMX_SCR_SCRATCH,
+						     0x8000000000000000ull);
+				cvmx_pow_tag_sw_null_nocheck();
+			}
+		}
+
+		skb_in_hw = USE_SKBUFFS_IN_HW && work->word2.s.bufs == 1;
+		if (likely(skb_in_hw)) {
+			skb =
+			    *(struct sk_buff
+			      **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
+				  sizeof(void *));
+			prefetch(&skb->head);
+			prefetch(&skb->len);
+		}
+		prefetch(cvm_oct_device[work->ipprt]);
+
+		rx_count++;
+		/* Immediately throw away all packets with receive errors */
+		if (unlikely(work->word2.snoip.rcv_error)) {
+			if (cvm_oct_check_rcv_error(work))
+				continue;
+		}
+
+		/*
+		 * We can only use the zero copy path if skbuffs are
+		 * in the FPA pool and the packet fits in a single
+		 * buffer.
+		 */
+		if (likely(skb_in_hw)) {
+			/*
+			 * This calculation was changed in case the
+			 * skb header is using a different address
+			 * aliasing type than the buffer. It doesn't
+			 * make any differnece now, but the new one is
+			 * more correct.
+			 */
+			skb->data =
+			    skb->head + work->packet_ptr.s.addr -
+			    cvmx_ptr_to_phys(skb->head);
+			prefetch(skb->data);
+			skb->len = work->len;
+			skb_set_tail_pointer(skb, skb->len);
+			packet_not_copied = 1;
+		} else {
+
+			/*
+			 * We have to copy the packet. First allocate
+			 * an skbuff for it.
+			 */
+			skb = dev_alloc_skb(work->len);
+			if (!skb) {
+				DEBUGPRINT("Port %d failed to allocate "
+					   "skbuff, packet dropped\n",
+				     work->ipprt);
+				cvm_oct_free_work(work);
+				continue;
+			}
+
+			/*
+			 * Check if we've received a packet that was
+			 * entirely stored in the work entry. This is
+			 * untested.
+			 */
+			if (unlikely(work->word2.s.bufs == 0)) {
+				uint8_t *ptr = work->packet_data;
+
+				if (likely(!work->word2.s.not_IP)) {
+					/*
+					 * The beginning of the packet
+					 * moves for IP packets.
+					 */
+					if (work->word2.s.is_v6)
+						ptr += 2;
+					else
+						ptr += 6;
+				}
+				memcpy(skb_put(skb, work->len), ptr, work->len);
+				/* No packet buffers to free */
+			} else {
+				int segments = work->word2.s.bufs;
+				union cvmx_buf_ptr segment_ptr =
+					work->packet_ptr;
+				int len = work->len;
+
+				while (segments--) {
+					union cvmx_buf_ptr next_ptr =
+					    *(union cvmx_buf_ptr *)
+					    cvmx_phys_to_ptr(segment_ptr.s.
+							     addr - 8);
+			/*
+			 * Octeon Errata PKI-100: The segment size is
+			 * wrong. Until it is fixed, calculate the
+			 * segment size based on the packet pool
+			 * buffer size. When it is fixed, the
+			 * following line should be replaced with this
+			 * one: int segment_size =
+			 * segment_ptr.s.size;
+			 */
+					int segment_size =
+					    CVMX_FPA_PACKET_POOL_SIZE -
+					    (segment_ptr.s.addr -
+					     (((segment_ptr.s.addr >> 7) -
+					       segment_ptr.s.back) << 7));
+					/* Don't copy more than what is left
+					   in the packet */
+					if (segment_size > len)
+						segment_size = len;
+					/* Copy the data into the packet */
+					memcpy(skb_put(skb, segment_size),
+					       cvmx_phys_to_ptr(segment_ptr.s.
+								addr),
+					       segment_size);
+					/* Reduce the amount of bytes left
+					   to copy */
+					len -= segment_size;
+					segment_ptr = next_ptr;
+				}
+			}
+			packet_not_copied = 0;
+		}
+
+		if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&
+			   cvm_oct_device[work->ipprt])) {
+			struct net_device *dev = cvm_oct_device[work->ipprt];
+			struct octeon_ethernet *priv = netdev_priv(dev);
+
+			/* Only accept packets for devices
+			   that are currently up */
+			if (likely(dev->flags & IFF_UP)) {
+				skb->protocol = eth_type_trans(skb, dev);
+				skb->dev = dev;
+
+				if (unlikely
+				    (work->word2.s.not_IP
+				     || work->word2.s.IP_exc
+				     || work->word2.s.L4_error))
+					skb->ip_summed = CHECKSUM_NONE;
+				else
+					skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+				/* Increment RX stats for virtual ports */
+				if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {
+#ifdef CONFIG_64BIT
+					atomic64_add(1, (atomic64_t *)&priv->stats.rx_packets);
+					atomic64_add(skb->len, (atomic64_t *)&priv->stats.rx_bytes);
+#else
+					atomic_add(1, (atomic_t *)&priv->stats.rx_packets);
+					atomic_add(skb->len, (atomic_t *)&priv->stats.rx_bytes);
+#endif
+				}
+				netif_receive_skb(skb);
+			} else {
+				/*
+				 * Drop any packet received for a
+				 * device that isn't up.
+				 */
+				/*
+				   DEBUGPRINT("%s: Device not up, packet dropped\n",
+				   dev->name);
+				 */
+#ifdef CONFIG_64BIT
+				atomic64_add(1, (atomic64_t *)&priv->stats.rx_dropped);
+#else
+				atomic_add(1, (atomic_t *)&priv->stats.rx_dropped);
+#endif
+				dev_kfree_skb_irq(skb);
+			}
+		} else {
+			/*
+			 * Drop any packet received for a device that
+			 * doesn't exist.
+			 */
+			DEBUGPRINT("Port %d not controlled by Linux, packet "
+				   "dropped\n",
+			     work->ipprt);
+			dev_kfree_skb_irq(skb);
+		}
+		/*
+		 * Check to see if the skbuff and work share the same
+		 * packet buffer.
+		 */
+		if (USE_SKBUFFS_IN_HW && likely(packet_not_copied)) {
+			/*
+			 * This buffer needs to be replaced, increment
+			 * the number of buffers we need to free by
+			 * one.
+			 */
+			cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
+					      1);
+
+			cvmx_fpa_free(work, CVMX_FPA_WQE_POOL,
+				      DONT_WRITEBACK(1));
+		} else {
+			cvm_oct_free_work(work);
+		}
+	}
+
+	/* Restore the original POW group mask */
+	cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
+	if (USE_ASYNC_IOBDMA) {
+		/* Restore the scratch area */
+		cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
+	}
+
+	if (USE_SKBUFFS_IN_HW) {
+		/* Refill the packet buffer pool */
+		number_to_free =
+		    cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
+
+		if (number_to_free > 0) {
+			cvmx_fau_atomic_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE,
+					      -number_to_free);
+			num_freed =
+			    cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL,
+						 CVMX_FPA_PACKET_POOL_SIZE,
+						 number_to_free);
+			if (num_freed != number_to_free) {
+				cvmx_fau_atomic_add32
+				    (FAU_NUM_PACKET_BUFFERS_TO_FREE,
+				     number_to_free - num_freed);
+			}
+		}
+	}
+}
+
+void cvm_oct_rx_initialize(void)
+{
+	int i;
+	/* Initialize all of the tasklets */
+	for (i = 0; i < NR_CPUS; i++)
+		tasklet_init(&cvm_oct_tasklet[i].t, cvm_oct_tasklet_rx, 0);
+}
+
+void cvm_oct_rx_shutdown(void)
+{
+	int i;
+	/* Shutdown all of the tasklets */
+	for (i = 0; i < NR_CPUS; i++)
+		tasklet_kill(&cvm_oct_tasklet[i].t);
+}
diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h
new file mode 100644
index 0000000..a9b72b8
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-rx.h
@@ -0,0 +1,33 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+
+irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id);
+void cvm_oct_poll_controller(struct net_device *dev);
+void cvm_oct_tasklet_rx(unsigned long unused);
+
+void cvm_oct_rx_initialize(void);
+void cvm_oct_rx_shutdown(void);
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
new file mode 100644
index 0000000..58fa39c
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -0,0 +1,129 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-util.h"
+#include "ethernet-common.h"
+
+#include "cvmx-helper.h"
+
+#include "cvmx-gmxx-defs.h"
+
+static int cvm_oct_sgmii_open(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+	cvmx_helper_link_info_t link_info;
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+	if (!octeon_is_simulation()) {
+		link_info = cvmx_helper_link_get(priv->port);
+		if (!link_info.s.link_up)
+			netif_carrier_off(dev);
+	}
+
+	return 0;
+}
+
+static int cvm_oct_sgmii_stop(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+	return 0;
+}
+
+static void cvm_oct_sgmii_poll(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvmx_helper_link_info_t link_info;
+
+	link_info = cvmx_helper_link_get(priv->port);
+	if (link_info.u64 == priv->link_info)
+		return;
+
+	link_info = cvmx_helper_link_autoconf(priv->port);
+	priv->link_info = link_info.u64;
+
+	/* Tell Linux */
+	if (link_info.s.link_up) {
+
+		if (!netif_carrier_ok(dev))
+			netif_carrier_on(dev);
+		if (priv->queue != -1)
+			DEBUGPRINT
+			    ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
+			     dev->name, link_info.s.speed,
+			     (link_info.s.full_duplex) ? "Full" : "Half",
+			     priv->port, priv->queue);
+		else
+			DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
+				   dev->name, link_info.s.speed,
+				   (link_info.s.full_duplex) ? "Full" : "Half",
+				   priv->port);
+	} else {
+		if (netif_carrier_ok(dev))
+			netif_carrier_off(dev);
+		DEBUGPRINT("%s: Link down\n", dev->name);
+	}
+}
+
+int cvm_oct_sgmii_init(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvm_oct_common_init(dev);
+	dev->open = cvm_oct_sgmii_open;
+	dev->stop = cvm_oct_sgmii_stop;
+	dev->stop(dev);
+	if (!octeon_is_simulation())
+		priv->poll = cvm_oct_sgmii_poll;
+
+	/* FIXME: Need autoneg logic */
+	return 0;
+}
+
+void cvm_oct_sgmii_uninit(struct net_device *dev)
+{
+	cvm_oct_common_uninit(dev);
+}
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c
new file mode 100644
index 0000000..e0971bb
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-spi.c
@@ -0,0 +1,323 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-common.h"
+#include "ethernet-util.h"
+
+#include "cvmx-spi.h"
+
+#include <asm/octeon/cvmx-npi-defs.h>
+#include "cvmx-spxx-defs.h"
+#include "cvmx-stxx-defs.h"
+
+static int number_spi_ports;
+static int need_retrain[2] = { 0, 0 };
+
+static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
+{
+	irqreturn_t return_status = IRQ_NONE;
+	union cvmx_npi_rsl_int_blocks rsl_int_blocks;
+
+	/* Check and see if this interrupt was caused by the GMX block */
+	rsl_int_blocks.u64 = cvmx_read_csr(CVMX_NPI_RSL_INT_BLOCKS);
+	if (rsl_int_blocks.s.spx1) {	/* 19 - SPX1_INT_REG & STX1_INT_REG */
+
+		union cvmx_spxx_int_reg spx_int_reg;
+		union cvmx_stxx_int_reg stx_int_reg;
+
+		spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(1));
+		cvmx_write_csr(CVMX_SPXX_INT_REG(1), spx_int_reg.u64);
+		if (!need_retrain[1]) {
+
+			spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(1));
+			if (spx_int_reg.s.spf)
+				pr_err("SPI1: SRX Spi4 interface down\n");
+			if (spx_int_reg.s.calerr)
+				pr_err("SPI1: SRX Spi4 Calendar table "
+				       "parity error\n");
+			if (spx_int_reg.s.syncerr)
+				pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
+				       "errors have exceeded "
+				       "SPX_ERR_CTL[ERRCNT]\n");
+			if (spx_int_reg.s.diperr)
+				pr_err("SPI1: SRX Spi4 DIP4 error\n");
+			if (spx_int_reg.s.tpaovr)
+				pr_err("SPI1: SRX Selected port has hit "
+				       "TPA overflow\n");
+			if (spx_int_reg.s.rsverr)
+				pr_err("SPI1: SRX Spi4 reserved control "
+				       "word detected\n");
+			if (spx_int_reg.s.drwnng)
+				pr_err("SPI1: SRX Spi4 receive FIFO "
+				       "drowning/overflow\n");
+			if (spx_int_reg.s.clserr)
+				pr_err("SPI1: SRX Spi4 packet closed on "
+				       "non-16B alignment without EOP\n");
+			if (spx_int_reg.s.spiovr)
+				pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
+			if (spx_int_reg.s.abnorm)
+				pr_err("SPI1: SRX Abnormal packet "
+				       "termination (ERR bit)\n");
+			if (spx_int_reg.s.prtnxa)
+				pr_err("SPI1: SRX Port out of range\n");
+		}
+
+		stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(1));
+		cvmx_write_csr(CVMX_STXX_INT_REG(1), stx_int_reg.u64);
+		if (!need_retrain[1]) {
+
+			stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
+			if (stx_int_reg.s.syncerr)
+				pr_err("SPI1: STX Interface encountered a "
+				       "fatal error\n");
+			if (stx_int_reg.s.frmerr)
+				pr_err("SPI1: STX FRMCNT has exceeded "
+				       "STX_DIP_CNT[MAXFRM]\n");
+			if (stx_int_reg.s.unxfrm)
+				pr_err("SPI1: STX Unexpected framing "
+				       "sequence\n");
+			if (stx_int_reg.s.nosync)
+				pr_err("SPI1: STX ERRCNT has exceeded "
+				       "STX_DIP_CNT[MAXDIP]\n");
+			if (stx_int_reg.s.diperr)
+				pr_err("SPI1: STX DIP2 error on the Spi4 "
+				       "Status channel\n");
+			if (stx_int_reg.s.datovr)
+				pr_err("SPI1: STX Spi4 FIFO overflow error\n");
+			if (stx_int_reg.s.ovrbst)
+				pr_err("SPI1: STX Transmit packet burst "
+				       "too big\n");
+			if (stx_int_reg.s.calpar1)
+				pr_err("SPI1: STX Calendar Table Parity "
+				       "Error Bank1\n");
+			if (stx_int_reg.s.calpar0)
+				pr_err("SPI1: STX Calendar Table Parity "
+				       "Error Bank0\n");
+		}
+
+		cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
+		cvmx_write_csr(CVMX_STXX_INT_MSK(1), 0);
+		need_retrain[1] = 1;
+		return_status = IRQ_HANDLED;
+	}
+
+	if (rsl_int_blocks.s.spx0) {	/* 18 - SPX0_INT_REG & STX0_INT_REG */
+		union cvmx_spxx_int_reg spx_int_reg;
+		union cvmx_stxx_int_reg stx_int_reg;
+
+		spx_int_reg.u64 = cvmx_read_csr(CVMX_SPXX_INT_REG(0));
+		cvmx_write_csr(CVMX_SPXX_INT_REG(0), spx_int_reg.u64);
+		if (!need_retrain[0]) {
+
+			spx_int_reg.u64 &= cvmx_read_csr(CVMX_SPXX_INT_MSK(0));
+			if (spx_int_reg.s.spf)
+				pr_err("SPI0: SRX Spi4 interface down\n");
+			if (spx_int_reg.s.calerr)
+				pr_err("SPI0: SRX Spi4 Calendar table "
+				       "parity error\n");
+			if (spx_int_reg.s.syncerr)
+				pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
+				       "errors have exceeded "
+				       "SPX_ERR_CTL[ERRCNT]\n");
+			if (spx_int_reg.s.diperr)
+				pr_err("SPI0: SRX Spi4 DIP4 error\n");
+			if (spx_int_reg.s.tpaovr)
+				pr_err("SPI0: SRX Selected port has hit "
+				       "TPA overflow\n");
+			if (spx_int_reg.s.rsverr)
+				pr_err("SPI0: SRX Spi4 reserved control "
+				       "word detected\n");
+			if (spx_int_reg.s.drwnng)
+				pr_err("SPI0: SRX Spi4 receive FIFO "
+				       "drowning/overflow\n");
+			if (spx_int_reg.s.clserr)
+				pr_err("SPI0: SRX Spi4 packet closed on "
+				       "non-16B alignment without EOP\n");
+			if (spx_int_reg.s.spiovr)
+				pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
+			if (spx_int_reg.s.abnorm)
+				pr_err("SPI0: SRX Abnormal packet "
+				       "termination (ERR bit)\n");
+			if (spx_int_reg.s.prtnxa)
+				pr_err("SPI0: SRX Port out of range\n");
+		}
+
+		stx_int_reg.u64 = cvmx_read_csr(CVMX_STXX_INT_REG(0));
+		cvmx_write_csr(CVMX_STXX_INT_REG(0), stx_int_reg.u64);
+		if (!need_retrain[0]) {
+
+			stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
+			if (stx_int_reg.s.syncerr)
+				pr_err("SPI0: STX Interface encountered a "
+				       "fatal error\n");
+			if (stx_int_reg.s.frmerr)
+				pr_err("SPI0: STX FRMCNT has exceeded "
+				       "STX_DIP_CNT[MAXFRM]\n");
+			if (stx_int_reg.s.unxfrm)
+				pr_err("SPI0: STX Unexpected framing "
+				       "sequence\n");
+			if (stx_int_reg.s.nosync)
+				pr_err("SPI0: STX ERRCNT has exceeded "
+				       "STX_DIP_CNT[MAXDIP]\n");
+			if (stx_int_reg.s.diperr)
+				pr_err("SPI0: STX DIP2 error on the Spi4 "
+				       "Status channel\n");
+			if (stx_int_reg.s.datovr)
+				pr_err("SPI0: STX Spi4 FIFO overflow error\n");
+			if (stx_int_reg.s.ovrbst)
+				pr_err("SPI0: STX Transmit packet burst "
+				       "too big\n");
+			if (stx_int_reg.s.calpar1)
+				pr_err("SPI0: STX Calendar Table Parity "
+				       "Error Bank1\n");
+			if (stx_int_reg.s.calpar0)
+				pr_err("SPI0: STX Calendar Table Parity "
+				       "Error Bank0\n");
+		}
+
+		cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
+		cvmx_write_csr(CVMX_STXX_INT_MSK(0), 0);
+		need_retrain[0] = 1;
+		return_status = IRQ_HANDLED;
+	}
+
+	return return_status;
+}
+
+static void cvm_oct_spi_enable_error_reporting(int interface)
+{
+	union cvmx_spxx_int_msk spxx_int_msk;
+	union cvmx_stxx_int_msk stxx_int_msk;
+
+	spxx_int_msk.u64 = cvmx_read_csr(CVMX_SPXX_INT_MSK(interface));
+	spxx_int_msk.s.calerr = 1;
+	spxx_int_msk.s.syncerr = 1;
+	spxx_int_msk.s.diperr = 1;
+	spxx_int_msk.s.tpaovr = 1;
+	spxx_int_msk.s.rsverr = 1;
+	spxx_int_msk.s.drwnng = 1;
+	spxx_int_msk.s.clserr = 1;
+	spxx_int_msk.s.spiovr = 1;
+	spxx_int_msk.s.abnorm = 1;
+	spxx_int_msk.s.prtnxa = 1;
+	cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), spxx_int_msk.u64);
+
+	stxx_int_msk.u64 = cvmx_read_csr(CVMX_STXX_INT_MSK(interface));
+	stxx_int_msk.s.frmerr = 1;
+	stxx_int_msk.s.unxfrm = 1;
+	stxx_int_msk.s.nosync = 1;
+	stxx_int_msk.s.diperr = 1;
+	stxx_int_msk.s.datovr = 1;
+	stxx_int_msk.s.ovrbst = 1;
+	stxx_int_msk.s.calpar1 = 1;
+	stxx_int_msk.s.calpar0 = 1;
+	cvmx_write_csr(CVMX_STXX_INT_MSK(interface), stxx_int_msk.u64);
+}
+
+static void cvm_oct_spi_poll(struct net_device *dev)
+{
+	static int spi4000_port;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface;
+
+	for (interface = 0; interface < 2; interface++) {
+
+		if ((priv->port == interface * 16) && need_retrain[interface]) {
+
+			if (cvmx_spi_restart_interface
+			    (interface, CVMX_SPI_MODE_DUPLEX, 10) == 0) {
+				need_retrain[interface] = 0;
+				cvm_oct_spi_enable_error_reporting(interface);
+			}
+		}
+
+		/*
+		 * The SPI4000 TWSI interface is very slow. In order
+		 * not to bring the system to a crawl, we only poll a
+		 * single port every second. This means negotiation
+		 * speed changes take up to 10 seconds, but at least
+		 * we don't waste absurd amounts of time waiting for
+		 * TWSI.
+		 */
+		if (priv->port == spi4000_port) {
+			/*
+			 * This function does nothing if it is called on an
+			 * interface without a SPI4000.
+			 */
+			cvmx_spi4000_check_speed(interface, priv->port);
+			/*
+			 * Normal ordering increments. By decrementing
+			 * we only match once per iteration.
+			 */
+			spi4000_port--;
+			if (spi4000_port < 0)
+				spi4000_port = 10;
+		}
+	}
+}
+
+int cvm_oct_spi_init(struct net_device *dev)
+{
+	int r;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+
+	if (number_spi_ports == 0) {
+		r = request_irq(OCTEON_IRQ_RML, cvm_oct_spi_rml_interrupt,
+				IRQF_SHARED, "SPI", &number_spi_ports);
+	}
+	number_spi_ports++;
+
+	if ((priv->port == 0) || (priv->port == 16)) {
+		cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
+		priv->poll = cvm_oct_spi_poll;
+	}
+	cvm_oct_common_init(dev);
+	return 0;
+}
+
+void cvm_oct_spi_uninit(struct net_device *dev)
+{
+	int interface;
+
+	cvm_oct_common_uninit(dev);
+	number_spi_ports--;
+	if (number_spi_ports == 0) {
+		for (interface = 0; interface < 2; interface++) {
+			cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
+			cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
+		}
+		free_irq(8 + 46, &number_spi_ports);
+	}
+}
diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
new file mode 100644
index 0000000..77b7122
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-tx.c
@@ -0,0 +1,634 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/init.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/string.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <net/dst.h>
+#ifdef CONFIG_XFRM
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#endif /* CONFIG_XFRM */
+
+#include <asm/atomic.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-util.h"
+
+#include "cvmx-wqe.h"
+#include "cvmx-fau.h"
+#include "cvmx-pko.h"
+#include "cvmx-helper.h"
+
+#include "cvmx-gmxx-defs.h"
+
+/*
+ * You can define GET_SKBUFF_QOS() to override how the skbuff output
+ * function determines which output queue is used. The default
+ * implementation always uses the base queue for the port. If, for
+ * example, you wanted to use the skb->priority fieid, define
+ * GET_SKBUFF_QOS as: #define GET_SKBUFF_QOS(skb) ((skb)->priority)
+ */
+#ifndef GET_SKBUFF_QOS
+#define GET_SKBUFF_QOS(skb) 0
+#endif
+
+/**
+ * Packet transmit
+ *
+ * @skb:    Packet to send
+ * @dev:    Device info structure
+ * Returns Always returns zero
+ */
+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	cvmx_pko_command_word0_t pko_command;
+	union cvmx_buf_ptr hw_buffer;
+	uint64_t old_scratch;
+	uint64_t old_scratch2;
+	int dropped;
+	int qos;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int32_t in_use;
+	int32_t buffers_to_free;
+#if REUSE_SKBUFFS_WITHOUT_FREE
+	unsigned char *fpa_head;
+#endif
+
+	/*
+	 * Prefetch the private data structure.  It is larger that one
+	 * cache line.
+	 */
+	prefetch(priv);
+
+	/* Start off assuming no drop */
+	dropped = 0;
+
+	/*
+	 * The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to
+	 * completely remove "qos" in the event neither interface
+	 * supports multiple queues per port.
+	 */
+	if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
+	    (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
+		qos = GET_SKBUFF_QOS(skb);
+		if (qos <= 0)
+			qos = 0;
+		else if (qos >= cvmx_pko_get_num_queues(priv->port))
+			qos = 0;
+	} else
+		qos = 0;
+
+	if (USE_ASYNC_IOBDMA) {
+		/* Save scratch in case userspace is using it */
+		CVMX_SYNCIOBDMA;
+		old_scratch = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+		old_scratch2 = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
+
+		/*
+		 * Assume we're going to be able t osend this
+		 * packet. Fetch and increment the number of pending
+		 * packets for output.
+		 */
+		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH + 8,
+					       FAU_NUM_PACKET_BUFFERS_TO_FREE,
+					       0);
+		cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH,
+					       priv->fau + qos * 4, 1);
+	}
+
+	/*
+	 * The CN3XXX series of parts has an errata (GMX-401) which
+	 * causes the GMX block to hang if a collision occurs towards
+	 * the end of a <68 byte packet. As a workaround for this, we
+	 * pad packets to be 68 bytes whenever we are in half duplex
+	 * mode. We don't handle the case of having a small packet but
+	 * no room to add the padding.  The kernel should always give
+	 * us at least a cache line
+	 */
+	if ((skb->len < 64) && OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+		union cvmx_gmxx_prtx_cfg gmx_prt_cfg;
+		int interface = INTERFACE(priv->port);
+		int index = INDEX(priv->port);
+
+		if (interface < 2) {
+			/* We only need to pad packet in half duplex mode */
+			gmx_prt_cfg.u64 =
+			    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+			if (gmx_prt_cfg.s.duplex == 0) {
+				int add_bytes = 64 - skb->len;
+				if ((skb_tail_pointer(skb) + add_bytes) <=
+				    skb_end_pointer(skb))
+					memset(__skb_put(skb, add_bytes), 0,
+					       add_bytes);
+			}
+		}
+	}
+
+	/* Build the PKO buffer pointer */
+	hw_buffer.u64 = 0;
+	hw_buffer.s.addr = cvmx_ptr_to_phys(skb->data);
+	hw_buffer.s.pool = 0;
+	hw_buffer.s.size =
+	    (unsigned long)skb_end_pointer(skb) - (unsigned long)skb->head;
+
+	/* Build the PKO command */
+	pko_command.u64 = 0;
+	pko_command.s.n2 = 1;	/* Don't pollute L2 with the outgoing packet */
+	pko_command.s.segs = 1;
+	pko_command.s.total_bytes = skb->len;
+	pko_command.s.size0 = CVMX_FAU_OP_SIZE_32;
+	pko_command.s.subone0 = 1;
+
+	pko_command.s.dontfree = 1;
+	pko_command.s.reg0 = priv->fau + qos * 4;
+	/*
+	 * See if we can put this skb in the FPA pool. Any strange
+	 * behavior from the Linux networking stack will most likely
+	 * be caused by a bug in the following code. If some field is
+	 * in use by the network stack and get carried over when a
+	 * buffer is reused, bad thing may happen.  If in doubt and
+	 * you dont need the absolute best performance, disable the
+	 * define REUSE_SKBUFFS_WITHOUT_FREE. The reuse of buffers has
+	 * shown a 25% increase in performance under some loads.
+	 */
+#if REUSE_SKBUFFS_WITHOUT_FREE
+	fpa_head = skb->head + 128 - ((unsigned long)skb->head & 0x7f);
+	if (unlikely(skb->data < fpa_head)) {
+		/*
+		 * printk("TX buffer beginning can't meet FPA
+		 * alignment constraints\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely
+	    ((skb_end_pointer(skb) - fpa_head) < CVMX_FPA_PACKET_POOL_SIZE)) {
+		/*
+		   printk("TX buffer isn't large enough for the FPA\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely(skb_shared(skb))) {
+		/*
+		   printk("TX buffer sharing data with someone else\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely(skb_cloned(skb))) {
+		/*
+		   printk("TX buffer has been cloned\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely(skb_header_cloned(skb))) {
+		/*
+		   printk("TX buffer header has been cloned\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely(skb->destructor)) {
+		/*
+		   printk("TX buffer has a destructor\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely(skb_shinfo(skb)->nr_frags)) {
+		/*
+		   printk("TX buffer has fragments\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+	if (unlikely
+	    (skb->truesize !=
+	     sizeof(*skb) + skb_end_pointer(skb) - skb->head)) {
+		/*
+		   printk("TX buffer truesize has been changed\n");
+		 */
+		goto dont_put_skbuff_in_hw;
+	}
+
+	/*
+	 * We can use this buffer in the FPA.  We don't need the FAU
+	 * update anymore
+	 */
+	pko_command.s.reg0 = 0;
+	pko_command.s.dontfree = 0;
+
+	hw_buffer.s.back = (skb->data - fpa_head) >> 7;
+	*(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
+
+	/*
+	 * The skbuff will be reused without ever being freed. We must
+	 * cleanup a bunch of Linux stuff.
+	 */
+	dst_release(skb->dst);
+	skb->dst = NULL;
+#ifdef CONFIG_XFRM
+	secpath_put(skb->sp);
+	skb->sp = NULL;
+#endif
+	nf_reset(skb);
+
+#ifdef CONFIG_NET_SCHED
+	skb->tc_index = 0;
+#ifdef CONFIG_NET_CLS_ACT
+	skb->tc_verd = 0;
+#endif /* CONFIG_NET_CLS_ACT */
+#endif /* CONFIG_NET_SCHED */
+
+dont_put_skbuff_in_hw:
+#endif /* REUSE_SKBUFFS_WITHOUT_FREE */
+
+	/* Check if we can use the hardware checksumming */
+	if (USE_HW_TCPUDP_CHECKSUM && (skb->protocol == htons(ETH_P_IP)) &&
+	    (ip_hdr(skb)->version == 4) && (ip_hdr(skb)->ihl == 5) &&
+	    ((ip_hdr(skb)->frag_off == 0) || (ip_hdr(skb)->frag_off == 1 << 14))
+	    && ((ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
+		|| (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP))) {
+		/* Use hardware checksum calc */
+		pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
+	}
+
+	if (USE_ASYNC_IOBDMA) {
+		/* Get the number of skbuffs in use by the hardware */
+		CVMX_SYNCIOBDMA;
+		in_use = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+		buffers_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH + 8);
+	} else {
+		/* Get the number of skbuffs in use by the hardware */
+		in_use = cvmx_fau_fetch_and_add32(priv->fau + qos * 4, 1);
+		buffers_to_free =
+		    cvmx_fau_fetch_and_add32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
+	}
+
+	/*
+	 * If we're sending faster than the receive can free them then
+	 * don't do the HW free.
+	 */
+	if ((buffers_to_free < -100) && !pko_command.s.dontfree) {
+		pko_command.s.dontfree = 1;
+		pko_command.s.reg0 = priv->fau + qos * 4;
+	}
+
+	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
+				     CVMX_PKO_LOCK_CMD_QUEUE);
+
+	/* Drop this packet if we have too many already queued to the HW */
+	if (unlikely
+	    (skb_queue_len(&priv->tx_free_list[qos]) >= MAX_OUT_QUEUE_DEPTH)) {
+		/*
+		   DEBUGPRINT("%s: Tx dropped. Too many queued\n", dev->name);
+		 */
+		dropped = 1;
+	}
+	/* Send the packet to the output queue */
+	else if (unlikely
+		 (cvmx_pko_send_packet_finish
+		  (priv->port, priv->queue + qos, pko_command, hw_buffer,
+		   CVMX_PKO_LOCK_CMD_QUEUE))) {
+		DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
+		dropped = 1;
+	}
+
+	if (USE_ASYNC_IOBDMA) {
+		/* Restore the scratch area */
+		cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
+		cvmx_scratch_write64(CVMX_SCR_SCRATCH + 8, old_scratch2);
+	}
+
+	if (unlikely(dropped)) {
+		dev_kfree_skb_any(skb);
+		cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
+		priv->stats.tx_dropped++;
+	} else {
+		if (USE_SKBUFFS_IN_HW) {
+			/* Put this packet on the queue to be freed later */
+			if (pko_command.s.dontfree)
+				skb_queue_tail(&priv->tx_free_list[qos], skb);
+			else {
+				cvmx_fau_atomic_add32
+				    (FAU_NUM_PACKET_BUFFERS_TO_FREE, -1);
+				cvmx_fau_atomic_add32(priv->fau + qos * 4, -1);
+			}
+		} else {
+			/* Put this packet on the queue to be freed later */
+			skb_queue_tail(&priv->tx_free_list[qos], skb);
+		}
+	}
+
+	/* Free skbuffs not in use by the hardware, possibly two at a time */
+	if (skb_queue_len(&priv->tx_free_list[qos]) > in_use) {
+		spin_lock(&priv->tx_free_list[qos].lock);
+		/*
+		 * Check again now that we have the lock. It might
+		 * have changed.
+		 */
+		if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
+			dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
+		if (skb_queue_len(&priv->tx_free_list[qos]) > in_use)
+			dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
+		spin_unlock(&priv->tx_free_list[qos].lock);
+	}
+
+	return 0;
+}
+
+/**
+ * Packet transmit to the POW
+ *
+ * @skb:    Packet to send
+ * @dev:    Device info structure
+ * Returns Always returns zero
+ */
+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	void *packet_buffer;
+	void *copy_location;
+
+	/* Get a work queue entry */
+	cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
+	if (unlikely(work == NULL)) {
+		DEBUGPRINT("%s: Failed to allocate a work queue entry\n",
+			   dev->name);
+		priv->stats.tx_dropped++;
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	/* Get a packet buffer */
+	packet_buffer = cvmx_fpa_alloc(CVMX_FPA_PACKET_POOL);
+	if (unlikely(packet_buffer == NULL)) {
+		DEBUGPRINT("%s: Failed to allocate a packet buffer\n",
+			   dev->name);
+		cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
+		priv->stats.tx_dropped++;
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	/*
+	 * Calculate where we need to copy the data to. We need to
+	 * leave 8 bytes for a next pointer (unused). We also need to
+	 * include any configure skip. Then we need to align the IP
+	 * packet src and dest into the same 64bit word. The below
+	 * calculation may add a little extra, but that doesn't
+	 * hurt.
+	 */
+	copy_location = packet_buffer + sizeof(uint64_t);
+	copy_location += ((CVMX_HELPER_FIRST_MBUFF_SKIP + 7) & 0xfff8) + 6;
+
+	/*
+	 * We have to copy the packet since whoever processes this
+	 * packet will free it to a hardware pool. We can't use the
+	 * trick of counting outstanding packets like in
+	 * cvm_oct_xmit.
+	 */
+	memcpy(copy_location, skb->data, skb->len);
+
+	/*
+	 * Fill in some of the work queue fields. We may need to add
+	 * more if the software at the other end needs them.
+	 */
+	work->hw_chksum = skb->csum;
+	work->len = skb->len;
+	work->ipprt = priv->port;
+	work->qos = priv->port & 0x7;
+	work->grp = pow_send_group;
+	work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
+	work->tag = pow_send_group;	/* FIXME */
+	/* Default to zero. Sets of zero later are commented out */
+	work->word2.u64 = 0;
+	work->word2.s.bufs = 1;
+	work->packet_ptr.u64 = 0;
+	work->packet_ptr.s.addr = cvmx_ptr_to_phys(copy_location);
+	work->packet_ptr.s.pool = CVMX_FPA_PACKET_POOL;
+	work->packet_ptr.s.size = CVMX_FPA_PACKET_POOL_SIZE;
+	work->packet_ptr.s.back = (copy_location - packet_buffer) >> 7;
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+		work->word2.s.ip_offset = 14;
+#if 0
+		work->word2.s.vlan_valid = 0;	/* FIXME */
+		work->word2.s.vlan_cfi = 0;	/* FIXME */
+		work->word2.s.vlan_id = 0;	/* FIXME */
+		work->word2.s.dec_ipcomp = 0;	/* FIXME */
+#endif
+		work->word2.s.tcp_or_udp =
+		    (ip_hdr(skb)->protocol == IP_PROTOCOL_TCP)
+		    || (ip_hdr(skb)->protocol == IP_PROTOCOL_UDP);
+#if 0
+		/* FIXME */
+		work->word2.s.dec_ipsec = 0;
+		/* We only support IPv4 right now */
+		work->word2.s.is_v6 = 0;
+		/* Hardware would set to zero */
+		work->word2.s.software = 0;
+		/* No error, packet is internal */
+		work->word2.s.L4_error = 0;
+#endif
+		work->word2.s.is_frag = !((ip_hdr(skb)->frag_off == 0)
+					  || (ip_hdr(skb)->frag_off ==
+					      1 << 14));
+#if 0
+		/* Assume Linux is sending a good packet */
+		work->word2.s.IP_exc = 0;
+#endif
+		work->word2.s.is_bcast = (skb->pkt_type == PACKET_BROADCAST);
+		work->word2.s.is_mcast = (skb->pkt_type == PACKET_MULTICAST);
+#if 0
+		/* This is an IP packet */
+		work->word2.s.not_IP = 0;
+		/* No error, packet is internal */
+		work->word2.s.rcv_error = 0;
+		/* No error, packet is internal */
+		work->word2.s.err_code = 0;
+#endif
+
+		/*
+		 * When copying the data, include 4 bytes of the
+		 * ethernet header to align the same way hardware
+		 * does.
+		 */
+		memcpy(work->packet_data, skb->data + 10,
+		       sizeof(work->packet_data));
+	} else {
+#if 0
+		work->word2.snoip.vlan_valid = 0;	/* FIXME */
+		work->word2.snoip.vlan_cfi = 0;	/* FIXME */
+		work->word2.snoip.vlan_id = 0;	/* FIXME */
+		work->word2.snoip.software = 0;	/* Hardware would set to zero */
+#endif
+		work->word2.snoip.is_rarp = skb->protocol == htons(ETH_P_RARP);
+		work->word2.snoip.is_arp = skb->protocol == htons(ETH_P_ARP);
+		work->word2.snoip.is_bcast =
+		    (skb->pkt_type == PACKET_BROADCAST);
+		work->word2.snoip.is_mcast =
+		    (skb->pkt_type == PACKET_MULTICAST);
+		work->word2.snoip.not_IP = 1;	/* IP was done up above */
+#if 0
+		/* No error, packet is internal */
+		work->word2.snoip.rcv_error = 0;
+		/* No error, packet is internal */
+		work->word2.snoip.err_code = 0;
+#endif
+		memcpy(work->packet_data, skb->data, sizeof(work->packet_data));
+	}
+
+	/* Submit the packet to the POW */
+	cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
+			     work->grp);
+	priv->stats.tx_packets++;
+	priv->stats.tx_bytes += skb->len;
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+/**
+ * Transmit a work queue entry out of the ethernet port. Both
+ * the work queue entry and the packet data can optionally be
+ * freed. The work will be freed on error as well.
+ *
+ * @dev:     Device to transmit out.
+ * @work_queue_entry:
+ *                Work queue entry to send
+ * @do_free: True if the work queue entry and packet data should be
+ *                freed. If false, neither will be freed.
+ * @qos:     Index into the queues for this port to transmit on. This
+ *                is used to implement QoS if their are multiple queues per
+ *                port. This parameter must be between 0 and the number of
+ *                queues per port minus 1. Values outside of this range will
+ *                be change to zero.
+ *
+ * Returns Zero on success, negative on failure.
+ */
+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
+			 int do_free, int qos)
+{
+	unsigned long flags;
+	union cvmx_buf_ptr hw_buffer;
+	cvmx_pko_command_word0_t pko_command;
+	int dropped;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvmx_wqe_t *work = work_queue_entry;
+
+	if (!(dev->flags & IFF_UP)) {
+		DEBUGPRINT("%s: Device not up\n", dev->name);
+		if (do_free)
+			cvm_oct_free_work(work);
+		return -1;
+	}
+
+	/* The check on CVMX_PKO_QUEUES_PER_PORT_* is designed to completely
+	   remove "qos" in the event neither interface supports
+	   multiple queues per port */
+	if ((CVMX_PKO_QUEUES_PER_PORT_INTERFACE0 > 1) ||
+	    (CVMX_PKO_QUEUES_PER_PORT_INTERFACE1 > 1)) {
+		if (qos <= 0)
+			qos = 0;
+		else if (qos >= cvmx_pko_get_num_queues(priv->port))
+			qos = 0;
+	} else
+		qos = 0;
+
+	/* Start off assuming no drop */
+	dropped = 0;
+
+	local_irq_save(flags);
+	cvmx_pko_send_packet_prepare(priv->port, priv->queue + qos,
+				     CVMX_PKO_LOCK_CMD_QUEUE);
+
+	/* Build the PKO buffer pointer */
+	hw_buffer.u64 = 0;
+	hw_buffer.s.addr = work->packet_ptr.s.addr;
+	hw_buffer.s.pool = CVMX_FPA_PACKET_POOL;
+	hw_buffer.s.size = CVMX_FPA_PACKET_POOL_SIZE;
+	hw_buffer.s.back = work->packet_ptr.s.back;
+
+	/* Build the PKO command */
+	pko_command.u64 = 0;
+	pko_command.s.n2 = 1;	/* Don't pollute L2 with the outgoing packet */
+	pko_command.s.dontfree = !do_free;
+	pko_command.s.segs = work->word2.s.bufs;
+	pko_command.s.total_bytes = work->len;
+
+	/* Check if we can use the hardware checksumming */
+	if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc))
+		pko_command.s.ipoffp1 = 0;
+	else
+		pko_command.s.ipoffp1 = sizeof(struct ethhdr) + 1;
+
+	/* Send the packet to the output queue */
+	if (unlikely
+	    (cvmx_pko_send_packet_finish
+	     (priv->port, priv->queue + qos, pko_command, hw_buffer,
+	      CVMX_PKO_LOCK_CMD_QUEUE))) {
+		DEBUGPRINT("%s: Failed to send the packet\n", dev->name);
+		dropped = -1;
+	}
+	local_irq_restore(flags);
+
+	if (unlikely(dropped)) {
+		if (do_free)
+			cvm_oct_free_work(work);
+		priv->stats.tx_dropped++;
+	} else if (do_free)
+		cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
+
+	return dropped;
+}
+EXPORT_SYMBOL(cvm_oct_transmit_qos);
+
+/**
+ * This function frees all skb that are currenty queued for TX.
+ *
+ * @dev:    Device being shutdown
+ */
+void cvm_oct_tx_shutdown(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	unsigned long flags;
+	int qos;
+
+	for (qos = 0; qos < 16; qos++) {
+		spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+		while (skb_queue_len(&priv->tx_free_list[qos]))
+			dev_kfree_skb_any(__skb_dequeue
+					  (&priv->tx_free_list[qos]));
+		spin_unlock_irqrestore(&priv->tx_free_list[qos].lock, flags);
+	}
+}
diff --git a/drivers/staging/octeon/ethernet-tx.h b/drivers/staging/octeon/ethernet-tx.h
new file mode 100644
index 0000000..5106236
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-tx.h
@@ -0,0 +1,32 @@
+/*********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+
+int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev);
+int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
+			 int do_free, int qos);
+void cvm_oct_tx_shutdown(struct net_device *dev);
diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h
new file mode 100644
index 0000000..37b6659
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-util.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+*********************************************************************/
+
+#define DEBUGPRINT(format, ...) do { if (printk_ratelimit()) 		\
+					printk(format, ##__VA_ARGS__);	\
+				} while (0)
+
+/**
+ * Given a packet data address, return a pointer to the
+ * beginning of the packet buffer.
+ *
+ * @packet_ptr: Packet data hardware address
+ * Returns Packet buffer pointer
+ */
+static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr)
+{
+	return cvmx_phys_to_ptr(((packet_ptr.s.addr >> 7) - packet_ptr.s.back)
+				<< 7);
+}
+
+/**
+ * Given an IPD/PKO port number, return the logical interface it is
+ * on.
+ *
+ * @ipd_port: Port to check
+ *
+ * Returns Logical interface
+ */
+static inline int INTERFACE(int ipd_port)
+{
+	if (ipd_port < 32)	/* Interface 0 or 1 for RGMII,GMII,SPI, etc */
+		return ipd_port >> 4;
+	else if (ipd_port < 36)	/* Interface 2 for NPI */
+		return 2;
+	else if (ipd_port < 40)	/* Interface 3 for loopback */
+		return 3;
+	else if (ipd_port == 40)	/* Non existant interface for POW0 */
+		return 4;
+	else
+		panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
+}
+
+/**
+ * Given an IPD/PKO port number, return the port's index on a
+ * logical interface.
+ *
+ * @ipd_port: Port to check
+ *
+ * Returns Index into interface port list
+ */
+static inline int INDEX(int ipd_port)
+{
+	if (ipd_port < 32)
+		return ipd_port & 15;
+	else
+		return ipd_port & 3;
+}
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
new file mode 100644
index 0000000..f08eb32
--- /dev/null
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -0,0 +1,127 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "octeon-ethernet.h"
+#include "ethernet-common.h"
+#include "ethernet-util.h"
+
+#include "cvmx-helper.h"
+
+#include "cvmx-gmxx-defs.h"
+
+static int cvm_oct_xaui_open(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+	cvmx_helper_link_info_t link_info;
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 1;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+
+	if (!octeon_is_simulation()) {
+		link_info = cvmx_helper_link_get(priv->port);
+		if (!link_info.s.link_up)
+			netif_carrier_off(dev);
+	}
+	return 0;
+}
+
+static int cvm_oct_xaui_stop(struct net_device *dev)
+{
+	union cvmx_gmxx_prtx_cfg gmx_cfg;
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	int interface = INTERFACE(priv->port);
+	int index = INDEX(priv->port);
+
+	gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
+	gmx_cfg.s.en = 0;
+	cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64);
+	return 0;
+}
+
+static void cvm_oct_xaui_poll(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvmx_helper_link_info_t link_info;
+
+	link_info = cvmx_helper_link_get(priv->port);
+	if (link_info.u64 == priv->link_info)
+		return;
+
+	link_info = cvmx_helper_link_autoconf(priv->port);
+	priv->link_info = link_info.u64;
+
+	/* Tell Linux */
+	if (link_info.s.link_up) {
+
+		if (!netif_carrier_ok(dev))
+			netif_carrier_on(dev);
+		if (priv->queue != -1)
+			DEBUGPRINT
+			    ("%s: %u Mbps %s duplex, port %2d, queue %2d\n",
+			     dev->name, link_info.s.speed,
+			     (link_info.s.full_duplex) ? "Full" : "Half",
+			     priv->port, priv->queue);
+		else
+			DEBUGPRINT("%s: %u Mbps %s duplex, port %2d, POW\n",
+				   dev->name, link_info.s.speed,
+				   (link_info.s.full_duplex) ? "Full" : "Half",
+				   priv->port);
+	} else {
+		if (netif_carrier_ok(dev))
+			netif_carrier_off(dev);
+		DEBUGPRINT("%s: Link down\n", dev->name);
+	}
+}
+
+int cvm_oct_xaui_init(struct net_device *dev)
+{
+	struct octeon_ethernet *priv = netdev_priv(dev);
+	cvm_oct_common_init(dev);
+	dev->open = cvm_oct_xaui_open;
+	dev->stop = cvm_oct_xaui_stop;
+	dev->stop(dev);
+	if (!octeon_is_simulation())
+		priv->poll = cvm_oct_xaui_poll;
+
+	return 0;
+}
+
+void cvm_oct_xaui_uninit(struct net_device *dev)
+{
+	cvm_oct_common_uninit(dev);
+}
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
new file mode 100644
index 0000000..e8ef9e0
--- /dev/null
+++ b/drivers/staging/octeon/ethernet.c
@@ -0,0 +1,507 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+
+#include <net/dst.h>
+
+#include <asm/octeon/octeon.h>
+
+#include "ethernet-defines.h"
+#include "ethernet-mem.h"
+#include "ethernet-rx.h"
+#include "ethernet-tx.h"
+#include "ethernet-util.h"
+#include "ethernet-proc.h"
+#include "ethernet-common.h"
+#include "octeon-ethernet.h"
+
+#include "cvmx-pip.h"
+#include "cvmx-pko.h"
+#include "cvmx-fau.h"
+#include "cvmx-ipd.h"
+#include "cvmx-helper.h"
+
+#include "cvmx-smix-defs.h"
+
+#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
+	&& CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
+int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
+#else
+int num_packet_buffers = 1024;
+#endif
+module_param(num_packet_buffers, int, 0444);
+MODULE_PARM_DESC(num_packet_buffers, "\n"
+	"\tNumber of packet buffers to allocate and store in the\n"
+	"\tFPA. By default, 1024 packet buffers are used unless\n"
+	"\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
+
+int pow_receive_group = 15;
+module_param(pow_receive_group, int, 0444);
+MODULE_PARM_DESC(pow_receive_group, "\n"
+	"\tPOW group to receive packets from. All ethernet hardware\n"
+	"\twill be configured to send incomming packets to this POW\n"
+	"\tgroup. Also any other software can submit packets to this\n"
+	"\tgroup for the kernel to process.");
+
+int pow_send_group = -1;
+module_param(pow_send_group, int, 0644);
+MODULE_PARM_DESC(pow_send_group, "\n"
+	"\tPOW group to send packets to other software on. This\n"
+	"\tcontrols the creation of the virtual device pow0.\n"
+	"\talways_use_pow also depends on this value.");
+
+int always_use_pow;
+module_param(always_use_pow, int, 0444);
+MODULE_PARM_DESC(always_use_pow, "\n"
+	"\tWhen set, always send to the pow group. This will cause\n"
+	"\tpackets sent to real ethernet devices to be sent to the\n"
+	"\tPOW group instead of the hardware. Unless some other\n"
+	"\tapplication changes the config, packets will still be\n"
+	"\treceived from the low level hardware. Use this option\n"
+	"\tto allow a CVMX app to intercept all packets from the\n"
+	"\tlinux kernel. You must specify pow_send_group along with\n"
+	"\tthis option.");
+
+char pow_send_list[128] = "";
+module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
+MODULE_PARM_DESC(pow_send_list, "\n"
+	"\tComma separated list of ethernet devices that should use the\n"
+	"\tPOW for transmit instead of the actual ethernet hardware. This\n"
+	"\tis a per port version of always_use_pow. always_use_pow takes\n"
+	"\tprecedence over this list. For example, setting this to\n"
+	"\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
+	"\tusing the pow_send_group.");
+
+static int disable_core_queueing = 1;
+module_param(disable_core_queueing, int, 0444);
+MODULE_PARM_DESC(disable_core_queueing, "\n"
+	"\tWhen set the networking core's tx_queue_len is set to zero.  This\n"
+	"\tallows packets to be sent without lock contention in the packet\n"
+	"\tscheduler resulting in some cases in improved throughput.\n");
+
+/**
+ * Periodic timer to check auto negotiation
+ */
+static struct timer_list cvm_oct_poll_timer;
+
+/**
+ * Array of every ethernet device owned by this driver indexed by
+ * the ipd input port number.
+ */
+struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
+
+extern struct semaphore mdio_sem;
+
+/**
+ * Periodic timer tick for slow management operations
+ *
+ * @arg:    Device to check
+ */
+static void cvm_do_timer(unsigned long arg)
+{
+	static int port;
+	if (port < CVMX_PIP_NUM_INPUT_PORTS) {
+		if (cvm_oct_device[port]) {
+			int queues_per_port;
+			int qos;
+			struct octeon_ethernet *priv =
+				netdev_priv(cvm_oct_device[port]);
+			if (priv->poll) {
+				/* skip polling if we don't get the lock */
+				if (!down_trylock(&mdio_sem)) {
+					priv->poll(cvm_oct_device[port]);
+					up(&mdio_sem);
+				}
+			}
+
+			queues_per_port = cvmx_pko_get_num_queues(port);
+			/* Drain any pending packets in the free list */
+			for (qos = 0; qos < queues_per_port; qos++) {
+				if (skb_queue_len(&priv->tx_free_list[qos])) {
+					spin_lock(&priv->tx_free_list[qos].
+						  lock);
+					while (skb_queue_len
+					       (&priv->tx_free_list[qos]) >
+					       cvmx_fau_fetch_and_add32(priv->
+									fau +
+									qos * 4,
+									0))
+						dev_kfree_skb(__skb_dequeue
+							      (&priv->
+							       tx_free_list
+							       [qos]));
+					spin_unlock(&priv->tx_free_list[qos].
+						    lock);
+				}
+			}
+			cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
+		}
+		port++;
+		/* Poll the next port in a 50th of a second.
+		   This spreads the polling of ports out a little bit */
+		mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
+	} else {
+		port = 0;
+		/* All ports have been polled. Start the next iteration through
+		   the ports in one second */
+		mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
+	}
+}
+
+/**
+ * Configure common hardware for all interfaces
+ */
+static __init void cvm_oct_configure_common_hw(void)
+{
+	int r;
+	/* Setup the FPA */
+	cvmx_fpa_enable();
+	cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
+			     num_packet_buffers);
+	cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
+			     num_packet_buffers);
+	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
+		cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
+				     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
+
+	if (USE_RED)
+		cvmx_helper_setup_red(num_packet_buffers / 4,
+				      num_packet_buffers / 8);
+
+	/* Enable the MII interface */
+	if (!octeon_is_simulation())
+		cvmx_write_csr(CVMX_SMIX_EN(0), 1);
+
+	/* Register an IRQ hander for to receive POW interrupts */
+	r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
+			cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
+			cvm_oct_device);
+
+#if defined(CONFIG_SMP) && 0
+	if (USE_MULTICORE_RECEIVE) {
+		irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
+				 cpu_online_mask);
+	}
+#endif
+}
+
+/**
+ * Free a work queue entry received in a intercept callback.
+ *
+ * @work_queue_entry:
+ *               Work queue entry to free
+ * Returns Zero on success, Negative on failure.
+ */
+int cvm_oct_free_work(void *work_queue_entry)
+{
+	cvmx_wqe_t *work = work_queue_entry;
+
+	int segments = work->word2.s.bufs;
+	union cvmx_buf_ptr segment_ptr = work->packet_ptr;
+
+	while (segments--) {
+		union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
+			cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
+		if (unlikely(!segment_ptr.s.i))
+			cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
+				      segment_ptr.s.pool,
+				      DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
+						     128));
+		segment_ptr = next_ptr;
+	}
+	cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
+
+	return 0;
+}
+EXPORT_SYMBOL(cvm_oct_free_work);
+
+/**
+ * Module/ driver initialization. Creates the linux network
+ * devices.
+ *
+ * Returns Zero on success
+ */
+static int __init cvm_oct_init_module(void)
+{
+	int num_interfaces;
+	int interface;
+	int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
+	int qos;
+
+	pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
+
+	cvm_oct_proc_initialize();
+	cvm_oct_rx_initialize();
+	cvm_oct_configure_common_hw();
+
+	cvmx_helper_initialize_packet_io_global();
+
+	/* Change the input group for all ports before input is enabled */
+	num_interfaces = cvmx_helper_get_number_of_interfaces();
+	for (interface = 0; interface < num_interfaces; interface++) {
+		int num_ports = cvmx_helper_ports_on_interface(interface);
+		int port;
+
+		for (port = cvmx_helper_get_ipd_port(interface, 0);
+		     port < cvmx_helper_get_ipd_port(interface, num_ports);
+		     port++) {
+			union cvmx_pip_prt_tagx pip_prt_tagx;
+			pip_prt_tagx.u64 =
+			    cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
+			pip_prt_tagx.s.grp = pow_receive_group;
+			cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
+				       pip_prt_tagx.u64);
+		}
+	}
+
+	cvmx_helper_ipd_and_packet_input_enable();
+
+	memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
+
+	/*
+	 * Initialize the FAU used for counting packet buffers that
+	 * need to be freed.
+	 */
+	cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
+
+	if ((pow_send_group != -1)) {
+		struct net_device *dev;
+		pr_info("\tConfiguring device for POW only access\n");
+		dev = alloc_etherdev(sizeof(struct octeon_ethernet));
+		if (dev) {
+			/* Initialize the device private structure. */
+			struct octeon_ethernet *priv = netdev_priv(dev);
+			memset(priv, 0, sizeof(struct octeon_ethernet));
+
+			dev->init = cvm_oct_common_init;
+			priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
+			priv->port = CVMX_PIP_NUM_INPUT_PORTS;
+			priv->queue = -1;
+			strcpy(dev->name, "pow%d");
+			for (qos = 0; qos < 16; qos++)
+				skb_queue_head_init(&priv->tx_free_list[qos]);
+
+			if (register_netdev(dev) < 0) {
+				pr_err("Failed to register ethernet "
+					 "device for POW\n");
+				kfree(dev);
+			} else {
+				cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
+				pr_info("%s: POW send group %d, receive "
+					"group %d\n",
+				     dev->name, pow_send_group,
+				     pow_receive_group);
+			}
+		} else {
+			pr_err("Failed to allocate ethernet device "
+				 "for POW\n");
+		}
+	}
+
+	num_interfaces = cvmx_helper_get_number_of_interfaces();
+	for (interface = 0; interface < num_interfaces; interface++) {
+		cvmx_helper_interface_mode_t imode =
+		    cvmx_helper_interface_get_mode(interface);
+		int num_ports = cvmx_helper_ports_on_interface(interface);
+		int port;
+
+		for (port = cvmx_helper_get_ipd_port(interface, 0);
+		     port < cvmx_helper_get_ipd_port(interface, num_ports);
+		     port++) {
+			struct octeon_ethernet *priv;
+			struct net_device *dev =
+			    alloc_etherdev(sizeof(struct octeon_ethernet));
+			if (!dev) {
+				pr_err("Failed to allocate ethernet device "
+					 "for port %d\n", port);
+				continue;
+			}
+			if (disable_core_queueing)
+				dev->tx_queue_len = 0;
+
+			/* Initialize the device private structure. */
+			priv = netdev_priv(dev);
+			memset(priv, 0, sizeof(struct octeon_ethernet));
+
+			priv->imode = imode;
+			priv->port = port;
+			priv->queue = cvmx_pko_get_base_queue(priv->port);
+			priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
+			for (qos = 0; qos < 16; qos++)
+				skb_queue_head_init(&priv->tx_free_list[qos]);
+			for (qos = 0; qos < cvmx_pko_get_num_queues(port);
+			     qos++)
+				cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
+
+			switch (priv->imode) {
+
+			/* These types don't support ports to IPD/PKO */
+			case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+			case CVMX_HELPER_INTERFACE_MODE_PCIE:
+			case CVMX_HELPER_INTERFACE_MODE_PICMG:
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_NPI:
+				dev->init = cvm_oct_common_init;
+				dev->uninit = cvm_oct_common_uninit;
+				strcpy(dev->name, "npi%d");
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_XAUI:
+				dev->init = cvm_oct_xaui_init;
+				dev->uninit = cvm_oct_xaui_uninit;
+				strcpy(dev->name, "xaui%d");
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_LOOP:
+				dev->init = cvm_oct_common_init;
+				dev->uninit = cvm_oct_common_uninit;
+				strcpy(dev->name, "loop%d");
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_SGMII:
+				dev->init = cvm_oct_sgmii_init;
+				dev->uninit = cvm_oct_sgmii_uninit;
+				strcpy(dev->name, "eth%d");
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_SPI:
+				dev->init = cvm_oct_spi_init;
+				dev->uninit = cvm_oct_spi_uninit;
+				strcpy(dev->name, "spi%d");
+				break;
+
+			case CVMX_HELPER_INTERFACE_MODE_RGMII:
+			case CVMX_HELPER_INTERFACE_MODE_GMII:
+				dev->init = cvm_oct_rgmii_init;
+				dev->uninit = cvm_oct_rgmii_uninit;
+				strcpy(dev->name, "eth%d");
+				break;
+			}
+
+			if (!dev->init) {
+				kfree(dev);
+			} else if (register_netdev(dev) < 0) {
+				pr_err("Failed to register ethernet device "
+					 "for interface %d, port %d\n",
+					 interface, priv->port);
+				kfree(dev);
+			} else {
+				cvm_oct_device[priv->port] = dev;
+				fau -=
+				    cvmx_pko_get_num_queues(priv->port) *
+				    sizeof(uint32_t);
+			}
+		}
+	}
+
+	if (INTERRUPT_LIMIT) {
+		/*
+		 * Set the POW timer rate to give an interrupt at most
+		 * INTERRUPT_LIMIT times per second.
+		 */
+		cvmx_write_csr(CVMX_POW_WQ_INT_PC,
+			       octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
+							     16 * 256) << 8);
+
+		/*
+		 * Enable POW timer interrupt. It will count when
+		 * there are packets available.
+		 */
+		cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
+			       0x1ful << 24);
+	} else {
+		/* Enable POW interrupt when our port has at least one packet */
+		cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
+	}
+
+	/* Enable the poll timer for checking RGMII status */
+	init_timer(&cvm_oct_poll_timer);
+	cvm_oct_poll_timer.data = 0;
+	cvm_oct_poll_timer.function = cvm_do_timer;
+	mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
+
+	return 0;
+}
+
+/**
+ * Module / driver shutdown
+ *
+ * Returns Zero on success
+ */
+static void __exit cvm_oct_cleanup_module(void)
+{
+	int port;
+
+	/* Disable POW interrupt */
+	cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
+
+	cvmx_ipd_disable();
+
+	/* Free the interrupt handler */
+	free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
+
+	del_timer(&cvm_oct_poll_timer);
+	cvm_oct_rx_shutdown();
+	cvmx_pko_disable();
+
+	/* Free the ethernet devices */
+	for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
+		if (cvm_oct_device[port]) {
+			cvm_oct_tx_shutdown(cvm_oct_device[port]);
+			unregister_netdev(cvm_oct_device[port]);
+			kfree(cvm_oct_device[port]);
+			cvm_oct_device[port] = NULL;
+		}
+	}
+
+	cvmx_pko_shutdown();
+	cvm_oct_proc_shutdown();
+
+	cvmx_ipd_free_ptr();
+
+	/* Free the HW pools */
+	cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
+			      num_packet_buffers);
+	cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
+			      num_packet_buffers);
+	if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
+		cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
+				      CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
+MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
+module_init(cvm_oct_init_module);
+module_exit(cvm_oct_cleanup_module);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
new file mode 100644
index 0000000..b319907
--- /dev/null
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -0,0 +1,127 @@
+/**********************************************************************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2007 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+**********************************************************************/
+
+/*
+ * External interface for the Cavium Octeon ethernet driver.
+ */
+#ifndef OCTEON_ETHERNET_H
+#define OCTEON_ETHERNET_H
+
+/**
+ * This is the definition of the Ethernet driver's private
+ * driver state stored in netdev_priv(dev).
+ */
+struct octeon_ethernet {
+	/* PKO hardware output port */
+	int port;
+	/* PKO hardware queue for the port */
+	int queue;
+	/* Hardware fetch and add to count outstanding tx buffers */
+	int fau;
+	/*
+	 * Type of port. This is one of the enums in
+	 * cvmx_helper_interface_mode_t
+	 */
+	int imode;
+	/* List of outstanding tx buffers per queue */
+	struct sk_buff_head tx_free_list[16];
+	/* Device statistics */
+	struct net_device_stats stats
+;	/* Generic MII info structure */
+	struct mii_if_info mii_info;
+	/* Last negotiated link state */
+	uint64_t link_info;
+	/* Called periodically to check link status */
+	void (*poll) (struct net_device *dev);
+};
+
+/**
+ * Free a work queue entry received in a intercept callback.
+ *
+ * @work_queue_entry:
+ *               Work queue entry to free
+ * Returns Zero on success, Negative on failure.
+ */
+int cvm_oct_free_work(void *work_queue_entry);
+
+/**
+ * Transmit a work queue entry out of the ethernet port. Both
+ * the work queue entry and the packet data can optionally be
+ * freed. The work will be freed on error as well.
+ *
+ * @dev:     Device to transmit out.
+ * @work_queue_entry:
+ *                Work queue entry to send
+ * @do_free: True if the work queue entry and packet data should be
+ *                freed. If false, neither will be freed.
+ * @qos:     Index into the queues for this port to transmit on. This
+ *                is used to implement QoS if their are multiple queues per
+ *                port. This parameter must be between 0 and the number of
+ *                queues per port minus 1. Values outside of this range will
+ *                be change to zero.
+ *
+ * Returns Zero on success, negative on failure.
+ */
+int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
+			 int do_free, int qos);
+
+/**
+ * Transmit a work queue entry out of the ethernet port. Both
+ * the work queue entry and the packet data can optionally be
+ * freed. The work will be freed on error as well. This simply
+ * wraps cvmx_oct_transmit_qos() for backwards compatability.
+ *
+ * @dev:     Device to transmit out.
+ * @work_queue_entry:
+ *                Work queue entry to send
+ * @do_free: True if the work queue entry and packet data should be
+ *                freed. If false, neither will be freed.
+ *
+ * Returns Zero on success, negative on failure.
+ */
+static inline int cvm_oct_transmit(struct net_device *dev,
+				   void *work_queue_entry, int do_free)
+{
+	return cvm_oct_transmit_qos(dev, work_queue_entry, do_free, 0);
+}
+
+extern int cvm_oct_rgmii_init(struct net_device *dev);
+extern void cvm_oct_rgmii_uninit(struct net_device *dev);
+extern int cvm_oct_sgmii_init(struct net_device *dev);
+extern void cvm_oct_sgmii_uninit(struct net_device *dev);
+extern int cvm_oct_spi_init(struct net_device *dev);
+extern void cvm_oct_spi_uninit(struct net_device *dev);
+extern int cvm_oct_xaui_init(struct net_device *dev);
+extern void cvm_oct_xaui_uninit(struct net_device *dev);
+
+extern int always_use_pow;
+extern int pow_send_group;
+extern int pow_receive_group;
+extern char pow_send_list[];
+extern struct net_device *cvm_oct_device[];
+
+#endif
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index ab5547f..38d695d 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -37,7 +37,6 @@
 #include <linux/mount.h>
 #include <linux/idr.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <net/9p/9p.h>
 #include <net/9p/client.h>
 
@@ -231,10 +230,8 @@
 {
 	struct v9fs_session_info *v9ses;
 
-	lock_kernel();
 	v9ses = sb->s_fs_info;
 	v9fs_session_cancel(v9ses);
-	unlock_kernel();
 }
 
 static const struct super_operations v9fs_super_ops = {
diff --git a/fs/Kconfig b/fs/Kconfig
index 4044f16..d78e950 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -134,7 +134,7 @@
 config HUGETLBFS
 	bool "HugeTLB file system support"
 	depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
-		   (S390 && 64BIT) || BROKEN
+		   (S390 && 64BIT) || SYS_SUPPORTS_HUGETLBFS || BROKEN
 	help
 	  hugetlbfs is a filesystem backing for HugeTLB pages, based on
 	  ramfs. For architectures that support it, say Y here and read
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index a6665f3..9cc1877 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -1,3 +1,6 @@
+#include <linux/fs.h>
+#include <linux/adfs_fs.h>
+
 /* Internal data structures for ADFS */
 
 #define ADFS_FREE_FRAG		 0
@@ -17,6 +20,58 @@
 struct buffer_head;
 
 /*
+ * adfs file system inode data in memory
+ */
+struct adfs_inode_info {
+	loff_t		mmu_private;
+	unsigned long	parent_id;	/* object id of parent		*/
+	__u32		loadaddr;	/* RISC OS load address		*/
+	__u32		execaddr;	/* RISC OS exec address		*/
+	unsigned int	filetype;	/* RISC OS file type		*/
+	unsigned int	attr;		/* RISC OS permissions		*/
+	unsigned int	stamped:1;	/* RISC OS file has date/time	*/
+	struct inode vfs_inode;
+};
+
+/*
+ * Forward-declare this
+ */
+struct adfs_discmap;
+struct adfs_dir_ops;
+
+/*
+ * ADFS file system superblock data in memory
+ */
+struct adfs_sb_info {
+	struct adfs_discmap *s_map;	/* bh list containing map		 */
+	struct adfs_dir_ops *s_dir;	/* directory operations			 */
+
+	uid_t		s_uid;		/* owner uid				 */
+	gid_t		s_gid;		/* owner gid				 */
+	umode_t		s_owner_mask;	/* ADFS owner perm -> unix perm		 */
+	umode_t		s_other_mask;	/* ADFS other perm -> unix perm		 */
+
+	__u32		s_ids_per_zone;	/* max. no ids in one zone		 */
+	__u32		s_idlen;	/* length of ID in map			 */
+	__u32		s_map_size;	/* sector size of a map			 */
+	unsigned long	s_size;		/* total size (in blocks) of this fs	 */
+	signed int	s_map2blk;	/* shift left by this for map->sector	 */
+	unsigned int	s_log2sharesize;/* log2 share size			 */
+	__le32		s_version;	/* disc format version			 */
+	unsigned int	s_namelen;	/* maximum number of characters in name	 */
+};
+
+static inline struct adfs_sb_info *ADFS_SB(struct super_block *sb)
+{
+	return sb->s_fs_info;
+}
+
+static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
+{
+	return container_of(inode, struct adfs_inode_info, vfs_inode);
+}
+
+/*
  * Directory handling
  */
 struct adfs_dir {
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index 4d40734..23aa52f 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -9,15 +9,7 @@
  *
  *  Common directory handling for ADFS
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/spinlock.h>
 #include <linux/smp_lock.h>
-#include <linux/buffer_head.h>		/* for file_fsync() */
-
 #include "adfs.h"
 
 /*
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c
index 31df6ad..bafc712 100644
--- a/fs/adfs/dir_f.c
+++ b/fs/adfs/dir_f.c
@@ -9,15 +9,7 @@
  *
  *  E and F format directory handling
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/spinlock.h>
 #include <linux/buffer_head.h>
-#include <linux/string.h>
-
 #include "adfs.h"
 #include "dir_f.h"
 
diff --git a/fs/adfs/dir_fplus.c b/fs/adfs/dir_fplus.c
index 139e0f3..1796bb35 100644
--- a/fs/adfs/dir_fplus.c
+++ b/fs/adfs/dir_fplus.c
@@ -7,15 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/spinlock.h>
 #include <linux/buffer_head.h>
-#include <linux/string.h>
-
 #include "adfs.h"
 #include "dir_fplus.h"
 
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index 8224d54..005ea34 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -19,10 +19,6 @@
  *
  *  adfs regular file handling primitives           
  */
-#include <linux/fs.h>
-#include <linux/buffer_head.h>			/* for file_fsync() */
-#include <linux/adfs_fs.h>
-
 #include "adfs.h"
 
 const struct file_operations adfs_file_operations = {
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 05b3a67..798cb07 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -7,17 +7,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/string.h>
-#include <linux/mm.h>
 #include <linux/smp_lock.h>
-#include <linux/module.h>
 #include <linux/buffer_head.h>
-
 #include "adfs.h"
 
 /*
@@ -395,4 +386,3 @@
 	unlock_kernel();
 	return ret;
 }
-MODULE_LICENSE("GPL");
diff --git a/fs/adfs/map.c b/fs/adfs/map.c
index 568081b..d1a5932 100644
--- a/fs/adfs/map.c
+++ b/fs/adfs/map.c
@@ -7,14 +7,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/spinlock.h>
 #include <linux/buffer_head.h>
-
 #include <asm/unaligned.h>
-
 #include "adfs.h"
 
 /*
diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 0ec5aaf..aad92f0 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -8,26 +8,12 @@
  * published by the Free Software Foundation.
  */
 #include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/adfs_fs.h>
-#include <linux/slab.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/string.h>
 #include <linux/init.h>
 #include <linux/buffer_head.h>
-#include <linux/vfs.h>
 #include <linux/parser.h>
-#include <linux/bitops.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <stdarg.h>
-
+#include <linux/statfs.h>
 #include "adfs.h"
 #include "dir_f.h"
 #include "dir_fplus.h"
@@ -534,3 +520,4 @@
 
 module_init(init_adfs_fs)
 module_exit(exit_adfs_fs)
+MODULE_LICENSE("GPL");
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 89cd2de..615d549 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -735,8 +735,6 @@
 static void
 befs_put_super(struct super_block *sb)
 {
-	lock_kernel();
-
 	kfree(BEFS_SB(sb)->mount_opts.iocharset);
 	BEFS_SB(sb)->mount_opts.iocharset = NULL;
 
@@ -747,8 +745,6 @@
 
 	kfree(sb->s_fs_info);
 	sb->s_fs_info = NULL;
-
-	unlock_kernel();
 }
 
 /* Allocate private field of the superblock, fill it.
diff --git a/fs/efs/dir.c b/fs/efs/dir.c
index 49308a2..7ee6f7e3 100644
--- a/fs/efs/dir.c
+++ b/fs/efs/dir.c
@@ -5,12 +5,12 @@
  */
 
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include "efs.h"
 
 static int efs_readdir(struct file *, void *, filldir_t);
 
 const struct file_operations efs_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= efs_readdir,
 };
@@ -33,8 +33,6 @@
 	if (inode->i_size & (EFS_DIRBSIZE-1))
 		printk(KERN_WARNING "EFS: WARNING: readdir(): directory size not a multiple of EFS_DIRBSIZE\n");
 
-	lock_kernel();
-
 	/* work out where this entry can be found */
 	block = filp->f_pos >> EFS_DIRBSIZE_BITS;
 
@@ -107,7 +105,6 @@
 
 	filp->f_pos = (block << EFS_DIRBSIZE_BITS) | slot;
 out:
-	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index c3fb5f9..1511bf9 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -8,7 +8,6 @@
 
 #include <linux/buffer_head.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/exportfs.h>
 #include "efs.h"
 
@@ -63,16 +62,12 @@
 	efs_ino_t inodenum;
 	struct inode * inode = NULL;
 
-	lock_kernel();
 	inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
 	if (inodenum) {
 		inode = efs_iget(dir->i_sb, inodenum);
-		if (IS_ERR(inode)) {
-			unlock_kernel();
+		if (IS_ERR(inode))
 			return ERR_CAST(inode);
-		}
 	}
-	unlock_kernel();
 
 	return d_splice_alias(inode, dentry);
 }
@@ -115,11 +110,9 @@
 	struct dentry *parent = ERR_PTR(-ENOENT);
 	efs_ino_t ino;
 
-	lock_kernel();
 	ino = efs_find_entry(child->d_inode, "..", 2);
 	if (ino)
 		parent = d_obtain_alias(efs_iget(child->d_inode->i_sb, ino));
-	unlock_kernel();
 
 	return parent;
 }
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c
index 41911ec..75117d0 100644
--- a/fs/efs/symlink.c
+++ b/fs/efs/symlink.c
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include "efs.h"
 
 static int efs_symlink_readpage(struct file *file, struct page *page)
@@ -22,9 +21,8 @@
   
 	err = -ENAMETOOLONG;
 	if (size > 2 * EFS_BLOCKSIZE)
-		goto fail_notlocked;
+		goto fail;
   
-	lock_kernel();
 	/* read first 512 bytes of link target */
 	err = -EIO;
 	bh = sb_bread(inode->i_sb, efs_bmap(inode, 0));
@@ -40,14 +38,11 @@
 		brelse(bh);
 	}
 	link[size] = '\0';
-	unlock_kernel();
 	SetPageUptodate(page);
 	kunmap(page);
 	unlock_page(page);
 	return 0;
 fail:
-	unlock_kernel();
-fail_notlocked:
 	SetPageError(page);
 	kunmap(page);
 	unlock_page(page);
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index d81ef2f..e0c7454 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -129,12 +129,15 @@
 static inline struct posix_acl *
 ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl)
 {
-	struct posix_acl *acl = EXT3_ACL_NOT_CACHED;
+	struct posix_acl *acl = ACCESS_ONCE(*i_acl);
 
-	spin_lock(&inode->i_lock);
-	if (*i_acl != EXT3_ACL_NOT_CACHED)
-		acl = posix_acl_dup(*i_acl);
-	spin_unlock(&inode->i_lock);
+	if (acl) {
+		spin_lock(&inode->i_lock);
+		acl = *i_acl;
+		if (acl != EXT3_ACL_NOT_CACHED)
+			acl = posix_acl_dup(acl);
+		spin_unlock(&inode->i_lock);
+	}
 
 	return acl;
 }
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 647e0d6..605aeed 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -129,12 +129,15 @@
 static inline struct posix_acl *
 ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl)
 {
-	struct posix_acl *acl = EXT4_ACL_NOT_CACHED;
+	struct posix_acl *acl = ACCESS_ONCE(*i_acl);
 
-	spin_lock(&inode->i_lock);
-	if (*i_acl != EXT4_ACL_NOT_CACHED)
-		acl = posix_acl_dup(*i_acl);
-	spin_unlock(&inode->i_lock);
+	if (acl) {
+		spin_lock(&inode->i_lock);
+		acl = *i_acl;
+		if (acl != EXT4_ACL_NOT_CACHED)
+			acl = posix_acl_dup(acl);
+		spin_unlock(&inode->i_lock);
+	}
 
 	return acl;
 }
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index f0df55a..d8673cc 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -19,7 +19,6 @@
 #include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/exportfs.h>
-#include <linux/smp_lock.h>
 
 MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
 MODULE_DESCRIPTION("Filesystem in Userspace");
@@ -260,9 +259,7 @@
 
 static void fuse_umount_begin(struct super_block *sb)
 {
-	lock_kernel();
 	fuse_abort_conn(get_fuse_conn_super(sb));
-	unlock_kernel();
 }
 
 static void fuse_send_destroy(struct fuse_conn *fc)
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 286f38d..001f8d3 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -70,9 +70,7 @@
 	res = get_user(block, p);
 	if (res)
 		return res;
-	lock_kernel();
 	res = mapping->a_ops->bmap(mapping, block);
-	unlock_kernel();
 	return put_user(res, p);
 }
 
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 3aebe32..6ac693f 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -12,13 +12,14 @@
 /* bitmap.c contains the code that handles the inode and block bitmaps */
 
 #include "minix.h"
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/bitops.h>
 #include <linux/sched.h>
 
 static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 };
 
+static DEFINE_SPINLOCK(bitmap_lock);
+
 static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits)
 {
 	unsigned i, j, sum = 0;
@@ -69,11 +70,11 @@
 		return;
 	}
 	bh = sbi->s_zmap[zone];
-	lock_kernel();
+	spin_lock(&bitmap_lock);
 	if (!minix_test_and_clear_bit(bit, bh->b_data))
 		printk("minix_free_block (%s:%lu): bit already cleared\n",
 		       sb->s_id, block);
-	unlock_kernel();
+	spin_unlock(&bitmap_lock);
 	mark_buffer_dirty(bh);
 	return;
 }
@@ -88,18 +89,18 @@
 		struct buffer_head *bh = sbi->s_zmap[i];
 		int j;
 
-		lock_kernel();
+		spin_lock(&bitmap_lock);
 		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
 		if (j < bits_per_zone) {
 			minix_set_bit(j, bh->b_data);
-			unlock_kernel();
+			spin_unlock(&bitmap_lock);
 			mark_buffer_dirty(bh);
 			j += i * bits_per_zone + sbi->s_firstdatazone-1;
 			if (j < sbi->s_firstdatazone || j >= sbi->s_nzones)
 				break;
 			return j;
 		}
-		unlock_kernel();
+		spin_unlock(&bitmap_lock);
 	}
 	return 0;
 }
@@ -211,10 +212,10 @@
 	minix_clear_inode(inode);	/* clear on-disk copy */
 
 	bh = sbi->s_imap[ino];
-	lock_kernel();
+	spin_lock(&bitmap_lock);
 	if (!minix_test_and_clear_bit(bit, bh->b_data))
 		printk("minix_free_inode: bit %lu already cleared\n", bit);
-	unlock_kernel();
+	spin_unlock(&bitmap_lock);
 	mark_buffer_dirty(bh);
  out:
 	clear_inode(inode);		/* clear in-memory copy */
@@ -237,7 +238,7 @@
 	j = bits_per_zone;
 	bh = NULL;
 	*error = -ENOSPC;
-	lock_kernel();
+	spin_lock(&bitmap_lock);
 	for (i = 0; i < sbi->s_imap_blocks; i++) {
 		bh = sbi->s_imap[i];
 		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
@@ -245,17 +246,17 @@
 			break;
 	}
 	if (!bh || j >= bits_per_zone) {
-		unlock_kernel();
+		spin_unlock(&bitmap_lock);
 		iput(inode);
 		return NULL;
 	}
 	if (minix_test_and_set_bit(j, bh->b_data)) {	/* shouldn't happen */
-		unlock_kernel();
+		spin_unlock(&bitmap_lock);
 		printk("minix_new_inode: bit already set\n");
 		iput(inode);
 		return NULL;
 	}
-	unlock_kernel();
+	spin_unlock(&bitmap_lock);
 	mark_buffer_dirty(bh);
 	j += i * bits_per_zone;
 	if (!j || j > sbi->s_ninodes) {
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index e5f2064..d407e7a 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -11,7 +11,6 @@
 #include "minix.h"
 #include <linux/buffer_head.h>
 #include <linux/highmem.h>
-#include <linux/smp_lock.h>
 #include <linux/swap.h>
 
 typedef struct minix_dir_entry minix_dirent;
@@ -20,6 +19,7 @@
 static int minix_readdir(struct file *, void *, filldir_t);
 
 const struct file_operations minix_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= minix_readdir,
 	.fsync		= simple_fsync,
@@ -102,8 +102,6 @@
 	char *name;
 	__u32 inumber;
 
-	lock_kernel();
-
 	pos = (pos + chunk_size-1) & ~(chunk_size-1);
 	if (pos >= inode->i_size)
 		goto done;
@@ -146,7 +144,6 @@
 
 done:
 	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
-	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index f91a236..74ea82d 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -35,8 +35,6 @@
 	int i;
 	struct minix_sb_info *sbi = minix_sb(sb);
 
-	lock_kernel();
-
 	if (!(sb->s_flags & MS_RDONLY)) {
 		if (sbi->s_version != MINIX_V3)	 /* s_state is now out from V3 sb */
 			sbi->s_ms->s_state = sbi->s_mount_state;
@@ -50,8 +48,6 @@
 	kfree(sbi->s_imap);
 	sb->s_fs_info = NULL;
 	kfree(sbi);
-
-	unlock_kernel();
 }
 
 static struct kmem_cache * minix_inode_cachep;
diff --git a/fs/super.c b/fs/super.c
index 83b47416..d40d53a 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -545,24 +545,18 @@
 	if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY)) {
 		if (force)
 			mark_files_ro(sb);
-		else if (!fs_may_remount_ro(sb)) {
-			unlock_kernel();
+		else if (!fs_may_remount_ro(sb))
 			return -EBUSY;
-		}
 		retval = vfs_dq_off(sb, 1);
-		if (retval < 0 && retval != -ENOSYS) {
-			unlock_kernel();
+		if (retval < 0 && retval != -ENOSYS)
 			return -EBUSY;
-		}
 	}
 	remount_rw = !(flags & MS_RDONLY) && (sb->s_flags & MS_RDONLY);
 
 	if (sb->s_op->remount_fs) {
 		retval = sb->s_op->remount_fs(sb, &flags, data);
-		if (retval) {
-			unlock_kernel();
+		if (retval)
 			return retval;
-		}
 	}
 	sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
 	if (remount_rw)
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index c779807..4e50286 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -15,13 +15,13 @@
 
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
-#include <linux/smp_lock.h>
 #include <linux/swap.h>
 #include "sysv.h"
 
 static int sysv_readdir(struct file *, void *, filldir_t);
 
 const struct file_operations sysv_dir_operations = {
+	.llseek		= generic_file_llseek,
 	.read		= generic_read_dir,
 	.readdir	= sysv_readdir,
 	.fsync		= simple_fsync,
@@ -74,8 +74,6 @@
 	unsigned long n = pos >> PAGE_CACHE_SHIFT;
 	unsigned long npages = dir_pages(inode);
 
-	lock_kernel();
-
 	pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
 	if (pos >= inode->i_size)
 		goto done;
@@ -113,7 +111,6 @@
 
 done:
 	filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset;
-	unlock_kernel();
 	return 0;
 }
 
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 4799234..9824743 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -21,7 +21,6 @@
  *  the superblock.
  */
 
-#include <linux/smp_lock.h>
 #include <linux/highuid.h>
 #include <linux/slab.h>
 #include <linux/init.h>
@@ -37,7 +36,6 @@
 	unsigned long time = get_seconds(), old_time;
 
 	lock_super(sb);
-	lock_kernel();
 
 	/*
 	 * If we are going to write out the super block,
@@ -52,7 +50,6 @@
 		mark_buffer_dirty(sbi->s_bh2);
 	}
 
-	unlock_kernel();
 	unlock_super(sb);
 
 	return 0;
@@ -82,8 +79,6 @@
 {
 	struct sysv_sb_info *sbi = SYSV_SB(sb);
 
-	lock_kernel();
-
 	if (sb->s_dirt)
 		sysv_write_super(sb);
 
@@ -99,8 +94,6 @@
 		brelse(sbi->s_bh2);
 
 	kfree(sbi);
-
-	unlock_kernel();
 }
 
 static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -275,7 +268,6 @@
 		return -EIO;
 	}
 
-	lock_kernel();
 	raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode);
 	raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(inode->i_uid));
 	raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(inode->i_gid));
@@ -291,7 +283,6 @@
 	for (block = 0; block < 10+1+1+1; block++)
 		write3byte(sbi, (u8 *)&si->i_data[block],
 			&raw_inode->i_data[3*block]);
-	unlock_kernel();
 	mark_buffer_dirty(bh);
 	if (wait) {
                 sync_dirty_buffer(bh);
@@ -315,9 +306,7 @@
 	truncate_inode_pages(&inode->i_data, 0);
 	inode->i_size = 0;
 	sysv_truncate(inode);
-	lock_kernel();
 	sysv_free_inode(inode);
-	unlock_kernel();
 }
 
 static struct kmem_cache *sysv_inode_cachep;
diff --git a/include/linux/adfs_fs.h b/include/linux/adfs_fs.h
index ef788c2..b19801f 100644
--- a/include/linux/adfs_fs.h
+++ b/include/linux/adfs_fs.h
@@ -41,8 +41,6 @@
 #define ADFS_DR_SIZE_BITS	(ADFS_DR_SIZE << 3)
 
 #ifdef __KERNEL__
-#include <linux/adfs_fs_i.h>
-#include <linux/adfs_fs_sb.h>
 /*
  * Calculate the boot block checksum on an ADFS drive.  Note that this will
  * appear to be correct if the sector contains all zeros, so also check that
@@ -60,17 +58,6 @@
 
 	return (result & 0xff) != ptr[511];
 }
-
-static inline struct adfs_sb_info *ADFS_SB(struct super_block *sb)
-{
-	return sb->s_fs_info;
-}
-
-static inline struct adfs_inode_info *ADFS_I(struct inode *inode)
-{
-	return container_of(inode, struct adfs_inode_info, vfs_inode);
-}
-
 #endif
 
 #endif
diff --git a/include/linux/adfs_fs_i.h b/include/linux/adfs_fs_i.h
deleted file mode 100644
index cb54303..0000000
--- a/include/linux/adfs_fs_i.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- *  linux/include/linux/adfs_fs_i.h
- *
- * Copyright (C) 1997 Russell King
- */
-
-#ifndef _ADFS_FS_I
-#define _ADFS_FS_I
-
-/*
- * adfs file system inode data in memory
- */
-struct adfs_inode_info {
-	loff_t		mmu_private;
-	unsigned long	parent_id;	/* object id of parent		*/
-	__u32		loadaddr;	/* RISC OS load address		*/
-	__u32		execaddr;	/* RISC OS exec address		*/
-	unsigned int	filetype;	/* RISC OS file type		*/
-	unsigned int	attr;		/* RISC OS permissions		*/
-	unsigned int	stamped:1;	/* RISC OS file has date/time	*/
-	struct inode vfs_inode;
-};
-
-#endif
diff --git a/include/linux/adfs_fs_sb.h b/include/linux/adfs_fs_sb.h
deleted file mode 100644
index d9bf05c..0000000
--- a/include/linux/adfs_fs_sb.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  linux/include/linux/adfs_fs_sb.h
- *
- * Copyright (C) 1997-1999 Russell King
- */
-
-#ifndef _ADFS_FS_SB
-#define _ADFS_FS_SB
-
-/*
- * Forward-declare this
- */
-struct adfs_discmap;
-struct adfs_dir_ops;
-
-/*
- * ADFS file system superblock data in memory
- */
-struct adfs_sb_info {
-	struct adfs_discmap *s_map;	/* bh list containing map		 */
-	struct adfs_dir_ops *s_dir;	/* directory operations			 */
-
-	uid_t		s_uid;		/* owner uid				 */
-	gid_t		s_gid;		/* owner gid				 */
-	umode_t		s_owner_mask;	/* ADFS owner perm -> unix perm		 */
-	umode_t		s_other_mask;	/* ADFS other perm -> unix perm		 */
-
-	__u32		s_ids_per_zone;	/* max. no ids in one zone		 */
-	__u32		s_idlen;	/* length of ID in map			 */
-	__u32		s_map_size;	/* sector size of a map			 */
-	unsigned long	s_size;		/* total size (in blocks) of this fs	 */
-	signed int	s_map2blk;	/* shift left by this for map->sector	 */
-	unsigned int	s_log2sharesize;/* log2 share size			 */
-	__le32		s_version;	/* disc format version			 */
-	unsigned int	s_namelen;	/* maximum number of characters in name	 */
-};
-
-#endif