Quantenna sdk-v37.4.1.89: Files from outside the Linux tree

mkdir drivers/qtn
cp -pr
/usr/local/hdd1/home/danielmentz/quantenna-sdk-v37.4.1.89.pristine/drivers/*
drivers/qtn

mkdir arch/arc/plat-qtn/sdk-qsr1000
cp -pr
/usr/local/hdd1/home/danielmentz/quantenna-sdk-v37.4.1.89.pristine/common/
arch/arc/plat-qtn/sdk-qsr1000
cp -pr
/usr/local/hdd1/home/danielmentz/quantenna-sdk-v37.4.1.89.pristine/include/
arch/arc/plat-qtn/sdk-qsr1000

rm arch/arc/include/asm/board-ruby
ln -s ../../../../drivers/qtn/ruby/ arch/arc/include/asm/board-ruby

rm -rf arch/arc/plat-qtn/sdk-qsr1000/common/doxygen
diff --git a/arch/arc/include/asm/board-ruby b/arch/arc/include/asm/board-ruby
index 1ca4289..b4672d4 120000
--- a/arch/arc/include/asm/board-ruby
+++ b/arch/arc/include/asm/board-ruby
@@ -1 +1 @@
-../../../../../drivers/ruby/
\ No newline at end of file
+drivers/qtn/ruby/
\ No newline at end of file
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/Makefile b/arch/arc/plat-qtn/sdk-qsr1000/common/Makefile
new file mode 100755
index 0000000..b25a070
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/Makefile
@@ -0,0 +1,91 @@
+#
+#   common/Makefile
+# 
+#   Copyright (c) Quantenna Communications Incorporated 2007.
+#   All rights reserved.
+# 
+#  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
+# 
+#  This file defines the major, minor and build numbers for this release, and
+#  can create a C header file corresponding to those values. 
+#
+
+# This section is AWK'd by the release script, so keep the format to be
+# <start of line><label><space>:=<space><number>
+UMS_RELEASE_MAJOR := 0
+UMS_RELEASE_MINOR := 6
+UMS_RELEASE_BUILD := 1
+
+HFILE := ums_release
+
+PDFTK = $(shell which pdftk)
+ENSCRIPT = $(shell which enscript)
+PS2PDF = $(shell which ps2pdf)
+
+$(HFILE).h: Makefile
+	echo "/* This file is auto-generated by common/Makefile */" > $(HFILE).h
+	echo "#ifndef __$(HFILE)_H" >> $(HFILE).h
+	echo "#define __$(HFILE)_H" >> $(HFILE).h
+	echo "#define UMS_RELEASE_MAJOR	 ($(UMS_RELEASE_MAJOR))" >> $(HFILE).h
+	echo "#define UMS_RELEASE_MINOR	 ($(UMS_RELEASE_MINOR))" >> $(HFILE).h
+	echo "#define UMS_RELEASE_BUILD	 ($(UMS_RELEASE_BUILD))" >> $(HFILE).h
+	echo "#endif" >> $(HFILE).h
+
+header_version: check_enscript check_ps2pdf
+	-rm rev-num.pdf .tmp.rev-num .tmp.rev-num.ps
+	echo "$(REV_NUM)" > .tmp.rev-num
+	enscript -B --margins 67:200:260:240 -f Courier24 -p ./.tmp.rev-num.ps .tmp.rev-num
+	ps2pdf .tmp.rev-num.ps rev-num.pdf
+	-rm .tmp.rev-num .tmp.rev-num.ps
+
+clean:
+	rm -f $(HFILE).h
+	
+distclean: clean
+
+doco_pktlogger_i: check_pdftk header_version
+	REV_NUM=$(REV_NUM) make -e -C doxygen/pktlogger_doc Quantenna_pktlogger-INTERNAL-ONLY.pdf
+
+doco_pktlogger_ext_no_muc: check_pdftk header_version
+	REV_NUM=$(REV_NUM) make -e -C doxygen/pktlogger_doc Quantenna_pktlogger-external-no-muc.pdf
+
+doco_pktlogger_ext: check_pdftk header_version
+	REV_NUM=$(REV_NUM) make -e -C doxygen/pktlogger_doc Quantenna_pktlogger.pdf
+
+check_pdftk:
+	@if [ "$(PDFTK)" = "" ]; then \
+		echo "Please install pdftk to generate internal documentation"; \
+		exit 1; \
+	fi
+
+check_enscript:
+	@if [ "$(ENSCRIPT)" = "" ]; then \
+		echo "Please install enscript"; \
+		exit 1; \
+	fi
+
+check_ps2pdf:
+	@if [ "$(PS2PDF)" = "" ]; then \
+		echo "Please install ps2pdf"; \
+		exit 1; \
+	fi
+
+doco_qcsapi: check_pdftk header_version
+	REV_NUM=$(REV_NUM) make -e -C doxygen/qcsapi_doc
+
+ALL_DOCS = doco_pktlogger_ext doco_qcsapi doco_pktlogger_i doco_pktlogger_ext_no_muc
+doco: $(ALL_DOCS)
+.PHONY: doco $(ALL_DOCS)
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/common_mem.h b/arch/arc/plat-qtn/sdk-qsr1000/common/common_mem.h
new file mode 100644
index 0000000..7b785c4
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/common_mem.h
@@ -0,0 +1,277 @@
+/*
+ * (C) Copyright 2014 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes the Ruby and Topaz platforms.
+ * Used by both run-time and boot loader images.
+ *
+ * Do not put run-time specific definitions in this file.
+ */
+
+#ifndef __COMMON_MEM_H
+#define __COMMON_MEM_H
+
+#include "ruby_config.h"
+
+/* Platform memory */
+/* SRAM */
+#define RUBY_SRAM_UNIFIED_BEGIN			0x98000000
+#define RUBY_SRAM_UNIFIED_NOCACHE_BEGIN		0x60000000
+#define RUBY_SRAM_ALIAS_NOCACHE_BEGIN		0xf8000000
+#define RUBY_SRAM_FLIP_BEGIN			0x88000000
+#define RUBY_SRAM_FLIP_NOCACHE_BEGIN		0x60000000
+#define RUBY_SRAM_NOFLIP_BEGIN			0x80000000
+#define RUBY_SRAM_NOFLIP_NOCACHE_BEGIN		0x60000000
+#define RUBY_SRAM_BANK_SIZE			(64 * 1024)
+
+#define RUBY_SRAM_SIZE			(8 * RUBY_SRAM_BANK_SIZE)
+#define RUBY_SRAM_BANK_SAFE_SIZE	RUBY_SRAM_BANK_SIZE
+
+/* DDR */
+#define RUBY_DRAM_UNIFIED_BEGIN			0x80000000
+#define RUBY_DRAM_UNIFIED_NOCACHE_BEGIN		0x40000000
+#define RUBY_DRAM_ALIAS_NOCACHE_BEGIN		0xd0000000
+#define RUBY_DRAM_FLIP_BEGIN			0x80000000
+#define RUBY_DRAM_FLIP_NOCACHE_BEGIN		0x40000000
+#define RUBY_DRAM_NOFLIP_BEGIN			0x0
+#define RUBY_DRAM_NOFLIP_NOCACHE_BEGIN		0x40000000
+#if TOPAZ_MMAP_UNIFIED && TOPAZ_SUPPORT_256MB_DDR
+#define RUBY_MAX_DRAM_SIZE			DDR_256MB
+#else
+#define RUBY_MAX_DRAM_SIZE			DDR_128MB
+#endif
+#define RUBY_MIN_DRAM_SIZE			DDR_64MB
+
+#if TOPAZ_MMAP_UNIFIED && TOPAZ_MMAP_ALIAS
+	#define RUBY_SRAM_BEGIN			RUBY_SRAM_UNIFIED_BEGIN
+	#define RUBY_SRAM_BUS_BEGIN		RUBY_SRAM_UNIFIED_BEGIN
+	#define RUBY_SRAM_NOCACHE_BEGIN		RUBY_SRAM_ALIAS_NOCACHE_BEGIN
+	#define RUBY_DRAM_BEGIN			RUBY_DRAM_UNIFIED_BEGIN
+	#define RUBY_DRAM_BUS_BEGIN		RUBY_DRAM_UNIFIED_BEGIN
+	#define RUBY_DRAM_NOCACHE_BEGIN		RUBY_DRAM_ALIAS_NOCACHE_BEGIN
+#elif TOPAZ_MMAP_UNIFIED
+	#define RUBY_SRAM_BEGIN			RUBY_SRAM_UNIFIED_BEGIN
+	#define RUBY_SRAM_BUS_BEGIN		RUBY_SRAM_UNIFIED_BEGIN
+	#define RUBY_SRAM_NOCACHE_BEGIN		RUBY_SRAM_UNIFIED_NOCACHE_BEGIN
+	#define RUBY_DRAM_BEGIN			RUBY_DRAM_UNIFIED_BEGIN
+	#define RUBY_DRAM_BUS_BEGIN		RUBY_DRAM_UNIFIED_BEGIN
+	#define RUBY_DRAM_NOCACHE_BEGIN		RUBY_DRAM_UNIFIED_NOCACHE_BEGIN
+#elif RUBY_MMAP_FLIP
+	#define RUBY_SRAM_BEGIN			RUBY_SRAM_FLIP_BEGIN
+	#define RUBY_SRAM_BUS_BEGIN		RUBY_SRAM_NOFLIP_BEGIN
+	#define RUBY_SRAM_NOCACHE_BEGIN		RUBY_SRAM_FLIP_NOCACHE_BEGIN
+	#define RUBY_DRAM_BEGIN			RUBY_DRAM_FLIP_BEGIN
+	#define RUBY_DRAM_BUS_BEGIN		RUBY_DRAM_NOFLIP_BEGIN
+	#define RUBY_DRAM_NOCACHE_BEGIN		RUBY_DRAM_FLIP_NOCACHE_BEGIN
+#else
+	#define RUBY_SRAM_BEGIN			RUBY_SRAM_NOFLIP_BEGIN
+	#define RUBY_SRAM_BUS_BEGIN		RUBY_SRAM_NOFLIP_BEGIN
+	#define RUBY_SRAM_NOCACHE_BEGIN		RUBY_SRAM_NOFLIP_NOCACHE_BEGIN
+	#define RUBY_DRAM_BEGIN			RUBY_DRAM_NOFLIP_BEGIN
+	#define RUBY_DRAM_BUS_BEGIN		RUBY_DRAM_NOFLIP_BEGIN
+	#define RUBY_DRAM_NOCACHE_BEGIN		RUBY_DRAM_NOFLIP_NOCACHE_BEGIN
+#endif
+
+/*****************************************************************************/
+/* SPI memory mapped                                                         */
+/*****************************************************************************/
+#define RUBY_SPI_FLASH_ADDR     0x90000000
+
+ /* Hardware */
+#define RUBY_HARDWARE_BEGIN	0xC0000000
+
+#define	ROUNDUP(x, y)		((((x)+((y)-1))/(y))*(y))
+
+/* Config space */
+#define CONFIG_ARC_CONF_SIZE		(8 * 1024)
+/* Config area for Universal H/W ID */
+#define CONFIG_ARC_CONF_BASE		(0x80000000 + CONFIG_ARC_CONF_SIZE)
+
+#define CONFIG_ARC_KERNEL_PAGE_SIZE	(8 * 1024)
+
+#define RUBY_KERNEL_LOAD_DRAM_BEGIN	(RUBY_DRAM_BEGIN + 0x3000000)
+
+/* Safety offset from stack top address */
+#define RUBY_STACK_INIT_OFFSET		4
+
+/* DDR layout */
+#define CONFIG_ARC_NULL_BASE		0x00000000
+#define CONFIG_ARC_NULL_SIZE		(64 * 1024)
+#define CONFIG_ARC_NULL_END		(CONFIG_ARC_NULL_BASE + CONFIG_ARC_NULL_SIZE)
+
+/* PCIe BDA area */
+#define CONFIG_ARC_PCIE_BASE		(RUBY_DRAM_BEGIN + CONFIG_ARC_NULL_END)
+#define CONFIG_ARC_PCIE_SIZE		(64 * 1024) /* minimal PCI BAR size */
+#if ((CONFIG_ARC_PCIE_BASE & (64 * 1024 - 1)) != 0)
+	#error "The reserved region for PCIe BAR should 64k aligned!"
+#endif
+
+/*
+ * CONFIG_ARC_MUC_STACK_OFFSET_UBOOT must be equal to CONFIG_ARC_MUC_STACK_OFFSET
+ * and RUBY_CRUMBS_OFFSET_UBOOT must be equal to RUBY_CRUMBS_OFFSET.
+ * Their values can be obtained with host/utilities/ruby_mem_helper.
+ */
+#if TOPAZ_RX_ACCELERATE
+	/* Must be equal to CONFIG_ARC_MUC_STACK_OFFSET */
+	#define CONFIG_ARC_MUC_STACK_OFFSET_UBOOT	(0x0003F7C0)
+	/* MuC stack, included in CONFIG_ARC_MUC_SRAM_SIZE */
+	#define CONFIG_ARC_MUC_STACK_SIZE		(4 * 1024)
+#else
+	/* Must be equal to CONFIG_ARC_MUC_STACK_OFFSET */
+	#define CONFIG_ARC_MUC_STACK_OFFSET_UBOOT	(0x0003FFA0)
+	/* MuC stack, included in CONFIG_ARC_MUC_SRAM_SIZE */
+	#define CONFIG_ARC_MUC_STACK_SIZE		(6 * 1024)
+#endif
+
+#define CONFIG_ARC_MUC_STACK_INIT_UBOOT		(RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_STACK_OFFSET_UBOOT)
+
+/* Must be equal to RUBY_CRUMBS_OFFSET */
+#define RUBY_CRUMBS_OFFSET_UBOOT	(0x0003FFC0)
+
+#define RUBY_UBOOT_PIGGY_MAX_SIZE		0x14000
+#define RUBY_CRUMBS_ADDR_UBOOT			(RUBY_SRAM_BEGIN + RUBY_CRUMBS_OFFSET_UBOOT)
+
+/*
+ * Crumb structure, sits at the end of 4th SRAM bank. Each core can use it to
+ * store the last run function to detect bus hangs.
+ */
+#define RUBY_CRUMBS_SIZE		64
+
+#ifndef __ASSEMBLY__
+	struct ruby_crumbs_percore {
+		unsigned long	blink;
+		unsigned long	status32;
+		unsigned long	sp;
+	};
+
+	struct ruby_crumbs_mem_section {
+		unsigned long	start;
+		unsigned long	end;
+	};
+
+	struct ruby_crumbs {
+		struct ruby_crumbs_percore	lhost;
+		struct ruby_crumbs_percore	muc;
+		struct ruby_crumbs_percore	dsp;
+		/*
+		 * allow (somewhat) intelligent parsing of muc stacks by
+		 * specifying the text section
+		 */
+		struct ruby_crumbs_mem_section	muc_dram;
+		struct ruby_crumbs_mem_section	muc_sram;
+
+		/*
+		 * magic token; if set incorrectly we probably have
+		 * random values after power-on
+		 */
+		unsigned long			magic;
+	};
+
+	#define	RUBY_CRUMBS_MAGIC	0x7c97be8f
+
+#endif /* __ASSEMBLY__ */
+
+/* Utility functions */
+#ifndef __ASSEMBLY__
+	#if defined(AUC_BUILD) || defined(RUBY_MINI)
+		#define NO_RUBY_WEAK	1
+	#else
+		#define NO_RUBY_WEAK	0
+	#endif
+
+	#define RUBY_BAD_BUS_ADDR	((unsigned  long)0)
+	#define RUBY_BAD_VIRT_ADDR	((void*)RUBY_BAD_BUS_ADDR)
+	#define RUBY_ERROR_ADDR		((unsigned long)0xefefefef)
+
+	#if defined(__CHECKER__)
+		#define RUBY_INLINE			static inline __attribute__((always_inline))
+		#define RUBY_WEAK(name)			RUBY_INLINE
+	#elif defined(__GNUC__)
+		/*GCC*/
+		#define RUBY_INLINE			static inline __attribute__((always_inline))
+		#if NO_RUBY_WEAK
+			#define RUBY_WEAK(name)		RUBY_INLINE
+		#else
+			#define RUBY_WEAK(name)		__attribute__((weak))
+		#endif
+	#else
+		/*MCC*/
+		#define RUBY_INLINE			static _Inline
+		#if NO_RUBY_WEAK
+			#define RUBY_WEAK(name)		RUBY_INLINE
+		#else
+			#define RUBY_WEAK(name)		pragma Weak(name);
+		#endif
+		#pragma Offwarn(428)
+	#endif
+
+	#define ____in_mem_range(addr, start, size)	\
+		(((addr) >= (start)) && ((addr) < (start) + (size)))
+
+	#if defined(STATIC_CHECK) || defined(__CHECKER__)
+		RUBY_INLINE int __in_mem_range(unsigned long addr, unsigned long start, unsigned long size)
+		{
+			return (((addr) >= (start)) && ((addr) < (start) + (size)));
+		}
+	#else
+		#define __in_mem_range ____in_mem_range
+	#endif
+
+	#if RUBY_MMAP_FLIP
+		RUBY_INLINE unsigned long virt_to_bus(const void *addr)
+		{
+			unsigned long ret = (unsigned long)addr;
+			if (__in_mem_range(ret, RUBY_SRAM_FLIP_BEGIN, RUBY_SRAM_SIZE)) {
+				ret = ret - RUBY_SRAM_FLIP_BEGIN + RUBY_SRAM_NOFLIP_BEGIN;
+			} else if (__in_mem_range(ret, RUBY_DRAM_FLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+				ret = ret - RUBY_DRAM_FLIP_BEGIN + RUBY_DRAM_NOFLIP_BEGIN;
+			} else if (ret < RUBY_HARDWARE_BEGIN) {
+				ret = RUBY_BAD_BUS_ADDR;
+			}
+			return ret;
+		}
+		RUBY_WEAK(bus_to_virt) void* bus_to_virt(unsigned long addr)
+		{
+			unsigned long ret = addr;
+			if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_BEGIN, RUBY_SRAM_SIZE)) {
+				ret = ret - RUBY_SRAM_NOFLIP_BEGIN + RUBY_SRAM_FLIP_BEGIN;
+			} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+				ret = ret - RUBY_DRAM_NOFLIP_BEGIN + RUBY_DRAM_FLIP_BEGIN;
+			} else if (ret < RUBY_HARDWARE_BEGIN) {
+				ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
+			}
+			return (void*)ret;
+		}
+	#else
+		/* Map 1:1, (x) address must be upper then 0x8000_0000. */
+		#define virt_to_bus(x) ((unsigned long)(x))
+		#define bus_to_virt(x) ((void *)(x))
+	#endif /* #if RUBY_MMAP_FLIP */
+
+	#ifndef __GNUC__
+		/* MCC */
+		#pragma Popwarn()
+	#endif
+
+#endif /* #ifndef __ASSEMBLY__ */
+
+#endif /* __COMMON_MEM_H */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h b/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h
new file mode 100644
index 0000000..13899f3
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h
@@ -0,0 +1,12 @@
+#define TOPAZ_PLATFORM
+#define TOPAZ_FPGA_PLATFORM 0
+#define TOPAZ_EMAC_NULL_BUF_WR
+#undef TOPAZ_FPGA_UMCTL1
+#define PLATFORM_WMAC_MODE ap
+#undef PLATFORM_DEFAULT_BOARD_ID
+#define ARC_HW_REV_NEEDS_TLBMISS_FIX
+#define TOPAZ_SUPPORT_UMM 0
+#define TOPAZ_SUPPORT_256MB_DDR 0
+#define FLASH_SUPPORT_64KB
+#define WPA_TKIP_SUPPORT 0
+#define SIGMA_TESTBED_SUPPORT 0
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/pktlogger/pktlogger_nl_common.h b/arch/arc/plat-qtn/sdk-qsr1000/common/pktlogger/pktlogger_nl_common.h
new file mode 100644
index 0000000..22e842c
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/pktlogger/pktlogger_nl_common.h
@@ -0,0 +1,135 @@
+/* (C)2016 Quantenna Communications Inc. */
+
+/* Common structures for netdebug - userspace/kernelspace interface */
+#ifndef __PKTLOGGER_NL_COMMON_H__
+#define __PKTLOGGER_NL_COMMON_H__
+
+
+#define PKTLOGGER_MSG_MAGIC 0x79FFA904
+
+/* Magic, version, type, length then variable value. */
+struct pktlogger_nl_hdr_t
+{
+	uint32_t magic;
+	uint32_t mver;
+	uint32_t mtype;
+	uint32_t mlen;
+	uint32_t mseq;
+	uint8_t  msg[0];
+};
+
+enum pktlogger_nl_msg
+{
+	PKTLOGGER_NETLINK_MTYPE_QUERY        = 1,
+	PKTLOGGER_NETLINK_MTYPE_CONFIG       = 2,
+	PKTLOGGER_NETLINK_MTYPE_CONFIG_ONE   = 3,
+	PKTLOGGER_NETLINK_MTYPE_PTYPE_CONFIG = 4
+};
+
+struct pktlogger_nl_query_t
+{
+	struct pktlogger_nl_hdr_t hdr;
+	uint32_t query_num;
+	uint32_t arg1;
+	uint32_t arg2;
+	uint8_t data[0];
+};
+
+struct pktlogger_nl_pktlog_config_t
+{
+	uint16_t type;
+	uint16_t flags;
+	char     name[16];
+	uint32_t rate;
+	uint32_t history;
+	uint16_t struct_bsize;
+	uint16_t struct_vsize;
+};
+
+struct pktlogger_nl_radio_config_t
+{
+	uint32_t destip;	/* Network endian destination IP address for pktlogger data.       */
+	uint32_t srcip;
+	uint8_t  destmac[6];	/* Destination MAC address.                                        */
+	uint8_t  srcmac[6];	/* Source MAC address.                                             */
+	uint16_t destport;	/* UDP dest port for this radio.                                   */
+	uint16_t srcport;	/* UDP src port for this radio.                                    */
+	uint32_t pktlog_ver_cnt;/*  0x000000FF: Number of entries in the pktlog_configs array,
+				0x00FFFF00: reserved
+				0xFF000000: Version of pktlog_types.                               */
+	char     radioname[16];	/* Radio name (eg, wifi0, wifi1, wifi2).
+				Filled out on query, ignored on configuration.                     */
+	struct   pktlogger_nl_pktlog_config_t pktlog_configs[16];	/* Per-pktlogger config.
+									Pointer to the first element. */
+};
+
+struct pktlogger_nl_config_t
+{
+	uint32_t rev;
+	uint32_t rcontrol;
+	struct pktlogger_nl_radio_config_t per_radio[3];
+};
+
+struct pktlogger_nl_config_one_t
+{
+	uint32_t radio_index;
+	struct pktlogger_nl_pktlog_config_t config;
+};
+
+struct pktlogger_nl_config_set_t
+{
+	struct pktlogger_nl_hdr_t hdr;
+	struct pktlogger_nl_config_t config;
+};
+
+struct pktlogger_nl_config_oneset_t
+{
+	struct pktlogger_nl_hdr_t hdr;
+	struct pktlogger_nl_config_one_t config;
+};
+
+enum pktlogger_nl_query
+{
+	PKTLOGGER_QUERY_STRUCT       = 0,
+	PKTLOGGER_QUERY_CONFIG       = 1,
+	PKTLOGGER_QUERY_CONFIG_ONE   = 2,
+	PKTLOGGER_QUERY_PTYPE_CONFIG = 3
+};
+
+/* pktlogger header - for all incoming data frames */
+struct pktlogger_nl_pktlogger_hdr
+{
+	struct udphdr hdr;
+	uint8_t type;
+	uint8_t opmode;
+	/**
+	 * The source address (the bridge MAC address).
+	 */
+	unsigned char src[6];
+	u_int32_t version;
+	u_int32_t builddate;
+	/**
+	 * Identifying string to easily see in packet dumps that this is a packetlogger packet.
+	 */
+	char buildstring[32];
+	u_int8_t flags;
+
+	/**
+	 * Epoch timestamp.
+	 */
+	u_int32_t timestamp;
+	/**
+	 * TSF timestamp low bytes.
+	 */
+	u_int32_t tsf_lo;
+	/**
+	 * TSF timestamp high bytes.
+	 */
+	u_int32_t tsf_hi;
+
+	u_int32_t platform;
+	u_int32_t stats_len;
+	char padding[3];     /* Word align data start */
+} __attribute__((__packed__));
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/queue.h b/arch/arc/plat-qtn/sdk-qsr1000/common/queue.h
new file mode 100644
index 0000000..c384592
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/queue.h
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ * $Id: queue.h 1441 2006-02-06 16:03:21Z mrenzmann $
+ */
+
+#ifndef _SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+#ifdef MUC_BUILD
+#include <stddef.h>
+#endif
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *				SLIST	LIST	STAILQ	TAILQ
+ * _HEAD			+	+	+	+
+ * _HEAD_INITIALIZER		+	+	+	+
+ * _ENTRY			+	+	+	+
+ * _INIT			+	+	+	+
+ * _EMPTY			+	+	+	+
+ * _FIRST			+	+	+	+
+ * _NEXT			+	+	+	+
+ * _PREV			-	-	-	+
+ * _LAST			-	-	+	+
+ * _FOREACH			+	+	+	+
+ * _FOREACH_SAFE		+	+	+	+
+ * _FOREACH_REVERSE		-	-	-	+
+ * _FOREACH_REVERSE_SAFE	-	-	-	+
+ * _INSERT_HEAD			+	+	+	+
+ * _INSERT_BEFORE		-	+	-	+
+ * _INSERT_AFTER		+	+	+	+
+ * _INSERT_TAIL			-	-	+	+
+ * _CONCAT			-	-	+	+
+ * _REMOVE_HEAD			+	-	+	-
+ * _REMOVE			+	+	+	+
+ *
+ */
+
+#ifdef MUC_BUILD
+# define QUEUE_MACRO_LOCK_DEBUG	0
+#else
+# define QUEUE_MACRO_LOCK_DEBUG	0
+#endif
+
+/*
+ * Additional fields to try and locate unprotected accesses of fields.
+ * These macros provide hooks to a function which is checked when the
+ * various queue macros are 
+ */
+#if QUEUE_MACRO_LOCK_DEBUG
+# define QUEUE_MACRO_LOCK_FIELD(prefix)					\
+		int prefix##lockcontext;
+
+# define QUEUE_MACRO_LOCK_INIT(prefix, x)	(x)->prefix##lockcontext = 0
+struct os_spinlock;
+int queue_debug_muc_context_check(int* context, const char* file, const int line);
+# define MUC_CONTEXT_CHECK_IN_INTERRUPT		0x00000001
+# define MUC_CONTEXT_CHECK_NOT_IN_INTERRUPT	0x00000002
+# define MUC_CONTEXT_CHECK(context)		queue_debug_muc_context_check(&(context), __FILE__, __LINE__)
+# define QUEUE_MACRO_LOCK_ASSERT(context)	MUC_CONTEXT_CHECK(context)
+#elif defined(SYSTEM_BUILD)
+# define QUEUE_MACRO_LOCK_FIELD(prefix)	int dummy
+# define QUEUE_MACRO_LOCK_INIT(prefix, x)	int dummy
+# define QUEUE_MACRO_LOCK_ASSERT(context)	__queue_macro_lock_assert_noop()
+static __inline int __queue_macro_lock_assert_noop(void) {
+	return 1;
+}
+#else
+# define QUEUE_MACRO_LOCK_FIELD(prefix)
+# define QUEUE_MACRO_LOCK_INIT(prefix, x)
+# define QUEUE_MACRO_LOCK_ASSERT(context)	__queue_macro_lock_assert_noop()
+static __inline__ int __queue_macro_lock_assert_noop(void) {
+	return 1;
+}
+#endif
+
+#define	QUEUE_MACRO_DEBUG 0
+#if QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct qm_trace {
+	char *lastfile;
+	int lastline;
+	char *prevfile;
+	int prevline;
+};
+
+#define	TRACEBUF	struct qm_trace trace;
+#define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+
+#define	QMD_TRACE_HEAD(head) do {					\
+	(head)->trace.prevline = (head)->trace.lastline;		\
+	(head)->trace.prevfile = (head)->trace.lastfile;		\
+	(head)->trace.lastline = __LINE__;				\
+	(head)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#define	QMD_TRACE_ELEM(elem) do {					\
+	(elem)->trace.prevline = (elem)->trace.lastline;		\
+	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
+	(elem)->trace.lastline = __LINE__;				\
+	(elem)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#else
+#define	QMD_TRACE_ELEM(elem)
+#define	QMD_TRACE_HEAD(head)
+#define	TRACEBUF
+#define	TRASHIT(x)
+#endif	/* QUEUE_MACRO_DEBUG */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+	QUEUE_MACRO_LOCK_FIELD(slh_);					\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+#define SLIST_LOCK_ASSERT(head)		\
+	QUEUE_MACRO_LOCK_ASSERT((head)->slh_lockcontext)
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	SLIST_FIRST(head)	((head)->slh_first)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for ((var) = SLIST_FIRST((head));				\
+	    SLIST_LOCK_ASSERT((head)) && (var);				\
+	    (var) = SLIST_NEXT((var), field))
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST((head));				\
+	    SLIST_LOCK_ASSERT((head)) &&				\
+	    (var) && ((tvar) = SLIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	SLIST_FOREACH_PREVPTR(var, varp, head, field)			\
+	for ((varp) = &SLIST_FIRST((head));				\
+	    SLIST_LOCK_ASSERT((head)) &&				\
+	    ((var) = *(varp)) != NULL;					\
+	    (varp) = &SLIST_NEXT((var), field))
+
+#define	SLIST_INIT(head) do {						\
+	SLIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	SLIST_LOCK_ASSERT((head));					\
+	SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);	\
+	SLIST_NEXT((slistelm), field) = (elm);				\
+} while (0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	SLIST_LOCK_ASSERT((head));					\
+	SLIST_NEXT((elm), field) = SLIST_FIRST((head));			\
+	SLIST_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	SLIST_LOCK_ASSERT((head));					\
+	if (SLIST_FIRST((head)) == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = SLIST_FIRST((head));		\
+		while (SLIST_NEXT(curelm, field) != (elm))		\
+			curelm = SLIST_NEXT(curelm, field);		\
+		SLIST_NEXT(curelm, field) =				\
+		    SLIST_NEXT(SLIST_NEXT(curelm, field), field);	\
+	}								\
+} while (0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	SLIST_LOCK_ASSERT((head));					\
+	SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);	\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+	QUEUE_MACRO_LOCK_FIELD(stqh_);	/* debug locking primitive */	\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+#define STAILQ_LOCK_ASSERT(head)	\
+	QUEUE_MACRO_LOCK_ASSERT((head)->stqh_lockcontext)
+#if QUEUE_MACRO_LOCK_DEBUG
+# define STAILQ_INIT_LOCK_DEBUG(head, lock)	(head)->stqh_lock = lock;
+#else
+# define STAILQ_INIT_LOCK_DEBUG(head, intref)
+#endif
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (0)
+
+#define	STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for((var) = STAILQ_FIRST((head));				\
+	   STAILQ_LOCK_ASSERT((head)) && (var);				\
+	   (var) = STAILQ_NEXT((var), field))
+
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST((head));				\
+	    STAILQ_LOCK_ASSERT((head)) &&				\
+	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	STAILQ_INIT(head) do {						\
+	STAILQ_FIRST((head)) = NULL;					\
+	(head)->stqh_last = &STAILQ_FIRST((head));			\
+	QUEUE_MACRO_LOCK_INIT(stqh_, (head));				\
+} while (0)
+
+#define	STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	STAILQ_LOCK_ASSERT(head);					\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_NEXT((tqelm), field) = (elm);				\
+} while (0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	STAILQ_LOCK_ASSERT(head);					\
+	if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &STAILQ_NEXT((elm), field);		\
+	STAILQ_FIRST((head)) = (elm);					\
+} while (0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	STAILQ_LOCK_ASSERT(head);					\
+	STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &STAILQ_NEXT((elm), field);			\
+} while (0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)					\
+		((char *)((head)->stqh_last) - __offsetof(struct type, field))))
+
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	STAILQ_LOCK_ASSERT(head);					\
+	if (STAILQ_FIRST((head)) == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = STAILQ_FIRST((head));		\
+		while (STAILQ_NEXT(curelm, field) != (elm))		\
+			curelm = STAILQ_NEXT(curelm, field);		\
+		if ((STAILQ_NEXT(curelm, field) =			\
+		     STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
+	}								\
+} while (0)
+
+
+#define	STAILQ_REMOVE_AFTER(head, elm, field) do {			\
+	STAILQ_LOCK_ASSERT(head);					\
+	if (STAILQ_NEXT(elm, field)) {		\
+		if ((STAILQ_NEXT(elm, field) =			\
+		    STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)\
+			(head)->stqh_last = &STAILQ_NEXT((elm), field); \
+	}								\
+} while (0)
+
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	STAILQ_LOCK_ASSERT(head);					\
+	if ((STAILQ_FIRST((head)) =					\
+	     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)		\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+#define	STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {			\
+	STAILQ_LOCK_ASSERT(head);					\
+	if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL)	\
+		(head)->stqh_last = &STAILQ_FIRST((head));		\
+} while (0)
+
+/*
+ * List declarations.
+ */
+#define	ATH_LIST_HEAD(name, type)					\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+	QUEUE_MACRO_LOCK_FIELD(lh_);					\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+#define LIST_LOCK_ASSERT(head)	\
+	QUEUE_MACRO_LOCK_ASSERT((head)->lh_lockcontext)
+
+/*
+ * List functions.
+ */
+
+#define	LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	LIST_FIRST(head)	((head)->lh_first)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = LIST_FIRST((head));				\
+	    LIST_LOCK_ASSERT((head)) && (var);				\
+	    (var) = LIST_NEXT((var), field))
+
+#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = LIST_FIRST((head));				\
+	    LIST_LOCK_ASSERT((head)) &&					\
+	    (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	LIST_INIT(head) do {						\
+	LIST_FIRST((head)) = NULL;					\
+} while (0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
+		LIST_NEXT((listelm), field)->field.le_prev =		\
+		    &LIST_NEXT((elm), field);				\
+	LIST_NEXT((listelm), field) = (elm);				\
+	(elm)->field.le_prev = &LIST_NEXT((listelm), field);		\
+} while (0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	LIST_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &LIST_NEXT((elm), field);		\
+} while (0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	LIST_LOCK_ASSERT((head));					\
+	if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)	\
+		LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
+	LIST_FIRST((head)) = (elm);					\
+	(elm)->field.le_prev = &LIST_FIRST((head));			\
+} while (0)
+
+#define	LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	if (LIST_NEXT((elm), field) != NULL)				\
+		LIST_NEXT((elm), field)->field.le_prev = 		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = LIST_NEXT((elm), field);		\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	TAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+	TRACEBUF							\
+	QUEUE_MACRO_LOCK_FIELD(tqh_);					\
+}
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).tqh_first }
+#if (!defined(TAILQ_ENTRY))
+#define	TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+	TRACEBUF							\
+}
+#endif
+
+#define TAILQ_LOCK_ASSERT(head)	\
+	QUEUE_MACRO_LOCK_ASSERT((head)->tqh_lockcontext)
+
+/*
+ * Tail queue functions.
+ */
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+		QMD_TRACE_HEAD(head);					\
+		QMD_TRACE_HEAD(head2);					\
+	}								\
+} while (0)
+
+#define	TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = TAILQ_FIRST((head));				\
+	    TAILQ_LOCK_ASSERT((head)) && (var);				\
+	    (var) = TAILQ_NEXT((var), field))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = TAILQ_FIRST((head));				\
+	    TAILQ_LOCK_ASSERT((head)) &&				\
+	    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    TAILQ_LOCK_ASSERT((head)) && (var);				\
+	    (var) = TAILQ_PREV((var), headname, field))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    TAILQ_LOCK_ASSERT((head)) &&				\
+	    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	TAILQ_INIT(head) do {						\
+	TAILQ_FIRST((head)) = NULL;					\
+	(head)->tqh_last = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+} while (0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	TAILQ_LOCK_ASSERT((head));					\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    &TAILQ_NEXT((elm), field);				\
+	else {								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	TAILQ_NEXT((listelm), field) = (elm);				\
+	(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	TAILQ_NEXT((elm), field) = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);		\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+	QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	TAILQ_LOCK_ASSERT((head));					\
+	if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)	\
+		TAILQ_FIRST((head))->field.tqe_prev =			\
+		    &TAILQ_NEXT((elm), field);				\
+	else								\
+		(head)->tqh_last = &TAILQ_NEXT((elm), field);		\
+	TAILQ_FIRST((head)) = (elm);					\
+	(elm)->field.tqe_prev = &TAILQ_FIRST((head));			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	TAILQ_LOCK_ASSERT((head));					\
+	TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &TAILQ_NEXT((elm), field);			\
+	QMD_TRACE_HEAD(head);						\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+#define	TAILQ_LAST(head, headname)					\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	TAILQ_LOCK_ASSERT((head));					\
+	if ((TAILQ_NEXT((elm), field)) != NULL)				\
+		TAILQ_NEXT((elm), field)->field.tqe_prev =		\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		QMD_TRACE_HEAD(head);					\
+	}								\
+	*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);		\
+	TRASHIT((elm)->field.tqe_next);					\
+	TRASHIT((elm)->field.tqe_prev);					\
+	QMD_TRACE_ELEM(&(elm)->field);					\
+} while (0)
+
+
+#ifdef _KERNEL
+
+/*
+ * XXX insque() and remque() are an old way of handling certain queues.
+ * They bogusly assumes that all queue heads look alike.
+ */
+
+struct quehead {
+	struct quehead *qh_link;
+	struct quehead *qh_rlink;
+};
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER)
+
+static __inline void
+insque(void *a, void *b)
+{
+	struct quehead *element = (struct quehead *)a,
+		 *head = (struct quehead *)b;
+
+	element->qh_link = head->qh_link;
+	element->qh_rlink = head;
+	head->qh_link = element;
+	element->qh_link->qh_rlink = element;
+}
+
+static __inline void
+remque(void *a)
+{
+	struct quehead *element = (struct quehead *)a;
+
+	element->qh_link->qh_rlink = element->qh_rlink;
+	element->qh_rlink->qh_link = element->qh_link;
+	element->qh_rlink = 0;
+}
+
+#else /* !(__GNUC__ || __INTEL_COMPILER) */
+
+void	insque(void *a, void *b);
+void	remque(void *a);
+
+#endif /* __GNUC__ || __INTEL_COMPILER */
+
+#endif /* _KERNEL */
+
+#endif /* !_SYS_QUEUE_H_ */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_arasan_emac_ahb.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_arasan_emac_ahb.h
new file mode 100755
index 0000000..15dae08
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_arasan_emac_ahb.h
@@ -0,0 +1,437 @@
+/*
+ *  drivers/net/arasan_emac_ahb.h
+ *
+ *  Copyright (c) Quantenna Communications Incorporated 2007.
+ *  All rights reserved.
+ *
+ * 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
+ *
+ */
+
+#ifndef __COMMON_RUBY_ARASAN_EMAC_AHB_H
+#define __COMMON_RUBY_ARASAN_EMAC_AHB_H	1
+
+#include "ruby_platform.h"
+#ifdef TOPAZ_AMBER_IP
+#include <include/qtn/amber.h>
+#endif
+
+extern __inline__ void __mydelay(unsigned long loops)
+{
+	__asm__ __volatile__ ( "1: \n\t"
+			     "sub.f %0, %1, 1\n\t"
+			     "jpnz 1b"
+			     : "=r" (loops)
+			     : "0" (loops));
+}
+
+/*
+ * Division by multiplication: you don't have to worry about loss of
+ * precision.
+ *
+ * Use only for very small delays ( < 1 msec).  Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays.  This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+static inline void __const_myudelay(unsigned long xloops)
+{
+	__asm__ ("mpyhu %0, %1, %2"
+		 : "=r" (xloops)
+		 : "r" (xloops), "r" (1<<20));	/* Number derived from loops per jiffy */
+	__mydelay(xloops * 100);		/* Jiffies per sec */
+}
+
+static inline void __myudelay(unsigned long usecs)
+{
+	__const_myudelay(usecs * 4295);	/* 2**32 / 1000000 */
+}
+#ifndef MAX_UDELAY_MS
+#define MAX_UDELAY_MS	5
+#endif
+
+#ifndef mydelay
+#define mydelay(n) (\
+	(__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? __myudelay((n)*1000) : \
+	({unsigned long __ms=(n); while (__ms--) __myudelay(1000);}))
+#endif
+
+#define		DELAY_40MILLISEC	(40)
+#define		DELAY_50MILLISEC	(50)
+
+/* Arasan Gigabit AHB controller register offsets */
+#define EMAC_DMA_CONFIG			0x0000
+#define EMAC_DMA_CTRL			0x0004
+#define EMAC_DMA_STATUS_IRQ		0x0008
+#define EMAC_DMA_INT_ENABLE		0x000C
+#define EMAC_DMA_TX_AUTO_POLL		0x0010
+#define EMAC_DMA_TX_POLL_DEMAND		0x0014
+#define EMAC_DMA_RX_POLL_DEMAND		0x0018
+#define EMAC_DMA_TX_BASE_ADDR		0x001C
+#define EMAC_DMA_RX_BASE_ADDR		0x0020
+#define EMAC_DMA_MISSED_FRAMES		0x0024
+#define EMAC_DMA_STOP_FLUSHES		0x0028
+#define EMAC_DMA_RX_IRQ_MITIGATION	0x002C
+#define EMAC_DMA_CUR_TXDESC_PTR		0x0030
+#define EMAC_DMA_CUR_TXBUF_PTR		0x0034
+#define EMAC_DMA_CUR_RXDESC_PTR		0x0038
+#define EMAC_DMA_CUR_RXBUF_PTR		0x003C
+
+#define EMAC_MAC_GLOBAL_CTRL		0x0100
+#define EMAC_MAC_TX_CTRL		0x0104
+#define EMAC_MAC_RX_CTRL		0x0108
+#define EMAC_MAC_MAX_FRAME_SIZE		0x010C
+#define EMAC_MAC_TX_JABBER_SIZE		0x0110
+#define EMAC_MAC_RX_JABBER_SIZE		0x0114
+#define EMAC_MAC_ADDR_CTRL		0x0118
+#define EMAC_MAC_ADDR1_HIGH		0x0120
+#define EMAC_MAC_ADDR1_MED		0x0124
+#define EMAC_MAC_ADDR1_LOW		0x0128
+#define EMAC_MAC_ADDR2_HIGH		0x012C
+#define EMAC_MAC_ADDR2_MED		0x0130
+#define EMAC_MAC_ADDR2_LOW		0x0134
+#define EMAC_MAC_ADDR3_HIGH		0x0138
+#define EMAC_MAC_ADDR3_MED		0x013C
+#define EMAC_MAC_ADDR3_LOW		0x0140
+#define EMAC_MAC_ADDR4_HIGH		0x0144
+#define EMAC_MAC_ADDR4_MED		0x0148
+#define EMAC_MAC_ADDR4_LOW		0x014C
+#define EMAC_MAC_TABLE1			0x0150
+#define EMAC_MAC_TABLE2			0x0154
+#define EMAC_MAC_TABLE3			0x0158
+#define EMAC_MAC_TABLE4			0x015C
+#define EMAC_MAC_FLOW_CTRL		0x0160
+#define EMAC_MAC_FLOW_PAUSE_GENERATE	0x0164
+#define EMAC_MAC_FLOW_SA_HIGH		0x0168
+#define EMAC_MAC_FLOW_SA_MED		0x016C
+#define EMAC_MAC_FLOW_SA_LOW		0x0170
+#define EMAC_MAC_FLOW_DA_HIGH		0x0174
+#define EMAC_MAC_FLOW_DA_MED		0x0178
+#define EMAC_MAC_FLOW_DA_LOW		0x017C
+#define EMAC_MAC_FLOW_PAUSE_TIMEVAL	0x0180
+#define EMAC_MAC_MDIO_CTRL		0x01A0
+#define EMAC_MAC_MDIO_DATA		0x01A4
+#define EMAC_MAC_RXSTAT_CTRL		0x01A8
+#define EMAC_MAC_RXSTAT_DATA_HIGH	0x01AC
+#define EMAC_MAC_RXSTAT_DATA_LOW	0x01B0
+#define EMAC_MAC_TXSTAT_CTRL		0x01B4
+#define EMAC_MAC_TXSTAT_DATA_HIGH	0x01B8
+#define EMAC_MAC_TXSTAT_DATA_LOW	0x01BC
+#define EMAC_MAC_TX_ALMOST_FULL		0x01C0
+#define EMAC_MAC_TX_START_THRESHOLD	0x01C4
+#define EMAC_MAC_RX_START_THRESHOLD	0x01C8
+#define EMAC_MAC_INT			0x01E0
+#define EMAC_MAC_INT_ENABLE		0x01E4
+
+#ifndef __ASSEMBLY__
+
+/* Common structure for tx and rx descriptors */
+struct emac_desc {
+	volatile u32 status;
+	volatile u32 control;
+	volatile u32 bufaddr1;
+	volatile u32 bufaddr2;
+};
+
+enum DmaRxDesc {
+	/* status field */
+	RxDescOwn = (1 << 31),
+	RxDescFirstDesc = (1 << 30),
+	RxDescLastDesc = (1 << 29),
+	RxDescStatusLenErr = (1 << 23),
+	RxDescStatusJabberErr = (1 << 22),
+	RxDescStatusMaxLenErr = (1 << 21),
+	RxDescStatusCRCErr = (1 << 20),
+	RxDescStatusRuntFrame = (1 << 15),
+	RxDescStatusAlignErr = (1 << 14),
+	RxDescStatusShift = 14,
+	RxDescStatusMask = 0x7fff,
+	RxDescFrameLenShift = 0,
+	RxDescFrameLenMask = 0x3fff,
+	/* control field */
+	RxDescEndOfRing = (1 << 26),
+	RxDescChain2ndAddr = (1 << 25),
+	RxDescBuf2SizeShift = 12,
+	RxDescBuf2SizeMask = 0xfff,
+	RxDescBuf1SizeShift = 0,
+	RxDescBuf1SizeMask = 0xfff,
+};
+
+enum DmaTxDesc {
+	/* status field */
+	TxDescOwn = (1 << 31),
+	TxDescStatusShift = 0,
+	TxDescStatusMask = 0x8fffffff,
+	/* control field */
+	TxDescIntOnComplete = (1 << 31),
+	TxDescLastSeg = (1 << 30),
+	TxDescFirstSeg = (1 << 29),
+	TxDescCrcDisable = (1 << 28),
+	TxDescPadDisable = (1 << 27),
+	TxDescEndOfRing = (1 << 26),
+	TxDescChain2ndAddr = (1 << 25),
+	TxDescForceEopErr = (1 << 24),
+	TxDescBuf2SizeShift = 12,
+	TxDescBuf2SizeMask = 0xfff,
+	TxDescBuf1SizeShift = 0,
+	TxDescBuf1SizeMask = 0xfff,
+};
+
+enum AraMacRegVals {
+	/* DMA config register */
+	DmaSoftReset = 1,
+	Dma1WordBurst = (0x01 << 1),
+	Dma4WordBurst = (0x04 << 1),
+	Dma16WordBurst = (0x10 << 1),
+	DmaRoundRobin = (1 << 15),
+	DmaWait4Done = (1 << 16),
+	DmaStrictBurst = (1 << 17),
+	Dma64BitMode = (1 << 18),
+	/* DMA control register */
+	DmaStartTx = (1 << 0),
+	DmaStartRx = (1 << 1),
+	/* DMA status/interrupt & interrupt mask registers */
+	DmaTxDone = (1 << 0),
+	DmaNoTxDesc = (1 << 1),
+	DmaTxStopped = (1 << 2),
+	DmaRxDone = (1 << 4),
+	DmaNoRxDesc = (1 << 5),
+	DmaRxStopped = (1 << 6),
+	DmaRxMissedFrame = (1 << 7),
+	DmaMacInterrupt = (1 << 8),
+	DmaAllInts = DmaTxDone | DmaNoTxDesc | DmaTxStopped | DmaRxDone | 
+		DmaNoRxDesc | DmaRxStopped | DmaRxMissedFrame | DmaMacInterrupt,
+	DmaTxStateMask = (7 << 16),
+	DmaTxStateStopped = (0 << 16),
+	DmaTxStateFetchDesc = (1 << 16),
+	DmaTxStateFetchData = (2 << 16),
+	DmaTxStateWaitEOT = (3 << 16),
+	DmaTxStateCloseDesc = (4 << 16),
+	DmaTxStateSuspended = (5 << 16),
+	DmaRxStateMask = (15 << 21),
+	DmaRxStateStopped = (0 << 21),
+	DmaRxStateFetchDesc = (1 << 21),
+	DmaRxStateWaitEOR = (2 << 21),
+	DmaRxStateWaitFrame = (3 << 21),
+	DmaRxStateSuspended = (4 << 21),
+	DmaRxStateCloseDesc = (5 << 21),
+	DmaRxStateFlushBuf = (6 << 21),
+	DmaRxStatePutBuf = (7 << 21),
+	DmaRxStateWaitStatus = (8 << 21),
+	/* MAC global control register */
+	MacSpeed10M = (0 << 0),
+	MacSpeed100M = (1 << 0),
+	MacSpeed1G = (2 << 0),
+	MacSpeedMask = (3 << 0),
+	MacFullDuplex = (1 << 2),
+	MacResetRxStats = (1 << 3),
+	MacResetTxStats = (1 << 4),
+	/* MAC TX control */
+	MacTxEnable = (1 << 0),
+	MacTxInvertFCS = (1 << 1),
+	MacTxDisableFCSInsertion = (1 << 2),
+	MacTxAutoRetry = (1 << 3),
+	MacTxIFG96 = (0 << 4),
+	MacTxIFG64 = (1 << 4),
+	MacTxIFG128 = (2 << 4),
+	MacTxIFG256 = (3 << 4),
+	MacTxPreamble7 = (0 << 6),
+	MacTxPreamble3 = (2 << 6),
+	MacTxPreamble5 = (3 << 6),
+	/* MAC RX control */
+	MacRxEnable = (1 << 0),
+	MacRxStripFCS = (1 << 2),
+	MacRxStoreAndForward = (1 << 3),
+	MacAccountVLANs = (1 << 6),
+	/* MAC address control */
+	MacAddr1Enable = (1 << 0),
+	MacAddr2Enable = (1 << 1),
+	MacAddr3Enable = (1 << 2),
+	MacAddr4Enable = (1 << 3),
+	MacInverseAddr1Enable = (1 << 4),
+	MacInverseAddr2Enable = (1 << 5),
+	MacInverseAddr3Enable = (1 << 6),
+	MacInverseAddr4Enable = (1 << 7),
+	MacPromiscuous = (1 << 8),
+	/* MAC flow control */
+	MacFlowDecodeEnable = (1 << 0),
+	MacFlowGenerationEnable = (1 << 1),
+	MacAutoFlowGenerationEnable = (1 << 2),
+	MacFlowMulticastMode = (1 << 3),
+	MacBlockPauseFrames = (1 << 4),
+	/* MDIO control register values */
+	MacMdioCtrlPhyMask = 0x1f,
+	MacMdioCtrlPhyShift = 0,
+	MacMdioCtrlRegMask = 0x1f,
+	MacMdioCtrlRegShift = 5,
+	MacMdioCtrlRead = (1 << 10),
+	MacMdioCtrlWrite = 0,
+	MacMdioCtrlClkMask = 0x3,
+	MacMdioCtrlClkShift = 11,
+	MacMdioCtrlStart = (1 << 15),
+	/* MDIO data register values */
+	MacMdioDataMask = 0xffff,
+	/* MAC interrupt & interrupt mask values */
+	MacUnderrun = (1 << 0),
+	MacJabber = (1 << 0),
+	/* RX statistics counter control */
+	RxStatReadBusy = (1 << 15),
+	/* TX statistics counter control */
+	TxStatReadBusy = (1 << 15),
+};
+
+enum ArasanTxStatisticsCounters {
+	FramesSentOK = 0,
+	FramesSentTotal = 1,
+	OctetsSentOK = 2,
+	FramesSentError = 3,
+	FramesSentSingleCol = 4,
+	FramesSentMultipleCol = 5,
+	FramesSentLateCol = 6,
+	FramesSentExcessiveCol = 7,
+	FramesSentUnicast = 8,
+	FramesSentMulticast = 9,
+	FramesSentBroadcast = 10,
+	FramesSentPause = 11,
+	TxLastStatCounter = 11,
+};
+
+enum ArasanRxStatisticsCounters {
+	FramesRxOK = 0,
+	FramesRxTotal = 1,
+	FramesRxCrcErr = 2,
+	FramesRxAlignErr = 3,
+	FramesRxErrTotal = 4,
+	OctetsRxOK = 5,
+	OctetsRxTotal = 6,
+	FramesRxUnicast = 7,
+	FramesRxMulticast = 8,
+	FramesRxBroadcast = 9,
+	FramesRxPause = 10,
+	FramesRxLenErr = 11,
+	FramesRxUndersized = 12,
+	FramesRxOversized = 13,
+	FramesRxFragments = 14,
+	FramesRxJabber = 15,
+	FramesRx64bytes = 16,
+	FramesRx65to127bytes = 17,
+	FramesRx128to255bytes = 18,
+	FramesRx256to511bytes = 19,
+	FramesRx512to1023bytes = 20,
+	FramesRx1024to1518bytes = 21,
+	FramesRxOver1518bytes = 22,
+	FramesRxDroppedBufFull = 23,
+	FramesRxTruncatedBufFull = 24,
+	RxLastStatCounter = 24,
+};
+
+extern int mdc_clk_divisor;
+static inline void arasan_initialize_release_reset(uint32_t emac0_cfg,
+		uint32_t emac1_cfg, uint32_t rgmii_timing, uint32_t ext_reset)
+{
+	uint32_t emac_cfg = emac0_cfg | emac1_cfg;
+	unsigned long reset_mask;
+	uint32_t mii_value = 0x481 | ((mdc_clk_divisor & MacMdioCtrlClkMask) << MacMdioCtrlClkShift);
+
+	if (!(emac_cfg & EMAC_IN_USE)) {
+		return;
+	}
+
+	/* both interfaces (if enabled) must use same mii config so we can just or here */
+	writel(RUBY_SYS_CTL_MASK_MII, RUBY_SYS_CTL_MASK);
+	if (emac0_cfg & EMAC_PHY_MII) {
+		writel(RUBY_SYS_CTL_MASK_MII_EMAC0, RUBY_SYS_CTL_CTRL);
+	}
+	if (emac1_cfg & EMAC_PHY_MII) {
+		writel(RUBY_SYS_CTL_MASK_MII_EMAC1, RUBY_SYS_CTL_CTRL);
+	}
+	if (!(emac0_cfg & EMAC_PHY_MII) && !(emac1_cfg & EMAC_PHY_MII)){
+		writel(0, RUBY_SYS_CTL_CTRL);
+	}
+	/* Have PLL clock signal go out */
+	writel_topaz(TOPAZ_SYS_CTL_PLLCLKOUT_EN, RUBY_SYS_CTL_MASK);
+	writel_topaz(TOPAZ_SYS_CTL_PLLCLKOUT_EN, RUBY_SYS_CTL_CTRL);
+
+	/*
+	 * if RGMII mode, we need to configure the clock before we release reset and also
+	 * make sure we actually reset the block
+	 */
+	writel(rgmii_timing, RUBY_SYS_CTL_GMII_CLKDLL);
+
+	/* Release Ethernet busses from reset separately to emacs */
+	reset_mask = RUBY_SYS_CTL_RESET_NETSS | RUBY_SYS_CTL_RESET_IOSS;
+	writel(reset_mask, RUBY_SYS_CTL_CPU_VEC_MASK);
+	writel(reset_mask, RUBY_SYS_CTL_CPU_VEC);
+
+	if (emac1_cfg & EMAC_IN_USE) {
+		/*
+		 * emac1 only or emac0 + emac1 configurations both require emac0
+		 * to be taken out of reset, since both PHYs use a shared mdio bus
+		 * starting from emac0
+		 */
+		reset_mask = RUBY_SYS_CTL_RESET_ENET0 | RUBY_SYS_CTL_RESET_ENET1;
+	} else if (emac0_cfg & EMAC_IN_USE) {
+		reset_mask = RUBY_SYS_CTL_RESET_ENET0;
+	}
+#ifdef TOPAZ_AMBER_IP
+	amber_bus_flush_req(TOPAZ_AMBER_BUS_FLUSH_RGMII);
+#endif
+	if (ext_reset) {
+		reset_mask |= RUBY_SYS_CTL_RESET_EXT;
+	}
+	if (reset_mask && (readl(RUBY_SYS_CTL_CPU_VEC) & reset_mask) != reset_mask) {
+		writel(reset_mask, RUBY_SYS_CTL_CPU_VEC_MASK);
+		if (ext_reset) {
+			writel(RUBY_SYS_CTL_RESET_EXT, RUBY_SYS_CTL_CPU_VEC);
+			mydelay(DELAY_40MILLISEC);
+			reset_mask &= ~RUBY_SYS_CTL_RESET_EXT;
+		}
+		writel(0, RUBY_SYS_CTL_CPU_VEC);
+		mydelay(DELAY_50MILLISEC);
+	}
+	/* Bring the EMAC out of reset */
+	writel(reset_mask, RUBY_SYS_CTL_CPU_VEC_MASK);
+	writel(reset_mask, RUBY_SYS_CTL_CPU_VEC);
+
+	writel(0, RUBY_SYS_CTL_MASK);
+	writel(0, RUBY_SYS_CTL_CPU_VEC_MASK);
+#ifdef TOPAZ_AMBER_IP
+	amber_bus_flush_release(TOPAZ_AMBER_BUS_FLUSH_RGMII);
+#endif
+
+	/*
+	 * Trigger dummy MDIO read to set MDC clock
+	 */
+	writel(mii_value, RUBY_ENET0_BASE_ADDR + EMAC_MAC_MDIO_CTRL);
+
+	/*
+	 * Remove EMAC DMA from soft reset; all other EMAC register
+	 * writes result in bus hang if the EMAC is in soft reset
+	 */
+	if (emac0_cfg & EMAC_IN_USE) {
+		writel(0x0, RUBY_ENET0_BASE_ADDR + EMAC_DMA_CONFIG);
+		writel(0x0, RUBY_ENET0_BASE_ADDR + EMAC_DMA_CTRL);
+	}
+	if (emac1_cfg & EMAC_IN_USE) {
+		writel(0x0, RUBY_ENET1_BASE_ADDR + EMAC_DMA_CONFIG);
+		writel(0x0, RUBY_ENET1_BASE_ADDR + EMAC_DMA_CTRL);
+	}
+
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_cfg.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_cfg.h
new file mode 100644
index 0000000..3528dc4
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_cfg.h
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __RUBY_BOARD_CFG_H
+#define __RUBY_BOARD_CFG_H
+
+#include "ruby_platform.h"
+
+#define	SPI1_NOT_IN_USE			(0)
+#define	SPI1_IN_USE			(BIT(0))
+
+/*
+ * There is a copy named qdpc_pcie_board_cfg_t in qdpc_config.h they must be the same.
+ * The copy is used for Host driver Because the Host driver can't cite to here.
+ */
+typedef struct board_cfg {
+	int bc_board_id;
+	char *bc_name;		/* optional name of cfg */
+	int bc_ddr_type;	/* ID */
+	int bc_ddr_speed;	/* speed in MHz */
+	int bc_ddr_size;	/* in bytes */
+	int bc_emac0;		/* in use? */
+	int bc_emac1;		/* in use? */
+	int bc_phy0_addr;	/* address */
+	int bc_phy1_addr;	/* address */
+	int bc_spi1;		/* in use? */
+	int bc_wifi_hw;		/* WiFi hardware type */
+	int bc_uart1;		/* in use? */
+	int bc_pcie;		/* in use? */
+	int bc_rgmii_timing;	/* special timing value for RGMII */
+} board_cfg_t;
+
+#define BOARD_CFG_STRUCT_NUM_FIELDS	(sizeof(struct board_cfg) / sizeof(int))
+
+/* These are index into cfg array */
+#define BOARD_CFG_ID			(0)
+#define BOARD_CFG_NAME			(1)
+#define BOARD_CFG_DDR_TYPE		(2)
+#define BOARD_CFG_DDR_SPEED		(3)
+#define BOARD_CFG_DDR_SIZE		(4)
+#define BOARD_CFG_EMAC0			(5)
+#define BOARD_CFG_EMAC1			(6)
+#define BOARD_CFG_PHY0_ADDR		(7)
+#define BOARD_CFG_PHY1_ADDR		(8)
+#define BOARD_CFG_SPI1			(9)
+#define BOARD_CFG_WIFI_HW		(10)
+#define BOARD_CFG_UART1			(11)
+#define BOARD_CFG_PCIE			(12)
+#define BOARD_CFG_RGMII_TIMING		(13)
+#define BOARD_CFG_EXT_LNA_GAIN		(14)
+#define BOARD_CFG_TX_ANTENNA_NUM	(15)
+#define BOARD_CFG_FLASH_SIZE		(16)
+#define BOARD_CFG_TX_ANTENNA_GAIN	(17)
+#define BOARD_CFG_EXT_LNA_BYPASS_GAIN	(18)
+#define BOARD_CFG_RFIC			(19)
+#define BOARD_CFG_CALSTATE_VPD		(20)
+
+#define BOARD_CFG_FIELD_NAMES	{	\
+	"bc_board_id",			\
+	"bc_name",			\
+	"bc_ddr_type",			\
+	"bc_ddr_speed",			\
+	"bc_ddr_size",			\
+	"bc_emac0",			\
+	"bc_emac1",			\
+	"bc_phy0_addr",			\
+	"bc_phy1_addr",			\
+	"bc_spi1",			\
+	"bc_wifi_hw",			\
+	"bc_uart1",			\
+	"bc_pcie",			\
+	"bc_rgmii_timing",		\
+	"bc_ext_lna_gain",		\
+	"bc_tx_antenna_num",		\
+	"bc_flash_cfg",			\
+	"bc_tx_antenna_gain",		\
+	"bc_ext_lna_bypass_gain",	\
+	"bc_rfic",			\
+	"bc_tx_power_cal",		\
+}
+
+#define RUBY_BDA_VERSION		0x1000
+#define RUBY_BDA_NAMELEN		32
+#define QTN_MAX_BOOTLINE                (256)
+
+/*
+ * quantenna board configuration information,
+ * shared between u-boot and linux kernel.
+ */
+typedef struct qtn_board_cfg_info {
+	uint16_t	bda_len;			/* Size of BDA block */
+	uint16_t	bda_version;			/* BDA version */
+	uint8_t		rsvd[36];
+	board_cfg_t	bda_boardcfg;
+	uint32_t	bda_flashsz;
+	char		bda_boardname[RUBY_BDA_NAMELEN];
+	char            bda_bootline[QTN_MAX_BOOTLINE];
+} __attribute__ ((packed)) ruby_bda_t;
+
+#endif /* __RUBY_BOARD_CFG_H */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_db.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_db.h
new file mode 100644
index 0000000..9999df1
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_board_db.h
@@ -0,0 +1,1184 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _RUBY_BOARD_DB_
+#define _RUBY_BOARD_DB_
+
+#include "ruby_platform.h"
+
+#ifdef UBOOT_BOARD_AUTOCONFIG
+/*
+ * UBoot dynamic board config
+ * Placed here to allow for simplified maintenence
+ */
+struct ruby_cfgstr_map {
+	const char *name;
+	const int val;
+};
+#define CFGSTR(x)	{ #x, (x) }
+
+struct ruby_board_param {
+	const struct ruby_cfgstr_map * const p_map;
+	const uint32_t p_index;
+};
+
+const struct ruby_cfgstr_map g_cfgstr_board_id_cfg[] = {
+	{ "UNIVERSAL_ID", QTN_RUBY_UNIVERSAL_BOARD_ID },
+	{ 0 , 0 }
+};
+
+/* Board name */
+static const struct ruby_cfgstr_map g_cfgstr_name_cfg[] = {
+	{ "hw_QTN_test", 0 },
+	{ 0 , 0 }
+};
+
+/* DDR Configuration strings */
+/* DDR Type */
+static const struct ruby_cfgstr_map g_cfgstr_ddr_cfg[] = {
+	CFGSTR(DDR_16_ETRON),
+	CFGSTR(DDR_32_MICRON),
+	CFGSTR(DDR_16_MICRON),
+	CFGSTR(DDR_32_ETRON),
+	CFGSTR(DDR_32_SAMSUNG),
+	CFGSTR(DDR_16_SAMSUNG),
+	CFGSTR(DDR_16_HYNIX),
+	CFGSTR(DDR3_16_WINBOND),
+	CFGSTR(DDR3_32_WINBOND),
+	CFGSTR(DEFAULT_DDR_CFG),
+	{ 0 , 0 }
+};
+
+/* DDR Size */
+static const struct ruby_cfgstr_map g_cfgstr_ddr_size[] = {
+	CFGSTR(DDR_32MB),
+	CFGSTR(DDR_64MB),
+	CFGSTR(DDR_128MB),
+	CFGSTR(DDR_256MB),
+	CFGSTR(DDR_AUTO),
+	CFGSTR(DEFAULT_DDR_SIZE),
+	{ 0 , 0 }
+};
+
+/* DDR Speed */
+static const struct ruby_cfgstr_map g_cfgstr_ddr_speed[] = {
+	CFGSTR(DDR_160),
+	CFGSTR(DDR_250),
+	CFGSTR(DDR_320),
+	CFGSTR(DDR_400),
+	CFGSTR(DDR3_320MHz),
+	CFGSTR(DDR3_400MHz),
+	CFGSTR(DDR3_500MHz),
+	CFGSTR(DDR3_640MHz),
+	CFGSTR(DDR3_800MHz),
+	CFGSTR(DEFAULT_DDR_SPEED),
+	{ 0 , 0 }
+};
+
+/* EMAC configuration strings */
+static const struct ruby_cfgstr_map g_cfgstr_emac_cfg[] = {
+	{ "EMAC_IN_USE", EMAC_IN_USE },
+	{ "EMAC_RGMII_AN", EMAC_IN_USE },
+	{ "EMAC_NOT_IN_USE", EMAC_NOT_IN_USE },
+	{ "EMAC_MII_AN", (EMAC_IN_USE | EMAC_PHY_MII) },
+	{ "EMAC_MII_100M", (EMAC_IN_USE | EMAC_PHY_NOT_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB) },
+	{ "EMAC_MII_100M_PHY", (EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB) },
+	{ "EMAC_AR8327_RGMII", (EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8327) },
+	{ "EMAC_RTL8363S_RGMII", (EMAC_IN_USE |  EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE) },
+	{ "EMAC_RTL8363SB_RGMII_P0", (EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_RTL8363SB_P0) },
+	{ "EMAC_RTL8363SB_RGMII_P1", (EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_RTL8363SB_P1) },
+	{ "EMAC_RTL8363SB_RGMII_BONDED", (EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE |
+			EMAC_PHY_RTL8363SB_P0 | EMAC_PHY_RTL8363SB_P1 | EMAC_BONDED) },
+	{ "EMAC_RTL8211E_RGMII", (EMAC_IN_USE |  EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE) },
+	{ "EMAC_88E6071_MII", (EMAC_MV88E6071) },
+	{ "EMAC_B2B_RGMII", (EMAC_IN_USE |  EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE) },
+	{ "EMAC_B2B_RGMII_100M", (EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE) },
+	{ "EMAC_B2B_RGMII_1000M", (EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE) },
+	{ "EMAC_AR8236_MII", (EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8236) },
+	{ "EMAC_MII_GPIO1_RST", (EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_GPIO1_RESET) },
+	{ "EMAC_MII_100M_GPIO13_RST", (EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_GPIO13_RESET | EMAC_PHY_FORCE_100MB) },
+	{ "DEFAULT_EMAC", (EMAC_NOT_IN_USE) },
+	{ 0 , 0 }
+};
+
+
+static const struct ruby_cfgstr_map g_cfgstr_emac_phyaddr[] = {
+	CFGSTR(24),
+	CFGSTR(31),
+	CFGSTR(EMAC_PHY_ADDR_SCAN),
+	{ "EMAC_PHY0_ADDR", 1 },
+	{ "EMAC_PHY1_ADDR", 3 },
+	{ "DEFAULT_PHY_ADDR", EMAC_PHY_ADDR_SCAN },
+	{ 0 , 0 }
+};
+
+/* Wireless PHY */
+static const struct ruby_cfgstr_map g_cfgstr_rfpa_cfg[] = {
+	CFGSTR(QTN_RUBY_BRINGUP_RWPA),
+	CFGSTR(QTN_RUBY_REF_RWPA),
+	CFGSTR(QTN_RUBY_SIGE),
+	CFGSTR(QTN_RUBY_WIFI_NONE),
+	CFGSTR(QTN_TPZ_SE5003L1),
+	CFGSTR(QTN_TPZ_SE5003L1_INV),
+	CFGSTR(QTN_TPZ_SKY85703),
+	CFGSTR(QTN_TPZ_DBS),
+	CFGSTR(QTN_TPZ_SKY85405_BPF840),
+	CFGSTR(QTN_TPZ_DBS),
+	CFGSTR(QTN_TPZ_SE5502L),
+	CFGSTR(QTN_TPZ_SKY85710_NG),
+	CFGSTR(QTN_TPZ_DBS_5591),
+	CFGSTR(QTN_TPZ_DBS_5591),
+	CFGSTR(QTN_TPZ_DBS_NXP_BGU7224_BGU7258),
+	CFGSTR(QTN_TPZ_2_4GHZ_NXP_BGU7224),
+	CFGSTR(QTN_TPZ_5GHZ_NXP_BGU7258),
+	CFGSTR(QTN_TPZ_5GHZ_SKY85728),
+	CFGSTR(QTN_TPZ_DBS_SKY85806_SKY85811),
+	{ "DEFAULT_WIFI_HW", QTN_RUBY_REF_RWPA },
+	{ 0 , 0 }
+};
+
+/* SPI config */
+static const struct ruby_cfgstr_map g_cfgstr_spi_cfg[] = {
+	CFGSTR(SPI1_IN_USE),
+	CFGSTR(SPI1_NOT_IN_USE),
+	{ 0 , 0 }
+};
+
+/* UART Config */
+static const struct ruby_cfgstr_map g_cfgstr_uart_cfg[] = {
+	CFGSTR(UART1_NOT_IN_USE),
+	CFGSTR(UART1_IN_USE),
+	{ "DEFAULT_UART1", UART1_NOT_IN_USE },
+	{ 0 , 0 }
+};
+
+/* RGMII Timing Config */
+static const struct ruby_cfgstr_map g_cfgstr_rgmii_cfg[] = {
+	{ "RGMII_DEFAULT_S2p7ns_H1p1ns", CONFIG_ARCH_RGMII_DEFAULT },
+	{ "RGMII_S2p4ns_H1p4ns", CONFIG_ARCH_RGMII_DLL_TIMING },
+	{ "RGMII_S1p8ns_H1p9ns", CONFIG_ARCH_RGMII_S1P8NS_H1P9NS },
+	{ "RGMII_P1RX00TX0E", CONFIG_ARCH_RGMII_P1RX00TX0E },
+	{ "RGMII_710F", CONFIG_ARCH_RGMII_710F },
+	{ "RGMII_NODELAY", CONFIG_ARCH_RGMII_NODELAY },
+	{ "DEFAULT_RGMII_TIMING", CONFIG_ARCH_RGMII_DEFAULT },
+	{ 0 , 0 }
+};
+
+
+/* PCIE Config */
+static const struct ruby_cfgstr_map g_cfgstr_pcie_cfg[] = {
+	CFGSTR(PCIE_NOT_IN_USE),
+	CFGSTR(PCIE_ENDPOINT),
+	CFGSTR(PCIE_ROOTCOMPLEX),
+	{ 0 , 0 }
+};
+
+/* Flash config */
+static const struct ruby_cfgstr_map g_cfgstr_flash_cfg[] = {
+	CFGSTR(FLASH_SIZE_JEDEC),
+	CFGSTR(FLASH_32MB),
+	CFGSTR(FLASH_16MB),
+	CFGSTR(FLASH_8MB),
+	CFGSTR(FLASH_4MB),
+	CFGSTR(FLASH_2MB),
+	CFGSTR(DEFAULT_FLASH_SIZE),
+	{ 0 , 0 }
+};
+
+static const struct ruby_cfgstr_map g_cfgstr_tx_antenna_num[] = {
+	{ "TX_ANTENNA_NUM_1", 1 },
+	{ "TX_ANTENNA_NUM_2", 2 },
+	{ "TX_ANTENNA_NUM_3", 3 },
+	{ "TX_ANTENNA_NUM_4", 4 },
+	{ "DEFAULT_TX_ANTENNA_NUM", 4 },
+	{ 0 , 0 }
+};
+
+#define TX_ANTENNA_GAIN_1_1dB	4506
+static const struct ruby_cfgstr_map g_cfgstr_tx_antenna_gain[] = {
+	CFGSTR(TX_ANTENNA_GAIN_1_1dB),
+	{ "DEFAULT_TX_ANTENNA_GAIN", TX_ANTENNA_GAIN_1_1dB },
+	{ 0 , 0 }
+};
+
+#define LNA_gain_12dB		12
+static const struct ruby_cfgstr_map g_cfgstr_ext_lna_gain[] = {
+	CFGSTR(LNA_gain_12dB),
+	{ "DEFAULT_EXT_LNA_GAIN", LNA_gain_12dB },
+	{ 0 , 0 }
+};
+
+#define LNA_gain_BYPASS_N5dB	-5
+static const struct ruby_cfgstr_map g_cfgstr_ext_lna_bypass_gain[] = {
+	CFGSTR(LNA_gain_BYPASS_N5dB),
+	{ "DEFAULT_EXT_LNA_BYPASS_GAIN", LNA_gain_BYPASS_N5dB },
+	{ 0 , 0 }
+};
+
+#define RFIC_NOT_IN_USE		0
+#define RFIC_V4_IN_USE		4
+#define RFIC_V6_IN_USE		6
+static const struct ruby_cfgstr_map g_cfgstr_rfic[] = {
+	CFGSTR(RFIC_NOT_IN_USE),
+	CFGSTR(RFIC_V4_IN_USE),
+	CFGSTR(RFIC_V6_IN_USE),
+	{ "DEFAULT_RFIC", RFIC_V4_IN_USE },
+	{ 0 , 0 }
+};
+
+#define CALSTATE_VPD_LOG	0
+#define CALSTATE_VPD_LINEAR	1
+static const struct ruby_cfgstr_map g_cfgstr_txpow_cal[] = {
+	CFGSTR(CALSTATE_VPD_LOG),
+	CFGSTR(CALSTATE_VPD_LINEAR),
+	{ "DEFAULT_CALSTATE_VPD", CALSTATE_VPD_LOG },
+	{ 0 , 0 }
+};
+
+static const struct ruby_board_param g_custom_board_params[] = {
+	{ g_cfgstr_board_id_cfg, BOARD_CFG_ID },
+	{ g_cfgstr_name_cfg, BOARD_CFG_NAME },
+	{ g_cfgstr_ddr_cfg, BOARD_CFG_DDR_TYPE },
+	{ g_cfgstr_ddr_speed, BOARD_CFG_DDR_SPEED },
+	{ g_cfgstr_ddr_size, BOARD_CFG_DDR_SIZE },
+	{ g_cfgstr_emac_cfg, BOARD_CFG_EMAC0 },
+	{ g_cfgstr_emac_cfg, BOARD_CFG_EMAC1 },
+	{ g_cfgstr_emac_phyaddr, BOARD_CFG_PHY0_ADDR },
+	{ g_cfgstr_emac_phyaddr, BOARD_CFG_PHY1_ADDR },
+	{ g_cfgstr_rfpa_cfg, BOARD_CFG_WIFI_HW },
+	{ g_cfgstr_spi_cfg, BOARD_CFG_SPI1 },
+	{ g_cfgstr_uart_cfg, BOARD_CFG_UART1 },
+	{ g_cfgstr_rgmii_cfg, BOARD_CFG_RGMII_TIMING },
+	{ g_cfgstr_pcie_cfg, BOARD_CFG_PCIE },
+	{ g_cfgstr_flash_cfg, BOARD_CFG_FLASH_SIZE },
+	{ g_cfgstr_tx_antenna_num, BOARD_CFG_TX_ANTENNA_NUM },
+	{ g_cfgstr_tx_antenna_gain, BOARD_CFG_TX_ANTENNA_GAIN },
+	{ g_cfgstr_ext_lna_gain, BOARD_CFG_EXT_LNA_GAIN },
+	{ g_cfgstr_ext_lna_bypass_gain, BOARD_CFG_EXT_LNA_BYPASS_GAIN },
+	{ g_cfgstr_rfic, BOARD_CFG_RFIC },
+	{ g_cfgstr_txpow_cal, BOARD_CFG_CALSTATE_VPD },
+	{0, 0 }
+};
+
+static board_cfg_t g_custom_board_cfg = {
+	.bc_board_id	= QTN_RUBY_AUTOCONFIG_ID,
+	.bc_name	= "Autoconfigured board",
+	.bc_ddr_type	= DEFAULT_DDR_CFG,
+	.bc_ddr_speed	= DEFAULT_DDR_SPEED,
+	.bc_ddr_size	= DDR_AUTO,
+	.bc_emac0	= EMAC_NOT_IN_USE,
+	.bc_emac1	= EMAC_NOT_IN_USE,
+	.bc_spi1	= SPI1_NOT_IN_USE,
+	.bc_wifi_hw	= QTN_RUBY_WIFI_NONE,
+	.bc_uart1	= UART1_NOT_IN_USE,
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,
+};
+
+#endif
+
+
+#define QTN_BOARD_DB					{		\
+	{ /* 0 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD,			\
+	.bc_name	= "micron32-160, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_32_320,		\
+	.bc_name	= "micron32-250, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 2 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_16_320,		\
+	.bc_name	= "micron16-250, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 3 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_16_160,		\
+	.bc_name	= "micron16-160, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 4 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON,			\
+	.bc_name	= "etron16-250, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 5 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON_320,		\
+	.bc_name	= "etron16-320, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 6 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON_160,		\
+	.bc_name	= "etron16-160, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 7 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_16_200,		\
+	.bc_name	= "micron16-200, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_200,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 8 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_32_200,		\
+	.bc_name	= "micron32-200, emac0-24, pa0",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_200,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 9 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_PCIE,			\
+	.bc_name	= "etron16-160, pcie, pa2, phy loopbk",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_USE_PHY_LOOPBK,		\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{								\
+	/* test arbitration settings */					\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_32_160_ARB,		\
+	.bc_name	= "micron32-160, emac0-24, pa0, arb",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{								\
+	/* test emac1 */						\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_32_160_ARB_1,		\
+	.bc_name	= "micron32-160, emac1-31, pa0, arb",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_phy1_addr	= 31,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{	/* 12 - arb, 16bit emac1 */				\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_16_160_ARB_1,		\
+	.bc_name	= "micron16-160, emac1-31, pa0, arb",		\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= 31,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{	/* 13 - arb, 16bit emac1 */				\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_32_160_ARB_0,		\
+	.bc_name	= "micron16-160, emac0-24, pa0, arb",		\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{	/* 14 */						\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON_160_EMAC1,	\
+	.bc_name	= "etron16-160, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 15 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON_250_EMAC1,	\
+	.bc_name	= "etron16-250, emac1-31, pa0",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_phy1_addr	= 31,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 16 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_ETRON_32_320_EMAC1,	\
+	.bc_name	= "etron32-320, emac1-31, pa0",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_phy1_addr	= 31,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 17 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_ETRON32_160,			\
+	.bc_name	= "etron32-160, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_USE_PHY_LOOPBK,		\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 18 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_ETRON32_320,			\
+	.bc_name	= "etron32-250, emac0-24, pa0",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_USE_PHY_LOOPBK,		\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 19 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC,	\
+	.bc_name	= "micron32-160, emac0, emac1, pa0",		\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 20 */							\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC_MII,	\
+	.bc_name	= "micron32-160, emac0-mii-100, emac1-mii-100, pa0",	\
+	.bc_ddr_type	= DDR_32_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,			\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{								\
+	/* 21 Bringup board with dual EMAC loopback */			\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_MICRON_DUALEMAC_LOOPBACK,		\
+	.bc_name	= "micron16-160, pcie, emac0, emac1, pa0, phy loopback",	\
+	.bc_ddr_type	= DDR_16_MICRON,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,				\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_phy1_addr	= 31,						\
+	.bc_phy0_addr	= 24,						\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_BRINGUP_RWPA,		\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_USE_PHY_LOOPBK,\
+	 },{	/* 22 */												\
+	.bc_board_id	= QTN_RUBY_BRINGUP_BOARD_16_160_DUALEMAC,	\
+	.bc_name        = "etron16-160, emac1,emac0, pa0",			\
+	.bc_ddr_type    = DDR_16_ETRON,								\
+	.bc_ddr_speed   = DDR_160,									\
+	.bc_ddr_size    = DDR_64MB,									\
+	.bc_emac0       = EMAC_IN_USE,								\
+	.bc_emac1       = EMAC_IN_USE,								\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,						\
+	.bc_phy1_addr   = EMAC_PHY_ADDR_SCAN,						\
+	.bc_spi1        = SPI1_IN_USE,								\
+	.bc_wifi_hw     = QTN_RUBY_BRINGUP_RWPA,					\
+	.bc_uart1       = UART1_IN_USE,								\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,				\
+	 },{ /* 1000 */							\
+	.bc_board_id	= QTN_RUBY_REFERENCE_DESIGN_BOARD,		\
+	.bc_name	= "etron16-160, emac1, pa1",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1001 */							\
+	.bc_board_id	= QTN_RUBY_REFERENCE_DESIGN_BOARD_250,		\
+	.bc_name	= "etron16-250, emac1, pa1",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1002 */							\
+	.bc_board_id	= QTN_RUBY_REF_BOARD_DUAL_CON,			\
+	.bc_name	= "etron32-160, emac1, pa1",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_pcie	= PCIE_IN_USE,					\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1003 */							\
+	.bc_board_id	= QTN_RUBY_REFERENCE_DESIGN_BOARD_320,		\
+	.bc_name	= "etron16-320, emac1, pa1",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1004 */							\
+	.bc_board_id	= QTN_RUBY_ETRON_32_320_EMAC1,			\
+	.bc_name	= "etron32-320, emac1, pa1",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1005 */							\
+	.bc_board_id	= QTN_RUBY_ETRON_32_250_EMAC1,			\
+	.bc_name	= "etron32-250, emac1, pa1",			\
+	.bc_ddr_type	= DDR_32_ETRON,					\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1006 */							\
+	.bc_board_id	= QTN_RUBY_REFERENCE_DESIGN_BOARD_RGMII_DLL,	\
+	.bc_name	= "etron16-160, emac1-rgmii-dll, pa2",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DLL_TIMING,		\
+	 },{ /* 1007 */							\
+	.bc_board_id	= QTN_RUBY_QHS710_5S5_SIGE_DDR250,		\
+	.bc_name	= "etron16-250, emac1, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_250,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1008 */							\
+	.bc_board_id	= QTN_RUBY_QHS710_5S5_SIGE_DDR320,		\
+	.bc_name	= "etron16-320, emac1, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1009 */							\
+	.bc_board_id	= QTN_RUBY_OHS711_PCIE_320DDR,			\
+	.bc_name	= "etron16-320, pcie, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1170 */							\
+	.bc_board_id	= QTN_RUBY_QHS713_5S1_PCIERC_DDR160,		\
+	.bc_name	= "etron16-160, emac1, pcie-rc, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_RC_MODE,			\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1171 */							\
+	.bc_board_id	= QTN_RUBY_OHS711_5S13_PCIE_DDR320,		\
+	.bc_name	= "etron16-320, pcie-ep, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1172 */							\
+	.bc_board_id	= QTN_RUBY_QHS713_5S1_PCIERC_DDR320,		\
+	.bc_name	= "etron16-320, emac1, pcie-rc, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_320,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_RC_MODE,			\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1200 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_0,				\
+	.bc_name	= "etron16-160, emac1-mii, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_MII,			\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1201 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_1,				\
+	.bc_name	= "etron16-160, emac0-mii, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_MII,			\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1202 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_2,				\
+	.bc_name	= "etron16-160, emac1 88e6071-mii, pa1",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_MV88E6071,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1203 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_3,				\
+	.bc_name	= "etron16-160, emac1 ar8236-mii, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8236,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1204 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_4,				\
+	.bc_name	= "etron16-160, pcie, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1205 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_5,				\
+	.bc_name	= "etron16-160, emac1, mii-100, pa1",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_NOT_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1206 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_6,				\
+	.bc_name	= "etron16-160, emac1, mii-100, pa2",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_NOT_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1207 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_7,				\
+	.bc_name	= "etron16-160, emac1, pa2",			\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE,					\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1208 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_8,				\
+	.bc_name	= "etron16-160, emac1 ar8327-rgmii, pa1",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8327,     \
+	.bc_phy1_addr   = EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_REF_RWPA,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1209*/							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_9,				\
+	.bc_name	= "etron16-160, emac1 rtl8363s-rgmii , pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE |  EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1210*/							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_10,			\
+	.bc_name	= "etron16-160, emac1 back-to-back-rgmii, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE |  EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1211 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_11,			\
+	.bc_name	= "etron16-160, emac0-mii, pa2",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_MII,			\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1212 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_12,			\
+	.bc_name	= "etron16-160, emac1 88e6071-mii, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_MV88E6071,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1213 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_13,			\
+	.bc_name	= "etron16-160, emac0, emac1 b2b-rgmii 100M, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1214 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_14,			\
+	.bc_name	= "etron16-160, emac0-mii-gpio1rst, emac1-mii-gpio13rst-100M, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_GPIO1_RESET,		\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_GPIO13_RESET | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy0_addr	= 1,				\
+	.bc_phy1_addr	= 2,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1215 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_15,			\
+	.bc_name	= "etron16-160, emac0, emac1 b2b-rgmii 1000M, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_710F,			\
+	 },{ /* 1216 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_16,			\
+	.bc_name	= "etron16-160, emac1 b2b-rgmii 100M, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1217 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_17,			\
+	.bc_name	= "etron16-160, emac1 b2b-rgmii 1000M, pa2",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_710F,			\
+	 },{ /* 1218 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_18,			\
+	.bc_name	= "etron16-160, emac1-mii, pa2",		\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_NOT_IN_USE,				\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1219 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_19,			\
+	.bc_name	= "samsung16-160, emac1, mii-100, pa2",		\
+	.bc_ddr_type	= DDR_16_SAMSUNG,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_NOT_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	 },{ /* 1220 */							\
+	.bc_board_id	= QTN_RUBY_ODM_BOARD_20,			\
+	.bc_name	= "etron16-160, emac0, emac1 b2b-rgmii 1000M, no wifi",	\
+	.bc_ddr_type	= DDR_16_ETRON,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE,	\
+	.bc_phy0_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_phy1_addr	= EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw	= QTN_RUBY_WIFI_NONE,				\
+	.bc_uart1	= UART1_NOT_IN_USE,				\
+	.bc_pcie	= PCIE_IN_USE | PCIE_RC_MODE,			\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1221 */							\
+	.bc_board_id = QTN_RUBY_ODM_BOARD_21,				\
+	.bc_name = "etron16-160, emac1 ar8236-mii, pa2",		\
+	.bc_ddr_type = DDR_16_ETRON,					\
+	.bc_ddr_speed = DDR_160,					\
+	.bc_ddr_size = DDR_64MB,					\
+	.bc_emac1 = EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8236,                                          \
+	.bc_phy1_addr = EMAC_PHY_ADDR_SCAN,				\
+	.bc_wifi_hw = QTN_RUBY_SIGE,                                    \
+	.bc_uart1 = UART1_NOT_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1222 */							\
+	.bc_board_id    = QTN_RUBY_ODM_BOARD_22,                        \
+	.bc_name        = "etron16-160, emac1 ar8327-rgmii, pa2",       \
+	.bc_ddr_type    = DDR_16_ETRON,                                 \
+	.bc_ddr_speed   = DDR_160,                                      \
+	.bc_ddr_size    = DDR_64MB,                                     \
+	.bc_emac1       = EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_AR8327, \
+	.bc_phy1_addr   = EMAC_PHY_ADDR_SCAN,                           \
+	.bc_wifi_hw     = QTN_RUBY_SIGE,                                \
+	.bc_uart1       = UART1_NOT_IN_USE,                             \
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,                   \
+	 },{ /* 1223 */							\
+	.bc_board_id	= QTN_TOPAZ_FPGAA_BOARD,		\
+	.bc_name	= "FPGA-A(hw_config_id:1223) DDR3, EMAC1, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,					\
+	.bc_ddr_speed	= DDR3_320MHz,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE, \
+	.bc_emac1	= EMAC_NOT_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE, \
+	.bc_phy0_addr	= TOPAZ_FPGAA_PHY0_ADDR,			\
+	.bc_phy1_addr	= TOPAZ_FPGAA_PHY1_ADDR,			\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1224 */							\
+	.bc_board_id	= QTN_TOPAZ_FPGAB_BOARD,		\
+	.bc_name	= "FPGA-B(hw_config_id:1224) DDR3, EMAC0, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,					\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB, \
+	.bc_emac1	= EMAC_NOT_IN_USE | EMAC_PHY_FORCE_100MB,	\
+	.bc_phy0_addr	= TOPAZ_FPGAB_PHY0_ADDR,			\
+	.bc_phy1_addr	= TOPAZ_FPGAB_PHY1_ADDR,			\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1225 */							\
+	.bc_board_id	= QTN_TOPAZ_DUAL_EMAC_FPGAA_BOARD,		\
+	.bc_name	= "FPGA-A(hw_config_id:1225) DDR3, EMAC0, EMAC1, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,				\
+	.bc_ddr_speed	= DDR3_320MHz,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_FPGAA_ONLY, \
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_FPGAA_ONLY, \
+	.bc_phy0_addr	= TOPAZ_FPGAA_PHY0_ADDR,			\
+	.bc_phy1_addr	= TOPAZ_FPGAA_PHY1_ADDR,			\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1226 */							\
+	.bc_board_id	= QTN_TOPAZ_DUAL_EMAC_FPGAB_BOARD,		\
+	.bc_name	= "FPGA-B(hw_config_id:1226) DDR3, EMAC0, EMAC1, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,				\
+	.bc_ddr_speed	= DDR3_320MHz,					\
+	.bc_ddr_size	= DDR_64MB,					\
+	.bc_emac0	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_FPGAB_ONLY, \
+	.bc_emac1	= EMAC_IN_USE | EMAC_PHY_FORCE_100MB | EMAC_PHY_FPGAB_ONLY, \
+	.bc_phy0_addr	= TOPAZ_FPGAB_PHY0_ADDR,			\
+	.bc_phy1_addr	= TOPAZ_FPGAB_PHY1_ADDR,			\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1227 */							\
+	.bc_board_id	= QTN_TOPAZ_RC_BOARD,				\
+	.bc_name	= "FPGA-A(hw_config_id:1227) DDR3, EMAC1, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,				\
+	.bc_ddr_speed	= DDR3_320MHz,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= TOPAZ_PHY0_ADDR,				\
+	.bc_phy1_addr	= TOPAZ_PHY1_ADDR,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_WIFI_NONE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_pcie        = PCIE_IN_USE | PCIE_RC_MODE,			\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	 },{ /* 1228 */							\
+	.bc_board_id	= QTN_TOPAZ_EP_BOARD,				\
+	.bc_name	= "FPGA-B(hw_config_id:1228) DDR3, EMAC0, WMAC, RGMII-1G", \
+	.bc_ddr_type	= DDR3_16_WINBOND,				\
+	.bc_ddr_speed	= DDR_160,					\
+	.bc_ddr_size	= DDR_128MB,					\
+	.bc_emac0	= EMAC_IN_USE,					\
+	.bc_emac1	= EMAC_NOT_IN_USE,				\
+	.bc_phy0_addr	= TOPAZ_PHY0_ADDR,				\
+	.bc_phy1_addr	= TOPAZ_PHY1_ADDR,				\
+	.bc_spi1	= SPI1_IN_USE,					\
+	.bc_wifi_hw	= QTN_RUBY_SIGE,				\
+	.bc_uart1	= UART1_IN_USE,					\
+	.bc_pcie	= PCIE_IN_USE,					\
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,			\
+	} ,{ /* 1229 */							\
+	.bc_board_id    = QTN_TOPAZ_BB_BOARD, \
+	.bc_name        = "BB-EVK(hw_config_id:1229) DDR3, EMAC0, WMAC, RGMII-1G", \
+	.bc_ddr_type    = DDR3_16_WINBOND, \
+	.bc_ddr_speed   = DDR3_400MHz, \
+	.bc_ddr_size    = DDR_128MB, \
+	.bc_emac0       = EMAC_IN_USE, \
+	.bc_emac1       = EMAC_IN_USE, \
+	.bc_phy0_addr   = TOPAZ_PHY0_ADDR, \
+	.bc_phy1_addr   = TOPAZ_PHY1_ADDR, \
+	.bc_spi1        = SPI1_IN_USE, \
+	.bc_wifi_hw     = QTN_RUBY_WIFI_NONE, \
+	.bc_uart1       = UART1_IN_USE, \
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_NODELAY, \
+	} ,{ /* 1230 */ \
+	.bc_board_id    = QTN_TOPAZ_RF_BOARD, \
+	.bc_name        = "RF-EVK(hw_config_id:1230) DDR3, EMAC0, WMAC, RGMII-1G", \
+	.bc_ddr_type    = DDR3_16_WINBOND, \
+	.bc_ddr_speed   = DDR3_500MHz, \
+	.bc_ddr_size    = DDR_128MB, \
+	.bc_emac0       = EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE, \
+	.bc_emac1       = EMAC_IN_USE, \
+	.bc_phy0_addr   = TOPAZ_PHY0_ADDR, \
+	.bc_phy1_addr   = TOPAZ_PHY1_ADDR, \
+	.bc_spi1        = SPI1_IN_USE, \
+	.bc_wifi_hw     = QTN_TPZ_SE5003L1_INV, \
+	.bc_uart1       = UART1_IN_USE, \
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_NODELAY, \
+	} ,{ /* 1231 */ \
+	.bc_board_id    = QTN_TOPAZ_QHS840_5S1, \
+	.bc_name        = "QHS840_5S1 RDK", \
+	.bc_ddr_type    = DDR3_16_WINBOND, \
+	.bc_ddr_speed   = DDR3_500MHz, \
+	.bc_ddr_size    = DDR_128MB, \
+	.bc_emac0       = EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE | EMAC_PHY_RTL8363SB_P0, \
+	.bc_wifi_hw     = QTN_TPZ_SE5003L1, \
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_NODELAY, \
+	} ,{ /* 2008 */ \
+	.bc_board_id    = QTN_TOPAZ_RGMII_RFIC6, \
+	.bc_name        = "TOPAZ RGMII RFIC6", \
+	.bc_ddr_type    = DDR_NO_INIT, \
+	.bc_ddr_speed   = DEFAULT_DDR_SPEED, \
+	.bc_ddr_size    = DDR_128MB, \
+	.bc_emac0       = EMAC_IN_USE | EMAC_PHY_FORCE_1000MB | EMAC_PHY_NOT_IN_USE, \
+	.bc_emac1       = EMAC_NOT_IN_USE, \
+	.bc_phy0_addr   = TOPAZ_PHY0_ADDR, \
+	.bc_phy1_addr   = TOPAZ_PHY1_ADDR, \
+	.bc_spi1        = SPI1_IN_USE, \
+	.bc_wifi_hw     = QTN_TPZ_DBS_SKY85806_SKY85811, \
+	.bc_uart1       = UART1_IN_USE, \
+	.bc_rgmii_timing = CONFIG_ARCH_RGMII_DEFAULT,		\
+	}\
+}
+
+#endif /* _RUBY_BOARD_DB_ */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_config.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_config.h
new file mode 100644
index 0000000..4caec1b
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_config.h
@@ -0,0 +1,187 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Ruby platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __RUBY_CONFIG_H
+#define __RUBY_CONFIG_H
+
+#include "topaz_config.h"
+
+/*******************************************************************/
+
+#if TOPAZ_MMAP_UNIFIED
+	#define RUBY_MMAP_FLIP		0
+#else
+	#if !(defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD))
+		#define RUBY_MMAP_FLIP		1
+	#else
+		#define RUBY_MMAP_FLIP		0
+	#endif
+#endif
+
+/* Set to 1 if MuC need to enable TLB, otherwise set to 0 */
+#define RUBY_MUC_TLB_ENABLE		1
+
+/*******************************************************************/
+
+#ifdef RUBY_PLATFORM
+
+	#if RUBY_FPGA_PLATFORM
+		#define RUBY_SERIAL_BAUD	38400
+		#define RUBY_FIXED_DEV_CLK	12500000
+		#define RUBY_FIXED_CPU_CLK	40000000
+		#define RUBY_FPGA_DDR
+	#else
+		#define RUBY_SERIAL_BAUD	115200
+		#define RUBY_FIXED_DEV_CLK	125000000
+		#define RUBY_FIXED_CPU_CLK	400000000
+		#define RUBY_ASIC_DDR
+	#endif /* #if RUBY_FPGA_PLATFORM */
+
+	#define UPF_SPD_FLAG	0
+	#define DEFAULT_BAUD	RUBY_SERIAL_BAUD
+
+#endif /* #ifdef RUBY_PLATFORM */
+
+/*******************************************************************/
+/* Define some constants for Linux ARC kernel */
+#define CONFIG_ARC700_SERIAL_BAUD	RUBY_SERIAL_BAUD
+#define CONFIG_ARC700_CLK		RUBY_FIXED_CPU_CLK
+#define CONFIG_ARC700_DEV_CLK		RUBY_FIXED_DEV_CLK
+
+/*******************************************************************/
+
+/* RGMII related defines */
+#define CONFIG_ARCH_RUBY_ENET_RGMII
+
+#define CONFIG_ARCH_RGMII_DEFAULT	0x8F8F8F8F
+#define CONFIG_ARCH_RGMII_DLL_TIMING	0x8F8D8F8F
+#define CONFIG_ARCH_RGMII_S1P8NS_H1P9NS	0x8F891F1F
+#define CONFIG_ARCH_RGMII_NODELAY	0x1F1F1F1F
+#define CONFIG_ARCH_RGMII_710F		CONFIG_ARCH_RGMII_NODELAY
+#define CONFIG_ARCH_RGMII_P1RX00TX0E    0x0E8E1F1F
+
+/* EMAC related defines */
+
+/* EMAC flags */
+#define EMAC_NOT_IN_USE			(0)
+#define EMAC_IN_USE			(BIT(0))
+#define EMAC_PHY_NOT_IN_USE		(BIT(1))  // do not initialize/access phy mdio
+#define EMAC_PHY_FORCE_10MB		(BIT(2))
+#define EMAC_PHY_FORCE_100MB		(BIT(3))
+#define EMAC_PHY_FORCE_1000MB		(BIT(4))
+#define EMAC_PHY_FORCE_HDX		(BIT(5))
+#define EMAC_PHY_RESET			(BIT(6)) // force PHY reset
+#define EMAC_PHY_MII			(BIT(7)) // default is rgmii
+#define EMAC_PHY_AUTO_MASK		(EMAC_PHY_FORCE_10MB | EMAC_PHY_FORCE_100MB | EMAC_PHY_FORCE_1000MB)
+#define EMAC_PHY_AR8236			(BIT(8))
+#define EMAC_PHY_AR8327			(BIT(9))
+#define EMAC_PHY_GPIO1_RESET		(BIT(10))
+#define EMAC_PHY_GPIO13_RESET		(BIT(11))
+#define EMAC_PHY_NO_COC			(BIT(12)) // do not adjust link speed for power savings
+#define EMAC_PHY_MV88E6071		(BIT(13))
+#define EMAC_PHY_FPGAA_ONLY		(BIT(15))
+#define EMAC_PHY_FPGAB_ONLY		(BIT(16))
+#define EMAC_PHY_RTL8363SB_P0		(BIT(18))
+#define EMAC_PHY_RTL8363SB_P1		(BIT(19))
+#define EMAC_BONDED			(BIT(20))
+#define EMAC_PHY_RTL8365MB		(BIT(21))
+#define EMAC_PHY_RTL8211DS		(BIT(22))
+#define EMAC_PHY_RTL8367RB		(BIT(23))
+#define EMAC_PHY_CUSTOM			(BIT(31))
+
+#define EMAC_MV88E6071			(EMAC_IN_USE | EMAC_PHY_MII | EMAC_PHY_NOT_IN_USE |	\
+						EMAC_PHY_NO_COC | EMAC_PHY_FORCE_100MB | EMAC_PHY_MV88E6071)
+#define EMAC_SLOW_PHY			(EMAC_PHY_FORCE_10MB|EMAC_PHY_FORCE_100MB|EMAC_PHY_MII)
+
+/* force phy addr scan */
+#define EMAC_PHY_ADDR_SCAN		(32)	// scan bus for addr
+
+/* Flash memory sizes */
+#define FLASH_64MB			(64*1024*1024)
+#define FLASH_32MB			(32*1024*1024)
+#define FLASH_16MB			(16*1024*1024)
+#define FLASH_8MB			(8*1024*1024)
+#define FLASH_4MB			(4*1024*1024)
+#define FLASH_2MB			(2*1024*1024)
+#define FLASH_256KB			(256*1024)
+#define FLASH_64KB			(64*1024)
+#define DEFAULT_FLASH_SIZE		(FLASH_8MB)
+#define FLASH_SIZE_JEDEC		(0)
+
+/* DDR memory sizes */
+#define DDR_256MB			(256*1024*1024)
+#define DDR_128MB			(128*1024*1024)
+#define DDR_64MB			(64*1024*1024)
+#define DDR_46MB			(46*1024*1024)
+#define DDR_32MB			(32*1024*1024)
+#define DDR_AUTO			(0)
+#define DEFAULT_DDR_SIZE		(DDR_64MB)
+
+/* Other DDR defines */
+#define DDR3_800MHz		800
+#define DDR3_640MHz		640
+#define DDR3_500MHz		500
+#define DDR3_400MHz		400
+#define DDR3_320MHz		320
+#define DDR_400			400
+#define DDR_320			320
+#define DDR_250			250
+#define DDR_200			200
+#define DDR_160			160
+#define DDR_125			125
+#define DEFAULT_DDR_SPEED	(DDR_160)
+
+#define	DDR_32_MICRON		0
+#define DDR_16_MICRON		1
+#define DDR_16_ETRON		2
+#define DDR_16_SAMSUNG		3
+#define DDR_32_ETRON		4
+#define DDR_32_SAMSUNG		5
+#define DDR_16_HYNIX		6
+#define DDR3_16_WINBOND		7
+#define DDR3_32_WINBOND		8
+#define DDR_NO_INIT		9
+#define DEFAULT_DDR_CFG		(DDR_16_MICRON)
+
+/* UART1 defines */
+#define	UART1_NOT_IN_USE	0
+#define	UART1_IN_USE		1
+
+#define PCIE_NOT_IN_USE		0
+#define PCIE_IN_USE		(BIT(0))
+#define PCIE_USE_PHY_LOOPBK	(BIT(1))
+#define PCIE_RC_MODE		(BIT(2))
+#define PCIE_ENDPOINT		(PCIE_IN_USE | PCIE_USE_PHY_LOOPBK)
+#define PCIE_ROOTCOMPLEX	(PCIE_IN_USE | PCIE_RC_MODE | PCIE_USE_PHY_LOOPBK)
+
+/*******************************************************************/
+
+#define CONFIG_USE_SPI1_FOR_IPC	PLATFORM_REG_SWITCH(1, 0)
+
+#endif // #ifndef __RUBY_CONFIG_H
+
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_flip.S b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_flip.S
new file mode 100644
index 0000000..31b57a2
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_flip.S
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <config.h>
+#include <asm/arcregs.h>
+#include <asm/arch/platform.h>
+#include "start.inl"
+
+#if RUBY_MMAP_FLIP || TOPAZ_MMAP_UNIFIED
+
+ruby_flip_mmap:
+	.globl ruby_flip_mmap
+	/* Code must be position-independent! */
+
+	/*
+	* Flush and invalidate data cache.
+	* Please make sure that instructions which touch
+	* d-cache are NOT used until flipping is done.
+	*/
+	/* Set flush mode for invalidate operation */
+	lr      r1, [ARC_REG_DC_CTRL]
+	bset    r1, r1, 0x6
+	sr      r1, [ARC_REG_DC_CTRL]
+	/* Start invalidate operation */
+	mov     r1, 0x1
+	sr      r1, [ARC_REG_DC_IVDC]
+	/* Check while cache invalidating will be finished */
+dcache_flush_continue:
+	lr      r1, [ARC_REG_DC_CTRL]
+	and     r1, r1, ARC_DC_FLUSH_STATUS_BIT
+	brne    r1, 0x0, dcache_flush_continue
+
+	/* Prepare flipping.
+	 * After code is finished, memory maps will change as follows:
+	 *     Flip map:
+	 *         SRAM 0x8000_0000 -> 0x8800_0000
+	 *         DRAM 0x0         -> 0x8000_0000
+	 *     Unified map:
+	 *         SRAM 0x8000_0000 -> 0x9800_0000
+	 *         DRAM 0x0         -> 0x8000_0000
+	 */
+	mov     r1, RUBY_SYS_CTL_BASE_ADDR_NOMAP
+	mov     r2, FLIPBIT | RUBY_SYS_CTL_REMAP(0x3)
+	st.di   r2, [r1, RUBY_SYS_CTL_MASK - RUBY_SYS_CTL_BASE_ADDR]
+	mov     r2, FLIPBIT
+
+.align ARC_ICACHE_LINE_LEN
+	/* Do flipping.
+	* Align to cache line to ensure we don't hit memory during following instructions.
+	* Code must fit into 1 cache line (32 bytes).
+	*/
+	st.di   r2, [r1, RUBY_SYS_CTL_CTRL - RUBY_SYS_CTL_BASE_ADDR]
+	ld.di   r2, [r1, RUBY_SYS_CTL_CTRL - RUBY_SYS_CTL_BASE_ADDR] /* read back to clear pipeline */
+	sync
+	j       boot_continue		/* jump to absolute addr in sram */
+	/* Align to cache line so code occupy strictly 1 cache line. */
+.align ARC_ICACHE_LINE_LEN
+
+boot_continue:
+	/* Finalize flipping. */
+	mov     r2, 0x0
+	st.di   r2, [r1, RUBY_SYS_CTL_MASK - RUBY_SYS_CTL_BASE_ADDR]
+
+	/* Let's discard instruction cache.
+	*/
+	mov     r2, 0x1
+	sr      r2, [ARC_REG_IC_IVIC] /* invalidate i-cache */
+	lr      r2, [ARC_REG_IC_CTRL] /* read will be not completed until i-cache is invalidated */
+
+	/* Done. We are now sitting in different addresses. */
+	b	ruby_boot
+#endif // #if RUBY_MMAP_FLIP
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_mem.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_mem.h
new file mode 100644
index 0000000..b23561d
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_mem.h
@@ -0,0 +1,517 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Ruby platform.
+ * Has to be used by runtime firmware.
+ */
+
+#ifndef __RUBY_MEM_H
+#define __RUBY_MEM_H
+
+#include "common_mem.h"
+
+/* FIXME: Move CPU related macros to a separate header file. */
+#define ARC_DCACHE_LINE_LENGTH			32
+
+/* NEVTBD - put in real XYMEM values */
+#define RUBY_DSP_XYMEM_BEGIN			0xD0000000
+#define RUBY_DSP_XYMEM_END			0xDFFFFFFF
+
+/* SRAM layout */
+
+#ifdef QTN_RC_ENABLE_HDP
+#define TOPAZ_HBM_BUF_EMAC_RX_COUNT_S		(14)
+#define TOPAZ_HBM_BUF_WMAC_RX_COUNT_S		(0)
+#else
+#define TOPAZ_HBM_BUF_EMAC_RX_COUNT_S		(13)
+#define TOPAZ_HBM_BUF_WMAC_RX_COUNT_S		(11)
+#endif
+#define TOPAZ_HBM_EMAC_TX_DONE_COUNT_S		(12)
+
+#define TOPAZ_HBM_BUF_EMAC_RX_COUNT		(1 << TOPAZ_HBM_BUF_EMAC_RX_COUNT_S)
+#define TOPAZ_HBM_BUF_WMAC_RX_COUNT		(1 << TOPAZ_HBM_BUF_WMAC_RX_COUNT_S)
+#define TOPAZ_HBM_EMAC_TX_DONE_COUNT		(1 << TOPAZ_HBM_EMAC_TX_DONE_COUNT_S)
+
+/* dedicated SRAM space for HBM pointer pools */
+#define TOPAZ_HBM_POOL_PTR_SIZE			4	/* sizeof(void *), 32 bit arch */
+#define TOPAZ_HBM_POOL_EMAC_RX_START		0x00000000
+#define TOPAZ_HBM_POOL_EMAC_RX_SIZE		(TOPAZ_HBM_BUF_EMAC_RX_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
+#define TOPAZ_HBM_POOL_EMAC_RX_END		(TOPAZ_HBM_POOL_EMAC_RX_START + TOPAZ_HBM_POOL_EMAC_RX_SIZE)
+#define TOPAZ_HBM_POOL_WMAC_RX_START		TOPAZ_HBM_POOL_EMAC_RX_END
+#define TOPAZ_HBM_POOL_WMAC_RX_SIZE		(TOPAZ_HBM_BUF_WMAC_RX_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
+#define TOPAZ_HBM_POOL_WMAC_RX_END		(TOPAZ_HBM_POOL_WMAC_RX_START + TOPAZ_HBM_POOL_WMAC_RX_SIZE)
+#define TOPAZ_HBM_POOL_EMAC_TX_DONE_START	TOPAZ_HBM_POOL_WMAC_RX_END
+#define TOPAZ_HBM_POOL_EMAC_TX_DONE_SIZE	(TOPAZ_HBM_EMAC_TX_DONE_COUNT * TOPAZ_HBM_POOL_PTR_SIZE)
+#define TOPAZ_HBM_POOL_EMAC_TX_DONE_END		(TOPAZ_HBM_POOL_EMAC_TX_DONE_START + TOPAZ_HBM_POOL_EMAC_TX_DONE_SIZE)
+#define TOPAZ_FWT_SW_START			TOPAZ_HBM_POOL_EMAC_TX_DONE_END
+#define TOPAZ_FWT_SW_SIZE			(4096)
+#define TOPAZ_FWT_SW_END			(TOPAZ_FWT_SW_START + TOPAZ_FWT_SW_SIZE)
+
+#define CONFIG_MUC_EXTRA_RES_BASE		TOPAZ_FWT_SW_END
+#define CONFIG_MUC_EXTRA_RESERVE_SIZE		(8 * 1024)
+#define CONFIG_MUC_EXTRA_RES_END		(CONFIG_MUC_EXTRA_RES_BASE + CONFIG_MUC_EXTRA_RESERVE_SIZE)
+
+#define CONFIG_ARC_KERNEL_SRAM_B1_BASE		ROUNDUP(CONFIG_MUC_EXTRA_RES_END, CONFIG_ARC_KERNEL_PAGE_SIZE)
+#define CONFIG_ARC_KERNEL_SRAM_B1_SIZE		(22 * 1024)
+#define CONFIG_ARC_KERNEL_SRAM_B1_END		(CONFIG_ARC_KERNEL_SRAM_B1_BASE + CONFIG_ARC_KERNEL_SRAM_B1_SIZE)
+#define CONFIG_ARC_KERNEL_SRAM_B2_BASE		CONFIG_ARC_KERNEL_SRAM_B1_END
+#define CONFIG_ARC_KERNEL_SRAM_B2_END		ROUNDUP(CONFIG_ARC_KERNEL_SRAM_B2_BASE, RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_KERNEL_SRAM_B2_SIZE		(CONFIG_ARC_KERNEL_SRAM_B2_END - CONFIG_ARC_KERNEL_SRAM_B2_BASE)
+#define CONFIG_ARC_MUC_SRAM_B1_BASE		ROUNDUP(CONFIG_ARC_KERNEL_SRAM_B2_END, CONFIG_ARC_KERNEL_PAGE_SIZE)
+#define CONFIG_ARC_MUC_SRAM_B1_END		ROUNDUP(CONFIG_ARC_MUC_SRAM_B1_BASE + 1, RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_MUC_SRAM_B1_SIZE		(CONFIG_ARC_MUC_SRAM_B1_END - CONFIG_ARC_MUC_SRAM_B1_BASE)
+#define CONFIG_ARC_MUC_SRAM_B2_BASE		ROUNDUP(CONFIG_ARC_MUC_SRAM_B1_END, RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_MUC_SRAM_B2_SIZE		(RUBY_SRAM_BANK_SAFE_SIZE - RUBY_CRUMBS_SIZE)
+#define CONFIG_ARC_MUC_SRAM_B2_END		(CONFIG_ARC_MUC_SRAM_B2_BASE + CONFIG_ARC_MUC_SRAM_B2_SIZE)
+#define CONFIG_ARC_AUC_SRAM_BASE		ROUNDUP(CONFIG_ARC_MUC_SRAM_B2_END, RUBY_SRAM_BANK_SIZE)
+
+#define CONFIG_ARC_AUC_MU_SRAM_SIZE		(3 * RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_AUC_MU_SRAM_END		(CONFIG_ARC_AUC_SRAM_BASE + CONFIG_ARC_AUC_MU_SRAM_SIZE)
+#define CONFIG_ARC_AUC_NOMU_SRAM_SIZE		(4 * RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_AUC_NOMU_SRAM_END		(CONFIG_ARC_AUC_SRAM_BASE + CONFIG_ARC_AUC_NOMU_SRAM_SIZE)
+
+/* MU TxBF qmatrix is stored at the last bank of SRAM, DSP writes to it, has to use SRAM BUS addr.
+ * WARN: CONFIG_ARC_MU_QMAT_* defines are only valid if MU-enabled AuC FW is running,
+ * since in non-MU AuC FW case MU QMat SRAM bank is used by AuC.
+ */
+#define CONFIG_ARC_MU_QMAT_BASE		(RUBY_SRAM_BUS_BEGIN + 7 * RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_MU_QMAT_SIZE		RUBY_SRAM_BANK_SIZE
+#define CONFIG_ARC_MU_QMAT_END		(CONFIG_ARC_MU_QMAT_BASE + CONFIG_ARC_MU_QMAT_SIZE)
+
+#define CONFIG_ARC_SRAM_END		RUBY_SRAM_SIZE
+
+#if TOPAZ_RX_ACCELERATE
+	/* TODO FIXME - MuC crashed when copying data between SRAM and DDR */
+	#define CONFIG_ARC_MUC_STACK_OFFSET		(CONFIG_ARC_MUC_SRAM_B2_END - 2048)
+#else
+	#define CONFIG_ARC_MUC_STACK_OFFSET		(CONFIG_ARC_MUC_SRAM_B2_END)
+#endif
+
+#if CONFIG_ARC_MUC_STACK_OFFSET_UBOOT != CONFIG_ARC_MUC_STACK_OFFSET
+	#error "CONFIG_ARC_MUC_STACK_OFFSET_UBOOT must be equal to CONFIG_ARC_MUC_STACK_OFFSET!"
+#endif
+
+#define CONFIG_ARC_MUC_STACK_INIT	(RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_STACK_OFFSET)
+
+#define RUBY_CRUMBS_OFFSET		(CONFIG_ARC_MUC_SRAM_B2_END)
+
+#if RUBY_CRUMBS_OFFSET != RUBY_CRUMBS_OFFSET_UBOOT
+	#error "RUBY_CRUMBS_OFFSET_UBOOT must be equal to RUBY_CRUMBS_OFFSET!"
+#endif
+
+#define RUBY_CRUMBS_ADDR		(RUBY_SRAM_BEGIN + RUBY_CRUMBS_OFFSET)
+
+/* DDR layout  */
+#define CONFIG_ARC_PCIE_RSVD_SIZE	(64 * 1024)
+#define CONFIG_ARC_DSP_BASE		(CONFIG_ARC_NULL_END + CONFIG_ARC_PCIE_RSVD_SIZE)
+#define CONFIG_ARC_DSP_SIZE		(768 * 1024)
+#define CONFIG_ARC_DSP_END		(CONFIG_ARC_DSP_BASE + CONFIG_ARC_DSP_SIZE)
+#define CONFIG_ARC_MUC_BASE		CONFIG_ARC_DSP_END
+#ifdef TOPAZ_128_NODE_MODE
+#define CONFIG_ARC_MUC_SIZE		((3 * 1024 * 1024) + (584 * 1024))
+#else
+#define CONFIG_ARC_MUC_SIZE		((2 * 1024 * 1024) + (772 * 1024))
+#endif
+#define MUC_DRAM_RX_RESVERED_RELOC_SIZE		(8 * 1024)
+#define CONFIG_ARC_MUC_END		(CONFIG_ARC_MUC_BASE + CONFIG_ARC_MUC_SIZE)
+#define CONFIG_ARC_MUC_MAPPED_BASE	CONFIG_ARC_MUC_BASE
+#define CONFIG_ARC_MUC_MAPPED_SIZE	(RUBY_MAX_DRAM_SIZE - CONFIG_ARC_MUC_MAPPED_BASE)
+
+#define CONFIG_ARC_AUC_BASE		CONFIG_ARC_MUC_END
+#define CONFIG_ARC_AUC_SIZE		(1024 * 1024 + 768 * 1024 + 40 * 1024)
+#define CONFIG_ARC_AUC_END		(CONFIG_ARC_AUC_BASE + CONFIG_ARC_AUC_SIZE)
+#define TOPAZ_HBM_BUF_ALIGN		(1 * 1024)
+
+#define TOPAZ_HBM_BUF_EMAC_RX_POOL	0
+#define TOPAZ_HBM_BUF_WMAC_RX_POOL	1
+#define TOPAZ_HBM_AUC_FEEDBACK_POOL	2
+#define TOPAZ_HBM_EMAC_TX_DONE_POOL	3
+
+#define TOPAZ_HBM_BUF_EMAC_RX_SIZE	(4 * 1024)
+#define TOPAZ_HBM_BUF_WMAC_RX_SIZE	(17 * 1024)
+
+#define TOPAZ_HBM_BUF_META_SIZE		64		/* keep it 2^n */
+#define TOPAZ_HBM_POOL_GUARD_SIZE	(64 * 1024)
+
+#define TOPAZ_HBM_BUF_EMAC_RX_TOTAL	(TOPAZ_HBM_BUF_EMAC_RX_COUNT *	\
+						TOPAZ_HBM_BUF_EMAC_RX_SIZE)
+#define TOPAZ_HBM_BUF_WMAC_RX_TOTAL	(TOPAZ_HBM_BUF_WMAC_RX_COUNT *	\
+						TOPAZ_HBM_BUF_WMAC_RX_SIZE)
+#define TOPAZ_HBM_BUF_META_BASE		CONFIG_ARC_AUC_END
+
+#define TOPAZ_HBM_BUF_META_EMAC_RX_BASE		(TOPAZ_HBM_BUF_META_BASE + TOPAZ_HBM_BUF_META_SIZE)
+#define TOPAZ_HBM_BUF_META_EMAC_RX_BASE_VIRT	(RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_EMAC_RX_BASE)
+#define TOPAZ_HBM_BUF_META_EMAC_RX_TOTAL	(TOPAZ_HBM_BUF_EMAC_RX_COUNT * \
+							TOPAZ_HBM_BUF_META_SIZE)
+#define TOPAZ_HBM_BUF_META_EMAC_RX_END		(TOPAZ_HBM_BUF_META_EMAC_RX_BASE + \
+							TOPAZ_HBM_BUF_META_EMAC_RX_TOTAL)
+
+#define TOPAZ_HBM_BUF_META_WMAC_RX_BASE		(TOPAZ_HBM_BUF_META_EMAC_RX_END + TOPAZ_HBM_BUF_META_SIZE)
+#define TOPAZ_HBM_BUF_META_WMAC_RX_BASE_VIRT	(RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_WMAC_RX_BASE)
+#define TOPAZ_HBM_BUF_META_WMAC_RX_TOTAL	(TOPAZ_HBM_BUF_WMAC_RX_COUNT * \
+							TOPAZ_HBM_BUF_META_SIZE)
+#define TOPAZ_HBM_BUF_META_WMAC_RX_END		(TOPAZ_HBM_BUF_META_WMAC_RX_BASE + \
+							TOPAZ_HBM_BUF_META_WMAC_RX_TOTAL)
+
+#define TOPAZ_HBM_BUF_META_END		(TOPAZ_HBM_BUF_META_WMAC_RX_END + TOPAZ_HBM_BUF_META_SIZE)
+#define TOPAZ_HBM_BUF_META_TOTAL	(TOPAZ_HBM_BUF_META_END - TOPAZ_HBM_BUF_META_BASE)
+
+#define TOPAZ_HBM_BUF_BASE		ROUNDUP(TOPAZ_HBM_BUF_META_END, TOPAZ_HBM_BUF_ALIGN)
+
+#define TOPAZ_HBM_BUF_EMAC_RX_BASE	(TOPAZ_HBM_BUF_BASE + TOPAZ_HBM_POOL_GUARD_SIZE)
+#define TOPAZ_HBM_BUF_EMAC_RX_BASE_VIRT	(RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_EMAC_RX_BASE)
+#define TOPAZ_HBM_BUF_EMAC_RX_END	(TOPAZ_HBM_BUF_EMAC_RX_BASE +	\
+						TOPAZ_HBM_BUF_EMAC_RX_TOTAL)
+
+#define TOPAZ_HBM_BUF_WMAC_RX_BASE	(TOPAZ_HBM_BUF_EMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
+#define TOPAZ_HBM_BUF_WMAC_RX_BASE_VIRT	(RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_WMAC_RX_BASE)
+#define TOPAZ_HBM_BUF_WMAC_RX_END	(TOPAZ_HBM_BUF_WMAC_RX_BASE +	\
+						TOPAZ_HBM_BUF_WMAC_RX_TOTAL)
+
+#define TOPAZ_HBM_BUF_END		(TOPAZ_HBM_BUF_WMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
+
+#define TOPAZ_FWT_MCAST_ENTRIES		2048
+#define TOPAZ_FWT_MCAST_FF_ENTRIES	1	/* one for all FF addresses */
+#define TOPAZ_FWT_MCAST_IPMAP_ENT_SIZE	64	/* sizeof(struct topaz_fwt_sw_ipmap) */
+#define TOPAZ_FWT_MCAST_TQE_ENT_SIZE	20	/* sizeof(struct topaz_fwt_sw_mcast_entry) */
+/* Tables are cache-line aligned to ensure proper memory flushing. */
+#define TOPAZ_FWT_MCAST_IPMAP_SIZE	\
+	ROUNDUP(TOPAZ_FWT_MCAST_ENTRIES * TOPAZ_FWT_MCAST_IPMAP_ENT_SIZE,	\
+			ARC_DCACHE_LINE_LENGTH)
+#define TOPAZ_FWT_MCAST_TQE_SIZE	\
+	ROUNDUP(TOPAZ_FWT_MCAST_ENTRIES * TOPAZ_FWT_MCAST_TQE_ENT_SIZE,		\
+			ARC_DCACHE_LINE_LENGTH)
+#define TOPAZ_FWT_MCAST_TQE_FF_SIZE	\
+	ROUNDUP(TOPAZ_FWT_MCAST_FF_ENTRIES * TOPAZ_FWT_MCAST_TQE_ENT_SIZE,	\
+			ARC_DCACHE_LINE_LENGTH)
+
+#define TOPAZ_FWT_MCAST_IPMAP_BASE	TOPAZ_HBM_BUF_END
+#define TOPAZ_FWT_MCAST_IPMAP_END	(TOPAZ_FWT_MCAST_IPMAP_BASE + TOPAZ_FWT_MCAST_IPMAP_SIZE)
+#define TOPAZ_FWT_MCAST_TQE_BASE	TOPAZ_FWT_MCAST_IPMAP_END
+#define TOPAZ_FWT_MCAST_TQE_END		(TOPAZ_FWT_MCAST_TQE_BASE + TOPAZ_FWT_MCAST_TQE_SIZE)
+#define TOPAZ_FWT_MCAST_TQE_FF_BASE	TOPAZ_FWT_MCAST_TQE_END
+#define TOPAZ_FWT_MCAST_TQE_FF_END	(TOPAZ_FWT_MCAST_TQE_FF_BASE + TOPAZ_FWT_MCAST_TQE_FF_SIZE)
+#define TOPAZ_FWT_MCAST_END		TOPAZ_FWT_MCAST_TQE_FF_END
+
+/* Offset from DDR beginning, from which memory start to belong to Linux */
+#define CONFIG_ARC_KERNEL_MEM_BASE	TOPAZ_FWT_MCAST_END
+
+#if TOPAZ_HBM_BUF_EMAC_RX_BASE & (TOPAZ_HBM_BUF_ALIGN - 1)
+	#error EMAC Buffer start not aligned
+#endif
+#if TOPAZ_HBM_BUF_WMAC_RX_BASE & (TOPAZ_HBM_BUF_ALIGN - 1)
+	#error WMAC Buffer start not aligned
+#endif
+#define CONFIG_ARC_UBOOT_RESERVED_SPACE	(8 * 1024)
+
+/* Linux kernel u-boot image start address, for uncompressed images */
+#define CONFIG_ARC_KERNEL_BOOT_BASE	ROUNDUP(CONFIG_ARC_KERNEL_MEM_BASE, \
+						CONFIG_ARC_KERNEL_PAGE_SIZE)
+/* Linux kernel image start */
+#define CONFIG_ARC_KERNEL_BASE		(CONFIG_ARC_KERNEL_BOOT_BASE + CONFIG_ARC_UBOOT_RESERVED_SPACE)
+#define CONFIG_ARC_KERNEL_MAX_SIZE	(RUBY_MAX_DRAM_SIZE - CONFIG_ARC_KERNEL_MEM_BASE)
+#define CONFIG_ARC_KERNEL_MIN_SIZE	(RUBY_MIN_DRAM_SIZE - CONFIG_ARC_KERNEL_MEM_BASE)
+
+/* AuC tightly coupled memory specification */
+#define TOPAZ_AUC_IMEM_ADDR		0xE5000000
+#define TOPAZ_AUC_IMEM_SIZE		(32 * 1024)
+/* BBIC4 RevB AuC DMEM bottom 4KB: 0xE510_0000 to 0xE510_0FFF is aliased with Wmac1 TCM 0xE514_0000
+ * exclude the bottom 4K from DMEM, and reduce the size from 16KB to 12KB
+ */
+#define TOPAZ_AUC_DMEM_ADDR		0xE5101000
+#define TOPAZ_AUC_DMEM_SIZE		(12 * 1024)
+#define TOPAZ_REVB_DMEM_SIZE_RESERVED	(4 *1024)
+/***************/
+
+/* Utility functions */
+#ifndef __ASSEMBLY__
+
+	#if defined(__CHECKER__)
+		#define __sram_text
+		#define __sram_data
+	#elif defined(__GNUC__)
+		/*GCC*/
+		#if defined(CONFIG_ARCH_RUBY_NUMA) && defined(__KERNEL__) && defined(__linux__)
+			/* Kernel is compiled with -mlong-calls option, so we can make calls between code fragments placed in different memories */
+			#define __sram_text_sect_name	".sram.text"
+			#define __sram_data_sect_name	".sram.data"
+			#define __sram_text
+			#define __sram_data
+		#else
+			#define __sram_text_sect_name	".text"
+			#define __sram_data_sect_name	".data"
+			#define __sram_text
+			#define __sram_data
+		#endif
+	#else
+		#pragma Offwarn(428)
+	#endif
+
+	#define __in_mem_range_sram(addr)		__in_mem_range(addr, RUBY_SRAM_BEGIN, RUBY_SRAM_SIZE)
+	#define __in_mem_range_sram_nocache(addr)	__in_mem_range(addr, RUBY_SRAM_NOCACHE_BEGIN, RUBY_SRAM_SIZE)
+	#define __in_mem_range_dram(addr)		__in_mem_range(addr, RUBY_DRAM_BEGIN, RUBY_MAX_DRAM_SIZE)
+	#define __in_mem_range_dram_nocache(addr)	__in_mem_range(addr, RUBY_DRAM_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)
+	RUBY_INLINE int is_valid_mem_addr(unsigned long addr)
+	{
+		if (__in_mem_range(addr, RUBY_SRAM_BEGIN, RUBY_SRAM_SIZE)) {
+			return 1;
+		} else if (__in_mem_range(addr, RUBY_DRAM_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+			return 1;
+		}
+		return 0;
+	}
+
+	#if TOPAZ_MMAP_UNIFIED
+		RUBY_WEAK(virt_to_nocache) void* virt_to_nocache(const void *addr)
+		{
+			unsigned long ret = (unsigned long)addr;
+			if (__in_mem_range(ret, RUBY_SRAM_BEGIN, RUBY_SRAM_SIZE)) {
+				ret = ret - RUBY_SRAM_BEGIN + RUBY_SRAM_NOCACHE_BEGIN;
+			} else if (__in_mem_range(ret, RUBY_DRAM_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+				ret = ret - RUBY_DRAM_BEGIN + RUBY_DRAM_NOCACHE_BEGIN;
+			} else if (ret < RUBY_HARDWARE_BEGIN) {
+				ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
+			}
+			return (void*)ret;
+		}
+		RUBY_WEAK(nocache_to_virt) void* nocache_to_virt(const void *addr)
+		{
+			unsigned long ret = (unsigned long)addr;
+			if (__in_mem_range(ret, RUBY_SRAM_NOCACHE_BEGIN, RUBY_SRAM_SIZE)) {
+				ret = ret - RUBY_SRAM_NOCACHE_BEGIN + RUBY_SRAM_BEGIN;
+			} else if (__in_mem_range(ret, RUBY_DRAM_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+				ret = ret - RUBY_DRAM_NOCACHE_BEGIN + RUBY_DRAM_BEGIN;
+			} else if (ret < RUBY_HARDWARE_BEGIN) {
+				ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
+			}
+			return (void*)ret;
+		}
+	#endif
+
+	#if RUBY_MUC_TLB_ENABLE
+		#if TOPAZ_MMAP_UNIFIED
+#define is_muc_nocached_address(addr) \
+	(__in_mem_range((unsigned long )addr, RUBY_SRAM_NOCACHE_BEGIN, RUBY_SRAM_SIZE) || \
+	 (__in_mem_range((unsigned long )addr, RUBY_DRAM_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)))
+#define is_muc_cached_address(addr) \
+	((unsigned long)addr > RUBY_DRAM_BEGIN) && ((unsigned long)addr < RUBY_HARDWARE_BEGIN)
+			#define muc_to_nocache virt_to_nocache
+			#define nocache_to_muc nocache_to_virt
+		#else
+#define is_muc_nocached_address(addr) \
+	((muc_to_nocache(addr) == RUBY_BAD_VIRT_ADDR) ? 1 : 0)
+#define is_muc_cached_address(addr) \
+	((nocache_to_muc(addr) == RUBY_BAD_VIRT_ADDR) ? 1 : 0)
+
+			RUBY_WEAK(muc_to_nocache) void* muc_to_nocache(const void *addr)
+			{
+				unsigned long ret = (unsigned long)addr;
+				if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_BEGIN, RUBY_SRAM_SIZE)) {
+					ret = ret - RUBY_SRAM_NOFLIP_BEGIN + RUBY_SRAM_NOFLIP_NOCACHE_BEGIN;
+				} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+					ret = ret - RUBY_DRAM_NOFLIP_BEGIN + RUBY_DRAM_NOFLIP_NOCACHE_BEGIN;
+				} else if (ret < RUBY_HARDWARE_BEGIN) {
+					ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
+				}
+				return (void*)ret;
+			}
+			RUBY_WEAK(nocache_to_muc) void* nocache_to_muc(const void *addr)
+			{
+				unsigned long ret = (unsigned long)addr;
+				if (__in_mem_range(ret, RUBY_SRAM_NOFLIP_NOCACHE_BEGIN, RUBY_SRAM_SIZE)) {
+					ret = ret - RUBY_SRAM_NOFLIP_NOCACHE_BEGIN + RUBY_SRAM_NOFLIP_BEGIN;
+				} else if (__in_mem_range(ret, RUBY_DRAM_NOFLIP_NOCACHE_BEGIN, RUBY_MAX_DRAM_SIZE)) {
+					ret = ret - RUBY_DRAM_NOFLIP_NOCACHE_BEGIN + RUBY_DRAM_NOFLIP_BEGIN;
+				} else if (ret < RUBY_HARDWARE_BEGIN) {
+					ret = (unsigned long)RUBY_BAD_VIRT_ADDR;
+				}
+				return (void*)ret;
+			}
+		#endif
+		#ifndef MUC_BUILD
+			RUBY_INLINE unsigned long muc_to_lhost(unsigned long addr)
+			{
+				void *tmp = nocache_to_muc((void*)addr);
+				if (tmp != RUBY_BAD_VIRT_ADDR) {
+					addr = (unsigned long)tmp;
+				}
+				return (unsigned long)bus_to_virt(addr);
+			}
+		#endif // #ifndef MUC_BUILD
+	#else
+		#define muc_to_nocache(x) ((void*)(x))
+		#define nocache_to_muc(x) ((void*)(x))
+		#ifndef MUC_BUILD
+			#define muc_to_lhost(x)   ((unsigned long)bus_to_virt((unsigned long)(x)))
+		#endif // #ifndef MUC_BUILD
+	#endif // #if RUBY_MUC_TLB_ENABLE
+
+	#ifndef __GNUC__
+		/*MCC*/
+		#pragma Popwarn()
+	#endif
+
+#endif // #ifndef __ASSEMBLY__
+
+/*
+ * "Write memory barrier" instruction emulation.
+ * Ruby platform has complex net of connected buses.
+ * Write transactions are buffered.
+ * qtn_wmb() guarantees that all issued earlier and pending writes
+ * to system controller, to SRAM and to DDR are completed
+ * before qtn_wmb() is finished.
+ * For complete safety Linux's wmb() should be defined
+ * through qtn_wmb(), but I afraid it would kill performance.
+ */
+#ifndef __ASSEMBLY__
+	#define RUBY_SYS_CTL_SAFE_READ_REGISTER 0xE0000000
+	#if defined(__GNUC__) && defined(__i386__)
+		#define qtn_wmb()		do {} while(0)
+		static inline unsigned long _qtn_addr_wmb(unsigned long *addr) { return *addr; }
+		#define qtn_addr_wmb(addr)	_qtn_addr_wmb((unsigned long *)(addr))
+		#define qtn_pipeline_drain()	do {} while(0)
+	#elif defined(__GNUC__)
+		/*GCC*/
+		#if defined(__arc__)
+			#define qtn_wmb() \
+			({ \
+				unsigned long temp; \
+				__asm__ __volatile__ ( \
+					"ld.di %0, [%1]\n\t" \
+					"ld.di %0, [%2]\n\t" \
+					"ld.di %0, [%3]\n\t" \
+					"sync\n\t" \
+					: "=r"(temp) \
+					: "i"(RUBY_DRAM_BEGIN + CONFIG_ARC_KERNEL_MEM_BASE), "i"(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B1_BASE), "i"(RUBY_SYS_CTL_SAFE_READ_REGISTER) \
+					: "memory"); \
+			})
+			#define qtn_addr_wmb(addr) \
+			({ \
+				unsigned long temp; \
+				__asm__ __volatile__ ( \
+					"ld.di %0, [%1]\n\t" \
+					"sync\n\t" \
+					: "=r"(temp) \
+					: "r"(addr) \
+					: "memory"); \
+				temp; \
+			})
+			#define qtn_pipeline_drain() \
+			({ \
+				__asm__ __volatile__ ( \
+					"sync\n\t" \
+					: : : "memory"); \
+			})
+		#else
+			#define qtn_wmb()
+			#define qtn_addr_wmb(addr)	*((volatile uint32_t*)addr)
+			#define qtn_pipeline_drain()
+		#endif
+	#else
+		/*MCC*/
+		#if _ARCVER >= 0x31/*ARC7*/
+			#define _qtn_pipeline_drain() \
+				sync
+		#else
+			#define _qtn_pipeline_drain() \
+				nop_s; nop_s; nop_s
+		#endif
+		_Asm void qtn_wmb(void)
+		{
+			/*r12 is temporary register, so we can use it inside this function freely*/
+			ld.di %r12, [RUBY_DRAM_BEGIN + CONFIG_ARC_MUC_BASE]
+			ld.di %r12, [RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_SRAM_B1_BASE]
+			ld.di %r12, [RUBY_SYS_CTL_SAFE_READ_REGISTER]
+			_qtn_pipeline_drain()
+		}
+		_Asm u_int32_t qtn_addr_wmb(unsigned long addr)
+		{
+			%reg addr;
+			ld.di %r0, [addr]
+			_qtn_pipeline_drain()
+		}
+		_Asm void qtn_pipeline_drain(void)
+		{
+			_qtn_pipeline_drain()
+		}
+	#endif
+#endif
+
+/*
+ * Problem - writing to first half of cache way trash second half.
+ * Idea is to lock second half.
+ * Need make sure that invalidation does not unlock these lines (whole
+ * cache invalidation unlocks), or need to re-lock lines back.
+ * Also side effect - half of lines will be cached, half - not.
+ * So may need to shuffle data to make hot data cacheable.
+ */
+#define TOPAZ_CACHE_WAR_OFFSET	2048
+#ifndef __ASSEMBLY__
+#ifdef __GNUC__
+RUBY_INLINE void qtn_cache_topaz_war_dcache_lock(unsigned long aux_reg, unsigned long val)
+{
+	unsigned long addr;
+	unsigned long way_iter;
+	unsigned long line_iter;
+
+	asm volatile (
+		"	sr	%4, [%3]\n"
+		"	mov	%0, 0xA0000000\n"
+		"	mov	%1, 0\n"
+		"1:	add	%0, %0, 2048\n"
+		"	mov	%2, 0\n"
+		"2:	sr	%0, [0x49]\n"
+		"	add	%0, %0, 32\n"
+		"	add	%2, %2, 1\n"
+		"	cmp	%2, 64\n"
+		"	bne	2b\n"
+		"	add	%1, %1, 1\n"
+		"	cmp	%1, 4\n"
+		"	bne	1b\n"
+		: "=r"(addr), "=r"(way_iter), "=r"(line_iter)
+		: "r"(aux_reg), "r"(val)
+	);
+}
+#else
+_Inline _Asm  void qtn_cache_topaz_war_dcache_lock(unsigned long aux_reg, unsigned long val)
+{
+	% reg aux_reg, reg val;
+
+	sr	val, [aux_reg]
+	mov	%r0, 0xA0000000
+	mov	%r1, 0
+	1:	add	%r0, %r0, 2048
+	mov	%r2, 0
+	2:	sr	%r0, [0x49]
+	add	%r0, %r0, 32
+	add	%r2, %r2, 1
+	cmp	%r2, 64
+	bne	2b
+	add	%r1, %r1, 1
+	cmp	%r1, 4
+	bne	1b
+}
+#endif // #ifdef __GNUC__
+#endif // #ifndef __ASSEMBLY__
+
+#endif // #ifndef __RUBY_MEM_H
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_partitions.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_partitions.h
new file mode 100644
index 0000000..1af2bc5
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_partitions.h
@@ -0,0 +1,102 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Ruby platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __RUBY_PARTITIONS_H
+#define __RUBY_PARTITIONS_H
+
+#define F64K_UBOOT_PIGGY_PARTITION_SIZE	0x5000
+
+#if defined(FLASH_SUPPORT_256KB)
+	#define F256K_UBOOT_PIGGY_PARTITION_SIZE 0x5000
+	#define F256K_ENV_PARTITION_SIZE	0x18000
+#endif
+#define F64K_ENV_PARTITION_SIZE         0x6000
+
+#define UBOOT_TEXT_PARTITION_SIZE	0x20000
+#define UBOOT_TINY_TEXT_PARTITION_SIZE	UBOOT_TEXT_PARTITION_SIZE
+#if defined(FLASH_SUPPORT_256KB)
+	#define UBOOT_ENV_PARTITION_SIZE	0x40000
+#else
+	#define UBOOT_ENV_PARTITION_SIZE        0x10000
+#endif
+#define UBOOT_ENV_PARTITION_ADDR	UBOOT_TEXT_PARTITION_SIZE
+
+/*
+ * Make sure CONFIG_ENV_SIZE in file carve_env_partition.sh is the same value
+ */
+#if defined(FLASH_SUPPORT_256KB)
+	#define BOOT_CFG_SIZE			(96 * 1024)
+#elif defined(FLASH_SUPPORT_64KB)
+	#define BOOT_CFG_SIZE			(24 * 1024)
+#else
+	#define BOOT_CFG_SIZE			(64 * 1024)
+#endif
+
+#if defined(FLASH_SUPPORT_256KB)
+	#define BOOT_CFG_BASE_SIZE	(24 * 1024)
+#else
+	#define BOOT_CFG_BASE_SIZE      (16 * 1024)
+#endif
+
+#define BOOT_CFG_DATA_SIZE		(BOOT_CFG_SIZE - sizeof(u32))
+#define BOOT_CFG_DEF_START		(0x1000)
+
+#define RUBY_MIN_DATA_PARTITION_SIZE	(512 * 1024)
+#define IMAGES_START_ADDR		(UBOOT_ENV_PARTITION_ADDR + UBOOT_ENV_PARTITION_SIZE * 2)
+#define NON_IMAGE_SIZE			(UBOOT_TEXT_PARTITION_SIZE +		\
+						UBOOT_ENV_PARTITION_SIZE * 2 +	\
+						RUBY_MIN_DATA_PARTITION_SIZE)
+#define TINY_CFG_NON_IMAGE_SIZE		(UBOOT_TINY_TEXT_PARTITION_SIZE +	\
+						UBOOT_ENV_PARTITION_SIZE * 2 +	\
+						UBOOT_TEXT_PARTITION_SIZE * 2 +	\
+						RUBY_MIN_DATA_PARTITION_SIZE)
+
+#define IMG_SIZE_8M_FLASH_2_IMG		((FLASH_8MB - NON_IMAGE_SIZE) / 2)
+#define IMG_SIZE_8M_FLASH_1_IMG		((FLASH_8MB - NON_IMAGE_SIZE) / 1)
+#define IMG_SIZE_16M_FLASH_2_IMG	((FLASH_16MB - NON_IMAGE_SIZE) / 2)
+#define IMG_SIZE_16M_FLASH_1_IMG	((FLASH_16MB - NON_IMAGE_SIZE) / 1)
+
+#define TINY_CFG_SIZE_16M_FLASH_1_IMG	(FLASH_16MB - TINY_CFG_NON_IMAGE_SIZE)
+#define UBOOT_SAFE_PARTITION_ADDR	(IMAGES_START_ADDR + TINY_CFG_SIZE_16M_FLASH_1_IMG)
+#define UBOOT_LIVE_PARTITION_ADDR	(UBOOT_SAFE_PARTITION_ADDR + UBOOT_TEXT_PARTITION_SIZE)
+
+#define MTD_PARTNAME_UBOOT_BIN		"uboot"
+#define MTD_PARTNAME_UBOOT_TINY_BIN	"uboot_tiny"
+#define MTD_PARTNAME_UBOOT_SAFETY	"uboot_safety"
+#define MTD_PARTNAME_UBOOT_LIVE		"uboot_live"
+#define MTD_PARTNAME_UBOOT_ENV		"uboot_env"
+#define MTD_PARTNAME_UBOOT_ENV_BAK	"uboot_env_bak"
+#define MTD_PARTNAME_LINUX_SAFETY	"linux_safety"
+#define MTD_PARTNAME_LINUX_LIVE		"linux_live"
+#define MTD_PARTNAME_DATA		"data"
+#define MTD_PARTNAME_EXTEND		"extend"
+
+#define IMG_SIZE_LIMIT_PLATFORM	IMG_SIZE_16M_FLASH_2_IMG
+
+#endif // #ifndef __RUBY_PARTITIONS_H
+
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pcie_bda.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pcie_bda.h
new file mode 100644
index 0000000..89091ae
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pcie_bda.h
@@ -0,0 +1,136 @@
+/*

+ * (C) Copyright 2011 Quantenna Communications Inc.

+ *

+ * See file CREDITS for list of people who contributed to this

+ * project.

+ *

+ * 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

+ */

+

+/*

+ * Header file which describes Ruby PCI Express Boot Data Area

+ * Has to be used by both kernel and bootloader.

+ */

+

+#ifndef RUBY_PCIE_BDA_H

+#define RUBY_PCIE_BDA_H

+

+/* Area mapped by via the BAR visible to the host */

+#define RUBY_PCIE_BDA_ADDR		CONFIG_ARC_PCIE_BASE

+#define RUBY_PCIE_BDA_SIZE		CONFIG_ARC_PCIE_SIZE

+

+#define RUBY_BDA_VADDR			(RUBY_PCIE_BDA_ADDR + 0x80000000)

+

+

+#define QDPC_PCIE_BDA_VERSION	0x1000

+

+#define QDPC_BDA_PCIE_INIT		0x01

+#define QDPC_BDA_PCIE_RDY		0x02

+#define QDPC_BDA_FW_LOAD_RDY		0x03

+#define QDPC_BDA_FW_LOAD_DONE		0x04

+#define QDPC_BDA_FW_START		0x05

+#define QDPC_BDA_FW_RUN			0x06

+#define QDPC_BDA_FW_HOST_RDY		0x07

+#define QDPC_BDA_FW_TARGET_RDY		0x11

+#define QDPC_BDA_FW_TARGET_BOOT		0x12

+#define QDPC_BDA_FW_FLASH_BOOT		0x13

+#define QDPC_BDA_FW_HOST_LOAD		0x08

+#define QDPC_BDA_FW_BLOCK_DONE		0x09

+#define QDPC_BDA_FW_BLOCK_RDY		0x0A

+#define QDPC_BDA_FW_EP_RDY		0x0B

+#define QDPC_BDA_FW_BLOCK_END		0x0C

+#define QDPC_BDA_FW_CONFIG		0x0D

+#define QDPC_BDA_FW_RUNNING		0x0E

+

+#define QDPC_BDA_PCIE_FAIL		0x82

+#define QDPC_BDA_FW_LOAD_FAIL		0x85

+

+

+#define PCIE_BDA_RCMODE                 BIT(1)

+#define PCIE_BDA_MSI                    BIT(2)

+#define PCIE_BDA_BAR64                  BIT(3)

+#define PCIE_BDA_FLASH_PRESENT          BIT(4)  /* Tell the Host if EP have flash contain firmware */

+#define PCIE_BDA_FLASH_BOOT             BIT(5)  /* Tell TARGET to boot from flash */

+#define PCIE_BDA_XMIT_UBOOT             BIT(6) /* EP ask for u-boot.bin */

+#define PCIE_BDA_TARGET_FBOOT_ERR       BIT(8)  /* TARGET flash boot failed */

+#define PCIE_BDA_TARGET_FWLOAD_ERR      BIT(9)  /* TARGET firmware load failed */

+#define PCIE_BDA_HOST_NOFW_ERR          BIT(12) /* Host not find any firmware */

+#define PCIE_BDA_HOST_MEMALLOC_ERR      BIT(13) /* Host malloc firmware download memory block failed */

+#define PCIE_BDA_HOST_MEMMAP_ERR        BIT(14) /* Host pci map download memory block failed */

+#define PCIE_BDA_VER(x)                 (((x) >> 4) & 0xFF)

+#define PCIE_BDA_ERROR_MASK             0xFF00  /* take the second 8 bits as error flag */

+

+#define PCIE_DMA_OFFSET_ERROR		0xFFFF

+#define PCIE_DMA_OFFSET_ERROR_MASK	0xFFFF

+

+#define PCIE_BDA_NAMELEN		32

+

+#define QDPC_PCI_ENDIAN_DETECT_DATA	0x12345678

+#define QDPC_PCI_ENDIAN_REVERSE_DATA	0x78563412

+

+#define QDPC_PCI_ENDIAN_VALID_STATUS	0x3c3c3c3c

+#define QDPC_PCI_ENDIAN_INVALID_STATUS	0

+

+#define QDPC_PCI_LITTLE_ENDIAN		0

+#define	QDPC_PCI_BIG_ENDIAN		0xffffffff

+

+#define QDPC_SCHED_TIMEOUT		(HZ / 20)

+

+#define PCIE_DMA_ISSUE_LOG_NUM		128

+

+#define PCIE_RC_TX_QUEUE_LEN		256

+#define PCIE_TX_VALID_PKT		0x80000000

+#define PCIE_PKT_LEN_MASK		0xffff

+

+struct vmac_pkt_info {

+	uint32_t addr;

+	uint32_t info;

+};

+

+typedef struct qdpc_pcie_bda {

+	uint16_t	bda_len;			/* Size of BDA block */

+	uint16_t	bda_version;			/* BDA version */

+	uint32_t	bda_bootstate;			/* Boot state of device */

+	uint32_t	bda_dma_mask;			/* Number of addressable DMA bits */

+	uint32_t	bda_dma_offset;			/* HW specific offset for DMA engine */

+	uint32_t	bda_flags;

+	uint32_t	bda_img;			/* Current load image block */

+	uint32_t	bda_img_size;			/* Current load image block size */

+	uint32_t	bda_ep2h_irqstatus;		/* Added here to allow boot loader to use irqs if desired */

+	uint32_t	bda_h2ep_irqstatus;		/* Added here to allow boot loader to use irqs if desired */

+	uint32_t	bda_msi_addr;

+	uint8_t		reserved1[56];			/* Reserve 56 bytes to make it compatible with older version */

+	uint32_t	bda_flashsz;

+	char		bda_boardname[PCIE_BDA_NAMELEN];

+	uint32_t	bda_pci_pre_status;		/* PCI endian check previous status */

+	uint32_t	bda_pci_endian;			/* Check pci memory endian format */

+	uint32_t	bda_pci_post_status;		/* PCI endian check post status */

+	int32_t		bda_h2ep_txd_budget;		/* txdone replenish budget for ep */

+	int32_t		bda_ep2h_txd_budget;		/* txdone replenish budget for host */

+	uint32_t	bda_rc_rx_bd_base;		/* EP rx buffer descriptors base address */

+	uint32_t	bda_rc_rx_bd_num;

+	uint32_t	bda_rc_tx_bd_base;		/* RC rx buffer descriptors base address */

+	uint32_t	bda_rc_tx_bd_num;

+	uint8_t		bda_ep_link_state;

+	uint8_t		bda_rc_link_state;

+	uint8_t		bda_rc_msi_enabled;

+	uint8_t		reserved2;

+        uint32_t        bda_ep_next_pkt;		/* A pointer to RC's memory specifying next packet to be handled by EP */

+	struct vmac_pkt_info request[PCIE_RC_TX_QUEUE_LEN];

+} qdpc_pcie_bda_t;

+

+#endif

+

diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_platform.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_platform.h
new file mode 100644
index 0000000..4cc2ebb
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_platform.h
@@ -0,0 +1,831 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Ruby platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __RUBY_PLATFORM_H
+#define __RUBY_PLATFORM_H
+
+#include "ruby_config.h"
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* Common                                                                    */
+/*****************************************************************************/
+#define RUBY_BIT(x)			(1 << (x))
+/*****************************************************************************/
+/* DRAM registers                                                            */
+/*****************************************************************************/
+#define RUBY_DDR_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF6000000, 0xE40E0000)
+#define RUBY_DDR_CONTROL		(RUBY_DDR_BASE_ADDR + 0x0)
+#define RUBY_DDR_CONTROL_POWERDOWN_EN	RUBY_BIT(1)
+#define RUBY_DDR_SETTLE_US		(4)
+/*****************************************************************************/
+/*****************************************************************************/
+/* GPIO constants                                                            */
+/*****************************************************************************/
+#define RUBY_GPIO_MAX			(32)
+#define RUBY_GPIO_MODE1_MAX		(11)
+#define RUBY_GPIO_MODE2_MAX		(22)
+#define RUBY_GPIO_IRQ_MAX		(16)
+/*****************************************************************************/
+/* GPIO registers                                                            */
+/*****************************************************************************/
+#define RUBY_GPIO_REGS_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF1000000, 0xE4090000)
+#define RUBY_GPIO_INPUT			(RUBY_GPIO_REGS_ADDR + 0x00)
+#define GPIO_INPUT			RUBY_GPIO_INPUT
+#define RUBY_GPIO_OMASK			(RUBY_GPIO_REGS_ADDR + 0x04)
+#define GPIO_OUTPUT_MASK		RUBY_GPIO_OMASK
+#define RUBY_GPIO_OUTPUT		(RUBY_GPIO_REGS_ADDR + 0x08)
+#define GPIO_OUTPUT			RUBY_GPIO_OUTPUT
+#define RUBY_GPIO_MODE1			(RUBY_GPIO_REGS_ADDR + 0x0c)
+#define GPIO_MODE1			RUBY_GPIO_MODE1
+#define RUBY_GPIO_MODE2			(RUBY_GPIO_REGS_ADDR + 0x10)
+#define GPIO_MODE2			RUBY_GPIO_MODE2
+#define RUBY_GPIO_AFSEL			(RUBY_GPIO_REGS_ADDR + 0x14)
+#define GPIO_ALTFN			RUBY_GPIO_AFSEL
+#define RUBY_GPIO_DEF			(RUBY_GPIO_REGS_ADDR + 0x18)
+#define	RUBY_GPIO1_PWM0			(RUBY_GPIO_REGS_ADDR + 0x20) /* AFSEL: UART1 (input) */
+#define	RUBY_GPIO9_PWM2			(RUBY_GPIO_REGS_ADDR + 0x28) /* AFSEL: UART1 (output) */
+/*****************************************************************************/
+/* GPIO pins                                                                 */
+/*****************************************************************************/
+#define RUBY_GPIO_PIN0			(0)
+#define RUBY_GPIO_PIN1			(1)
+#define RUBY_GPIO_PIN2			(2)
+#define RUBY_GPIO_PIN3			(3)
+#define RUBY_GPIO_PIN4			(4)
+#define RUBY_GPIO_PIN5			(5)
+#define RUBY_GPIO_PIN6			(6)
+#define RUBY_GPIO_PIN7			(7)
+#define RUBY_GPIO_PIN8			(8)
+#define RUBY_GPIO_PIN9			(9)
+#define RUBY_GPIO_PIN10			(10)
+#define RUBY_GPIO_PIN11			(11)
+#define RUBY_GPIO_PIN12			(12)
+#define RUBY_GPIO_PIN13			(13)
+#define RUBY_GPIO_PIN14			(14)
+#define RUBY_GPIO_PIN15			(15)
+#define RUBY_GPIO_PIN16			(16)
+#define RUBY_GPIO_PIN17			(17)
+
+#define RUBY_GPIO_UART0_SI		(0)
+#define RUBY_GPIO_UART0_SO		(8)
+#define RUBY_GPIO_UART1_SI		(1)
+#define RUBY_GPIO_UART1_SO		(9)
+/* these are for spi1, bga has dedicated spi0 pins */
+#define RUBY_GPIO_SPI_MISO		(2)
+#define RUBY_GPIO_SPI_SCK		(6)
+#define RUBY_GPIO_SPI_MOSI		(5)
+#define RUBY_GPIO_SPI_nCS		(4)
+
+#define RUBY_GPIO_LNA_TOGGLE		(7)
+
+#define RUBY_GPIO_RTD			(3)	/* Reset to default */
+#define RUBY_GPIO_WPS			(7)
+#define RUBY_GPIO_I2C_SCL		(10)
+#define RUBY_GPIO_I2C_SDA		(11)
+#define RUBY_GPIO_WLAN_DISABLE		(12)
+#define RUBY_GPIO_LED1			(13)
+#define RUBY_GPIO_RFIC_INTR		(14)
+
+#ifndef TOPAZ_AMBER_IP
+#define RUBY_GPIO_RFIC_RESET		(15)
+#else
+#define RUBY_GPIO_RFIC_RESET		(10)
+#endif
+
+#define RUBY_GPIO_LED2			(16)
+
+/*****************************************************************************/
+/* GPIO function constants                                                   */
+/*****************************************************************************/
+#define RUBY_GPIO_MODE_INPUT		(0)
+#define GPIO_MODE_INPUT				RUBY_GPIO_MODE_INPUT
+#define RUBY_GPIO_MODE_OUTPUT		(1)
+#define GPIO_MODE_OUTPUT			RUBY_GPIO_MODE_OUTPUT
+#define RUBY_GPIO_MODE_OPEN_SOURCE	(2)
+#define RUBY_GPIO_MODE_OPEN_DRAIN	(3)
+#define RUBY_GPIO_ALT_INPUT			(4)
+#define RUBY_GPIO_ALT_OUTPUT		(5)
+#define RUBY_GPIO_ALT_OPEN_SOURCE	(6)
+#define RUBY_GPIO_ALT_OPEN_DRAIN	(7)
+#define	GPIO_PIN(x)			(x)
+#define	GPIO_OUTPUT_LO			(0)
+#define	GPIO_OUTPUT_HI			(1)
+/*****************************************************************************/
+/*****************************************************************************/
+/* UART FIFO size                                                            */
+/*****************************************************************************/
+#define RUBY_UART_FIFO_SIZE		(16)
+/*****************************************************************************/
+/* UART register addresses                                                   */
+/*****************************************************************************/
+#define RUBY_UART0_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF0000000, 0xE4080000)
+#define RUBY_UART0_RBR_THR_DLL		(RUBY_UART0_BASE_ADDR + 0x00)
+#define RUBY_UART0_DLH_IER		(RUBY_UART0_BASE_ADDR + 0x04)
+#define RUBY_UART0_IIR_FCR_LCR		(RUBY_UART0_BASE_ADDR + 0x08)
+#define RUBY_UART0_LCR			(RUBY_UART0_BASE_ADDR + 0x0c)
+#define RUBY_UART0_MCR			(RUBY_UART0_BASE_ADDR + 0x10)
+#define RUBY_UART0_LSR			(RUBY_UART0_BASE_ADDR + 0x14)
+#define RUBY_UART0_MSR			(RUBY_UART0_BASE_ADDR + 0x18)
+#define RUBY_UART0_SCR			(RUBY_UART0_BASE_ADDR + 0x1c)
+#define RUBY_UART0_LPDLL		(RUBY_UART0_BASE_ADDR + 0x20)
+#define RUBY_UART0_LPDLH		(RUBY_UART0_BASE_ADDR + 0x24)
+#define RUBY_UART0_SRBR			(RUBY_UART0_BASE_ADDR + 0x30)
+#define RUBY_UART0_STHR			(RUBY_UART0_BASE_ADDR + 0x34)
+#define RUBY_UART0_FAR			(RUBY_UART0_BASE_ADDR + 0x70)
+#define RUBY_UART0_TFR			(RUBY_UART0_BASE_ADDR + 0x74)
+#define RUBY_UART0_RFW			(RUBY_UART0_BASE_ADDR + 0x78)
+#define RUBY_UART0_USR			(RUBY_UART0_BASE_ADDR + 0x7c)
+#define RUBY_UART0_TFL			(RUBY_UART0_BASE_ADDR + 0x80)
+#define RUBY_UART0_RFL			(RUBY_UART0_BASE_ADDR + 0x84)
+#define RUBY_UART0_SRR			(RUBY_UART0_BASE_ADDR + 0x88)
+#define RUBY_UART0_SRTS			(RUBY_UART0_BASE_ADDR + 0x8c)
+#define RUBY_UART0_SBCR			(RUBY_UART0_BASE_ADDR + 0x90)
+#define RUBY_UART0_SDMAM		(RUBY_UART0_BASE_ADDR + 0x94)
+#define RUBY_UART0_SFE			(RUBY_UART0_BASE_ADDR + 0x98)
+#define RUBY_UART0_SRT			(RUBY_UART0_BASE_ADDR + 0x9c)
+#define RUBY_UART0_STET			(RUBY_UART0_BASE_ADDR + 0xa0)
+#define RUBY_UART0_HTX			(RUBY_UART0_BASE_ADDR + 0xa4)
+#define RUBY_UART0_DMASA		(RUBY_UART0_BASE_ADDR + 0xa8)
+#define RUBY_UART0_CPR			(RUBY_UART0_BASE_ADDR + 0xf4)
+#define RUBY_UART0_UCV			(RUBY_UART0_BASE_ADDR + 0xf8)
+#define RUBY_UART0_CTR			(RUBY_UART0_BASE_ADDR + 0xfc)
+
+#define RUBY_UART1_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF5000000, 0xE40D0000)
+#define RUBY_UART1_RBR_THR_DLL		(RUBY_UART1_BASE_ADDR + 0x00)
+#define RUBY_UART1_DLH_IER		(RUBY_UART1_BASE_ADDR + 0x04)
+#define RUBY_UART1_IIR_FCR_LCR		(RUBY_UART1_BASE_ADDR + 0x08)
+#define RUBY_UART1_LCR			(RUBY_UART1_BASE_ADDR + 0x0c)
+#define RUBY_UART1_MCR			(RUBY_UART1_BASE_ADDR + 0x10)
+#define RUBY_UART1_LSR			(RUBY_UART1_BASE_ADDR + 0x14)
+#define RUBY_UART1_MSR			(RUBY_UART1_BASE_ADDR + 0x18)
+#define RUBY_UART1_SCR			(RUBY_UART1_BASE_ADDR + 0x1c)
+#define RUBY_UART1_LPDLL		(RUBY_UART1_BASE_ADDR + 0x20)
+#define RUBY_UART1_LPDLH		(RUBY_UART1_BASE_ADDR + 0x24)
+#define RUBY_UART1_SRBR			(RUBY_UART1_BASE_ADDR + 0x30)
+#define RUBY_UART1_STHR			(RUBY_UART1_BASE_ADDR + 0x34)
+#define RUBY_UART1_FAR			(RUBY_UART1_BASE_ADDR + 0x70)
+#define RUBY_UART1_TFR			(RUBY_UART1_BASE_ADDR + 0x74)
+#define RUBY_UART1_RFW			(RUBY_UART1_BASE_ADDR + 0x78)
+#define RUBY_UART1_USR			(RUBY_UART1_BASE_ADDR + 0x7c)
+#define RUBY_UART1_TFL			(RUBY_UART1_BASE_ADDR + 0x80)
+#define RUBY_UART1_RFL			(RUBY_UART1_BASE_ADDR + 0x84)
+#define RUBY_UART1_SRR			(RUBY_UART1_BASE_ADDR + 0x88)
+#define RUBY_UART1_SRTS			(RUBY_UART1_BASE_ADDR + 0x8c)
+#define RUBY_UART1_SBCR			(RUBY_UART1_BASE_ADDR + 0x90)
+#define RUBY_UART1_SDMAM		(RUBY_UART1_BASE_ADDR + 0x94)
+#define RUBY_UART1_SFE			(RUBY_UART1_BASE_ADDR + 0x98)
+#define RUBY_UART1_SRT			(RUBY_UART1_BASE_ADDR + 0x9c)
+#define RUBY_UART1_STET			(RUBY_UART1_BASE_ADDR + 0xa0)
+#define RUBY_UART1_HTX			(RUBY_UART1_BASE_ADDR + 0xa4)
+#define RUBY_UART1_DMASA		(RUBY_UART1_BASE_ADDR + 0xa8)
+#define RUBY_UART1_CPR			(RUBY_UART1_BASE_ADDR + 0xf4)
+#define RUBY_UART1_UCV			(RUBY_UART1_BASE_ADDR + 0xf8)
+#define RUBY_UART1_CTR			(RUBY_UART1_BASE_ADDR + 0xfc)
+
+/*****************************************************************************/
+/* UART Status Register - USR                                                */
+/*****************************************************************************/
+#define RUBY_USR_TX_Fifo_Empty		0x04
+#define RUBY_USR_RX_Fifo_Full		0x10
+#define RUBY_USR_TX_Fifo_nFull		0x02
+#define RUBY_USR_RX_Fifo_nEmpty		0x08
+#define RUBY_USR_Busy			0x01
+/*****************************************************************************/
+/* Line Status Register - LSR                                                */
+/*****************************************************************************/
+#define RUBY_LSR_TX_Empty		0x40
+#define RUBY_LSR_RX_Ready		0x01
+/*****************************************************************************/
+/* Line Control Register - LCR                                               */
+/*****************************************************************************/
+#define RUBY_LCR_Data_Word_Length_5	0x0
+#define RUBY_LCR_Data_Word_Length_6	0x1
+#define RUBY_LCR_Data_Word_Length_7	0x2
+#define RUBY_LCR_Data_Word_Length_8	0x3
+#define RUBY_LCR_Stop_Bit_1		0x0
+#define RUBY_LCR_Stop_Bit_2		0x4
+#define RUBY_LCR_No_Parity		0x0
+#define RUBY_LCR_Odd_Parity		0x8
+#define RUBY_LCR_Even_Parity		0x18
+#define RUBY_LCR_High_Parity		0x28
+#define RUBY_LCR_Low_Parity		0x38
+#define RUBY_LCR_Break_Disable		0x0
+#define RUBY_LCR_Break_Enable		0x40
+#define RUBY_LCR_DLAB			0x80
+/*****************************************************************************/
+/*****************************************************************************/
+/* Timer constants                                                           */
+/*****************************************************************************/
+#define RUBY_TIMER_INT_MASK		(RUBY_BIT(2))
+#define RUBY_TIMER_SINGLE		(RUBY_BIT(1))
+#define RUBY_TIMER_ENABLE		(RUBY_BIT(0))
+/*****************************************************************************/
+#define RUBY_CPU_TIMERS			(2)
+#define RUBY_NUM_TIMERS			(4)
+#define RUBY_TIMER_MUC_CCA              (3)
+#define RUBY_TIMER_FREQ                 125000000
+
+#define RUBY_TIMER_MUC_CCA_FREQ_SHIFT    2    /* shift from 1ms base */
+#define RUBY_TIMER_MUC_CCA_FREQ          (1000 << RUBY_TIMER_MUC_CCA_FREQ_SHIFT)
+#define RUBY_TIMER_MUC_CCA_LIMIT         (RUBY_TIMER_FREQ / RUBY_TIMER_MUC_CCA_FREQ)
+#define RUBY_TIMER_MUC_CCA_INTV          (1000 >> RUBY_TIMER_MUC_CCA_FREQ_SHIFT)    /* microseconds */
+#define RUBY_TIMER_MUC_CCA_CNT2MS(_v)    ((_v) >> RUBY_TIMER_MUC_CCA_FREQ_SHIFT)
+/*****************************************************************************/
+#define RUBY_TIMER_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF3000000, 0xE40B0000)
+#define RUBY_TIMER_CHANNEL		(0x14)
+#define RUBY_TIMER_LOAD_COUNT(x)	(RUBY_TIMER_BASE_ADDR + ((x)*RUBY_TIMER_CHANNEL) + 0)
+#define RUBY_TIMER_VALUE(x)		(RUBY_TIMER_BASE_ADDR + ((x)*RUBY_TIMER_CHANNEL) + 4)
+#define RUBY_TIMER_CONTROL(x)		(RUBY_TIMER_BASE_ADDR + ((x)*RUBY_TIMER_CHANNEL) + 8)
+#define RUBY_TIMER_EOI(x)		(RUBY_TIMER_BASE_ADDR + ((x)*RUBY_TIMER_CHANNEL) + 12)
+#define RUBY_TIMER_INTSTAT(x)		(RUBY_TIMER_BASE_ADDR + ((x)*RUBY_TIMER_CHANNEL) + 16)
+/*****************************************************************************/
+#define RUBY_TIMER_GLOBAL_INT_STATUS	(RUBY_TIMER_BASE_ADDR + 0xa0)
+#define RUBY_TIMER_GLOBAL_EOI		(RUBY_TIMER_BASE_ADDR + 0xa4)
+#define RUBY_TIMER_GLOBAL_RAW_STATUS	(RUBY_TIMER_BASE_ADDR + 0xa8)
+#define RUBY_TIMER_GLOBAL_COMP_VER	(RUBY_TIMER_BASE_ADDR + 0xac)
+/*****************************************************************************/
+#define RUBY_TIMER_ORINT_EN(x)		(1 << (18 + (x)))
+/*****************************************************************************/
+/*****************************************************************************/
+/* ENET registers                                                            */
+/*****************************************************************************/
+#define RUBY_ENET0_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xED000000, 0xE4070000)
+#define RUBY_ENET1_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xE8000000, 0xE4040000)
+/*****************************************************************************/
+/*****************************************************************************/
+/* System controller registers                                               */
+/*****************************************************************************/
+#define RUBY_SYS_CTL_BASE_ADDR_NOMAP		0xE0000000
+#define RUBY_SYS_CTL_BASE_ADDR			TOPAZ_ALIAS_MAP_SWITCH(RUBY_SYS_CTL_BASE_ADDR_NOMAP, 0xE4000000)
+#define RUBY_SYS_CTL_CPU_VEC_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x00)
+#define RUBY_SYS_CTL_CPU_VEC			(RUBY_SYS_CTL_BASE_ADDR + 0x04)
+#define RUBY_SYS_CTL_MASK			(RUBY_SYS_CTL_BASE_ADDR + 0x08)
+#define RUBY_SYS_CTL_CTRL			(RUBY_SYS_CTL_BASE_ADDR + 0x0c)
+#define RUBY_SYS_CTL_RESET_CAUSE		(RUBY_SYS_CTL_BASE_ADDR + 0x10)
+#define RUBY_SYS_CTL_CSR			(RUBY_SYS_CTL_BASE_ADDR + 0x14)
+#define RUBY_SYS_CTL_DEBUG_SEL			(RUBY_SYS_CTL_BASE_ADDR + 0x18)
+#define RUBY_SYS_CTL_L2M_INT			(RUBY_SYS_CTL_BASE_ADDR + 0x1C)
+#define RUBY_SYS_CTL_L2M_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x20)
+#define RUBY_SYS_CTL_L2D_INT			(RUBY_SYS_CTL_BASE_ADDR + PLATFORM_REG_SWITCH(0x24, 0x34))
+#define RUBY_SYS_CTL_L2D_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + PLATFORM_REG_SWITCH(0x28, 0x38))
+#define RUBY_SYS_CTL_M2L_INT			(RUBY_SYS_CTL_BASE_ADDR + 0x2C)
+#define RUBY_SYS_CTL_M2L_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x30)
+#define RUBY_SYS_CTL_M2D_INT			(RUBY_SYS_CTL_BASE_ADDR + PLATFORM_REG_SWITCH(0x34, 0x24))
+#define RUBY_SYS_CTL_M2D_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + PLATFORM_REG_SWITCH(0x38, 0x28))
+#define RUBY_SYS_CTL_D2L_INT			(RUBY_SYS_CTL_BASE_ADDR + 0x3C)
+#define RUBY_SYS_CTL_D2L_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x40)
+#define RUBY_SYS_CTL_D2M_INT			(RUBY_SYS_CTL_BASE_ADDR + 0x44)
+#define RUBY_SYS_CTL_D2M_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x48)
+#define RUBY_SYS_CTL_LHOST_INT_EN		(RUBY_SYS_CTL_BASE_ADDR + 0x4C)
+#define RUBY_SYS_CTL_MUC_INT_EN			(RUBY_SYS_CTL_BASE_ADDR + 0x50)
+#define RUBY_SYS_CTL_DSP_INT_EN			(RUBY_SYS_CTL_BASE_ADDR + 0x54)
+#define RUBY_SYS_CTL_LHOST_ORINT_EN		(RUBY_SYS_CTL_BASE_ADDR + 0x58)
+#define RUBY_SYS_CTL_MUC_ORINT_EN		(RUBY_SYS_CTL_BASE_ADDR + 0x5C)
+#define RUBY_SYS_CTL_DSP_ORINT_EN		(RUBY_SYS_CTL_BASE_ADDR + 0x60)
+#define RUBY_SYS_CTL_MUC_REMAP			(RUBY_SYS_CTL_BASE_ADDR + 0x64)
+#define RUBY_SYS_CTL_DSP_REMAP			(RUBY_SYS_CTL_BASE_ADDR + 0x68)
+#define RUBY_SYS_CTL_PCIE_CFG0			(RUBY_SYS_CTL_BASE_ADDR + 0x6C)
+#define RUBY_SYS_CTL_PCIE_CFG1			(RUBY_SYS_CTL_BASE_ADDR + 0x70)
+#define RUBY_SYS_CTL_PCIE_CFG2			(RUBY_SYS_CTL_BASE_ADDR + 0x74)
+#define RUBY_SYS_CTL_PCIE_CFG3			(RUBY_SYS_CTL_BASE_ADDR + 0x78)
+#define RUBY_SYS_CTL_PCIE_CFG4			(RUBY_SYS_CTL_BASE_ADDR + 0x7C)
+#define RUBY_SYS_CTL_PLL0_CTRL			(RUBY_SYS_CTL_BASE_ADDR + 0x80)
+#define RUBY_SYS_CTL_PLL1_CTRL			(RUBY_SYS_CTL_BASE_ADDR + 0x84)
+#define RUBY_SYS_CTL_LHOST_ID			(RUBY_SYS_CTL_BASE_ADDR + 0x88)
+#define RUBY_SYS_CTL_PLL2_CTRL			(RUBY_SYS_CTL_BASE_ADDR + 0x8C)
+#define RUBY_SYS_CTL_MUC_ID			(RUBY_SYS_CTL_BASE_ADDR + 0x90)
+#define RUBY_SYS_CTL_L2M_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0x94)
+#define RUBY_SYS_CTL_M2L_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0x98)
+#define RUBY_SYS_CTL_L2D_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0x9C)
+#define RUBY_SYS_CTL_D2L_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0xA0)
+#define RUBY_SYS_CTL_M2D_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0xA4)
+#define RUBY_SYS_CTL_D2M_SEM			(RUBY_SYS_CTL_BASE_ADDR + 0xA8)
+#define RUBY_SYS_CTL_INTR_INV0			(RUBY_SYS_CTL_BASE_ADDR + 0xAC)
+#define RUBY_SYS_CTL_INTR_INV1			(RUBY_SYS_CTL_BASE_ADDR + 0xB0)
+#define RUBY_SYS_CTL_GMII_CLKDLL		(RUBY_SYS_CTL_BASE_ADDR + 0xB4)
+#define RUBY_SYS_CTL_DEBUG_BUS			(RUBY_SYS_CTL_BASE_ADDR + 0xB8)
+#define RUBY_SYS_CTL_SPARE			(RUBY_SYS_CTL_BASE_ADDR + 0xBC)
+#define RUBY_SYS_CTL_PCIE_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0xC0)
+#define	RUBY_SYS_CTL_GPIO_IRQ_SEL		(RUBY_SYS_CTL_BASE_ADDR + 0xc4)
+#define RUBY_SYS_CTL_PCIE_SLV_REQ_MISC_INFO	(RUBY_SYS_CTL_BASE_ADDR + 0xCC)
+#define RUBY_SYS_CTL_DDR_CTRL			(RUBY_SYS_CTL_BASE_ADDR + 0xE8)
+#define RUBY_SYS_CTL_GPIO_INT_STATUS		(RUBY_SYS_CTL_BASE_ADDR + 0x154)
+#define RUBY_SYS_AHB_MON_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x160)
+#define RUBY_SYS_CTL_BOND_OPT			(RUBY_SYS_CTL_BASE_ADDR + 0x16C)
+
+/*****************************************************************************/
+/* System controller constants                                               */
+/*****************************************************************************/
+#define RUBY_SYS_CTL_REMAP(x)		(((x) & 0x3) << 3)
+#define RUBY_SYS_CTL_LINUX_MAP(x)	(((x) & 0x1) << 31)
+#define RUBY_SYS_CTL_SPICLK(x)		(((x) & 0x3) << 15)
+#define RUBY_SYS_CTL_CLKSEL(x)		(((x) & 0x3) << 5)
+#define RUBY_SYS_CTL_MUC_REMAP_SHIFT	15
+#define RUBY_SYS_CTL_MUC_REMAP_VAL(x)	(RUBY_BIT(31) | ((x) >> RUBY_SYS_CTL_MUC_REMAP_SHIFT))
+#define RUBY_SYS_CTL_DSP_REMAP_SHIFT	15
+#define RUBY_SYS_CTL_DSP_REMAP_VAL(x)	(RUBY_BIT(31) | ((x) >> RUBY_SYS_CTL_DSP_REMAP_SHIFT))
+/* reset bits - names match rtl */
+#define RUBY_SYS_CTL_RESET_LHOST_CORE	(RUBY_BIT(0))
+#define RUBY_SYS_CTL_RESET_LHOST_BUS	(RUBY_BIT(1))
+#define RUBY_SYS_CTL_RESET_DDR		(RUBY_BIT(2))
+#define RUBY_SYS_CTL_RESET_SRAM		(RUBY_BIT(3))
+#define RUBY_SYS_CTL_RESET_DSP		(RUBY_BIT(4))
+#define RUBY_SYS_CTL_RESET_IOSS		(RUBY_BIT(5))
+#define RUBY_SYS_CTL_RESET_NETSS	(RUBY_BIT(7))
+#define RUBY_SYS_CTL_RESET_MAC		(RUBY_BIT(8))
+#define RUBY_SYS_CTL_RESET_ENET0	(RUBY_BIT(9))
+#define RUBY_SYS_CTL_RESET_MUC		(RUBY_BIT(11))
+#define RUBY_SYS_CTL_RESET_ENET1	(RUBY_BIT(12))
+#define RUBY_SYS_CTL_RESET_PCIE		(RUBY_BIT(13))
+#define RUBY_SYS_CTL_RESET_BB		(RUBY_BIT(14))
+#define RUBY_SYS_CTL_RESET_EXT		(RUBY_BIT(15))
+/* reset useful constants */
+#define RUBY_SYS_CTL_RESET_ALL		(~0x0)
+#define RUBY_SYS_CTL_RESET_MUC_ALL	RUBY_SYS_CTL_RESET_MUC
+#define RUBY_SYS_CTL_RESET_DSP_ALL	RUBY_SYS_CTL_RESET_DSP
+/* reset cause definitions */
+#define	RUBY_SYS_CTL_RESET_CAUSE_PO	(RUBY_BIT(0))
+#define	RUBY_SYS_CTL_RESET_CAUSE_SR	(RUBY_BIT(1))
+#define	RUBY_SYS_CTL_RESET_CAUSE_WD	(RUBY_BIT(2))
+#define RUBY_SYS_CTL_INTR_TIMER_MSK(t)	(1 << (20 + (t)))
+/* sysctl vector/mask bit definitions */
+#define RUBY_SYS_CTL_MASK_BOOTMODE	(0x7 << 0)
+#define RUBY_SYS_CTL_MASK_REMAP		(0x3 << 3)
+#define RUBY_SYS_CTL_MASK_CLKSEL	(0x3 << 5)
+/* clksel: 00 = cpu(400)      bus(200) */
+#define RUBY_SYS_CTL_CLKSEL_00_BUS_FREQ	200000000
+/* clksel: 01 = cpu(320)      bus(160) */
+#define RUBY_SYS_CTL_CLKSEL_01_BUS_FREQ	160000000
+/* clksel: 10 = cpu(250)      bus(125) */
+#define RUBY_SYS_CTL_CLKSEL_10_BUS_FREQ	125000000
+/* clksel: 11 = cpu(200)      bus(100) */
+#define RUBY_SYS_CTL_CLKSEL_11_BUS_FREQ	100000000
+#define RUBY_SYS_CTL_MASK_DDRDRV	(0x1 << 7)
+#define RUBY_SYS_CTL_MASK_DDRODT	(0x3 << 8)
+#define RUBY_SYS_CTL_MASK_NODDR		(0x1 << 12)
+#define RUBY_SYS_CTL_MASK_MII		(0x3 << 13)
+#define RUBY_SYS_CTL_MASK_MII_EMAC0	(0x1 << 13)
+#define RUBY_SYS_CTL_MASK_MII_EMAC1	(0x1 << 14)
+#define RUBY_SYS_CTL_MASK_SPICLK	(0x3 << 15)
+#define RUBY_SYS_CTL_MASK_JTAGCHAIN	(0x1 << 17)
+
+#define RUBY_SYS_CTL_MASK_GMII0_TXCLK	(0x3 << 18)
+#define RUBY_SYS_CTL_MASK_GMII0_10M	(0x0 << 18)
+#define RUBY_SYS_CTL_MASK_GMII0_100M	(0x1 << 18)
+#define RUBY_SYS_CTL_MASK_GMII0_1000M	(0x2 << 18)
+
+#define RUBY_SYS_CTL_MASK_GMII1_TXCLK	(0x3 << 20)
+#define RUBY_SYS_CTL_MASK_GMII1_10M	(0x0 << 20)
+#define RUBY_SYS_CTL_MASK_GMII1_100M	(0x1 << 20)
+#define RUBY_SYS_CTL_MASK_GMII1_1000M	(0x2 << 20)
+
+#define RUBY_SYS_CTL_MASK_GMII_10M	(0)
+#define RUBY_SYS_CTL_MASK_GMII_100M	(1)
+#define RUBY_SYS_CTL_MASK_GMII_1000M	(2)
+#define RUBY_SYS_CTL_MASK_GMII_TXCLK	(3)
+#define RUBY_SYS_CTL_MASK_GMII0_SHIFT	(18)
+#define RUBY_SYS_CTL_MASK_GMII1_SHIFT	(20)
+
+#define RUBY_SYS_CTL_MASK_DDRCLK	(0x7 << 22)
+#define RUBY_SYS_CTL_MASK_LINUX_MAP	(0x1 << 31)
+
+#define RUBY_RESET_CAUSE_UART_SHIFT	(7)
+#define RUBY_RESET_CAUSE_UART(x)	(1 << (RUBY_RESET_CAUSE_UART_SHIFT + x))
+
+/* global[30:25,11] unused */
+/* for compatibility */
+#define SYSCTRL_CTRL_MASK		(RUBY_SYS_CTL_MASK - RUBY_SYS_CTL_BASE_ADDR)
+#define SYSCTRL_CTRL			(RUBY_SYS_CTL_CTRL - RUBY_SYS_CTL_BASE_ADDR)
+#define SYSCTRL_RESET_MASK		(RUBY_SYS_CTL_CPU_VEC_MASK - RUBY_SYS_CTL_BASE_ADDR)
+#define SYSCTRL_RESET			(RUBY_SYS_CTL_CPU_VEC - RUBY_SYS_CTL_BASE_ADDR)
+#define SYSCTRL_REV_NUMBER		(RUBY_SYS_CTL_CSR - RUBY_SYS_CTL_BASE_ADDR)
+#define SYSCTRL_RGMII_DLL		(RUBY_SYS_CTL_GMII_CLKDLL - RUBY_SYS_CTL_BASE_ADDR)
+/*****************************************************************************/
+/*****************************************************************************/
+/* Watchdog registers                                                        */
+/*****************************************************************************/
+#define RUBY_WDT_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF4000000, 0xE40C0000)
+#define RUBY_WDT_CTL			(RUBY_WDT_BASE_ADDR + 0x00)
+#define RUBY_WDT_TIMEOUT_RANGE		(RUBY_WDT_BASE_ADDR + 0x04)
+#define RUBY_WDT_CURRENT_VALUE		(RUBY_WDT_BASE_ADDR + 0x08)
+#define RUBY_WDT_COUNTER_RESTART	(RUBY_WDT_BASE_ADDR + 0x0c)
+#define RUBY_WDT_INT_STAT		(RUBY_WDT_BASE_ADDR + 0x10)
+#define RUBY_WDT_INT_CLEAR		(RUBY_WDT_BASE_ADDR + 0x14)
+/*****************************************************************************/
+/* Watchdog constants                                                        */
+/*****************************************************************************/
+#define RUBY_WDT_ENABLE_IRQ_WARN	(RUBY_BIT(1))
+#define RUBY_WDT_ENABLE			(RUBY_BIT(0))
+#define RUBY_WDT_MAGIC_NUMBER		(0x76)
+#define RUBY_WDT_MAX_TIMEOUT		(0xF)
+#define RUBY_WDT_RESET_TIMEOUT		(0x8)
+/*****************************************************************************/
+/*****************************************************************************/
+/* SPI registers                                                             */
+/*****************************************************************************/
+#define RUBY_SPI_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xE2000000, 0xE4030000)
+#define RUBY_SPI_COMMIT			(RUBY_SPI_BASE_ADDR + 0x0000)
+#define RUBY_SPI_CONTROL		(RUBY_SPI_BASE_ADDR + 0x0004)
+#define RUBY_SPI_WRITE_STATUS		(RUBY_SPI_BASE_ADDR + 0x0100)
+#define RUBY_SPI_PAGE_PROGRAM		(RUBY_SPI_BASE_ADDR + 0x0200)
+#define RUBY_SPI_WRITE_DIS		(RUBY_SPI_BASE_ADDR + 0x0400)
+#define RUBY_SPI_READ_STATUS		(RUBY_SPI_BASE_ADDR + 0x0500)
+#define RUBY_SPI_WRITE_EN		(RUBY_SPI_BASE_ADDR + 0x0600)
+#define RUBY_SPI_FAST_READ		(RUBY_SPI_BASE_ADDR + 0x0B00)
+#define RUBY_SPI_WRITE_REG3		(RUBY_SPI_BASE_ADDR + 0x1100)
+#define RUBY_SPI_READ_REG3              (RUBY_SPI_BASE_ADDR + 0x1500)
+#define RUBY_SPI_SECTOR_ERASE_20	(RUBY_SPI_BASE_ADDR + 0x2000)
+#define RUBY_SPI_READ_SCUR              (RUBY_SPI_BASE_ADDR + 0x2b00)
+#define RUBY_SPI_WRITE_IBUP		(RUBY_SPI_BASE_ADDR + 0x3900)
+#define RUBY_SPI_WRITE_PRO_SEL          (RUBY_SPI_BASE_ADDR + 0x6800)
+#define RUBY_SPI_GBLOCK_LOCK            (RUBY_SPI_BASE_ADDR + 0x7e00)
+#define RUBY_SPI_GBLOCK_UNLOCK          (RUBY_SPI_BASE_ADDR + 0x9800)
+#define TOPAZ_SPI_GBLOCK_UNLOCK		(RUBY_SPI_BASE_ADDR + 0x9800)
+#define RUBY_SPI_READ_ID		(RUBY_SPI_BASE_ADDR + 0x9F00)
+#define RUBY_SPI_BULK_ERASE		(RUBY_SPI_BASE_ADDR + 0xC700)
+#define RUBY_SPI_SECTOR_ERASE_D8	(RUBY_SPI_BASE_ADDR + 0xD800)
+#define RUBY_SPI_READ_DPB               (RUBY_SPI_BASE_ADDR + 0xe000)
+#define RUBY_SPI_WRITE_DPB              (RUBY_SPI_BASE_ADDR + 0xe100)
+#define RUBY_SPI_PAGE_PROGRAM_4B	(RUBY_SPI_BASE_ADDR + 0x1200)
+#define RUBY_SPI_SECTOR_ERASE_D8_4B	(RUBY_SPI_BASE_ADDR + 0xDC00)
+#define RUBY_SPI_SECTOR_ERASE_20_4B	(RUBY_SPI_BASE_ADDR + 0x2100)
+#define RUBY_SPI_ADDRESS_MODE_4B	0x85
+#define RUBY_SPI_BOUNDARY_4B		0x1000000
+
+#define RUBY_SPI_READ_LOCK               (RUBY_SPI_BASE_ADDR + 0x2D00)
+#define RUBY_SPI_WRITE_LOCK              (RUBY_SPI_BASE_ADDR + 0x2C00)
+#define RUBY_SPI_READ_CONFIG              (RUBY_SPI_BASE_ADDR + 0x1500)
+#define RUBY_SPI_READ_SPB               (RUBY_SPI_BASE_ADDR + 0xE200)
+#define RUBY_SPI_WRITE_SPB              (RUBY_SPI_BASE_ADDR + 0xE300)
+#define RUBY_SPI_ERASE_SPB              (RUBY_SPI_BASE_ADDR + 0xE400)
+
+#define RUBY_SPI_WRITE_PASWORD          (RUBY_SPI_BASE_ADDR + 0x2800)
+#define RUBY_SPI_READ_PASSWORD			(RUBY_SPI_BASE_ADDR + 0x2700)
+#define RUBY_SPI_UNLOCK_PASSWORD		(RUBY_SPI_BASE_ADDR + 0x2900)
+#define RUBY_SPI_WRITE_SPBLOCK			(RUBY_SPI_BASE_ADDR + 0xA600)
+#define RUBY_SPI_READ_SPBLOCK			(RUBY_SPI_BASE_ADDR + 0xA700)
+
+/*
+ * UBOOT_VERSION_LOCATION:
+ * This is hardwired in u-boot's start.S; the first instruction generates a
+ * 32 bit branch instruction.  The next several locations holds a human
+ * readable ascii version string that is visible in the file and in memory.
+ * The branch target of the first instruction is the next 4 byte aligned
+ * address following the version string.
+ *
+ */
+#define UBOOT_VERSION_LOCATION		(RUBY_SPI_FLASH_ADDR + 4)
+
+/*****************************************************************************/
+/* SPI constants                                                             */
+/*****************************************************************************/
+#define RUBY_SPI_WR_IN_PROGRESS		(RUBY_BIT(0))
+#define RUBY_SPI_PROTECTION		(0x3C)
+
+/*****************************************************************************/
+/* SPI1 registers                                                             */
+/*****************************************************************************/
+#define RUBY_SPI1_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xF2000000, 0xE40A0000)
+#define RUBY_SPI1_SPCR			(RUBY_SPI1_BASE_ADDR + 0x0000)
+#define RUBY_SPI1_SPSR			(RUBY_SPI1_BASE_ADDR + 0x0004)
+#define RUBY_SPI1_SPDR			(RUBY_SPI1_BASE_ADDR + 0x0008)
+#define RUBY_SPI1_SPER			(RUBY_SPI1_BASE_ADDR + 0x000C)
+#define RUBY_SPI1_SLVN			(RUBY_SPI1_BASE_ADDR + 0x0010)
+/*****************************************************************************/
+/* SPI1 constants                                                            */
+/*****************************************************************************/
+#define RUBY_SPI1_SPCR_SPIE_BIT		7
+#define RUBY_SPI1_SPCR_SPIE		(RUBY_BIT(RUBY_SPI1_SPCR_SPIE_BIT))
+#define RUBY_SPI1_SPCR_SPE		(RUBY_BIT(6))
+#define RUBY_SPI1_SPCR_MSTR		(RUBY_BIT(4))
+#define RUBY_SPI1_SPCR_CPOL		(RUBY_BIT(3))
+#define RUBY_SPI1_SPCR_CPHA		(RUBY_BIT(2))
+#define RUBY_SPI1_SPCR_SPR(x)		((x) & 0x3)
+#define RUBY_SPI1_SPSR_SPIF		(RUBY_BIT(7))
+#define RUBY_SPI1_SPSR_WCOL		(RUBY_BIT(6))
+#define RUBY_SPI1_SPSR_WFFULL		(RUBY_BIT(3))
+#define RUBY_SPI1_SPSR_WFEMPTY		(RUBY_BIT(2))
+#define RUBY_SPI1_SPSR_RFFULL		(RUBY_BIT(1))
+#define RUBY_SPI1_SPSR_RFEMPTY		(RUBY_BIT(0))
+#define RUBY_SPI1_SPER_ICNT(x)		(((x) & 0x3) << 6)
+#define RUBY_SPI1_SPER_ESPR(x)		((x) & 0x3)
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* I2C constants                                                            */
+/*****************************************************************************/
+#define RUBY_I2C_BASE_ADDR			TOPAZ_ALIAS_MAP_SWITCH(0xF9000000, 0xE40F0000)
+#define RUBY_I2C_MEM_SIZE			(0x0A08)
+#define RUBY_I2C_ADAPTER_NUM		(0)
+
+/*****************************************************************************/
+/* Interrupts                                                                */
+/*****************************************************************************/
+#define RUBY_IRQ_RESET			(0)
+#define RUBY_IRQ_MEM_ERR		(1)
+#define RUBY_IRQ_INS_ERR		(2)
+#define RUBY_IRQ_CPUTIMER0		(3)
+#define RUBY_IRQ_CPUTIMER1		(4)
+#define RUBY_IRQ_WATCHDOG		(5)
+#define RUBY_IRQ_DMA0			(6)
+#define RUBY_IRQ_BB			(7)
+#define RUBY_IRQ_IPC_LO			(8)
+#define IRQ_MAC0_0			RUBY_IRQ_IPC_LO
+#define RUBY_IRQ_DSP			(9)
+#define RUBY_IRQ_IPC_HI			(10)
+#define RUBY_IRQ_MAC_TX_DONE		(11)
+#define RUBY_IRQ_MAC_TX_ALERT		(12)
+#define RUBY_IRQ_MAC_RX_DONE		(13)
+#define RUBY_IRQ_MAC_RX_TYPE		(14)
+#define RUBY_IRQ_MAC_MIB		(15)
+#define RUBY_IRQ_MAC_0			(16)
+#define RUBY_IRQ_MAC_1			(17)
+#define RUBY_IRQ_PCIE			(18)
+#define RUBY_IRQ_ENET0			(19)
+#define RUBY_IRQ_ENET1			(20)
+#define RUBY_IRQ_DMA1			(21)
+#define RUBY_IRQ_DMA2			(22)
+#define RUBY_IRQ_DMA3			(23)
+#define RUBY_IRQ_UART			(24)
+#define RUBY_IRQ_GPIO			(25)
+#define RUBY_IRQ_TIMER			(26)
+#define RUBY_IRQ_MISC			(27)
+/* Combined PCIe Interrupt IRQ 28 */
+#define RUBY_IRQ_MSI			(28)
+#define RUBY_IRQ_INTA			(28)
+/* Combined PCIe DMA Legacy/MSI Interrupt IRQ 22 */
+#define TOPAZ_IRQ_PCIE_DMA_INT		(22)
+#define TOPAZ_IRQ_PCIE_IPC4_INT		(29)
+/* Combined PCIe Legacy/MSI Interrupt IRQ 28 */
+#define TOPAZ_IRQ_PCIE_INT		RUBY_IRQ_INTA
+#define RUBY_IRQ_SPI			(30)
+#define RUBY_IRQ_BB_PER_PACKET		(31)
+#define RUBY_MAX_IRQ_VECTOR		(31)
+#define RUBY_IRQ_VECTORS_NUM		(RUBY_MAX_IRQ_VECTOR + 1)
+/* these are extended (shared) irqs */
+#define GPIO2IRQ(x)			((x) + RUBY_IRQ_GPIO0)
+#define RUBY_IRQ_GPIO0			(32)
+#define RUBY_IRQ_GPIO1			(33)
+#define RUBY_IRQ_GPIO2			(34)
+#define RUBY_IRQ_GPIO3			(35)
+#define RUBY_IRQ_GPIO4			(36)
+#define RUBY_IRQ_GPIO5			(37)
+#define RUBY_IRQ_GPIO6			(38)
+#define RUBY_IRQ_GPIO7			(39)
+#define RUBY_IRQ_GPIO8			(40)
+#define RUBY_IRQ_GPIO9			(41)
+#define RUBY_IRQ_GPIO10			(42)
+#define RUBY_IRQ_GPIO11			(43)
+#define RUBY_IRQ_GPIO12			(44)
+#define RUBY_IRQ_GPIO13			(45)
+#define RUBY_IRQ_GPIO14			(46)
+#define RUBY_IRQ_GPIO15			(47)
+#define RUBY_IRQ_UART0			(48)
+#define RUBY_IRQ_UART1			(49)
+#define RUBY_IRQ_TIMER0			(50)
+#define RUBY_IRQ_TIMER1			(51)
+#define RUBY_IRQ_TIMER2			(52)
+#define RUBY_IRQ_TIMER3			(53)
+#define RUBY_IRQ_MISC_I2C		(56)
+#define RUBY_IRQ_MISC_SRAM		(57)
+#define RUBY_IRQ_MISC_NETSS		(58)
+#define RUBY_IRQ_MISC_PLL1		(59)
+#define RUBY_IRQ_MISC_PLL2		(60)
+#define RUBY_IRQ_MISC_EXT_IRQ_COUNT		(5)
+#define RUBY_IRQ_MISC_EXT_IRQ_START		(56)
+#define RUBY_IRQ_MISC_RST_CAUSE_START	(26)
+
+#define QTN_IRQ_MISC_EXT_IRQ_COUNT		TOPAZ_IRQ_MISC_EXT_IRQ_COUNT
+#define QTN_IRQ_MISC_RST_CAUSE_START	TOPAZ_IRQ_MISC_RST_CAUSE_START
+
+#define RUBY_MAX_IRQ_EXT_VECTOR		(63)
+#define RUBY_IRQ_EXT_VECTORS_NUM	(RUBY_MAX_IRQ_EXT_VECTOR + 1)
+
+/* M2L interrupt register is [31:16] high prio, [15:0] low prio */
+#define RUBY_M2L_IRQ_NUM_HI		(16)
+#define RUBY_M2L_IRQ_NUM_LO		(16)
+/* M2L High priority interrupts, sent to RUBY_IRQ_IPC_HI */
+#define RUBY_M2L_IRQ_HI_REBOOT		RUBY_M2L_IPC_HI_IRQ(13)
+#define RUBY_M2L_IRQ_HI_DIE		RUBY_M2L_IPC_HI_IRQ(14)
+/* M2L Low priority interrupts, sent to RUBY_IRQ_IPC_LO */
+#define RUBY_M2L_IRQ_LO_MEAS		(8)
+#define RUBY_M2L_IRQ_LO_OCAC		(9)
+#define RUBY_M2L_IRQ_LO_CSA		(10)
+#define RUBY_M2L_IRQ_LO_SCS		(11)
+#define RUBY_M2L_IRQ_LO_SCAN		(12)
+#define RUBY_M2L_IRQ_LO_VSP		(13)
+#define RUBY_M2L_IRQ_LO_PRINT		(14)
+#define RUBY_M2L_IRQ_LO_HLINK		(15)
+
+/* these are DSP interrupts */
+#define RUBY_DSP_IRQ_TIMER0		(3)
+#define RUBY_DSP_IRQ_TIMER1		(5)
+#define RUBY_DSP_IRQ_IPC_MUC2DSP	(10)
+#define RUBY_DSP_IRQ_IPC_LHOST2DSP	(11)
+#define RUBY_DSP_IRQ_IPC_MUC2DSP_HI	(17)
+#define RUBY_DSP_IRQ_WMAC_COMBINED	(20)
+
+/* M2D High priority interrupts, sent to RUBY_DSP_IRQ_IPC_MUC2DSP_HI */
+#define RUBY_M2D_IRQ_HI_DIE		PLATFORM_REG_SWITCH(RUBY_IPC_HI_IRQ(7), 0)
+
+/* L2M Low priority interrupts */
+#define RUBY_L2M_IRQ_HLINK		(6)
+#define RUBY_L2M_IRQ_HIGH		(7)
+
+/*****************************************************************************/
+/*****************************************************************************/
+/* BB registers                                                             */
+/*****************************************************************************/
+#define RUBY_BB_BASE_ADDR			0xE6000000
+/* FIXME: no BB2 on Ruby - this should expand to something else */
+#define UMS_REGS_BB2				RUBY_BB_BASE_ADDR
+#define RUBY_QT3_BB_GLBL_PREG_RIF_ENABLE	(RUBY_BB_BASE_ADDR + 0x1F4)
+#define RUBY_QT3_BB_GLBL_PREG_RIF_ENABLE_ON	0x1
+#define RUBY_QT3_BB_GLBL_PREG_RIF_ENABLE_OFF	0x0
+#define RUBY_QT3_BB_GLBL_PREG_INTR_STATUS	(RUBY_BB_BASE_ADDR + 0x320)
+#define RUBY_QT3_BB_FFT_INTR			(0x1000)
+#define RUBY_QT3_BB_MIMO_PREG_RX_IPG_RST_ENABLE	(RUBY_BB_BASE_ADDR + 0x50268)
+#define RUBY_QT3_BB_MIMO_BF_RX			(RUBY_BB_BASE_ADDR + 0x501FC)
+#define RUBY_QT3_BB_MIMO_BF_RX_DUMP_ENABLE	(1 << 1) /*11n HT-LF dump enable*/
+
+#define RUBY_QT3_BB_GLBL_SOFT_RST		(RUBY_BB_BASE_ADDR + 0x0008)
+#define RUBY_QT3_BB_GLBL_SPI_CTRL		(RUBY_BB_BASE_ADDR + 0x0024)
+#define RUBY_QT3_BB_TD_BASE_ADDR		(RUBY_BB_BASE_ADDR + 0x90000)
+
+#define RUBY_QT3_BB_RF1_BASE_ADDR		0xE6080000
+#define RUBY_QT3_BB_BONDING_4SS			0x01
+
+#define RUBY_QT3_BB_TD_SPARE_0			(RUBY_QT3_BB_TD_BASE_ADDR + 0x5f4)
+#define RUBY_QT3_BB_TD_SPARE_1			(RUBY_QT3_BB_TD_BASE_ADDR + 0x5f8)
+#define RUBY_QT3_BB_TD_MAX_GAIN			(RUBY_QT3_BB_TD_BASE_ADDR + 0x36c)
+
+/*****************************************************************************/
+/* Radar registers                                                           */
+/*****************************************************************************/
+#define RUBY_RADAR_CNT_L	0xE6090558
+
+/*****************************************************************************/
+/* ARC addresses                                                             */
+/*****************************************************************************/
+#define RUBY_ARC_TLB_BYPASS	0x80000000
+#define RUBY_ARC_CACHE_BYPASS	0xC0000000
+
+/*****************************************************************************/
+/*               DMA registers and bit defines.                              */
+/*****************************************************************************/
+#define RUBY_DMA_NUM_CHANNELS	(4)
+#define RUBY_DMA_BASE_ADDR		TOPAZ_ALIAS_MAP_SWITCH(0xEA000000, 0xE4060000)
+#define	RUBY_DMA_SAR(x)			(RUBY_DMA_BASE_ADDR + 0x00 + (x)*0x58)
+#define	RUBY_DMA_DAR(x)			(RUBY_DMA_BASE_ADDR + 0x08 + (x)*0x58)
+#define	RUBY_DMA_LLP(x)			(RUBY_DMA_BASE_ADDR + 0x10 + (x)*0x58)
+#define	RUBY_DMA_CTL(x)			(RUBY_DMA_BASE_ADDR + 0x18 + (x)*0x58)
+#define	RUBY_DMA_SIZE(x)		(RUBY_DMA_BASE_ADDR + 0x1c + (x)*0x58)
+#define	RUBY_DMA_SSTAT(x)		(RUBY_DMA_BASE_ADDR + 0x20 + (x)*0x58)
+#define	RUBY_DMA_DSTAT(x)		(RUBY_DMA_BASE_ADDR + 0x28 + (x)*0x58)
+#define	RUBY_DMA_SSTATAR(x)		(RUBY_DMA_BASE_ADDR + 0x30 + (x)*0x58)
+#define	RUBY_DMA_DSTATAR(x)		(RUBY_DMA_BASE_ADDR + 0x38 + (x)*0x58)
+#define	RUBY_DMA_CFG(x)			(RUBY_DMA_BASE_ADDR + 0x40 + (x)*0x58)
+#define	RUBY_DMA_SGR(x)			(RUBY_DMA_BASE_ADDR + 0x48 + (x)*0x58)
+#define	RUBY_DMA_DSR(x)			(RUBY_DMA_BASE_ADDR + 0x50 + (x)*0x58)
+
+#define RUBY_DMA_MASK_BLK		(RUBY_DMA_BASE_ADDR + 0x318)
+#define RUBY_DMA_BLK_CLR		(RUBY_DMA_BASE_ADDR + 0x340)
+#define RUBY_DMA_DMA_CFG		(RUBY_DMA_BASE_ADDR + 0x398)
+#define RUBY_DMA_CH_EN			(RUBY_DMA_BASE_ADDR + 0x3a0)
+/************** RUBY_DMA_CTL(x) bit defines. *********************************/
+#define RUBY_DMA_CTL_INT_EN		RUBY_BIT(0)
+#define RUBY_DMA_CTL_DINC		(0)
+#define RUBY_DMA_CTL_DDEC		RUBY_BIT(7)
+#define RUBY_DMA_CTL_DNOCHNG		RUBY_BIT(8)
+#define RUBY_DMA_CTL_SINC		(0)
+#define RUBY_DMA_CTL_SDEC		RUBY_BIT(9)
+#define RUBY_DMA_CTL_SNOCHNG		RUBY_BIT(10)
+#define RUBY_DMA_CTL_DMS_LHOST		(0)
+#define RUBY_DMA_CTL_DMS_MUC		RUBY_BIT(23)
+#define RUBY_DMA_CTL_SMS_LHOST		(0)		// ahb master bus 1
+#define RUBY_DMA_CTL_SMS_MUC		RUBY_BIT(25)	// ahb master bus 2
+
+/************** RUBY_DMA_CFG(x) bit defines. *********************************/
+#define RUBY_DMA_CFG_ENABLE		RUBY_BIT(0)
+
+/*****************************************************************************/
+/* PCI registers & memory regions for target driver.                         */
+/*****************************************************************************/
+#define RUBY_PCIE_REG_BASE			TOPAZ_ALIAS_MAP_SWITCH(0xE9000000, 0xE4050000)
+#define RUBY_PCIE_CONFIG_REGION			(0xCF000000)
+
+#define RUBY_PCIE_CMD_REG			(RUBY_PCIE_REG_BASE + 0x0004)
+#define RUBY_PCIE_BAR_NUM			(6)
+#define	RUBY_PCIE_BAR_BASE			(RUBY_PCIE_REG_BASE + 0x0010)
+#define	RUBY_PCIE_BAR(n)			(RUBY_PCIE_BAR_BASE + (n << 2))
+#define	RUBY_PCIE_BAR_MASK_ADDR			(RUBY_PCIE_REG_BASE + 0x1010)
+#define	RUBY_PCIE_BAR_MASK(n)			(RUBY_PCIE_BAR_MASK_ADDR + (n << 2))
+
+#define RUBY_PCIE_ATU_VIEW			(RUBY_PCIE_REG_BASE + 0x0900)
+#define RUBY_PCIE_ATU_CTL1			(RUBY_PCIE_REG_BASE + 0x0904)
+#define RUBY_PCIE_ATU_CTL2			(RUBY_PCIE_REG_BASE + 0x0908)
+#define RUBY_PCIE_ATU_BASE_LO			(RUBY_PCIE_REG_BASE + 0x090c)
+#define RUBY_PCIE_ATU_BASE_HI			(RUBY_PCIE_REG_BASE + 0x0910)
+#define RUBY_PCIE_ATU_BASE_LIMIT		(RUBY_PCIE_REG_BASE + 0x0914)
+#define RUBY_PCIE_ATU_TARGET_LO			(RUBY_PCIE_REG_BASE + 0x0918)
+#define RUBY_PCIE_ATU_TARGET_HI			(RUBY_PCIE_REG_BASE + 0x091c)
+
+#define RUBY_PCIE_ATU_OB_REGION(n)		(0x0 + n)
+#define RUBY_PCIE_ATU_IB_REGION(n)		(0x80000000 + n)
+#define RUBY_PCIE_ATU_CFG_SHIFT			RUBY_BIT(28)
+#define RUBY_PCIE_ATU_OB_ENABLE			RUBY_BIT(31)
+
+#define RUBY_PCI_RC_MEM_WINDOW			(32 << 20) /* 32MB  MEMORY window in Root Complex for pcie tree  */
+#define RUBY_PCI_RC_CFG_SIZE			(64 << 10) /* 64KB  CFG size in Root Complex for pcie tree */
+#define RUBY_PCI_RC_MEM_START			(0xc0000000) /* PCI memory region in Root Complex's kernel address space */
+
+#define RUBY_PCIE_INT_MASK			(RUBY_SYS_CTL_BASE_ADDR + 0xC0)
+#define RUBY_PCIE_MSI_ENABLE			RUBY_BIT(16)
+#define MSI_CTL_OFFSET				(0x50)
+#define RUBY_MSI_ADDR_LOWER			(RUBY_PCIE_REG_BASE + 0x820)
+#define RUBY_MSI_ADDR_UPPER			(RUBY_PCIE_REG_BASE + 0x824)
+#define RUBY_MSI_INT_ENABLE			(RUBY_PCIE_REG_BASE + 0x828)
+#define RUBY_PCIE_MSI_MASK			(RUBY_PCIE_REG_BASE + 0x82c)
+#define RUBY_PCIE_MSI_STATUS			(RUBY_PCIE_REG_BASE + 0x830)
+#define RUBY_PCIE_MSI_REGION			(0xce000000) /* msi message address */
+#define RUBY_MSI_DATA				(0x0)	     /* msi message data */
+#define RUBY_PCIE_MSI_CLEAR			RUBY_BIT(0)  /* clear msi intr */
+
+#define TOPAZ_PCIE_STAT				(RUBY_SYS_CTL_BASE_ADDR + 0x017C)
+#if TOPAZ_FPGA_PLATFORM
+	#define TOPAZ_PCIE_LINKUP		(0xe)
+#else
+	#define TOPAZ_PCIE_LINKUP		(0x7)
+#endif
+
+#define PCIE_LINK_STAT				(RUBY_PCIE_REG_BASE + 0x80)
+#define PCIE_LINK_CTL2				(RUBY_PCIE_REG_BASE + 0xa0)
+#define PCIE_ASPM_L1_CTRL			(RUBY_PCIE_REG_BASE + 0x70c)
+#define PCIE_ASPM_LINK_CTRL			(PCIE_LINK_STAT)
+#define PCIE_PORT_LINK_CTL			(RUBY_PCIE_REG_BASE + 0x710)
+#define PCIE_ASPM_L1_SUBSTATE_TIMING		(RUBY_PCIE_REG_BASE + 0xB44)
+#define PCIE_L1SUB_CTRL1			(RUBY_PCIE_REG_BASE + 0x150)
+#define PCIE_PMCSR				(RUBY_PCIE_REG_BASE + 0x44)
+
+/* PCIe link defines */
+#define PCIE_LINK_GEN1				(BIT(0))
+#define PCIE_LINK_GEN2				(BIT(1))
+#define PCIE_LINK_GEN3				(BIT(2))
+#define PCIE_LINK_MODE(x)			(((x) >> 16) & 0x7)
+
+/* ATU setting for Host Buffer Descriptor Mapping */
+#define PCIE_HOSTBD_REGION			(RUBY_PCIE_ATU_OB_REGION(2))
+#define PCIE_ATU_BAR_MIN_SIZE			0x00010000 /* 64k */
+#define PCIE_HOSTBD_SIZE			(2 * PCIE_ATU_BAR_MIN_SIZE)
+#define PCIE_HOSTBD_SIZE_MASK			(PCIE_HOSTBD_SIZE - 1)
+#define PCIE_HOSTBD_START_HI			0x00000000
+#define PCIE_HOSTBD_REGION_ENABLE		RUBY_PCIE_ATU_OB_ENABLE
+
+/* Extra system controller bits */
+#define TOPAZ_SYS_CTL_PLLCLKOUT_EN		(RUBY_BIT(10))
+
+/* Board platform and revision */
+#define TOPAZ_BOARD_REVA			0x40
+#define TOPAZ_BOARD_REVB			0x41
+#define TOPAZ_BOARD_REVA2			0x43
+
+/*
+ * WOWLAN GPIO assignment
+ * On RGMII module - GPIO_B_10 (set as output for WoWLAN)
+ * On RGMII host board - GPIO_B_10 (set as input to wake up the host)
+ *
+ * On PCIe module - WAKE# or GPIO_B_12 ( set as output for WoWLAN, use WAKE# by default)
+ * On PCIe host board - GPIO_B_14 (set as input to wake up the host)
+ */
+#ifdef CONFIG_TOPAZ_PCIE_TARGET
+#define WOWLAN_GPIO_OUTPUT_PIN	12
+#else
+#define WOWLAN_GPIO_OUTPUT_PIN	10
+#endif
+#endif // #ifndef __RUBY_PLATFORM_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm.h
new file mode 100644
index 0000000..be4cc2f
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm.h
@@ -0,0 +1,162 @@
+/*
+ * (C) Copyright 2012 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __RUBY_PM_H
+#define __RUBY_PM_H
+
+/* Power save levels */
+#define BOARD_PM_LEVEL_FORCE_NO			(0)
+#define BOARD_PM_LEVEL_NO			(1)
+#define BOARD_PM_LEVEL_SLOW_DOWN		(2)
+#define BOARD_PM_LEVEL_LATENCY_UP		(3)
+#define BOARD_PM_LEVEL_DISTANCE_DOWN		(4)
+#define BOARD_PM_LEVEL_IDLE			(5)
+#define BOARD_PM_LEVEL_SUSPEND			(6)
+
+#define BOARD_PM_LEVEL_INIT			BOARD_PM_LEVEL_FORCE_NO
+
+/* Duty level, shared between Lhost and MuC */
+#define BOARD_PM_LEVEL_DUTY			BOARD_PM_LEVEL_IDLE
+
+/* Names of power save governors */
+#define BOARD_PM_GOVERNOR_WLAN			"wlan"
+#define BOARD_PM_GOVERNOR_QDISC			"qdisc"
+#define BOARD_PM_GOVERNOR_QCSAPI		"qcsapi"
+
+/* wlan timings to switch between modes */
+#define BOARD_PM_WLAN_IDLE_TIMEOUT		(120 * HZ)
+#define BOARD_PM_WLAN_STA_IDLE_TIMEOUT		(15 * HZ)
+#define BOARD_PM_WLAN_DEFAULT_TIMEOUT		(0)
+#define BOARD_PM_WLAN_AP_IDLE_AFTER_BEACON_SCHEME	(50 * HZ)
+/* qdisc parameters to switch between modes */
+#define BOARD_PM_QDISC_TIMER_TIMEOUT		(50/*ms*/ * HZ / 1000)
+#define BOARD_PM_QDISC_SPEEDUP_THRESHOLD	(400)
+#define BOARD_PM_QDISC_SLOWDOWN_THRESHOLD	(100)
+#define BOARD_PM_QDISC_SLOWDOWN_COUNT		(80)
+#define BOARD_PM_QDISC_SLOWDOWN_TIMEOUT		(3 * HZ)
+#define BOARD_PM_QDISC_DEFAULT_TIMEOUT		(0)
+
+/* Beacon TSF setting */
+#define BOARD_PM_WAKE_BEACON_TSF_DEADLINE_PCT		(50)
+#define BOARD_PM_WAKE_BEACON_TSF_ALERT_PCT		(25)
+
+/* Default setting, shared between Lhost and MuC */
+#define BOARD_PM_PDUTY_PERIOD_MS_DEFAULT		80
+#define BOARD_PM_PDUTY_PCT_LOW_DEFAULT			80
+#define BOARD_PM_SUSPEND_PERIOD_MS_DEFAULT		100
+#define BOARD_PM_SUSPEND_PCT_LOW_DEFAULT		99
+
+/* Multiple Periods Support */
+#define BOARD_PM_PERIOD_CHANGE_INTERVAL			1
+#define BOARD_PM_PERIOD_CNT			3
+
+enum qtn_pm_param {
+	QTN_PM_CURRENT_LEVEL,
+
+	QTN_PM_SUSPEND,
+	QTN_PM_SUSPEND_PERIOD_MS,
+	QTN_PM_SUSPEND_PCT_LOW,
+	QTN_PM_SUSPEND_HRESET,
+	QTN_PM_SUSPEND_ALLCHAINS_DISABLE,
+
+	QTN_PM_PDUTY,
+	QTN_PM_PDUTY_PERIOD_MS,
+	QTN_PM_PDUTY_PCT_LOW,
+	QTN_PM_PDUTY_HRESET,
+	QTN_PM_PDUTY_RXCHAINS_DISABLE,
+
+	QTN_PM_MUC_SLEEP,
+
+	QTN_PM_RXCHAIN_IDLE_COUNT,
+	QTN_PM_RXCHAIN_IDLE_LEVEL,
+	QTN_PM_TXCHAIN_IDLE_COUNT,
+	QTN_PM_TXCHAIN_IDLE_LEVEL,
+
+	QTN_PM_PAUSE_MGMT_PROBERESP,
+	QTN_PM_PAUSE_MGMT_ASSOCRESP,
+	QTN_PM_PAUSE_MGMT_AUTH,
+	QTN_PM_PAUSE_DATA = QTN_PM_PAUSE_MGMT_AUTH,
+
+	/* For Multiple Periods Support */
+	QTN_PM_PERIOD_CHANGE_INTERVAL,	/* How long period setting will be changed(unit: second) */
+	QTN_PM_PERIOD_CNT,	/* How many periods in period group(Max 3) */
+	QTN_PM_PERIOD_GROUP,	/* Period group(Max 3 periods, each <= 255ms, unit: millisecond)*/
+
+	QTN_PM_IOCTL_MAX
+};
+
+#define QTN_PM_PARAM_NAMES	{						\
+	"level",			/* QTN_PM_CURRENT_LEVEL */		\
+	"suspend_level",		/* QTN_PM_SUSPEND */			\
+	"suspend_period",		/* QTN_PM_SUSPEND_PERIOD_MS */		\
+	"suspend_pct",			/* QTN_PM_SUSPEND_PCT_LOW */		\
+	"suspend_hreset",		/* QTN_PM_SUSPEND_HRESET */		\
+	"suspend_allchains",		/* QTN_PM_SUSPEND_ALLCHAINS_DISABLE */	\
+	"pduty_level",			/* QTN_PM_PDUTY */			\
+	"pduty_period",			/* QTN_PM_PDUTY_PERIOD_MS */		\
+	"pduty_pct",			/* QTN_PM_PDUTY_PCT_LOW */		\
+	"pduty_hreset",			/* QTN_PM_PDUTY_HRESET */		\
+	"pduty_rxchains",		/* QTN_PM_PDUTY_RXCHAINS_DISABLE */	\
+	"muc_sleep_level",		/* QTN_PM_MUC_SLEEP */			\
+	"rxchain_count",		/* QTN_PM_RXCHAIN_IDLE_COUNT */		\
+	"rxchain_level",		/* QTN_PM_RXCHAIN_IDLE_LEVEL */		\
+	"txchain_count",		/* QTN_PM_TXCHAIN_IDLE_COUNT */		\
+	"txchain_level",		/* QTN_PM_TXCHAIN_IDLE_LEVEL */		\
+	"pause_proberesp",		/* QTN_PM_PAUSE_MGMT_PROBERESP */	\
+	"pause_assocresp",		/* QTN_PM_PAUSE_MGMT_ASSOCRESP */	\
+	"pause_auth",			/* QTN_PM_PAUSE_MGMT_ASSOCRESP */	\
+	"period_change_interval",	/* QTN_PM_PERIOD_CHANGE_INTERVAL */	\
+	"period_cnt",			/* QTN_PM_PERIOD_CNT */	\
+	"period_group"			/* QTN_PM_PERIOD_GROUP */	\
+}
+
+#define QTN_PM_PARAM_DEFAULTS	{							\
+	BOARD_PM_LEVEL_INIT,			/* QTN_PM_CURRENT_LEVEL */		\
+	BOARD_PM_LEVEL_SUSPEND,			/* QTN_PM_SUSPEND */			\
+	BOARD_PM_SUSPEND_PERIOD_MS_DEFAULT,	/* QTN_PM_SUSPEND_PERIOD_MS */		\
+	BOARD_PM_SUSPEND_PCT_LOW_DEFAULT,	/* QTN_PM_SUSPEND_PCT_LOW */		\
+	1,					/* QTN_PM_SUSPEND_HRESET */		\
+	1,					/* QTN_PM_SUSPEND_ALL_CHAINS_DISABLE */	\
+	BOARD_PM_LEVEL_DUTY,			/* QTN_PM_PDUTY */			\
+	BOARD_PM_PDUTY_PERIOD_MS_DEFAULT,	/* QTN_PM_PDUTY_PERIOD_MS */		\
+	BOARD_PM_PDUTY_PCT_LOW_DEFAULT,		/* QTN_PM_PDUTY_PCT_LOW */		\
+	0,					/* QTN_PM_PDUTY_HRESET */		\
+	1,					/* QTN_PM_PDUTY_RXCHAINS_DISABLE */	\
+	BOARD_PM_LEVEL_LATENCY_UP,		/* QTN_PM_MUC_SLEEP */			\
+	4,					/* QTN_PM_RXCHAIN_IDLE_COUNT */		\
+	BOARD_PM_LEVEL_DISTANCE_DOWN,		/* QTN_PM_RXCHAIN_IDLE_LEVEL */		\
+	4,					/* QTN_PM_TXCHAIN_IDLE_COUNT */		\
+	BOARD_PM_LEVEL_DISTANCE_DOWN,		/* QTN_PM_TXCHAIN_IDLE_LEVEL */		\
+	60000,					/* QTN_PM_PAUSE_MGMT_PROBERESP */	\
+	5000,					/* QTN_PM_PAUSE_MGMT_ASSOCRESP */	\
+	5000,					/* QTN_PM_PAUSE_MGMT_AUTH */		\
+	BOARD_PM_PERIOD_CHANGE_INTERVAL,	/* QTN_PM_PERIOD_CHANGE_INTERVAL */	\
+	BOARD_PM_PERIOD_CNT,			/* QTN_PM_PERIOD_CNT */	\
+	0x50321E				/* QTN_PM_PERIOD_GROUP(30ms, 50ms, 80ms) */	\
+}
+
+#define QTN_PM_UNPACK_PARAM(x)		((x) & 0xFF)
+#define QTN_PM_UNPACK_VALUE(x)		((x) >> 8)
+#define QTN_PM_PACK_PARAM_VALUE(p, v)	(((p) & 0xFF) | (((v) << 8) & 0xFFFFFF00))
+
+#endif /* __RUBY_PM_H */
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm_mproc.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm_mproc.h
new file mode 100644
index 0000000..869303c
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_pm_mproc.h
@@ -0,0 +1,75 @@
+/*
+ * (C) Copyright 2012 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __RUBY_PM_MPROC_H
+#define __RUBY_PM_MPROC_H
+
+#if defined(__KERNEL__) || defined(MUC_BUILD)
+	#include <qtn/mproc_sync.h>
+	#include "ruby_pm.h"
+
+#if QTN_SEM_TRACE
+#define qtn_pm_duty_try_lock(_cpu) qtn_pm_duty_try_lock_dbg(_cpu, __FILE__, __LINE__)
+	RUBY_WEAK(qtn_pm_duty_try_lock_dbg) int
+	qtn_pm_duty_try_lock_dbg(QTN_SOC_CPU current_cpu, char *caller, int caller_line)
+#else
+	RUBY_WEAK(qtn_pm_duty_try_lock) int
+	qtn_pm_duty_try_lock(QTN_SOC_CPU current_cpu)
+#endif
+	{
+		int ret = 0;
+		unsigned long flags;
+		uint32_t fail_sem = 0;
+
+		if (__qtn_mproc_sync_spin_try_lock(current_cpu, QTN_ALL_SOC_CPU, QTN_SEM_BB_MUTEX_SEMNUM, &flags, &fail_sem)) {
+			u_int32_t lock = qtn_mproc_sync_addr(&qtn_mproc_sync_shared_params_get()->pm_duty_lock);
+			if (!qtn_mproc_sync_mem_read(lock)) {
+				qtn_mproc_sync_mem_write_wmb(lock, 1);
+				ret = 1;
+			}
+			__qtn_mproc_sync_spin_unlock(current_cpu, QTN_ALL_SOC_CPU, QTN_SEM_BB_MUTEX_SEMNUM, &flags);
+		}
+
+		return ret;
+	}
+
+#if QTN_SEM_TRACE
+#define qtn_pm_duty_unlock(_cpu) qtn_pm_duty_unlock_dbg(_cpu, __FILE__, __LINE__)
+	RUBY_WEAK(qtn_pm_duty_unlock_dbg) void
+	qtn_pm_duty_unlock_dbg(QTN_SOC_CPU current_cpu, char *caller, int caller_line)
+#else
+	RUBY_WEAK(qtn_pm_duty_unlock) void
+	qtn_pm_duty_unlock(QTN_SOC_CPU current_cpu)
+#endif
+	{
+		u_int32_t lock = qtn_mproc_sync_addr(&qtn_mproc_sync_shared_params_get()->pm_duty_lock);
+		unsigned long flags;
+
+		__qtn_mproc_sync_spin_lock(current_cpu, QTN_ALL_SOC_CPU, QTN_SEM_BB_MUTEX_SEMNUM, &flags);
+		qtn_mproc_sync_mem_write_wmb(lock, 0);
+		__qtn_mproc_sync_spin_unlock(current_cpu, QTN_ALL_SOC_CPU, QTN_SEM_BB_MUTEX_SEMNUM, &flags);
+	}
+
+#endif	// defined(__KERNEL__) || defined(MUC_BUILD)
+
+#endif /* __RUBY_PM_MPROC_H */
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_api.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_api.h
new file mode 100644
index 0000000..e4a7c34
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_api.h
@@ -0,0 +1,147 @@
+/*
+ *(C) Copyright 2014 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __RUBY_SPI_API_H__
+#define __RUBY_SPI_API_H__
+
+/*
+ * Swap bytes
+ */
+
+#define SWAP32(x)	((((x) & 0x000000ff) << 24)  | \
+			(((x)  & 0x0000ff00) << 8)   | \
+			(((x)  & 0x00ff0000) >> 8)   | \
+			(((x)  & 0xff000000) >> 24))
+
+
+#define SPI_WR_IN_PROGRESS	(BIT(0))
+#define SPI_SR_QUAD_MODE	(BIT(6))
+#define SPI_SCUR_WPSEL		(BIT(7))
+#define SPI_PROTECTION		(0x3c)
+#define SPI_WPS_SELECT		(0x4)
+#define SPI_SECTOR_SIZE_4K	4
+#define ADDRESS_MASK		(0x0fffffff)
+#define SPI_WRITE_DELAY         (9)
+#define SPI_FLASH_ADDR		(0x90000000)
+#define SECTOR_MASK		(0x01ffff00)
+#define SECTOR_ERASE_WAIT_TIME	(90)
+#define CHIP_ERASE_WAIT_TIME	(50)
+#define SPI_WRITE_TIMEOUT       (1) /*sec*/
+#define SPI_ERASE_TIMEOUT       (5) /*sec*/
+#define SPI_UNLOCK_TIMEOUT      (5) /*sec*/
+#define MX_25L12805_ID		(0xc22018)
+#define MX_25L25635_ID		(0xc22019)
+#define MX_25L6405_ID		(0xc22017)
+#define M25P32_ID		(0x202016)
+#define W25Q128_ID		(0xef4018)
+#define	MX25L512E		(0xc22010)
+#define S25FL129P		(0x012018)
+#define SPI_SECTOR_64K		(64 * 1024)
+#define SPI_SECTOR_COUNT_256	(256)
+#define SPI_SECTOR_4K		(4 * 1024)
+#define SPI_SECTOR_COUNT_4K	(4 * 1024)
+#define SPI_SECTOR_INDEX	(16)
+#define SPI_SR_QUAD_MODE_MASK(X)	(((X) & 0xfffff0ff) | (2<<8))
+#define SPI_SR_SINGLE_MODE_MASK(X)	((X) & 0xfffff0ff)
+#define RUBY_SPI_READ_SCUR_MASK(X)	(((X) & 0xffffff00) | 2)
+#define RUBY_SPI_READ_DPB_MASK(X)	(((X) & 0xffffff00) | 0x86)
+#define RUBY_SPI_GBLOCK_LOCK_MASK(X)	(((X) & 0xffffff00) | 0x1)
+#define RUBY_SPI_GBLOCK_UNLOCK_MASK(X)	(((X) & 0xffffff00) | 0x1)
+#define RUBY_SPI_WRITE_PRO_SEL_MASK(X)	(((X) & 0xffffff00) | 1)
+#define RUBY_SPI_WRITE_WPS_SEL_MASK(X)	(((X) & 0xffffff00) | 2)   /* writing 2 bytes */
+#define RUBY_SPI_WRITE_DPB_MASK(X)	(((X) & 0xffffff00) | 0x86)
+#define RUBY_SPI_WRITE_IBUP_MASK(X)	(((X) & 0xffffff00) | 0x06)
+#define RUBY_SPI_WRITE_WPS_MASK(X)	(((X) & 0xffffff00) | 0x64)
+#define RUBY_SPI_READ_ID_MASK		(0xffffff)
+#define RUBY_SPI_READ_STATUS_MASK	(0xff)
+#define SECTOR_ERASE_OP20		(0x02)
+#define SPI_WPS_ENABLE			(0x00640000)
+#define SPI_PROTECT_MODE		"spi_protect"
+#define SPI_PROTECT_MODE_STR		17
+#define SPI_PROTECT_MODE_ENABLE		"enable"
+#define SPI_PROTECT_MODE_FLAG_DISABLE	1
+#define SPI_PROTECT_MODE_FLAG_ENABLE	0
+
+#define RUBY_SPI_PASS_CMD_MASK(X)	(((X) & 0xfffffff0) | 0x1)
+#define RUBY_SPI_PASS_ONE_MASK(X)	(((X) & 0xfffffff0) | 0x2)
+#define RUBY_SPI_PASS_TWO_MASK(X)	(((X) & 0xfffffff0) | 0x3)
+#define RUBY_SPI_PASS_FOUR_MASK(X)	(((X) & 0xfffffff0) | 0x5)
+#define RUBY_SPI_PASS_EIGHT_MASK(X)	(((X) & 0xfffffff0) | 0x9)
+#define RUBY_SPI_PASS_FIVE_MASK(X)	(((X) & 0xfffffff0) | 0x6)
+#define RUBY_SPI_PASS_ONE_ADDR_MASK(X)	(((X) & 0xfffffff0) | 0x6)
+#define RUBY_SPI_CMD_MASK(X)		(((X) & 0xff) << 8)
+#define RUBY_SPI_READ_DATA_MASK		(0xff)
+#define SPI_LOCK_SPM		(BIT(1))
+#define SPI_LOCK_PPM		(BIT(2))
+#define SPI_LOCK_SPMOTP		(BIT(3))
+
+#define SPI_MICRON_STATUS_BP_MASK		(BIT(6)|BIT(4)|BIT(3)|BIT(2))
+#define SPI_MICRON_BP_STATUS(X)			((X & 1<<3)<<3 |(X & 7<<0)<<2 )
+#define SPI_MICRON_STATUS_BP(X)			((X & 1<<6)>>3 |(X & 7<<2)>>2 )
+#define SPI_MICRON_STATUS_LOCK_MASK		(BIT(7))
+#define SPI_MICRON_STATUS_BOTTON_MASK	(BIT(5))
+
+/*
+*
+* Ruby uses 3 msb bytes to form addresses.
+* Topaz uses all 4 bytes, just skip first msb if in 3-bytes address mode.
+*
+*/
+#define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF))
+#define SPI_MEM_ADDR_4B(addr)	(((addr) & 0xFFFFFFFF))
+
+enum SPI_TYPES{
+	NOT_SUPPORTED,
+	ATMEL,
+	SPANSION,
+	SST,
+	ST_MICROELECTRONICS,
+	WINBOND,
+	MACRONIX,
+	ESMT,
+	EON,
+	MICRON,
+	GD
+};
+
+struct flash_info {
+	char *name;
+	/* JEDEC id zero means "no ID" (most older chips); otherwise it has
+	 * a high byte of zero plus three data bytes: the manufacturer id,
+	 * then a two byte device id.
+	 */
+	u32 jedec_id;
+
+	/* The size listed here is what works with OPCODE_SE, which isn't
+	 * necessarily called a "sector" by the vendor.
+	 */
+	unsigned sector_size;
+	u16 n_sectors;
+
+	u16 flags;
+
+	unsigned freq;
+	enum SPI_TYPES single_unprotect_mode;
+};
+
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_flash_data.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_flash_data.h
new file mode 100644
index 0000000..15cf2e7
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_spi_flash_data.h
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * MTD SPI driver for ST M25Pxx (and similar) serial flash chips
+ *
+ * Author: Mike Lavender, mike@steroidmicros.com
+ *
+ * Copyright (c) 2005, Intec Automation Inc.
+ *
+ * Some parts are based on lart.c by Abraham Van Der Merwe
+ *
+ * Cleaned up and generalized based on mtd_dataflash.c
+ *
+ * This code 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.
+ *
+ */
+
+
+/*****************************************************
+ * Structure definitions as well as data was borrowed
+ * from Linux kernel, 2.6.30 version.
+ * File name is drivers/mtd/devices/m25p80.c
+ */
+
+#ifndef __SPI_FLASH_DATA_H
+#define __SPI_FLASH_DATA_H
+
+#include "ruby_spi_api.h"
+
+#define FREQ_UNKNOWN		0
+#define FREQ_MHZ(num)		(num * 1000000)
+
+/* NOTE: double check command sets and memory organization when you add
+ * more flash chips.  This current list focusses on newer chips, which
+ * have been converging on command sets which including JEDEC ID.
+ */
+
+static struct flash_info flash_data [] = {
+
+	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
+	{ "at25fs010", 0x1f6601, 32 * 1024, 4, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at25fs040", 0x1f6604, 64 * 1024, 8, 0, FREQ_UNKNOWN, ATMEL, },
+
+	{ "at25df041a", 0x1f4401, 64 * 1024, 8, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at25df641", 0x1f4800, 64 * 1024, 128, 0, FREQ_UNKNOWN, ATMEL, },
+
+	{ "at26f004", 0x1f0400, 64 * 1024, 8, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at26df081a", 0x1f4501, 64 * 1024, 16, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at26df161a", 0x1f4601, 64 * 1024, 32, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at26df321",  0x1f4701, 64 * 1024, 64, 0, FREQ_UNKNOWN, ATMEL, },
+	{ "at25f512b",  0x1f6500,  4 * 1024, 16, SECTOR_ERASE_OP20, FREQ_MHZ(50), ATMEL, },
+
+	/* Spansion -- single (large) sector size only, at least
+	 * for the chips listed here (without boot sectors).
+	 */
+	{ "s25sl004a", 0x010212, 64 * 1024, 8, 0, FREQ_UNKNOWN, SPANSION },
+	{ "s25sl008a", 0x010213, 64 * 1024, 16, 0, FREQ_UNKNOWN, SPANSION },
+	{ "s25sl016a", 0x010214, 64 * 1024, 32, 0, FREQ_UNKNOWN, SPANSION },
+	{ "s25fl032", 0x010215, 64 * 1024, 64, 0, FREQ_UNKNOWN, SPANSION },
+	{ "s25sl064a", 0x010216, 64 * 1024, 128, 0, FREQ_UNKNOWN, SPANSION },
+	{ "s25sl12801", 0x012018, 64 * 1024, 256, 0, FREQ_MHZ(40), SPANSION }, /* S25FL129P has same jedec_id, but higher frequency - so it should be supported, but at not at maximum speed */
+	{ "s25fl256s", 0x010219, 64 * 1024, 512, 0, FREQ_UNKNOWN, SPANSION },
+
+	/* Micron */
+	{ "N25Q032", 0x20ba16, 64 * 1024, 64, 0, FREQ_UNKNOWN, MICRON },
+	{ "N25Q256", 0x20ba19, 64 * 1024, 512, 0, FREQ_MHZ(80), MICRON },
+
+	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
+	{ "sst25vf040b", 0xbf258d, 64 * 1024, 8, 0, FREQ_UNKNOWN, SST },
+	{ "sst25vf080b", 0xbf258e, 64 * 1024, 16, 0, FREQ_UNKNOWN, SST },
+	{ "sst25vf016b", 0xbf2541, 64 * 1024, 32, 0, FREQ_UNKNOWN, SST },
+	{ "sst25vf032b", 0xbf254a, 64 * 1024, 64, 0, FREQ_UNKNOWN, SST },
+
+	/* ST Microelectronics -- newer production may have feature updates */
+	{ "m25p05", 0x202010, 32 * 1024, 2, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p10", 0x202011, 32 * 1024, 4, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p20", 0x202012, 64 * 1024, 4, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p40", 0x202013, 64 * 1024, 8, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p80", 0x202014, 64 * 1024, 16, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p16", 0x202015, 64 * 1024, 32, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p32", 0x202016, 64 * 1024, 64, 0, FREQ_MHZ(75), ST_MICROELECTRONICS },
+	{ "m25p64", 0x202017, 64 * 1024, 128, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25p128", 0x202018, 256 * 1024, 64, 0, FREQ_MHZ(54), ST_MICROELECTRONICS },
+
+	{ "m45pe80", 0x204014, 64 * 1024, 16, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m45pe16", 0x204015, 64 * 1024, 32, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+
+	{ "m25pe80", 0x208014, 64 * 1024, 16, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+	{ "m25pe16", 0x208015, 64 * 1024, 32, 0, FREQ_UNKNOWN, ST_MICROELECTRONICS },
+
+	/* Winbond -- w25x "blocks" are 64K, except w25q128 is 4K  */
+	{ "w25x05", 0xef3010, 4 * 1024,  16, SECTOR_ERASE_OP20, FREQ_MHZ(104), WINBOND },
+	{ "w25x10", 0xef3011, 64 * 1024, 2, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25x20", 0xef3012, 4 * 1024, 64, SECTOR_ERASE_OP20, FREQ_UNKNOWN, WINBOND },
+	{ "w25x40", 0xef3013, 64 * 1024, 8, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25x80", 0xef3014, 64 * 1024, 16, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25x16", 0xef3015, 64 * 1024, 32, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25x32", 0xef3016, 64 * 1024, 64, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25x64", 0xef3017, 64 * 1024, 128, 0, FREQ_UNKNOWN, WINBOND },
+	{ "w25q64", 0xef4017, 64 * 1024, 128, 0, FREQ_MHZ(80), WINBOND },
+	{ "w25q128", 0xef4018, 64 * 1024, 256, 0, FREQ_MHZ(104), WINBOND },
+
+	/* Macronix -- MX25L "blocks" are 64K, except mx25l12836e and mx25l25635 are 4K */
+	{ "mx25l512e", 0xc22010, 4 * 1024, 16, SECTOR_ERASE_OP20, FREQ_MHZ(104), MACRONIX },
+	{ "mx25l1606e", 0xc22015, 64 * 1024, 32, 0, FREQ_MHZ(50), MACRONIX },
+	{ "mx25l6405", 0xc22017, 64 * 1024, 128, 0, FREQ_MHZ(50), MACRONIX },
+	{ "mx25l12836e", 0xc22018, 64 * 1024, 256, 0, FREQ_MHZ(104), MACRONIX },
+	{ "mx25l25635f", 0xc22019, 64 * 1024, 512, 0, FREQ_MHZ(104), MACRONIX },
+	{ "mx25l25655f", 0xc22619, 64 * 1024, 512, 0, FREQ_MHZ(104), MACRONIX },
+	{ "mx25l51245g", 0xc2201A, 64 * 1024, 1024, 0, FREQ_MHZ(104), MACRONIX },
+
+	/* ESMT -- F25L "blocks are 64K, "sectors" are 4KiB */
+	{ "f25l05pa", 0x8c3010, 4 * 1024, 16, SECTOR_ERASE_OP20, FREQ_MHZ(50), ESMT },
+	{ "f25l64qa", 0x8c4117, 64 * 1024, 128, 0, FREQ_MHZ(50), ESMT },
+
+	/* EON -- EN25Q "blocks are 64K, "sectors" are 4KiB */
+	{ "en25f05", 0x1c3110, 4 * 1024, 16, SECTOR_ERASE_OP20, FREQ_MHZ(100), EON },
+	{ "en25q64", 0x1c3017, 64 * 1024, 128, 0, FREQ_MHZ(104), EON },
+	{ "en25q128", 0x1c3018, 64 * 1024, 256, 0, FREQ_MHZ(104), EON },
+
+	/* GD -- GD25Q "blocks are 64K, "sectors" are 4KiB */
+	{ "qd25q512", 0xc84010, 4 * 1024, 16, SECTOR_ERASE_OP20, FREQ_MHZ(104), GD },
+	{ "gd25q128", 0xc84018, 64 * 1024, 256, 0, FREQ_MHZ(104), GD },
+
+};
+
+#endif // #ifndef __SPI_FLASH_DATA_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_version.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_version.h
new file mode 100644
index 0000000..342d60e
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_version.h
@@ -0,0 +1,17 @@
+#ifndef __RUBY_RELEASE_H__
+#define __RUBY_RELEASE_H__
+/*
+ * Copyright (c) 2011 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ *  Header file to hold build version information.
+ *
+ */
+
+////////////////////////////////////////////////////////////////////////////
+// Defines
+////////////////////////////////////////////////////////////////////////////
+
+#define RUBY_UBOOT_VERSION	"v37.4.0.29"
+
+#endif // __RUBY_RELEASE_H__
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_config.h b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_config.h
new file mode 100644
index 0000000..a71a123
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_config.h
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Topaz platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __TOPAZ_CONFIG_H
+#define __TOPAZ_CONFIG_H
+
+#include "current_platform.h"
+
+#if !TOPAZ_FPGA_PLATFORM
+#undef TOPAZ_ICACHE_WORKAROUND
+#endif
+
+/*
+ * Control registers move depending on unified + alias bit
+ */
+#if TOPAZ_SUPPORT_UMM
+#define TOPAZ_MMAP_UNIFIED	1
+#else
+#define TOPAZ_MMAP_UNIFIED	0
+#endif
+
+#define TOPAZ_MMAP_ALIAS	0
+#define TOPAZ_RX_ACCELERATE	1
+
+/* If MU-MIMO done in HDP or SDP */
+#define QTN_HDP_MU		1
+
+#if TOPAZ_MMAP_UNIFIED
+	#define RUBY_MMAP_FLIP		0
+	#define TOPAZ_UBOOT_UNIFIED_MAP		1
+#else
+	#if !(defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD))
+		#define RUBY_MMAP_FLIP		1
+	#else
+		#define RUBY_MMAP_FLIP		0
+	#endif
+	#define TOPAZ_UBOOT_UNIFIED_MAP		0
+#endif
+
+#if TOPAZ_MMAP_ALIAS && (defined(__linux__) || TOPAZ_UBOOT_UNIFIED_MAP)
+	#define RUBY_SYS_CTL_MMAP_REGVAL	(TOPAZ_SYS_CTL_UNIFIED_MAP | TOPAZ_SYS_CTL_ALIAS_MAP)
+#elif TOPAZ_MMAP_UNIFIED && (defined(__linux__) || TOPAZ_UBOOT_UNIFIED_MAP)
+	#define RUBY_SYS_CTL_MMAP_REGVAL	TOPAZ_SYS_CTL_UNIFIED_MAP
+#elif RUBY_MMAP_FLIP || defined(TOPAZ_PLATFORM)
+	#define RUBY_SYS_CTL_MMAP_REGVAL	RUBY_SYS_CTL_LINUX_MAP(0x1)
+#else
+	#undef RUBY_SYS_CTL_MMAP_REGVAL
+#endif
+
+#if QTN_HDP_MU
+#define QTN_HDP_MU_FCS_WORKROUND	1
+#else
+#define QTN_HDP_MU_FCS_WORKROUND	0
+#endif
+
+#if TOPAZ_MMAP_ALIAS && !TOPAZ_MMAP_UNIFIED
+	#error Alias map requires unified map
+#endif
+
+#if TOPAZ_MMAP_ALIAS
+	#define TOPAZ_ALIAS_MAP_SWITCH(a, b)	(b)
+#else
+	#define TOPAZ_ALIAS_MAP_SWITCH(a, b)	(a)
+#endif
+
+/* Topaz fixed phy addresses */
+#define TOPAZ_FPGAA_PHY0_ADDR		2
+#define TOPAZ_FPGAA_PHY1_ADDR		3
+#define TOPAZ_FPGAB_PHY0_ADDR		4
+#define TOPAZ_FPGAB_PHY1_ADDR		1
+#define TOPAZ_PHY0_ADDR				1
+#define TOPAZ_PHY1_ADDR				3
+
+#ifndef TOPAZ_FPGA_PLATFORM
+	#define TOPAZ_FPGA_PLATFORM	0
+#endif
+
+/* Definition indicates that Topaz platform is FPGA */
+#if TOPAZ_FPGA_PLATFORM
+	/* CLK speeds are in MHz and 1/10th the speed of actual ASIC */
+	#define TOPAZ_SERIAL_BAUD	38400
+	#define TOPAZ_APB_CLK		12500000
+	#define TOPAZ_AHB_CLK		25000000
+	#define TOPAZ_CPU_CLK		50000000
+	#define RUBY_FPGA_DDR
+#else
+	#define TOPAZ_SERIAL_BAUD	115200
+	#define TOPAZ_APB_CLK		125000000
+	#define TOPAZ_AHB_CLK		250000000
+	#define TOPAZ_CPU_CLK		500000000
+	#define RUBY_ASIC_DDR
+#endif /* #if TOPAZ_FPGA_PLATFORM */
+
+/*
+ * Setting UPF_SPD_FLAG gives a developer the option to set the
+ * flag to match a UPF_ define from <linux>/include/linux/serial_core.h
+ * or set the value to 0 to use the default baud rate setting DEFAULT_BAUD
+ */
+#define UPF_SPD_FLAG	0
+#define DEFAULT_BAUD	TOPAZ_SERIAL_BAUD
+
+/*
+ * Re-use Ruby defines to simplify the number of changes required
+ * to compile new binaries for Topaz
+ */
+#define RUBY_SERIAL_BAUD	TOPAZ_SERIAL_BAUD
+#define RUBY_FIXED_DEV_CLK	TOPAZ_APB_CLK
+#define RUBY_FIXED_CPU_CLK	TOPAZ_CPU_CLK
+
+#ifdef PLATFORM_DEFAULT_BOARD_ID
+        #define DEFAULT_BOARD_ID	PLATFORM_DEFAULT_BOARD_ID
+#else
+	/* Default board id used to match Topaz setting if there is no SPI Flash */
+	#define DEFAULT_BOARD_ID	QTN_TOPAZ_BB_BOARD
+#endif /* TOPAZ_DEFAULT_BOARD_ID */
+
+#ifndef PLATFORM_ARC7_MMU_VER
+	#define PLATFORM_ARC7_MMU_VER	2
+#endif
+
+#define CONFIG_RUBY_BROKEN_IPC_IRQS	0
+
+#define RUBY_IPC_HI_IRQ(bit_num)	((bit_num) + 8)
+#define RUBY_M2L_IPC_HI_IRQ(bit_num)	(bit_num)
+
+#define PLATFORM_REG_SWITCH(reg1, reg2)	(reg2)
+
+#define writel_topaz(a, b)		writel(a, b)
+#define writel_ruby(a, b)
+
+#define QTN_VLAN_LLC_ENCAP		1
+
+#define TOPAZ_128_NODE_MODE		1
+
+#define TOPAZ_ETH_REFLECT_SW_FWD	0
+
+#define DSP_ENABLE_STATS		1
+
+#endif /* #ifndef __TOPAZ_CONFIG_H */
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_emac.h b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_emac.h
new file mode 100644
index 0000000..b6c0bcc
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_emac.h
@@ -0,0 +1,281 @@
+/*
+ * (C) Copyright 2012 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __TOPAZ_EMAC_H
+#define __TOPAZ_EMAC_H
+
+#include "topaz_platform.h"
+#ifdef _KERNEL
+#include "ruby_arasan_emac_ahb.h"
+#endif
+
+#define TOPAZ_EMAC_NUM_DPI_FIELDS		32
+#define TOPAZ_EMAC_NUM_DPI_FILTERS		16
+#define TOPAZ_EMAC_NUM_DPI_IPTUPLES		8
+
+#define TOPAZ_EMAC_WRAP_CTRL			0x300
+# define TOPAZ_EMAC_WRAP_CTRL_VERSION			0x0000000f
+#define TOPAZ_EMAC_RXP_CTRL			0x304
+# define TOPAZ_EMAC_RXP_CTRL_ENABLE			BIT(0)
+# define TOPAZ_EMAC_RXP_CTRL_ENDIAN			BIT(1)
+# define TOPAZ_EMAC_RXP_CTRL_TQE_SYNC_EN_BP		BIT(2)
+# define TOPAZ_EMAC_RXP_CTRL_TQE_SYNC_EN_SUCC		BIT(3)
+# define TOPAZ_EMAC_RXP_CTRL_SYNC_NONE			0
+# define TOPAZ_EMAC_RXP_CTRL_SYNC_TQE			BIT(4)
+# define TOPAZ_EMAC_RXP_CTRL_SYNC_RX_DMA		BIT(5)
+# define TOPAZ_EMAC_RXP_CTRL_SYNC_RX_PARSER		(BIT(4) | BIT(5))
+# define TOPAZ_EMAC_RXP_CTRL_SRESET			BIT(8)
+#define TOPAZ_EMAC_TXP_CTRL			0x308
+# define TOPAZ_EMAC_TXP_CTRL_AHB_ENABLE			BIT(0)
+# define TOPAZ_EMAC_TXP_CTRL_SRESET			BIT(8)
+#define TOPAZ_EMAC_TXP_Q_FULL			0x320
+# define TOPAZ_EMAC_TXP_Q_FULL_BIT			BIT(31)
+#define TOPAZ_EMAC_TXP_DESC_PTR			0x324
+#define TOPAZ_EMAC_DEBUG_BUS_SEL		0x328
+#define TOPAZ_EMAC_DEBUG_BUS_SEL_TXP_PTR		0x00000001
+
+#define TOPAZ_EMAC_BUFFER_POOLS			0x32c
+# define TOPAZ_EMAC_BUFFER_POOLS_RX_REPLENISH		0x00000003
+# define TOPAZ_EMAC_BUFFER_POOLS_RX_REPLENISH_S		0
+# define TOPAZ_EMAC_BUFFER_POOLS_TX_RETURN		0x0000000c
+# define TOPAZ_EMAC_BUFFER_POOLS_TX_RETURN_S		2
+#define TOPAZ_EMAC_TXP_STATUS			0x330
+
+/*
+ * EMAC Tx-ring read/write pointer, should write 0x1 to reg_0x328 before read the pointer.
+ * Bit[12:0]  : EMAC read pointer
+ * Bit[25:13] : TQE write pointer
+ */
+#define TOPAZ_EMAC_TXP_READ_PTR(stat)			((stat) & 0x1FFF)
+#define TOPAZ_EMAC_TXP_WRITE_PTR(stat)			(((stat) >> 13) & 0x1FFF)
+
+#define TOPAZ_EMAC_DESC_LIMIT			0x334
+# define TOPAZ_EMAC_DESC_LIMIT_MASK			0x0000ffff
+#define TOPAZ_EMAC_RXP_PRIO_CTRL		0x350
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_TID_SEL		0x00000003
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_TID_SEL_S		0
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_TID_MINMAX		0x00000004
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_TID_MINMAX_S		2
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_SW_TID		0x00000f00
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_SW_TID_S		8
+# define TOPAZ_EMAC_RXP_PRIO_CTRL_SW_TID_SEL		BIT(12)
+
+#define TOPAZ_EMAC_RXP_OUTPORT_CTRL		0x354
+# define TOPAZ_EMAC_RXP_OP_CTRL_DA			0x00000003
+# define TOPAZ_EMAC_RXP_OP_CTRL_DA_S			0
+# define TOPAZ_EMAC_RXP_OP_CTRL_VLAN			0x0000000c
+# define TOPAZ_EMAC_RXP_OP_CTRL_VLAN_S			2
+# define TOPAZ_EMAC_RXP_OP_CTRL_IP			0x00000030
+# define TOPAZ_EMAC_RXP_OP_CTRL_IP_S			4
+# define TOPAZ_EMAC_RXP_OP_CTRL_DPI			0x000000c0
+# define TOPAZ_EMAC_RXP_OP_CTRL_DPI_S			6
+# define TOPAZ_EMAC_RXP_OP_CTRL_MCAST_EN		BIT(8)
+# define TOPAZ_EMAC_RXP_OP_CTRL_MCAST_SEL		BIT(9)
+# define TOPAZ_EMAC_RXP_OP_CTRL_MCAST_PORT		0x00003c00
+# define TOPAZ_EMAC_RXP_OP_CTRL_MCAST_PORT_S		10
+# define TOPAZ_EMAC_RXP_OP_CTRL_DYNAMIC_FAIL_PORT	0x000f0000
+# define TOPAZ_EMAC_RXP_OP_CTRL_DYNAMIC_FAIL_PORT_S	16
+# define TOPAZ_EMAC_RXP_OP_CTRL_SW_BACKDOOR_PORT	0x00f00000
+# define TOPAZ_EMAC_RXP_OP_CTRL_SW_BACKDOOR_PORT_S	20
+# define TOPAZ_EMAC_RXP_OP_CTRL_STATIC_FAIL_PORT	0x0f000000
+# define TOPAZ_EMAC_RXP_OP_CTRL_STATIC_FAIL_PORT_S	24
+# define TOPAZ_EMAC_RXP_OP_CTRL_STATIC_PORT_SEL		0x70000000
+# define TOPAZ_EMAC_RXP_OP_CTRL_STATIC_PORT_SEL_S	28
+# define TOPAZ_EMAC_RXP_OP_CTRL_STATIC_ENABLE		BIT(31)
+#ifndef __ASSEMBLY__
+union topaz_emac_rxp_outport_ctrl {
+	struct {
+		uint32_t word0;
+	} raw;
+	struct {
+		uint32_t da_prio		: 2,
+			vlan_prio		: 2,
+			ip_prio			: 2,
+			dpi_prio		: 2,
+			mcast_en		: 1,
+			mcast_sel		: 1,
+			mcast_port		: 4,
+			__unused		: 2,
+			dynamic_fail_port	: 4,
+			sw_backdoor_port	: 4,
+			static_fail_port	: 4,
+			static_port_sel		: 3,
+			static_mode_en		: 1;
+	} data;
+};
+#endif	// __ASSEMBLY__
+
+#define TOPAZ_EMAC_RXP_OUTNODE_CTRL		0x358
+union topaz_emac_rxp_outnode_ctrl {
+	struct {
+		uint32_t word0;
+	} raw;
+	struct {
+		uint32_t mcast_node		: 6,
+			 __unused		: 4,
+			 dynamic_fail_node	: 6,
+			 sw_backdoor_node	: 6,
+			 static_fail_node	: 6,
+			 static_node_sel	: 3,
+			 __unused2		: 1;
+	} data;
+};
+#define TOPAZ_EMAC_RXP_VLAN_PRI_TO_TID		0x380
+# define TOPAZ_EMAC_RXP_VLAN_PRI_TO_TID_PRI(pcp, tid)	(((tid) & 0xf) << ((pcp) * 4))
+#define TOPAZ_EMAC_RXP_VLAN_PRI_CTRL		0x384
+# define TOPAZ_EMAC_RXP_VLAN_PRI_CTRL_TAG		0x00000003
+# define TOPAZ_EMAC_RXP_VLAN_PRI_CTRL_TAG_S		0
+#define TOPAZ_EMAC_RXP_VLAN_TAG_0_1		0x388
+# define TOPAZ_EMAC_RXP_VLAN_TAG_0			0x0000ffff
+# define TOPAZ_EMAC_RXP_VLAN_TAG_0_S			0
+# define TOPAZ_EMAC_RXP_VLAN_TAG_1			0xffff0000
+# define TOPAZ_EMAC_RXP_VLAN_TAG_1_S			16
+#define TOPAZ_EMAC_RXP_VLAN_TAG_2_3		0x38c
+# define TOPAZ_EMAC_RXP_VLAN_TAG_2			0x0000ffff
+# define TOPAZ_EMAC_RXP_VLAN_TAG_2_S			0
+# define TOPAZ_EMAC_RXP_VLAN_TAG_3			0xffff0000
+# define TOPAZ_EMAC_RXP_VLAN_TAG_3_S			16
+#define TOPAZ_EMAC_RXP_IP_DIFF_SRV_TID_REG(x)	(0x390 + 4 * (x))
+#define TOPAZ_EMAC_RXP_IP_DIFF_SRV_TID_REGS	8
+#define TOPAZ_EMAC_RXP_IP_CTRL			0x3b0
+#define TOPAZ_EMAC_RXP_DPI_TID_MAP_REG(x)	(0x3b4 + 4 * (x))
+#define TOPAZ_EMAC_RXP_DPI_TID_MAP_INDEX(x)	TOPAZ_EMAC_RXP_DPI_TID_MAP_REG((x) >> 3)
+#define TOPAZ_EMAC_RXP_TID_MAP_INDEX_SHIFT(x)	(((x) & 0x7) << 2)
+#define TOPAZ_EMAC_RXP_TID_MAP_INDEX_MASK(x)	(0xF << TOPAZ_EMAC_RXP_TID_MAP_INDEX_SHIFT(x))
+#define TOPAZ_EMAC_RXP_DPI_CTRL			0x3bc
+# define TOPAZ_EMAC_RXP_DPI_CTRL_DPI_FAIL_TID		0x0000000f
+#define TOPAZ_EMAC_RXP_STATUS			0x3c0
+#define TOPAZ_EMAC_RXP_CST_SEL			0x3c4
+#define TOPAZ_EMAC_RXP_FRAME_CNT_CLEAR		0x3cc
+# define TOPAZ_EMAC_RXP_FRAME_CNT_CLEAR_ERROR		BIT(0)
+# define TOPAZ_EMAC_RXP_FRAME_CNT_CLEAR_TOTAL		BIT(1)
+# define TOPAZ_EMAC_RXP_FRAME_CNT_CLEAR_DA_MATCH	BIT(2)
+# define TOPAZ_EMAC_RXP_FRAME_CNT_CLEAR_SA_MATCH	BIT(3)
+#define TOPAZ_EMAC_FRM_COUNT_ERRORS		0x3d0
+#define TOPAZ_EMAC_FRM_COUNT_TOTAL		0x3d4
+#define TOPAZ_EMAC_FRM_COUNT_DA_MATCH		0x3d8
+#define TOPAZ_EMAC_FRM_COUNT_SA_MATCH		0x3dc
+#define TOPAZ_EMAC_RX_DPI_FIELD_VAL(x)		(0x400 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_FIELD_MASK(x)		(0x480 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_FIELD_CTRL(x)		(0x500 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_FIELD_GROUP(x)	(0x580 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_OUT_CTRL(x)		(0x5c0 + 4 * (x))
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_NODE	0x0000007f
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_NODE_S	0
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_PORT	0x00000780
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_PORT_S	7
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_COMBO	0x00001800
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_COMBO_S	11
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_OFF		0x0
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_IPTUPLE	0x1
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_DPI		0x2
+# define TOPAZ_EMAC_RX_DPI_OUT_CTRL_BOTH	0x3
+
+#ifndef __ASSEMBLY__
+enum topaz_emac_rx_dpi_anchor {
+	TOPAZ_EMAC_RX_DPI_ANCHOR_FRAME	= 0x0,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_VLAN0	= 0x1,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_VLAN1	= 0x2,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_VLAN2	= 0x3,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_VLAN3	= 0x4,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_OTHER	= 0x5,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_LLC	= 0x6,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_IPV4	= 0x7,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_IPV6	= 0x8,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_TCP	= 0x9,
+	TOPAZ_EMAC_RX_DPI_ANCHOR_UDP	= 0xa,
+};
+
+enum topaz_emac_rx_dpi_cmp_op {
+	TOPAZ_EMAC_RX_DPI_CMP_OP_EQUAL	= 0x0,
+	TOPAZ_EMAC_RX_DPI_CMP_OP_NEQUAL	= 0x1,
+	TOPAZ_EMAC_RX_DPI_CMP_OP_GT	= 0x2,
+	TOPAZ_EMAC_RX_DPI_CMP_OP_LT	= 0x3,
+};
+
+#define TOPAZ_EMAC_RX_DPI_ANCHOR_NAMES	{		\
+	"frame", "vlan0", "vlan1", "vlan2", "vlan3",	\
+	"other", "llc", "ipv4", "ipv6", "tcp", "udp",	\
+}
+
+#define TOPAZ_EMAC_RX_DPI_CMP_OP_NAMES	{		\
+	"==", "!=", ">", "<",				\
+}
+
+
+union topaz_emac_rx_dpi_ctrl {
+	uint32_t raw;
+	struct {
+		uint32_t offset		: 9,
+			 anchor		: 4,
+			 cmp_op		: 2,
+			 enable		: 1,
+			 __unused	: 16;
+	} data;
+};
+#endif	// __ASSEMBLY__
+
+#define TOPAZ_EMAC_RX_DPI_IPT_GROUP(x)		(0x720 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_IPT_GROUP_SRCADDR(x)	BIT((x) + 0)
+#define TOPAZ_EMAC_RX_DPI_IPT_GROUP_DESTADDR(x)	BIT((x) + 8)
+#define TOPAZ_EMAC_RX_DPI_IPT_GROUP_DESTPORT(x)	BIT((x) + 16)
+#define TOPAZ_EMAC_RX_DPI_IPT_GROUP_SRCPORT(x)	BIT((x) + 24)
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_DATA(x)	(0x600 + 4 * (x))
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_DATA_MAX	8
+#define TOPAZ_EMAC_RX_DPI_IPT_PORT_DEST		0x0000FFFF
+#define TOPAZ_EMAC_RX_DPI_IPT_PORT_DEST_S	0
+#define TOPAZ_EMAC_RX_DPI_IPT_PORT_SRC		0xFFFF0000
+#define TOPAZ_EMAC_RX_DPI_IPT_PORT_SRC_S	16
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_COM		0x620
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_COM_ENT	0x0000000F
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_COM_ENT_S	0
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_COM_WRITE	BIT(8)
+#define TOPAZ_EMAC_RX_DPI_IPT_MEM_COM_READ	BIT(9)
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRIES			9
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRY_SRCADDR_START	0
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRY_SRCADDR_END		4
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRY_DESTADDR_START	4
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRY_DESTADDR_END	8
+#define TOPAZ_EMAC_RX_DPI_IPT_ENTRY_PORTS		8
+
+
+#define TOPAZ_EMAC_IP_PROTO_ENTRY(x)		(0xa000 + 4 * (x))
+#define TOPAZ_EMAC_IP_PROTO_ENTRIES		256
+#define TOPAZ_EMAC_IP_PROTO_OUT_NODE		0x0000007F
+#define TOPAZ_EMAC_IP_PROTO_OUT_NODE_S		0
+#define TOPAZ_EMAC_IP_PROTO_OUT_PORT		0x00000780
+#define TOPAZ_EMAC_IP_PROTO_OUT_PORT_S		7
+#define TOPAZ_EMAC_IP_PROTO_VALID		BIT(11)
+#define TOPAZ_EMAC_IP_PROTO_VALID_S		11
+
+#define TOPAZ_EMAC_IPDSCP_HWT_SHIFT	2
+
+#define TOPAZ_EMAC_RXP_PRIO_IS_BIT2	0
+#define TOPAZ_EMAC_RXP_PRIO_IS_VLAN	1
+#define TOPAZ_EMAC_RXP_PRIO_IS_DSCP	2
+#define TOPAZ_EMAC_RXP_PRIO_IS_DPI	3
+
+extern void topaz_emac_to_lhost(uint32_t enable);
+extern int topaz_emac_get_bonding(void);
+
+#endif	// __TOPAZ_EMAC_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_mmap.S b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_mmap.S
new file mode 100644
index 0000000..12456bc
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_mmap.S
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#if defined(__linux__) && defined (__KERNEL__)
+#if defined (DC_CTRL_FLUSH_STATUS)
+	#define ARC_DC_FLUSH_STATUS_BIT	DC_CTRL_FLUSH_STATUS
+#elif defined (BIT_DC_CTRL_FLUSH_STATUS)
+	#define ARC_DC_FLUSH_STATUS_BIT	BIT_DC_CTRL_FLUSH_STATUS
+#endif
+#endif
+
+
+topaz_unified_mmap:
+	.globl topaz_unified_mmap
+	/* Code must be position-independent! */
+
+	/*
+	* Flush and invalidate data cache.
+	* Please make sure that instructions which touch
+	* d-cache are NOT used until flipping is done.
+	*/
+	/* Set flush mode for invalidate operation */
+	lr      r3, [ARC_REG_DC_CTRL]
+	bset    r3, r3, 0x6
+	sr      r3, [ARC_REG_DC_CTRL]
+	/* Start invalidate operation */
+	mov     r3, 0x1
+	sr      r3, [ARC_REG_DC_IVDC]
+	/* Check while cache invalidating will be finished */
+dcache_flush_continue:
+	lr      r3, [ARC_REG_DC_CTRL]
+	and     r3, r3, ARC_DC_FLUSH_STATUS_BIT
+	brne    r3, 0x0, dcache_flush_continue
+
+	/* Prepare flipping.
+	 * After code is finished, memory maps will change as follows:
+	 *     Flip map:
+	 *         SRAM 0x8000_0000 -> 0x8800_0000
+	 *         DRAM 0x0         -> 0x8000_0000
+	 *     Unified map:
+	 *         SRAM 0x8000_0000 -> 0x9800_0000
+	 *         DRAM 0x0         -> 0x8000_0000
+	 */
+	mov     r3, RUBY_SYS_CTL_BASE_ADDR_NOMAP
+	mov     r4, RUBY_SYS_CTL_MMAP_REGVAL
+	or      r4, r4, RUBY_SYS_CTL_REMAP(0x3)
+	st.di   r4, [r3, RUBY_SYS_CTL_MASK - RUBY_SYS_CTL_BASE_ADDR]
+	mov     r4, RUBY_SYS_CTL_MMAP_REGVAL
+
+.align 32 /*ARC_ICACHE_LINE_LEN*/
+	/* Do flipping.
+	* Align to cache line to ensure we don't hit memory during following instructions.
+	* Code must fit into 1 cache line (32 bytes).
+	*/
+	st.di   r4, [r3, RUBY_SYS_CTL_CTRL - RUBY_SYS_CTL_BASE_ADDR]
+	ld.di   r4, [r3, RUBY_SYS_CTL_CTRL - RUBY_SYS_CTL_BASE_ADDR] /* read back to clear pipeline */
+	sync
+	j       boot_continue		/* jump to absolute addr in sram */
+	/* Align to cache line so code occupy strictly 1 cache line. */
+.align 32 /* ARC_ICACHE_LINE_LEN */
+
+boot_continue:
+	/* Finalize flipping. */
+	mov     r4, 0x0
+	st.di   r4, [r3, RUBY_SYS_CTL_MASK - RUBY_SYS_CTL_BASE_ADDR]
+
+	/* Let's discard instruction cache.
+	*/
+	mov     r4, 0x1
+	sr      r4, [ARC_REG_IC_IVIC] /* invalidate i-cache */
+	lr      r4, [ARC_REG_IC_CTRL] /* read will be not completed until i-cache is invalidated */
+
+	/* Done. We are now sitting in different addresses. */
+	b	ruby_boot
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_platform.h b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_platform.h
new file mode 100644
index 0000000..be27da5
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_platform.h
@@ -0,0 +1,498 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Topaz platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __TOPAZ_PLATFORM_H
+#define __TOPAZ_PLATFORM_H
+
+#include "ruby_platform.h"
+
+#ifndef MS
+#define MS(_v, _f)		(((_v) & _f) >> _f##_S)
+#endif
+#ifndef SM
+#define SM(_v, _f)		(((_v) << _f##_S) & _f)
+#endif
+
+/*
+ * The following macro couldn't be defined via SM because of issues with nesting ##
+ * i.e. the following define does not work
+ * do{ where = (where) & (~(bitmask)) | SM(new_value, bitmask); }while(0)
+ */
+#define UPDATE_BITSET(where, bitmask, new_value) \
+	do{ where = ((where) & (~(bitmask))) | (((new_value) << bitmask##_S) & bitmask); }while(0)
+
+/* Extra reset bits */
+#define TOPAZ_SYS_CTL_RESET_AUC		(RUBY_BIT(10))
+#define TOPAZ_SYS_CTL_ALIAS_MAP		(RUBY_BIT(29))
+#define TOPAZ_SYS_CTL_UNIFIED_MAP	(RUBY_BIT(30))
+
+/* Extra system controller bits */
+#define TOPAZ_SYS_CTL_DDRCLK_S		22
+#define TOPAZ_SYS_CTL_DDRCLK		(0x7 << TOPAZ_SYS_CTL_DDRCLK_S)
+#define TOPAZ_SYS_CTL_DDRCLK_400MHZ	SM(0, TOPAZ_SYS_CTL_DDRCLK)
+#define TOPAZ_SYS_CTL_DDRCLK_320MHZ	SM(1, TOPAZ_SYS_CTL_DDRCLK)
+#define TOPAZ_SYS_CTL_DDRCLK_250MHZ	SM(2, TOPAZ_SYS_CTL_DDRCLK)
+#define TOPAZ_SYS_CTL_DDRCLK_200MHZ	SM(3, TOPAZ_SYS_CTL_DDRCLK)
+#define TOPAZ_SYS_CTL_DDRCLK_160MHZ	SM(4, TOPAZ_SYS_CTL_DDRCLK)
+
+/* Extra system controller registers */
+#define TOPAZ_SYS_CTL_M2D_2_INT		(RUBY_SYS_CTL_BASE_ADDR + 0x0184)
+#define TOPAZ_SYS_CTL_M2D_2_INT_MASK	(RUBY_SYS_CTL_BASE_ADDR + 0x0188)
+#define TOPAZ_SYS_CTL_M2D_3_INT		(RUBY_SYS_CTL_BASE_ADDR + 0x018C)
+#define TOPAZ_SYS_CTL_M2D_3_INT_MASK	(RUBY_SYS_CTL_BASE_ADDR + 0x0190)
+
+/* Temperature control registers */
+#define TOPAZ_SYS_CTL_TEMPSENS_CTL	(RUBY_SYS_CTL_BASE_ADDR + 0x0108)
+#define TOPAZ_SYS_CTL_TEMPSENS_CTL_START_CONV		0x00000001
+#define TOPAZ_SYS_CTL_TEMPSENS_CTL_SHUTDWN		0x00000002
+
+#define TOPAZ_SYS_CTL_TEMP_SENS_TEST_CTL		(RUBY_SYS_CTL_BASE_ADDR + 0x010C)
+
+#define TOPAZ_SYS_CTL_TEMP_SENS_DATA			(RUBY_SYS_CTL_BASE_ADDR + 0x0110)
+#define TOPAZ_SYS_CTL_TEMP_SENS_DATA_TEMP		0x00000FFF
+#define TOPAZ_SYS_CTL_TEMP_SENS_DATA_END_CONV		0x00001000
+#define TOPAZ_SYS_CTL_TEMP_SENS_DATA_END_CONV_S		11
+
+/* AuC SoC interrupt controller registers */
+#define TOPAZ_AUC_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x0174)
+#define TOPAZ_AUC_IPC_INT		(RUBY_SYS_CTL_BASE_ADDR + 0x0178)
+#define TOPAZ_AUC_IPC_INT_MASK(val)	((val & 0xFFFF) << 16)
+#define TOPAZ_AUC_INT_STATUS		(RUBY_SYS_CTL_BASE_ADDR + 0x00D0)
+
+/* Linux Host interrupt controller registers */
+#define TOPAZ_LH_IPC3_INT		(RUBY_SYS_CTL_BASE_ADDR + 0x14C)
+#define TOPAZ_LH_IPC3_INT_MASK		(RUBY_SYS_CTL_BASE_ADDR + 0x150)
+#define TOPAZ_IPC4_INT(base)	((base) + 0x13C)
+#define TOPAZ_IPC4_INT_MASK(base)	((base) + 0x140)
+#define TOPAZ_LH_IPC4_INT		(TOPAZ_IPC4_INT(RUBY_SYS_CTL_BASE_ADDR))
+#define TOPAZ_LH_IPC4_INT_MASK		(TOPAZ_IPC4_INT_MASK(RUBY_SYS_CTL_BASE_ADDR))
+
+/* Multi-processor hardware semahpore */
+#define TOPAZ_MPROC_SEMA		(RUBY_SYS_CTL_BASE_ADDR + 0x0170)
+
+/* MuC SoC Interrupt controller registers */
+#define TOPAZ_SYS_CTL_A2M_INT		(RUBY_SYS_CTL_BASE_ADDR + 0x0144)
+#define TOPAZ_SYS_CTL_A2M_INT_MASK	(RUBY_SYS_CTL_BASE_ADDR + 0x0148)
+
+/* PCIE SoC Interrupt controller registers */
+#define TOPAZ_SYS_CTL_PCIE_INT_STATUS	(RUBY_SYS_CTL_BASE_ADDR + 0x017c)
+#define TOPAZ_SYS_CTL_TQE_INT_STATS_BIT	(RUBY_BIT(10))
+
+#define TOPAZ_SWITCH_BASE_ADDR		0xE1000000
+#define TOPAZ_SWITCH_OUT_NODE_BITS	7		/* Up to 128 output nodes */
+#define TOPAZ_SWITCH_OUT_NODE_MAX	(1 << TOPAZ_SWITCH_OUT_NODE_BITS)
+#define TOPAZ_SWITCH_OUT_NODE_MASK	((1 << TOPAZ_SWITCH_OUT_NODE_BITS) - 1)
+#define TOPAZ_SWITCH_OUT_PORT_BITS	4		/* Up to 16 output ports. 8 are used */
+#define TOPAZ_SWITCH_OUT_PORT_MAX	(1 << TOPAZ_SWITCH_OUT_PORT_BITS)
+#define TOPAZ_SWITCH_OUT_PORT_MASK	((1 << TOPAZ_SWITCH_OUT_PORT_BITS) - 1)
+
+/* TQE */
+#define TOPAZ_TQE_BASE_ADDR		(TOPAZ_SWITCH_BASE_ADDR + 0x30000)
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL	(TOPAZ_TQE_BASE_ADDR + 0x0000)
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_VAL				0x000000FF
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_VAL_S			0
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_SHIFT			24	/* reg bits [7:0] become emac ctrl [31:24] */
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_MCAST_APPEND_CNTR_EN_S	16
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_MCAST_APPEND_CNTR_EN		0x00010000
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_PRI_MODE			0x0F000000
+#define TOPAZ_TQE_EMAC_TDES_1_CNTL_PRI_MODE_S			24
+#define TOPAZ_TQE_MISC			(TOPAZ_TQE_BASE_ADDR + 0x0004)
+#define TOPAZ_TQE_MISC_CLR_DONE_DLY_CYCLE_NUM		0x000003FF	/* q_avail_clr_done delay cycles */
+#define TOPAZ_TQE_MISC_CLR_DONE_DLY_CYCLE_NUM_S		0
+#define TOPAZ_TQE_MISC_RFLCT_OUT_PORT			0x000F0000	/* dest port for reflected pkts */
+#define TOPAZ_TQE_MISC_RFLCT_OUT_PORT_S			16
+#define TOPAZ_TQE_MISC_RFLCT_OUT_PORT_ENABLE		0x00100000	/* redirect emac0<->emac0 or emac1<->emac1 reflected pkts */
+#define TOPAZ_TQE_MISC_RFLCT_OUT_PORT_ENABLE_S		20
+#define TOPAZ_TQE_MISC_RFLCT_2_OUT_PORT_ENABLE		0x00200000	/* redirect emac0<->emac0/emac1 or emac1<->emac0/emac1 reflected pkts */
+#define TOPAZ_TQE_MISC_RFLCT_2_OUT_PORT_ENABLE_S	21
+#define TOPAZ_TQE_MISC_CLR_DONE_DLY_ENABLE		0x80000000	/* enable q_avail_clr_done delay */
+#define TOPAZ_TQE_MISC_CLR_DONE_DLY_ENABLE_S		31
+#define TOPAZ_TQE_WMAC_Q_STATUS_PTR	(TOPAZ_TQE_BASE_ADDR + 0x0008)
+#define TOPAZ_TQE_CPU_SEM		(TOPAZ_TQE_BASE_ADDR + 0x000c)
+#define TOPAZ_TQE_OUTPORT_EMAC0_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0010)
+#define TOPAZ_TQE_OUTPORT_EMAC1_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0014)
+#define TOPAZ_TQE_OUTPORT_WMAC_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0018)
+#define TOPAZ_TQE_OUTPORT_LHOST_CNT	(TOPAZ_TQE_BASE_ADDR + 0x001c)
+#define TOPAZ_TQE_OUTPORT_MUC_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0020)
+#define TOPAZ_TQE_OUTPORT_DSP_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0024)
+#define TOPAZ_TQE_OUTPORT_AUC_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0028)
+#define TOPAZ_TQE_OUTPORT_PCIE_CNT	(TOPAZ_TQE_BASE_ADDR + 0x002c)
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL	(TOPAZ_TQE_BASE_ADDR + 0x0030)
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_TID		0xF
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_TID_S	0
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_NODE		0x7F00
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_NODE_S	8
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_CLEAR	RUBY_BIT(30)
+#define TOPAZ_TQE_Q_AVAIL_CLR_CNTL_CLEAR_DONE	RUBY_BIT(31)
+#define TOPAZ_TQE_DROP_CNT		(TOPAZ_TQE_BASE_ADDR + 0x0034)
+#define TOPAZ_TQE_DROP_EMAC0_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0040)
+#define TOPAZ_TQE_DROP_EMAC1_CNT	(TOPAZ_TQE_BASE_ADDR + 0x0044)
+#define TOPAZ_TQE_DROP_WMAC_CNT		(TOPAZ_TQE_BASE_ADDR + 0x0048)
+#define TOPAZ_TQE_DROP_LHOST_CNT	(TOPAZ_TQE_BASE_ADDR + 0x004c)
+#define TOPAZ_TQE_DROP_MUC_CNT		(TOPAZ_TQE_BASE_ADDR + 0x0050)
+#define TOPAZ_TQE_DROP_DSP_CNT		(TOPAZ_TQE_BASE_ADDR + 0x0054)
+#define TOPAZ_TQE_DROP_AUC_CNT		(TOPAZ_TQE_BASE_ADDR + 0x0058)
+#define TOPAZ_TQE_DROP_PCIE_CNT		(TOPAZ_TQE_BASE_ADDR + 0x005c)
+
+/* TQE-CPU interface */
+#define TOPAZ_TQE_CPUIF_BASE(num)		(TOPAZ_TQE_BASE_ADDR + 0x4000 + 0x1000 * (num))	// For FPGA build 72 and earlier need to use (0xE1040000 + 0x10000 * (num))
+#define TOPAZ_TQE_CPUIF_CSR(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0000)
+#define TOPAZ_TQE_CPUIF_RX_RING_SIZE(num)	(TOPAZ_TQE_CPUIF_BASE(num) + 0x0004)
+#define TOPAZ_TQE_CPUIF_RX_RING(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0008)
+#define TOPAZ_TQE_CPUIF_RX_CURPTR(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x000c)
+#define TOPAZ_TQE_CPUIF_PKT_FINISH(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0010)
+#define TOPAZ_TQE_CPUIF_Q_PTR_STATUS(num)	(TOPAZ_TQE_CPUIF_BASE(num) + 0x0014)
+#define TOPAZ_TQE_CPUIF_PPCTL0(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0020)
+#define TOPAZ_TQE_CPUIF_PPCTL1(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0024)
+#define TOPAZ_TQE_CPUIF_PPCTL2(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0028)
+#define TOPAZ_TQE_CPUIF_PPCTL3(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x002c)
+#define TOPAZ_TQE_CPUIF_PPCTL4(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0030)
+#define TOPAZ_TQE_CPUIF_PPCTL5(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0034)
+#define TOPAZ_TQE_CPUIF_TXSTART(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x0038)
+#define TOPAZ_TQE_CPUIF_STATUS(num)		(TOPAZ_TQE_CPUIF_BASE(num) + 0x003C)
+/* Some bits definitions */
+#define TOPAZ_TQE_CPUIF_CSR_IRQ_EN		RUBY_BIT(0)
+#define TOPAZ_TQE_CPUIF_CSR_IRQ_THRESHOLD(num)	(((num) & 0x7F) << 8)
+#define TOPAZ_TQE_CPUIF_CSR_IRQ_THRESHOLD_EN	RUBY_BIT(15)
+#define TOPAZ_TQE_CPUIF_CSR_RESET		RUBY_BIT(31)
+/* Aux definitions */
+#define TOPAZ_TQE_CPUIF_RXDESC_ALIGN		8	/* TQE CPU rx descriptors must be 64 bit aligned */
+
+/**
+ * Hardware Buffer Manager
+ */
+#define TOPAZ_HBM_BASE_ADDR		(TOPAZ_SWITCH_BASE_ADDR + 0x20000)
+#define TOPAZ_HBM_CSR_REG		(TOPAZ_HBM_BASE_ADDR + 0x0000)
+#define TOPAZ_HBM_CSR_Q_EN(x)		(BIT(0 + (x)))
+#define TOPAZ_HBM_CSR_INT_EN		(BIT(7))
+#define TOPAZ_HBM_CSR_OFLOW_INT_MASK(x)	(BIT(8 + (x)))
+#define TOPAZ_HBM_CSR_UFLOW_INT_MASK(x)	(BIT(12 + (x)))
+#define TOPAZ_HBM_CSR_OFLOW_INT_RAW(x)	(BIT(16 + (x)))
+#define TOPAZ_HBM_CSR_UFLOW_INT_RAW(x)	(BIT(20 + (x)))
+#define TOPAZ_HBM_CSR_INT_MSK_RAW	(0xff << 16)
+#define TOPAZ_HBM_CSR_OFLOW_INT_STATUS(x) (BIT(24 + (x)))
+#define TOPAZ_HBM_CSR_UFLOW_INT_STATUS(x) (BIT(28 + (x)))
+
+#define TOPAZ_HBM_BASE_REG(x)		(TOPAZ_HBM_BASE_ADDR + 0x0004 + ((x) * 0x10))
+#define TOPAZ_HBM_LIMIT_REG(x)		(TOPAZ_HBM_BASE_ADDR + 0x0008 + ((x) * 0x10))
+#define TOPAZ_HBM_WR_PTR(x)		(TOPAZ_HBM_BASE_ADDR + 0x000c + ((x) * 0x10))
+#define TOPAZ_HBM_RD_PTR(x)		(TOPAZ_HBM_BASE_ADDR + 0x0010 + ((x) * 0x10))
+
+#define TOPAZ_HBM_POOL(x)		(TOPAZ_HBM_BASE_ADDR + 0x0100 + ((x) * 0x4))
+#define TOPAZ_HBM_POOL_REQ(x)		(TOPAZ_HBM_BASE_ADDR + 0x0110 + ((x) * 0x4))
+#define TOPAZ_HBM_POOL_DATA(x)		(TOPAZ_HBM_BASE_ADDR + 0x0140 + ((x) * 0x4))
+
+#define TOPAZ_HBM_OVERFLOW_CNT		(TOPAZ_HBM_BASE_ADDR + 0x0190)
+#define TOPAZ_HBM_UNDERFLOW_CNT		(TOPAZ_HBM_BASE_ADDR + 0x0194)
+
+#define TOPAZ_HBM_MASTER_COUNT				9
+#define TOPAZ_HBM_POOL_COUNT				4
+#define TOPAZ_HBM_POOL_REQUEST_CNT(master, pool)	(TOPAZ_HBM_BASE_ADDR + 0x0200 + (master) * 0x20 + (pool) * 0x4)
+#define TOPAZ_HBM_POOL_RELEASE_CNT(master, pool)	(TOPAZ_HBM_BASE_ADDR + 0x0210 + (master) * 0x20 + (pool) * 0x4)
+
+#define TOPAZ_HBM_RELEASE_BUF		(BIT(0))
+#define TOPAZ_HBM_REQUEST_BUF		(BIT(1))
+#define TOPAZ_HBM_POOL_NUM(x)		((x) << 2)
+#define TOPAZ_HBM_DONE			(BIT(31))
+
+/* SoC interrupts */
+#define TOPAZ_SYS_CTL_M2L_HI_INT	PLATFORM_REG_SWITCH(RUBY_SYS_CTL_M2L_INT, (RUBY_SYS_CTL_BASE_ADDR + 0xFC))
+
+/**
+ * Forwarding Table
+ */
+#define TOPAZ_FWT_BASE_ADDR		(TOPAZ_SWITCH_BASE_ADDR + 0x0)
+#define TOPAZ_FWT_SIZE			(BIT(12))
+
+#define TOPAZ_FWT_TABLE_BASE		(TOPAZ_FWT_BASE_ADDR)
+
+#define TOPAZ_FWT_VLAN_TABLE_BASE	(TOPAZ_FWT_BASE_ADDR + 0x10000)
+#define TOPAZ_FWT_VLAN_TABLE_LIMIT	(TOPAZ_FWT_BASE_ADDR + 0x14000)
+
+#define TOPAZ_FWT_CTRL_BASE_ADDR	(TOPAZ_FWT_BASE_ADDR + 0xA000)
+
+#define TOPAZ_FWT_CPU_ACCESS		(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0000)
+#define TOPAZ_FWT_CPU_ACCESS_STATE	0x0000000F
+#define TOPAZ_FWT_CPU_ACCESS_STATE_S	0
+#define TOPAZ_FWT_CPU_ACCESS_STATE_GRANTED	0x3
+#define TOPAZ_FWT_CPU_ACCESS_REQ	BIT(31)
+#define TOPAZ_FWT_TIME_STAMP_CTRL	(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0004)
+#define TOPAZ_FWT_TIME_STAMP_CTRL_UNIT		0x0000001F
+#define TOPAZ_FWT_TIME_STAMP_CTRL_UNIT_S	0
+#define TOPAZ_FWT_TIME_STAMP_CTRL_SCALE		0x000003e0
+#define TOPAZ_FWT_TIME_STAMP_CTRL_SCALE_S	5
+#define TOPAZ_FWT_TIME_STAMP_DIS_AUTO_UPDATE_S	(16)
+#define TOPAZ_FWT_TIME_STAMP_CTRL_CLEAR		BIT(31)
+#define TOPAZ_FWT_TIME_STAMP_CNT	(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0008)
+#define TOPAZ_FWT_HASH_CTRL		(TOPAZ_FWT_CTRL_BASE_ADDR + 0x000c)
+#define TOPAZ_FWT_HASH_CTRL_ENABLE	BIT(15)
+
+#define TOPAZ_FWT_LOOKUP_LHOST		0
+#define TOPAZ_FWT_LOOKUP_MUC		1
+#define TOPAZ_FWT_LOOKUP_DSP		2
+#define TOPAZ_FWT_LOOKUP_AUC		3
+
+#define	__TOPAZ_FWT_LOOKUP_REG(x)	(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0010 + ((x) * 0x10))
+#define	__TOPAZ_FWT_LOOKUP_MAC_LO(x)	(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0014 + ((x) * 0x10))
+#define	__TOPAZ_FWT_LOOKUP_MAC_HI(x)	(TOPAZ_FWT_CTRL_BASE_ADDR + 0x0018 + ((x) * 0x10))
+
+#define TOPAZ_FWT_LOOKUP_TRIG		0x00000001
+#define TOPAZ_FWT_LOOKUP_TRIG_S		0
+#define TOPAZ_FWT_LOOKUP_ENTRY_ADDR	0x7FF00000
+#define TOPAZ_FWT_LOOKUP_ENTRY_ADDR_S	20
+#define TOPAZ_FWT_LOOKUP_HASH_ADDR	0x0003FF00
+#define TOPAZ_FWT_LOOKUP_HASH_ADDR_S	8
+#define TOPAZ_FWT_LOOKUP_VALID		0x80000000
+#define TOPAZ_FWT_LOOKUP_VALID_S	31
+
+#define TOPAZ_FWT_PORT_EMAC0		(0)
+#define TOPAZ_FWT_PORT_EMAC1		(1)
+#define TOPAZ_FWT_PORT_WMAC		(2)
+#define TOPAZ_FWT_PORT_PCIE		(3)
+#define TOPAZ_FWT_PORT_LH		(4)
+#define TOPAZ_FWT_PORT_MUC		(5)
+#define TOPAZ_FWT_PORT_DSP		(6)
+#define TOPAZ_FWT_PORT_AUC		(7)
+
+#define TOPAZ_FWT_ENTRY_NXT_ENTRY	0x0FFE0000
+#define TOPAZ_FWT_ENTRY_NXT_ENTRY_S	17
+#define TOPAZ_FWT_ENTRY_VALID		0x80000000
+#define TOPAZ_FWT_ENTRY_VALID_S		31
+#define TOPAZ_FWT_ENTRY_PORTAL		0x40000000
+#define TOPAZ_FWT_ENTRY_PORTAL_S	30
+
+#define TOPAZ_FWT_ENTRY_OUT_NODE_0		0x0000007F
+#define TOPAZ_FWT_ENTRY_OUT_NODE_0_S		0
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_0		0x00000080
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_0_S	7
+#define TOPAZ_FWT_ENTRY_OUT_NODE_1		0x00007F00
+#define TOPAZ_FWT_ENTRY_OUT_NODE_1_S		8
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_1		0x00008000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_1_S	15
+#define TOPAZ_FWT_ENTRY_OUT_NODE_2		0x007F0000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_2_S		16
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_2		0x00800000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_2_S	23
+#define TOPAZ_FWT_ENTRY_OUT_NODE_3		0x7F000000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_3_S		24
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_3		0x80000000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_3_S	31
+#define TOPAZ_FWT_ENTRY_OUT_NODE_4		0x007F0000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_4_S		16
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_4		0x00800000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_4_S	23
+#define TOPAZ_FWT_ENTRY_OUT_NODE_5		0x7F000000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_5_S		24
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_5		0x80000000
+#define TOPAZ_FWT_ENTRY_OUT_NODE_VLD_5_S	31
+
+#define TOPAZ_FWT_ENTRY_OUT_PORT	0x00003C00
+#define TOPAZ_FWT_ENTRY_OUT_PORT_S	10
+
+#define TOPAZ_FWT_ENTRY_TIMESTAMP	0x000003FF
+#define TOPAZ_FWT_ENTRY_TIMESTAMP_S	0
+
+#define TOPAZ_FWT_HW_HASH_SHIFT		10
+#define TOPAZ_FWT_HW_HASH_MASK		((1 << TOPAZ_FWT_HW_HASH_SHIFT) - 1)
+#define TOPAZ_FWT_HW_LEVEL1_ENTRIES	(1 << TOPAZ_FWT_HW_HASH_SHIFT)
+#define TOPAZ_FWT_HW_LEVEL2_ENTRIES	1024
+#define TOPAZ_FWT_HW_TOTAL_ENTRIES	(TOPAZ_FWT_HW_LEVEL1_ENTRIES + TOPAZ_FWT_HW_LEVEL2_ENTRIES)
+
+/*
+ * VLAN table
+ */
+#define TOPAZ_VLAN_BASE_ADDR		(TOPAZ_SWITCH_BASE_ADDR + 0x10000)
+#define TOPAZ_VLAN_ENTRIES		(1 << 12)	/* 802.1Q VLAN ID */
+#define TOPAZ_VLAN_ENTRY_ADDR(x)	(TOPAZ_VLAN_BASE_ADDR + 4 * (x))
+#define TOPAZ_VLAN_OUT_NODE		0x0000007F
+#define TOPAZ_VLAN_OUT_NODE_S		0
+#define TOPAZ_VLAN_OUT_PORT		0x00000380
+#define TOPAZ_VLAN_OUT_PORT_S		7
+#define TOPAZ_VLAN_VALID		0x00000400
+#define TOPAZ_VLAN_VALID_S		10
+#define TOPAZ_VLAN_HW_BITMASK		0x000007ff
+
+/* TX AGG */
+#define TOPAZ_TX_AGG_BASE_ADDR				0xE5090000
+#define TOPAZ_TX_AGG_NODE_N_TID_Q_AVAIL(node)		(TOPAZ_TX_AGG_BASE_ADDR + 0x000 + 4 * (node))
+#define TOPAZ_TX_AGG_NODE_N_TID_Q_AVAIL_MASK(val)	((val & 0xFFFF) << 16)
+#define TOPAZ_TX_AGG_NODE_N_TID_Q_AVAIL_SUP(node)	(TOPAZ_TX_AGG_BASE_ADDR + 0x200 + 4 * (node))
+#define TOPAZ_TX_AGG_NODE_N_TID_Q_AVAIL_SUP_MASK(val)	((val & 0xFFFF) << 16)
+#define TOPAZ_TX_AGG_CSR				(TOPAZ_TX_AGG_BASE_ADDR + 0x460)
+#define TOPAZ_TX_AGG_TAC_MAP_MODE_64			0
+#define TOPAZ_TX_AGG_TAC_MAP_MODE_128			1
+#define TOPAZ_TX_AGG_AC					0xF0000000
+#define TOPAZ_TX_AGG_AC_S				28
+#define TOPAZ_TX_AGG_CPU_Q_ACCESS_SEM			(TOPAZ_TX_AGG_BASE_ADDR + 0x464)
+#define TOPAZ_TX_AGG_UC_Q_ACCESS_SEM			(TOPAZ_TX_AGG_BASE_ADDR + 0x468)
+#define TOPAZ_TX_AGG_TAC_CNTL				(TOPAZ_TX_AGG_BASE_ADDR + 0x46C)
+#ifdef TOPAZ_128_NODE_MODE
+#define TOPAZ_TX_AGG_TAC_CNTL_NODE(node)		((node) & 0x7F)
+#else
+#define TOPAZ_TX_AGG_TAC_CNTL_NODE(node)		((node) & 0x3F)
+#endif
+#define TOPAZ_TX_AGG_TAC_CNTL_TID(tid)			(((tid) & 0xF) << 8)
+#define TOPAZ_TX_AGG_TAC_CNTL_READ_CMD(cmd)		(((cmd) & 0x3) << 12)
+#define TOPAZ_TX_AGG_TAC_CNTL_READ_DATA_VLD		RUBY_BIT(29)
+#define TOPAZ_TX_AGG_TAC_CNTL_READ			RUBY_BIT(30)
+#define TOPAZ_TX_AGG_TAC_CNTL_WRITE			RUBY_BIT(31)
+#define TOPAZ_TX_AGG_TAC_DATA				(TOPAZ_TX_AGG_BASE_ADDR + 0x470)
+#define TOPAZ_TX_AGG_TAC_DATA_AC(__ac)			((__ac) & 0x3)
+#define TOPAZ_TX_AGG_TAC_DATA_PRIORITY(__pri)		(((__pri) & 0xFF) << 2)
+#ifdef TOPAZ_128_NODE_MODE
+#define TOPAZ_TX_AGG_TAC_DATA_AC_LO			0x00000003
+#define TOPAZ_TX_AGG_TAC_DATA_AC_LO_S			0
+#define TOPAZ_TX_AGG_TAC_DATA_PRIORITY_LO		0x0000001c
+#define TOPAZ_TX_AGG_TAC_DATA_PRIORITY_LO_S		2
+#define TOPAZ_TX_AGG_TAC_DATA_AC_HI			0x00000060
+#define TOPAZ_TX_AGG_TAC_DATA_AC_HI_S			5
+#define TOPAZ_TX_AGG_TAC_DATA_PRIORITY_HI		0x00000380
+#define TOPAZ_TX_AGG_TAC_DATA_PRIORITY_HI_S		7
+#endif
+#define TOPAZ_TX_AGG_AC_N_NODE_TID(ac)			(TOPAZ_TX_AGG_BASE_ADDR + 0x478 + 4 * (ac))
+#define TOPAZ_TX_AGG_AC_N_STAT_PTR(ac)			(TOPAZ_TX_AGG_BASE_ADDR + 0x488 + 4 * (ac))
+#define TOPAZ_TX_AGG_Q_FULL_THRESH			(TOPAZ_TX_AGG_BASE_ADDR + 0x498)
+#define TOPAZ_TX_AGG_Q_FULL_THRESH_VAL(q0, q1, q2, q3)	(((q0) & 0xF) | (((q1) & 0xF) << 4) | (((q2) & 0xF) << 8) | (((q3) & 0xF) << 12))
+#define TOPAZ_TX_AGG_CPU_IRQ_CSR			(TOPAZ_TX_AGG_BASE_ADDR + 0x49C)
+#define TOPAZ_TX_AGG_STATUS_IRQ				(TOPAZ_TX_AGG_BASE_ADDR + 0x4A0)
+#define TOPAZ_TX_AGG_AC_N_NODE_TID_NO_SEL(ac)		(TOPAZ_TX_AGG_BASE_ADDR + 0x4A4 + 4 * (ac))
+#define TOPAZ_TX_AGG_TAC_CNTL_READ_CMD_NODE_TAB		0
+#define TOPAZ_TX_AGG_TAC_CNTL_READ_CMD_AVAIL_LO		1
+#define TOPAZ_TX_AGG_TAC_CNTL_READ_CMD_AVAIL_HI		3
+#define TOPAZ_TX_AGG_MAX_NODE_NUM			128
+#define TOPAZ_TX_AGG_HALF_MAX_NODE_NUM			(TOPAZ_TX_AGG_MAX_NODE_NUM >> 1)
+
+/*
+ * MuC/Lhost new interrupts.
+ * Old interrupts (even changed number) are in ruby_platform, RUBY_IRQ_*
+ */
+#define	TOPAZ_IRQ_TQE					(5)
+#define TOPAZ_IRQ_HDMA0					(RUBY_IRQ_DMA0)
+#define TOPAZ_IRQ_HBM					(RUBY_IRQ_DMA1)
+#define TOPAZ_IRQ_HDMA1					(RUBY_IRQ_DMA3)
+#define TOPAZ_IRQ_PCIE					(28)
+#define TOPAZ_IRQ_IPC_A2M				(18)
+#define TOPAZ_IQR_TQE_DSP				(19)
+#define	TOPAZ_IRQ_PCIE_DMA				(RUBY_IRQ_DMA2)
+#define	TOPAZ_IRQ_IPC4					(29)
+#define	TOPAZ_MUC_IRQ_BB_PER_PKT			(31)
+#define TOPAZ_HBM_INT_EN				RUBY_BIT(31)
+#define TOPAZ_PCIE_INTX_CLR_MASK			RUBY_BIT(11)
+#define	TOPAZ_PCIE_INT_MASK				RUBY_PCIE_INT_MASK
+#define	TOPAZ_PCIE_MSI_MASK				RUBY_PCIE_MSI_MASK
+#define TOPAZ_PCIE_MSI_EN				RUBY_BIT(0)
+#define TOPAZ_PCIE_MSI_BASE				0xE9000050
+#define TOPAZ_PCIE_MSI_CAP				(TOPAZ_PCIE_MSI_BASE + 0x0)
+
+#define TOPAZ_PCIE_EXP_DEVCTL				(0xE9000078)
+
+/* MSI defines to be used in Topaz PCIe host driver */
+#define	TOPAZ_PCIE_MSI_REGION				RUBY_PCIE_MSI_REGION
+#define	TOPAZ_MSI_ADDR_LOWER				RUBY_MSI_ADDR_LOWER
+#define	TOPAZ_MSI_ADDR_UPPER				RUBY_MSI_ADDR_UPPER
+#define	TOPAZ_MSI_INT_ENABLE				RUBY_MSI_INT_ENABLE
+
+/* AHB Bus monitors */
+#define TOPAZ_BUSMON_INTR_STATUS			(RUBY_SYS_CTL_BASE_ADDR + 0x015c)
+#define TOPAZ_BUSMON_INTR_MASK				(RUBY_SYS_CTL_BASE_ADDR + 0x0160)
+#define TOPAZ_BUSMON_INTR_MASK_TIMEOUT_EN(master)	BIT((master) * 2 + 0)
+#define TOPAZ_BUSMON_INTR_MASK_RANGE_CHECK_EN(master)	BIT((master) * 2 + 1)
+#define TOPAZ_BUSMON_DEBUG_VIEW				(RUBY_SYS_CTL_BASE_ADDR + 0x0164)
+#define TOPAZ_BUSMON_DEBUG_VIEW_MASTER(x)		(((x) & 0x3) << 0)
+#define TOPAZ_BUSMON_DEBUG_VIEW_DATA_SEL(x)		(((x) & 0x7) << 2)
+#define TOPAZ_BUSMON_DEBUG_STATUS			(RUBY_SYS_CTL_BASE_ADDR + 0x0168)
+#define TOPAZ_BUSMON_CTL_BASE_ADDR			(RUBY_SYS_CTL_BASE_ADDR + 0x0200)
+#define TOPAZ_BUSMON_CTL(core)				(TOPAZ_BUSMON_CTL_BASE_ADDR + ((core) * 0x40))
+#define __TOPAZ_BUSMON_CTL_RANGE(core, range)		(TOPAZ_BUSMON_CTL(core) + 0x8 + ((range) * 0x8))
+#define TOPAZ_BUSMON_CTL_RANGE_LOW(core, range)		(__TOPAZ_BUSMON_CTL_RANGE((core), (range)) + 0x0)
+#define TOPAZ_BUSMON_CTL_RANGE_HIGH(core, range)	(__TOPAZ_BUSMON_CTL_RANGE((core), (range)) + 0x4)
+#define TOPAZ_BUSMON_HREADY_EN				BIT(0)
+#define TOPAZ_BUSMON_TIMER_INT_EN			BIT(1)
+#define TOPAZ_BUSMON_TIMER_ERROR_EN			BIT(2)
+#define TOPAZ_BUSMON_ADDR_CHECK_EN			BIT(3)
+#define TOPAZ_BUSMON_REGION_VALID(x)			(((x) & 0xF) << 4)
+#define TOPAZ_BUSMON_TIMEOUT(cycles)			(((cycles) & 0x3FF) << 8)
+#define TOPAZ_BUSMON_BLOCK_TRANS_EN			BIT(18)
+#define TOPAZ_BUSMON_OUTSIDE_ADDR_CHECK			BIT(19)
+
+/* AHB Bus monitor masters */
+#define TOPAZ_BUSMON_LHOST				0
+#define TOPAZ_BUSMON_MUC				1
+#define TOPAZ_BUSMON_DSP				2
+#define TOPAZ_BUSMON_AUC				3
+#define TOPAZ_BUSMON_WMAC				4
+#define TOPAZ_BUSMON_PCIE				5
+#define TOPAZ_BUSMON_SWE				6
+#define TOPAZ_BUSMON_EMAC				7
+
+#define TOPAZ_BUSMON_MASTER_NAMES	{ "lhost", "muc", "dsp", "auc", "wmac", "pcie", "swe", "emac" }
+
+/* AHB Bus monitor debug data select */
+#define TOPAZ_BUSMON_ADDR				0
+#define TOPAZ_BUSMON_WR_L32				1
+#define TOPAZ_BUSMON_WR_H32				2
+#define TOPAZ_BUSMON_RD_L32				3
+#define TOPAZ_BUSMON_RD_H32				4
+#define TOPAZ_BUSMON_CTRL0				5
+#define TOPAZ_BUSMON_CTRL1				6
+#define TOPAZ_BUSMON_CTRL2				7
+#define TOPAZ_BUSMON_DEBUG_MAX				8
+
+/* GPIO Registers */
+#define RUBY_GPIO3_PWM1					(RUBY_GPIO1_PWM0 + 4)
+#define RUBY_GPIO12_PWM3				(RUBY_GPIO1_PWM0 + 12)
+#define RUBY_GPIO13_PWM4				(RUBY_GPIO1_PWM0 + 16)
+#define RUBY_GPIO15_PWM5				(RUBY_GPIO1_PWM0 + 20)
+#define RUBY_GPIO16_PWM6				(RUBY_GPIO1_PWM0 + 24)
+#define RUBY_GPIO_PWM_LOW_SHIFT				(0)
+#define RUBY_GPIO_PWM_HIGH_SHIFT			(8)
+#define RUBY_GPIO_PWM_ENABLE				(BIT(16))
+#define RUBY_GPIO_PWM_MAX_COUNT				(255)
+
+#ifdef TOPAZ_AMBER_IP
+#define	AMBER_GPIO11_PWM0				(RUBY_GPIO_REGS_ADDR + 0x20)
+#define AMBER_GPIO12_PWM1				(RUBY_GPIO_REGS_ADDR + 0x24)
+#define	AMBER_GPIO13_PWM2				(RUBY_GPIO_REGS_ADDR + 0x28)
+#define AMBER_GPIO14_PWM3				(RUBY_GPIO_REGS_ADDR + 0x2C)
+#define AMBER_GPIO15_PWM4				(RUBY_GPIO_REGS_ADDR + 0x30)
+#define AMBER_GPIO16_PWM5				(RUBY_GPIO_REGS_ADDR + 0x34)
+#define AMBER_GPIO17_PWM6				(RUBY_GPIO_REGS_ADDR + 0x38)
+#endif
+
+/* Interrupt lines */
+#define TOPAZ_IRQ_MISC_WDT				(57)
+#define TOPAZ_IRQ_MISC_SPI1				(58)
+#define TOPAZ_IRQ_MISC_AHB_MON				(61)
+#define TOPAZ_IRQ_MISC_HBM				(62)
+#define TOPAZ_IRQ_MISC_FWT				(63)
+#define TOPAZ_IRQ_MISC_EXT_IRQ_COUNT			(8)
+#define TOPAZ_IRQ_MISC_RST_CAUSE_START			(9)
+
+/* RESET CAUSE */
+#define TOPAZ_SYS_CTL_INTR_TIMER_MSK(t)		(1 << (3 + (t)))
+
+#endif /* #ifndef __TOPAZ_PLATFORM_H */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_reset.h b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_reset.h
new file mode 100644
index 0000000..fab7393
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_reset.h
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2015 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/* This header file defines reset function to be used on Topaz */
+
+#ifndef __TOPAZ_RESET_H
+#define __TOPAZ_RESET_H
+
+#include <include/qtn/mproc_sync_base.h>
+#ifdef TOPAZ_AMBER_IP
+#include <include/qtn/amber.h>
+#endif
+
+static void topaz_set_reset_vec(int enable, unsigned long reset)
+{
+#ifdef TOPAZ_AMBER_IP
+	unsigned long flush_mask = 0;
+
+	switch (reset) {
+	case TOPAZ_SYS_CTL_RESET_AUC:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_AUC;
+		break;
+	case RUBY_SYS_CTL_RESET_DSP_ALL:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_DSP;
+		break;
+	case RUBY_SYS_CTL_RESET_MUC_ALL:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_MUC;
+		break;
+	case RUBY_SYS_CTL_RESET_ENET0:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_RGMII;
+		break;
+	case RUBY_SYS_CTL_RESET_IOSS:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_BRIDGE | TOPAZ_AMBER_BUS_FLUSH_DMA;
+		break;
+	case RUBY_SYS_CTL_RESET_MAC:
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_WMAC;
+		break;
+	case RUBY_SYS_CTL_RESET_BB:
+		flush_mask = 0;
+		break;
+	default:
+		/* In the case we accidentally get here - request/release flush for everything to be safe */
+		flush_mask = TOPAZ_AMBER_BUS_FLUSH_AUC |
+			TOPAZ_AMBER_BUS_FLUSH_DSP |
+			TOPAZ_AMBER_BUS_FLUSH_MUC |
+			TOPAZ_AMBER_BUS_FLUSH_RGMII |
+			TOPAZ_AMBER_BUS_FLUSH_BRIDGE |
+			TOPAZ_AMBER_BUS_FLUSH_DMA |
+			TOPAZ_AMBER_BUS_FLUSH_WMAC |
+			TOPAZ_AMBER_BUS_FLUSH_LHOST;
+		qtn_mproc_sync_log("%s:%u: error - invalid reset flag 0x%08x\n", __FILE__, __LINE__, reset);
+		break;
+	}
+
+	if (!enable && flush_mask) {
+		/* Need to request bus flush before switching off */
+		amber_bus_flush_req(flush_mask);
+	}
+#endif
+
+	qtn_mproc_sync_mem_write(RUBY_SYS_CTL_CPU_VEC_MASK, reset);
+	qtn_mproc_sync_mem_write_wmb(RUBY_SYS_CTL_CPU_VEC, enable ? reset : 0);
+	qtn_mproc_sync_mem_write_wmb(RUBY_SYS_CTL_CPU_VEC_MASK, 0);
+
+#ifdef TOPAZ_AMBER_IP
+	if (enable && flush_mask) {
+		/* Need to release bus flush after switching on */
+		amber_bus_flush_release(flush_mask);
+	}
+#endif
+
+}
+#endif // #ifndef __TOPAZ_RESET_H
+
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_rfic6_config b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_rfic6_config
new file mode 100644
index 0000000..0b7d498
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/topaz_rfic6_config
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2010 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Header file which describes Topaz platform.
+ * Has to be used by both kernel and bootloader.
+ */
+
+#ifndef __TOPAZ_CONFIG_H
+#define __TOPAZ_CONFIG_H
+
+#include "current_platform.h"
+
+#if !TOPAZ_FPGA_PLATFORM
+#undef TOPAZ_ICACHE_WORKAROUND
+#endif
+
+/*
+ * Control registers move depending on unified + alias bit
+ */
+
+#define TOPAZ_MMAP_UNIFIED	0
+#define TOPAZ_MMAP_ALIAS	0
+#define TOPAZ_RX_ACCELERATE	1
+
+/*
+ * VSP/QTM
+ * Macro TOPAZ_QTM is used to help identify changes between original VSP and QTM.
+ * In Lhost kernel driver, it must be used within CONFIG_QVSP(in kernel .config).
+ * CONFIG_QVSP	TOPAZ_QTM	ruby		topaz
+ * Y		1		invalid		*QTM works
+ * Y		0		*VSP works	VSP alive but doesn't work for HDP
+ * N		1		invalid		*no VSP/QTM
+ * N		0		*no VSP		no VSP/QTM, and no QTM changes in MuC and AuC
+ * So generally, sololy changing CONFIG_QVSP works for both ruby and topaz as indicated by *.
+ * But to throughly clean QTM code in AuC and MuC, disable TOPAZ_QTM in topaz below.
+ */
+	#define TOPAZ_QTM		1
+
+/*
+ * HBM buffer process in MuC requires that TOPAZ_AUC_RX is dependent on TOPAZ_RX_ACCELERATE, so let's
+ * enable TOPAZ_AUC_RX only when TOPAZ_RX_ACCELERATE is enabled.
+ */
+#if TOPAZ_RX_ACCELERATE
+#define TOPAZ_AUC_RX	1
+#else
+#define TOPAZ_AUC_RX	0
+#endif
+
+#if TOPAZ_MMAP_ALIAS && !TOPAZ_MMAP_UNIFIED
+	#error Alias map requires unified map
+#endif
+
+#if TOPAZ_MMAP_ALIAS
+	#define TOPAZ_ALIAS_MAP_SWITCH(a, b)	(b)
+#else
+	#define TOPAZ_ALIAS_MAP_SWITCH(a, b)	(a)
+#endif
+
+/* Topaz fixed phy addresses */
+#define TOPAZ_FPGAA_PHY0_ADDR		2
+#define TOPAZ_FPGAA_PHY1_ADDR		3
+#define TOPAZ_FPGAB_PHY0_ADDR		4
+#define TOPAZ_FPGAB_PHY1_ADDR		1
+#define TOPAZ_PHY0_ADDR				1
+#define TOPAZ_PHY1_ADDR				3
+
+#ifndef TOPAZ_FPGA_PLATFORM
+	#define TOPAZ_FPGA_PLATFORM	0
+#endif
+
+/* Definition indicates that Topaz platform is FPGA */
+#if TOPAZ_FPGA_PLATFORM
+	/* CLK speeds are in MHz and 1/10th the speed of actual ASIC */
+	#define TOPAZ_SERIAL_BAUD	38400
+	#define TOPAZ_APB_CLK		12500000
+	#define TOPAZ_AHB_CLK		25000000
+	#define TOPAZ_CPU_CLK		50000000
+	#define RUBY_FPGA_DDR
+#else
+	#define TOPAZ_SERIAL_BAUD	115200
+	#define TOPAZ_APB_CLK		125000000
+	#define TOPAZ_AHB_CLK		250000000
+	#define TOPAZ_CPU_CLK		500000000
+	#define RUBY_ASIC_DDR
+#endif /* #if TOPAZ_FPGA_PLATFORM */
+
+/*
+ * Setting UPF_SPD_FLAG gives a developer the option to set the
+ * flag to match a UPF_ define from <linux>/include/linux/serial_core.h
+ * or set the value to 0 to use the default baud rate setting DEFAULT_BAUD
+ */
+#define UPF_SPD_FLAG	0
+#define DEFAULT_BAUD	TOPAZ_SERIAL_BAUD
+
+/*
+ * Re-use Ruby defines to simplify the number of changes required
+ * to compile new binaries for Topaz
+ */
+#define RUBY_SERIAL_BAUD	TOPAZ_SERIAL_BAUD
+#define RUBY_FIXED_DEV_CLK	TOPAZ_APB_CLK
+#define RUBY_FIXED_CPU_CLK	TOPAZ_CPU_CLK
+
+#ifdef PLATFORM_DEFAULT_BOARD_ID
+        #define DEFAULT_BOARD_ID	PLATFORM_DEFAULT_BOARD_ID
+#else
+	/* Default board id used to match Topaz setting if there is no SPI Flash */
+	#define DEFAULT_BOARD_ID	QTN_TOPAZ_BB_BOARD
+#endif /* TOPAZ_DEFAULT_BOARD_ID */
+
+#ifndef PLATFORM_ARC7_MMU_VER
+	#define PLATFORM_ARC7_MMU_VER	2
+#endif
+
+#define CONFIG_RUBY_BROKEN_IPC_IRQS	0
+
+#define RUBY_IPC_HI_IRQ(bit_num)	((bit_num) + 8)
+#define RUBY_M2L_IPC_HI_IRQ(bit_num)	(bit_num)
+
+#define PLATFORM_REG_SWITCH(reg1, reg2)	(reg2)
+
+#define writel_topaz(a, b)		writel(a, b)
+#define writel_ruby(a, b)
+
+#define QTN_VLAN_LLC_ENCAP		1
+
+#define TOPAZ_128_NODE_MODE		1
+
+#endif /* #ifndef __TOPAZ_CONFIG_H */
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/uboot_header.h b/arch/arc/plat-qtn/sdk-qsr1000/common/uboot_header.h
new file mode 100644
index 0000000..478cf06
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/uboot_header.h
@@ -0,0 +1,70 @@
+/*
+ *  Copyright (c) 2015 Quantenna Communications, Inc.
+ *  All rights reserved.
+ *
+ * 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
+ *
+ * This code is taken from u-boot/include/image.h file
+ */
+#ifndef UBOOT_HEADER_H
+#define UBOOT_HEADER_H
+
+#ifndef __ASSEMBLY__
+#define IH_MAGIC      0x27051956      /* Image Magic Number           */
+#define IH_NMLEN              32      /* Image Name Length            */
+
+/*
+ * Legacy format image header,
+ * all data in network byte order (aka natural aka bigendian).
+ */
+typedef struct image_header {
+	uint32_t        ih_magic;       /* Image Header Magic Number    */
+	uint32_t        ih_hcrc;        /* Image Header CRC Checksum    */
+	uint32_t        ih_time;        /* Image Creation Timestamp     */
+	uint32_t        ih_size;        /* Image Data Size              */
+	uint32_t        ih_load;        /* Data  Load  Address          */
+	uint32_t        ih_ep;          /* Entry Point Address          */
+	uint32_t        ih_dcrc;        /* Image Data CRC Checksum      */
+	uint8_t         ih_os;          /* Operating System             */
+	uint8_t         ih_arch;        /* CPU architecture             */
+	uint8_t         ih_type;        /* Image Type                   */
+	uint8_t         ih_comp;        /* Compression Type             */
+	uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
+} image_header_t;
+
+static inline uint32_t image_get_header_size(void)
+{
+#define MAX_KNOWN_PAGE_SIZE 8192
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
+	return ROUND_UP(sizeof(image_header_t), MAX_KNOWN_PAGE_SIZE);
+}
+
+struct early_flash_config {
+	uint32_t	method;
+	uint32_t	ipaddr;
+	uint32_t	serverip;
+	uint8_t		reserved[8];
+	uint8_t		built_time_utc_sec[11];
+	uint8_t		uboot_type;
+} __attribute__ ((packed));
+#endif /* __ASSEMBLY__ */
+
+#define RUBY_BOOT_METHOD_TRYLOOP        0
+#define RUBY_BOOT_METHOD_TFTP           1
+#define RUBY_BOOT_METHOD_BOOTP          2
+#define RUBY_BOOT_METHOD_MAX            3
+
+#endif /* UBOOT_HEADER_H */
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/ums_platform.h b/arch/arc/plat-qtn/sdk-qsr1000/common/ums_platform.h
new file mode 100755
index 0000000..ff8e7bd
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/ums_platform.h
@@ -0,0 +1,347 @@
+/*
+ *  common/ums_platform.h
+ *
+ *  Copyright (c) Quantenna Communications Incorporated 2007.
+ *  All rights reserved.
+ *
+ * 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
+ *
+ * This file holds the hardware specific memory map and common declarations
+ * for the UMS build system.  The defines here are used in the bootrom,
+ * the U-Boot bootloader and the linux kernel.
+ *
+ * This file should only contain definitions that are assembler-friendly.
+ */
+
+#ifndef __UMS_PLATFORM_H
+#define __UMS_PLATFORM_H	1
+
+/* ================ System boot modes ================ */
+/* These are used in the boot rom which is hardcoded into
+ * the chip.  Do not change them unless the chip changes.
+ */
+#define BMODE_PRODUCTION_TEST 0
+#define BMODE_SERIAL_ICC 1
+#define BMODE_NOR 2
+
+/* ================ Physical address map ================ */
+#define UMS_DDR				0x00000000
+#define UMS_SRAM			0x80000000
+#define UMS_SRAM_SIZE			0x00080000
+#define UMS_EBB_CS0			0x90000000
+#define UMS_EBB_CS1			0x91000000
+#define UMS_EBB_CS2			0x92000000
+#define UMS_EBB_CS3			0x93000000
+#define UMS_EBB_CS4			0x94000000
+#define UMS_BOOTROM			0xA0000000
+#define UMS_ARM_ITCM			0xB0000000
+#define UMS_ITCM_SIZE			0x00008000
+#define UMS_ARM_DTCM			0xB0100000
+#define UMS_DTCM_SIZE			0x00008000
+#define UMS_REGS_DSP_UART		0xD0000000
+#define UMS_REGS_DSP_GPIO		0xD1000000
+#define UMS_REGS_DSP_SPI		0xD3000000
+#define UMS_REGS_DSP_CTRLRESET		0xD8000000
+#define UMS_REGS_DSP_MSP		0xD9000000
+#define UMS_REGS_DSP_XMEM		0xDCF80000
+#define UMS_REGS_DSP_YMEM		0xDCFA0000
+#define UMS_REGS_SYSCTRL		0xE0000000
+#define UMS_REGS_DDR			0xE1000000
+#define UMS_REGS_EBI			0xE2000000
+#define UMS_REGS_SRAM			0xE3000000
+#define UMS_REGS_MB			0xE4000000
+#define UMS_REGS_MAC			0xE5000000
+#define UMS_REGS_BB			0xE6000000
+#define UMS_REGS_RADAR			0xE6080000
+#define UMS_REGS_BB2			0xE6800000
+#define UMS_REGS_RADAR2			0xE6880000
+#define UMS_REGS_ICC			0xE8000000
+#define UMS_REGS_USB			0xE9000000
+#define UMS_REGS_ULA			0xEC000000
+#define UMS_REGS_ULA_MB         0xEC200000
+#define UMS_REGS_ETHERNET0		0xED000000
+#define UMS_REGS_ARM_UART0		0xF0000000
+#define UMS_REGS_ARM_GPIO		0xF1000000
+#define UMS_REGS_ARM_SPI		0xF2000000
+#define UMS_REGS_ARM_TIMERS		0xF3000000
+#define UMS_REGS_ARM_WATCHDOG		0xF4000000
+#define UMS_REGS_ARM_UART1		0xF5000000
+#define UMS_REGS_ARM_DMA		0xF8000000
+#define UMS_REGS_ARM_DSPI2C		0xF9000000
+#define UMS_REGS_ARM_VICS		0xFFF00000
+
+/* Explicit virtual address mappings for TCMs */
+#define UMS_ARM_ITCM_VA			0xFB000000
+#define UMS_ARM_DTCM_VA			0xFB100000
+
+#define UMS_ARM_SRAM_AREA		UMS_SRAM + CONFIG_ARCH_UMS_MUC_SRAM_REQUIREMENT
+#define UMS_ARM_SRAM_AREA_VA		IO_ADDRESS(UMS_ARM_SRAM_AREA)
+
+/* !!! FIXME_UMS - at present SRAM lives in IO address space */
+#define UMS_IO_AREA_START		UMS_SRAM
+
+/* ============== Interrupt functions ============== */
+
+/* Set bits in these values to make an interrupt a FIQ rather than an IRQ.
+   SELECT0 is for interrupts 0-31, SELECT1 for the others.
+*/
+#define FIQ_SELECT0 (0)
+#define FIQ_SELECT1 (0)
+
+#define VIC0_OFFSET	0x000FF000
+#define VIC1_OFFSET	0x000FE000
+#define INTERRUPT_VA0(a) (IO_ADDRESS(UMS_REGS_ARM_VICS) + VIC0_OFFSET + (a))
+#define INTERRUPT_VA1(a) (IO_ADDRESS(UMS_REGS_ARM_VICS) + VIC1_OFFSET + (a))
+#define PL192_IRQSTATUS (0)
+#define PL192_INTSELECT (0x0c)
+#define PL192_ENABLE (0x10)
+#define PL192_DISABLE (0x14)
+#define PL192_SOFTINT (0x18)
+#define PL192_SOFTINT_CLEAR (0x1c)
+#define PL192_PROTECTION (0x20)
+#define PL192_PRIORITY_MASK (0x24)
+#define PL192_PRIORITY_DAISY (0x28)
+#define PL192_VECTOR_ADDR (0x100)
+#define PL192_VECTOR_PRIORITY (0x200)
+#define PL192_VECTORADDRESS	0x0F00
+
+/* ============== Timer functions ============== */
+
+#define TIMER_VA(a) (IO_ADDRESS(UMS_REGS_ARM_TIMERS) + (a))
+
+#define TIMER_PRESCALAR_ENABLE (0x00)
+#define TIMER_PRESCALAR0 (0x04)
+#define TIMER_PRESCALAR1 (0x08)
+#define TIMER_CONTROL0 (0x0c)
+#define TIMER_VALUE0 (0x10)
+#define TIMER_CONTROL1 (0x14)
+#define TIMER_VALUE1 (0x18)
+#define TIMER_CONTROL2 (0x1c)
+#define TIMER_VALUE2 (0x20)
+#define TIMER_CONTROL3 (0x24)
+#define TIMER_VALUE3 (0x28)
+#define TIMER_INT_ENABLE (0x2c)
+#define TIMER_INT_STATUS (0x30)
+#define TIMER_INT_CLEAR (0x34)
+
+/* GPIO block register offsets */
+#define GPIO_INPUT		(0x00)
+#define GPIO_OUTPUT_MASK	(0x04)
+#define GPIO_OUTPUT		(0x08)
+#define GPIO_MODE1		(0x0c)
+#define GPIO_MODE2		(0x10)
+#define GPIO_ALTFN		(0x14)
+#define GPIO_ALTFN_DEFVAL	(0x18)
+
+/* GPIO special function GPIO line assignments (ARM GPIO block) */
+#define GPIO_UART0_SI		(0)
+#define GPIO_UART0_nRI		(1)
+#define GPIO_UART0_DSR		(2)
+#define GPIO_UART0_nDCD		(3)
+#define GPIO_UART0_nCTS		(4)
+#define GPIO_SPI_MISO		(5)
+#define GPIO_UART1_SI		(6)
+#define GPIO_UART0_SO		(8)
+#define GPIO_UART0_nRTS		(9)
+#define GPIO_UART0_nDTR		(10)
+#define GPIO_SPI_SCK		(11)
+#define GPIO_SPI_MOSI		(12)
+#define GPIO_UART1_SO		(13)
+#define GPIO_SPI_nCS		(14)
+
+/* alternate use for gpio5 */
+#define GPIO_RGMII_MODE		(5)
+
+/* GPIO mode register values */
+#define GPIO_MODE_INPUT		(0)
+#define GPIO_MODE_OUTPUT	(1)
+#define GPIO_MODE_OSOURCE	(2)
+#define GPIO_MODE_ODRAIN	(3)
+
+/* SPI controller register offsets */
+#define SPI_SPCR		(0x00)
+#define SPI_SPSR		(0x04)
+#define SPI_SPDR		(0x08)
+#define SPI_SPER		(0x0c)
+#define SPI_SLVN		(0x10)
+
+/* SPI status register bits */
+#define SPI_SPSR_RFEMPTY	(1 << 0)
+#define SPI_SPSR_RFFULL		(1 << 1)
+#define SPI_SPSR_WFEMPTY	(1 << 2)
+#define SPI_SPSR_WFFULL		(1 << 3)
+
+/* SPI control register bits */
+#define SPI_SPCR_SPR(x)		(((x) & 3) << 0)
+#define SPI_SPCR_CPHA		(1 << 2)
+#define SPI_SPCR_CPOL		(1 << 3)
+#define SPI_SPCR_MSTR		(1 << 4)
+#define SPI_SPCR_SPE		(1 << 6)
+#define SPI_SPCR_SPIE		(1 << 7)
+
+/* SPI extended control register bits */
+#define SPI_SPER_ESPR(x)	(((x) & 3) << 0)
+#define SPI_SPER_ICNT(x)	(((x) & 3) << 6)
+
+/* System controller register offset and bit position definitions */
+#define SYSCTRL_RESET_MASK	(0x00)
+#define SYSCTRL_RESET		(0x04)
+#define SYSCTRL_CTRL_MASK	(0x08)
+#define SYSCTRL_CTRL		(0x0c)
+#define SYSCTRL_RESET_CAUSE	(0x10)
+#define SYSCTRL_REV_NUMBER	(0x14)
+#define SYSCTRL_RGMII_DELAY	(0x1c)
+
+/* Reset bit positions for RESET_MASK and RESET_VEC registers */
+#define SYSCTRL_ARM_RUN		(1 << 0)
+#define SYSCTRL_EBI_RUN		(1 << 1)
+#define SYSCTRL_DDR_RUN		(1 << 2)
+#define SYSCTRL_SRAM_RUN	(1 << 3)
+#define SYSCTRL_DSPSS_RUN	(1 << 4)
+#define SYSCTRL_DSP_RUN		(1 << 5)
+#define SYSCTRL_MUC_RUN		(1 << 6)
+#define SYSCTRL_NETSS_RUN	(1 << 7)
+#define SYSCTRL_MMC_RUN		(1 << 8)
+#define SYSCTRL_ETHERNET_RUN	(1 << 9)
+#define SYSCTRL_IOSS_RUN	(1 << 10)
+#define SYSCTRL_ICC_RUN		(1 << 12)
+#define SYSCTRL_USB_RUN		(1 << 13)
+#define SYSCTRL_RESET_OUT   (1 << 31)
+
+/* System controller control register */
+#define SYSCTRL_BOOT_MODE(x)	(((x) & 7) << 0)
+#define SYSCTRL_REMAP(x)	(((x) & 3) << 3)
+#define SYSCTRL_CLKSEL(x)	(((x) & 3) << 5)
+#define SYSCTRL_ARM_IS_2X	(1 << 7)
+#define SYSCTRL_DSP_CLK		(1 << 8)
+#define SYSCTRL_MAC_CLK(x)	(((x) & 7) << 9)
+#define SYSCTRL_REMAP_SRAM	(1 << 12)
+#define SYSCTRL_ULPI_ENABLE	(1 << 13)
+#define SYSCTRL_ARM_GPIO_ENABLE	(1 << 14)
+#define SYSCTRL_DSP_GPIO_ENABLE	(1 << 15)
+#define SYSCTRL_EBI_MUXMODE	(1 << 16)
+#define SYSCTRL_ARBITER_MODE(x)	(((x) & 0xf) << 17)
+#define SYSCTRL_SPLIT_DISABLE	(1 << 21)
+#define SYSCTRL_EXT_USBCLK	(1 << 22)
+#define SYSCTRL_PCIE_ENABLE	(1 << 23)
+#define SYSCTRL_NETBUS_SWAP	(1 << 24)
+#define SYSCTRL_IOBUS_SWAP	(1 << 25)
+#define SYSCTRL_DSPBUS_SWAP	(1 << 26)
+
+#define SYSCTRL_REMAP_DDR	(0)
+#define SYSCTRL_REMAP_ROM	(1)
+#define SYSCTRL_REMAP_NOR	(2)
+#define SYSCTRL_REMAP_NAND	(3)
+
+/* Reset cause definitions */
+#define SYSCTRL_HARD_RESET	(1 << 0)
+#define SYSCTRL_SOFT_RESET	(1 << 1)
+#define SYSCTRL_WATCHDOG	(1 << 2)
+#define SYSCTRL_PLL_DRIFT	(1 << 3)
+#define SYSCTRL_EBI_STRAP(x)	(((x) & 3) >> 16)
+
+/* bbic2 bit to switch between 100M and 1000M */
+#define SYS_CTL_GMII_CLK_SEL	(1 << 23)
+#define SYS_CTL_FORCE_RGMII		(0xc0000000)
+
+/* Chip revision macros - use with SYSCTRL_REV_NUMBER */
+#define SYSCTRL_CHIP_MINOR(x)	((x) & 0xff)
+#define SYSCTRL_CHIP_MAJOR(x)	(((x) & 0xff) >> 8)
+#define SYSCTRL_CHIP_TYPE(x)	(((x) & 0xff) >> 16)
+#define SYSCTRL_CHIP_TYPE_UMS	(0)
+
+/* UART register offsets */
+#define PL011_DR	(0x00)
+#define PL011_RSR_ECR	(0x04)
+#define PL011_FR	(0x18)
+#define PL011_ILPR	(0x20)
+#define PL011_IBRD	(0x24)
+#define PL011_FBRD	(0x28)
+#define PL011_LCR_H	(0x2c)
+#define PL011_CR	(0x30)
+#define PL011_IFLS	(0x34)
+#define PL011_IMSC	(0x38)
+#define PL011_RIS	(0x3c)
+#define PL011_MIS	(0x40)
+#define PL011_ICR	(0x44)
+#define PL011_DMACR	(0x48)
+#define PL011_PERIPHID0	(0xfe0)
+#define PL011_PERIPHID1	(0xfe4)
+#define PL011_PERIPHID2	(0xfe8)
+#define PL011_PERIPHID3	(0xfec)
+#define PL011_CELLID0	(0xff0)
+#define PL011_CELLID1	(0xff4)
+#define PL011_CELLID2	(0xff8)
+#define PL011_CELLID3	(0xffc)
+
+/* Static memory controller offsets */
+#define PL241_DIRCMD	(0x1010)
+#define PL241_SETCYC	(0x1014)
+#define PL241_SETOPM	(0x1018)
+#define PL241_SETCYC0	(0x1100)
+#define PL241_SETOPM0	(0x1104)
+
+/* ICC register offsets */
+#define ICC_SRC		(0x00)
+#define ICC_DST		(0x04)
+#define ICC_CTRL	(0x08)
+#define ICC_ISR		(0x0C)
+#define ICC_MASKED_ISR	(0x10)
+#define ICC_IEN		(0x14)
+#define ICC_CLR_RIP	(0x18)
+#define ICC_RD_CMD	(0x20)
+#define ICC_BUSY_FLAG	(1 << 31) /* Busy bit in CTRL register */
+#define ICC_RD_COMPLETE	(1 << 1)  /* Read complete bit in ISR register */
+#define ICC_MAX_XFER	(0x8000) /* Max ICC length = 64kB !!! FIXME */
+
+/* MAC register offsets */
+#define UMS_MAC_IMEM	(0x00000)
+#define UMS_MAC_DMEM	(0x20000)
+#define UMS_MAC_PKTMEM	(0x30000)
+#define UMS_MAC_TXMEM	(0x40000)
+#define UMS_MAC_GBLCTRL	(0x42000)
+#define UMS_MAC0_TXREGS	(0x50000)
+#define UMS_MAC0_RXREGS	(0x52000)
+#define UMS_MAC0_SHARED	(0x53000)
+#define UMS_MAC1_TXREGS	(0x60000)
+#define UMS_MAC1_RXREGS	(0x62000)
+#define UMS_MAC1_SHARED	(0x63000)
+#define UMS_MAC_DMA	(0x70000)
+#define UMS_MAC_HOSTIF	(0x71000)
+
+/* BB register offsets*/
+/* MAY need revisit XXX */
+#define UMS_BB_SPI  (0x40000)
+#define UMS_BB_GAIN (0x50000) 
+#define UMS_BB_XREF (0x60000) 
+#define UMS_BB_RFIC (0x70000)
+#define UMS_BB_RDR  (0x80000)
+#define UMS_BB_COMPQ_MEM  (0xB0000)
+
+/* MBX register offsets */
+#define UMS_MBX_DSP_POP  (0x0000)
+#define UMS_MBX_DSP_PUSH (0x0040)
+#define UMS_MBX_CTRL     (0x0080)
+#define UMS_MBX_STATUS   (0x0084)
+#define UMS_MBX_INT_MSK  (0x0088)
+#define UMS_MBX_INT_CLR  (0x008C)
+
+/* MBX register bitfields */
+#define UMS_MBX_INT0 (1 << 0)
+#define UMS_MBX_INT1 (1 << 1)
+
+#define UMS_MBX_DSP_TO_ARM_EMPTY ( 1 << 24 )
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/Makefile b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/Makefile
new file mode 100644
index 0000000..97415c3
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/Makefile
@@ -0,0 +1,23 @@
+#
+# Copyright (C)2014 Quantenna Communications
+#
+
+TOPDIR=../..
+
+MUC_STATS_HEADER=./muc_txrx_stats.h
+MUC_COMMON_STAT_HEADER=./qtn_muc_stats_print.h
+
+.PHONY: FORCE
+
+all: ${MUC_COMMON_STAT_HEADER}
+
+${MUC_COMMON_STAT_HEADER}: ${MUC_STATS_HEADER} ${MUC_STATS_HEADER}.raw
+
+${MUC_STATS_HEADER}: ${MUC_STATS_HEADER}.raw
+
+${MUC_STATS_HEADER}.raw: FORCE
+	@cat ${MUC_STATS_HEADER} | \
+		${TOPDIR}/host/scripts/struct_get.sh | \
+		grep -v "^[[:blank:]]*$$" > $@
+	./muc_dbg_parse
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_debug_stats.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_debug_stats.h
new file mode 100755
index 0000000..fd26ce5
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_debug_stats.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2013 Quantenna Communications, Inc.
+ */
+
+#ifndef _AUC_DEBUG_STATS_H_
+#define _AUC_DEBUG_STATS_H_
+
+#include <qtn/auc_share_def.h>
+
+/*
+ * Firmware updates counters through such macros as AUC_DBG_INC(), AUC_DBG_INC_OFFSET(), AUC_DBG_INC_COND(), etc.
+ * Other CPU (e.g. Lhost) can read structure and dump counters.
+ * Feel free to add more counters here.
+ * Good to have counters organized and grouped using name prefix.
+ */
+struct auc_dbg_counters
+{
+	/* pktlogger expects task_alive_counters to be the first member of this struct */
+	uint32_t task_alive_counters[AUC_TID_NUM];
+	uint32_t task_false_trigger[AUC_TID_NUM];
+	uint32_t tqew_ac[4];
+	uint32_t tqew_ac_avail[4];
+	uint32_t tqew_air_humble;
+	uint32_t tqew_air_suppress;
+	uint32_t tqew_air_use_idletime;
+	uint32_t tqew_air_dequeue_only;
+	uint32_t tqew_pkt_pending_for_txdone;
+	uint32_t tqew_descr_alloc_fail;
+	uint32_t tqew_ring_alloc_fail;
+	uint32_t tqew_pop_alloc_fail;
+	uint32_t tqew_pop_sw_limit;
+	uint32_t tqew_pop_empty;
+	uint32_t tqew_available_set;
+	uint32_t tqew_available_reset;
+	uint32_t tqew_rx;
+	uint32_t tqew_drop;
+	uint32_t tqew_free;
+	uint32_t tqew_buf_invalid;
+	uint32_t wmac_tx_done[4];
+	uint32_t agg_aggregate_flag;
+	uint32_t agg_aggressive_agg;
+	uint32_t hdrs_available_recent_min;
+	uint32_t agg_states[QTN_AUC_TID_TX_STATE_MAX + 1];
+	uint32_t ethq_push;
+	uint32_t ethq_pop;
+	uint32_t agg_aggregate_mpdu;
+	uint32_t agg_aggregate_msdu;
+	uint32_t agg_singleton_mpdu;
+	uint32_t agg_singleton_mgmt;
+	uint32_t agg_singleton_ctl;
+	uint32_t agg_singleton_probe;
+	uint32_t agg_4K_amsdu;
+	uint32_t agg_8K_amsdu;
+	uint32_t agg_11K_amsdu;
+	uint32_t tx_feedback_success;
+	uint32_t tx_feedback_fail;
+	uint32_t tx_done_status_success;
+	uint32_t tx_done_status_timeout;
+	uint32_t tx_done_status_xretry;
+	uint32_t tx_done_status_timeout_xretry;
+	uint32_t tx_done_pkt_chain_reset;
+	uint32_t tx_done_pkt_chain_success;
+	uint32_t tx_done_pkt_chain_drop_tid_down;
+	uint32_t tx_done_pkt_chain_drop_xattempts;
+	uint32_t tx_done_singleton_finish;
+	uint32_t tx_done_singleton_swretry;
+	uint32_t tx_done_aggregate_finish;
+	uint32_t tx_done_aggregate_hwretry;
+	uint32_t tx_done_aggregate_swretry;
+	uint32_t tx_done_mpdu_swretry;
+	uint32_t tx_sample;
+	uint32_t tx_bw_sample;
+	uint32_t tx_swretry_lower_bw;
+	uint32_t tx_swretry_agg_exceed;
+	uint32_t tx_scale_base_20m;
+	uint32_t tx_scale_base_40m;
+	uint32_t tx_scale_base_80m;
+	uint32_t tx_scale_max;
+	uint32_t tx_scale_overstep;
+	uint32_t alloc_tqew_fast;
+	uint32_t free_tqew_fast;
+	uint32_t alloc_tqew_slow;
+	uint32_t free_tqew_slow;
+	uint32_t alloc_tqew_local;
+	uint32_t free_tqew_local;
+	uint32_t alloc_hdr_fast;
+	uint32_t free_hdr_fast;
+	uint32_t alloc_hdr_slow;
+	uint32_t free_hdr_slow;
+	uint32_t alloc_msdu_hdr_failed;
+	uint32_t alloc_mpdu_hdr_failed;
+	uint32_t alloc_tid_superfast;
+	uint32_t free_tid_superfast;
+	uint32_t alloc_tid_fast;
+	uint32_t free_tid_fast;
+	uint32_t alloc_tid_slow;
+	uint32_t free_tid_slow;
+	uint32_t alloc_node_rate_fast;
+	uint32_t free_node_rate_fast;
+	uint32_t alloc_node_rate_slow;
+	uint32_t free_node_rate_slow;
+	uint32_t alloc_node_superfast;
+	uint32_t free_node_superfast;
+	uint32_t alloc_node_fast;
+	uint32_t free_node_fast;
+	uint32_t alloc_fcs;
+	uint32_t free_fcs;
+	uint32_t alloc_mac_descr;
+	uint32_t free_mac_descr;
+	uint32_t tx_mac_push;
+	uint32_t tx_mac_idle;
+	uint32_t tx_mac_rts;
+	uint32_t tx_mac_cts2self;
+	uint32_t tx_vlan_drop;
+	uint32_t tx_acm_drop;
+	uint32_t tx_ps_drop;
+	uint32_t ocs_tx_suspend;
+	uint32_t ocs_tx_resume;
+	uint32_t ocs_singleton_suspend;
+	uint32_t ocs_ampdu_suspend;
+	uint32_t ocs_frame_created;
+	uint32_t pwr_mgmt_awake;
+	uint32_t pwr_mgmt_sleep;
+	uint32_t pwr_mgmt_tx;
+	uint32_t pspoll_rx;
+	uint32_t dtim_q_push;
+	uint32_t dtim_q_pop;
+	uint32_t dtim_trigger;
+	uint32_t dtim_q_overflow;
+	uint32_t tx_restrict_dropped;
+	uint32_t tx_throt_dropped;
+	uint32_t tx_block_singleton;
+	uint32_t tx_force_unblock_tid;
+	uint32_t tx_ctl_pkt_hbm_alloc_fails;
+	uint32_t tx_ctl_pkt_alloc_descr_fails;
+	uint32_t tx_bar_alloc_ctl_pkt_fails;
+	uint32_t tx_valid_bit_not_set;
+
+	uint32_t wmm_ps_tx;
+	uint32_t wmm_ps_tx_null_frames;
+	uint32_t wmm_ps_tx_more_data_frames;
+	uint32_t wmm_ps_tx_eosp_frames;
+
+	/*
+	 * Mu Tx & Done & Retry
+	 */
+	uint32_t mu_tx_su_count;	/* Can't find buddy, and this AMPDU be sent as SU */
+
+	uint32_t mu_tx_send_mu_fail;	/* Can't be sent as MU, send them as SU */
+
+	uint32_t mu_tx_push_count;
+	uint32_t mu_tx_done_count;
+
+	uint32_t mu_tx_done_succ;	/* The succ/fail counter of AMPDU which be sent via WMAC1 */
+	uint32_t mu_tx_done_fail;
+	uint32_t mu_tx_sample;            /* mu sampling phy rate count */
+	uint32_t mu_bar_bitmap_non_zero;
+	uint32_t mu_bar_bitmap_zero;
+	uint32_t mu_mac_wmac1_ipc_push;
+	uint32_t mu_mac_wmac1_auc_push;
+	uint32_t mu_wmac1_resets;
+
+	uint32_t mu_tx_swretry_agg_exceed;
+
+	uint32_t mu_tx_buddy_try;
+	uint32_t mu_tx_buddy_fail_wmac;
+	uint32_t mu_tx_buddy_fail_ptid;
+	uint32_t mu_tx_buddy_fail_rate;
+	uint32_t mu_tx_buddy_fail_create_agg;
+
+	uint32_t mu_tx_buddy_mu_only_timeout;
+
+	uint32_t mu_tx_another_q_push_succ;
+	uint32_t mu_tx_another_q_push_fail;	/* If current cont_q is not ready, try another cont_q */
+	uint32_t mu_tx_buddy_multi_tid;
+
+	/* For debug, remove it before submitting */
+	uint32_t mu_tx_wmac_0_done_count;
+	uint32_t mu_tx_wmac_0_bitmap_non_zero;
+	uint32_t mu_tx_wmac_0_bitmap_zero;
+	uint32_t mu_tx_wmac_0_done_timeout;
+	uint32_t mu_tx_wmac_0_done_succ;
+	uint32_t mu_tx_wmac_0_done_fail;
+
+	uint32_t mu_tx_wmac_1_done_succ;
+	uint32_t mu_tx_wmac_1_done_fail;
+
+	uint32_t mu_tx_wmac_0_mpdu_total;
+	uint32_t mu_tx_wmac_0_mpdu_succ;
+
+	uint32_t mu_tx_wmac_1_mpdu_total;
+	uint32_t mu_tx_wmac_1_mpdu_succ;
+
+	uint32_t mu_tx_qnum[AUC_FW_WMAC_TX_QNUM];
+	uint32_t tqe_sema_fails;
+};
+#endif // #ifndef _AUC_DEBUG_STATS_H_
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_share_def.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_share_def.h
new file mode 100755
index 0000000..3fc17e3
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/auc_share_def.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Quantenna Communications, Inc.
+ */
+
+#ifndef _AUC_SHARE_DEF_H_
+#define _AUC_SHARE_DEF_H_
+
+/* Define how many TIDs have and which is timer TID */
+#define AUC_TID_FIRST			0
+#define AUC_TID_NUM			20
+#define AUC_TID_TIMER			19
+
+#ifndef __ASSEMBLY__
+/* WMAC parameters */
+#define AUC_FW_WMAC_TX_QNUM		4
+#define AUC_FW_WMAC_TX_QDEEP		4
+
+#define AUC_FW_WMAC_RX_Q_MGMT		0
+#define AUC_FW_WMAC_RX_Q_CTRL		1
+#define AUC_FW_WMAC_RX_Q_DATA		2
+#define AUC_FW_WMAC_RX_QNUM		3
+#define AUC_FW_WMAC_RX_QDEEP_MGMT		8
+#define AUC_FW_WMAC_RX_QDEEP_CTRL		8
+#define AUC_FW_WMAC_RX_QDEEP_DATA		64
+#define AUC_FW_WMAC_RX_DESC_NUM	(AUC_FW_WMAC_RX_QDEEP_MGMT + \
+	AUC_FW_WMAC_RX_QDEEP_CTRL + AUC_FW_WMAC_RX_QDEEP_DATA)
+#endif
+
+/* Used to define 'state' field of qtn_auc_per_tid_data */
+#define QTN_AUC_TID_TX_STATE_IDLE			0		/* idle state, this is init state, please keep zero value */
+#define QTN_AUC_TID_TX_STATE_RUN			1		/* sending state */
+#define QTN_AUC_TID_TX_STATE_WAIT_TIMER_AGG		2		/* waiting on agg timer firing */
+#define QTN_AUC_TID_TX_STATE_WAIT_TX_DONE		3		/* waiting on tx done firing */
+#define QTN_AUC_TID_TX_STATE_WAIT_TX_RESUME		4		/* waiting on ocs tx resume */
+#define QTN_AUC_TID_TX_STATE_MAX			4		/* maximum value of tx states */
+
+/* Used to define 'tqew_state' field of qtn_auc_per_tid_data */
+#define QTN_AUC_TID_TQEW_STATE_RUN			0
+#define QTN_AUC_TID_TQEW_STATE_WAIT_TX_DONE		1
+#define QTN_AUC_TID_TQEW_STATE_MAX			1
+
+#endif // #ifndef _AUC_SHARE_DEF_H_
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/bootcfg.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/bootcfg.h
new file mode 100644
index 0000000..966720a
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/bootcfg.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2009 Quantenna Communications, Inc.
+ * All rights reserved.
+ *
+ *  Syscfg module - uses config sector for common filesytem between linux and
+ *  uboot.
+ */
+
+
+typedef u32 bootcfg_t;
+
+/******************************************************************************
+	Function:   bootcfg_create
+	Purpose:	create file
+ 	Returns:	0 if successful			
+  	Note:  	    if size is zero, the proc entry is created but
+  	            no data is allocated until the first write
+ *****************************************************************************/
+int bootcfg_create(const char *filename,u32 size);
+
+/******************************************************************************
+	Function:   bootcfg_delete
+	Purpose:	delete file
+ 	Returns:	0 if successful			
+  	Note:  	    
+ *****************************************************************************/
+int bootcfg_delete(const char *token);
+
+/******************************************************************************
+   Function:    bootcfg_get_var
+   Purpose:     Get variable from environment
+   Returns:     NULL if variable not found, pointer to storage otherwise
+   Note:        variable value copied to storage
+ *****************************************************************************/
+char* bootcfg_get_var(const char *variable, char *storage);
+
+/******************************************************************************
+   Function:    bootcfg_set_var
+   Purpose:     Set variable to environment
+   Returns:     NULL if variable not found, pointer to storage otherwise
+   Note:        variable value copied to storage
+ *****************************************************************************/
+int bootcfg_set_var(const char *var, const char *value);
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dmautil.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dmautil.h
new file mode 100644
index 0000000..dab25bd
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dmautil.h
@@ -0,0 +1,122 @@
+/*
+ *  Copyright (c) Quantenna Communications, Inc. 2012
+ *  All rights reserved.
+ *
+ * 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
+ *
+ */
+
+#ifndef __QTN_DMA_UTIL_H
+#define __QTN_DMA_UTIL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <asm/dma-mapping.h>
+#include <asm/cacheflush.h>
+
+#define ALIGNED_DMA_DESC(typeq, type)		\
+	struct aligned_dma_##type {		\
+		uint32_t desc_count;		\
+		typeq type *descs;		\
+		unsigned long aligned_vdescs;	\
+		unsigned long unaligned_vdescs;	\
+		unsigned long descs_dma_addr;	\
+	}
+
+typedef ALIGNED_DMA_DESC(, void) aligned_dma_descs;
+
+#define ALIGNED_DMA_DESC_ALLOC(_ptr, _count, _align, _is_sram)			\
+	dmautil_aligned_dma_desc_alloc((aligned_dma_descs *)(_ptr),		\
+			sizeof((_ptr)->descs[0]), (_count), (_align), (_is_sram))
+int dmautil_aligned_dma_desc_alloc(aligned_dma_descs *d,
+		unsigned int desc_size, unsigned int desc_count,
+		unsigned int align, bool is_sram);
+
+#define ALIGNED_DMA_DESC_FREE(_ptr)	dmautil_aligned_dma_desc_free((aligned_dma_descs *)(_ptr))
+void dmautil_aligned_dma_desc_free(aligned_dma_descs *d);
+
+/*
+ * Alignment helpers
+ */
+__always_inline static unsigned long align_val_up(unsigned long val, unsigned long step)
+{
+	return ((val + step - 1) & (~(step - 1)));
+}
+__always_inline static unsigned long align_val_down(unsigned long val, unsigned long step)
+{
+	return (val & (~(step - 1)));
+}
+__always_inline static void* align_buf_dma(void *addr)
+{
+	return (void*)align_val_up((unsigned long)addr, dma_get_cache_alignment());
+}
+__always_inline static unsigned long align_buf_dma_offset(void *addr)
+{
+	return ((char *)align_buf_dma(addr) - (char *)addr);
+}
+__always_inline static void* align_buf_cache(void *addr)
+{
+	return (void*)align_val_down((unsigned long)addr, dma_get_cache_alignment());
+}
+__always_inline static unsigned long align_buf_cache_offset(void *addr)
+{
+	return ((char *)addr - (char *)align_buf_cache(addr));
+}
+__always_inline static unsigned long align_buf_cache_size(void *addr, unsigned long size)
+{
+	return align_val_up(size + align_buf_cache_offset(addr), dma_get_cache_alignment());
+}
+
+__always_inline static void flush_dcache_sizerange_safe(void *p, size_t size)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+	dma_cache_wback((unsigned long)p, size);
+#else
+	uintptr_t op_start = (uintptr_t) align_buf_cache(p);
+	size_t op_size = align_buf_cache_size(p, size);
+	flush_dcache_range(op_start, op_start + op_size);
+#endif
+}
+
+__always_inline static void flush_and_inv_dcache_sizerange_safe(void *p, size_t size)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+	dma_cache_wback_inv((unsigned long)p, size);
+#else
+	uintptr_t op_start = (uintptr_t) align_buf_cache(p);
+	size_t op_size = align_buf_cache_size(p, size);
+	flush_and_inv_dcache_range(op_start, op_start + op_size);
+#endif
+
+}
+
+__always_inline static void inv_dcache_sizerange_safe(void *p, size_t size)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+	dma_cache_inv((unsigned long)p, size);
+#else
+	uintptr_t op_start = (uintptr_t) align_buf_cache(p);
+	size_t op_size = align_buf_cache_size(p, size);
+	inv_dcache_range(op_start, op_start + op_size);
+#endif
+}
+
+#endif	// __ASSEMBLY__
+#endif	// __QTN_DMA_UTIL_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dsp_stats.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dsp_stats.h
new file mode 100644
index 0000000..7f003f2
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/dsp_stats.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2016 Quantenna Communications, Inc.
+ */
+
+#ifndef _DSP_STATS_H_
+#define _DSP_STATS_H_
+
+#include "qtn/txbf_common.h"
+
+#define DSP_ACT_RX_DBG_SIZE	10
+
+#if DSP_ENABLE_STATS
+struct qtn_dsp_stats {
+	uint32_t dsp_ndp_rx;
+
+	/* Per-node DSP stats */
+
+	/* Total number of feedbacks received */
+	uint32_t dsp_act_rx[DSP_ACT_RX_DBG_SIZE];
+
+	/* Number of SU feedbacks */
+	uint32_t dsp_act_rx_su[DSP_ACT_RX_DBG_SIZE];
+
+	/* Number of MU group selection feedbacks */
+	uint32_t dsp_act_rx_mu_grp_sel[DSP_ACT_RX_DBG_SIZE];
+
+	/* Number of MU precoding feedbacks */
+	uint32_t dsp_act_rx_mu_prec[DSP_ACT_RX_DBG_SIZE];
+
+	/* Number of bad feedbacks, i.e. those that are not met SU nor MU criteria */
+	uint32_t dsp_act_rx_bad[DSP_ACT_RX_DBG_SIZE];
+
+	/*
+	 * Number of feedbacks that were not places into the cache due to any reason. Counters for two reasons
+	 * are just below
+	 */
+	uint32_t dsp_act_rx_mu_drop[DSP_ACT_RX_DBG_SIZE];
+
+	/* The number of MU feedback not placed into the cache as the previous one has not been exprired */
+	uint32_t dsp_act_rx_mu_nexp[DSP_ACT_RX_DBG_SIZE];
+
+	/* The number of MU feedback not placed into the cache due to cache is locked */
+	uint32_t dsp_act_rx_mu_lock_cache[DSP_ACT_RX_DBG_SIZE];
+
+	/*
+	 * The number of precoding feedback was released unused, i.e. not participated in QMat calculation.
+	 * It means the buddy feedback either have not been received or received after cache expiration time
+	 */
+	uint32_t dsp_act_rx_mu_rel_nuse[DSP_ACT_RX_DBG_SIZE];
+
+	/* The number of MU feedback for which dsp_qmat_check_act_len is failed */
+	uint32_t dsp_act_rx_inval_len[DSP_ACT_RX_DBG_SIZE];
+
+	uint32_t dsp_del_mu_node_rx;
+	uint32_t dsp_ipc_in;
+	uint32_t dsp_ipc_out;
+	uint32_t dsp_sleep_in;
+	uint32_t dsp_sleep_out;
+	uint32_t dsp_act_tx;
+	uint32_t dsp_ndp_discarded;
+	uint32_t dsp_ndp_inv_len;
+	uint32_t dsp_ndp_max_len;
+	uint32_t dsp_ndp_inv_bw;
+	uint32_t dsp_act_free_tx;
+	uint32_t dsp_inst_mu_grp_tx;
+	uint32_t dsp_qmat_invalid;
+	uint32_t dsp_su_feedback_proc_time;
+/* Number of QMat currently installed */
+	int32_t dsp_sram_qmat_num;
+/*
+ * Number of times dsp_sram_qmat_num becomes negative. Non zero value signals that the number
+ * of QMat de-installation is more than the number of installations. This is an error condition but not a critical one
+ */
+	uint32_t dsp_err_neg_qmat_num;
+	uint32_t dsp_flag;
+	/* Interrupts */
+	uint32_t dsp_ipc_int;
+	uint32_t dsp_timer_int;
+	uint32_t dsp_timer1_int;
+	uint32_t dsp_last_int;
+
+	uint32_t dsp_exc;
+	/* registers */
+	uint32_t dsp_status32;
+	uint32_t dsp_status32_l1;
+	uint32_t dsp_status32_l2;
+	uint32_t dsp_ilink1;
+	uint32_t dsp_ilink2;
+	uint32_t dsp_blink;
+	uint32_t dsp_sp;
+	uint32_t dsp_time;
+
+	uint32_t dsp_point;
+	uint32_t dsp_stat_bad_stack;
+
+	int16_t dspmu_D_user1[4];
+	int16_t dspmu_D_user2[4];
+	int16_t dspmu_max_intf_user1;
+	int16_t dspmu_max_intf_user2;
+	int16_t rank_criteria;
+	int16_t pad;
+	uint32_t dsp_trig_mu_grp_sel;
+	uint32_t dsp_mu_rank_success;
+	uint32_t dsp_mu_rank_fail;
+
+	/* The number of failed group installations */
+	uint32_t dsp_mu_grp_inst_fail;
+
+	/* Per-MU group DSP stats */
+	/* The number of successful group installations */
+	uint32_t dsp_mu_grp_inst_success[QTN_MU_QMAT_MAX_SLOTS];
+	/* The number of successful QMat installations */
+	uint32_t dsp_mu_grp_update_success[QTN_MU_QMAT_MAX_SLOTS];
+	/* The number of failed QMat installations */
+	uint32_t dsp_mu_grp_update_fail[QTN_MU_QMAT_MAX_SLOTS];
+	/* Group's AID 0 */
+	uint32_t dsp_mu_grp_aid0[QTN_MU_QMAT_MAX_SLOTS];
+	/* Group's AID 1 */
+	uint32_t dsp_mu_grp_aid1[QTN_MU_QMAT_MAX_SLOTS];
+	/* Group's rank */
+	int32_t dsp_mu_grp_rank[QTN_MU_QMAT_MAX_SLOTS];
+
+	/*
+	 * Distribution (histogram) of MU QMat copying time
+	 0:  0- 3us
+	 1:  4- 7us
+	 ...............
+	 3: 12+ us
+	 */
+#define DSP_MU_QMAT_COPY_TIME_HIST_WIDTH_US	4
+	uint32_t dsp_mu_qmat_qmem_copy_time_hist[4];
+	uint32_t dsp_mu_qmat_qmem_copy_time_max;
+
+	/*
+	 * Distribution (histogram) of MU QMat calculation and installation time
+	 0:  0- 3ms
+	 1:  4- 7ms
+	 ...............
+	 3: 12+ ms
+	 */
+#define DSP_MU_QMAT_INST_TIME_HIST_WIDTH_MS	6
+	uint32_t dsp_mu_qmat_inst_time_hist[8];
+	uint32_t dsp_mu_qmat_inst_time_max;
+
+	uint32_t dsp_mu_grp_inv_act;
+	uint32_t dsp_act_cache_expired[2];
+	uint32_t dsp_mu_grp_upd_done;
+	uint32_t dsp_mu_node_del;
+
+	uint32_t dsp_mimo_ctrl_fail;
+	uint32_t dsp_mu_fb_80mhz;
+	uint32_t dsp_mu_fb_40mhz;
+	uint32_t dsp_mu_fb_20mhz;
+	uint32_t dsp_mu_drop_20mhz;
+};
+#endif
+
+
+#endif	/* _DSP_STATS_H_ */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/emac_debug.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/emac_debug.h
new file mode 100644
index 0000000..6de7aee
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/emac_debug.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2012 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _QTN_EMAC_DEBUG_H
+#define _QTN_EMAC_DEBUG_H
+
+#include <qtn/skb_recycle.h>
+
+uint32_t qtn_eth_rx_lost_get(struct net_device *dev);
+
+#endif	// _QTN_EMAC_DEBUG_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/hardware_revision.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/hardware_revision.h
new file mode 100644
index 0000000..d754fbd
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/hardware_revision.h
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2011 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __RUBY_VERSION_H
+#define __RUBY_VERSION_H
+
+#ifndef __ASSEMBLY__
+
+#include "mproc_sync_base.h"
+
+RUBY_INLINE int get_hardware_revision(void)
+{
+	volatile struct shared_params* sp = qtn_mproc_sync_shared_params_get();
+	if (sp) {
+		return sp->hardware_revision;
+	} else {
+		return HARDWARE_REVISION_UNKNOWN;
+	}
+}
+
+#ifdef __KERNEL__
+RUBY_INLINE int _read_hardware_revision(void)
+{
+	int ret = HARDWARE_REVISION_UNKNOWN;
+	uint32_t board_rev = readl(RUBY_SYS_CTL_CSR);
+
+	if ((board_rev & CHIP_ID_MASK) == CHIP_ID_RUBY) {
+		uint32_t spare1 = readl(RUBY_QT3_BB_TD_SPARE_1);
+		if ((spare1 & CHIP_REV_ID_MASK)  == REV_ID_RUBY_A) {
+			ret = HARDWARE_REVISION_RUBY_A;
+		} else if ((spare1 & CHIP_REV_ID_MASK) == REV_ID_RUBY_B) {
+			ret = HARDWARE_REVISION_RUBY_B;
+		} else if ((spare1 & CHIP_REV_ID_MASK) == REV_ID_RUBY_D){
+			ret = HARDWARE_REVISION_RUBY_D;
+		}
+	} else if ((board_rev & CHIP_ID_MASK) == CHIP_ID_TOPAZ) {
+		switch (board_rev & CHIP_REV_ID_MASK) {
+			case REV_ID_TOPAZ_A:
+				ret = HARDWARE_REVISION_TOPAZ_A;
+				break;
+			case REV_ID_TOPAZ_B:
+				ret = HARDWARE_REVISION_TOPAZ_B;
+				break;
+			case REV_ID_TOPAZ_A2:
+				ret = HARDWARE_REVISION_TOPAZ_A2;
+				break;
+		}
+	}
+	return ret;
+}
+#endif //__KERNEL__
+
+#endif	// __ASSEMBLY__
+#endif	// __RUBY_VERSION_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/iputil.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/iputil.h
new file mode 100644
index 0000000..42791c7
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/iputil.h
@@ -0,0 +1,392 @@
+/*SH1
+*******************************************************************************
+**                                                                           **
+**         Copyright (c) 2012 Quantenna Communications. Inc.                 **
+**                            All Rights Reserved                            **
+**                                                                           **
+*******************************************************************************
+**                                                                           **
+**  Redistribution and use in source and binary forms, with or without       **
+**  modification, are permitted provided that the following conditions       **
+**  are met:                                                                 **
+**  1. Redistributions of source code must retain the above copyright        **
+**     notice, this list of conditions and the following disclaimer.         **
+**  2. Redistributions in binary form must reproduce the above copyright     **
+**     notice, this list of conditions and the following disclaimer in the   **
+**     documentation and/or other materials provided with the distribution.  **
+**  3. The name of the author may not be used to endorse or promote products **
+**     derived from this software without specific prior written permission. **
+**                                                                           **
+**  Alternatively, this software may be distributed under the terms of the   **
+**  GNU General Public License ("GPL") version 2, or (at your option) any    **
+**  later version as published by the Free Software Foundation.              **
+**                                                                           **
+**  In the case this software is distributed under the GPL license,          **
+**  you should have received a copy of the GNU General Public License        **
+**  along with this software; if not, write to the Free Software             **
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  **
+**                                                                           **
+**  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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.        **
+**                                                                           **
+*******************************************************************************
+EH1*/
+
+#ifndef _IPUTIL_H_
+#define _IPUTIL_H_
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+#include <asm/unaligned.h>
+#endif
+
+#include <linux/inetdevice.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <net80211/if_ethersubr.h>
+#if defined(CONFIG_IPV6)
+#include <net/ipv6.h>
+#include <linux/in6.h>
+#include <linux/inet.h>
+#include <net/addrconf.h>
+#endif
+
+#define IPUTIL_HDR_VER_4	4
+#define IPUTIL_HDR_VER_6	6
+
+#define IPUTIL_V4_ADDR_SSDP		htonl(0xEFFFFFFA) /* 239.255.255.250 */
+#define IPUTIL_V4_ADDR_MULTICAST(_addr)	\
+	((_addr & htonl(0xF0000000)) == htonl(0xE0000000)) /* 224.0.0.0/4 */
+#define IPUTIL_V6_ADDR_MULTICAST(_addr)	\
+	((_addr & htonl(0xFF000000)) == htonl(0xFF000000)) /* ff00::/8 - see __ipv6_addr_type() */
+#define IPUTIL_V4_ADDR_LNCB(_addr)	\
+	((_addr & htonl(0xFFFFFF00)) == htonl(0xE0000000)) /* 224.0.0.0/24 */
+#define IPUTIL_V6_ADDR_LNCB(_addr)     \
+	((_addr & htonl(0xFF0F0000)) == htonl(0xFF020000)) /* ffx2::/8 - see __ipv6_addr_type() */
+
+#define IPUTIL_V4_FRAG_OFFSET(_fh)	(ntohs(_fh->frag_off) & ~0x7)
+#define IPUTIL_V4_FRAG_MF(_fh)		(ntohs(_fh->frag_off) & IP6_MF)
+
+#define IPUTIL_V6_FRAG_OFFSET(_fh)	(ntohs(_fh->frag_off) & ~0x7)
+#define IPUTIL_V6_FRAG_MF(_fh)		(ntohs(_fh->frag_off) & IP6_MF)
+
+#define NIPV6OCTA_FMT "%pI6"
+#define NIPV6OCTA(_ipv6_addr_) _ipv6_addr_
+
+#define IPUTIL_V4_ADDR_LEN 4
+
+#ifdef CONFIG_IPV6
+int iputil_v6_skip_exthdr(const struct ipv6hdr *ipv6h, int start, uint8_t *nexthdrp,
+				int total_len, __be32 *ip_id, uint8_t *more_frags);
+int iputil_v6_ntop(char *buf, const struct in6_addr *addr);
+int iputil_v6_ntop_port(char *buf, const struct in6_addr *addr, __be16 port);
+int iputil_eth_is_v6_mld(void *iphdr, uint32_t data_len);
+
+int iputil_ipv6_is_neigh_msg(struct ipv6hdr *ipv6, struct icmp6hdr *icmpv6);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
+int iputil_ipv6_is_neigh_sol_msg(uint8_t dup_addr_detect,
+				const struct in6_addr *target,
+				const struct in6_addr *daddr);
+#else
+int iputil_ipv6_is_neigh_sol_msg(uint8_t dad, struct nd_msg *msg, struct ipv6hdr *ipv6);
+#endif
+#endif
+
+int iputil_v4_pton(const char *ip_str, __be32 *ipaddr);
+int iputil_v4_ntop_port(char *buf, __be32 addr, __be16 port);
+
+/*
+ * IPv6 broadcasts are scoped multicast.
+ * +--------+----+----+---------------------------------------------+
+ * | 8      | 4  | 4  |                 112 bits                    |
+ * +------ -+----+----+---------------------------------------------+
+ * |11111111|flgs|scop|                 group ID                    |
+ * +--------+----+----+---------------------------------------------+
+ *
+ *  Scope:
+ *  1: Interface-Local (loopback)
+ *  2: Link-Local
+ *  4: Admin-Local
+ *  5: Site-Local
+ *  8: Organization-Local
+ *  E: Global
+ *  0,3,F: reserved
+ *  others: unassigned, are available for administrators to define additional multicast regions.
+ *
+ *  RFC4291 http://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xml
+ */
+#ifdef CONFIG_IPV6
+static inline int iputil_mac_is_v6_local(const struct ipv6hdr *ipv6h)
+{
+	const struct in6_addr *ipaddr = &ipv6h->daddr;
+
+	return ((ipaddr->in6_u.u6_addr8[0] == 0xff) &&
+		(ipaddr->in6_u.u6_addr8[1] > 0x01) &&
+		(ipaddr->in6_u.u6_addr8[1] < 0x0E));
+}
+#endif
+
+static inline int iputil_is_v4_ssdp(const void *addr, const void *iph)
+{
+	static const char ssdp_addr[] = {0x01, 0x00, 0x5E, 0x7F, 0xFF, 0xFA};
+
+	if (unlikely(!memcmp(addr, ssdp_addr, sizeof(ssdp_addr)))) {
+		const struct iphdr *ipv4h = iph;
+		uint32_t daddr = get_unaligned((uint32_t *)&ipv4h->daddr);
+
+		if (daddr == IPUTIL_V4_ADDR_SSDP) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_IPV6
+/*
+ * IPv6 SSDP is 0xff0?::c
+ */
+static inline int iputil_is_v6_ssdp(const unsigned char *dest, const struct ipv6hdr *ipv6h)
+{
+	static const uint8_t ssdp6_addr[ETH_ALEN] = {0x33, 0x33, 0x00, 0x00, 0x00, 0x0c};
+	const struct in6_addr *ipaddr = &ipv6h->daddr;
+
+	return ((memcmp(dest, &ssdp6_addr, sizeof(ssdp6_addr)) == 0) &&
+		((__constant_ntohl(ipaddr->in6_u.u6_addr32[0]) & 0xfff0ffff) == 0xff000000) &&
+		(ipaddr->in6_u.u6_addr32[1] == 0) && (ipaddr->in6_u.u6_addr32[2] == 0) &&
+		(ipaddr->in6_u.u6_addr32[3] == __constant_htonl(0xc)));
+}
+#endif
+
+static inline int iputil_is_ssdp(const void *addr, const void *iph)
+{
+	if (iputil_is_v4_ssdp(addr, iph)) {
+		return 1;
+	}
+
+#ifdef CONFIG_IPV6
+	if (unlikely(iputil_is_v6_ssdp(addr, iph))) {
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+#ifdef CONFIG_IPV6
+static inline
+void iputil_in6_addr_copy(struct in6_addr *dst, const struct in6_addr *src)
+{
+	memcpy(dst, src, sizeof(*dst));
+}
+
+/*
+ * IPv6 all-nodes multicast address
+ * the link-local scope address to reach all nodes is 0xff02::1
+ */
+static inline int iputil_ipv6_is_ll_all_nodes_mc(const unsigned char *dest, void *iph)
+{
+	struct ipv6hdr *ipv6h = (struct ipv6hdr *)iph;
+	static const uint8_t ll_all_nodes_mac_addr[ETH_ALEN] = {0x33, 0x33, 0x00, 0x00, 0x00, 0x01};
+	struct in6_addr *ipaddr = &ipv6h->daddr;
+
+	return ((memcmp(dest, ll_all_nodes_mac_addr, sizeof(ll_all_nodes_mac_addr)) == 0) &&
+		(__constant_ntohl(ipaddr->in6_u.u6_addr32[0]) == 0xff020000) &&
+		(ipaddr->in6_u.u6_addr32[1] == 0) && (ipaddr->in6_u.u6_addr32[2] == 0) &&
+		(ipaddr->in6_u.u6_addr32[3] == __constant_htonl(0x1)));
+}
+#endif
+
+/* Check for a local network control block MAC address */
+static inline int iputil_is_lncb(const uint8_t *addr, const void *iph)
+{
+	static const char lncb_addr[] = {0x01, 0x00, 0x5E, 0x00, 0x00};
+
+	if (unlikely(!memcmp(addr, lncb_addr, sizeof(lncb_addr)))) {
+		const struct iphdr *ipv4h = iph;
+		uint32_t daddr = get_unaligned((uint32_t *)&ipv4h->daddr);
+
+		return IPUTIL_V4_ADDR_LNCB(daddr);
+	}
+
+#ifdef CONFIG_IPV6
+	{
+		static const char ipmc6_addr[] = {0x33, 0x33};
+
+		if (unlikely(!memcmp(addr, ipmc6_addr, sizeof(ipmc6_addr)))) {
+			const struct ipv6hdr *ipv6h = iph;
+			uint32_t daddr = get_unaligned((uint32_t *)ipv6h->daddr.s6_addr32);
+
+			return IPUTIL_V6_ADDR_LNCB(daddr);
+		}
+	}
+#endif
+
+	return 0;
+}
+
+static inline int iputil_is_multicast(void *iph)
+{
+	const struct iphdr *ipv4h = iph;
+
+	if (ipv4h->version == 4) {
+		uint32_t daddr = get_unaligned((uint32_t *)&ipv4h->daddr);
+
+		return IPUTIL_V4_ADDR_MULTICAST(daddr);
+	}
+
+#ifdef CONFIG_IPV6
+	if (ipv4h->version == 6) {
+		struct ipv6hdr *ipv6h = iph;
+		__be32 daddr = get_unaligned(ipv6h->daddr.s6_addr32);
+
+		return IPUTIL_V6_ADDR_MULTICAST(daddr);
+	}
+#endif
+	return 0;
+}
+
+static inline size_t iputil_hdrlen(void *iph, uint32_t data_len)
+{
+	const struct iphdr *ipv4h = iph;
+#ifdef CONFIG_IPV6
+	const struct ipv6hdr *ip6hdr_p = iph;
+	uint8_t nexthdr;
+	int nhdr_off;
+#endif
+
+	if (likely(ipv4h->version == 4)) {
+		return (ipv4h->ihl << 2);
+	}
+
+#ifdef CONFIG_IPV6
+	/*
+	 * This is the base IPv6 header. If the next header is an option header, its length must be
+	 * accounted for explicitly elsewhere.
+	 */
+	if (ipv4h->version == 6) {
+		nhdr_off = iputil_v6_skip_exthdr(ip6hdr_p,
+			sizeof(struct ipv6hdr),
+			&nexthdr, data_len, NULL, NULL);
+		return nhdr_off;
+	}
+#endif
+	return 0;
+}
+
+static inline int iputil_mac_is_v6_multicast(const uint8_t *mac)
+{
+	const char ipmc6_addr[] = {0x33, 0x33};
+
+	return mac[0] == ipmc6_addr[0] &&
+		mac[1] == ipmc6_addr[1];
+}
+
+static inline int iputil_mac_is_v4_multicast(const uint8_t *mac)
+{
+	const char ipmc4_addr[] = {0x01, 0x00, 0x5E};
+
+	return mac[0] == ipmc4_addr[0] &&
+		mac[1] == ipmc4_addr[1] &&
+		mac[2] == ipmc4_addr[2];
+}
+
+static inline int iputil_eth_is_type(const struct ether_header *eh, const uint16_t ether_type)
+{
+	if (eh->ether_type == __constant_htons(ETH_P_8021Q)) {
+		return (*(&eh->ether_type + 2) == ether_type);
+	}
+
+	return (eh->ether_type == ether_type);
+}
+
+static inline int iputil_eth_is_v6_multicast(const struct ether_header *eh)
+{
+
+	return iputil_eth_is_type(eh, __constant_htons(ETH_P_IPV6)) &&
+		iputil_mac_is_v6_multicast(eh->ether_dhost);
+}
+
+static inline int iputil_eth_is_v4_multicast(const struct ether_header *eh)
+{
+	return iputil_eth_is_type(eh, __constant_htons(ETH_P_IP)) &&
+		iputil_mac_is_v4_multicast(eh->ether_dhost);
+}
+
+static inline int iputil_eth_is_multicast(const struct ether_header *eh)
+{
+	if (iputil_eth_is_v4_multicast(eh)) {
+		return 1;
+	}
+
+#ifdef CONFIG_IPV6
+	if (iputil_eth_is_v6_multicast(eh)) {
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static inline int iputil_eth_is_ipv4or6(uint16_t ether_type)
+{
+	return ether_type == __constant_htons(ETH_P_IP) ||
+		ether_type == __constant_htons(ETH_P_IPV6);
+}
+
+/* Multicast data traffic, with the most common types of non-streaming mc filtered out */
+static inline int iputil_is_mc_data(const struct ether_header *eh, void *iph)
+{
+	return iputil_eth_is_multicast(eh) &&
+		!iputil_is_lncb(eh->ether_dhost, iph) &&
+		!iputil_is_ssdp(eh->ether_dhost, iph);
+}
+
+uint8_t iputil_proto_info(void *iph, void *data,
+	void **proto_data, uint32_t *ip_id, uint8_t *more_frags);
+
+static inline struct igmphdr *iputil_igmp_hdr(struct iphdr *p_iphdr)
+{
+	return (struct igmphdr *)((unsigned int*)p_iphdr + p_iphdr->ihl);
+}
+
+struct dhcp_message {
+	uint8_t op;
+	uint8_t htype;
+	uint8_t hlen;
+	uint8_t hops;
+	uint32_t xid;
+	uint16_t secs;
+	uint16_t flags;
+	uint32_t ciaddr;
+	uint32_t yiaddr;
+	uint32_t siaddr;
+	uint32_t giaddr;
+	uint8_t chaddr[16];
+	uint8_t sname[64];
+	uint8_t file[128];
+	uint32_t cookie;
+	uint8_t options[0];
+}__attribute__ ((packed));
+
+#define DHCPSERVER_PORT		67
+#define DHCPCLIENT_PORT		68
+
+#define DHCPV6SERVER_PORT	547
+#define DHCPV6CLIENT_PORT	546
+
+#define BOOTREQUEST		1
+#define DHCPREQUEST		3
+#define ARPHRD_ETHER		1
+#define DHCP_BROADCAST_FLAG	0x8000
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/lhost_muc_comm.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/lhost_muc_comm.h
new file mode 100644
index 0000000..4268b53
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/lhost_muc_comm.h
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (c) 2011 Quantenna Communications, Inc.
+ */
+
+/*
+ * This file contains host definitions which are common between the
+ * host driver and the microcontroller/MAC code.
+ */
+#ifndef _LHOST_MUC_COMM_H
+#define _LHOST_MUC_COMM_H
+
+#include "qtn_uc_comm.h"
+#include "qtn_cca.h"
+#include "qtn_wmm_ac.h"
+#include "net80211/ieee80211.h"
+#include "net80211/ieee80211_crypto.h"
+#include "muc_txrx_stats.h"
+#include "qtn/qvsp_common.h"
+#include "qtn/shared_defs.h"
+#include "qtn/txbf_common.h"
+
+/* packed definitions for each compiler */
+#if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
+# define PACKED	__packed
+# define LM(a,b)	(b)
+# define lhost_volatile
+# define muc_volatile	volatile
+#else
+# define PACKED __attribute__ ((packed))
+# define LM(a,b)	(a)
+# define lhost_volatile	volatile
+# define muc_volatile
+#endif // #if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
+
+#define HOST_TXD_NUMSEG		2
+
+#define QTN_BBIC_11N		0x30
+#define QTN_BBIC_11AC		0x40
+
+#define QTN_VSP_STATS_TID_NUM	4
+
+#define QTN_VSP_TIDS	{ 6, 5, 0, 1 }
+#define QTN_VSP_STATS_TID2IDX	{0, 1, -1, -1, -1, 2, 3, -1}	/* make sure no tids using same index */
+
+struct qtn_vsp_per_node_stats {
+	struct qtn_per_tid_stats per_tid_stats[QTN_VSP_STATS_TID_NUM];
+};
+
+struct qtn_vsp_stats {
+#define QVSP_FAT_MAX		1000
+#define QVSP_FAT_NONE		((uint32_t)(-1))
+	uint32_t	fat;		/* free airtime */
+	uint32_t	intf_ms;	/* interference */
+#if TOPAZ_QTM
+	struct qtn_vsp_per_node_stats per_node_stats[QTN_NCIDX_MAX];
+#endif
+};
+
+/**
+ * \brief This enumeration represents the mode in use on the device.
+ *
+ * This enumeration is used to set the correct bandwidth.
+ */
+
+enum {
+        QTN_11NAC_DISABLE  = 0,
+        QTN_11NAC_ENABLE = 1,
+};
+
+/* Host tx descriptor */
+struct host_txdesc {
+	uint32_t	hd_version:8;	/* Descriptor version */
+	uint32_t	hd_tid:4;	/* packet tid */
+	uint32_t	hd_txstatus:2;	/* Transmit status: 1 sent to MuC, 2 tx success */
+#define QTN_TXSTATUS_TX_ON_MUC 1
+#define QTN_TXSTATUS_TX_SUCCESS 2
+	uint32_t	hd_wmmac:2;	/* Reserved for WMM AC*/
+	uint32_t	hd_pktlen:16;	/* Pkt len (incl. all headers) */
+	uint32_t	hd_node_idx;	/* local node index */
+	uint16_t	hd_seglen[HOST_TXD_NUMSEG];	/* Segment lenghts */
+	uint32_t	hd_segaddr[HOST_TXD_NUMSEG];	/* Phys addr of each seg */
+	uint32_t	hd_ts;		/* Timestamp of the pkt */
+	uint32_t	hd_nextpa;	/* Phys addr of next host tx descr in fwd dir */
+	uint32_t	hd_nextpa_rev;	/* Phys addr of next host tx descr in rev dir */
+	void		*hd_nextva_rev;	/* Virtual addr (LHOST view) of next host tx descr in rev dir */
+	uint32_t	hd_pa;		/* Physical addr of this host tx descr */
+	void		*hd_va;		/* Virtual addr (LHOST view) of this host tx descr */
+	uint32_t		hd_status;	/* Status of HTxD */
+	void		(*hd_muc_txdone_cb)(void *, uint32_t, uint32_t); /* MuC callback after txdone */
+	uint32_t	hd_muc_cb_arg1; /* parameter for hd_muc_txdone_cb */
+	uint32_t	hd_muc_cb_arg2; /* parameter for hd_muc_txdone_cb */
+	uint32_t	hd_txtsf;	/* record the tsf_lo on that frame was sent successfully */
+	uint8_t		hd_mpdu[128];
+	uint8_t		hd_msdu[128];
+	uint8_t		hd_dma[128];
+#define	HTXD_FLAG_AMSDU_DEST_CAPABLE	0x00000002	/* Can be used for AMSDU destination (append to) */
+#define	HTXD_FLAG_AMSDU_SRC_CAPABLE	0x00000004	/* Can be used for AMSDU (copy from) */
+#define HTXD_FLAG_NO_UPDATE_NAV		0x00000008	/* Don't update NAV for this frame */
+#define HTXD_FLAG_NO_RETRY		0x00000010	/* Don't retry this frame if tx failed */
+#define HTXD_FLAG_NO_RETURN		0x00000020	/* Don't return txdesc from MuC to lhost */
+#define HTXD_FLAG_IMM_RETURN		0x00000040	/* Immediately return txdesc from Muc to lhost */
+	uint32_t	hd_flags;
+};
+
+#define QTN_AMSDU_DEST_CAPABLE_SIZE		ETHER_MAX_LEN
+#define QTN_AMSDU_DEST_CAPABLE_GUARD_SIZE	64
+#define QTN_AMSDU_SRC_FRAME_SIZE		(QTN_AMSDU_DEST_CAPABLE_SIZE / 10)
+#define QTN_AMSDU_DEST_CAPABLE_OCCUPY_SIZE	(QTN_AMSDU_DEST_CAPABLE_SIZE / 3 * 2)
+
+#define HTXD_FLAG_SET(_htxd, _flag) \
+	(((struct host_txdesc *)(_htxd))->hd_flags |= (_flag))
+#define	HTXD_FLAG_CLR(_htxd, _flag) \
+	(((struct host_txdesc *)(_htxd))->hd_flags &= ~(_flag))
+#define	HTXD_FLAG_GET(_htxd, _flag) \
+	(((struct host_txdesc *)(_htxd))->hd_flags & (_flag))
+#define	HTXD_FLAG_ISSET(_htxd, _flag) \
+	(!!(((struct host_txdesc *)(_htxd))->hd_flags & (_flag)))
+#define HTXD_FLAG_KEEP_ONLY(_htxd, _flag) \
+	(((struct host_txdesc *)(_htxd))->hd_flags &= (_flag))
+
+
+/* host_ioctl_hifinfo */
+
+#define NAMESIZE		16
+#define VERSION_SIZE		16
+#define MAC_ADDR_LEN		6
+#define MAC_STR_BUF_SIZE	18
+
+#define	HOST_NUM_IOCTLQ		1	/* Number of ioctl q's */
+/*
+ * LHost -> MuC TX queues are per node to allow variable backpressure per node.
+ * One universal management data frame tx mailbox, and one ioctl mailbox
+ */
+#define HOST_NUM_MGMTQ			1
+#define	HOST_NUM_DATAQ			(QTN_NCIDX_MAX)
+#define HOST_NUM_DATASEM		1
+
+#define HOST_IOCTL_INDEX_BASE		0
+#define HOST_MGMT_INDEX_BASE		(HOST_IOCTL_INDEX_BASE + HOST_NUM_IOCTLQ)
+#define HOST_DATA_INDEX_BASE		(HOST_MGMT_INDEX_BASE + HOST_NUM_MGMTQ)
+#define	HOST_NUM_HOSTIFQ		(HOST_NUM_DATAQ + HOST_NUM_IOCTLQ + HOST_NUM_MGMTQ)
+#define HOST_MBOX_SIZE			(sizeof(uint32_t) * HOST_NUM_HOSTIFQ)
+
+#define QTN_PHY_RATE_PROP_SCALE		1024
+#define QTN_MUC_NODE_PKT_LIMIT_MIN	16
+#define QTN_MUC_NODE_PKT_LIMIT_DEFAULT	64
+#define QTN_MUC_NODE_PKT_LIMIT_MAX	128
+
+#define IEEE80211_TXPOW_ENCODE(x)	((255 * 65536) + (x * 256) + 1)
+#define IEEE80211_TXPOW_DECODE(x)	(((x) - (255 * 65536) - 1) / 256)
+#define RF_MIXER_VAL_HI		0x1
+#define RF_MIXER_VAL_LO		0x7
+#define RF_PGA_VAL_HI		0x3
+#define RF_PGA_VAL_LO		0x0
+#define IEEE80211_LOWGAIN_TXPOW_MAX	10
+#define IEEE80211_LOWGAIN_TXPOW_MIN	9
+
+#define IEEE80211_CHAN_SEC_SHIFT	4
+#define IEEE80211_24G_CHAN_SEC_SHIFT	1
+
+struct host_ioctl_hifinfo {
+	uint32_t	hi_mboxstart;			/* Start address for mbox */
+	uint32_t	hi_rxdoneirq;			/* IRQ map for rx done */
+	uint32_t	hi_txdoneirq;			/* IRQ map for tx done */
+	uint32_t	hi_rxfifo;			/* Rx FIFO location */
+	uint32_t	hi_scanirq;			/* IRQ map for Scan */
+	uint32_t	hi_scanfifo;			/* Scan FIFO location */
+	uint32_t	hi_dspgpios;
+	uint32_t	hi_vsp_stats_phys;
+	uint32_t	hi_vapnode_idx;			/* node_idx of the vap node for tx */
+	uint8_t		hi_vapid;
+	char		hi_name[NAMESIZE];		/* Device name */
+	char		hi_version[VERSION_SIZE];	/* basic firmware version */
+	char		hi_algover[VERSION_SIZE];	/* calibration algorithm version */
+	uint8_t		hi_macaddr[MAC_ADDR_LEN];
+	uint8_t		hi_semmap[HOST_NUM_HOSTIFQ];	/* Mapping of semaphores */
+};
+
+typedef int (*scan_done_fn)(int sc_devid, void *chan, int type, int status);
+
+struct host_scandesc {
+	uint8_t	sd_type;
+	uint8_t	sd_devid;
+	uint8_t	status;
+	uint8_t	____pad;
+	uint8_t*	sd_data;
+	scan_done_fn *sd_ppfn;
+	struct host_scandesc *sd_next;
+};
+
+struct host_rxdesc {
+	uint8_t			hw_desc[128]; /* need to be aligned on 8 bytes */
+	uint8_t			*skbuff;
+	uint8_t			*rd_buffer;
+	uint32_t		rs_statword;
+	struct host_rxdesc	*rd_next;
+	struct host_rxdesc	*rd_pa;
+	struct host_rxdesc	*rd_va;
+	void			*node;		/* Where the frame was from */
+	uint8_t			gain_db;
+};
+
+struct host_descfifo {
+	struct host_rxdesc	*df_fifo;		/* Pointer to first descriptor in linked list */
+	volatile uint32_t	df_numelems;		/* Num elems on fifo */
+	volatile uint32_t	df_size;		/* Size of fifo */
+	struct host_rxdesc * volatile hrdstart; /* the ptr to the host_rxdesc linked list  ready for indication */
+};
+
+struct host_scanfifo {
+	uint32_t	sf_req;	/* Pointer to request mailbox */
+	uint32_t	sf_res;	/* Pointer to result mailbox */
+	uint8_t	sf_sem;	/* Semaphore for Scan fifo */
+	uint8_t	tx_sem; /* Semaphore for Scan fifo */
+	uint8_t	____pad[2];
+};
+
+struct host_rxfifo {
+	struct host_descfifo *rf_fifo;	/* Data Descriptor fifo */
+	uint8_t	rf_sem;		/* Semaphore for rx fifo */
+	uint8_t	____pad[3];
+};
+
+struct host_ndp_mesg {
+	uint8_t	macaddr_ta[6];
+	uint8_t	bw;
+	uint8_t	rxgain;
+	uint8_t	mcs;
+	uint8_t	____pad[3];
+};
+
+
+struct host_ioctl {
+	lhost_volatile uint32_t	ioctl_dev;	/* Device to run IOCTL on */
+	lhost_volatile uint32_t	ioctl_command;	/* Command type */
+	lhost_volatile uint32_t	ioctl_arg1;	/* Single valued arg 1 */
+	lhost_volatile uint32_t	ioctl_arg2;	/* Single valued arg 2 */
+	volatile uint32_t		ioctl_argp;	/* Argument payload pointer */
+	volatile uint32_t		ioctl_status;	/* Status from other side */
+	volatile uint32_t		ioctl_rc;	/* Command return code */
+	lhost_volatile struct host_ioctl *ioctl_next;	/* link to next msg in chain */
+};
+
+struct qtn_vap_args {
+	char vap_name[17];
+	uint8_t vap_id;
+	uint8_t vap_macaddr[IEEE80211_ADDR_LEN];
+};
+
+struct qtn_setparams_args
+{
+	int	ni_param;
+	int	ni_value;
+	int	ni_len;
+	unsigned char ni_data[64];
+};
+
+struct qtn_baparams_args {
+	unsigned char ni_addr[8];
+	enum ieee80211_ba_state	state;
+	int	tid;
+	int	type;
+	int	start_seq_num;
+	int	window_size;
+	int	lifetime;
+	uint16_t flags;
+};
+
+#define QTN_HLINK_RC_DONE		0x00000001
+#define QTN_HLINK_RC_ERR		0x00000002
+#define QTN_HLINK_STATUS_AVAIL		1
+
+#define	IOCTL_DEV_VAPCREATE		4	/* Create a vap */
+#define IOCTL_DEV_DEVOPEN		5	/* Bring the device up */
+#define IOCTL_DEV_BEACON_START		6	/* Start Beacon */
+#define	IOCTL_DEV_NEWASSOC		7	/* New associated node */
+#define	IOCTL_DEV_NEWBSSID		8	/* New associated node */
+#define IOCTL_DEV_SEND_NDP_ANNOUNCEMENT	10	/* Send NDP announcement */
+#define IOCTL_DEV_SETPARAMS		11	/* Configure Parameters */
+#define IOCTL_DEV_GETPARAMS		12	/* Configure Parameters */
+#define IOCTL_DEV_BA_ADDED_TX		13
+#define IOCTL_DEV_BA_ADDED_RX		14
+#define IOCTL_DEV_BA_REMOVED_TX		15
+#define IOCTL_DEV_BA_REMOVED_RX		16
+#define	IOCTL_DEV_CHANGE_CHANNEL	17
+#define	IOCTL_DEV_SETKEY		18
+#define IOCTL_DEV_CALCMD		19	/* Send the cal cmd */
+#define	IOCTL_DEV_DELKEY		20
+#define	IOCTL_DEV_CMD			21	/* General commands */
+#define IOCTL_DEV_DISASSOC		22	/* Configure node */
+#define	IOCTL_DEV_SMPS			23	/* MIMO power save mode change */
+#define	IOCTL_DEV_FORCEMICERROR		24
+#define IOCTL_DEV_SET_SCANMODE		25
+#define IOCTL_DEV_XMITCTL		26	/* transmission control (turning on or off) */
+#define IOCTL_DEV_BEACON_STOP		27	/* Stop transmitting beacons */
+#define IOCTL_DEV_SET_MACADDR		30
+#define IOCTL_DEV_KILL_MUC		31
+#define IOCTL_DEV_DUMP_LOG		32
+#define IOCTL_DEV_SET_HRFLAGS		33
+#define IOCTL_DEV_SAMPLE_CHANNEL	34
+#define	IOCTL_DEV_CHANGE_CHAN_DEFERRED	35
+#define	IOCTL_DEV_WMM_PARAMS		36
+#define IOCTL_DEV_VAPDELETE		37	/* Delete a vap */
+#define IOCTL_DEV_STORE_TXPOW		38	/* Store the Tx power, short-range workaround*/
+#define IOCTL_DEV_USE_RTS_CTS		39	/* Enable-disable RTS-CTS */
+#define IOCTL_DEV_RST_QUEUE_DEPTH	40
+#define IOCTL_DEV_SET_POWER_SAVE	41	/* send request to MuC to change power save level */
+#define IOCTL_DEV_VSP			42	/* Configure QVSP */
+#define IOCTL_DEV_SET_11G_ERP           43      /* set 11bg ERP on/off */
+#define IOCTL_DEV_BGSCAN_CHANNEL	44
+#define IOCTL_DEV_SET_OCAC		46
+#define IOCTL_DEV_MEAS_CHANNEL		47	/* notify MUC to execute measurement */
+#define IOCTL_DEV_GET_LINK_MARGIN_INFO	48	/* get rssi info */
+#define	IOCTL_DEV_SET_TDLS_PARAM	49	/* set tdls related paramters */
+#define	IOCTL_DEV_GET_TDLS_PARAM	50	/* set tdls related paramters */
+#define	IOCTL_DEV_POWER_SAVE		51	/* enter/leave power save state */
+#define	IOCTL_DEV_REMAIN_CHANNEL	52	/* Remain on target channel */
+#define IOCTL_DEV_SCS_UPDATE_SCAN_STATS	53
+#define IOCTL_DEV_SET_SCANMODE_STA	54
+#define IOCTL_DEV_GET_MU_GRP		55	/* get MU groups other releated data */
+#define IOCTL_DEV_SET_RX_GAIN_PARAMS	56	/* Set RX gain params */
+#define IOCTL_DEV_GET_MU_ENABLE		57	/* get MU enable flag */
+#define IOCTL_DEV_GET_PRECODE_ENABLE	58	/* get MU precode enable flag */
+#define IOCTL_DEV_GET_MU_USE_EQ		59	/* get EQ enable flag */
+#define IOCTL_DEV_SET_CHAN_POWER_TABLE	60	/* Set MuC power table */
+#define	IOCTL_DEV_ENABLE_VLAN		61	/* Set Global Vlan mode */
+#define	IOCTL_DEV_NODE_UPDATE		62	/* Update node information again after association */
+#define IOCTL_DEV_AIRTIME_CONTROL       63      /* control node tx airtime accumulation start|stop */
+#define IOCTL_DEV_SUSPEND_OFF_CHANNEL   64      /* suspend/resume all off-channel mechanisms globally */
+#define IOCTL_DEV_MU_GROUP_UPDATE	65	/* Update MU groups: nodes and qmats */
+#define IOCTL_DEV_FLUSH_DATA		66	/* periodically flush data */
+#define IOCTL_DEV_GET_TX_MAXAMSDU	67	/* get the TX max msdu size */
+#define IOCTL_DEV_SAMPLE_CHANNEL_CANCEL	68	/* cancel ongoing off channel sampling, when it finished, MuC notifies LHost by irq */
+#define IOCTL_DEV_UPDATE_OCAC_STATE_IE	69	/* OCAC: Update OCAC State IE at MuC */
+
+#define IOCTL_DEV_CMD_MEMDBG_DUMP	1	/* Dump MuC memory */
+#define IOCTL_DEV_CMD_MEMDBG_DUMPCFG	2	/* Configuration for dumping MuC memory */
+#define IOCTL_DEV_CMD_MEMDBG_DUMPNODES	3	/* Configuration for dumping MuC nodes */
+#define IOCTL_DEV_CMD_SET_DRV_DBG	4	/* Set MUC debug message level*/
+#define IOCTL_DEV_CMD_GET_DRV_DBG	5	/* Get MUC debug message level*/
+#define IOCTL_DEV_CMD_RF_REG_DUMP	6	/* Dump Rfic6 write fegister */
+
+#define	IOCTL_DEVATTACH_DEVFLAG_MASK			0xFFFF0000
+#define	IOCTL_DEVATTACH_DEVFLAG_MASK_S			16
+#define	IOCTL_DEVATTACH_DEVID_MASK			0x000000FF
+#define	IOCTL_DEVATTACH_DEV_RFCHIP_FREQID_MASK		0x00000F00
+#define	IOCTL_DEVATTACH_DEV_RFCHIP_FREQID_MASK_S	8
+#define	IOCTL_DEVATTACH_DEV_RFCHIP_VERID_MASK		0x0000F000
+#define	IOCTL_DEVATTACH_DEV_RFCHIP_VERID_MASK_S		12
+#define	IOCTL_DEVATTACH_IRQNUM				0x000000FF
+#define	IOCTL_DEVATTACH_IRQREG				0x00000F00
+#define	IOCTL_DEVATTACH_IRQREG_S			8
+#define	IOCTL_DEVATTACH_NMBOX_MASK			0x000000FF
+
+#define QTN_CHAN_IEEE			(0xFF << 0)
+#define QTN_CHAN_IEEE_S			(0)
+#define QTN_CHAN_PWR			(0xFF << 8)
+#define QTN_CHAN_PWR_S			(8)
+
+#define QTNCHAN_TO_IEEENUM(chan)	(MS(chan, QTN_CHAN_IEEE))
+
+#define QTN_CHAN_FLG_DFS		0x20000000
+#define QTN_CHAN_FLG_HT40		0x40000000
+#define QTN_CHAN_FLG_PRI_HI		0x80000000
+#define QTN_CHAN_FLG_RSV01		0x01000000
+#define QTN_CHAN_FLG_RSV02		0x02000000
+#define QTN_CHAN_FLG_RSV04		0x04000000
+#define QTN_CHAN_FLG_RSV08		0x08000000
+#define QTN_CHAN_FLG_RSV10		0x10000000
+
+#define QTN_CHAN_FLG_VHT80		0x00800000
+
+#define QTN_BAND_FREQ			(0xFF << 0)
+#define QTN_BAND_FREQ_S			(0)
+
+#define	IOCTL_HLINK_DEVATTACH		1	/* Attach device */
+#define	IOCTL_HLINK_DEVDETACH		2	/* Detach device */
+#define	IOCTL_HLINK_DEVCHANGE		3	/* Change device state/flags */
+#define IOCTL_HLINK_LOGATTACH		4	/* Attach Log */
+#define IOCTL_HLINK_TEMP_ATTACH		5	/* Share temperature struct */
+#define IOCTL_HLINK_SVCERRATTACH	6	/* Attach svcerr */
+#define IOCTL_HLINK_RTNLEVENT		7	/* RTNL event */
+#define IOCTL_HLINK_NDP_FRAME		8	/* NDP frame */
+#define IOCTL_HLINK_FOPS_REQ		9	/* Recv File I/O req */
+#define IOCTL_HLINK_MIC_ERR		10	/* TKIP MIC failure detected */
+#define IOCTL_HLINK_BOOTED		11	/* MuC boot complete */
+#define IOCTL_HLINK_DROP_BA		12	/* drop BA */
+#define IOCTL_HLINK_DISASSOC_STA	13	/* disassociate station with a given aid */
+#define IOCTL_HLINK_RFIC_CAUSED_REBOOT  14      /* detected RFIC abnormal reset, reboot the system */
+#define IOCTL_HLINK_BA_ADD_START	15	/* start Tx ADDBA REQ sequence */
+#define IOCTL_HLINK_PEER_RTS		16	/* Peer RTS enable or disable */
+#define IOCTL_HLINK_DYN_WMM		17	/* Dynamic WMM enable or disable */
+#define IOCTL_HLINK_TDLS_EVENTS		18	/* TDLS Events from MuCfw */
+#define IOCTL_HLINK_RATE_TRAIN		19	/* Per-node rate training hash */
+#define IOCTL_HLINK_CSA_COMPLETE	20	/* channel switch count down complete */
+#define IOCTL_HLINK_OCAC_BACKOFF_DONE	21	/* OCAC: BACKOFF -> NONE transition done */
+#define IOCTL_HLINK_CCA_STATS		22	/* Getting CCA stats */
+
+enum {
+	BW_INVALID = 0,
+	BW_HT20 = 20,
+	BW_HT40 = 40,
+	BW_HT80 = 80,
+	BW_HT160 = 160
+};
+
+struct qtn_off_chan_info {
+	uint32_t	freq_band;
+	uint32_t	channel;
+	uint32_t	dwell_msecs;
+	uint32_t	muc_status;
+#define QTN_OFF_CHAN_FLAG_ACTIVE		0x0001
+#define QTN_OFF_CHAN_FLAG_PASSIVE_FAST		0x0002
+#define QTN_OFF_CHAN_FLAG_PASSIVE_NORMAL	0x0004
+#define QTN_OFF_CHAN_FLAG_PASSIVE_SLOW		0x0008
+#define QTN_OFF_CHAN_FLAG_PASSIVE_ONESHOT	0x0010
+#define QTN_OFF_CHAN_TURNOFF_RF			0x0020
+#define QTN_OFF_CHAN_FLAG_MASK			(QTN_OFF_CHAN_FLAG_ACTIVE |		\
+						QTN_OFF_CHAN_FLAG_PASSIVE_FAST |	\
+						QTN_OFF_CHAN_FLAG_PASSIVE_NORMAL |	\
+						QTN_OFF_CHAN_FLAG_PASSIVE_SLOW |	\
+						QTN_OFF_CHAN_FLAG_PASSIVE_ONESHOT)
+	uint16_t	flags;
+};
+
+/* Fixed bw command offset */
+#define QTN_BW_FIXED_BW		0x3
+#define QTN_BW_FIXED_BW_S	0
+#define QTN_BW_FIXED_EN		0x10
+#define QTN_BW_FIXED_EN_S	4
+
+struct qtn_csa_info {
+	uint64_t	req_tsf;		/* aim to change channels at this tsf */
+	uint64_t	switch_tsf;		/* tsf just after channel change completed */
+	uint32_t	pre_notification_tu;	/* pre-switch notification to lhost in TU */
+	uint32_t	post_notification_tu;	/* post channel change notification */
+	uint32_t	freq_band;		/* freqency band info */
+	uint32_t	channel;		/* channel to switch to */
+	uint8_t		sta_dfs_strict_mode;
+#define QTN_CSA_STATUS_MUC_SCHEDULED		0x00000001
+#define QTN_CSA_STATUS_MUC_ERROR_SCHED		0x00000010
+#define QTN_CSA_STATUS_MUC_PRE			0x00000002
+#define QTN_CSA_STATUS_MUC_SWITCHED		0x00000004
+#define QTN_CSA_STATUS_MUC_POST			0x00000008
+#define QTN_CSA_STATUS_MUC_ERROR_SW		0x00000010
+#define QTN_CSA_STATUS_MUC_CANCELLED		0x00000020
+#define QTN_CSA_STATUS_MUC_COMPLETE		0x00000040
+	uint32_t	muc_status;		/* status written by MuC */
+
+#define QTN_CSA_RESTART_QUEUE			0x00000001
+#define QTN_CSA_STATUS_LHOST_PRE_DONE		0x00000002
+#define QTN_CSA_STATUS_LHOST_SWITCH_DONE	0x00000004
+#define QTN_CSA_STATUS_LHOST_POST_DONE		0x00000008
+#define QTN_CSA_CANCEL				0x00000010
+#define QTN_CSA_STATUS_LHOST_ACTIVE		0x00000020
+#define QTN_CSA_STATUS_LHOST_UNITS_OFFSET	0x00000040
+	uint32_t	lhost_status;		/* flags written by lhost */
+};
+
+#define MEAS_RPI_HISTOGRAM_SIZE		8
+
+enum meas_reason {
+	QTN_MEAS_REASON_SUCC = 0,
+	QTN_MEAS_REASON_OFF_CHANNEL_UNSUPPORT,
+	QTN_MEAS_REASON_DURATION_TOO_SHORT,
+	QTN_MEAS_REASON_TIMER_SCHED_FAIL,
+	QTN_MEAS_REASON_TYPE_UNSUPPORT,
+	QTN_MEAS_REASON_MAX,
+};
+
+enum meas_type {
+	QTN_MEAS_TYPE_BASIC = 0,
+	QTN_MEAS_TYPE_CCA,
+	QTN_MEAS_TYPE_RPI,
+	QTN_MEAS_TYPE_CHAN_LOAD,
+	QTN_MEAS_TYPE_NOISE_HIS,
+	QTN_MEAS_TYPE_MAX,
+};
+
+struct meas_time_slice {
+	uint32_t meas_slice;	/* time slice */
+	uint32_t meas_time_pri;	/* prime time count based on meas_slice */
+	uint32_t meas_time_sec; /* secondary time count based on meas_slice */
+};
+
+struct qtn_meas_chan_info {
+	uint32_t work_channel;			/* working channel to return to */
+	int32_t	meas_type;			/* measurement type */
+	int32_t	meas_reason;			/* measurement reason */
+	struct meas_time_slice time_slice;	/* time slice for measurement long duration */
+	uint32_t meas_channel;
+	uint64_t meas_start_tsf;
+	uint32_t meas_dur_ms;
+	union {
+		struct {
+			uint32_t cca_busy_cnt;
+			uint32_t cca_try_cnt;
+			uint32_t cca_try_ms;
+			uint32_t cca_busy_ms;
+		} cca_and_chanload;
+		uint8_t rpi_counts[MEAS_RPI_HISTOGRAM_SIZE];
+		int32_t basic_radar_num;
+		uint8_t basic;
+	} inter_data;
+};
+
+enum scs_lot_tsf_pos {
+	SCS_LOG_TSF_POS_LHOST_TASK_KICKOFF,
+	SCS_LOG_TSF_POS_LHOST_IOCTL2MUC,
+	SCS_LOG_TSF_POS_MUC_POLL_IOCTL_FROM_LHOST,
+	SCS_LOG_TSF_POS_MUC_QOSNULL_SENT,
+	SCS_LOG_TSF_POS_MUC_SMPL_START_BEFORE_CHAN_CHG,
+	SCS_LOG_TSF_POS_MUC_SMPL_START_AFTER_CHAN_CHG,
+	SCS_LOG_TSF_POS_MUC_SMPL_FINISH_BEFORE_CHAN_CHG,
+	SCS_LOG_TSF_POS_MUC_SMPL_FINISH_AFTER_CHAN_CHG,
+	SCS_LOG_TSF_POS_LHOST_CCA_INTR,
+	SCS_LOG_TSF_POS_LHOST_CCA_WORK,
+	SCS_LOG_TSF_POS_NUM
+};
+
+#define IEEE80211_SCS_LOG_TSF(_ic, _sample, _pos)	((_ic)->ic_get_tsf(&((_sample)->tsf[(_pos)])))
+#define QDRV_SCS_LOG_TSF(_sample, _pos)			(hal_get_tsf(&((_sample)->tsf[(_pos)])))
+#define MUC_SCS_LOG_TSF(_qh, _sample, _pos)		(hal_get_tsf((_qh), &((_sample)->tsf[(_pos)])))
+
+struct qtn_samp_chan_info {
+	struct qtn_off_chan_info base;		/* off channel base info, must be placed as the first field */
+#define QTN_CCA_STATUS_IDLE		0x0
+#define QTN_CCA_STATUS_HOST_IOCTL_SENT	0x1
+#define QTN_CCA_STATUS_MUC_SCHEDULED	0x2
+#define QTN_CCA_STATUS_MUC_STARTED	0x3
+#define QTN_CCA_STATUS_MUC_COMPLETE	0x4
+#define QTN_CCA_STATUS_MUC_CANCELLING	0x5
+#define QTN_CCA_STATUS_MUC_CANCELLED	0x6
+
+	uint64_t		start_tsf;	/* tsf at which to start sampling */
+
+	struct out_cca_info	result;		/* results structure for CCA measurement */
+#define QTN_CCA_TYPE_BACKGROUND		0x1
+#define QTN_CCA_TYPE_DIRECTLY		0x2
+	uint32_t		type;
+
+	uint32_t		qosnull_txdesc_host;	/* qosnull frame for channel sampling */
+	uint32_t		qosnull_txdesc_bus;	/* qosnull frame in phyaddr */
+	uint16_t		qosnull_frame_len;	/* the frame length of qosnull */
+	uint16_t		tx_node_idx;		/* the node index that qosnull frame to */
+	uint32_t		qosnull_txtsf;		/* the tsf_lo read from MAC on that qosnull frame was sent successfully */
+	uint32_t		qosnull_nav;		/* the large NAV in qosnull frame */
+	uint64_t		tsf[SCS_LOG_TSF_POS_NUM];	/* timestamps used for precise time control and profiling */
+};
+
+#define QTN_SCS_ASSOC_STA_MAX	12
+
+struct qtn_scs_vsp_node_stats {
+	uint32_t ni_associd;
+	uint32_t tx_usecs;
+	uint32_t rx_usecs;
+};
+
+struct qtn_scs_vsp_info {
+	uint32_t	num_of_assoc;
+	struct  qtn_scs_vsp_node_stats scs_vsp_node_stats[QTN_SCS_ASSOC_STA_MAX];
+};
+
+struct qtn_scs_scan_info {
+	uint32_t	bw_sel;
+	uint32_t	cca_idle;
+	uint32_t	cca_busy;
+	uint32_t	cca_tx;
+	uint32_t	cca_intf;
+	uint32_t	cca_try;
+	uint32_t	cca_pri;
+	uint32_t	cca_sec20;
+	uint32_t	cca_sec40;
+	uint32_t	bcn_rcvd;
+	uint32_t	crc_err;
+	uint32_t	lpre_err;
+	uint32_t	spre_err;
+};
+
+#define QTN_SCS_MAX_OC_INFO	32
+struct qtn_scs_data_history {
+#define QTN_SCS_FILTER_WINDOW_SZ	5
+#define QTN_SCS_FILTER_MEDIAN_IDX	(QTN_SCS_FILTER_WINDOW_SZ / 2)
+	uint32_t idx;
+	uint32_t buffer[QTN_SCS_FILTER_WINDOW_SZ];
+};
+
+struct qtn_scs_stats_history {
+	struct qtn_scs_data_history lp_errs[IEEE80211_MAX_DUAL_CHANNELS];
+	struct qtn_scs_data_history sp_errs[IEEE80211_MAX_DUAL_CHANNELS];
+};
+
+struct qtn_scs_oc_info {
+	uint32_t	off_channel;
+	uint32_t	off_chan_bw_sel;
+	uint32_t	off_chan_cca_busy;
+	uint32_t	off_chan_cca_sample_cnt;
+	uint32_t	off_chan_cca_try_cnt;
+	uint32_t	off_chan_beacon_recvd;
+	uint32_t	off_chan_crc_errs;
+	uint32_t	off_chan_sp_errs;
+	uint32_t	off_chan_lp_errs;
+	uint32_t	off_chan_cca_pri;
+	uint32_t	off_chan_cca_sec;
+	uint32_t	off_chan_cca_sec40;
+};
+/* Smart channel selection data shared between Lhost and MuC */
+struct qtn_scs_info {
+	uint32_t	oc_info_count;
+	struct qtn_scs_oc_info oc_info[QTN_SCS_MAX_OC_INFO];
+	uint32_t	bw_sel;
+	uint32_t	cca_try;
+	uint32_t	cca_busy;
+	uint32_t	cca_idle;
+	uint32_t	cca_tx;
+	uint32_t	cca_interference;
+	uint32_t	cca_pri;
+	uint32_t	cca_sec20;
+	uint32_t	cca_sec40;
+	uint32_t	beacon_recvd;
+	uint32_t	tx_usecs;
+	uint32_t	rx_usecs;
+	struct qtn_scs_vsp_info scs_vsp_info;
+};
+
+struct qtn_scs_info_set {
+	uint32_t	valid_index; /* 0 or 1 */
+	struct qtn_scs_info scs_info[2];
+	struct qtn_scs_scan_info scan_info[IEEE80211_CHAN_MAX];
+	struct qtn_scs_stats_history stats_history;
+};
+
+struct qtn_remain_chan_info {
+	uint32_t freq_band;
+	uint32_t data_channel;		/* Data channel to return to */
+	uint32_t off_channel;		/* The required remain channel */
+	uint32_t duration_usecs;	/* Duration in microseconds to stay on remain channel */
+	uint64_t start_tsf;		/* tsf at which to switch to remain channel */
+	uint32_t timeout_usecs;		/* timeout in microseconds to return base channel */
+
+#define QTN_REM_CHAN_STATUS_IDLE		0x0
+#define QTN_REM_CHAN_STATUS_HOST_IOCTL_SENT	0x1
+#define QTN_REM_CHAN_STATUS_MUC_SCHEDULED	0x2
+#define QTN_REM_CHAN_STATUS_MUC_STARTED	0x3
+#define QTN_REM_CHAN_STATUS_MUC_COMPLETE	0x4
+#define QTN_REM_CHAN_STATUS_MUC_CANCELLED	0x5
+	uint32_t status;		/* channel switch status */
+
+	uint8_t peer_mac[IEEE80211_ADDR_LEN];	/* peer node mac address */
+};
+
+
+#define QTN_CCA_CNT2MS(_cnt)   RUBY_TIMER_MUC_CCA_CNT2MS(_cnt)
+#define QTN_CCA_INTV           RUBY_TIMER_MUC_CCA_INTV
+
+enum scan_chan_tsf_pos {
+	SCAN_CHAN_TSF_LHOST_HOSTLINK_IOCTL = 0,
+	SCAN_CHAN_TSF_MUC_IOCTL_PROCESS,
+	SCAN_CHAN_TSF_MUC_SEND_START_FRM,
+	SCAN_CHAN_TSF_MUC_SEND_START_FRM_DONE,
+	SCAN_CHAN_TSF_MUC_GOTO_OFF_CHAN,
+	SCAN_CHAN_TSF_MUC_GOTO_OFF_CHAN_DONE,
+	SCAN_CHAN_TSF_MUC_SEND_PRBREQ_FRM,
+	SCAN_CHAN_TSF_MUC_SEND_PRBREQ_FRM_DONE,
+	SCAN_CHAN_TSF_MUC_GOTO_DATA_CHAN,
+	SCAN_CHAN_TSF_MUC_GOTO_DATA_CHAN_DONE,
+	SCAN_CHAN_TSF_MUC_SEND_FINISH_FRM,
+	SCAN_CHAN_TSF_MUC_SEND_FINISH_FRM_DONE,
+	SCAN_CHAN_TSF_LHOST_INTERRUPT,
+	SCAN_CHAN_TSF_LHOST_SCANWORK,
+	SCAN_CHAN_TSF_LOG_NUM
+};
+
+struct off_chan_tsf_dbg {
+	int pos_index;
+	char *log_name;
+};
+
+#define QDRV_SCAN_LOG_TSF(_scan, _pos)		(hal_get_tsf(&((_scan)->tsf[(_pos)])))
+#define MUC_SCAN_LOG_TSF(_qh, _scan, _pos)	(hal_get_tsf((_qh), &((_scan)->tsf[(_pos)])))
+
+struct qtn_scan_chan_info {
+	struct qtn_off_chan_info base;		/* off channel base info, must be placed as the first field */
+#define TIME_MARGIN_BEFORE_STARTFRM	3000	/* microseconds, time overhead for others before start frame is sent*/
+#define TIME_MARGIN_AFTER_STARTFRM	1000	/* microseconds, time overhead for others after start frame is sent*/
+#define TIME_OFFSET_SEND_PROBE_REQ	3000	/* microseconds, the time offset for sending probe_req frame
+						 * after switching to off channel*/
+#define TIME_OFFSET_SEND_START_FRM	5000	/* microseconds, the time offset for sending start frame
+						 * after set NETDEV_F_PAUSE_TX flag */
+#define TIME_DUR_FOR_ALL_BEACONS	25000	/* microseconds, the time duration for transmitting all beacons */
+#define TIME_MIN_WAIT_PROBE_REP		5000	/* microseconds, the minimal time for waiting for the probe
+						 * response frame on scanning channel */
+#define QTN_SCAN_CHAN_MUC_IDLE			0x0
+#define QTN_SCAN_CHAN_MUC_STARTED		0x1
+#define QTN_SCAN_CHAN_MUC_PROBING		0x2
+#define QTN_SCAN_CHAN_MUC_COMPLETED		0x3
+#define QTN_SCAN_CHAN_MUC_FAILED		0x4
+#define QTN_SCAN_CHAN_MUC_SCHEDULED		0x5
+
+	uint32_t	scan_flags;
+	uint32_t	start_txdesc_host;	/* The frame sent before go scan channel,
+						 * e.g. pwrsav frame in STA mode */
+	uint32_t	start_txdesc_bus;	/* Start frame in phyaddr */
+	uint16_t	start_node_idx;		/* the node index that frame to */
+	uint16_t	start_frame_len;	/* frame length */
+	uint32_t	prbreq_txdesc_host;	/* probe request frame for active scanning */
+	uint32_t	prbreq_txdesc_bus;	/* probe request frame in phyaddr */
+	uint16_t	prbreq_node_idx;	/* the node index that frame to */
+	uint16_t	prbreq_frame_len;	/* frame length */
+	uint32_t	finish_txdesc_host;	/* The frame sent after back data channel,
+						 * e.g. the frame to announce waking up in STA mode */
+	uint32_t	finish_txdesc_bus;	/* Complete frame in phyaddr */
+	uint16_t	finish_node_idx;		/* the node index that frame to */
+	uint16_t	finish_frame_len;	/* frame length */
+	uint64_t	tsf[SCAN_CHAN_TSF_LOG_NUM];
+};
+
+enum qtn_ocac_tsf_log {
+	OCAC_TSF_LOG_GOTO_OFF_CHAN = 0,
+	OCAC_TSF_LOG_GOTO_OFF_CHAN_DONE,
+	OCAC_TSF_LOG_GOTO_DATA_CHAN,
+	OCAC_TSF_LOG_GOTO_DATA_CHAN_DONE,
+	OCAC_TSF_LOG_NUM
+};
+
+struct qtn_ocac_info {
+	uint32_t		freq_band;	/* frequency band, written by lhost */
+	uint32_t		off_channel;	/* The off channel, "0" means to stop ocac in MuC, written by lhost*/
+	uint32_t		qosnull_txdesc_host;	/* qosnull frame in virtual address, written by lhost */
+	uint32_t		qosnull_txdesc_bus;	/* qosnull frame in physical address, written by lhost */
+	uint16_t		qosnull_frame_len;	/* the frame length of qosnull */
+	uint16_t		tx_node_idx;		/* the node index that qosnull frame to */
+	uint16_t		dwell_time;	/* the required time on off channel in one beacon interval, written by lhost */
+	uint16_t		secure_dwell;	/* milliseconds, the time on off channel within on off-channel action, using
+							qosnull frame with large NAV to protect the traffic */
+	uint16_t		threshold_fat;	/* the fat threshold to run off-channel CAC, written by lhost */
+	uint16_t		threshold_traffic;	/* the traffic threshold to run off-channel CAC, written by lhost */
+	uint16_t		threshold_fat_dec;	/* the threshold for consecutive fat decrease, written by lhost */
+	uint16_t		traffic_ctrl;	/* whether to send qosnull or not, written by lhost */
+	uint16_t		offset_txhalt;	/* milliseconds, the offset after beacon to halt tx, written by lhost */
+	uint16_t		offset_offchan;	/* milliseconds, the offset after halt tx to switch off channel, written by lhost */
+
+#define QTN_OCAC_ON_DATA_CHAN	0x1
+#define QTN_OCAC_ON_OFF_CHAN	0x2
+	uint16_t		chan_status;	/* current on which channel, written by MuC */
+	uint16_t		actual_dwell_time;	/* the actual time on off channel, written by MuC */
+	uint64_t		tsf_log[OCAC_TSF_LOG_NUM];	/* event tsf log, written by MuC */
+};
+
+enum bmps_state_e {
+	BMPS_STATE_OFF		= 0,		/* STA exits BMPS mode */
+	BMPS_STATE_WAKE		= 1,		/* in BMPS mode, and is fully powered on */
+						/* with PM set to 0 */
+	BMPS_STATE_SLEEP	= 2,		/* in BMPS mode, and is fully powered off */
+						/* with PM set to 1 */
+	BMPS_STATE_WAKE_TO_SLEEP	= 3,	/* in BMPS mode, and is transitting from */
+						/* power-on to power-off by sending Null frame */
+						/* with PM=1 to AP */
+	BMPS_STATE_LEAK_WINDOW	= 4,		/* in BMPS mode, and Null frame with PM=1 */
+						/* has been sent, TX path is paused, */
+						/* but RX patgh is still running to */
+						/* receive packets from leaky AP */
+	BMPS_STATE_SLEEP_TO_WAKE	= 5,	/* in BMPS mode, and is transitting from */
+						/* power-off to power-on by sending */
+						/* Null frame with PM=0 to AP */
+	BMPS_STATE_BEACON_SNOOP	= 6,		/* in BMPS mode, and RX chain is powered up */
+						/* to receive beacon */
+	BMPS_STATE_MAX		= BMPS_STATE_BEACON_SNOOP,
+};
+
+struct qtn_bmps_info {
+	uint32_t	null_txdesc_host;	/* null frame in virtual address */
+	uint32_t	null_txdesc_bus;	/* null frame in physical address */
+	uint16_t	null_frame_len;		/* the frame length of null */
+	uint16_t	tx_node_idx;		/* the node index that null frame to */
+	enum bmps_state_e	state;		/* shared BMPS status */
+};
+
+struct qtn_rf_rxgain_params
+{
+	uint8_t lna_on_indx;
+	uint8_t max_gain_idx;
+	int16_t cs_thresh_dbm;
+	int16_t cca_prim_dbm;
+	int16_t cca_sec_scs_off_dbm;
+	int16_t cca_sec_scs_on_dbm;
+};
+
+/* MuC fops requst */
+#define MUC_FOPS_MAX_FNAME_SIZE (50)
+enum {
+	MUC_FOPS_OPEN = 0,
+	MUC_FOPS_READ,
+	MUC_FOPS_WRITE,
+	MUC_FOPS_LSEEK,
+	MUC_FOPS_CLOSE,
+};
+
+enum {
+	MUC_FOPS_PENDING = 0x011ADDED,
+	MUC_FOPS_DONE    = 0xF035D0DE,
+};
+
+enum {
+	MUC_FOPS_RDONLY = 0x0,
+	MUC_FOPS_WRONLY = 0x1,
+	MUC_FOPS_RDWR 	= 0x2,
+	MUC_FOPS_APPEND = 0x4,
+};
+
+struct muc_fops_req	{
+	volatile int32_t ret_val;
+	volatile int32_t fd;
+	volatile uint32_t req_state;
+	volatile char *data_buff;
+};
+
+enum qdrv_cmd_muc_memdbgcnf_s {
+	QDRV_CMD_MUC_MEMDBG_STATUS,
+	QDRV_CMD_MUC_MEMDBG_FD_MAX,
+	QDRV_CMD_MUC_MEMDBG_NODE_MAX,
+	QDRV_CMD_MUC_MEMDBG_DUMP_MAX,
+	QDRV_CMD_MUC_MEMDBG_RATETBL,
+	QDRV_CMD_MUC_MEMDBG_MSG_SEND,
+	QDRV_CMD_MUC_MEMDBG_TRACE,
+	QDRV_CMD_MUC_MEMDBG_LAST
+};
+
+/* The following file indexes and file lists must all be kept in sync */
+#define FOPS_FD_EP_SAMPLES		9
+#define FOPS_FD_DCACHE_SAMPLES		10
+#ifdef PROFILE_MUC_SAMPLE_IPTR_AUC
+#define FOPS_FD_IPTR_SAMPLES		15
+#else
+#define FOPS_FD_IPTR_SAMPLES		11
+#endif
+#define FOPS_FD_UBOOT_ENV		12
+
+#ifdef TOPAZ_RFIC6_PLATFORM
+#define LHOST_CAL_FILES         {       \
+        NULL,                           \
+        "/proc/bootcfg/bf_factor",      \
+        "/tmp/txpower.txt",             \
+        "/proc/bootcfg/txpower.cal",    \
+        "/proc/bootcfg/dc_iq.cal",      \
+        "/mnt/jffs2/mon.out",           \
+        "/mnt/jffs2/gmon.out",          \
+        "/mnt/jffs2/pecount.out",       \
+        "/proc/bootcfg/pdetector.cal",  \
+        "/mnt/jffs2/profile_ep_muc",    \
+        "/mnt/jffs2/profile_dcache_muc",\
+        "/mnt/jffs2/profile_iptr_muc",  \
+        "/proc/bootcfg/env",            \
+        "/etc/mtest",           \
+        "/proc/bootcfg/rx_iq.cal", \
+				"/mnt/jffs2/profile_iptr_auc",	\
+				"/proc/bootcfg/bf_factor_2g",	\
+				"/tmp/txpower_2g.txt",		\
+				"/proc/bootcfg/dc_iq_2g.cal",	\
+				"/proc/bootcfg/pdetector_2g.cal",\
+				"/tmp/bond_opt.txt",	        \
+				"/mnt/jffs2/txlo_lpcalib.cal",	        \
+				"/proc/bootcfg/rc_calib.cal",	\
+}
+#else
+#define LHOST_CAL_FILES		{	\
+	NULL,				\
+	"/proc/bootcfg/bf_factor",	\
+	"/tmp/txpower.txt",		\
+	"/proc/bootcfg/txpower.cal",	\
+	"/proc/bootcfg/dc_iq.cal",	\
+	"/mnt/jffs2/mon.out",		\
+	"/mnt/jffs2/gmon.out",		\
+	"/mnt/jffs2/pecount.out",	\
+	"/proc/bootcfg/pdetector.cal",	\
+	"/mnt/jffs2/profile_ep_muc",	\
+	"/mnt/jffs2/profile_dcache_muc",\
+	"/mnt/jffs2/profile_iptr_muc",	\
+	"/proc/bootcfg/env",		\
+  "/etc/mtest",           \
+	"/proc/bootcfg/rx_iq.cal",	\
+	"/mnt/jffs2/profile_iptr_auc",	\
+}
+#endif
+
+#define MUC_CAL_FILES		{	\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	"mon.out",			\
+	"gmon.out",			\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+	NULL,				\
+}
+
+enum tdls_ioctl_params {
+	IOCTL_TDLS_STATUS = 1,
+	IOCTL_TDLS_UAPSD_IND_WND,
+	IOCTL_TDLS_PTI_CTRL,
+	IOCTL_TDLS_PTI,
+	IOCTL_TDLS_PTI_PENDING,
+	IOCTL_TDLS_DBG_LEVEL,
+	IOCTL_TDLS_PTI_DELAY,
+	IOCTL_TDLS_PTI_EVENT = 100
+};
+
+struct qtn_tdls_args {
+	uint8_t		ni_macaddr[IEEE80211_ADDR_LEN];
+	uint16_t	ni_ncidx;
+	uint32_t	tdls_cmd;
+	uint32_t	tdls_params;
+};
+
+struct qtn_node_args
+{
+	/* header */
+	uint8_t	ni_macaddr[IEEE80211_ADDR_LEN];
+	uint8_t	ni_bssid[IEEE80211_ADDR_LEN];
+	uint8_t	ni_nrates;
+	uint8_t	ni_rates[IEEE80211_RATE_MAXSIZE];
+	uint8_t	ni_htnrates;
+	uint8_t	ni_htrates[IEEE80211_HT_RATE_MAXSIZE];
+	uint16_t	ni_associd;	/* assoc response */
+	uint16_t	ni_node_idx;
+	uint16_t	ni_flags;	/* special-purpose state */
+	struct wmm_params	wmm_params[WME_NUM_AC];
+	uint8_t	ni_implicit_ba_rx; /* The RX side of the implicit BA. Zero for no implicit RX BA */
+	uint8_t	ni_implicit_ba_tx; /* The TX side of the implicit BA. Zero for no implicit TX BA */
+	uint16_t	ni_raw_bintval;		/* raw beacon interval */
+	uint16_t	ni_implicit_ba_size; /* Size of the implicit BAs */
+	uint8_t	ni_qtn_ie_flags;
+	uint8_t ni_vendor;
+	uint8_t ni_bbf_disallowed;      /* flag to disallow BBF */
+	uint8_t ni_std_bf_disallowed;      /* flag to disallow standard BF */
+	uint8_t ni_uapsd;	/* U-APSD per-node flags matching WMM STA Qos Info field */
+	uint8_t	ni_htcap[sizeof(struct ieee80211_htcap)];	/* Processed HT capabilities */
+	uint8_t	ni_htinfo[sizeof(struct ieee80211_htinfo)];	/* Processed HT info */
+	uint8_t	ni_vhtcap[sizeof(struct ieee80211_vhtcap)];	/* Processed VHT capabilities */
+	uint8_t	ni_vhtop[sizeof(struct ieee80211_vhtop)];	/* Processed VHT operational info */
+	struct qtn_node_shared_stats *ni_shared_stats;
+	uint32_t	ni_ver_sw;
+	uint32_t	ni_qtn_flags;
+	uint32_t	ni_tdls_status;
+	uint8_t		ni_mu_grp[sizeof(struct ieee80211_vht_mu_grp)];
+	uint16_t	ni_rsn_caps;		/* optional rsn capabilities */
+	uint8_t		rsn_ucastcipher;	/* selected unicast cipher */
+	uint16_t	tdls_peer_associd;	/* tdls peer AID allocated by AP, unique in BSS */
+	uint32_t	ni_rate_train;
+	uint32_t	ni_rate_train_peer;
+};
+
+struct qtn_beacon_args
+{
+	struct wmm_params		wmm_params[WME_NUM_AC];
+	uint32_t			bintval;
+	uint32_t			bo_tim_len;
+	uint32_t			bo_htcap;
+	uint32_t			bo_htinfo;
+	uint32_t			bo_vhtcap;
+	uint32_t			bo_vhtop;
+	uint32_t			bc_ie_head;		/* Beacon ie link list head */
+	uint32_t			bc_ie_buf_start;	/* Beacon ie buffer start for MuC */
+};
+
+struct qtn_key {
+	u_int8_t wk_keylen;		/* key length in bytes */
+	u_int8_t wk_flags;
+#define IEEE80211_KEY_XMIT	0x01	/* key used for xmit */
+#define IEEE80211_KEY_RECV	0x02	/* key used for recv */
+#define IEEE80211_KEY_GROUP	0x04	/* key used for WPA group operation */
+#define IEEE80211_KEY_SWCRYPT	0x10	/* host-based encrypt/decrypt */
+#define IEEE80211_KEY_SWMIC	0x20	/* host-based enmic/demic */
+	u_int16_t wk_keyix;		/* key index */
+	u_int8_t wk_key[IEEE80211_KEYBUF_SIZE + IEEE80211_MICBUF_SIZE];
+#define wk_txmic    wk_key + IEEE80211_KEYBUF_SIZE + 0  /* XXX can't () right */
+#define wk_rxmic    wk_key + IEEE80211_KEYBUF_SIZE + 8  /* XXX can't () right */
+	u_int64_t wk_keyrsc[IEEE80211_TID_SIZE];    /* key receive sequence counter */
+	u_int64_t wk_keytsc;		/* key transmit sequence counter */
+	u_int32_t wk_cipher;		/* cipher */
+	u_int32_t wk_ncidx;		/* node cache index */
+};
+#define IEEE80211_KEY_COMMON		/* common flags passed in by apps */\
+	(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
+
+struct qtn_key_args
+{
+	struct qtn_key	key;
+	uint8_t	wk_addr[IEEE80211_ADDR_LEN];
+};
+
+struct qtn_power_save_args
+{
+	uint32_t enable;
+	uint8_t ni_addr[IEEE80211_ADDR_LEN];
+};
+
+struct lhost_txdesc
+{
+	struct host_txdesc	hw_desc;	/* shared between muc and lhost */
+	struct sk_buff		*skb;
+	struct lhost_txdesc	*next;
+};
+
+#define MUC_TXSTATUS_READY		0x0
+#define MUC_TXSTATUS_DONE		0x1
+
+#define MUC_RXSTATUS_DONE		0x1
+
+#define MUC_RXSTATUS_MIC_ERR		0x00000002
+#define MUC_RXSTATUS_MIC_ERR_S		1
+#define MUC_RXSTATUS_NCIDX		0x00000FFC
+#define MUC_RXSTATUS_NCIDX_S		2
+#define MUC_RXSTATUS_RXLEN		0xFFFF0000
+#define MUC_RXSTATUS_RXLEN_S		16
+
+struct qtn_link_margin_info {
+	uint32_t	mcs;
+	uint32_t	bw;
+	int		rssi_avg;
+	int		reason;
+#define QTN_LINK_MARGIN_REASON_SUCC		0
+#define QTN_LINK_MARGIN_REASON_NOSUCHNODE	1
+	uint8_t		mac_addr[IEEE80211_ADDR_LEN];
+};
+
+#define QTN_RESERVED_DEVIDS		2
+#define QTN_WLANID_FROM_DEVID(devid)	\
+	((devid < QTN_RESERVED_DEVIDS)? 0 : (devid - QTN_RESERVED_DEVIDS))
+
+struct qtn_mu_grp_args {
+	/* MU group ID. 0 means the group is not used and grp_ni is empty*/
+	uint8_t grp_id;
+	/* mu QMat installation status */
+	/* QMat is not installed and not used */
+#define MU_QMAT_DISABLED	0
+	/* QMat is installed and used */
+#define MU_QMAT_ENABLED		1
+	/* QMat is installed, used but not updated */
+#define MU_QMAT_FREEZED		2
+	/* QMat is installed, not used and not updated */
+#define MU_QMAT_NOT_USED	3
+	uint8_t qmat_installed;
+	/* the index of the grp_ni[], is also the user position */
+	uint16_t aid[IEEE80211_MU_GRP_NODES_MAX];
+	uint8_t ncidx[IEEE80211_MU_GRP_NODES_MAX];
+	/* matrix addr offsets in sram */
+	unsigned int u0_1ss_u1_1ss;
+	unsigned int u0_2ss_u1_1ss;
+	unsigned int u0_3ss_u1_1ss;
+	unsigned int u0_1ss_u1_2ss;
+	unsigned int u0_1ss_u1_3ss;
+	unsigned int u0_2ss_u1_2ss;
+	/* stats */
+	uint32_t upd_cnt;
+	int32_t rank;
+};
+
+enum grp_op {
+	MU_GRP_NONE = 0,
+	MU_GRP_INST,
+	MU_GRP_DELE,
+};
+
+struct qtn_mu_group_update_args {
+	enum grp_op op;
+	struct upd_grp {
+		int grp_id;
+		unsigned int ap_devid;
+		uint8_t ap_macaddr[IEEE80211_ADDR_LEN];
+		struct upd_nodes {
+			int as_sta;
+			struct ieee80211_vht_mu_grp grp;
+			uint8_t macaddr[IEEE80211_ADDR_LEN];
+		} nodes[QTN_MU_NODES_PER_GROUP];
+	} groups[QTN_MU_QMAT_MAX_SLOTS];
+};
+
+struct qtn_cca_stats {
+	uint32_t	cca_sample_period;
+	uint32_t	cca_pri_cnt;
+	uint32_t	cca_sec_cnt;
+	uint32_t	cca_sec40_cnt;
+	uint32_t	cca_sample_cnt;
+	uint32_t	cca_try_cnt;
+	uint32_t	cca_csw_cnt;
+	uint32_t	cca_off_try_cnt;
+	uint32_t	cca_meas_cnt;
+	uint32_t	cca_busy_cnt;
+	uint32_t	cca_idle_cnt;
+	uint32_t	cca_tx_cnt;
+	uint32_t	rx_time_cnt;
+	uint32_t	tx_time_cnt;
+	uint32_t	cca_pri;
+	uint32_t	cca_sec;
+	uint32_t	cca_sec40;
+	uint32_t	cca_busy;
+	uint32_t	cca_fat;
+	uint32_t	cca_intf;
+	uint32_t	cca_trfc;
+};
+
+#ifdef CONFIG_NAC_MONITOR
+#define MAX_NAC_STA 128
+	struct nac_stats_entry {
+		uint8_t  nac_valid;
+		uint8_t  nac_avg_rssi;
+		uint8_t  nac_channel;
+		uint8_t  nac_packet_type;
+		uint64_t nac_timestamp;
+		uint8_t  nac_txmac[IEEE80211_ADDR_LEN];
+		uint16_t reserved;
+	};
+	struct nac_mon_info{
+		uint16_t nac_on_time;
+		uint16_t nac_cycle_time;
+		uint16_t nac_monitor_on;
+		uint16_t reserved;
+		struct nac_stats_entry nac_stats[MAX_NAC_STA];
+	};
+#endif
+
+#endif	// _LHOST_MUC_COMM_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/log_table/1024_10log10_table.txt b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/log_table/1024_10log10_table.txt
new file mode 100644
index 0000000..e95c1b3
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/log_table/1024_10log10_table.txt
@@ -0,0 +1,4096 @@
+0,
+3083,
+4886,
+6166,
+7158,
+7969,
+8654,
+9248,
+9772,
+10240,
+10664,
+11051,
+11407,
+11737,
+12044,
+12331,
+12600,
+12854,
+13095,
+13323,
+13540,
+13747,
+13945,
+14134,
+14315,
+14490,
+14658,
+14819,
+14975,
+15126,
+15272,
+15413,
+15550,
+15683,
+15812,
+15937,
+16059,
+16177,
+16293,
+16406,
+16515,
+16623,
+16727,
+16829,
+16929,
+17027,
+17123,
+17216,
+17308,
+17398,
+17486,
+17572,
+17657,
+17740,
+17822,
+17902,
+17981,
+18058,
+18134,
+18209,
+18282,
+18355,
+18426,
+18496,
+18565,
+18633,
+18700,
+18765,
+18830,
+18894,
+18957,
+19020,
+19081,
+19141,
+19201,
+19260,
+19318,
+19376,
+19432,
+19488,
+19543,
+19598,
+19652,
+19705,
+19758,
+19810,
+19861,
+19912,
+19962,
+20012,
+20061,
+20110,
+20158,
+20205,
+20252,
+20299,
+20345,
+20391,
+20436,
+20480,
+20525,
+20569,
+20612,
+20655,
+20697,
+20740,
+20781,
+20823,
+20864,
+20904,
+20945,
+20984,
+21024,
+21063,
+21102,
+21141,
+21179,
+21217,
+21254,
+21291,
+21328,
+21365,
+21401,
+21437,
+21473,
+21508,
+21543,
+21578,
+21613,
+21647,
+21681,
+21715,
+21749,
+21782,
+21815,
+21848,
+21881,
+21913,
+21945,
+21977,
+22009,
+22040,
+22071,
+22102,
+22133,
+22163,
+22194,
+22224,
+22254,
+22284,
+22313,
+22343,
+22372,
+22401,
+22429,
+22458,
+22487,
+22515,
+22543,
+22571,
+22598,
+22626,
+22653,
+22681,
+22708,
+22734,
+22761,
+22788,
+22814,
+22840,
+22866,
+22892,
+22918,
+22944,
+22969,
+22995,
+23020,
+23045,
+23070,
+23094,
+23119,
+23144,
+23168,
+23192,
+23216,
+23240,
+23264,
+23288,
+23311,
+23335,
+23358,
+23382,
+23405,
+23428,
+23450,
+23473,
+23496,
+23518,
+23541,
+23563,
+23585,
+23607,
+23629,
+23651,
+23673,
+23695,
+23716,
+23737,
+23759,
+23780,
+23801,
+23822,
+23843,
+23864,
+23885,
+23905,
+23926,
+23946,
+23967,
+23987,
+24007,
+24027,
+24047,
+24067,
+24087,
+24107,
+24126,
+24146,
+24165,
+24185,
+24204,
+24223,
+24242,
+24261,
+24280,
+24299,
+24318,
+24337,
+24355,
+24374,
+24392,
+24411,
+24429,
+24447,
+24466,
+24484,
+24502,
+24520,
+24538,
+24555,
+24573,
+24591,
+24608,
+24626,
+24643,
+24661,
+24678,
+24695,
+24713,
+24730,
+24747,
+24764,
+24781,
+24798,
+24815,
+24831,
+24848,
+24865,
+24881,
+24898,
+24914,
+24930,
+24947,
+24963,
+24979,
+24995,
+25011,
+25028,
+25043,
+25059,
+25075,
+25091,
+25107,
+25122,
+25138,
+25154,
+25169,
+25185,
+25200,
+25215,
+25231,
+25246,
+25261,
+25276,
+25291,
+25307,
+25322,
+25336,
+25351,
+25366,
+25381,
+25396,
+25410,
+25425,
+25440,
+25454,
+25469,
+25483,
+25498,
+25512,
+25526,
+25541,
+25555,
+25569,
+25583,
+25597,
+25611,
+25625,
+25639,
+25653,
+25667,
+25681,
+25695,
+25708,
+25722,
+25736,
+25749,
+25763,
+25777,
+25790,
+25804,
+25817,
+25830,
+25844,
+25857,
+25870,
+25883,
+25897,
+25910,
+25923,
+25936,
+25949,
+25962,
+25975,
+25988,
+26001,
+26013,
+26026,
+26039,
+26052,
+26064,
+26077,
+26090,
+26102,
+26115,
+26127,
+26140,
+26152,
+26165,
+26177,
+26189,
+26202,
+26214,
+26226,
+26238,
+26251,
+26263,
+26275,
+26287,
+26299,
+26311,
+26323,
+26335,
+26347,
+26359,
+26370,
+26382,
+26394,
+26406,
+26417,
+26429,
+26441,
+26452,
+26464,
+26476,
+26487,
+26499,
+26510,
+26522,
+26533,
+26544,
+26556,
+26567,
+26578,
+26590,
+26601,
+26612,
+26623,
+26634,
+26646,
+26657,
+26668,
+26679,
+26690,
+26701,
+26712,
+26723,
+26734,
+26745,
+26755,
+26766,
+26777,
+26788,
+26799,
+26809,
+26820,
+26831,
+26841,
+26852,
+26863,
+26873,
+26884,
+26894,
+26905,
+26915,
+26926,
+26936,
+26946,
+26957,
+26967,
+26978,
+26988,
+26998,
+27008,
+27019,
+27029,
+27039,
+27049,
+27059,
+27069,
+27080,
+27090,
+27100,
+27110,
+27120,
+27130,
+27140,
+27150,
+27160,
+27169,
+27179,
+27189,
+27199,
+27209,
+27219,
+27228,
+27238,
+27248,
+27257,
+27267,
+27277,
+27286,
+27296,
+27306,
+27315,
+27325,
+27334,
+27344,
+27353,
+27363,
+27372,
+27382,
+27391,
+27400,
+27410,
+27419,
+27429,
+27438,
+27447,
+27456,
+27466,
+27475,
+27484,
+27493,
+27502,
+27512,
+27521,
+27530,
+27539,
+27548,
+27557,
+27566,
+27575,
+27584,
+27593,
+27602,
+27611,
+27620,
+27629,
+27638,
+27647,
+27656,
+27665,
+27673,
+27682,
+27691,
+27700,
+27709,
+27717,
+27726,
+27735,
+27743,
+27752,
+27761,
+27769,
+27778,
+27787,
+27795,
+27804,
+27812,
+27821,
+27829,
+27838,
+27846,
+27855,
+27863,
+27872,
+27880,
+27889,
+27897,
+27905,
+27914,
+27922,
+27931,
+27939,
+27947,
+27955,
+27964,
+27972,
+27980,
+27988,
+27997,
+28005,
+28013,
+28021,
+28029,
+28037,
+28046,
+28054,
+28062,
+28070,
+28078,
+28086,
+28094,
+28102,
+28110,
+28118,
+28126,
+28134,
+28142,
+28150,
+28158,
+28166,
+28174,
+28181,
+28189,
+28197,
+28205,
+28213,
+28221,
+28228,
+28236,
+28244,
+28252,
+28259,
+28267,
+28275,
+28283,
+28290,
+28298,
+28306,
+28313,
+28321,
+28329,
+28336,
+28344,
+28351,
+28359,
+28366,
+28374,
+28382,
+28389,
+28397,
+28404,
+28412,
+28419,
+28426,
+28434,
+28441,
+28449,
+28456,
+28464,
+28471,
+28478,
+28486,
+28493,
+28500,
+28508,
+28515,
+28522,
+28530,
+28537,
+28544,
+28551,
+28559,
+28566,
+28573,
+28580,
+28587,
+28595,
+28602,
+28609,
+28616,
+28623,
+28630,
+28637,
+28645,
+28652,
+28659,
+28666,
+28673,
+28680,
+28687,
+28694,
+28701,
+28708,
+28715,
+28722,
+28729,
+28736,
+28743,
+28750,
+28757,
+28763,
+28770,
+28777,
+28784,
+28791,
+28798,
+28805,
+28812,
+28818,
+28825,
+28832,
+28839,
+28846,
+28852,
+28859,
+28866,
+28873,
+28879,
+28886,
+28893,
+28900,
+28906,
+28913,
+28920,
+28926,
+28933,
+28940,
+28946,
+28953,
+28959,
+28966,
+28973,
+28979,
+28986,
+28992,
+28999,
+29005,
+29012,
+29018,
+29025,
+29031,
+29038,
+29044,
+29051,
+29057,
+29064,
+29070,
+29077,
+29083,
+29090,
+29096,
+29102,
+29109,
+29115,
+29122,
+29128,
+29134,
+29141,
+29147,
+29153,
+29160,
+29166,
+29172,
+29179,
+29185,
+29191,
+29197,
+29204,
+29210,
+29216,
+29222,
+29229,
+29235,
+29241,
+29247,
+29253,
+29260,
+29266,
+29272,
+29278,
+29284,
+29290,
+29296,
+29303,
+29309,
+29315,
+29321,
+29327,
+29333,
+29339,
+29345,
+29351,
+29357,
+29363,
+29369,
+29375,
+29381,
+29387,
+29393,
+29399,
+29405,
+29411,
+29417,
+29423,
+29429,
+29435,
+29441,
+29447,
+29453,
+29459,
+29465,
+29471,
+29477,
+29482,
+29488,
+29494,
+29500,
+29506,
+29512,
+29518,
+29523,
+29529,
+29535,
+29541,
+29547,
+29552,
+29558,
+29564,
+29570,
+29575,
+29581,
+29587,
+29593,
+29598,
+29604,
+29610,
+29616,
+29621,
+29627,
+29633,
+29638,
+29644,
+29650,
+29655,
+29661,
+29667,
+29672,
+29678,
+29683,
+29689,
+29695,
+29700,
+29706,
+29711,
+29717,
+29723,
+29728,
+29734,
+29739,
+29745,
+29750,
+29756,
+29761,
+29767,
+29772,
+29778,
+29783,
+29789,
+29794,
+29800,
+29805,
+29811,
+29816,
+29822,
+29827,
+29833,
+29838,
+29843,
+29849,
+29854,
+29860,
+29865,
+29870,
+29876,
+29881,
+29886,
+29892,
+29897,
+29903,
+29908,
+29913,
+29919,
+29924,
+29929,
+29935,
+29940,
+29945,
+29950,
+29956,
+29961,
+29966,
+29972,
+29977,
+29982,
+29987,
+29993,
+29998,
+30003,
+30008,
+30013,
+30019,
+30024,
+30029,
+30034,
+30039,
+30045,
+30050,
+30055,
+30060,
+30065,
+30070,
+30076,
+30081,
+30086,
+30091,
+30096,
+30101,
+30106,
+30111,
+30116,
+30122,
+30127,
+30132,
+30137,
+30142,
+30147,
+30152,
+30157,
+30162,
+30167,
+30172,
+30177,
+30182,
+30187,
+30192,
+30197,
+30202,
+30207,
+30212,
+30217,
+30222,
+30227,
+30232,
+30237,
+30242,
+30247,
+30252,
+30257,
+30262,
+30267,
+30272,
+30277,
+30281,
+30286,
+30291,
+30296,
+30301,
+30306,
+30311,
+30316,
+30321,
+30325,
+30330,
+30335,
+30340,
+30345,
+30350,
+30355,
+30359,
+30364,
+30369,
+30374,
+30379,
+30383,
+30388,
+30393,
+30398,
+30403,
+30407,
+30412,
+30417,
+30422,
+30426,
+30431,
+30436,
+30441,
+30445,
+30450,
+30455,
+30459,
+30464,
+30469,
+30474,
+30478,
+30483,
+30488,
+30492,
+30497,
+30502,
+30506,
+30511,
+30516,
+30520,
+30525,
+30530,
+30534,
+30539,
+30544,
+30548,
+30553,
+30557,
+30562,
+30567,
+30571,
+30576,
+30580,
+30585,
+30590,
+30594,
+30599,
+30603,
+30608,
+30612,
+30617,
+30622,
+30626,
+30631,
+30635,
+30640,
+30644,
+30649,
+30653,
+30658,
+30662,
+30667,
+30671,
+30676,
+30680,
+30685,
+30689,
+30694,
+30698,
+30703,
+30707,
+30712,
+30716,
+30720,
+30725,
+30729,
+30734,
+30738,
+30743,
+30747,
+30752,
+30756,
+30760,
+30765,
+30769,
+30774,
+30778,
+30782,
+30787,
+30791,
+30795,
+30800,
+30804,
+30809,
+30813,
+30817,
+30822,
+30826,
+30830,
+30835,
+30839,
+30843,
+30848,
+30852,
+30856,
+30861,
+30865,
+30869,
+30873,
+30878,
+30882,
+30886,
+30891,
+30895,
+30899,
+30903,
+30908,
+30912,
+30916,
+30921,
+30925,
+30929,
+30933,
+30937,
+30942,
+30946,
+30950,
+30954,
+30959,
+30963,
+30967,
+30971,
+30975,
+30980,
+30984,
+30988,
+30992,
+30996,
+31001,
+31005,
+31009,
+31013,
+31017,
+31021,
+31026,
+31030,
+31034,
+31038,
+31042,
+31046,
+31050,
+31055,
+31059,
+31063,
+31067,
+31071,
+31075,
+31079,
+31083,
+31087,
+31091,
+31096,
+31100,
+31104,
+31108,
+31112,
+31116,
+31120,
+31124,
+31128,
+31132,
+31136,
+31140,
+31144,
+31148,
+31152,
+31156,
+31161,
+31165,
+31169,
+31173,
+31177,
+31181,
+31185,
+31189,
+31193,
+31197,
+31201,
+31205,
+31209,
+31213,
+31217,
+31221,
+31224,
+31228,
+31232,
+31236,
+31240,
+31244,
+31248,
+31252,
+31256,
+31260,
+31264,
+31268,
+31272,
+31276,
+31280,
+31284,
+31288,
+31291,
+31295,
+31299,
+31303,
+31307,
+31311,
+31315,
+31319,
+31323,
+31327,
+31330,
+31334,
+31338,
+31342,
+31346,
+31350,
+31354,
+31357,
+31361,
+31365,
+31369,
+31373,
+31377,
+31381,
+31384,
+31388,
+31392,
+31396,
+31400,
+31403,
+31407,
+31411,
+31415,
+31419,
+31423,
+31426,
+31430,
+31434,
+31438,
+31441,
+31445,
+31449,
+31453,
+31457,
+31460,
+31464,
+31468,
+31472,
+31475,
+31479,
+31483,
+31487,
+31490,
+31494,
+31498,
+31502,
+31505,
+31509,
+31513,
+31516,
+31520,
+31524,
+31528,
+31531,
+31535,
+31539,
+31542,
+31546,
+31550,
+31553,
+31557,
+31561,
+31565,
+31568,
+31572,
+31576,
+31579,
+31583,
+31587,
+31590,
+31594,
+31598,
+31601,
+31605,
+31608,
+31612,
+31616,
+31619,
+31623,
+31627,
+31630,
+31634,
+31638,
+31641,
+31645,
+31648,
+31652,
+31656,
+31659,
+31663,
+31666,
+31670,
+31674,
+31677,
+31681,
+31684,
+31688,
+31691,
+31695,
+31699,
+31702,
+31706,
+31709,
+31713,
+31716,
+31720,
+31724,
+31727,
+31731,
+31734,
+31738,
+31741,
+31745,
+31748,
+31752,
+31755,
+31759,
+31762,
+31766,
+31769,
+31773,
+31776,
+31780,
+31783,
+31787,
+31790,
+31794,
+31797,
+31801,
+31804,
+31808,
+31811,
+31815,
+31818,
+31822,
+31825,
+31829,
+31832,
+31836,
+31839,
+31843,
+31846,
+31849,
+31853,
+31856,
+31860,
+31863,
+31867,
+31870,
+31874,
+31877,
+31880,
+31884,
+31887,
+31891,
+31894,
+31898,
+31901,
+31904,
+31908,
+31911,
+31915,
+31918,
+31921,
+31925,
+31928,
+31932,
+31935,
+31938,
+31942,
+31945,
+31948,
+31952,
+31955,
+31959,
+31962,
+31965,
+31969,
+31972,
+31975,
+31979,
+31982,
+31985,
+31989,
+31992,
+31995,
+31999,
+32002,
+32005,
+32009,
+32012,
+32015,
+32019,
+32022,
+32025,
+32029,
+32032,
+32035,
+32039,
+32042,
+32045,
+32049,
+32052,
+32055,
+32058,
+32062,
+32065,
+32068,
+32072,
+32075,
+32078,
+32081,
+32085,
+32088,
+32091,
+32094,
+32098,
+32101,
+32104,
+32108,
+32111,
+32114,
+32117,
+32121,
+32124,
+32127,
+32130,
+32133,
+32137,
+32140,
+32143,
+32146,
+32150,
+32153,
+32156,
+32159,
+32163,
+32166,
+32169,
+32172,
+32175,
+32179,
+32182,
+32185,
+32188,
+32191,
+32195,
+32198,
+32201,
+32204,
+32207,
+32210,
+32214,
+32217,
+32220,
+32223,
+32226,
+32230,
+32233,
+32236,
+32239,
+32242,
+32245,
+32249,
+32252,
+32255,
+32258,
+32261,
+32264,
+32267,
+32271,
+32274,
+32277,
+32280,
+32283,
+32286,
+32289,
+32292,
+32296,
+32299,
+32302,
+32305,
+32308,
+32311,
+32314,
+32317,
+32320,
+32324,
+32327,
+32330,
+32333,
+32336,
+32339,
+32342,
+32345,
+32348,
+32351,
+32354,
+32358,
+32361,
+32364,
+32367,
+32370,
+32373,
+32376,
+32379,
+32382,
+32385,
+32388,
+32391,
+32394,
+32397,
+32400,
+32403,
+32407,
+32410,
+32413,
+32416,
+32419,
+32422,
+32425,
+32428,
+32431,
+32434,
+32437,
+32440,
+32443,
+32446,
+32449,
+32452,
+32455,
+32458,
+32461,
+32464,
+32467,
+32470,
+32473,
+32476,
+32479,
+32482,
+32485,
+32488,
+32491,
+32494,
+32497,
+32500,
+32503,
+32506,
+32509,
+32512,
+32515,
+32518,
+32521,
+32524,
+32527,
+32530,
+32533,
+32536,
+32538,
+32541,
+32544,
+32547,
+32550,
+32553,
+32556,
+32559,
+32562,
+32565,
+32568,
+32571,
+32574,
+32577,
+32580,
+32583,
+32586,
+32588,
+32591,
+32594,
+32597,
+32600,
+32603,
+32606,
+32609,
+32612,
+32615,
+32618,
+32620,
+32623,
+32626,
+32629,
+32632,
+32635,
+32638,
+32641,
+32644,
+32646,
+32649,
+32652,
+32655,
+32658,
+32661,
+32664,
+32667,
+32669,
+32672,
+32675,
+32678,
+32681,
+32684,
+32687,
+32690,
+32692,
+32695,
+32698,
+32701,
+32704,
+32707,
+32709,
+32712,
+32715,
+32718,
+32721,
+32724,
+32727,
+32729,
+32732,
+32735,
+32738,
+32741,
+32743,
+32746,
+32749,
+32752,
+32755,
+32758,
+32760,
+32763,
+32766,
+32769,
+32772,
+32774,
+32777,
+32780,
+32783,
+32786,
+32788,
+32791,
+32794,
+32797,
+32800,
+32802,
+32805,
+32808,
+32811,
+32813,
+32816,
+32819,
+32822,
+32825,
+32827,
+32830,
+32833,
+32836,
+32838,
+32841,
+32844,
+32847,
+32849,
+32852,
+32855,
+32858,
+32860,
+32863,
+32866,
+32869,
+32871,
+32874,
+32877,
+32880,
+32882,
+32885,
+32888,
+32891,
+32893,
+32896,
+32899,
+32901,
+32904,
+32907,
+32910,
+32912,
+32915,
+32918,
+32921,
+32923,
+32926,
+32929,
+32931,
+32934,
+32937,
+32939,
+32942,
+32945,
+32948,
+32950,
+32953,
+32956,
+32958,
+32961,
+32964,
+32966,
+32969,
+32972,
+32974,
+32977,
+32980,
+32982,
+32985,
+32988,
+32990,
+32993,
+32996,
+32998,
+33001,
+33004,
+33006,
+33009,
+33012,
+33014,
+33017,
+33020,
+33022,
+33025,
+33028,
+33030,
+33033,
+33036,
+33038,
+33041,
+33044,
+33046,
+33049,
+33051,
+33054,
+33057,
+33059,
+33062,
+33065,
+33067,
+33070,
+33072,
+33075,
+33078,
+33080,
+33083,
+33086,
+33088,
+33091,
+33093,
+33096,
+33099,
+33101,
+33104,
+33106,
+33109,
+33112,
+33114,
+33117,
+33119,
+33122,
+33125,
+33127,
+33130,
+33132,
+33135,
+33137,
+33140,
+33143,
+33145,
+33148,
+33150,
+33153,
+33156,
+33158,
+33161,
+33163,
+33166,
+33168,
+33171,
+33173,
+33176,
+33179,
+33181,
+33184,
+33186,
+33189,
+33191,
+33194,
+33196,
+33199,
+33202,
+33204,
+33207,
+33209,
+33212,
+33214,
+33217,
+33219,
+33222,
+33224,
+33227,
+33229,
+33232,
+33235,
+33237,
+33240,
+33242,
+33245,
+33247,
+33250,
+33252,
+33255,
+33257,
+33260,
+33262,
+33265,
+33267,
+33270,
+33272,
+33275,
+33277,
+33280,
+33282,
+33285,
+33287,
+33290,
+33292,
+33295,
+33297,
+33300,
+33302,
+33305,
+33307,
+33310,
+33312,
+33315,
+33317,
+33320,
+33322,
+33325,
+33327,
+33330,
+33332,
+33334,
+33337,
+33339,
+33342,
+33344,
+33347,
+33349,
+33352,
+33354,
+33357,
+33359,
+33362,
+33364,
+33366,
+33369,
+33371,
+33374,
+33376,
+33379,
+33381,
+33384,
+33386,
+33389,
+33391,
+33393,
+33396,
+33398,
+33401,
+33403,
+33406,
+33408,
+33410,
+33413,
+33415,
+33418,
+33420,
+33423,
+33425,
+33427,
+33430,
+33432,
+33435,
+33437,
+33439,
+33442,
+33444,
+33447,
+33449,
+33452,
+33454,
+33456,
+33459,
+33461,
+33464,
+33466,
+33468,
+33471,
+33473,
+33476,
+33478,
+33480,
+33483,
+33485,
+33487,
+33490,
+33492,
+33495,
+33497,
+33499,
+33502,
+33504,
+33507,
+33509,
+33511,
+33514,
+33516,
+33518,
+33521,
+33523,
+33526,
+33528,
+33530,
+33533,
+33535,
+33537,
+33540,
+33542,
+33544,
+33547,
+33549,
+33551,
+33554,
+33556,
+33559,
+33561,
+33563,
+33566,
+33568,
+33570,
+33573,
+33575,
+33577,
+33580,
+33582,
+33584,
+33587,
+33589,
+33591,
+33594,
+33596,
+33598,
+33601,
+33603,
+33605,
+33608,
+33610,
+33612,
+33615,
+33617,
+33619,
+33622,
+33624,
+33626,
+33628,
+33631,
+33633,
+33635,
+33638,
+33640,
+33642,
+33645,
+33647,
+33649,
+33652,
+33654,
+33656,
+33658,
+33661,
+33663,
+33665,
+33668,
+33670,
+33672,
+33674,
+33677,
+33679,
+33681,
+33684,
+33686,
+33688,
+33690,
+33693,
+33695,
+33697,
+33700,
+33702,
+33704,
+33706,
+33709,
+33711,
+33713,
+33715,
+33718,
+33720,
+33722,
+33725,
+33727,
+33729,
+33731,
+33734,
+33736,
+33738,
+33740,
+33743,
+33745,
+33747,
+33749,
+33752,
+33754,
+33756,
+33758,
+33761,
+33763,
+33765,
+33767,
+33770,
+33772,
+33774,
+33776,
+33779,
+33781,
+33783,
+33785,
+33787,
+33790,
+33792,
+33794,
+33796,
+33799,
+33801,
+33803,
+33805,
+33807,
+33810,
+33812,
+33814,
+33816,
+33819,
+33821,
+33823,
+33825,
+33827,
+33830,
+33832,
+33834,
+33836,
+33838,
+33841,
+33843,
+33845,
+33847,
+33849,
+33852,
+33854,
+33856,
+33858,
+33860,
+33863,
+33865,
+33867,
+33869,
+33871,
+33874,
+33876,
+33878,
+33880,
+33882,
+33885,
+33887,
+33889,
+33891,
+33893,
+33895,
+33898,
+33900,
+33902,
+33904,
+33906,
+33909,
+33911,
+33913,
+33915,
+33917,
+33919,
+33922,
+33924,
+33926,
+33928,
+33930,
+33932,
+33935,
+33937,
+33939,
+33941,
+33943,
+33945,
+33947,
+33950,
+33952,
+33954,
+33956,
+33958,
+33960,
+33962,
+33965,
+33967,
+33969,
+33971,
+33973,
+33975,
+33977,
+33980,
+33982,
+33984,
+33986,
+33988,
+33990,
+33992,
+33995,
+33997,
+33999,
+34001,
+34003,
+34005,
+34007,
+34009,
+34012,
+34014,
+34016,
+34018,
+34020,
+34022,
+34024,
+34026,
+34028,
+34031,
+34033,
+34035,
+34037,
+34039,
+34041,
+34043,
+34045,
+34047,
+34050,
+34052,
+34054,
+34056,
+34058,
+34060,
+34062,
+34064,
+34066,
+34068,
+34071,
+34073,
+34075,
+34077,
+34079,
+34081,
+34083,
+34085,
+34087,
+34089,
+34091,
+34094,
+34096,
+34098,
+34100,
+34102,
+34104,
+34106,
+34108,
+34110,
+34112,
+34114,
+34116,
+34118,
+34121,
+34123,
+34125,
+34127,
+34129,
+34131,
+34133,
+34135,
+34137,
+34139,
+34141,
+34143,
+34145,
+34147,
+34149,
+34151,
+34154,
+34156,
+34158,
+34160,
+34162,
+34164,
+34166,
+34168,
+34170,
+34172,
+34174,
+34176,
+34178,
+34180,
+34182,
+34184,
+34186,
+34188,
+34190,
+34192,
+34194,
+34196,
+34199,
+34201,
+34203,
+34205,
+34207,
+34209,
+34211,
+34213,
+34215,
+34217,
+34219,
+34221,
+34223,
+34225,
+34227,
+34229,
+34231,
+34233,
+34235,
+34237,
+34239,
+34241,
+34243,
+34245,
+34247,
+34249,
+34251,
+34253,
+34255,
+34257,
+34259,
+34261,
+34263,
+34265,
+34267,
+34269,
+34271,
+34273,
+34275,
+34277,
+34279,
+34281,
+34283,
+34285,
+34287,
+34289,
+34291,
+34293,
+34295,
+34297,
+34299,
+34301,
+34303,
+34305,
+34307,
+34309,
+34311,
+34313,
+34315,
+34317,
+34319,
+34321,
+34323,
+34325,
+34327,
+34329,
+34331,
+34333,
+34335,
+34337,
+34339,
+34341,
+34343,
+34345,
+34347,
+34349,
+34351,
+34352,
+34354,
+34356,
+34358,
+34360,
+34362,
+34364,
+34366,
+34368,
+34370,
+34372,
+34374,
+34376,
+34378,
+34380,
+34382,
+34384,
+34386,
+34388,
+34390,
+34392,
+34394,
+34395,
+34397,
+34399,
+34401,
+34403,
+34405,
+34407,
+34409,
+34411,
+34413,
+34415,
+34417,
+34419,
+34421,
+34423,
+34425,
+34427,
+34428,
+34430,
+34432,
+34434,
+34436,
+34438,
+34440,
+34442,
+34444,
+34446,
+34448,
+34450,
+34452,
+34454,
+34455,
+34457,
+34459,
+34461,
+34463,
+34465,
+34467,
+34469,
+34471,
+34473,
+34475,
+34476,
+34478,
+34480,
+34482,
+34484,
+34486,
+34488,
+34490,
+34492,
+34494,
+34496,
+34497,
+34499,
+34501,
+34503,
+34505,
+34507,
+34509,
+34511,
+34513,
+34515,
+34516,
+34518,
+34520,
+34522,
+34524,
+34526,
+34528,
+34530,
+34532,
+34533,
+34535,
+34537,
+34539,
+34541,
+34543,
+34545,
+34547,
+34549,
+34550,
+34552,
+34554,
+34556,
+34558,
+34560,
+34562,
+34564,
+34565,
+34567,
+34569,
+34571,
+34573,
+34575,
+34577,
+34579,
+34580,
+34582,
+34584,
+34586,
+34588,
+34590,
+34592,
+34593,
+34595,
+34597,
+34599,
+34601,
+34603,
+34605,
+34606,
+34608,
+34610,
+34612,
+34614,
+34616,
+34618,
+34619,
+34621,
+34623,
+34625,
+34627,
+34629,
+34631,
+34632,
+34634,
+34636,
+34638,
+34640,
+34642,
+34643,
+34645,
+34647,
+34649,
+34651,
+34653,
+34654,
+34656,
+34658,
+34660,
+34662,
+34664,
+34665,
+34667,
+34669,
+34671,
+34673,
+34675,
+34676,
+34678,
+34680,
+34682,
+34684,
+34686,
+34687,
+34689,
+34691,
+34693,
+34695,
+34696,
+34698,
+34700,
+34702,
+34704,
+34706,
+34707,
+34709,
+34711,
+34713,
+34715,
+34716,
+34718,
+34720,
+34722,
+34724,
+34725,
+34727,
+34729,
+34731,
+34733,
+34735,
+34736,
+34738,
+34740,
+34742,
+34744,
+34745,
+34747,
+34749,
+34751,
+34753,
+34754,
+34756,
+34758,
+34760,
+34761,
+34763,
+34765,
+34767,
+34769,
+34770,
+34772,
+34774,
+34776,
+34778,
+34779,
+34781,
+34783,
+34785,
+34787,
+34788,
+34790,
+34792,
+34794,
+34795,
+34797,
+34799,
+34801,
+34803,
+34804,
+34806,
+34808,
+34810,
+34811,
+34813,
+34815,
+34817,
+34818,
+34820,
+34822,
+34824,
+34826,
+34827,
+34829,
+34831,
+34833,
+34834,
+34836,
+34838,
+34840,
+34841,
+34843,
+34845,
+34847,
+34848,
+34850,
+34852,
+34854,
+34855,
+34857,
+34859,
+34861,
+34862,
+34864,
+34866,
+34868,
+34869,
+34871,
+34873,
+34875,
+34876,
+34878,
+34880,
+34882,
+34883,
+34885,
+34887,
+34889,
+34890,
+34892,
+34894,
+34896,
+34897,
+34899,
+34901,
+34903,
+34904,
+34906,
+34908,
+34910,
+34911,
+34913,
+34915,
+34916,
+34918,
+34920,
+34922,
+34923,
+34925,
+34927,
+34929,
+34930,
+34932,
+34934,
+34935,
+34937,
+34939,
+34941,
+34942,
+34944,
+34946,
+34948,
+34949,
+34951,
+34953,
+34954,
+34956,
+34958,
+34960,
+34961,
+34963,
+34965,
+34966,
+34968,
+34970,
+34972,
+34973,
+34975,
+34977,
+34978,
+34980,
+34982,
+34983,
+34985,
+34987,
+34989,
+34990,
+34992,
+34994,
+34995,
+34997,
+34999,
+35001,
+35002,
+35004,
+35006,
+35007,
+35009,
+35011,
+35012,
+35014,
+35016,
+35017,
+35019,
+35021,
+35023,
+35024,
+35026,
+35028,
+35029,
+35031,
+35033,
+35034,
+35036,
+35038,
+35039,
+35041,
+35043,
+35044,
+35046,
+35048,
+35050,
+35051,
+35053,
+35055,
+35056,
+35058,
+35060,
+35061,
+35063,
+35065,
+35066,
+35068,
+35070,
+35071,
+35073,
+35075,
+35076,
+35078,
+35080,
+35081,
+35083,
+35085,
+35086,
+35088,
+35090,
+35091,
+35093,
+35095,
+35096,
+35098,
+35100,
+35101,
+35103,
+35105,
+35106,
+35108,
+35110,
+35111,
+35113,
+35115,
+35116,
+35118,
+35120,
+35121,
+35123,
+35124,
+35126,
+35128,
+35129,
+35131,
+35133,
+35134,
+35136,
+35138,
+35139,
+35141,
+35143,
+35144,
+35146,
+35148,
+35149,
+35151,
+35152,
+35154,
+35156,
+35157,
+35159,
+35161,
+35162,
+35164,
+35166,
+35167,
+35169,
+35170,
+35172,
+35174,
+35175,
+35177,
+35179,
+35180,
+35182,
+35184,
+35185,
+35187,
+35188,
+35190,
+35192,
+35193,
+35195,
+35197,
+35198,
+35200,
+35201,
+35203,
+35205,
+35206,
+35208,
+35210,
+35211,
+35213,
+35214,
+35216,
+35218,
+35219,
+35221,
+35222,
+35224,
+35226,
+35227,
+35229,
+35231,
+35232,
+35234,
+35235,
+35237,
+35239,
+35240,
+35242,
+35243,
+35245,
+35247,
+35248,
+35250,
+35251,
+35253,
+35255,
+35256,
+35258,
+35260,
+35261,
+35263,
+35264,
+35266,
+35268,
+35269,
+35271,
+35272,
+35274,
+35276,
+35277,
+35279,
+35280,
+35282,
+35283,
+35285,
+35287,
+35288,
+35290,
+35291,
+35293,
+35295,
+35296,
+35298,
+35299,
+35301,
+35303,
+35304,
+35306,
+35307,
+35309,
+35311,
+35312,
+35314,
+35315,
+35317,
+35318,
+35320,
+35322,
+35323,
+35325,
+35326,
+35328,
+35329,
+35331,
+35333,
+35334,
+35336,
+35337,
+35339,
+35341,
+35342,
+35344,
+35345,
+35347,
+35348,
+35350,
+35352,
+35353,
+35355,
+35356,
+35358,
+35359,
+35361,
+35362,
+35364,
+35366,
+35367,
+35369,
+35370,
+35372,
+35373,
+35375,
+35377,
+35378,
+35380,
+35381,
+35383,
+35384,
+35386,
+35387,
+35389,
+35391,
+35392,
+35394,
+35395,
+35397,
+35398,
+35400,
+35401,
+35403,
+35405,
+35406,
+35408,
+35409,
+35411,
+35412,
+35414,
+35415,
+35417,
+35418,
+35420,
+35422,
+35423,
+35425,
+35426,
+35428,
+35429,
+35431,
+35432,
+35434,
+35435,
+35437,
+35439,
+35440,
+35442,
+35443,
+35445,
+35446,
+35448,
+35449,
+35451,
+35452,
+35454,
+35455,
+35457,
+35459,
+35460,
+35462,
+35463,
+35465,
+35466,
+35468,
+35469,
+35471,
+35472,
+35474,
+35475,
+35477,
+35478,
+35480,
+35481,
+35483,
+35484,
+35486,
+35488,
+35489,
+35491,
+35492,
+35494,
+35495,
+35497,
+35498,
+35500,
+35501,
+35503,
+35504,
+35506,
+35507,
+35509,
+35510,
+35512,
+35513,
+35515,
+35516,
+35518,
+35519,
+35521,
+35522,
+35524,
+35525,
+35527,
+35528,
+35530,
+35531,
+35533,
+35534,
+35536,
+35538,
+35539,
+35541,
+35542,
+35544,
+35545,
+35547,
+35548,
+35550,
+35551,
+35553,
+35554,
+35556,
+35557,
+35559,
+35560,
+35562,
+35563,
+35565,
+35566,
+35568,
+35569,
+35571,
+35572,
+35573,
+35575,
+35576,
+35578,
+35579,
+35581,
+35582,
+35584,
+35585,
+35587,
+35588,
+35590,
+35591,
+35593,
+35594,
+35596,
+35597,
+35599,
+35600,
+35602,
+35603,
+35605,
+35606,
+35608,
+35609,
+35611,
+35612,
+35614,
+35615,
+35617,
+35618,
+35620,
+35621,
+35622,
+35624,
+35625,
+35627,
+35628,
+35630,
+35631,
+35633,
+35634,
+35636,
+35637,
+35639,
+35640,
+35642,
+35643,
+35645,
+35646,
+35648,
+35649,
+35650,
+35652,
+35653,
+35655,
+35656,
+35658,
+35659,
+35661,
+35662,
+35664,
+35665,
+35667,
+35668,
+35670,
+35671,
+35672,
+35674,
+35675,
+35677,
+35678,
+35680,
+35681,
+35683,
+35684,
+35686,
+35687,
+35688,
+35690,
+35691,
+35693,
+35694,
+35696,
+35697,
+35699,
+35700,
+35702,
+35703,
+35704,
+35706,
+35707,
+35709,
+35710,
+35712,
+35713,
+35715,
+35716,
+35717,
+35719,
+35720,
+35722,
+35723,
+35725,
+35726,
+35728,
+35729,
+35730,
+35732,
+35733,
+35735,
+35736,
+35738,
+35739,
+35741,
+35742,
+35743,
+35745,
+35746,
+35748,
+35749,
+35751,
+35752,
+35753,
+35755,
+35756,
+35758,
+35759,
+35761,
+35762,
+35764,
+35765,
+35766,
+35768,
+35769,
+35771,
+35772,
+35774,
+35775,
+35776,
+35778,
+35779,
+35781,
+35782,
+35783,
+35785,
+35786,
+35788,
+35789,
+35791,
+35792,
+35793,
+35795,
+35796,
+35798,
+35799,
+35801,
+35802,
+35803,
+35805,
+35806,
+35808,
+35809,
+35810,
+35812,
+35813,
+35815,
+35816,
+35818,
+35819,
+35820,
+35822,
+35823,
+35825,
+35826,
+35827,
+35829,
+35830,
+35832,
+35833,
+35834,
+35836,
+35837,
+35839,
+35840,
+35842,
+35843,
+35844,
+35846,
+35847,
+35849,
+35850,
+35851,
+35853,
+35854,
+35856,
+35857,
+35858,
+35860,
+35861,
+35863,
+35864,
+35865,
+35867,
+35868,
+35870,
+35871,
+35872,
+35874,
+35875,
+35877,
+35878,
+35879,
+35881,
+35882,
+35883,
+35885,
+35886,
+35888,
+35889,
+35890,
+35892,
+35893,
+35895,
+35896,
+35897,
+35899,
+35900,
+35902,
+35903,
+35904,
+35906,
+35907,
+35908,
+35910,
+35911,
+35913,
+35914,
+35915,
+35917,
+35918,
+35920,
+35921,
+35922,
+35924,
+35925,
+35926,
+35928,
+35929,
+35931,
+35932,
+35933,
+35935,
+35936,
+35937,
+35939,
+35940,
+35942,
+35943,
+35944,
+35946,
+35947,
+35948,
+35950,
+35951,
+35953,
+35954,
+35955,
+35957,
+35958,
+35959,
+35961,
+35962,
+35964,
+35965,
+35966,
+35968,
+35969,
+35970,
+35972,
+35973,
+35974,
+35976,
+35977,
+35979,
+35980,
+35981,
+35983,
+35984,
+35985,
+35987,
+35988,
+35989,
+35991,
+35992,
+35994,
+35995,
+35996,
+35998,
+35999,
+36000,
+36002,
+36003,
+36004,
+36006,
+36007,
+36008,
+36010,
+36011,
+36013,
+36014,
+36015,
+36017,
+36018,
+36019,
+36021,
+36022,
+36023,
+36025,
+36026,
+36027,
+36029,
+36030,
+36031,
+36033,
+36034,
+36035,
+36037,
+36038,
+36040,
+36041,
+36042,
+36044,
+36045,
+36046,
+36048,
+36049,
+36050,
+36052,
+36053,
+36054,
+36056,
+36057,
+36058,
+36060,
+36061,
+36062,
+36064,
+36065,
+36066,
+36068,
+36069,
+36070,
+36072,
+36073,
+36074,
+36076,
+36077,
+36078,
+36080,
+36081,
+36082,
+36084,
+36085,
+36086,
+36088,
+36089,
+36090,
+36092,
+36093,
+36094,
+36096,
+36097,
+36098,
+36100,
+36101,
+36102,
+36104,
+36105,
+36106,
+36108,
+36109,
+36110,
+36112,
+36113,
+36114,
+36116,
+36117,
+36118,
+36119,
+36121,
+36122,
+36123,
+36125,
+36126,
+36127,
+36129,
+36130,
+36131,
+36133,
+36134,
+36135,
+36137,
+36138,
+36139,
+36141,
+36142,
+36143,
+36144,
+36146,
+36147,
+36148,
+36150,
+36151,
+36152,
+36154,
+36155,
+36156,
+36158,
+36159,
+36160,
+36162,
+36163,
+36164,
+36165,
+36167,
+36168,
+36169,
+36171,
+36172,
+36173,
+36175,
+36176,
+36177,
+36179,
+36180,
+36181,
+36182,
+36184,
+36185,
+36186,
+36188,
+36189,
+36190,
+36192,
+36193,
+36194,
+36195,
+36197,
+36198,
+36199,
+36201,
+36202,
+36203,
+36205,
+36206,
+36207,
+36208,
+36210,
+36211,
+36212,
+36214,
+36215,
+36216,
+36217,
+36219,
+36220,
+36221,
+36223,
+36224,
+36225,
+36226,
+36228,
+36229,
+36230,
+36232,
+36233,
+36234,
+36235,
+36237,
+36238,
+36239,
+36241,
+36242,
+36243,
+36244,
+36246,
+36247,
+36248,
+36250,
+36251,
+36252,
+36253,
+36255,
+36256,
+36257,
+36259,
+36260,
+36261,
+36262,
+36264,
+36265,
+36266,
+36268,
+36269,
+36270,
+36271,
+36273,
+36274,
+36275,
+36276,
+36278,
+36279,
+36280,
+36282,
+36283,
+36284,
+36285,
+36287,
+36288,
+36289,
+36290,
+36292,
+36293,
+36294,
+36296,
+36297,
+36298,
+36299,
+36301,
+36302,
+36303,
+36304,
+36306,
+36307,
+36308,
+36310,
+36311,
+36312,
+36313,
+36315,
+36316,
+36317,
+36318,
+36320,
+36321,
+36322,
+36323,
+36325,
+36326,
+36327,
+36328,
+36330,
+36331,
+36332,
+36333,
+36335,
+36336,
+36337,
+36339,
+36340,
+36341,
+36342,
+36344,
+36345,
+36346,
+36347,
+36349,
+36350,
+36351,
+36352,
+36354,
+36355,
+36356,
+36357,
+36359,
+36360,
+36361,
+36362,
+36364,
+36365,
+36366,
+36367,
+36369,
+36370,
+36371,
+36372,
+36374,
+36375,
+36376,
+36377,
+36379,
+36380,
+36381,
+36382,
+36384,
+36385,
+36386,
+36387,
+36389,
+36390,
+36391,
+36392,
+36394,
+36395,
+36396,
+36397,
+36398,
+36400,
+36401,
+36402,
+36403,
+36405,
+36406,
+36407,
+36408,
+36410,
+36411,
+36412,
+36413,
+36415,
+36416,
+36417,
+36418,
+36420,
+36421,
+36422,
+36423,
+36424,
+36426,
+36427,
+36428,
+36429,
+36431,
+36432,
+36433,
+36434,
+36436,
+36437,
+36438,
+36439,
+36440,
+36442,
+36443,
+36444,
+36445,
+36447,
+36448,
+36449,
+36450,
+36451,
+36453,
+36454,
+36455,
+36456,
+36458,
+36459,
+36460,
+36461,
+36463,
+36464,
+36465,
+36466,
+36467,
+36469,
+36470,
+36471,
+36472,
+36474,
+36475,
+36476,
+36477,
+36478,
+36480,
+36481,
+36482,
+36483,
+36484,
+36486,
+36487,
+36488,
+36489,
+36491,
+36492,
+36493,
+36494,
+36495,
+36497,
+36498,
+36499,
+36500,
+36501,
+36503,
+36504,
+36505,
+36506,
+36508,
+36509,
+36510,
+36511,
+36512,
+36514,
+36515,
+36516,
+36517,
+36518,
+36520,
+36521,
+36522,
+36523,
+36524,
+36526,
+36527,
+36528,
+36529,
+36530,
+36532,
+36533,
+36534,
+36535,
+36536,
+36538,
+36539,
+36540,
+36541,
+36542,
+36544,
+36545,
+36546,
+36547,
+36548,
+36550,
+36551,
+36552,
+36553,
+36554,
+36556,
+36557,
+36558,
+36559,
+36560,
+36562,
+36563,
+36564,
+36565,
+36566,
+36568,
+36569,
+36570,
+36571,
+36572,
+36574,
+36575,
+36576,
+36577,
+36578,
+36580,
+36581,
+36582,
+36583,
+36584,
+36586,
+36587,
+36588,
+36589,
+36590,
+36591,
+36593,
+36594,
+36595,
+36596,
+36597,
+36599,
+36600,
+36601,
+36602,
+36603,
+36605,
+36606,
+36607,
+36608,
+36609,
+36610,
+36612,
+36613,
+36614,
+36615,
+36616,
+36618,
+36619,
+36620,
+36621,
+36622,
+36623,
+36625,
+36626,
+36627,
+36628,
+36629,
+36630,
+36632,
+36633,
+36634,
+36635,
+36636,
+36638,
+36639,
+36640,
+36641,
+36642,
+36643,
+36645,
+36646,
+36647,
+36648,
+36649,
+36650,
+36652,
+36653,
+36654,
+36655,
+36656,
+36657,
+36659,
+36660,
+36661,
+36662,
+36663,
+36665,
+36666,
+36667,
+36668,
+36669,
+36670,
+36672,
+36673,
+36674,
+36675,
+36676,
+36677,
+36678,
+36680,
+36681,
+36682,
+36683,
+36684,
+36685,
+36687,
+36688,
+36689,
+36690,
+36691,
+36692,
+36694,
+36695,
+36696,
+36697,
+36698,
+36699,
+36701,
+36702,
+36703,
+36704,
+36705,
+36706,
+36708,
+36709,
+36710,
+36711,
+36712,
+36713,
+36714,
+36716,
+36717,
+36718,
+36719,
+36720,
+36721,
+36723,
+36724,
+36725,
+36726,
+36727,
+36728,
+36729,
+36731,
+36732,
+36733,
+36734,
+36735,
+36736,
+36738,
+36739,
+36740,
+36741,
+36742,
+36743,
+36744,
+36746,
+36747,
+36748,
+36749,
+36750,
+36751,
+36752,
+36754,
+36755,
+36756,
+36757,
+36758,
+36759,
+36760,
+36762,
+36763,
+36764,
+36765,
+36766,
+36767,
+36768,
+36770,
+36771,
+36772,
+36773,
+36774,
+36775,
+36776,
+36778,
+36779,
+36780,
+36781,
+36782,
+36783,
+36784,
+36786,
+36787,
+36788,
+36789,
+36790,
+36791,
+36792,
+36793,
+36795,
+36796,
+36797,
+36798,
+36799,
+36800,
+36801,
+36803,
+36804,
+36805,
+36806,
+36807,
+36808,
+36809,
+36810,
+36812,
+36813,
+36814,
+36815,
+36816,
+36817,
+36818,
+36820,
+36821,
+36822,
+36823,
+36824,
+36825,
+36826,
+36827,
+36829,
+36830,
+36831,
+36832,
+36833,
+36834,
+36835,
+36836,
+36838,
+36839,
+36840,
+36841,
+36842,
+36843,
+36844,
+36845,
+36847,
+36848,
+36849,
+36850,
+36851,
+36852,
+36853,
+36854,
+36855,
+36857,
+36858,
+36859,
+36860,
+36861,
+36862,
+36863,
+36864,
+36866,
+36867,
+36868,
+36869,
+36870,
+36871,
+36872,
+36873,
+36874,
+36876,
+36877,
+36878,
+36879,
+36880,
+36881,
+36882,
+36883,
+36884,
+36886,
+36887,
+36888,
+36889,
+36890,
+36891,
+36892,
+36893,
+36894,
+36896,
+36897,
+36898,
+36899,
+36900,
+36901,
+36902,
+36903,
+36904,
+36906,
+36907,
+36908,
+36909,
+36910,
+36911,
+36912,
+36913,
+36914,
+36916,
+36917,
+36918,
+36919,
+36920,
+36921,
+36922,
+36923,
+36924,
+36925,
+36927,
+36928,
+36929,
+36930,
+36931,
+36932,
+36933,
+36934,
+36935,
+36936,
+36938,
+36939,
+36940,
+36941,
+36942,
+36943,
+36944,
+36945,
+36946,
+36947,
+36949,
+36950,
+36951,
+36952,
+36953,
+36954,
+36955,
+36956,
+36957,
+36958,
+36959,
+36961,
+36962,
+36963,
+36964,
+36965,
+36966,
+36967,
+36968,
+36969,
+36970,
+36971,
+36973,
+36974,
+36975,
+36976,
+36977,
+36978,
+36979,
+36980,
+36981,
+36982,
+36983,
+36985,
+36986,
+36987,
+36988,
+36989,
+36990,
+36991,
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync.h
new file mode 100644
index 0000000..633341c
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync.h
@@ -0,0 +1,724 @@
+/*
+ * (C) Copyright 2011 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __QTN_MPROC_SYNC_H
+#define __QTN_MPROC_SYNC_H
+
+#ifdef __KERNEL__
+#include <linux/sched.h>
+#endif
+
+#include "mproc_sync_base.h"
+#include "semaphores.h"
+#include "shared_params.h"
+#include "topaz_tqe_cpuif.h"
+
+#ifndef __ASSEMBLY__
+
+#define QTN_MPROC_TIMEOUT	(6 * HZ)
+
+/*
+ * NOTE: functions started from "__" are internal, and must not be used by client code.
+ */
+
+/* Enum represents each CPU in system */
+typedef enum _QTN_SOC_CPU
+{
+	QTN_LHOST_SOC_CPU = (1 << 0),
+	QTN_MUC_SOC_CPU   = (1 << 1),
+	QTN_DSP_SOC_CPU   = (1 << 2)
+} QTN_SOC_CPU;
+
+#if QTN_SEM_TRACE
+#define QTN_SEM_TRACE_NUM    12
+#define QTN_SEM_TRACE_DEPTH  2
+
+#define SEM_TRACE_CPU_LHOST     0
+#define SEM_TRACE_CPU_MUC       1
+#define SEM_TRACE_CPU_DSP       2
+#define SEM_TRACE_CPU_AUC       3
+#define SEM_TRACE_CPU_NUM       4
+
+enum qtn_sem_state {
+	QTN_SEM_STARTLOCK = 0,
+	QTN_SEM_LOCKED = 1,
+	QTN_SEM_UNLOCKED = 2,
+};
+
+struct qtn_sem_trace_entry {
+	volatile uint32_t    pos;
+	volatile uint64_t    jiffies;        /* per cpu jiffies: lhost: 32b jiffies; mus: 64b jiffies; dsp: no jiffies */
+	volatile uint32_t    state;
+	volatile uint32_t    caller_file[QTN_SEM_TRACE_DEPTH];
+	volatile uint32_t    caller_line[QTN_SEM_TRACE_DEPTH];
+};
+struct qtn_sem_trace_log {
+	volatile uint32_t trace_pos[SEM_TRACE_CPU_NUM];
+	volatile uint32_t trace_idx[SEM_TRACE_CPU_NUM];
+	volatile uint32_t last_dump_pos[SEM_TRACE_CPU_NUM];
+	struct qtn_sem_trace_entry traces[SEM_TRACE_CPU_NUM][QTN_SEM_TRACE_NUM];
+};
+
+#if defined(DSP_BUILD)
+#define PER_CPU_CLK    0
+#else
+#define PER_CPU_CLK    jiffies    /* Lhost, MuC and AuC has different HZ */
+#endif
+
+#endif /* QTN_SEM_TRACE */
+
+#if defined(AUC_BUILD)
+#define PER_CPU_PRINTK                auc_os_printf
+#elif defined(MUC_BUILD)
+#define PER_CPU_PRINTK                uc_printk
+#elif !defined(DSP_BUILD)
+#define PER_CPU_PRINTK                printk
+#endif
+
+#define	HAL_REG_READ_RAW(_r)	(uint32_t)(*((volatile uint32_t *)(_r)))
+
+#if defined(CONFIG_RUBY_PCIE_TARGET)
+/*
+ * Trashed L2M_SEM_REG(0xE0000094) will lead to semaphore deadlock in Muc.
+ * We still don't know who/where/why the register been trashed.
+ * Proposal a workaround as following:
+ * Record a software copy of the L2M and M2L semaphore register, and set/clear/update
+ * the register(L2M and M2L) according to it's software copy.
+ */
+#define	CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND	(1)
+#define	QTN_SYNC_MAX_RW_CHECK_NUM					(10000)
+#endif
+
+#define QTN_ALL_SOC_CPU	(QTN_LHOST_SOC_CPU | QTN_MUC_SOC_CPU | QTN_DSP_SOC_CPU)
+#define QTN_MULTI_PROCESS_TQE_SEMA		0xf
+#define QTN_MULTI_PROCESSOR_SEMA_KEY_SHIFT	28
+
+/*
+ * This multi-processor semaphore register supports up to 7 semaphores,
+ * which is implemented by dedicated flops, not memory. Reading them is as slow or even slower
+ * than reading SRAM.
+ * Currently, the first semaphore is used for TQE and the other 6 semaphores are unused.
+ * However enabling other semaphores could introduce more wait cycles to each other.
+ * The semaphore lock process are:
+ * 1. Try to lock with write CPUID | CPUID << 24 to semaphore register.
+ * 2. Return immediately if successfully lock with passing read verify, otherwise step 3.
+ * 3. Read semaphore and wait for free to lock, then step 1 or timeout with a failure.
+ */
+RUBY_INLINE int
+_qtn_mproc_3way_tqe_sem_down(enum topaz_mproc_tqe_sem_id cpuid)
+{
+	const uint32_t  set_value = ((cpuid << QTN_MULTI_PROCESSOR_SEMA_KEY_SHIFT) | cpuid);
+	uint32_t        sem_set_cnt = 0;
+
+	do {
+		/*
+		 * The semaphore bits [3:0] can be set successfully only when it is unset or already
+		 * owned by current cpuid, otherwise the write has no effect.
+		 */
+		qtn_mproc_sync_mem_write(TOPAZ_MPROC_SEMA, set_value);
+		if ((qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA) &
+				QTN_MULTI_PROCESS_TQE_SEMA) == cpuid) {
+			return 1;
+		}
+	} while (++sem_set_cnt < TQE_SEMA_GET_MAX);
+
+	return 0;
+}
+
+/*
+ * Returns 1 mean success.
+ * Returns 0 if the processor did not hold the semaphore.
+ */
+RUBY_INLINE int
+_qtn_mproc_3way_tqe_sem_up(enum topaz_mproc_tqe_sem_id cpuid)
+{
+	uint32_t	value;
+
+	value = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
+	value &= QTN_MULTI_PROCESS_TQE_SEMA;
+	if (value != cpuid)
+		return 0;
+	/* Write current ID back to release HW semaphore */
+	qtn_mproc_sync_mem_write(TOPAZ_MPROC_SEMA, value << QTN_MULTI_PROCESSOR_SEMA_KEY_SHIFT);
+
+	return 1;
+}
+
+RUBY_INLINE void
+__qtn_mproc_refcnt_inc(volatile u_int32_t *refcnt)
+{
+	*refcnt = *refcnt + 1;
+	qtn_addr_wmb(qtn_mproc_sync_addr(refcnt));
+}
+
+RUBY_INLINE void
+__qtn_mproc_refcnt_dec(volatile u_int32_t *refcnt)
+{
+	u_int32_t tmp = *refcnt;
+	if (tmp == 0) {
+		qtn_mproc_sync_log("ref counter dec broken");
+	} else {
+		*refcnt = tmp - 1;
+		qtn_addr_wmb(qtn_mproc_sync_addr(refcnt));
+	}
+}
+
+RUBY_INLINE u_int32_t
+__qtn_mproc_sync_hw_sem1_addr(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set)
+{
+	switch (current_cpu)
+	{
+	case QTN_LHOST_SOC_CPU:
+		if (QTN_DSP_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_L2D_SEM;
+		}
+		break;
+
+	case QTN_MUC_SOC_CPU:
+		if (QTN_DSP_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_M2D_SEM;
+		}
+		break;
+
+	case QTN_DSP_SOC_CPU:
+		if (QTN_MUC_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_D2M_SEM;
+		}
+		break;
+	}
+
+	return RUBY_BAD_BUS_ADDR;
+}
+
+RUBY_INLINE u_int32_t
+__qtn_mproc_sync_hw_sem2_addr(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set)
+{
+	switch (current_cpu)
+	{
+	case QTN_LHOST_SOC_CPU:
+		if (QTN_MUC_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_L2M_SEM;
+		}
+		break;
+
+	case QTN_MUC_SOC_CPU:
+		if (QTN_LHOST_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_M2L_SEM;
+		}
+		break;
+
+	case QTN_DSP_SOC_CPU:
+		if (QTN_LHOST_SOC_CPU & peer_cpu_set) {
+			return RUBY_SYS_CTL_D2L_SEM;
+		}
+		break;
+	}
+
+	return RUBY_BAD_BUS_ADDR;
+}
+
+RUBY_INLINE u_int32_t
+__qtn_mproc_sync_hw_sem_bit(u_int32_t which_sem)
+{
+	return (1 << which_sem);
+}
+
+RUBY_INLINE int
+__qtn_mproc_sync_set_hw_sem(u_int32_t sem_addr, u_int32_t which_sem)
+{
+	int ret = 0;
+#if defined(CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND)
+	/* check counter */
+	int check_counter = 0;
+#endif
+
+	if (sem_addr == RUBY_BAD_BUS_ADDR) {
+		ret = 1;
+	} else {
+		u_int32_t sem_bit = __qtn_mproc_sync_hw_sem_bit(which_sem);
+		u_int32_t sem_val = qtn_mproc_sync_mem_read(sem_addr);
+
+#if defined(CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND)
+		while (sem_val != qtn_mproc_sync_mem_read(sem_addr)) {
+			if(++check_counter > QTN_SYNC_MAX_RW_CHECK_NUM) {
+				qtn_mproc_sync_log("__qtn_mproc_sync_set_hw_sem: read semaphore mismatch...");
+				return ret;
+			} else {
+				sem_val = qtn_mproc_sync_mem_read(sem_addr);
+			}
+		}
+#endif	/* CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND */
+		sem_val |= sem_bit;
+
+		if (qtn_mproc_sync_mem_write_wmb(sem_addr, sem_val) & sem_bit) {
+			ret = 1;
+		}
+	}
+	return ret;
+}
+
+RUBY_INLINE void
+__qtn_mproc_sync_clear_hw_sem(u_int32_t sem_addr, u_int32_t which_sem)
+{
+#if defined(CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND)
+	/* check counter */
+	int check_counter = 0;
+#endif
+
+	if (sem_addr != RUBY_BAD_BUS_ADDR) {
+		u_int32_t sem_bit = __qtn_mproc_sync_hw_sem_bit(which_sem);
+		u_int32_t sem_val = qtn_mproc_sync_mem_read(sem_addr);
+
+#if defined(CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND)
+		while (sem_val != qtn_mproc_sync_mem_read(sem_addr)) {
+			if(++check_counter > QTN_SYNC_MAX_RW_CHECK_NUM) {
+				check_counter = 0;
+				qtn_mproc_sync_log("__qtn_mproc_sync_clear_hw_sem: read semaphore mismatch...");
+			}
+			sem_val = qtn_mproc_sync_mem_read(sem_addr);
+		}
+#endif	/* CONFIG_PCIE_TARGET_SEM_TRASHED_WORKAROUND */
+		sem_val &= ~sem_bit;
+
+		qtn_mproc_sync_mem_write_wmb(sem_addr, sem_val);
+	}
+}
+
+RUBY_INLINE int
+__qtn_mproc_sync_spin_try_lock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set,
+	u_int32_t which_sem, unsigned long *flags, uint32_t *fail_sem)
+{
+	u_int32_t sem1_addr = __qtn_mproc_sync_hw_sem1_addr(current_cpu, peer_cpu_set);
+	u_int32_t sem2_addr = __qtn_mproc_sync_hw_sem2_addr(current_cpu, peer_cpu_set);
+
+	local_irq_save(*flags);
+
+	if(!__qtn_mproc_sync_set_hw_sem(sem1_addr, which_sem)) {
+		*fail_sem = sem1_addr;
+		goto unlock1;
+	}
+
+	if(!__qtn_mproc_sync_set_hw_sem(sem2_addr, which_sem)) {
+		*fail_sem = sem2_addr;
+		goto unlock2;
+	}
+
+	return 1;
+
+unlock2:
+	__qtn_mproc_sync_clear_hw_sem(sem1_addr, which_sem);
+unlock1:
+	local_irq_restore(*flags);
+	return 0;
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_spin_lock_reg_dump(void)
+{
+#if !defined(DSP_BUILD)
+	uint32_t reg;
+
+	PER_CPU_PRINTK("Dump semaphore registers:\n");
+	for (reg = RUBY_SYS_CTL_L2M_SEM; reg <= RUBY_SYS_CTL_D2M_SEM; reg += 4) {
+		PER_CPU_PRINTK("reg 0x%08x=0x%08x\n", reg, HAL_REG_READ_RAW(reg));
+	}
+#endif
+}
+
+#if QTN_SEM_TRACE
+RUBY_INLINE struct qtn_sem_trace_log *qtn_mproc_sync_get_sem_trace_log(void)
+{
+	struct shared_params *sp = qtn_mproc_sync_shared_params_get();
+	struct qtn_sem_trace_log *log;
+
+#if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
+	log = sp->sem_trace_log_bus;
+#else
+	log = sp->sem_trace_log_lhost;
+#endif
+	return log;
+}
+
+RUBY_INLINE void qtn_sem_trace_log(int state, char *caller0_file, int caller0_line, char *caller1_file, int caller1_line)
+{
+#if !defined(DSP_BUILD) || (QTN_SEM_TRACE_DSP)
+	struct qtn_sem_trace_log *log = qtn_mproc_sync_get_sem_trace_log();
+#if defined(MUC_BUILD)
+	int cpu = SEM_TRACE_CPU_MUC;
+#elif defined(DSP_BUILD)
+	int cpu = SEM_TRACE_CPU_DSP;
+#elif defined(AUC_BUILD)
+	int cpu = SEM_TRACE_CPU_AUC;
+#else
+	int cpu = SEM_TRACE_CPU_LHOST;
+#endif
+	int idx;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	idx = log->trace_idx[cpu];
+
+	log->traces[cpu][idx].pos = log->trace_pos[cpu];
+	log->traces[cpu][idx].jiffies = PER_CPU_CLK;
+	log->traces[cpu][idx].state = state;
+	log->traces[cpu][idx].caller_file[0] = (unsigned int)caller0_file;
+	log->traces[cpu][idx].caller_line[0] = caller0_line;
+	log->traces[cpu][idx].caller_file[1] = (unsigned int)caller1_file;
+	log->traces[cpu][idx].caller_line[1] = caller1_line;
+	log->trace_pos[cpu]++;
+	log->trace_idx[cpu] = (log->trace_pos[cpu]) % QTN_SEM_TRACE_NUM;
+
+	local_irq_restore(flags);
+#endif
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_spin_lock_log_dump(void)
+{
+#if !defined(DSP_BUILD)
+	struct qtn_sem_trace_log *log = qtn_mproc_sync_get_sem_trace_log();
+	int i, j, idx;
+	struct qtn_sem_trace_entry *e;
+	unsigned int file[QTN_SEM_TRACE_DEPTH];
+
+	PER_CPU_PRINTK("Dump semaphore trace log at jiffies=%u\n", (unsigned int)jiffies);
+	for (idx = 0; idx < SEM_TRACE_CPU_NUM; idx++) {
+#if !QTN_SEM_TRACE_DSP
+		if (idx == SEM_TRACE_CPU_DSP) {
+			PER_CPU_PRINTK("CPU %d semaphore trace log is not available in this build\n", idx);
+			continue;
+		}
+#endif
+		PER_CPU_PRINTK("CPU %d semaphore trace log: pos=%u, last_dump_pos=%u\n",
+				idx, log->trace_pos[idx], log->last_dump_pos[idx]);
+		for (i = 0; i < QTN_SEM_TRACE_NUM; i++) {
+			e = &log->traces[idx][i];
+			for (j = 0; j < QTN_SEM_TRACE_DEPTH; j++) {
+				file[j] = 0;
+				if (e->caller_file[j]) {
+					file[j] = e->caller_file[j];
+#if defined(MUC_BUILD)
+					if (idx != SEM_TRACE_CPU_MUC) {
+						/* have no reliable way to convert lhost/dsp/auc string addr to muc */
+						file[j] = 0;
+					}
+#elif defined(AUC_BUILD)
+					if (idx != SEM_TRACE_CPU_AUC) {
+						/* have no reliable way to convert lhost/dsp/muc string addr to auc */
+						file[j] = 0;
+					}
+#else
+					/* lhost */
+					if (idx != SEM_TRACE_CPU_LHOST) {
+						file[j] = (unsigned int)bus_to_virt(file[j]);
+					}
+#endif
+				}
+			}
+			PER_CPU_PRINTK("%d pos=%u, jiffies=%u_%u, state=%u, "
+					"caller0=0x%x %s %d, caller1=0x%x %s %d\n",
+					i, e->pos, U64_HIGH32(e->jiffies), U64_LOW32(e->jiffies),
+					e->state,
+					(unsigned int)e->caller_file[0],
+					file[0] ? (char*)file[0] : "N/A",
+					e->caller_line[0],
+					(unsigned int)e->caller_file[1],
+					file[1] ? (char*)file[1] : "N/A",
+					e->caller_line[1]
+					);
+		}
+		log->last_dump_pos[idx] = log->trace_pos[idx];
+	}
+#endif
+}
+#endif /* QTN_SEM_TRACE */
+
+RUBY_INLINE int
+__qtn_mproc_sync_spin_lock_wait(QTN_SOC_CPU current_cpu)
+{
+	int wait_shift = 0;
+	u_int32_t pm_lock_addr = qtn_mproc_sync_addr(&qtn_mproc_sync_shared_params_get()->pm_duty_lock);
+	int i;
+
+	if (unlikely(qtn_mproc_sync_mem_read(pm_lock_addr))) {
+		wait_shift = 2;
+	}
+
+	for (i = 0; i < (10 << (wait_shift + current_cpu)); ++i) {
+		qtn_pipeline_drain();
+	}
+
+	return wait_shift;
+}
+
+#if QTN_SEM_TRACE
+#define __qtn_mproc_sync_spin_lock(_cpu, _peer, _sem, _flags)  \
+	__qtn_mproc_sync_spin_lock_dbg(_cpu, _peer, _sem, _flags, __FILE__, __LINE__, caller, caller_line)
+
+RUBY_INLINE void
+__qtn_mproc_sync_spin_lock_dbg(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set,
+	u_int32_t which_sem, unsigned long *flags,
+	char *caller0_file, int caller0_line,
+	char *caller1_file, int caller1_line)
+#else
+RUBY_INLINE void
+__qtn_mproc_sync_spin_lock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set,
+	u_int32_t which_sem, unsigned long *flags)
+#endif
+{
+	/* Help to detect lockups */
+	unsigned log_counter = 0;
+	unsigned log_max_counter = 10000;
+#define LOG_MAX_COUNTER_PANIC    320000
+	int log_success = 0;
+	uint32_t fail_sem = 0;
+	int dumped =0;
+#ifdef __KERNEL__
+	unsigned long timeout_jiff;
+#endif
+
+#if QTN_SEM_TRACE
+	qtn_sem_trace_log(QTN_SEM_STARTLOCK, caller0_file, caller0_line, caller1_file, caller1_line);
+#endif
+
+	/*
+	 * We have 3 interlocked hw semaphores to be used for mutual exclusion in 3 CPU pairs.
+	 * Doesn't matter which semaphore be locked first and which second,
+	 * we can easily enters dead-lock state.
+	 * To prevent dead-locking let's rollback if locking of whole set of 3 mutexes is failed
+	 * at any stage.
+	 * Also let's add per-processor delays after failed locking, so in case of collision
+	 * it will be resolved faster.
+	 *
+	 * I think, that hw design of hw interlocked semaphores is not very lucky.
+	 * It would be much better if we have 3 registers, 1 per CPU.
+	 * And all 3 (not 2 as now) registers be interlocked.
+	 */
+	while (!__qtn_mproc_sync_spin_try_lock(current_cpu, peer_cpu_set, which_sem, flags, &fail_sem)) {
+		unsigned int i;
+		for (i = 0; i < 10 * (current_cpu + 1); ++i) {
+			qtn_pipeline_drain();
+		}
+		if(unlikely(!__qtn_mproc_sync_spin_lock_wait(current_cpu) &&
+				(++log_counter >= log_max_counter))) {
+			log_counter = 0;
+			log_max_counter = (log_max_counter << 1);
+			if (unlikely(!log_max_counter)) {
+				log_max_counter = 1;
+			}
+			qtn_mproc_sync_log("qtn_mproc_sync: waiting for semaphore ...");
+			if ((log_max_counter >= LOG_MAX_COUNTER_PANIC) && (!dumped)) {
+				/* Don't make false alert for PM/COC feature */
+#if QTN_SEM_TRACE
+				qtn_mproc_sync_spin_lock_log_dump();
+#endif
+				qtn_mproc_sync_spin_lock_reg_dump();
+#ifdef __KERNEL__
+				timeout_jiff = jiffies + QTN_MPROC_TIMEOUT;
+				while (time_before(jiffies, timeout_jiff)) {
+					schedule();
+				}
+
+				panic("Semaphore hang detected at clk %u: cpu=%x peer=%x sem=%x flags=%x fail_sem=%x\n",
+					(unsigned int)jiffies, current_cpu, peer_cpu_set, which_sem,
+					(unsigned int)*flags, fail_sem);
+#endif
+				dumped = 1;
+			}
+			log_success = 1;
+		}
+	}
+#if QTN_SEM_TRACE
+	qtn_sem_trace_log(QTN_SEM_LOCKED, caller0_file, caller0_line, caller1_file, caller1_line);
+#endif
+	if (unlikely(log_success)) {
+		qtn_mproc_sync_log("qtn_mproc_sync: wait succeeded");
+	}
+}
+
+#if QTN_SEM_TRACE
+#define __qtn_mproc_sync_spin_unlock(_cpu, _peer, _sem, _flags)  \
+	__qtn_mproc_sync_spin_unlock_dbg(_cpu, _peer, _sem, _flags, __FILE__, __LINE__, caller, caller_line)
+
+RUBY_INLINE void
+__qtn_mproc_sync_spin_unlock_dbg(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set,
+	u_int32_t which_sem, unsigned long *flags,
+	char *caller0_file, int caller0_line,
+	char *caller1_file, int caller1_line)
+#else
+RUBY_INLINE void
+__qtn_mproc_sync_spin_unlock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set,
+	u_int32_t which_sem, unsigned long *flags)
+#endif
+{
+	/* Caller must ensure that it hold spinlock. */
+
+	__qtn_mproc_sync_clear_hw_sem(
+		__qtn_mproc_sync_hw_sem2_addr(current_cpu, peer_cpu_set),
+		which_sem);
+	__qtn_mproc_sync_clear_hw_sem(
+		__qtn_mproc_sync_hw_sem1_addr(current_cpu, peer_cpu_set),
+		which_sem);
+
+#if QTN_SEM_TRACE
+	qtn_sem_trace_log(QTN_SEM_UNLOCKED, caller0_file, caller0_line, caller1_file, caller1_line);
+#endif
+
+	local_irq_restore(*flags);
+}
+
+RUBY_INLINE int
+qtn_mproc_sync_set_hw_sem(u_int32_t sem_addr, u_int32_t which_sem)
+{
+	unsigned long flags;
+	int ret;
+
+	local_irq_save(flags);
+	ret = __qtn_mproc_sync_set_hw_sem(sem_addr, which_sem);
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_clear_hw_sem(u_int32_t sem_addr, u_int32_t which_sem)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__qtn_mproc_sync_clear_hw_sem(sem_addr, which_sem);
+	local_irq_restore(flags);
+}
+
+
+/*
+ * Try lock interprocessor spinlock. Spinlock is not recoursive.
+ */
+RUBY_WEAK(qtn_mproc_sync_spin_try_lock) int
+qtn_mproc_sync_spin_try_lock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set, u_int32_t which_sem)
+{
+	unsigned long flags;
+	uint32_t fail_sem;
+	if (__qtn_mproc_sync_spin_try_lock(current_cpu, peer_cpu_set, which_sem, &flags, &fail_sem)) {
+		local_irq_restore(flags);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+  * Lock interprocessor spinlock. Spinlock is not recoursive.
+ */
+#if QTN_SEM_TRACE
+RUBY_WEAK(qtn_mproc_sync_spin_lock) void
+qtn_mproc_sync_spin_lock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set, u_int32_t which_sem, char *caller, int caller_line)
+#else
+RUBY_WEAK(qtn_mproc_sync_spin_lock) void
+qtn_mproc_sync_spin_lock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set, u_int32_t which_sem)
+#endif
+{
+	unsigned long flags;
+	__qtn_mproc_sync_spin_lock(current_cpu, peer_cpu_set, which_sem, &flags);
+	local_irq_restore(flags);
+}
+
+/*
+ * Unlock interprocessor spinlock. Spinlock is not recoursive.
+ */
+#if QTN_SEM_TRACE
+RUBY_WEAK(qtn_mproc_sync_spin_unlock) void
+qtn_mproc_sync_spin_unlock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set, u_int32_t which_sem, char *caller, int caller_line)
+#else
+RUBY_WEAK(qtn_mproc_sync_spin_unlock) void
+qtn_mproc_sync_spin_unlock(QTN_SOC_CPU current_cpu, QTN_SOC_CPU peer_cpu_set, u_int32_t which_sem)
+#endif
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	__qtn_mproc_sync_spin_unlock(current_cpu, peer_cpu_set, which_sem, &flags);
+}
+
+RUBY_INLINE volatile u_int32_t*
+qtn_mproc_sync_irq_fixup_data(u_int32_t irq_reg)
+{
+#if CONFIG_RUBY_BROKEN_IPC_IRQS
+	if (irq_reg == RUBY_SYS_CTL_M2L_INT) {
+		return &qtn_mproc_sync_shared_params_get()->m2l_irq[0];
+	}
+#endif
+	return RUBY_BAD_VIRT_ADDR;
+}
+
+RUBY_INLINE volatile u_int32_t*
+qtn_mproc_sync_irq_fixup_data_ack(u_int32_t irq_reg)
+{
+#if !defined(MUC_BUILD) && !defined(DSP_BUILD)
+	return qtn_mproc_sync_irq_fixup_data(irq_reg);
+#else
+	return RUBY_BAD_VIRT_ADDR;
+#endif
+}
+
+RUBY_INLINE volatile u_int32_t*
+qtn_mproc_sync_irq_fixup_data_trigger(u_int32_t irq_reg)
+{
+#if defined(MUC_BUILD)
+	return qtn_mproc_sync_irq_fixup_data(irq_reg);
+#else
+	return RUBY_BAD_VIRT_ADDR;
+#endif
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_irq_trigger(u_int32_t irq_reg, u_int32_t irqno)
+{
+	u_int32_t req = (1 << (irqno + 16)) | (1 << irqno);
+	qtn_mproc_sync_mem_write_wmb(irq_reg, req);
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_irq_ack_nolock(u_int32_t irq_reg, u_int32_t mask)
+{
+	u_int32_t status = qtn_mproc_sync_mem_read(irq_reg) & (mask << 16);
+	u_int32_t ret = (status >> 16);
+	if (likely(ret)) {
+		qtn_mproc_sync_mem_write_wmb(irq_reg, status & 0xFFFF0000);
+	}
+	return ret;
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_irq_ack(u_int32_t irq_reg, u_int32_t mask)
+{
+	return qtn_mproc_sync_irq_ack_nolock(irq_reg, mask);
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_irq_ack_all(u_int32_t irq_reg)
+{
+	return qtn_mproc_sync_irq_ack(irq_reg, 0xFFFFFFFF);
+}
+
+#endif // #ifndef __ASSEMBLY__
+
+#endif // #ifndef __QTN_MPROC_SYNC_H
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_base.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_base.h
new file mode 100644
index 0000000..3c5a5c9
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_base.h
@@ -0,0 +1,167 @@
+/*
+ * (C) Copyright 2011 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __QTN_MPROC_SYNC_BASE_H
+#define __QTN_MPROC_SYNC_BASE_H
+
+#ifndef __ASSEMBLY__
+
+#include "../common/ruby_mem.h"
+#include "../common/topaz_platform.h"
+
+/*
+ * Functions from this module use local_irq_save()/local_irq_restore()
+ * as synchronization primitives within CPU.
+ * This works only for uniprocessor systems.
+ * If we would ever use SMP inside our SoC, we must
+ * switch to something like spin_lock_irqsave()/spin_lock_irqrestore().
+ */
+#if defined(MUC_BUILD) || defined(DSP_BUILD)
+	#include "os/os_arch_arc.h"
+	#define local_irq_save(_flags)		do { (_flags) = _save_disable_all(); } while(0)
+	#define local_irq_restore(_flags)	do { _restore_enable((_flags)); } while(0)
+#elif defined(AUC_BUILD)
+	/* AuC now has no user-defined ISR. No need to synchronize. */
+	#define local_irq_save(_flags)		do { (void)_flags; } while(0)
+	#define local_irq_restore(_flags)	do { (void)_flags; } while(0)
+#else
+	/* Linux target. Functions defined here already. */
+#endif // #if defined(MUC_BUILD) || defined(DSP_BUILD)
+
+
+RUBY_INLINE void
+qtn_mproc_sync_log(const char *msg)
+{
+#if defined(MUC_BUILD)
+	extern int uc_printk(const char *fmt, ...);
+	uc_printk("MuC: %s\n", msg);
+#elif defined(DSP_BUILD)
+	#ifdef DSP_DEBUG
+	extern void dsp_serial_puts(const char *str);
+	dsp_serial_puts("DSP: ");
+	dsp_serial_puts(msg);
+	dsp_serial_puts("\n");
+	#endif
+#elif defined(AUC_BUILD)
+	extern int auc_os_printf(const char *fmt, ...);
+	auc_os_printf("AuC: %s\n", msg);
+#elif defined(ARCSHELL)
+#elif defined(__KERNEL__) && !defined(UBOOT_BUILD)
+	/* Linux target */
+	printk(KERN_INFO"LHOST: %s : %s : %s\n", KBUILD_MODNAME, KBUILD_BASENAME, msg);
+#else
+	printf("LHOST: %s\n", msg);
+#endif // #if defined(MUC_BUILD)
+}
+
+RUBY_INLINE void*
+qtn_mproc_sync_nocache(void *ptr)
+{
+#if defined(MUC_BUILD)
+	return muc_to_nocache(ptr);
+#else
+	return ptr;
+#endif
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_mem_write_16(u_int32_t addr, u_int16_t val)
+{
+	/*
+	 * Rely on fact that this operation is atomic,
+	 * that single bus transaction handles write.
+	 */
+	*((volatile u_int16_t*)addr) = val;
+}
+
+RUBY_INLINE u_int16_t
+qtn_mproc_sync_mem_read_16(u_int32_t addr)
+{
+	/*
+	 * Rely on fact that this operation is atomic,
+	 * that single bus transaction handles read.
+	 */
+	return *((volatile u_int16_t*)addr);
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_mem_write(u_int32_t addr, u_int32_t val)
+{
+	/*
+	 * Rely on fact that this operation is atomic,
+	 * that single bus transaction handles write.
+	 */
+	*((volatile u_int32_t*)addr) = val;
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_mem_read(u_int32_t addr)
+{
+	/*
+	 * Rely on fact that this operation is atomic,
+	 * that single bus transaction handles read.
+	 */
+	return *((volatile u_int32_t*)addr);
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_mem_write_wmb(u_int32_t addr, u_int32_t val)
+{
+	qtn_mproc_sync_mem_write(addr, val);
+	return qtn_addr_wmb(addr);
+}
+
+RUBY_INLINE u_int32_t
+qtn_mproc_sync_addr(volatile void *addr)
+{
+	return (u_int32_t)addr;
+}
+
+#if defined(MUC_BUILD) || defined(DSP_BUILD) || defined(AUC_BUILD)
+	RUBY_INLINE struct shared_params*
+	qtn_mproc_sync_shared_params_get(void)
+	{
+		return (struct shared_params*)qtn_mproc_sync_nocache((void*)
+			qtn_mproc_sync_mem_read(RUBY_SYS_CTL_SPARE));
+	}
+#else
+	extern struct shared_params *soc_shared_params;
+
+	RUBY_INLINE struct shared_params*
+	qtn_mproc_sync_shared_params_get(void)
+	{
+		return soc_shared_params;
+	}
+
+	/* Has to be used by Linux only */
+	RUBY_INLINE void
+	qtn_mproc_sync_shared_params_set(struct shared_params *params)
+	{
+		qtn_mproc_sync_mem_write_wmb(RUBY_SYS_CTL_SPARE, (u_int32_t)params);
+	}
+#endif // #if defined(MUC_BUILD) || defined(DSP_BUILD)
+
+#endif // #ifndef __ASSEMBLY__
+
+#endif // #ifndef __QTN_MPROC_SYNC_BASE_H
+
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_mutex.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_mutex.h
new file mode 100644
index 0000000..83c2473
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/mproc_sync_mutex.h
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2012 Quantenna Communications Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ *
+ * This is implementation of Peterson's algorithm for mutual exclusion for 2 processes.
+ * Implemented for little endian system only now.
+ *
+ *		//flag[] is boolean array; and turn is an integer
+ *		flag[0]   = false;
+ *		flag[1]   = false;
+ *		turn;
+ *
+ *		P0: flag[0] = true;
+ *		turn = 1;
+ *		while (flag[1] == true && turn == 1)
+ *		{
+ *			// busy wait
+ *		}
+ *		// critical section
+ *		...
+ *		// end of critical section
+ *		flag[0] = false;
+ *
+ *		P1: flag[1] = true;
+ *		turn = 0;
+ *		while (flag[0] == true && turn == 0)
+ *		{
+ *			// busy wait
+ *		}
+ *		// critical section
+ *		...
+ *		// end of critical section
+ *		flag[1] = false;
+ *
+ */
+
+#ifndef __QTN_MPROC_SYNC_MUTEX_H
+#define __QTN_MPROC_SYNC_MUTEX_H
+
+#include "mproc_sync_base.h"
+
+#ifndef __ASSEMBLY__
+
+/* Initial value must be zero. */
+typedef union __qtn_mproc_sync_mutex
+{
+	uint32_t dword;
+	struct
+	{
+		uint16_t raw_w0;
+		uint16_t raw_w1;
+	} words;
+	struct
+	{
+		uint8_t __reserved0;
+		uint8_t flag1;
+		uint8_t turn;
+		uint8_t flag0;
+	} bytes;
+} qtn_mproc_sync_mutex;
+
+RUBY_INLINE void
+qtn_mproc_sync_mutex_init(volatile qtn_mproc_sync_mutex *mutex)
+{
+	mutex->dword = 0;
+}
+
+#if !defined(__GNUC__) && defined(_ARC)
+_Inline _Asm void
+__qtn_mproc_sync_mutex_relax(int count)
+{
+	% reg count;
+	mov_s	%r12, count;
+1:
+	sub.f	%r12, %r12, 1;
+	bnz_s	1b;
+}
+RUBY_INLINE void
+qtn_mproc_sync_mutex_relax(int count)
+{
+	if (count) {
+		__qtn_mproc_sync_mutex_relax(count);
+	}
+}
+#else
+RUBY_INLINE void
+qtn_mproc_sync_mutex_relax(int count)
+{
+	int i;
+	for (i = 0; i < count; ++i) {
+		qtn_pipeline_drain();
+	}
+}
+#endif // #if !defined(__GNUC__) && defined(_ARC)
+
+RUBY_INLINE void
+qtn_mproc_sync_mutex0_lock(volatile qtn_mproc_sync_mutex *mutex, int relax_count)
+{
+	mutex->words.raw_w1 = 0x0101;
+
+	while ((mutex->dword & 0x00FFFF00) == 0x00010100) {
+		qtn_mproc_sync_mutex_relax(relax_count);
+	}
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_mutex0_unlock(volatile qtn_mproc_sync_mutex *mutex)
+{
+	mutex->bytes.flag0 = 0;
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_mutex1_lock(volatile qtn_mproc_sync_mutex *mutex, int relax_count)
+{
+	mutex->bytes.flag1 = 1;
+	mutex->bytes.turn = 0;
+
+	while (mutex->words.raw_w1 == 0x0100) {
+		qtn_mproc_sync_mutex_relax(relax_count);
+	}
+}
+
+RUBY_INLINE void
+qtn_mproc_sync_mutex1_unlock(volatile qtn_mproc_sync_mutex *mutex)
+{
+	mutex->bytes.flag1 = 0;
+}
+
+#endif // #ifndef __ASSEMBLY__
+
+#endif // #ifndef __QTN_MPROC_SYNC_MUTEX_H
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_dbg_parse b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_dbg_parse
new file mode 100755
index 0000000..98174b8
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_dbg_parse
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+$stats_header_file = 'qtn_muc_stats_print.h';
+$dbg_header_file = "muc_txrx_stats.h.raw";
+
+$in_tx_struct=0;
+$tx_stats_content = "";
+$in_rx_struct=0;
+$rx_stats_content = "";
+$rxq_num = 0;
+
+foreach my $line (`cat muc_share_def.h`) {
+	if ($line =~ /^\#define\s+QTN_FW_WMAC_RX_QNUM\s+(\d+).*$/) {
+		$rxq_num = $1;
+	}
+}
+
+if ($rxq_num == 0) {
+	die("muc_dbg_parse: fail to find macro QTN_FW_WMAC_RX_QNUM\n");
+}
+
+open(HDRFILE,"$dbg_header_file");
+while (<HDRFILE>) {
+
+	if (/\}/) {
+		if ($in_tx_struct == 1) {
+			$tx_stats_content .= "}";
+			$in_tx_struct=0;
+		}
+		if ($in_rx_struct == 1) {
+			$rx_stats_content .= "}";
+			$in_rx_struct=0;
+		}
+	}
+
+	if ($in_tx_struct) {
+		if(/(\w+)\;/){
+			$strtmp = $1;
+			$tx_stats_content .= "	\"$strtmp\", \\\n";
+		} else {
+			die("muc_dbg_parse: fail to process tx stats item \"$_\"");
+		}
+	}
+
+	if ($in_rx_struct) {
+		if (/(\w+)\;/) {
+			$strtmp = $1;
+			$rx_stats_content .= "	\"$strtmp\", \\\n";
+		} elsif (/(rxq_\w+)\[\w+\]\;/) {
+			$strtmp = $1;
+			for (my $i = 0; $i < $rxq_num; $i++) {
+				$rx_stats_content .= "	\"$strtmp"."[$i]\", \\\n";
+			}
+		} else {
+			die("muc_dbg_parse: fail to process rx stats item \"$_\"");
+		}
+	}
+
+	if (/^\s*struct\s+muc_tx_stats\s*\{/) {
+		$in_tx_struct=1;
+		$tx_stats_content .= "#define MUC_TX_STATS_NAMES_TABLE { \\\n";
+	}
+
+	if (/^\s*struct\s+muc_rx_stats\s*\{/) {
+		$in_rx_struct=1;
+		$rx_stats_content .= "#define MUC_RX_STATS_NAMES_TABLE { \\\n";
+	}
+
+}
+close(HDRFILE);
+
+unlink($stats_header_file);
+open(headfile,">>$stats_header_file");
+print headfile "/* autogenerated */\n\n";
+print headfile $tx_stats_content;
+print headfile "\n\n";
+print headfile $rx_stats_content;
+print headfile "\n";
+close(headfile);
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_phy_stats.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_phy_stats.h
new file mode 100644
index 0000000..c460727
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_phy_stats.h
@@ -0,0 +1,360 @@
+#ifndef  _MUC_PHY_STATS_H
+#define _MUC_PHY_STATS_H
+
+#include "../common/ruby_mem.h"
+#include "../common/queue.h"
+
+#define NUM_ANT 4
+#define NUM_LOG_BUFFS 0x8
+
+#define MUC_PHY_STATS_ALTERNATE		0
+#define MUC_PHY_STATS_RSSI_RCPI_ONLY	1
+#define MUC_PHY_STATS_ERROR_SUM_ONLY	2
+
+#define MUC_PHY_ERR_SUM_NOT_AVAIL	0xffffffff
+
+#define MUC_PHY_RSSI_NOT_AVAIL		(-1000)
+
+#include <qtn/muc_txrx_stats.h>
+
+/**
+ * \defgroup PHYSTATS PHY generated statistics
+ */
+/** @{ */
+
+#define QTN_STATS_MCS_SGI	0x40000000
+#define QTN_STATS_MCS_BW40	0x80000000
+
+#define QTN_PHY_STATS_MCS_PHYRATE	0xFFFF0000
+#define QTN_PHY_STATS_MCS_PHYRATE_S	16
+#define QTN_PHY_STATS_MCS_NSS	0xf000
+#define QTN_PHY_STATS_MCS_NSS_S	12
+#define QTN_PHY_STATS_MCS_BW		0xC00
+#define QTN_PHY_STATS_MCS_BW_S	10
+#define QTN_PHY_STATS_MCS_MODE		0x380
+#define QTN_PHY_STATS_MCS_MODE_S	7
+#define QTN_STATS_MCS_RATE_MASK	0x7f
+#define QTN_STATS_MCS_RATE_MASK_S 0
+
+#define QTN_PHY_STATS_MODE_11N	1
+#define QTN_PHY_STATS_MODE_11AC	2
+
+
+#define QTN_PER_NODE_STATS_POOL_SIZE	QTN_NODE_TBL_SIZE_LHOST
+
+#define EVM_TIME_MEAN_SHIFT	4
+#define EVM_TIME_MEAN_COUNT	(1 << EVM_TIME_MEAN_SHIFT)
+#define RSSI_TIME_MEAN_SHIFT	4
+#define RSSI_TIME_MEAN_COUNT	(1 << RSSI_TIME_MEAN_SHIFT)
+#define PHY_RATE_MEAN_SHIFT	4
+#define PHY_RATE_MEAN_COUNT	(1 << PHY_RATE_MEAN_SHIFT)
+
+struct qtn_node_shared_stats_tx {
+	uint32_t max_queue;
+	/*
+	 * last_mcs are used as bitmask value
+	 * bit[31:16]		rate		(Mbps)
+	 * bit[15:12]		nss		(1~4)
+	 * bit[11:10]		bw		(0 - 20; 1-40; 2-80; 3-unknow)
+	 * bit[9:7]		mode		(1-11n, 2-11ac others-unknow)
+	 * bit[6:0]		mcs		([0,76] for 11n, [0,9] [33,76] for 11ac)
+	 */
+	uint32_t last_mcs;
+	uint32_t last_tx_scale;
+	uint32_t ralg_inv_phy_rate;
+	int32_t avg_rssi_dbm;
+	uint32_t cost;
+	uint32_t pkts;
+	uint32_t txdone_failed_cum;
+	uint32_t avg_per;
+	uint32_t pkts_per_sec;
+	uint32_t avg_tx_phy_rate;
+	uint32_t acks;
+	uint32_t tx_airtime;
+	uint32_t tx_accum_airtime;
+	/*
+	 * The number of data packets transmitted through
+	 * wireless media for each traffic category(TC).
+	 */
+#define WMM_AC_NUM 4
+	uint32_t tx_sent_data_msdu[WMM_AC_NUM];
+};
+
+struct qtn_node_shared_stats_rx {
+	int32_t last_rssi_dbm[NUM_ANT + 1];
+	int32_t rssi_dbm_smoothed[NUM_ANT + 1];
+	int32_t last_rcpi_dbm[NUM_ANT + 1];
+	int32_t rcpi_dbm_smoothed[NUM_ANT + 1];
+	int32_t last_evm_dbm[NUM_ANT + 1];
+	int32_t evm_dbm_smoothed[NUM_ANT + 1];
+	int32_t last_hw_noise[NUM_ANT + 1];
+	uint32_t last_rxsym;
+	/*
+	 * last_mcs are used as bitmask value
+	 * bit[31:16]		rate		(Mbps)
+	 * bit[15:12]		nss		(1~4)
+	 * bit[11:10]		bw		(0 - 20; 1-40; 2-80; 3-unknow)
+	 * bit[9:7]		mode		(1-11n, 2-11ac others-unknow)
+	 * bit[6:0]		mcs		([0,76] for 11n, [0,9] [33,76] for 11ac)
+	 */
+	uint32_t last_mcs;
+	uint32_t pkts;
+	uint32_t pkts_cum;
+	uint32_t inv_phy_rate_smoothed;
+	uint32_t cost;
+	uint32_t rx_airtime;
+	uint32_t rx_accum_airtime;
+};
+
+/**
+ * Per node values and statistics; updated periodically
+ * with each invocation of qtn_stats_sample, based on
+ * MuC per node stats
+ */
+struct qtn_node_shared_stats {
+	/* 0 for SU, 1 for MU */
+#define STATS_MIN	0
+#define STATS_SU	STATS_MIN
+#define STATS_MU	1
+#define STATS_MAX	2
+	struct qtn_node_shared_stats_tx tx[STATS_MAX];
+	struct qtn_node_shared_stats_rx rx[STATS_MAX];
+	uint64_t beacon_tbtt;
+	uint64_t beacon_tbtt_jiffies;
+	uint64_t last_rx_jiffies;
+	uint64_t dtim_tbtt;
+	uint64_t qtn_tx_bytes;
+	uint64_t qtn_rx_bytes;
+	uint32_t tim_set;
+	uint32_t dtim_set;
+	uint16_t beacon_interval;
+	uint16_t pad;
+};
+
+/**
+ * \brief PHY receive statistics
+ *
+ * These statistics are either read directly from the PHY or are generated
+ * based on PHY inputs (eg, RX vector or other structures).
+ */
+struct qtn_rx_stats {
+	/**
+	 * The count of the number of packets the PHY has received and passed
+	 * up. This is the total of the number of singleton packets (MPDU, MMPDU, control frames),
+	 * plus the total of subframes within AMPDUs, plus the number of AMSDUs which have been
+	 * passed up from the PHY.
+	 *
+	 * \note On BBIC4, it just counts single AMPDU rather than the subframes in AMPDU.
+	 */
+	u_int32_t num_pkts;
+
+	/**
+	 * count of packets with A-MSDU flag set
+	 */
+	u_int32_t num_amsdu;
+
+	/**
+	 * The average RX gain used on the previously received packet
+	 * (MMPDU, MPDU, AMPDU or singleton AMSDU).
+	 */
+	u_int32_t avg_rxgain;
+
+	/**
+	 * The number of packets received by the PHY with invalid CRC.
+	 */
+	u_int32_t cnt_mac_crc;
+
+	/**
+	 * The number of short preamble failures reported by the PHY.
+	 */
+	u_int32_t cnt_sp_fail;
+
+	/**
+	 * The number of long preamble failures reported by the PHY.
+	 */
+	u_int32_t cnt_lp_fail;
+
+	int32_t hw_noise;
+
+	u_int32_t max_init_gain;
+
+	/**
+	 * The current temperature of the system.
+	 */
+	u_int32_t sys_temp;
+
+	/**
+	 * The mode of the last received packet.
+	 * 1 - 11n
+	 * 2 - 11ac
+	 * others - unknow
+	 */
+	u_int32_t last_rx_mode;
+
+	/**
+	 * The bandwidth of the last received packet.
+	 * 0 - 20MHZ
+	 * 1 - 40MHZ
+	 * 2 - 80MHZ
+	 * others - unknow
+	 */
+	u_int32_t last_rx_bw;
+
+	/**
+	 * The MCS index of the last received packet.
+	 */
+	u_int32_t last_rx_mcs;
+
+	/**
+	 * Debug information.
+	 */
+	u_int32_t rx_gain_fields;
+
+	/**
+	 * RSSI / RCPI / EVM for frames
+	 */
+	int32_t last_rssi_evm[NUM_ANT];
+
+	int32_t last_rssi_all;
+
+	u_int32_t last_rxsym;
+};
+
+/**
+ * \brief PHY transmit statistics
+ *
+ * These statistics are either read directly from the PHY or are generated
+ * based on PHY values.
+ */
+struct qtn_tx_stats {
+	/**
+	 * The count of the number of packets (MMPDU, MPDU, AMSDU, and one for each
+	 * subframe in an AMPDU) sent to the PHY.
+	 *
+	 * \note On BBIC4, it just counts single AMPDU rather than the subframes in AMPDU.
+	 */
+	u_int32_t num_pkts;
+
+	/**
+	 * The number of times transmitted packets were deferred due to CCA.
+	 */
+	u_int32_t num_defers;
+
+	/**
+	 * The number of times packets were timed out - spent too long inside the MAC.
+	 */
+	u_int32_t num_timeouts;
+
+	/**
+	 * The number of retries - singleton retransmissions, full AMPDU retransmissions,
+	 * or partial AMPDU retransmissions.
+	 */
+	u_int32_t num_retries;
+
+	/**
+	 * The transmit power scale index used for the last packet
+	 *
+	 * \note On BBIC4, This variable is not available.
+	 */
+	u_int32_t last_tx_scale;
+
+	/**
+	 * The mode of the last transmit packet.
+	 * 1 - 11n
+	 * 2 - 11ac
+	 * others - unknow
+	 */
+	u_int32_t last_tx_mode;
+
+	/**
+	 * The bandwidth of the last transmit packet.
+	 * 0 - 20MHZ
+	 * 1 - 40MHZ
+	 * 2 - 80MHZ
+	 */
+	u_int32_t last_tx_bw;
+
+	/**
+	 * The MCS index of the last acknowledged transmit packet.
+	 */
+	u_int32_t last_tx_mcs;
+
+	/**
+	 * Rate adaptations current best throughput rate
+	 */
+	u_int32_t rate;		/* this field must be last for stat_parser.pl */
+};
+
+/** @} */
+
+struct qtn_stats {
+	u_int32_t tstamp;
+	struct qtn_rx_stats rx_phy_stats;
+	struct qtn_rx_stats mu_rx_phy_stats;
+	struct qtn_tx_stats tx_phy_stats;
+	struct qtn_tx_stats mu_tx_phy_stats;
+};
+
+struct qtn_stats_log {
+	int curr_buff; /* Indx of the buffer with latest data */
+	struct qtn_stats stat_buffs[NUM_LOG_BUFFS];
+	struct muc_rx_stats *rx_muc_stats;
+	struct muc_rx_rates *rx_muc_rates;
+	struct muc_rx_bf_stats *rx_muc_bf_stats;
+	struct muc_tx_stats *tx_muc_stats;
+	struct qtn_rate_tx_stats_per_sec *tx_muc_rates;
+	uint32_t *muc_su_rate_stats_read;
+	uint32_t *muc_mu_rate_stats_read;
+	uint32_t *scs_cnt;
+	uint32_t pad[7]; /* Ensure the pad makes this structure a multiple of ARC cache line size */
+};
+
+/*
+ * Micro stats: provide stats in micro view along the time axis
+ * Can be used for off-channel and other debug purpose.
+ */
+#define QTN_MICRO_STATS_GRANULARITY	1	/* ms, for trace burst in traffic */
+#define QTN_MICRO_STATS_NUM		32	/* enough for max off-channel duration */
+struct qtn_micro_stats {
+	/*
+	 * tx msdu: collected in tx done. With average 1.5ms aggregation timeout, this is accurate
+	 * enough for off-channel use.
+	 */
+	uint32_t tx_msdu;
+	/*
+	 * rx msdu: collected after rx reorder and mpdu decap, and amsdu decap if existing.
+	 * - Delay in rx reorder lead to different instantaneous pkt rate from what is in the
+	 *   air in ms level granularity.
+	 * - If amsdu decap is done in lhost, bbic3 or bbic4 sdp, this value is not correct.
+	 */
+	uint32_t rx_msdu;
+};
+
+struct qtn_micro_stats_log {
+	struct qtn_micro_stats latest_stats;
+	/* snapshot */
+	uint32_t curr_idx;
+	struct qtn_micro_stats micro_stats[QTN_MICRO_STATS_NUM];
+};
+
+RUBY_INLINE int qtn_select_rssi_over_error_sums(u_int32_t timestamp, int muc_phy_stats_mode)
+{
+	int	retval = 0;
+
+	switch (muc_phy_stats_mode) {
+	case MUC_PHY_STATS_RSSI_RCPI_ONLY:
+		retval = 1;
+		break;
+	case MUC_PHY_STATS_ERROR_SUM_ONLY:
+		retval = 0;
+		break;
+	case MUC_PHY_STATS_ALTERNATE:
+	default:
+		retval = (timestamp & 0x01);
+		break;
+	}
+
+	return( retval );
+}
+
+#endif
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_share_def.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_share_def.h
new file mode 100755
index 0000000..2b4c64d
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_share_def.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014 Quantenna Communications, Inc.
+ */
+
+#ifndef _MUC_SHARE_DEF_H_
+#define _MUUC_SHARE_DEF_H_
+
+#include "../common/ruby_mem.h"
+
+#define QTN_FW_WMAC_RX_Q_MGMT		0
+#define QTN_FW_WMAC_RX_Q_CTRL		1
+#define QTN_FW_WMAC_RX_Q_DATA		2
+#define QTN_FW_WMAC_RX_QNUM		3
+#define QTN_FW_WMAC_RX_QDEEP_MGMT	9
+#define QTN_FW_WMAC_RX_QDEEP_CTRL	9
+#define QTN_FW_WMAC_RX_QDEEP_DATA	394
+#define QTN_FW_WMAC_RX_DESC_NUM	(QTN_FW_WMAC_RX_QDEEP_MGMT + \
+	QTN_FW_WMAC_RX_QDEEP_CTRL + QTN_FW_WMAC_RX_QDEEP_DATA)
+
+#endif // #ifndef _MUC_SHARE_DEF_H_
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_txrx_stats.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_txrx_stats.h
new file mode 100644
index 0000000..5e43739
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/muc_txrx_stats.h
@@ -0,0 +1,794 @@
+/*
+ * Copyright (c) 2008-2012 Quantenna Communications, Inc.
+ */
+
+/*
+ * This file contains host definitions which are common between the
+ * host driver and the microcontroller/MAC code.
+ */
+
+/**
+ * The host tx descriptor for an ethernet packet
+ */
+
+#ifndef _MUC_TXRX_STATS_H_
+#define _MUC_TXRX_STATS_H_
+
+#include <qtn/muc_share_def.h>
+
+#ifdef ENABLE_STATS
+#define MUC_UPDATE_STATS(_a, _b)	(_a += _b)
+#define MUC_SETSTAT(_a, _b)		(_a = _b)
+#else
+#define MUC_UPDATE_STATS(_a, _b)
+#define MUC_SETSTAT(_a, _b)
+#endif
+
+/**
+ * \defgroup MUCSTATS MuC generated statistics
+ */
+/** @{ */
+
+/**
+ * \brief MuC transmit statistics
+ *
+ * These statistics are generated on the MuC, mainly on the transmit datapath.
+ */
+struct muc_tx_stats {
+	/**
+	 * The number of times the software failed to enqueue a beacon to the
+	 * hardware.
+	 *
+	 * \note If this value is non-zero it could indicate a very congested
+	 * medium.
+	 */
+	u_int32_t	bcn_enq_failed;
+
+	/**
+	 * The number of times the TX status bit is set.
+	 */
+	u_int32_t	tx_status_set;
+
+	/**
+	 * The number of interrupts from the host to indicate data is ready for
+	 * transmit.
+	 *
+	 * \note This number will generally be quite low, as the LHost->MuC
+	 * data path is poll driven rather than interrupt driven.
+	 */
+	u_int32_t	host_intr;
+	u_int32_t	tx_reserved;
+	u_int32_t	tx_reserve_fail;
+	u_int32_t	txalert_mu_ndp_update;
+	u_int32_t	txalert_mu_rpt_poll;
+	u_int32_t	txalert_mu_queue_full;
+	u_int32_t	txalert_mu_queue_fail;
+	u_int32_t	sample_rate_mu;
+	u_int32_t	sample_bw_mu;
+	u_int32_t	txdone_intr;
+	u_int32_t	txalert_intr;
+	u_int32_t	txalert_tasklet;
+	u_int32_t	txalert_bcn_update;
+	u_int32_t	txalert_ndp_update;
+	u_int32_t	tx_ndp_q_occupied;
+	u_int32_t	tx_ndp_start;
+	u_int32_t	tx_pwr;
+	u_int32_t	bcn_scheme_power_save;
+	u_int32_t	bcn_scheme;
+
+	u_int32_t	fd_acquire;
+	u_int32_t	fd_release;
+	u_int32_t	fd_acq_fail;
+	u_int32_t	fd_acq_fail_frms;
+	u_int32_t	fd_acq_hal_fail;
+	u_int32_t	fd_acq_hal_fail_frms;
+	u_int32_t	ba_send;
+	u_int32_t	fd_free_nodeclean;
+	u_int32_t	tx_restrict_probe;
+	u_int32_t	tx_restrict_mode;
+	u_int32_t	tx_restrict_delay;
+	u_int32_t	tx_sample_pkts;
+	u_int32_t	tx_sample_bytes;
+	u_int32_t	tx_underflow;
+	u_int32_t	tx_hal_enqueued;
+	u_int32_t	txbf_mode;
+	u_int32_t	psel_matrix;
+	u_int32_t	sample_rate;
+	u_int32_t	sample_bw;
+	uint32_t	ra_flags;
+	u_int32_t	fd_balance;
+	uint32_t	invalid_delay;
+	uint32_t	halt_tx;
+	uint32_t	resume_tx;
+	uint32_t	rfctrl_on;
+	uint32_t	rfctrl_off;
+	uint32_t	go_offchan;
+	uint32_t	go_datachan;
+	uint32_t	defer_cc;
+	uint32_t	deferred_cc_done;
+	uint32_t	off_chan_sample;
+	uint32_t	off_chan_scan;
+	uint32_t	off_chan_cac;
+	uint32_t	cca_pri;
+	uint32_t	cca_sec;
+	uint32_t	cca_sec40;
+	uint32_t	cca_busy;
+	uint32_t	cca_fat;
+	uint32_t	cca_intf;
+	uint32_t	cca_trfc;
+	/**
+	 * These counter show the information of MU frames.
+	 */
+	uint32_t	mu_prec_snd_tx;
+	uint32_t	mu_prec_snd_wait_done;
+	uint32_t	mu_grp_sel_snd_tx;
+	uint32_t	mu_grp_sel_snd_wait_done;
+
+	uint32_t	oc_auctx_timeout;
+	uint32_t	oc_auctx_overwrite;
+	uint32_t	oc_auctx_fail;
+	uint32_t	gi_cnt;			/* times GI has been set for any node */
+	uint32_t	gi_ncidx;		/* last node to have GI set */
+	uint32_t	gi_val;			/* SGI enabled state for this node */
+	uint32_t	select_state_ncidx;	/* last node to have qn_select state set */
+	uint32_t	select_state_val;	/* PPPC state for this node */
+	uint32_t	pppc_scale_cnt;		/* times Tx gain scaling has been set for any node */
+	uint32_t	pppc_scale_ncidx;	/* last node to have Tx gain scaling set */
+	uint32_t	pppc_scale_val;		/* Tx gain scaling for this node (0 is max) */
+	uint32_t	pppc_scale_last_gput;		/* The last goodput used by PPPC */
+	uint32_t	pppc_scale_last_gput_idx;	/* The PPPC index of the last goodput value */
+	uint32_t	pppc_scale_base_cnt;		/* times Tx gain scaling base has been set for any node */
+	uint32_t	pppc_scale_base_20m;	/* Combined tx scale bases for different bf/nss cases in 20MHz */
+	uint32_t	pppc_scale_base_40m;	/* Combined tx scale bases for different bf/nss cases in 40MHz */
+	uint32_t	pppc_scale_base_80m;	/* Combined tx scale bases for different bf/nss cases in 80MHz */
+	uint32_t	pppc_scale_base_copy;	/* combined the flags indicating the tx scale bases are copied bfoff 1ss cases */
+	uint32_t	pppc_scale_overstep;	/* tx scale exceed the maximum scale indices */
+	uint32_t	pppc_scale_rollback;	/* tx scale roll back because scale index over step */
+	uint32_t	pppc_0_gput;		/* times pppc comparing goodput and both are zero */
+	uint32_t	tx_max_power;
+	uint32_t	nc_csr_read_count;	/* number of times Node Cache was read */
+	uint32_t	nc_csr_write_count;	/* number of times Node Cache was written to */
+	uint32_t	nc_csr_done_watermark;	/* Node cache done retries high watermark */
+	uint32_t	nc_csr_watermark_count; /* Number of times read retries reached max */
+	uint32_t	auc_dtim_notify;
+	uint32_t	auc_ps_notify;
+	uint32_t	tx_beacon_done;
+	uint32_t	sfs_peer_rts;
+	uint32_t	sfs_peer_rts_flags;
+	uint32_t	sfs_local_rts;
+	uint32_t	sfs_local_rts_flags;
+	uint32_t	sfs_dyn_wmm;
+	uint32_t	sfs_dyn_wmm_flags;
+	uint32_t	auc_wmm_ps_notify;
+	uint32_t	tx_wmm_ps_null_frames;
+	uint32_t	qtn_bcn_stop;
+	uint32_t	mu_grp_snd_queue_is_not_empty;
+	uint32_t	mu_prec_snd_queue_is_not_empty;
+	uint32_t	mu_group_delete;
+	uint32_t	mu_group_install;
+	uint32_t	mu_group_rate_node_updates;
+	uint32_t	mu_update_rates_mu;
+	uint32_t	mu_update_rates_su;
+	uint32_t	autocs_sample_bits;
+	uint32_t	autocs_adjust_bits;
+	uint32_t	autocs_step_size;
+	uint32_t	autocs_cs_thresh;
+	uint32_t	autocs_min_rssi;
+	uint32_t	bmps_null_tx_success;
+	uint32_t	bmps_null_tx_fail;
+	uint32_t	bmps_null_tx_timeout;
+	uint32_t	txqueue_g1q0_deadline_frozen;	/* beacon deadline register frozen counter */
+	uint32_t	auc_ipc_retry;
+	uint32_t	auc_ipc_hwm;
+	uint32_t	auc_ipc_send_delay;
+	uint32_t	auc_ipc_send_delay_hwm;
+};
+
+/**
+ * \brief MuC receive statistics
+ *
+ * These statistics are generated on the MuC, mainly on the receive datapath. This set of statistics
+ * also include low-level debugging facilities used internally.
+ */
+struct muc_rx_stats {
+	/**
+	 * This counter shows the number of descriptors taken from the host,
+	 * 'popped' from the top of the list.
+	 */
+	u_int32_t	rxdesc_pop_from_host;
+
+	/**
+	 * This counter shows the number of descriptors pushed to the hardware
+	 * for receive buffers.
+	 */
+	u_int32_t	rxdesc_get_from_queue;
+	u_int32_t	rxdesc_push_to_host;
+	u_int32_t	rxdesc_non_aggr_push_to_host;
+	u_int32_t	rxdesc_flush_to_host;
+	u_int32_t	rxdesc_reuse_push;
+	u_int32_t	rxdesc_reuse_pop;
+
+	/**
+	 * This counter shows the number of packets received with a bad duration.
+	 * A bad duration is where the duration field is all 1's - that is,
+	 * a packet which violates the 802.11 standard.
+	 */
+	u_int32_t	rxdesc_status_bad_dur;
+	u_int32_t	rxdesc_status_bad_len;
+	u_int32_t	rxdesc_status_crc_err;
+	u_int32_t	rxdesc_status_cmic_err;
+	u_int32_t	rxdesc_status_cmic_no_crc_err;
+	u_int32_t	rxdesc_status_retry;
+	u_int32_t	agg_stored;
+	u_int32_t	agg_duplicate;
+
+	u_int32_t	accel_mpdu;
+	u_int32_t	accel_msdu;
+	u_int32_t	accel_fwt_lu_timeout;
+	u_int32_t	accel_mcast_send;
+	u_int32_t	accel_mcast_drop;
+	u_int32_t	accel_no_match;
+	u_int32_t	accel_drop;
+	u_int32_t	accel_err;
+
+	u_int32_t	rate_train_chk;
+	u_int32_t	rate_train_err;
+	u_int32_t	rate_train_delay;
+	u_int32_t	rate_train_none;
+	u_int32_t	rate_train_hash_bad;
+	u_int32_t	rate_train_hash_good;
+
+	/**
+	 * This counter shows the number of MPDUs within an AMPDU that have been
+	 * discarded due to the sequence number being outside ('below') the current
+	 * receive sequence window.
+	 */
+	u_int32_t	agg_oldpkts;
+
+	/**
+	 * This counter shows the number of MPDUs within an AMPDU that have been
+	 * discarded due to the sequence number being off by > 2047 (half the sequence
+	 * space).
+	 */
+	u_int32_t	agg_very_oldpkts;
+	u_int32_t	agg_evict_in_order;
+	u_int32_t	agg_evict_in_move;
+
+	/**
+	 * This counter shows the number of received subframes within the
+	 * receive window that are missing when the window is moved.
+	 *
+	 * This counter represents one source receive packet loss.
+	 */
+	u_int32_t	agg_evict_empty;
+
+	/**
+	 * This counter shows the number of received subframes within the
+	 * receive window that are evicted due to timeout. Timeout is used
+	 * to ensure we don't sit with a stuck receive aggregate window when
+	 * the transmitter has stopped re-transmitting a given subframe.
+	 */
+	u_int32_t	agg_timeout;
+	u_int32_t	agg_rxwin_reset;
+	u_int32_t	rx_qnum_err;
+	u_int32_t	rx_mgmt;
+	u_int32_t	rx_ctrl;
+	u_int32_t	rx_pspoll;
+	u_int32_t	rx_pwr_mgmt;
+	u_int32_t	rx_delba;
+	/**
+	 * This counter shows the number of times the powersave bit is set
+	 * in the frame control field of packets received.
+	 *
+	 * \note This counter will generally be one greater than rx_pwr_mgmt_reset
+	 * when we have a single PS client associated and in power save.
+	 *
+	 * \sa rx_pwr_mgmt_reset
+	 */
+	u_int32_t	rx_pwr_mgmt_set;
+
+	/**
+	 * This counter shows the number of times the powersave bit of a
+	 * currently power save client is reset.
+	 *
+	 * \note This counter will generally be one less than rx_pwr_mgmt_set
+	 * when we have a single PS client associated and in power save mode.
+	 *
+	 * \sa rx_pwr_mgmt_set
+	 */
+	u_int32_t	rx_pwr_mgmt_reset;
+	u_int32_t	rx_desc_underflow;
+	u_int32_t	rx_desc_linkerr;
+	u_int32_t	rx_notify;
+	u_int32_t	rx_df_numelems;
+	u_int32_t	last_recv_seq;
+
+	/**
+	 * This counter shows the number of packets received for an unknown
+	 * node - that is - one which we do not have an association with.
+	 */
+	u_int32_t	rx_node_not_found;
+
+	/**
+	 * This counter shows the number of duplicates of non-QoS packets we
+	 * received and discarded.
+	 */
+	u_int32_t	rx_non_qos_duplicate;
+
+	/**
+	 * This counter shows the number of received NDPs.
+	 */
+	u_int32_t	rx_11n_ndp;
+	u_int32_t	rx_11ac_ndp;
+	u_int32_t	rx_ndp_inv_slot;
+	u_int32_t	rx_11n_ndp_no_capt;
+	u_int32_t	rx_ndp_sw_processed;
+	u_int32_t	rx_ndp_lockup;
+	u_int32_t	rx_11n_bf_act;
+	u_int32_t	rx_11ac_bf_act;
+	u_int32_t	rx_bf_act_inv_slot;
+
+	/**
+	 * This counter shows the number of received AMSDUs. This counter does
+	 * not count the number of subframes within the AMSDU.
+	 */
+	u_int32_t	rx_amsdu;
+	u_int32_t	rx_data;
+	u_int32_t	prev_rx_data;
+	u_int32_t	rx_recv_qnull;
+	u_int32_t	rx_recv_act;
+	u_int32_t	rx_recv_bcn;
+	u_int32_t	rx_recv_auth;
+	u_int32_t	rx_recv_assoc_req;
+	u_int32_t	rx_recv_assoc_res;
+	u_int32_t	rx_recv_deauth;
+	u_int32_t	rx_recv_disassoc;
+
+	/**
+	 * This counter shows the number of packets received where the MCS as
+	 * indicated in the PLCP is invalid (> 76).
+	 */
+	u_int32_t	rx_mcs_gt_76;
+	u_int32_t	tkip_keys;		/* Keep count of TKIP keys installed - for debug */
+	u_int32_t	rx_tkip_mic_err;	/* Number of TKIP packets RX with MIC error - the number reported to the higher layers */
+	u_int32_t	icv_errs; /* The number of raw ICV errors reported by the hardware */
+	u_int32_t	tmic_errs; /* The number of raw TMIC errors reported by the hardware */
+	u_int32_t	cmic_errs;
+	u_int32_t	crc_errs;
+
+	/**
+	 * This counter shows the number of transmit block ACK agreements
+	 * installed.
+	 *
+	 * If the upper bit is set, at least one implicit block ACK has been
+	 * established with a Quantenna peer.
+	 *
+	 * \note This number only increments - when block ACK agreements are
+	 * removed, this counter does not decrement.
+	 */
+	u_int32_t	ba_tx;
+
+	/**
+	 * This counter shows the number of receive block ACK agreements
+	 * installed.
+	 *
+	 * If the upper bit is set, at least one implicit block ACK has been
+	 * established with a Quantenna peer.
+	 *
+	 * \note This number only increments - when block ACK agreements are
+	 * removed, this counter does not decrement.
+	 */
+	u_int32_t	ba_rx;
+
+	/**
+	 * The number of times a block ACK has been rejected due to an out of
+	 * resource situation.
+	 */
+	u_int32_t	ba_rx_fail;
+	u_int32_t	sec_oflow;
+	u_int32_t	str_oflow;
+	u_int32_t	oflow_fixup_timeout;
+	u_int32_t	rxdone_intr;
+	u_int32_t	rxtypedone_intr;
+	u_int32_t	ipc_a2m_intr;
+	u_int32_t	tqe_intr;
+	u_int32_t	tqe_in_port_lhost;
+	u_int32_t	tqe_in_port_bad;
+	u_int32_t	tqe_a2m_type_txfb;
+	u_int32_t	tqe_a2m_type_rxpkt;
+	u_int32_t	tqe_a2m_type_unknown;
+	u_int32_t	tqe_reschedule_task;
+	u_int32_t	tqe_desc_unowned;
+
+	/**
+	 * \internal
+	 *
+	 * The number of interrupts from the baseband to the MuC.
+	 *
+	 * \note This should not be distributed externally - the following
+	 * fields are for internal debugging ONLY.
+	 */
+	u_int32_t	bb_intr;
+
+	/**
+	 * \internal
+	 *
+	 * The number of DLEAF overflow interrupts from the baseband.
+	 */
+	u_int32_t	bb_irq_dleaf_oflow;
+	u_int32_t	bb_irq_leaf_uflow;
+	u_int32_t	bb_irq_leaf_ldpc_uflow;
+	u_int32_t	bb_irq_tx_td_oflow_intr;
+	u_int32_t	bb_irq_tx_td_uflow_intr;
+	u_int32_t	bb_irq_rx_sm_wdg_intr;
+	/* BB spends more than 14.4ms (short GI)/16ms (long GI) to receive one packet */
+	u_int32_t	bb_irq_rx_long_dur;
+	u_int32_t	bb_irq_rx_long_dur_11ac;
+	u_int32_t	bb_irq_rx_long_dur_11n;
+	u_int32_t	bb_irq_rx_long_dur_11n_qtn;
+        /* BB reset due to spending more than 14.4ms/16ms to receive a packet. */
+	u_int32_t	bb_irq_rx_sym_exceed_rst;
+	u_int32_t	bb_irq_tx_sm_wdg_intr;
+
+	/**
+	 * \internal
+	 *
+	 * The number of BB state machine watchdogs that have kicked in.
+	 */
+	u_int32_t	bb_irq_main_sm_wdg_intr;
+	u_int32_t	bb_irq_hready_wdg_intr;
+	u_int32_t	mac_irq_rx_sec_buff_oflow;
+	u_int32_t	mac_irq_rx_strq_oflow;
+	u_int32_t	mac_irq_rx_bb_uflow_intr;
+	u_int32_t	mac_irq_rx_bb_oflow_intr;
+	u_int32_t	bb_irq_hready_wdg_reset;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented once at the start of the main watchdog state machine.
+	 *
+	 * \sa sreset_wdg_end
+	 */
+	u_int32_t	sreset_wdg_begin;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented once at the end of the main watchdog state machine.
+	 *
+	 * \sa sreset_wdg_begin
+	 */
+	u_int32_t	sreset_wdg_end;
+	u_int32_t	sreset_wdg_in_place;
+	u_int32_t	sreset_wdg_tx_beacon_hang;
+
+	/**
+	 * \internal
+	 *
+	 * The number of transmit hangs causing soft reset.
+	 *
+	 * Transmit hang is between 400 to 900ms from the time of sending a packet to the hardware
+	 * without receiving a tx done interrupt.
+	 */
+	u_int32_t	sreset_wdg_tx_hang;
+
+	/**
+	 * \internal
+	 *
+	 * The number of packet memory corruption causing soft reset.
+	 *
+	 * For unknown reason, packet memory may be corrupted. When packet memory corruption is detected,
+	 * soft reset is triggered, and this counter incremented once.
+	 */
+	u_int32_t	sreset_wdg_pm_corrupt;
+
+	/**
+	 * \internal
+	 *
+	 * The number of packet transmit control memory corruption causing soft reset.
+	 *
+	 * For unknown reason, transmit control memory may be corrupted. When transmit control memory corruption is detected,
+	 * soft reset is triggered, and this counter incremented once.
+	 */
+	u_int32_t	sreset_wdg_tcm_corrupt;
+
+	/**
+	 * \internal
+	 *
+	 * The number of receive hangs causing a soft reset.
+	 *
+	 * Receive hang is > 70s without receiving a single packet.
+	 *
+	 * Note that this can trigger in idle situations, but should not affect anything because
+	 * the link is idle.
+	 */
+	u_int32_t	sreset_wdg_rx_done;
+	u_int32_t	sreset_wdg_in_place_try;
+	u_int32_t	sreset_wdg_tasklet_sched_1;
+	u_int32_t	sreset_wdg_tasklet_sched_2;
+	u_int32_t	sreset_tasklet_sched;
+	u_int32_t	sreset_tasklet_begin;
+	u_int32_t	sreset_tasklet_end;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented when a BB hard reset is requested
+	 * to occur in the middle of a soft reset sequence
+	 */
+	u_int32_t	hreset_req;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented at the start of a soft reset.
+	 *
+	 * There should always be a corresponding increment in the sreset_end
+	 * counter, or there is a problem.
+	 *
+	 * \sa sreset_end
+	 */
+	u_int32_t	sreset_begin;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented at the end of a soft reset.
+	 *
+	 * The should always being a corresponding increment in the sreset_begin
+	 * counter, or there is a problem.
+	 *
+	 * \sa sreset_begin
+	 */
+	u_int32_t	sreset_end;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented each time DMA RX is in progress when a
+	 * soft reset is triggered.
+	 */
+	u_int32_t	sreset_dma_rx_inprog;
+
+	/**
+	 * \internal
+	 *
+	 * This counter is incremented each time DMA TX is in progress when a
+	 * soft reset is triggered.
+	 */
+	u_int32_t	sreset_dma_tx_inprog;
+	u_int32_t	sreset_dma_rx_max_wait;
+	u_int32_t	sreset_dma_tx_max_wait;
+	u_int32_t	sreset_dma_tx_hang;
+	u_int32_t	sreset_dma_rx_hang;
+	u_int32_t	sreset_dma_rx_wait_timeout;
+	u_int32_t	sreset_dma_tx_wait_timeout;
+	u_int32_t	sreset_drop_not_valid;
+	u_int32_t	sreset_drop_bad_addr;
+	u_int32_t	rf_cmpvtune_out;
+	u_int32_t	rf_cal_freq;
+	u_int32_t	ac_max;
+	u_int32_t	ac_min;
+	u_int32_t	ac_cur;
+	u_int32_t	ac_adj;
+	u_int32_t	rx_gain;
+	u_int32_t	rd_cache_indx;
+	u_int32_t	logger_sreset_wmac1_dma_rx_inprog;
+	u_int32_t	logger_sreset_wmac1_dma_tx_inprog;
+	u_int32_t	logger_sreset_wmac1_dma_rx_max_wait;
+	u_int32_t	logger_sreset_wmac1_dma_tx_max_wait;
+	u_int32_t	logger_sreset_wmac1_dma_tx_hang;
+	u_int32_t	logger_sreset_wmac1_dma_rx_hang;
+	u_int32_t	logger_sreset_wmac1_dma_rx_wait_timeout;
+	u_int32_t	logger_sreset_wmac1_dma_tx_wait_timeout;
+	/**
+	 * These counter show the information of MU frames.
+	 */
+	u_int32_t	mu_rx_pkt;
+
+	/**
+	 * \internal
+	 *
+	 * These counters monitor power duty cycling
+	 */
+	u_int32_t	pduty_sleep;
+	u_int32_t	pduty_rxoff;
+	u_int32_t	pduty_period;
+	u_int32_t	pduty_pct;
+
+	/**
+	 * \internal
+	 *
+	 * These counter are incremented when a soft-ring operation is triggered
+	 */
+	u_int32_t	soft_ring_push_to_tqe;
+	u_int32_t	soft_ring_empty;
+	u_int32_t	soft_ring_not_empty;
+	u_int32_t	soft_ring_add_force;
+	u_int32_t	soft_ring_add_to_head;
+	u_int32_t	soft_ring_add_continue;
+	u_int32_t	soft_ring_free_pool_empty;
+	u_int32_t	mimo_ps_mode_switch;	/* times STA switch MIMO power-save mode by HT action */
+
+	u_int32_t	rx_vlan_drop;
+	u_int32_t	auto_cca_state;
+	u_int32_t	auto_cca_th;
+	u_int32_t	auto_cca_spre;
+	u_int32_t	auto_cca_intf;
+
+	/**
+	 * \internal
+	 *
+	 * These counters are monitor memory allocation.
+	 */
+	u_int32_t	total_dmem_alloc;
+	u_int32_t	total_dram_alloc;
+	u_int32_t	dmem_alloc_fails;
+	u_int32_t	dram_alloc_fails;
+	u_int32_t	total_dmem_free;
+	u_int32_t	total_dram_free;
+
+	/* RX frames BW mode*/
+	u_int32_t	rx_bw_80;
+	u_int32_t	rx_bw_40;
+	u_int32_t	rx_bw_20;
+
+	/* U-APSD rx stats */
+	uint32_t	rx_wmm_ps_trigger;
+	uint32_t	rx_wmm_ps_set;
+	uint32_t	rx_wmm_ps_reset;
+
+	uint32_t	rx_intr_next_ptr_0;
+	uint32_t	rx_hbm_pool_depleted;
+
+	uint32_t	rxq_intr[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_fill[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_nobuf[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_stop[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_pkt[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_bad_status[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_pkt_oversize[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_pkt_delivered[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_status_hole_chk_num[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_status_hole_chk_step_sum[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_status_hole_chk_step_max[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_status_hole[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_status_hole_max_size[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_process_max[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_process_sum[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_process_num[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_process_limited[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rxq_desc_chain_empty[QTN_FW_WMAC_RX_QNUM];
+	uint32_t	rx_data_last_seqfrag;
+	uint32_t	rx_data_last_ip_id;
+	uint32_t	rx_opmode_notify;
+
+	/**
+	 * This counter is incremented once per packet which is sent via the
+	 * external filter (HotSpot functionality).
+	 */
+	uint32_t	accel_l2_ext_filter;
+	uint32_t	accel_mc_send_l2_ext_filter;
+
+	/**
+	 * This counter is incremented once per multicast packet dropped without
+	 * forwording to the external filter (HotSpot functionality).
+	 */
+	uint32_t	accel_mc_drop_l2_ext_filter;
+
+	uint32_t	rx_frame_addressed_to_wrong_bss;
+};
+
+#define MUC_LEGACY_NUM_RATES	12
+#define MUC_HT_NUM_RATES	77
+#define MUC_VHT_NUM_RATES	40
+struct muc_rx_rates {
+	u_int32_t rx_mcs[MUC_HT_NUM_RATES];
+	u_int32_t rx_mcs_11ac[MUC_VHT_NUM_RATES];
+};
+
+#define QTN_STATS_NUM_BF_SLOTS	10
+struct muc_rx_bf_stats {
+	u_int32_t	rx_bf_valid[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	rx_bf_aid[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	rx_bf_ng[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	rx_bf_11n_ndp[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	rx_bf_11ac_ndp[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	rx_bf_11n_act[QTN_STATS_NUM_BF_SLOTS];
+	/* Total number of 11ac BF feedbacks */
+	u_int32_t	rx_bf_11ac_act[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of MU group selection BF feedbacks */
+	u_int32_t	rx_bf_11ac_grp_sel[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of MU precoding BF feedbacks */
+	u_int32_t	rx_bf_11ac_prec[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of SU BF feedbacks */
+	u_int32_t	rx_bf_11ac_su[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of corrupted BF feedbacks */
+	u_int32_t	rx_bf_11ac_bad[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of MuC to DSP IPC failures while sending BF feedbacks */
+	u_int32_t	rx_bf_11ac_dsp_fail[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of times QMat for this node has been updated (the node was added to MU group) */
+	u_int32_t	mu_grp_add[QTN_STATS_NUM_BF_SLOTS];
+	/* Number of times the node was removed from MU group */
+	u_int32_t	mu_grp_del[QTN_STATS_NUM_BF_SLOTS];
+	u_int32_t	msg_buf_alloc_fail;
+};
+
+/** @} */
+
+extern struct muc_rx_stats uc_rx_stats;
+extern struct muc_rx_rates uc_rx_rates;
+extern struct muc_rx_bf_stats uc_rx_bf_stats;
+extern struct muc_tx_stats uc_tx_stats;
+extern struct qtn_rate_tx_stats_per_sec uc_tx_rates;
+extern uint32_t uc_su_rate_stats_read;
+extern uint32_t uc_mu_rate_stats_read;
+
+/*
+ * Rate adaption data collected for packet logger
+ * NOTE: Any changes to these definitions will require changes to stat_parser.pl
+ */
+#define RATES_STATS_NUM_ADAPTATIONS	16
+#define RATES_STATS_NUM_TX_RATES	6
+#define RATES_STATS_NUM_RX_RATES	8	/* Must be a multiple of word size */
+#define RATES_STATS_EVM_CNT		4
+
+/*
+ * Currently only two user positions are supported for MU group
+ * the following define should be aligned
+ * with IEEE80211_MU_GRP_NODES_MAX (4) in future.
+ * for now we don't want to take care about 2x extra zero-filled
+ * huge arrays in rate stats
+ */
+#define RATES_STATS_MAX_USER_IN_GROUP   2
+
+/**
+ * \addtogroup MUCSTATS
+ */
+/** @{ */
+struct qtn_rate_stats_mcs_data {
+	uint16_t	mcs_rate;
+	uint16_t	rate_index;
+	uint16_t	state;
+	uint16_t	pkt_total;
+	uint16_t	pkt_error;
+	uint16_t	pkt_hw_retry;
+	uint16_t	pkt_sample;
+	uint16_t	avg_per;
+} __attribute__((packed));
+
+struct qtn_rate_su_tx_stats {
+	uint32_t			seq_no;
+	uint32_t			timestamp;
+	uint32_t			flags;
+	uint16_t			sampling_index;
+	uint16_t			sampling_rate;
+	struct qtn_rate_stats_mcs_data	mcs_data[RATES_STATS_NUM_TX_RATES];
+} __attribute__((packed));
+
+struct qtn_rate_mu_tx_stats {
+	struct qtn_rate_su_tx_stats group_stats[RATES_STATS_MAX_USER_IN_GROUP];
+} __attribute__((packed));
+
+struct qtn_rate_gen_stats {
+	u_int16_t   rx_mcs_rates[RATES_STATS_NUM_RX_RATES];
+	u_int32_t  rx_mcs[RATES_STATS_NUM_RX_RATES];
+	u_int32_t  rx_crc;
+	u_int32_t  rx_sp_errors;
+	u_int32_t  rx_lp_errors;
+	u_int32_t  rx_evm[RATES_STATS_EVM_CNT];
+	u_int32_t  tx_subframe_success;
+	u_int32_t  tx_subframe_fail;
+	u_int32_t  tx_mgmt_success;
+	u_int32_t  tx_hw_retry;
+	u_int32_t  tx_sw_retry;
+} __attribute__((packed));
+
+struct qtn_rate_tx_stats_per_sec {
+	struct qtn_rate_su_tx_stats  stats_su[RATES_STATS_NUM_ADAPTATIONS];
+	struct qtn_rate_mu_tx_stats  stats_mu[RATES_STATS_NUM_ADAPTATIONS];
+};
+/** @} */
+
+#endif	/* _STATS_H_ */
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_bld.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_bld.h
new file mode 100644
index 0000000..268656a
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_bld.h
@@ -0,0 +1,6 @@
+/* Automatically generated file.  Do not edit. */
+#define QDRV_BLD_NAME	"v37.4.1.89"
+#define QDRV_BLD_LABEL	"v37.4.1.89"
+#define QDRV_BLD_VER	(0x25040159)
+#define QDRV_BLD_REV	"53858"
+#define QDRV_BLD_TYPE	(QDRV_BLD_TYPE_SDK)
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_sch.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_sch.h
new file mode 100644
index 0000000..e68a59e
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qdrv_sch.h
@@ -0,0 +1,461 @@
+/*SH0
+*******************************************************************************
+**                                                                           **
+**         Copyright (c) 2011 - 2012 Quantenna Communications, Inc.          **
+**                            All Rights Reserved                            **
+**                                                                           **
+*******************************************************************************
+**                                                                           **
+**  Redistribution and use in source and binary forms, with or without       **
+**  modification, are permitted provided that the following conditions       **
+**  are met:                                                                 **
+**  1. Redistributions of source code must retain the above copyright        **
+**     notice, this list of conditions and the following disclaimer.         **
+**  2. Redistributions in binary form must reproduce the above copyright     **
+**     notice, this list of conditions and the following disclaimer in the   **
+**     documentation and/or other materials provided with the distribution.  **
+**  3. The name of the author may not be used to endorse or promote products **
+**     derived from this software without specific prior written permission. **
+**                                                                           **
+**  Alternatively, this software may be distributed under the terms of the   **
+**  GNU General Public License ("GPL") version 2, or (at your option) any    **
+**  later version as published by the Free Software Foundation.              **
+**                                                                           **
+**  In the case this software is distributed under the GPL license,          **
+**  you should have received a copy of the GNU General Public License        **
+**  along with this software; if not, write to the Free Software             **
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  **
+**                                                                           **
+**  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "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.        **
+**                                                                           **
+*******************************************************************************
+EH0*/
+
+#ifndef __QDRV_SCH_H
+#define __QDRV_SCH_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#ifdef CONFIG_IPV6
+#include <linux/ipv6.h>
+#endif
+#include <net/pkt_sched.h>
+
+#include "net80211/if_ethersubr.h"
+#include "net80211/if_llc.h"
+
+#include <linux/if_vlan.h>
+
+#include <qtn/qtn_global.h>
+
+#include <qtn/qdrv_sch_data.h>
+#include "qdrv_sch_const.h"
+#include <qtn/iputil.h>
+#include <qtn/qtn_net_packet.h>
+#include <qtn/topaz_tqe_cpuif.h>
+#include <qtn/topaz_vlan_cpuif.h>
+#include <common/topaz_emac.h>
+#include <asm/hardware.h>
+#define ETHER_TYPE_UNKNOWN			0XFFFF
+#define IPTOS_PREC_SHIFT			5
+
+#define IP_DSCP_SHIFT		2
+#define IP_DSCP(_pri)           (((_pri) & 0xFF) >> IP_DSCP_SHIFT)
+#define IP_DSCP_MAPPING_SIZE	IP_DSCP_NUM >> 1
+#define VLANID_INDEX_INITVAL	4096
+/* 4-bits are used to store TID */
+#define QDRV_IP_DSCP_MAPPING_SHIFT	4
+#define QDRV_IP_DSCP_INDEX_SHIFT	3
+
+#define QDRV_SCH_RESERVED_TOKEN_PER_USER	64
+
+#define QDRV_SCH_EMAC0_IN_USE	1
+#define QDRV_SCH_EMAC1_IN_USE	2
+
+int qdrv_sch_module_init(void);
+void qdrv_sch_module_exit(void);
+
+extern __sram_data uint8_t qdrv_sch_tos2ac[];
+extern __sram_data uint8_t qdrv_vap_vlan_max;
+extern __sram_data uint8_t qdrv_sch_dscp2tid[QTN_MAX_BSS_VAPS][IP_DSCP_MAPPING_SIZE];
+extern __sram_data uint16_t qdrv_sch_vlan2index[QTN_MAX_BSS_VAPS];
+
+/*
+ * Refactoring of emac_wr(struct emac_common *arapc, int reg, u32 val)
+ * We can't visit the emac_common structure here.
+ */
+__always_inline static void qtn_emac_wr(uint32_t vbase, int reg, u32 val)
+{
+	writel(val, IO_ADDRESS(vbase + reg));
+	/* HW bug workaround - dummy access breaks up bus transactions. */
+	readl(RUBY_SYS_CTL_BASE_ADDR);
+}
+
+__always_inline static uint32_t qtn_emac_rd(uint32_t vbase, int reg)
+{
+	/*
+	 *HW bug workaround , sometimes we can't get the correct register value
+	 * so we need to do an extra readl
+	 */
+	readl(RUBY_SYS_CTL_BASE_ADDR);
+	return readl(IO_ADDRESS(vbase + reg));
+}
+
+static inline struct Qdisc *qdrv_tx_sch_vap_get_qdisc(const struct net_device *dev)
+{
+	/* This assumes 1 tx netdev queue per vap */
+	return netdev_get_tx_queue(dev, 0)->qdisc;
+}
+
+static inline int qdrv_sch_tclass_to_ac(const uint8_t dscp)
+{
+	int wme_ac;
+	uint8_t dot1p_up;
+	static const uint8_t qdrv_sch_dscp2dot1p[] = {
+		/* 000xxx */
+		0, 0, 0, 0, 0, 0, 0, 0,
+		/* 001xxx */
+		1, 1, 1, 1, 1, 1, 1, 1,
+		/* 010xxx */
+		2, 2, 2, 2, 2, 2, 2, 2,
+		/* 011xxx */
+		3, 3, 3, 3, 3, 3, 3, 3,
+		/* 100xxx */
+		4, 4, 4, 4, 4, 4, 4, 4,
+		/* 101xxx */
+		5, 5, 5, 5, 5, 5, 5, 5,
+		/* 110xxx */
+		6, 6, 6, 6, 6, 6, 6, 6,
+		/* 111xxx */
+		7, 7, 7, 7, 7, 7, 7, 7
+	};
+
+	dot1p_up = qdrv_sch_dscp2dot1p[IP_DSCP(dscp)];
+	if (dot1p_up < IEEE8021P_PRIORITY_NUM)
+		wme_ac = qdrv_sch_tos2ac[dot1p_up];
+	else
+		wme_ac = qdrv_sch_tos2ac[IPTOS_PREC(dscp) >> IPTOS_PREC_SHIFT];
+
+	return wme_ac;
+}
+
+static inline int
+qdrv_sch_classify_ctrl(struct sk_buff *skb)
+{
+	uint16_t ether_type = QTN_SKB_CB_ETHERTYPE(skb);
+	uint8_t ip_protocol;
+
+	if (likely(iputil_eth_is_ipv4or6(ether_type))) {
+		ip_protocol = QTN_SKB_CB_IPPROTO(skb);
+		if (unlikely((ip_protocol == IPPROTO_ICMP) ||
+				(ip_protocol == IPPROTO_ICMPV6) ||
+				(ip_protocol == IPPROTO_IGMP))) {
+			return 1;
+		}
+	} else if ((ether_type == __constant_htons(ETH_P_ARP)) ||
+			(ether_type == __constant_htons(ETH_P_PAE))) {
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline uint8_t qdrv_sch_mask_gettid(uint8_t ifindex, uint8_t dscp)
+{
+	uint8_t index;
+	uint32_t curval;
+	uint8_t	tid;
+
+	index = (dscp >> 1);
+	curval = qdrv_sch_dscp2tid[ifindex][index];
+
+	if (dscp & 0x1)
+		tid  = (curval & 0xf);
+	else
+		tid = (curval >> QDRV_IP_DSCP_MAPPING_SHIFT) & 0xf;
+
+	return tid;
+}
+
+/* Multiple VLAN tags are not currently supported */
+static inline void topaz_tqe_vlan_gettid(void *data, uint8_t *tid, uint8_t *vlan_index)
+{
+	struct vlan_ethhdr *vhd;
+	uint16_t vid = 0;
+	uint8_t ip_dscp = 0;
+	int i;
+	const void *iphdr = NULL;
+	const struct ether_header *eh = data;
+	const uint16_t *ether_type = &eh->ether_type;
+
+	*vlan_index = 0;
+	if (*ether_type == __constant_htons(ETH_P_8021Q)) {
+		ether_type += 2;
+		vhd = data;
+		vid = __constant_htons(vhd->h_vlan_TCI) & VLAN_VID_MASK;
+		for (i = 0; i < qdrv_vap_vlan_max; i++) {
+			if (qdrv_sch_vlan2index[i] == vid) {
+				*vlan_index = i;
+				break;
+			}
+		}
+	}
+
+	iphdr = ether_type + 1;
+	if (*ether_type == __constant_htons(ETH_P_IP)) {
+		const struct qtn_ipv4 *ipv4 = (const struct qtn_ipv4 *) iphdr;
+		ip_dscp = IP_DSCP(ipv4->dscp);
+	} else if (*ether_type == __constant_htons(ETH_P_IPV6)) {
+		const struct qtn_ipv6 *ipv6 = (const struct qtn_ipv6 *) iphdr;
+		ip_dscp = qtn_ipv6_tclass(ipv6);
+	} else if ((*ether_type == __constant_htons(ETH_P_ARP)) || (*ether_type == __constant_htons(ETH_P_PAE))) {
+		*tid = WME_AC_TO_TID(WMM_AC_VO);
+		return;
+	} else {
+		*tid = WME_AC_TO_TID(WMM_AC_BE);
+		return;
+	}
+
+	*tid = qdrv_sch_mask_gettid(*vlan_index, ip_dscp);
+}
+
+static inline void
+qdrv_sch_classify(struct sk_buff *skb, uint16_t ether_type, uint8_t *data_start)
+{
+	uint8_t wme_ac = WME_AC_BE;
+	uint8_t tid;
+	uint8_t vlan_index;
+
+	if (M_FLAG_ISSET(skb, M_CLASSIFY)) {
+		return;
+	}
+	M_FLAG_SET(skb, M_CLASSIFY);
+
+	QTN_SKB_CB_ETHERTYPE(skb) = ether_type;
+
+	if (ether_type == __constant_htons(ETH_P_IP)) {
+		struct iphdr *iphdr_p = (struct iphdr *)data_start;
+
+		if ((skb->len >= (data_start - skb->data) + sizeof(*iphdr_p)) &&
+				(iphdr_p->version == 4))
+			QTN_SKB_CB_IPPROTO(skb) = iphdr_p->protocol;
+	}
+#ifdef CONFIG_IPV6
+	else if (ether_type == __constant_htons(ETH_P_IPV6)) {
+		struct ipv6hdr *ipv6hdr_p = (struct ipv6hdr *)data_start;
+
+		if (skb->len >= (data_start - skb->data) + sizeof(struct ipv6hdr) &&
+				(ipv6hdr_p->version == 6)) {
+			uint8_t nexthdr;
+
+			iputil_v6_skip_exthdr(ipv6hdr_p, sizeof(struct ipv6hdr), &nexthdr,
+				(skb->len - ((uint8_t *)ipv6hdr_p - skb->data)), NULL, NULL);
+			QTN_SKB_CB_IPPROTO(skb) = nexthdr;
+		}
+	}
+#endif
+
+	if (qdrv_sch_classify_ctrl(skb)) {
+		wme_ac = QTN_AC_MGMT;
+	} else {
+		topaz_tqe_vlan_gettid(skb->data, &tid, &vlan_index);
+		wme_ac = TID_TO_WMM_AC(tid);
+	}
+
+	skb->priority = wme_ac;
+}
+
+static inline void
+qdrv_sch_classify_bk(struct sk_buff *skb)
+{
+	M_FLAG_SET(skb, M_CLASSIFY);
+	skb->priority = QDRV_BAND_AC_BK;
+}
+
+/*
+ * Skip over L2 headers in a buffer
+ *   Returns Ethernet type and a pointer to the payload
+ */
+static inline void *
+qdrv_sch_find_data_start(struct sk_buff *skb,
+		struct ether_header *eh, u16 *ether_type)
+{
+	struct llc *llc_p;
+	struct vlan_ethhdr *vlan_ethhdr_p;
+
+	if (ntohs(eh->ether_type) < ETHER_MAX_LEN) {
+		llc_p = (struct llc *)(eh + 1);
+		if ((skb->len >= LLC_SNAPFRAMELEN) &&
+		    (llc_p->llc_dsap == LLC_SNAP_LSAP) &&
+		    (llc_p->llc_ssap == LLC_SNAP_LSAP)) {
+			*ether_type = llc_p->llc_un.type_snap.ether_type;
+			return (void *)((char *)(eh + 1) - sizeof(ether_type) + LLC_SNAPFRAMELEN);
+		} else {
+			*ether_type = ETHER_TYPE_UNKNOWN;
+			return (void *)(eh + 1);
+		}
+	} else if (ntohs(eh->ether_type) == ETH_P_8021Q) {
+		vlan_ethhdr_p = (struct vlan_ethhdr *)eh;
+		*ether_type = vlan_ethhdr_p->h_vlan_encapsulated_proto;
+		skb->vlan_tci = ntohs(get_unaligned((__be16 *)(&vlan_ethhdr_p->h_vlan_TCI)));
+		return (void *)(vlan_ethhdr_p + 1);
+	} else {
+		*ether_type = eh->ether_type;
+		return (void *)(eh + 1);
+	}
+}
+
+static inline uint8_t qdrv_dscp2tid_default(const uint8_t dscp)
+{
+	const uint8_t tclass = dscp << IP_DSCP_SHIFT;
+	const uint8_t ac = qdrv_sch_tclass_to_ac(tclass);
+	const uint8_t tid = WME_AC_TO_TID(ac);
+
+	return tid;
+}
+
+/* Each byte contains 2 4-bit DSCP mapping values */
+static inline void qdrv_dscp2tid_setvalue(uint8_t ifindex , uint8_t dscp, uint8_t tid)
+{
+	uint8_t curval = 0;
+	uint8_t index = 0;
+
+	index = dscp >> 1;
+	curval = qdrv_sch_dscp2tid[ifindex][index];
+
+	if (dscp & 0x1) {
+		qdrv_sch_dscp2tid[ifindex][index] = (curval & ~0xf) | tid;
+	} else {
+		qdrv_sch_dscp2tid[ifindex][index] = (curval & ~(0xf << QDRV_IP_DSCP_MAPPING_SHIFT)) |
+			(tid << QDRV_IP_DSCP_MAPPING_SHIFT);
+	}
+}
+
+static inline void qdrv_dscp2tid_map_init(void)
+{
+	uint8_t ifindex;
+	uint8_t dscp;
+	uint8_t tid = 0;
+
+	for (dscp = 0; dscp < IP_DSCP_NUM; dscp++) {
+		tid =  qdrv_dscp2tid_default(dscp);
+		qdrv_dscp2tid_setvalue(0, dscp, tid);
+	}
+
+	for (ifindex = 1; ifindex < QTN_MAX_BSS_VAPS; ifindex++) {
+		memcpy(&qdrv_sch_dscp2tid[ifindex][0], &qdrv_sch_dscp2tid[0][0], sizeof(qdrv_sch_dscp2tid[0]));
+	}
+}
+
+#if !defined(CONFIG_TOPAZ_PCIE_HOST) && !defined(CONFIG_TOPAZ_PCIE_TARGET)
+/* conversion is only needed for tables that are different to the first table */
+static inline void qdrv_sch_set_vlanpath(void)
+{
+	int i;
+	union topaz_vlan_entry vlan_entry;
+	uint16_t vid;
+
+	/*
+	 * This comparison must be done again if the user changes wifi0 config to
+	 * be the same as some other interfaces.
+	 */
+	for (i = 1; i < QTN_MAX_BSS_VAPS; i++) {
+		vid = qdrv_sch_vlan2index[i];
+		if (vid == VLANID_INDEX_INITVAL) {
+			continue;
+		}
+
+		vlan_entry = topaz_vlan_get_entry(vid);
+		if (memcmp(&qdrv_sch_dscp2tid[0][0], &qdrv_sch_dscp2tid[i][0], sizeof(qdrv_sch_dscp2tid[0]))) {
+			vlan_entry.data.valid = 1;
+			vlan_entry.data.out_port = TOPAZ_TQE_LHOST_PORT;
+		} else {
+			vlan_entry.data.valid = 0;
+		}
+		topaz_vlan_clear_entry(vid);
+		topaz_vlan_set_entry(vid, vlan_entry);
+	}
+}
+
+/*
+ * Configure the HW DSCP to TID table, which is used for wifi0
+ * and any other TIDs that use the same config.
+ */
+static inline void qdrv_sch_set_dscp_hwtbl(uint8_t dscp, uint8_t tid, uint32_t reg_base)
+{
+	uint32_t dscp_reg_val = 0;
+	uint8_t dscp_reg_index = dscp >> QDRV_IP_DSCP_INDEX_SHIFT;
+	uint8_t dscp_nibble_index = dscp - (dscp_reg_index << QDRV_IP_DSCP_INDEX_SHIFT);
+
+	dscp_reg_val = qtn_emac_rd(reg_base, TOPAZ_EMAC_RXP_IP_DIFF_SRV_TID_REG(dscp_reg_index));
+
+	dscp_reg_val &= ~(0xF <<
+		(dscp_nibble_index << TOPAZ_EMAC_IPDSCP_HWT_SHIFT));
+	dscp_reg_val |= (tid & 0xF) <<
+		(dscp_nibble_index << TOPAZ_EMAC_IPDSCP_HWT_SHIFT);
+
+	qtn_emac_wr(reg_base, TOPAZ_EMAC_RXP_IP_DIFF_SRV_TID_REG(dscp_reg_index), dscp_reg_val);
+}
+#endif
+
+static inline void qdrv_sch_mask_settid(uint8_t ifindex, uint8_t dscp, uint8_t tid,
+		uint32_t emac_in_use)
+{
+	qdrv_dscp2tid_setvalue(ifindex, dscp, tid);
+#if !defined(CONFIG_TOPAZ_PCIE_HOST) && !defined(CONFIG_TOPAZ_PCIE_TARGET)
+	qdrv_sch_set_vlanpath();
+	if (ifindex == 0) {
+		if (emac_in_use & QDRV_SCH_EMAC0_IN_USE) {
+			qdrv_sch_set_dscp_hwtbl(dscp, tid, RUBY_ENET0_BASE_ADDR);
+		}
+		if (emac_in_use & QDRV_SCH_EMAC1_IN_USE) {
+			qdrv_sch_set_dscp_hwtbl(dscp, tid, RUBY_ENET1_BASE_ADDR);
+		}
+	}
+#endif
+}
+
+int qdrv_sch_node_is_active(const struct qdrv_sch_node_band_data *nbd,
+				const struct qdrv_sch_node_data *nd, uint8_t band);
+int qdrv_sch_enqueue_node(struct qdrv_sch_node_data *nd, struct sk_buff *skb,
+				bool is_over_quota, bool is_low_rate);
+
+void qdrv_sch_complete(struct qdrv_sch_node_data *nd, struct sk_buff *skb,
+					uint8_t under_quota);
+/*
+ * If qdrv_sch_dequeue_nostat is called, accounting in the qdisc
+ * is not complete until qdrv_sch_complete is called
+ */
+struct sk_buff *qdrv_sch_dequeue_nostat(struct qdrv_sch_shared_data *sd, struct Qdisc* sch);
+int qdrv_sch_flush_node(struct qdrv_sch_node_data *nd);
+int qdrv_sch_requeue(struct qdrv_sch_shared_data *sd, struct sk_buff *skb, struct Qdisc *sch);
+
+const char *qdrv_sch_tos2ac_str(int tos);
+void qdrv_sch_set_ac_map(int tos, int aid);
+
+int qdrv_sch_set_dscp2ac_map(const uint8_t vapid, uint8_t *ip_dscp, uint8_t listlen, uint8_t ac);
+int qdrv_sch_get_dscp2ac_map(const uint8_t vapid, uint8_t *dscp2ac);
+
+void qdrv_sch_set_dscp2tid_map(const uint8_t vapid, const uint8_t *dscp2tid);
+void qdrv_sch_get_dscp2tid_map(const uint8_t vapid, uint8_t *dscp2tid);
+
+void qdrv_tx_sch_node_data_init(struct Qdisc *sch, struct qdrv_sch_shared_data *sd,
+				struct qdrv_sch_node_data *nd, uint32_t users);
+void qdrv_tx_sch_node_data_exit(struct qdrv_sch_node_data *nd, uint32_t users);
+struct qdrv_sch_shared_data *qdrv_sch_shared_data_init(int16_t tokens, uint16_t rdt);
+void qdrv_sch_shared_data_exit(struct qdrv_sch_shared_data *sd);
+
+#endif
+
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_arc_processor.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_arc_processor.h
new file mode 100644
index 0000000..8091de5
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_arc_processor.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011 Quantenna Communications, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _QTN_ARC_PROCESSOR_H_
+#define _QTN_ARC_PROCESSOR_H_
+
+#if defined(STATIC_CHECK)
+uint32_t get_sp(void);
+uint32_t get_ilink1(void);
+uint32_t get_ilink2(void);
+uint32_t get_blink(void);
+uint32_t get_status32(void);
+uint8_t arc_read_uncached_8(const uint8_t *addr);
+void arc_write_uncached_8(uint8_t *addr, uint8_t value);
+uint16_t arc_read_uncached_16(const uint16_t *addr);
+void arc_write_uncached_16(uint16_t *addr, uint32_t value);
+uint32_t arc_read_uncached_32(const uint32_t *addr);
+void arc_write_uncached_32(uint32_t *addr, uint32_t value);
+#elif defined(_ARC)
+
+_Inline _Asm uint32_t get_sp(void)
+{
+	mov %r0, %r28
+}
+
+_Inline _Asm uint32_t get_ilink1(void)
+{
+	mov %r0, %r29
+}
+
+_Inline _Asm uint32_t get_ilink2(void)
+{
+	mov %r0, %r30
+}
+
+_Inline _Asm uint32_t get_blink(void)
+{
+	mov %r0, %r31
+}
+
+_Inline _Asm uint32_t get_status32(void)
+{
+	lr %r0, [%status32]
+}
+
+_Inline _Asm uint8_t arc_read_uncached_8(const uint8_t *addr)
+{
+	%reg addr
+	ldb.di %r0, [addr]
+}
+
+_Inline _Asm void arc_write_uncached_8(uint8_t *addr, uint8_t value)
+{
+	%reg addr, value
+	stb.di value, [addr]
+}
+
+_Inline _Asm uint16_t arc_read_uncached_16(const uint16_t *addr)
+{
+	%reg addr
+	ldw.di %r0, [addr]
+}
+
+_Inline _Asm void arc_write_uncached_16(uint16_t *addr, uint32_t value)
+{
+	%reg addr, value
+	stw.di value, [addr]
+}
+
+_Inline _Asm uint32_t arc_read_uncached_32(const uint32_t *addr)
+{
+	%reg addr
+	ld.di %r0, [addr]
+}
+
+_Inline _Asm void arc_write_uncached_32(uint32_t *addr, uint32_t value)
+{
+	%reg addr, value
+	st.di value, [addr]
+}
+
+#else
+/* implementations provided elsewhere */
+#endif	// STATIC_CHECK
+#endif	// _QTN_ARC_PROCESSOR_H_
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_auc_stats_fields.default.h b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_auc_stats_fields.default.h
new file mode 100644
index 0000000..d85a899
--- /dev/null
+++ b/arch/arc/plat-qtn/sdk-qsr1000/include/qtn/qtn_auc_stats_fields.default.h
@@ -0,0 +1,235 @@
+	{ 0xe51011f0, "sleep" },
+	{ 0xe5101228, "jiffies" },
+	{ 0xe5103404, "IRQ_0" },
+	{ 0xe5103408, "IRQ_1" },
+	{ 0xe510340c, "IRQ_2" },
+	{ 0xe5103410, "IRQ_3" },
+	{ 0xe5103414, "IRQ_4" },
+	{ 0xe5103418, "IRQ_5" },
+	{ 0xe510341c, "IRQ_6" },
+	{ 0xe5103420, "IRQ_7" },
+	{ 0xe5103424, "IRQ_8" },
+	{ 0xe5103428, "IRQ_9" },
+	{ 0xe510342c, "IRQ_10" },
+	{ 0xe5103430, "IRQ_11" },
+	{ 0xe5103434, "IRQ_12" },
+	{ 0xe5103438, "IRQ_13" },
+	{ 0xe510343c, "IRQ_14" },
+	{ 0xe5103440, "IRQ_15" },
+	{ 0xe5103444, "IRQ_16" },
+	{ 0xe5103448, "IRQ_17" },
+	{ 0xe510344c, "IRQ_18" },
+	{ 0xe5103450, "IRQ_19" },
+	{ 0xe5103460,	"task_alive_counters[0]" },
+	{ 0xe5103464,	"task_alive_counters[1]" },
+	{ 0xe5103468,	"task_alive_counters[2]" },
+	{ 0xe510346c,	"task_alive_counters[3]" },
+	{ 0xe5103470,	"task_alive_counters[4]" },
+	{ 0xe5103474,	"task_alive_counters[5]" },
+	{ 0xe5103478,	"task_alive_counters[6]" },
+	{ 0xe510347c,	"task_alive_counters[7]" },
+	{ 0xe5103480,	"task_alive_counters[8]" },
+	{ 0xe5103484,	"task_alive_counters[9]" },
+	{ 0xe5103488,	"task_alive_counters[10]" },
+	{ 0xe510348c,	"task_alive_counters[11]" },
+	{ 0xe5103490,	"task_alive_counters[12]" },
+	{ 0xe5103494,	"task_alive_counters[13]" },
+	{ 0xe5103498,	"task_alive_counters[14]" },
+	{ 0xe510349c,	"task_alive_counters[15]" },
+	{ 0xe51034a0,	"task_alive_counters[16]" },
+	{ 0xe51034a4,	"task_alive_counters[17]" },
+	{ 0xe51034a8,	"task_alive_counters[18]" },
+	{ 0xe51034ac,	"task_alive_counters[19]" },
+	{ 0xe51034b0,	"task_false_trigger[0]" },
+	{ 0xe51034b4,	"task_false_trigger[1]" },
+	{ 0xe51034b8,	"task_false_trigger[2]" },
+	{ 0xe51034bc,	"task_false_trigger[3]" },
+	{ 0xe51034c0,	"task_false_trigger[4]" },
+	{ 0xe51034c4,	"task_false_trigger[5]" },
+	{ 0xe51034c8,	"task_false_trigger[6]" },
+	{ 0xe51034cc,	"task_false_trigger[7]" },
+	{ 0xe51034d0,	"task_false_trigger[8]" },
+	{ 0xe51034d4,	"task_false_trigger[9]" },
+	{ 0xe51034d8,	"task_false_trigger[10]" },
+	{ 0xe51034dc,	"task_false_trigger[11]" },
+	{ 0xe51034e0,	"task_false_trigger[12]" },
+	{ 0xe51034e4,	"task_false_trigger[13]" },
+	{ 0xe51034e8,	"task_false_trigger[14]" },
+	{ 0xe51034ec,	"task_false_trigger[15]" },
+	{ 0xe51034f0,	"task_false_trigger[16]" },
+	{ 0xe51034f4,	"task_false_trigger[17]" },
+	{ 0xe51034f8,	"task_false_trigger[18]" },
+	{ 0xe51034fc,	"task_false_trigger[19]" },
+	{ 0xe5103500,	"tqew_ac[0]" },
+	{ 0xe5103504,	"tqew_ac[1]" },
+	{ 0xe5103508,	"tqew_ac[2]" },
+	{ 0xe510350c,	"tqew_ac[3]" },
+	{ 0xe5103510,	"tqew_ac_avail[0]" },
+	{ 0xe5103514,	"tqew_ac_avail[1]" },
+	{ 0xe5103518,	"tqew_ac_avail[2]" },
+	{ 0xe510351c,	"tqew_ac_avail[3]" },
+	{ 0xe5103520,	"tqew_air_humble" },
+	{ 0xe5103524,	"tqew_air_suppress" },
+	{ 0xe5103528,	"tqew_air_use_idletime" },
+	{ 0xe510352c,	"tqew_air_dequeue_only" },
+	{ 0xe5103530,	"tqew_pkt_pending_for_txdone" },
+	{ 0xe5103534,	"tqew_descr_alloc_fail" },
+	{ 0xe5103538,	"tqew_ring_alloc_fail" },
+	{ 0xe510353c,	"tqew_pop_alloc_fail" },
+	{ 0xe5103540,	"tqew_pop_sw_limit" },
+	{ 0xe5103544,	"tqew_pop_empty" },
+	{ 0xe5103548,	"tqew_available_set" },
+	{ 0xe510354c,	"tqew_available_reset" },
+	{ 0xe5103550,	"tqew_rx" },
+	{ 0xe5103554,	"tqew_drop" },
+	{ 0xe5103558,	"tqew_free" },
+	{ 0xe510355c,	"tqew_buf_invalid" },
+	{ 0xe5103560,	"wmac_tx_done[0]" },
+	{ 0xe5103564,	"wmac_tx_done[1]" },
+	{ 0xe5103568,	"wmac_tx_done[2]" },
+	{ 0xe510356c,	"wmac_tx_done[3]" },
+	{ 0xe5103570,	"agg_aggregate_flag" },
+	{ 0xe5103574,	"agg_aggressive_agg" },
+	{ 0xe5103578,	"hdrs_available_recent_min" },
+	{ 0xe510357c,	"agg_states[0]" },
+	{ 0xe5103580,	"agg_states[1]" },
+	{ 0xe5103584,	"agg_states[2]" },
+	{ 0xe5103588,	"agg_states[3]" },
+	{ 0xe510358c,	"agg_states[4]" },
+	{ 0xe5103590,	"ethq_push" },
+	{ 0xe5103594,	"ethq_pop" },
+	{ 0xe5103598,	"agg_aggregate_mpdu" },
+	{ 0xe510359c,	"agg_aggregate_msdu" },
+	{ 0xe51035a0,	"agg_singleton_mpdu" },
+	{ 0xe51035a4,	"agg_singleton_mgmt" },
+	{ 0xe51035a8,	"agg_singleton_ctl" },
+	{ 0xe51035ac,	"agg_singleton_probe" },
+	{ 0xe51035b0,	"agg_4K_amsdu" },
+	{ 0xe51035b4,	"agg_8K_amsdu" },
+	{ 0xe51035b8,	"agg_11K_amsdu" },
+	{ 0xe51035bc,	"tx_feedback_success" },
+	{ 0xe51035c0,	"tx_feedback_fail" },
+	{ 0xe51035c4,	"tx_done_status_success" },
+	{ 0xe51035c8,	"tx_done_status_timeout" },
+	{ 0xe51035cc,	"tx_done_status_xretry" },
+	{ 0xe51035d0,	"tx_done_status_timeout_xretry" },
+	{ 0xe51035d4,	"tx_done_pkt_chain_reset" },
+	{ 0xe51035d8,	"tx_done_pkt_chain_success" },
+	{ 0xe51035dc,	"tx_done_pkt_chain_drop_tid_down" },
+	{ 0xe51035e0,	"tx_done_pkt_chain_drop_xattempts" },
+	{ 0xe51035e4,	"tx_done_singleton_finish" },
+	{ 0xe51035e8,	"tx_done_singleton_swretry" },
+	{ 0xe51035ec,	"tx_done_aggregate_finish" },
+	{ 0xe51035f0,	"tx_done_aggregate_hwretry" },
+	{ 0xe51035f4,	"tx_done_aggregate_swretry" },
+	{ 0xe51035f8,	"tx_done_mpdu_swretry" },
+	{ 0xe51035fc,	"tx_sample" },
+	{ 0xe5103600,	"tx_bw_sample" },
+	{ 0xe5103604,	"tx_swretry_lower_bw" },
+	{ 0xe5103608,	"tx_swretry_agg_exceed" },
+	{ 0xe510360c,	"tx_scale_base_20m" },
+	{ 0xe5103610,	"tx_scale_base_40m" },
+	{ 0xe5103614,	"tx_scale_base_80m" },
+	{ 0xe5103618,	"tx_scale_max" },
+	{ 0xe510361c,	"tx_scale_overstep" },
+	{ 0xe5103620,	"alloc_tqew_fast" },
+	{ 0xe5103624,	"free_tqew_fast" },
+	{ 0xe5103628,	"alloc_tqew_slow" },
+	{ 0xe510362c,	"free_tqew_slow" },
+	{ 0xe5103630,	"alloc_tqew_local" },
+	{ 0xe5103634,	"free_tqew_local" },
+	{ 0xe5103638,	"alloc_hdr_fast" },
+	{ 0xe510363c,	"free_hdr_fast" },
+	{ 0xe5103640,	"alloc_hdr_slow" },
+	{ 0xe5103644,	"free_hdr_slow" },
+	{ 0xe5103648,	"alloc_msdu_hdr_failed" },
+	{ 0xe510364c,	"alloc_mpdu_hdr_failed" },
+	{ 0xe5103650,	"alloc_tid_superfast" },
+	{ 0xe5103654,	"free_tid_superfast" },
+	{ 0xe5103658,	"alloc_tid_fast" },
+	{ 0xe510365c,	"free_tid_fast" },
+	{ 0xe5103660,	"alloc_tid_slow" },
+	{ 0xe5103664,	"free_tid_slow" },
+	{ 0xe5103668,	"alloc_node_rate_fast" },
+	{ 0xe510366c,	"free_node_rate_fast" },
+	{ 0xe5103670,	"alloc_node_rate_slow" },
+	{ 0xe5103674,	"free_node_rate_slow" },
+	{ 0xe5103678,	"alloc_node_superfast" },
+	{ 0xe510367c,	"free_node_superfast" },
+	{ 0xe5103680,	"alloc_node_fast" },
+	{ 0xe5103684,	"free_node_fast" },
+	{ 0xe5103688,	"alloc_fcs" },
+	{ 0xe510368c,	"free_fcs" },
+	{ 0xe5103690,	"alloc_mac_descr" },
+	{ 0xe5103694,	"free_mac_descr" },
+	{ 0xe5103698,	"tx_mac_push" },
+	{ 0xe510369c,	"tx_mac_idle" },
+	{ 0xe51036a0,	"tx_mac_rts" },
+	{ 0xe51036a4,	"tx_mac_cts2self" },
+	{ 0xe51036a8,	"tx_vlan_drop" },
+	{ 0xe51036ac,	"tx_acm_drop" },
+	{ 0xe51036b0,	"tx_ps_drop" },
+	{ 0xe51036b4,	"ocs_tx_suspend" },
+	{ 0xe51036b8,	"ocs_tx_resume" },
+	{ 0xe51036bc,	"ocs_singleton_suspend" },
+	{ 0xe51036c0,	"ocs_ampdu_suspend" },
+	{ 0xe51036c4,	"ocs_frame_created" },
+	{ 0xe51036c8,	"pwr_mgmt_awake" },
+	{ 0xe51036cc,	"pwr_mgmt_sleep" },
+	{ 0xe51036d0,	"pwr_mgmt_tx" },
+	{ 0xe51036d4,	"pspoll_rx" },
+	{ 0xe51036d8,	"dtim_q_push" },
+	{ 0xe51036dc,	"dtim_q_pop" },
+	{ 0xe51036e0,	"dtim_trigger" },
+	{ 0xe51036e4,	"dtim_q_overflow" },
+	{ 0xe51036e8,	"tx_restrict_dropped" },
+	{ 0xe51036ec,	"tx_throt_dropped" },
+	{ 0xe51036f0,	"tx_block_singleton" },
+	{ 0xe51036f4,	"tx_force_unblock_tid" },
+	{ 0xe51036f8,	"tx_ctl_pkt_hbm_alloc_fails" },
+	{ 0xe51036fc,	"tx_ctl_pkt_alloc_descr_fails" },
+	{ 0xe5103700,	"tx_bar_alloc_ctl_pkt_fails" },
+	{ 0xe5103704,	"tx_valid_bit_not_set" },
+	{ 0xe5103708,	"wmm_ps_tx" },
+	{ 0xe510370c,	"wmm_ps_tx_null_frames" },
+	{ 0xe5103710,	"wmm_ps_tx_more_data_frames" },
+	{ 0xe5103714,	"wmm_ps_tx_eosp_frames" },
+	{ 0xe5103718,	"mu_tx_su_count" },
+	{ 0xe510371c,	"mu_tx_send_mu_fail" },
+	{ 0xe5103720,	"mu_tx_push_count" },
+	{ 0xe5103724,	"mu_tx_done_count" },
+	{ 0xe5103728,	"mu_tx_done_succ" },
+	{ 0xe510372c,	"mu_tx_done_fail" },
+	{ 0xe5103730,	"mu_tx_sample" },
+	{ 0xe5103734,	"mu_bar_bitmap_non_zero" },
+	{ 0xe5103738,	"mu_bar_bitmap_zero" },
+	{ 0xe510373c,	"mu_mac_wmac1_ipc_push" },
+	{ 0xe5103740,	"mu_mac_wmac1_auc_push" },
+	{ 0xe5103744,	"mu_wmac1_resets" },
+	{ 0xe5103748,	"mu_tx_swretry_agg_exceed" },
+	{ 0xe510374c,	"mu_tx_buddy_try" },
+	{ 0xe5103750,	"mu_tx_buddy_fail_wmac" },
+	{ 0xe5103754,	"mu_tx_buddy_fail_ptid" },
+	{ 0xe5103758,	"mu_tx_buddy_fail_rate" },
+	{ 0xe510375c,	"mu_tx_buddy_fail_create_agg" },
+	{ 0xe5103760,	"mu_tx_buddy_mu_only_timeout" },
+	{ 0xe5103764,	"mu_tx_another_q_push_succ" },
+	{ 0xe5103768,	"mu_tx_another_q_push_fail" },
+	{ 0xe510376c,	"mu_tx_buddy_multi_tid" },
+	{ 0xe5103770,	"mu_tx_wmac_0_done_count" },
+	{ 0xe5103774,	"mu_tx_wmac_0_bitmap_non_zero" },
+	{ 0xe5103778,	"mu_tx_wmac_0_bitmap_zero" },
+	{ 0xe510377c,	"mu_tx_wmac_0_done_timeout" },
+	{ 0xe5103780,	"mu_tx_wmac_0_done_succ" },
+	{ 0xe5103784,	"mu_tx_wmac_0_done_fail" },
+	{ 0xe5103788,	"mu_tx_wmac_1_done_succ" },
+	{ 0xe510378c,	"mu_tx_wmac_1_done_fail" },
+	{ 0xe5103790,	"mu_tx_wmac_0_mpdu_total" },
+	{ 0xe5103794,	"mu_tx_wmac_0_mpdu_succ" },
+	{ 0xe5103798,	"mu_tx_wmac_1_mpdu_total" },
+	{ 0xe510379c,	"mu_tx_wmac_1_mpdu_succ" },
+	{ 0xe51037a0,	"mu_tx_qnum[0]" },