Import from Quantenna SDK v37.4.0.46.

quantenna-sdk-v37.4.0.46.tar.gz/
  linux_2.6.35.12/* -> .
  drivers/ruby -> drivers
  drivers/topaz -> drivers
  common -> include
  drivers/include/* -> include
  include/qtn -> include

Change-Id: Idb868cfd5fd71045c22bb6da17d042a5dc915aad
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index d58098b..25610a1 100755
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -119,6 +119,12 @@
         int
         default "256" #"VMALLOC_SIZE(in MB)"
 
+# To support saving core dump in case of LHost, MuC or AuC crash
+config QTN_SOC_CORE_DUMP
+	bool
+	default y
+	select ZLIB_DEFLATE
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
diff --git a/arch/arc/configs/qhs710_msft_config b/arch/arc/configs/qhs710_msft_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/qhs710_msft_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/qhs710_msmr_config b/arch/arc/configs/qhs710_msmr_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/qhs710_msmr_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/qhs710_vb_cgi_config b/arch/arc/configs/qhs710_vb_cgi_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/qhs710_vb_cgi_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/qhs711_host_config b/arch/arc/configs/qhs711_host_config
deleted file mode 100644
index 67bc864..0000000
--- a/arch/arc/configs/qhs711_host_config
+++ /dev/null
@@ -1,1188 +0,0 @@
-#
-# Used with Quantenna PCIe hosts: QHS711 DBDC boards
-#
-# Linux kernel version: 2.6.35.12
-#
-CONFIG_ARCH_ARC=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_UID16=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-CONFIG_FLATMEM=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_MMU=y
-CONFIG_NO_IOPORT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_BINFMT_ELF=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-
-#
-# General setup
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE="/usr/local/ARC/gcc/bin/arc-linux-uclibc-"
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_TREE_RCU=y
-# CONFIG_TREE_PREEMPT_RCU is not set
-# CONFIG_TINY_RCU is not set
-CONFIG_RCU_TRACE=y
-CONFIG_RCU_FANOUT=32
-# CONFIG_RCU_FANOUT_EXACT is not set
-CONFIG_TREE_RCU_TRACE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../buildroot/rootfs.arc-linux-uclibc.cpio"
-CONFIG_INITRAMFS_ROOT_UID=0
-CONFIG_INITRAMFS_ROOT_GID=0
-# CONFIG_RD_GZIP is not set
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
-# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
-# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_DEFERRED_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-# CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_SIGNALFD is not set
-# CONFIG_TIMERFD is not set
-# CONFIG_EVENTFD is not set
-CONFIG_SHMEM=y
-# CONFIG_AIO is not set
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=1
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_FREEZER is not set
-
-#
-# Processor Type and features
-#
-CONFIG_ARCH_ARC700=y
-# CONFIG_ARCH_ARC800 is not set
-
-#
-# ARC CPU Core Configuration
-#
-CONFIG_ARC700_CACHE=y
-CONFIG_ARC700_USE_ICACHE=y
-CONFIG_ARC700_USE_DCACHE=y
-CONFIG_ARC700_CACHE_PAGES=y
-# CONFIG_ARCH_ARC_ICCM is not set
-# CONFIG_ARCH_ARC_DCCM is not set
-# CONFIG_ARC_MMU_V1 is not set
-CONFIG_ARC_MMU_V2=y
-# CONFIG_ARC_MMU_V3 is not set
-CONFIG_ARC_PAGE_SIZE_8K=y
-# CONFIG_ARC_PAGE_SIZE_16K is not set
-# CONFIG_ARC_PAGE_SIZE_4K is not set
-# CONFIG_ARCH_ARC_LV2_INTR is not set
-# CONFIG_ARCH_ARC_FPU is not set
-# CONFIG_ARC700_V_4_10 is not set
-
-#
-# Board Configuration
-#
-CONFIG_LINUX_LINK_BASE=0x80002000
-CONFIG_SDRAM_SIZE=0x04000000
-
-#
-# ARC Pheripheral Support
-#
-CONFIG_ARC_AHB_PCI_BRIDGE=y
-# CONFIG_NO_DMA is not set
-# CONFIG_ARC_IDE is not set
-# CONFIG_ARC_SERIAL is not set
-# CONFIG_ARCTANGENT_EMAC is not set
-# CONFIG_XILINX_TEMAC is not set
-# CONFIG_ISS_MAC is not set
-# CONFIG_ARCPGU is not set
-# CONFIG_VFB_SIM is not set
-# CONFIG_SOUND_ARC_AC97 is not set
-CONFIG_ARC_7XX_GPIO=y
-
-#
-# Bus options (PCI etc.)
-#
-CONFIG_PCI=y
-CONFIG_ARCH_SUPPORTS_MSI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_STUB is not set
-# CONFIG_PCI_IOV is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_PCCARD is not set
-CONFIG_ARCH_ARC_CURR_IN_REG=y
-# CONFIG_ARC_TLS_REG_EMUL is not set
-CONFIG_ARC_MISALIGNED_ACCESS=y
-# CONFIG_ARCH_ARC_SPACE_RND is not set
-CONFIG_MMAP_CODE_CMN_VADDR=y
-CONFIG_HZ=200
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_ARC_STACK_NONEXEC=y
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_ARCH_ARC_HLINK is not set
-CONFIG_ARC_DBG=y
-CONFIG_ARC_STACK_UNWIND=y
-# CONFIG_ARC_TLB_PARANOIA is not set
-# CONFIG_ARC_DBG_EVENT_TIMELINE is not set
-# CONFIG_ARC_TLB_PROFILE is not set
-# CONFIG_ARC_UBOOT_CMDLINE is not set
-# CONFIG_ARC_PROFILING is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_IPV6_ROUTER_PREF=y
-# CONFIG_IPV6_ROUTE_INFO is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONIFG_IPV6_MIP6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_NDISC_NODETYPE is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_SUBTREES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_PIMSM_V2 is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_ADVANCED is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_SIP=y
-# CONFIG_NF_CT_NETLINK is not set
-CONFIG_NETFILTER_XTABLES=y
-
-#
-# Xtables combined modules
-#
-CONFIG_NETFILTER_XT_MARK=m
-
-#
-# Xtables targets
-#
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-
-#
-# Xtables matches
-#
-# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
-CONFIG_NETFILTER_XT_MATCH_POLICY=y
-# CONFIG_NETFILTER_XT_MATCH_STATE is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_DEFRAG_IPV4=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-# CONFIG_NF_NAT is not set
-CONFIG_IP_NF_MANGLE=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-CONFIG_STP=y
-CONFIG_BRIDGE=y
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_PHONET is not set
-CONFIG_NET_SCHED=y
-
-#
-# IPv6: Netfilter Configuration
-#
-#
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_LOG is not set
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_SECURITY is not set
-
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=y
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_HFSC is not set
-CONFIG_NET_SCH_PRIO=y
-# CONFIG_NET_SCH_MULTIQ is not set
-CONFIG_NET_SCH_RED=y
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_TEQL is not set
-CONFIG_NET_SCH_TBF=y
-CONFIG_NET_SCH_GRED=y
-CONFIG_NET_SCH_DSMARK=y
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_DRR is not set
-CONFIG_NET_SCH_INGRESS=y
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=y
-CONFIG_NET_CLS_TCINDEX=y
-CONFIG_NET_CLS_ROUTE4=y
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=y
-CONFIG_NET_CLS_U32=y
-# CONFIG_CLS_U32_PERF is not set
-CONFIG_CLS_U32_MARK=y
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-CONFIG_NET_CLS_FLOW=y
-# CONFIG_NET_EMATCH is not set
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=y
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_NAT is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_SIMP is not set
-# CONFIG_NET_ACT_SKBEDIT is not set
-CONFIG_NET_CLS_IND=y
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_WEXT_PRIV=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
-
-#
-# Some wireless drivers require a rate control algorithm
-#
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_CAIF is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH=""
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=2048
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# You can enable one or both FireWire driver stacks.
-#
-
-#
-# The newer stack is recommended.
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-# CONFIG_IFB is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_ETHOC is not set
-# CONFIG_DNET is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_B44 is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851_MLL is not set
-# CONFIG_ATL2 is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_IGB is not set
-# CONFIG_IGBVF is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_CNIC is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_JME is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_TR is not set
-CONFIG_WLAN=y
-# CONFIG_ATMEL is not set
-# CONFIG_HOSTAP is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_VMXNET3 is not set
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_RAMOOPS is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_CHARDEV is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-# CONFIG_I2C_SMBUS is not set
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# PC SMBus host controller drivers
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_VIAPRO is not set
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_SPI is not set
-
-#
-# PPS support
-#
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO expanders:
-#
-# CONFIG_GPIO_IT8761E is not set
-# CONFIG_GPIO_SCH is not set
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_ADP5588 is not set
-
-#
-# PCI GPIO expanders:
-#
-# CONFIG_GPIO_CS5535 is not set
-# CONFIG_GPIO_BT8XX is not set
-# CONFIG_GPIO_LANGWELL is not set
-# CONFIG_GPIO_RDC321X is not set
-
-#
-# SPI GPIO expanders:
-#
-
-#
-# AC97 GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-CONFIG_MFD_SUPPORT=y
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_MFD_TIMBERDALE is not set
-# CONFIG_LPC_SCH is not set
-# CONFIG_MFD_RDC321X is not set
-# CONFIG_MFD_JANZ_CMODIO is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_MEDIA_SUPPORT is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGA_ARB is not set
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_INFINIBAND is not set
-# CONFIG_RTC_CLASS is not set
-CONFIG_DMADEVICES=y
-# CONFIG_DMADEVICES_DEBUG is not set
-
-#
-# DMA Devices
-#
-# CONFIG_TIMB_DMA is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_HFSPLUS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set
-CONFIG_PRINTK_TIME=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_LKDTM is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_TRACING_SUPPORT=y
-# CONFIG_FTRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_EARLY_PRINTK=y
-# CONFIG_16KSTACKS is not set
-# CONFIG_OPTIMIZE_INLINING is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_DEFAULT_SECURITY_SELINUX is not set
-# CONFIG_DEFAULT_SECURITY_SMACK is not set
-# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_PCBC is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
-
-#
-# Quantenna
-#
-CONFIG_QUANTENNA_RUBY=y
-CONFIG_ARCH_RUBY_NUMA=y
-CONFIG_QVSP=y
-# CONFIG_RUBY_PCIE_TARGET is not set
-CONFIG_RUBY_PCIE_HOST=y
-CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
-# CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
-CONFIG_ARCH_RUBY_EMAC_LIB=y
-CONFIG_ARCH_RUBY_EMAC=y
-CONFIG_ARCH_RUBY_EMAC_SMOOTHING=y
-CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
-CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
-# CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
-# CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
-
-#
-# Quantenna Topaz
-#
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
diff --git a/arch/arc/configs/qhs711_pcie_config b/arch/arc/configs/qhs711_pcie_config
deleted file mode 100644
index 0ae0638..0000000
--- a/arch/arc/configs/qhs711_pcie_config
+++ /dev/null
@@ -1,1061 +0,0 @@
-#
-# This file is under the control of Perforce and determines the kernel configuration for Ruby / BBIC3.
-# Used with QHS711 PCIe board types
-#
-# Linux kernel version: 2.6.35.12
-#
-CONFIG_ARCH_ARC=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_UID16=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-CONFIG_FLATMEM=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_MMU=y
-CONFIG_NO_IOPORT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_GPIO=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_BINFMT_ELF=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
-
-#
-# General setup
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_CROSS_COMPILE="/usr/local/ARC/gcc/bin/arc-linux-uclibc-"
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_TREE_RCU=y
-# CONFIG_TREE_PREEMPT_RCU is not set
-# CONFIG_TINY_RCU is not set
-CONFIG_RCU_TRACE=y
-CONFIG_RCU_FANOUT=32
-# CONFIG_RCU_FANOUT_EXACT is not set
-CONFIG_TREE_RCU_TRACE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_RELAY is not set
-# CONFIG_NAMESPACES is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="../buildroot/rootfs.arc-linux-uclibc.cpio"
-CONFIG_INITRAMFS_ROOT_UID=0
-CONFIG_INITRAMFS_ROOT_GID=0
-# CONFIG_RD_GZIP is not set
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_LZMA is not set
-# CONFIG_RD_LZO is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
-# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
-# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_DEFERRED_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-# CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_SIGNALFD is not set
-# CONFIG_TIMERFD is not set
-# CONFIG_EVENTFD is not set
-CONFIG_SHMEM=y
-# CONFIG_AIO is not set
-
-#
-# Kernel Performance Events And Counters
-#
-CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-
-#
-# GCOV-based kernel profiling
-#
-# CONFIG_GCOV_KERNEL is not set
-# CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=1
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_BLOCK=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_FREEZER is not set
-
-#
-# Processor Type and features
-#
-CONFIG_ARCH_ARC700=y
-# CONFIG_ARCH_ARC800 is not set
-
-#
-# ARC CPU Core Configuration
-#
-CONFIG_ARC700_CACHE=y
-CONFIG_ARC700_USE_ICACHE=y
-CONFIG_ARC700_USE_DCACHE=y
-CONFIG_ARC700_CACHE_PAGES=y
-# CONFIG_ARCH_ARC_ICCM is not set
-# CONFIG_ARCH_ARC_DCCM is not set
-# CONFIG_ARC_MMU_V1 is not set
-CONFIG_ARC_MMU_V2=y
-# CONFIG_ARC_MMU_V3 is not set
-CONFIG_ARC_PAGE_SIZE_8K=y
-# CONFIG_ARC_PAGE_SIZE_16K is not set
-# CONFIG_ARC_PAGE_SIZE_4K is not set
-# CONFIG_ARCH_ARC_LV2_INTR is not set
-# CONFIG_ARCH_ARC_FPU is not set
-# CONFIG_ARC700_V_4_10 is not set
-
-#
-# Board Configuration
-#
-CONFIG_LINUX_LINK_BASE=0x80002000
-CONFIG_SDRAM_SIZE=0x04000000
-
-#
-# ARC Pheripheral Support
-#
-# CONFIG_NO_DMA is not set
-# CONFIG_ARC_IDE is not set
-# CONFIG_ARC_SERIAL is not set
-# CONFIG_ARCTANGENT_EMAC is not set
-# CONFIG_XILINX_TEMAC is not set
-# CONFIG_ISS_MAC is not set
-# CONFIG_ARCPGU is not set
-# CONFIG_VFB_SIM is not set
-# CONFIG_SOUND_ARC_AC97 is not set
-CONFIG_ARC_7XX_GPIO=y
-
-#
-# Bus options (PCI etc.)
-#
-# CONFIG_PCI is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-CONFIG_ARCH_ARC_CURR_IN_REG=y
-# CONFIG_ARC_TLS_REG_EMUL is not set
-CONFIG_ARC_MISALIGNED_ACCESS=y
-# CONFIG_ARCH_ARC_SPACE_RND is not set
-# CONFIG_MMAP_CODE_CMN_VADDR is not set
-CONFIG_HZ=200
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_ARC_STACK_NONEXEC=y
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_ARCH_ARC_HLINK is not set
-CONFIG_ARC_DBG=y
-CONFIG_ARC_STACK_UNWIND=y
-# CONFIG_ARC_TLB_PARANOIA is not set
-# CONFIG_ARC_DBG_EVENT_TIMELINE is not set
-# CONFIG_ARC_TLB_PROFILE is not set
-# CONFIG_ARC_UBOOT_CMDLINE is not set
-# CONFIG_ARC_PROFILING is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_IPV6_ROUTER_PREF=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_ADVANCED is not set
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=y
-CONFIG_NETFILTER_NETLINK_LOG=y
-CONFIG_NF_CONNTRACK=y
-CONFIG_NF_CONNTRACK_FTP=y
-CONFIG_NF_CONNTRACK_IRC=y
-CONFIG_NF_CONNTRACK_SIP=y
-# CONFIG_NF_CT_NETLINK is not set
-CONFIG_NETFILTER_XTABLES=y
-
-#
-# Xtables combined modules
-#
-CONFIG_NETFILTER_XT_MARK=m
-
-#
-# Xtables targets
-#
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-
-#
-# Xtables matches
-#
-# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
-CONFIG_NETFILTER_XT_MATCH_POLICY=y
-# CONFIG_NETFILTER_XT_MATCH_STATE is not set
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_NF_DEFRAG_IPV4=y
-CONFIG_NF_CONNTRACK_IPV4=y
-CONFIG_NF_CONNTRACK_PROC_COMPAT=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-# CONFIG_NF_NAT is not set
-CONFIG_IP_NF_MANGLE=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_ATM is not set
-# CONFIG_L2TP is not set
-CONFIG_STP=y
-CONFIG_BRIDGE=y
-CONFIG_BRIDGE_IGMP_SNOOPING=y
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_DECNET is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_PHONET is not set
-CONFIG_NET_SCHED=y
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=y
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_HFSC is not set
-CONFIG_NET_SCH_PRIO=y
-# CONFIG_NET_SCH_MULTIQ is not set
-CONFIG_NET_SCH_RED=y
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_TEQL is not set
-CONFIG_NET_SCH_TBF=y
-CONFIG_NET_SCH_GRED=y
-CONFIG_NET_SCH_DSMARK=y
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_DRR is not set
-CONFIG_NET_SCH_INGRESS=y
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=y
-CONFIG_NET_CLS_TCINDEX=y
-CONFIG_NET_CLS_ROUTE4=y
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=y
-CONFIG_NET_CLS_U32=y
-# CONFIG_CLS_U32_PERF is not set
-CONFIG_CLS_U32_MARK=y
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-CONFIG_NET_CLS_FLOW=y
-# CONFIG_NET_EMATCH is not set
-CONFIG_NET_CLS_ACT=y
-CONFIG_NET_ACT_POLICE=y
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_NAT is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_SIMP is not set
-# CONFIG_NET_ACT_SKBEDIT is not set
-CONFIG_NET_CLS_IND=y
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_WEXT_PRIV=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_LIB80211 is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
-
-#
-# Some wireless drivers require a rate control algorithm
-#
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_CAIF is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH=""
-# CONFIG_DEVTMPFS is not set
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-
-#
-# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
-#
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=1
-CONFIG_BLK_DEV_RAM_SIZE=2048
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI_MOD=y
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-CONFIG_NETDEVICES=y
-# CONFIG_IFB is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_ETHOC is not set
-# CONFIG_DNET is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_B44 is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851_MLL is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_NETDEV_10000 is not set
-CONFIG_WLAN=y
-# CONFIG_HOSTAP is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-# CONFIG_WAN is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_RAMOOPS is not set
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_CHARDEV is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-# CONFIG_I2C_SMBUS is not set
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_SPI is not set
-
-#
-# PPS support
-#
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-
-#
-# Memory mapped GPIO expanders:
-#
-# CONFIG_GPIO_IT8761E is not set
-
-#
-# I2C GPIO expanders:
-#
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_ADP5588 is not set
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-
-#
-# AC97 GPIO expanders:
-#
-
-#
-# MODULbus GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-CONFIG_MFD_SUPPORT=y
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_MEDIA_SUPPORT is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_RTC_CLASS is not set
-CONFIG_DMADEVICES=y
-# CONFIG_DMADEVICES_DEBUG is not set
-
-#
-# DMA Devices
-#
-# CONFIG_TIMB_DMA is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-CONFIG_FILE_LOCKING=y
-CONFIG_FSNOTIFY=y
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_HFSPLUS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_TRACE_IRQFLAGS_SUPPORT is not set
-CONFIG_PRINTK_TIME=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_STRIP_ASM_SYMS is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_LKDTM is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_TRACING_SUPPORT=y
-# CONFIG_FTRACE is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_EARLY_PRINTK=y
-# CONFIG_16KSTACKS is not set
-# CONFIG_OPTIMIZE_INLINING is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_DEFAULT_SECURITY_SELINUX is not set
-# CONFIG_DEFAULT_SECURITY_SMACK is not set
-# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_PCBC is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_BINARY_PRINTF is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_DMA=y
-CONFIG_NLATTR=y
-
-#
-# Quantenna
-#
-CONFIG_QUANTENNA_RUBY=y
-CONFIG_ARCH_RUBY_NUMA=y
-# CONFIG_QVSP is not set
-CONFIG_RUBY_PCIE_TARGET=y
-# CONFIG_RUBY_PCIE_HOST is not set
-CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
-# CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
-# CONFIG_ARCH_RUBY_EMAC_LIB is not set
-# CONFIG_ARCH_RUBY_EMAC is not set
-# CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
-
-#
-# Quantenna Topaz
-#
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
diff --git a/arch/arc/configs/qtm710_np_config b/arch/arc/configs/qtm710_np_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/qtm710_np_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/qtm710_rgmii_config b/arch/arc/configs/qtm710_rgmii_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/qtm710_rgmii_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/ruby_config b/arch/arc/configs/ruby_config
deleted file mode 120000
index 6d2d30b..0000000
--- a/arch/arc/configs/ruby_config
+++ /dev/null
@@ -1 +0,0 @@
-qhs710_vb_config
\ No newline at end of file
diff --git a/arch/arc/configs/qtm710_rc_config b/arch/arc/configs/topaz_dbdc_config
similarity index 94%
rename from arch/arc/configs/qtm710_rc_config
rename to arch/arc/configs/topaz_dbdc_config
index 5c01aab..c70bcb7 100644
--- a/arch/arc/configs/qtm710_rc_config
+++ b/arch/arc/configs/topaz_dbdc_config
@@ -1,5 +1,5 @@
 #
-# Used with Quantenna PCIe hosts: QTM710 Network Processor boards
+# This file is under the control of Perforce and determines the kernel configuration for Topaz / BBIC4.
 #
 # Linux kernel version: 2.6.35.12
 #
@@ -74,9 +74,10 @@
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
+CONFIG_DEFERRED_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_BASE_FULL is not set
@@ -213,18 +214,17 @@
 # Bus options (PCI etc.)
 #
 CONFIG_PCI=y
-CONFIG_ARCH_SUPPORTS_MSI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCI_IOV is not set
 # CONFIG_HOTPLUG_PCI is not set
+# CONFIG_PCIEPORTBUS is not set
 # CONFIG_PCCARD is not set
 CONFIG_ARCH_ARC_CURR_IN_REG=y
 # CONFIG_ARC_TLS_REG_EMUL is not set
 CONFIG_ARC_MISALIGNED_ACCESS=y
 # CONFIG_ARCH_ARC_SPACE_RND is not set
-# CONFIG_MMAP_CODE_CMN_VADDR is not set
+CONFIG_MMAP_CODE_CMN_VADDR=y
 CONFIG_HZ=200
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARC_STACK_NONEXEC=y
@@ -285,25 +285,16 @@
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 CONFIG_IPV6_ROUTER_PREF=y
-# CONFIG_IPV6_ROUTE_INFO is not set
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 # CONFIG_INET6_AH is not set
 # CONFIG_INET6_ESP is not set
 # CONFIG_INET6_IPCOMP is not set
-# CONIFG_IPV6_MIP6 is not set
 # CONFIG_INET6_XFRM_TUNNEL is not set
 # CONFIG_INET6_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 # CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 # CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_NDISC_NODETYPE is not set
 # CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_SUBTREES is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_PIMSM_V2 is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -375,28 +366,6 @@
 CONFIG_NET_SCHED=y
 
 #
-# IPv6: Netfilter Configuration
-#
-#
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_LOG is not set
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_SECURITY is not set
-
 # Queueing/Scheduling
 #
 CONFIG_NET_SCH_CBQ=y
@@ -613,7 +582,7 @@
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
@@ -632,7 +601,7 @@
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
+CONFIG_REALTEK_PHY=y
 # CONFIG_NATIONAL_PHY is not set
 # CONFIG_STE10XP is not set
 # CONFIG_LSI_ET1011C_PHY is not set
@@ -792,7 +761,6 @@
 #
 # I2C Hardware Bus support
 #
-
 #
 # PC SMBus host controller drivers
 #
@@ -1024,7 +992,7 @@
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -1032,7 +1000,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1164,20 +1132,28 @@
 #
 CONFIG_QUANTENNA_RUBY=y
 CONFIG_ARCH_RUBY_NUMA=y
-# CONFIG_QVSP is not set
+CONFIG_QVSP=y
 # CONFIG_RUBY_PCIE_TARGET is not set
-CONFIG_RUBY_PCIE_HOST=y
+# CONFIG_RUBY_PCIE_HOST is not set
+# CONFIG_TOPAZ_PCIE_TARGET is not set
+# CONFIG_TOPAZ_PCIE_HOST is not set
+CONFIG_TOPAZ_DBDC_HOST=y
 CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
+CONFIG_ARCH_RUBY_EMAC_LIB=m
+CONFIG_ARCH_RUBY_EMAC=m
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING=y
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
+# CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
 # CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
+CONFIG_SWITCH_RTL8363SB=m
 
 #
 # Quantenna Topaz
 #
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
+CONFIG_QUANTENNA_TOPAZ=y
+CONFIG_ARCH_TOPAZ_FWT=m
+CONFIG_ARCH_TOPAZ_TQE=m
+# CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
+CONFIG_ARCH_TOPAZ_EMAC=m
diff --git a/arch/arc/configs/topaz_fpga_config b/arch/arc/configs/topaz_fpga_config
index f654913..1b65a29 100644
--- a/arch/arc/configs/topaz_fpga_config
+++ b/arch/arc/configs/topaz_fpga_config
@@ -1065,3 +1065,4 @@
 # CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
 # CONFIG_TOPAZ_PCIE_TARGET is not set
 # CONFIG_TOPAZ_PCIE_HOST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
diff --git a/arch/arc/configs/topaz_host_config b/arch/arc/configs/topaz_host_config
index 2528ca3..2984cf7 100644
--- a/arch/arc/configs/topaz_host_config
+++ b/arch/arc/configs/topaz_host_config
@@ -1157,7 +1157,6 @@
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
 CONFIG_SWITCH_RTL8363SB=m
 
@@ -1171,3 +1170,4 @@
 CONFIG_ARCH_TOPAZ_EMAC=m
 # CONFIG_TOPAZ_PCIE_TARGET is not set
 CONFIG_TOPAZ_PCIE_HOST=y
+# CONFIG_TOPAZ_DBDC_HOST is not set
diff --git a/arch/arc/configs/qhs710_vb_config b/arch/arc/configs/topaz_msft_config
old mode 100644
new mode 100755
similarity index 97%
copy from arch/arc/configs/qhs710_vb_config
copy to arch/arc/configs/topaz_msft_config
index ca7c0fc..4924fd6
--- a/arch/arc/configs/qhs710_vb_config
+++ b/arch/arc/configs/topaz_msft_config
@@ -1,6 +1,5 @@
 #
-# This file is under the control of Perforce and determines the kernel configuration for Ruby / BBIC3.
-# Used with QHS710 Video Bridge and QTM710 Network Processor board types
+# This file is under the control of Perforce and determines the kernel configuration for Topaz / BBIC4.
 #
 # Linux kernel version: 2.6.35.12
 #
@@ -74,8 +73,8 @@
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_DEFERRED_PRINTK=y
@@ -219,7 +218,7 @@
 # CONFIG_ARC_TLS_REG_EMUL is not set
 CONFIG_ARC_MISALIGNED_ACCESS=y
 # CONFIG_ARCH_ARC_SPACE_RND is not set
-# CONFIG_MMAP_CODE_CMN_VADDR is not set
+CONFIG_MMAP_CODE_CMN_VADDR=y
 CONFIG_HZ=200
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARC_STACK_NONEXEC=y
@@ -555,7 +554,7 @@
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
@@ -573,7 +572,7 @@
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
+CONFIG_REALTEK_PHY=y
 # CONFIG_NATIONAL_PHY is not set
 # CONFIG_STE10XP is not set
 # CONFIG_LSI_ET1011C_PHY is not set
@@ -903,7 +902,7 @@
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -911,7 +910,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1046,21 +1045,25 @@
 CONFIG_QVSP=y
 # CONFIG_RUBY_PCIE_TARGET is not set
 # CONFIG_RUBY_PCIE_HOST is not set
+# CONFIG_TOPAZ_PCIE_TARGET is not set
+# CONFIG_TOPAZ_PCIE_HOST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
 CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
-CONFIG_ARCH_RUBY_EMAC_LIB=y
-CONFIG_ARCH_RUBY_EMAC=y
+CONFIG_ARCH_RUBY_EMAC_LIB=m
+CONFIG_ARCH_RUBY_EMAC=m
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING=y
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
+CONFIG_SWITCH_RTL8363SB=m
 
 #
 # Quantenna Topaz
 #
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
+CONFIG_QUANTENNA_TOPAZ=y
+CONFIG_ARCH_TOPAZ_FWT=m
+CONFIG_ARCH_TOPAZ_TQE=m
+# CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
+CONFIG_ARCH_TOPAZ_EMAC=m
diff --git a/arch/arc/configs/qhs710_vb_config b/arch/arc/configs/topaz_msmr_config
old mode 100644
new mode 100755
similarity index 97%
copy from arch/arc/configs/qhs710_vb_config
copy to arch/arc/configs/topaz_msmr_config
index ca7c0fc..4924fd6
--- a/arch/arc/configs/qhs710_vb_config
+++ b/arch/arc/configs/topaz_msmr_config
@@ -1,6 +1,5 @@
 #
-# This file is under the control of Perforce and determines the kernel configuration for Ruby / BBIC3.
-# Used with QHS710 Video Bridge and QTM710 Network Processor board types
+# This file is under the control of Perforce and determines the kernel configuration for Topaz / BBIC4.
 #
 # Linux kernel version: 2.6.35.12
 #
@@ -74,8 +73,8 @@
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_DEFERRED_PRINTK=y
@@ -219,7 +218,7 @@
 # CONFIG_ARC_TLS_REG_EMUL is not set
 CONFIG_ARC_MISALIGNED_ACCESS=y
 # CONFIG_ARCH_ARC_SPACE_RND is not set
-# CONFIG_MMAP_CODE_CMN_VADDR is not set
+CONFIG_MMAP_CODE_CMN_VADDR=y
 CONFIG_HZ=200
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARC_STACK_NONEXEC=y
@@ -555,7 +554,7 @@
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
@@ -573,7 +572,7 @@
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
+CONFIG_REALTEK_PHY=y
 # CONFIG_NATIONAL_PHY is not set
 # CONFIG_STE10XP is not set
 # CONFIG_LSI_ET1011C_PHY is not set
@@ -903,7 +902,7 @@
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -911,7 +910,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1046,21 +1045,25 @@
 CONFIG_QVSP=y
 # CONFIG_RUBY_PCIE_TARGET is not set
 # CONFIG_RUBY_PCIE_HOST is not set
+# CONFIG_TOPAZ_PCIE_TARGET is not set
+# CONFIG_TOPAZ_PCIE_HOST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
 CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
-CONFIG_ARCH_RUBY_EMAC_LIB=y
-CONFIG_ARCH_RUBY_EMAC=y
+CONFIG_ARCH_RUBY_EMAC_LIB=m
+CONFIG_ARCH_RUBY_EMAC=m
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING=y
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
+CONFIG_SWITCH_RTL8363SB=m
 
 #
 # Quantenna Topaz
 #
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
+CONFIG_QUANTENNA_TOPAZ=y
+CONFIG_ARCH_TOPAZ_FWT=m
+CONFIG_ARCH_TOPAZ_TQE=m
+# CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
+CONFIG_ARCH_TOPAZ_EMAC=m
diff --git a/arch/arc/configs/topaz_pcie_config b/arch/arc/configs/topaz_pcie_config
index 3ccc952..ee42e2e 100644
--- a/arch/arc/configs/topaz_pcie_config
+++ b/arch/arc/configs/topaz_pcie_config
@@ -1046,7 +1046,7 @@
 CONFIG_QVSP=y
 # CONFIG_RUBY_PCIE_TARGET is not set
 # CONFIG_RUBY_PCIE_HOST is not set
-CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
+# CONFIG_ARCH_RUBY_SRAM_IRQ_STACK is not set
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
 CONFIG_ARCH_RUBY_EMAC_LIB=m
 CONFIG_ARCH_RUBY_EMAC=m
@@ -1054,7 +1054,6 @@
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
 CONFIG_SWITCH_RTL8363SB=m
 
@@ -1068,3 +1067,4 @@
 CONFIG_ARCH_TOPAZ_TQE=m
 CONFIG_ARCH_TOPAZ_EMAC=m
 # CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
diff --git a/arch/arc/configs/qhs710_vb_config b/arch/arc/configs/topaz_rfic6_config
similarity index 97%
rename from arch/arc/configs/qhs710_vb_config
rename to arch/arc/configs/topaz_rfic6_config
index ca7c0fc..66e9102 100644
--- a/arch/arc/configs/qhs710_vb_config
+++ b/arch/arc/configs/topaz_rfic6_config
@@ -1,6 +1,5 @@
 #
-# This file is under the control of Perforce and determines the kernel configuration for Ruby / BBIC3.
-# Used with QHS710 Video Bridge and QTM710 Network Processor board types
+# This file is under the control of Perforce and determines the kernel configuration for Topaz / BBIC4.
 #
 # Linux kernel version: 2.6.35.12
 #
@@ -74,11 +73,11 @@
 CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
-CONFIG_DEFERRED_PRINTK=y
+CONFIG_DEFERRED_PRINTK=n
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_BASE_FULL is not set
@@ -219,7 +218,7 @@
 # CONFIG_ARC_TLS_REG_EMUL is not set
 CONFIG_ARC_MISALIGNED_ACCESS=y
 # CONFIG_ARCH_ARC_SPACE_RND is not set
-# CONFIG_MMAP_CODE_CMN_VADDR is not set
+CONFIG_MMAP_CODE_CMN_VADDR=y
 CONFIG_HZ=200
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_ARC_STACK_NONEXEC=y
@@ -555,7 +554,7 @@
 CONFIG_NETDEVICES=y
 # CONFIG_IFB is not set
 # CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
+CONFIG_BONDING=m
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
@@ -573,7 +572,7 @@
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
+CONFIG_REALTEK_PHY=y
 # CONFIG_NATIONAL_PHY is not set
 # CONFIG_STE10XP is not set
 # CONFIG_LSI_ET1011C_PHY is not set
@@ -903,7 +902,7 @@
 # CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
@@ -911,7 +910,7 @@
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_LKDTM is not set
 # CONFIG_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
@@ -1046,21 +1045,25 @@
 CONFIG_QVSP=y
 # CONFIG_RUBY_PCIE_TARGET is not set
 # CONFIG_RUBY_PCIE_HOST is not set
+# CONFIG_TOPAZ_PCIE_TARGET is not set
+# CONFIG_TOPAZ_PCIE_HOST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
 CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
-CONFIG_ARCH_RUBY_EMAC_LIB=y
-CONFIG_ARCH_RUBY_EMAC=y
+CONFIG_ARCH_RUBY_EMAC_LIB=m
+CONFIG_ARCH_RUBY_EMAC=m
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING=y
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
-# CONFIG_SWITCH_RTL8363SB is not set
+CONFIG_SWITCH_RTL8363SB=m
 
 #
 # Quantenna Topaz
 #
-# CONFIG_QUANTENNA_TOPAZ is not set
-# CONFIG_TOPAZ_PCIE_TARGET is not set
-# CONFIG_TOPAZ_PCIE_HOST is not set
+CONFIG_QUANTENNA_TOPAZ=y
+CONFIG_ARCH_TOPAZ_FWT=m
+CONFIG_ARCH_TOPAZ_TQE=m
+# CONFIG_ARCH_TOPAZ_SWITCH_TEST is not set
+CONFIG_ARCH_TOPAZ_EMAC=m
diff --git a/arch/arc/configs/topaz_vb_config b/arch/arc/configs/topaz_vb_config
index 998a876..4924fd6 100644
--- a/arch/arc/configs/topaz_vb_config
+++ b/arch/arc/configs/topaz_vb_config
@@ -1047,6 +1047,7 @@
 # CONFIG_RUBY_PCIE_HOST is not set
 # CONFIG_TOPAZ_PCIE_TARGET is not set
 # CONFIG_TOPAZ_PCIE_HOST is not set
+# CONFIG_TOPAZ_DBDC_HOST is not set
 CONFIG_ARCH_RUBY_SRAM_IRQ_STACK=y
 # CONFIG_KERNEL_TEXT_SNAPSHOTS is not set
 CONFIG_ARCH_RUBY_EMAC_LIB=m
@@ -1055,7 +1056,6 @@
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_BURST_SIZE=48
 CONFIG_ARCH_RUBY_EMAC_SMOOTHING_RATE=50000
 # CONFIG_QUANTENNA_RESTRICT_WLAN_IP is not set
-CONFIG_QUANTENNA_RESTRICT_OWN_IP=0x02AF800A
 # CONFIG_SWITCH_RTL8365MB is not set
 CONFIG_SWITCH_RTL8363SB=m
 
diff --git a/arch/arc/configs/topaz_vzn_config b/arch/arc/configs/topaz_vzn_config
new file mode 120000
index 0000000..2d5890a
--- /dev/null
+++ b/arch/arc/configs/topaz_vzn_config
@@ -0,0 +1 @@
+topaz_vb_config
\ No newline at end of file
diff --git a/arch/arc/include/asm/mem.h b/arch/arc/include/asm/mem.h
index d5a1193..1e90471 100755
--- a/arch/arc/include/asm/mem.h
+++ b/arch/arc/include/asm/mem.h
@@ -42,16 +42,12 @@
 #define DMA_NOCACHE_END		(PAGE_OFFSET)
 
 /* PCI remapping */
-#define PCI_REMAP_SIZE		(512*1024*1024)
+#define PCI_REMAP_SIZE		(320*1024*1024)
 #define PCI_REMAP_START		(DMA_NOCACHE_START - PCI_REMAP_SIZE)
 #define PCI_REMAP_END		(DMA_NOCACHE_START)
 
 /* FIXME: this is done to accomodate 64MB DDR systems */
-#if defined (CONFIG_RUBY_PCIE_HOST)
-#define VMALLOC_SIZE		(128*1024*1024)
-#else
-#define VMALLOC_SIZE		(48*1024*1024)
-#endif
+#define VMALLOC_SIZE		(192*1024*1024)
 #define VMALLOC_START	(PCI_REMAP_START - VMALLOC_SIZE)
 #define VMALLOC_END		(PCI_REMAP_START)
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
diff --git a/arch/arc/kernel/module.c b/arch/arc/kernel/module.c
index f6d392c..61c4e51 100755
--- a/arch/arc/kernel/module.c
+++ b/arch/arc/kernel/module.c
@@ -237,7 +237,6 @@
 {
 	s_memlist.next = NULL;
 
-#ifdef TOPAZ_PLATFORM
 	void *heapbegin = roundmb(&__sram_end);
 #ifdef QTN_RC_ENABLE_HDP
 	void *heapend = truncmb(RUBY_SRAM_BEGIN + CONFIG_ARC_SRAM_END);
@@ -245,30 +244,12 @@
 	void *heapend = truncmb(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B2_END);
 #endif
 
-	printk(KERN_INFO"Topaz heap in SRAM %p<->%p\n",
-		heapbegin, heapend);
+	printk(KERN_INFO"Topaz heap in SRAM %p<->%p, B2 BASE %x\n",
+		heapbegin, heapend, CONFIG_ARC_KERNEL_SRAM_B2_BASE);
 
 	if (heapbegin < heapend) {
 		qtn_new_memblock_init(NULL, heapbegin, heapend);
 	}
-#else
-	void *heapbegin1 = roundmb(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B2_BASE);
-	void *heapend1 = truncmb(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B2_END);
-	void *heapbegin2 = roundmb(&__sram_end);
-	void *heapend2 = truncmb(RUBY_SRAM_BEGIN + CONFIG_ARC_KERNEL_SRAM_B1_END);
-	struct memblock *pmblock = NULL;
-
-	printk(KERN_INFO"Ruby heap in SRAM %p<->%p, %p<->%p\n",
-		heapbegin1, heapend1, heapbegin2, heapend2);
-
-	if (heapbegin1 < heapend1) {
-		pmblock = qtn_new_memblock_init(pmblock, heapbegin1, heapend1);
-	}
-
-	if (heapbegin2 < heapend2) {
-		pmblock = qtn_new_memblock_init(pmblock, heapbegin2, heapend2);
-	}
-#endif
 
 	return 0;
 }
@@ -407,6 +388,8 @@
 	/* Acquire memory from system */
 	if((pmem = (struct memblock *) qtn_memget(nbytes)) == NULL)
 	{
+		printk(KERN_DEBUG"Warning: %s failed to allocate 0x%x bytes from caller %p\n", __func__,
+				nbytes, __builtin_return_address(0));
 		return(NULL);
 	}
 
diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
index dd57905..535eb3d 100755
--- a/arch/arc/kernel/time.c
+++ b/arch/arc/kernel/time.c
@@ -36,9 +36,7 @@
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 
-#ifdef TOPAZ_PLATFORM
 #include <qtn/topaz_hbm.h>
-#endif
 /* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
  * Each can programmed to go from @count to @limit and optionally
  * interrupt when that happens
@@ -153,9 +151,7 @@
 
     pet_watchdog_timer();
     arc_timer0_ack_event(evt->mode == CLOCK_EVT_MODE_PERIODIC);
-#ifdef TOPAZ_PLATFORM
     topaz_hbm_filter_txdone_pool();
-#endif
     evt->event_handler(evt);
     return IRQ_HANDLED;
 }
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index eda8307..d981025 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -24,6 +24,11 @@
 #include <asm/board/kdump.h>
 #include <asm/board/troubleshoot.h>
 #include <asm/cacheflush.h>
+#include <linux/vmalloc.h>
+#include <linux/zlib.h>
+
+/* 3.4 times seems safe for LHost crash - found by trial and error */
+#define LHOST_CORE_DUMP_COMPRESS_RATIO	(340)
 
 static void show_ecr_verbose(struct pt_regs *regs, unsigned long address, unsigned int cause_reg);
 static void show_task_ecr_verbose(struct pt_regs *regs);
@@ -33,7 +38,7 @@
 #define MAX_GUEST_TROUBLESHOOT	1
 static void (*kdump_guest_troubleshooters[MAX_GUEST_TROUBLESHOOT])(void);
 
-static kdump_guest_troubleshooters_run(void)
+static void kdump_guest_troubleshooters_run(void)
 {
 	int i;
 
@@ -62,7 +67,7 @@
  * we simply loop otherwise gcc generates 13 calls to printk each with it's
  * own arg setup
  */
-void noinline print_reg_file(unsigned long *last_reg, int num)
+void noinline print_reg_file(long *last_reg, int num)
 {
     unsigned int i;
 
@@ -135,6 +140,7 @@
     }
     else printk("@No matching VMA found\n");
 }
+
 void show_stack_fragment(u32 sp)
 {
 	const u32 print_past_sp   = 512;
@@ -344,7 +350,7 @@
 			}
 		}
 	} else if (!is_valid_mem_addr(ret)) {
-		printk("Not a valid memory address to fetch (%08X)\n", ret);
+		printk("Not a valid memory address to fetch (%08lx)\n", ret);
 	} else {
 		/* Single valid address - dump four bytes. Should be safe... */
 		int i;
@@ -357,7 +363,7 @@
 }
 
 
-static void show_ruby_soc_registers()
+static void show_ruby_soc_registers(void)
 {
 	unsigned long base_addr = RUBY_SYS_CTL_BASE_ADDR;
 	/* Registers up to offset 0x8C are contiguous, then from 0x94 to 0xC0 */
@@ -400,38 +406,212 @@
 }
 EXPORT_SYMBOL(arc_set_troubleshoot_start_hook);
 
-void save_printk_sram(void)
+static int32_t compress_circular_buffer(char *p_log, uint32_t log_start, uint32_t log_end, uint32_t log_size, char *buf_out,
+					uint32_t len_buf_out, uint32_t *len_compress_data)
 {
-	char *sp = (char *)s_sram_start;
-	int log_start = 0;
-	int log_end = 0;
-	int log_size = 0;
-	char *p_log = NULL;
+	int32_t retval = -1;
+	int32_t zlib_retval;
+	int32_t workspace_size;
+	z_stream stream;
 
-	if (sf_troubleshoot_start) {
-		sf_troubleshoot_start(sp_troubleshoot_ctx);
+	if (!len_compress_data) {
+		printk(KERN_ERR "%s: len_compress_data is NULL\n", __func__);
+		return -EINVAL;
 	}
 
+	*len_compress_data = 0;
+
+	workspace_size = zlib_deflate_workspacesize();
+	printk(KERN_DEBUG "%s: workspace_size = %d\n", __func__, workspace_size);
+
+	stream.workspace = vmalloc(workspace_size);
+        if (!stream.workspace) {
+		printk(KERN_ERR "%s: Failed to allocate %d bytes for deflate workspace\n", __func__,
+			zlib_deflate_workspacesize());
+		return -ENOMEM;
+	}
+
+	/* Use zlib format because gzip is not available */
+	zlib_retval = zlib_deflateInit(&stream, Z_DEFAULT_COMPRESSION);
+	if (zlib_retval != Z_OK) {
+                printk(KERN_ERR "%s: zlib_deflateInit failed, zlib_retval = %d\n", __func__, zlib_retval);
+		vfree(stream.workspace);
+		return retval;
+	}
+
+	if (log_start <= log_end) {
+		/* Compress the complete data in 1 pass */
+		stream.next_in = (Byte *) p_log + log_start;
+		stream.avail_in = log_end - log_start + 1;
+		stream.total_in = 0;
+
+		stream.next_out = (Byte *) buf_out;
+		stream.avail_out = len_buf_out;
+		stream.total_out = 0;
+
+		zlib_retval = zlib_deflate(&stream, Z_FINISH);
+		if (zlib_retval != Z_STREAM_END) {
+			if (zlib_retval != Z_OK) {
+				printk(KERN_ERR "%s: zlib_deflate failed (only chunk), zlib_retval = %d\n",
+					__func__, zlib_retval);
+				goto deflate_end;
+			}
+
+			printk(KERN_WARNING "%s: zlib_deflate (only chunk): some data would be missing\n",
+				__func__);
+		}
+
+		/*
+		 * If stream.avail_in is not 0, some logs could be missing; we should recheck len_max_input in
+		 * arc_save_to_sram_safe_area()
+		 */
+		if (stream.avail_in != 0)
+			printk(KERN_WARNING "%s: stream.avail_in (%u) is not 0\n", __func__, stream.avail_in);
+	} else {
+		/* Compress the complete data in 2 passes */
+
+		/* Compress the first chunk; from log_start to the end of the buffer */
+		stream.next_in = (Byte *) p_log + log_start;
+		stream.avail_in = log_size - log_start;
+		stream.total_in = 0;
+
+		stream.next_out = (Byte *) buf_out;
+		stream.avail_out = len_buf_out;
+		stream.total_out = 0;
+
+		zlib_retval = zlib_deflate(&stream, Z_SYNC_FLUSH);
+		if (zlib_retval != Z_OK) {
+			printk(KERN_ERR "%s: zlib_deflate failed (first chunk), zlib_retval = %d\n", __func__,
+				zlib_retval);
+			goto deflate_end;
+		}
+
+		/*
+		 * If stream.avail_in is not 0, some logs could be missing; we should recheck len_max_input in
+		 * arc_save_to_sram_safe_area()
+		 */
+		if (stream.avail_in != 0)
+			printk(KERN_WARNING "%s: stream.avail_in (%u) is not 0\n", __func__, stream.avail_in);
+
+		/* Compress the second chunk; from the start of the buffer to log_end */
+		stream.next_in = (Byte *) p_log;
+		stream.avail_in = log_end;
+		stream.total_in = 0;
+
+		/*
+		 * No need to change next_out, avail_out and total_out as zlib_deflate() above has set them
+		 * to appropriate values
+		 */
+
+		zlib_retval = zlib_deflate(&stream, Z_FINISH);
+		if (zlib_retval != Z_STREAM_END) {
+			if (zlib_retval != Z_OK) {
+				printk(KERN_ERR "%s: zlib_deflate failed (second chunk), zlib_retval = %d\n",
+					__func__, zlib_retval);
+				goto deflate_end;
+			}
+
+			printk(KERN_WARNING "%s: zlib_deflate (second chunk): some data would be missing\n",
+				__func__);
+		}
+
+		/*
+		 * If stream.avail_in is not 0, some logs could be missing; we should recheck len_max_input in
+		 * arc_save_to_sram_safe_area()
+		 */
+		if (stream.avail_in != 0)
+			printk(KERN_WARNING "%s: stream.avail_in (%u) is not 0\n", __func__, stream.avail_in);
+	}
+
+	*len_compress_data = stream.total_out;
+	printk(KERN_DEBUG "%s: compressed data length = %u\n", __func__, *len_compress_data);
+
+	retval = 0;
+
+deflate_end:
+	zlib_retval = zlib_deflateEnd(&stream);
+	if (zlib_retval != Z_OK) {
+		printk(KERN_WARNING "%s: zlib_deflateEnd failed, zlib_retval = %d\n", __func__, zlib_retval);
+	}
+
+	vfree(stream.workspace);
+
+	return retval;
+}
+
+/* Save the printk circular buffer to the SRAM safe area */
+void arc_save_to_sram_safe_area(int compress_ratio)
+{
+	uint32_t log_start = 0;
+	uint32_t log_end = 0;
+	uint32_t log_size = 0;
+	char *p_log = NULL;
+	uint32_t len_max_input;
+	uint32_t extra_margin;
+	uint32_t len_compress_data;
+
+	if (sf_troubleshoot_start)
+		sf_troubleshoot_start(sp_troubleshoot_ctx);
+
 	get_log_buf(&log_end, &log_size, &p_log);
 
-	if (!log_size)
+	/* Ensure that there is something in the printk circular buffer */
+	if (!log_size) {
+		printk("%s: log_size is 0\n", __func__);
 		return;
-
-	if (log_end >= log_size)
-		log_start = log_end - log_size;
-
-	if ((log_end - log_start) >= s_sram_safe_size)
-		log_start = log_end - s_sram_safe_size;
-
-	while (log_start != log_end) {
-		*sp++ = *(p_log + (log_start++ & (log_size - 1)));
 	}
 
-	/* Magic number goes almost at the end of the buffer */
-	sp = (char *)s_sram_start + (s_sram_safe_size - 1);
-	*sp = QTN_SAFE_SRAM_MAGIC;
+	if (!log_end) {
+		printk("%s: log_end is 0\n", __func__);
+		return;
+	}
+
+	/* Expecting s_sram_start to be 2 byte aligned */
+	if ((s_sram_start & 0x1) != 0) {
+		printk("%s: s_sram_start (%lu) is not 2 bytes aligned\n", __func__, s_sram_start);
+		return;
+	}
+
+	/* Find the max input length that could be fed into the compression algo */
+	len_max_input = (compress_ratio * s_sram_safe_size) / 100;
+	if (len_max_input > log_size)
+		len_max_input = log_size;
+
+	/* log_end points one ahead of the last valid character i.e. where the next character would be written */
+	if (log_end > len_max_input) {
+		log_start = log_end - len_max_input;
+	}
+
+	/* Refer to include/linux/zlib.h */
+	extra_margin = (log_end - log_start) - (((log_end - log_start) * 1000) / 1001) + 12;
+
+	log_start += extra_margin;
+
+	/*
+	 * log_start and log_end are always incremented; we need to find offsets into the printk
+	 * circular buffer corresponding to them
+	 */
+	log_start = log_start & (log_size - 1);
+	log_end = (log_end - 1) & (log_size - 1);
+
+	/*
+	 * Compress the printk circular buffer and store it in SRAM safe aread (so as to retrieve it on the
+	 * next reboot)
+	 *
+	 * Format of buffer:
+	 *	2 bytes: Header (HEADER_CORE_DUMP)
+	 *	2 bytes: Length of the compressed logs (n)
+	 *	n bytes: Compressed logs
+	 */
+	compress_circular_buffer(p_log, log_start, log_end, log_size, (char *) (s_sram_start + 4),
+					s_sram_safe_size - 4, &len_compress_data);
+
+	*((uint16_t *) s_sram_start) = HEADER_CORE_DUMP;
+	*((uint16_t *) (s_sram_start + 2)) = (uint16_t) len_compress_data;
+
 	flush_dcache_all();
 }
+EXPORT_SYMBOL(arc_save_to_sram_safe_area);
 
 void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
 	unsigned long address, unsigned long cause_reg)
@@ -469,7 +649,8 @@
 	sort_snaps(1);
 
 	kdump_guest_troubleshooters_run();
-	save_printk_sram();
+
+	arc_save_to_sram_safe_area(LHOST_CORE_DUMP_COMPRESS_RATIO);
 }
 
 
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S
index 8f35ff6..2e57166 100755
--- a/arch/arc/kernel/vmlinux.lds.S
+++ b/arch/arc/kernel/vmlinux.lds.S
@@ -75,8 +75,6 @@
         __sram_start = .;
         __sram_datatext_start = .;
 
-        . = ALIGN(THREAD_SIZE);
-        *(.ksoftirqd.stack)
 #ifdef CONFIG_ARCH_RUBY_SRAM_IRQ_STACK
         __irq_stack_begin = .;
         . = . + THREAD_SIZE + TOPAZ_CACHE_WAR_OFFSET;
@@ -105,6 +103,10 @@
 
         __sram_bss_start = .;
         *(.sram.bss)
+#ifdef CONFIG_TOPAZ_PCIE_TARGET
+	. = ALIGN(THREAD_SIZE);
+	*(.ksoftirqd.stack)
+#endif
         __sram_bss_end = .;
 
         __sram_end = .;
@@ -141,8 +143,12 @@
 
     _edata = .;
 
-    BSS_SECTION(0, 0, 0)
 
+    BSS_SECTION(0, 0, 0)
+#ifndef CONFIG_TOPAZ_PCIE_TARGET
+    . = ALIGN(THREAD_SIZE);
+    .ksoftirqd.stack : { *(.ksoftirqd.stack) }
+#endif
     . = ALIGN(PAGE_SIZE);
     __start_unwind = .;
     .debug_frame  : { *(.debug_frame) }
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 64be466..acd38c8 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -949,6 +949,9 @@
 				phydev->adjust_link(phydev->attached_dev);
 			}
 			break;
+		case PHY_QTNPM:
+			needs_aneg = 1;
+			break;
 	}
 
 	mutex_unlock(&phydev->lock);
diff --git a/drivers/ruby/Kconfig b/drivers/ruby/Kconfig
index dfe0b55..345a095 100644
--- a/drivers/ruby/Kconfig
+++ b/drivers/ruby/Kconfig
@@ -41,6 +41,10 @@
 	bool "Include generic PCIe driver"
 	default y
 
+config TOPAZ_DBDC_HOST
+	bool "include topaz DBDC host interface for TOPAZ RC Host"
+	help
+	  A build for a board with a topaz RC Host support for DBDC must select this option
 
 config ARCH_RUBY_SRAM_IRQ_STACK
 	bool "Use dedicated SRAM stack for interrupts" if (!ARCH_ARC_LV2_INTR && ARCH_ARC_CURR_IN_REG && !PREEMPT)
@@ -102,11 +106,6 @@
 	Restrict the incoming IP traffic on the WLAN interface to prevent access to the
 	bridge interface on RGMII boards.
 
-config QUANTENNA_RESTRICT_OWN_IP
-	hex "The IP address to restrict access to"
-	default 0x02AF800A
-	depends on QUANTENNA_RESTRICT_WLAN_IP
-
 config SWITCH_RTL8365MB
 	tristate "Realtek RTL8365MB switch"
 	default n
diff --git a/drivers/ruby/arasan_emac_ahb.c b/drivers/ruby/arasan_emac_ahb.c
index 54e1445..fc00fec 100644
--- a/drivers/ruby/arasan_emac_ahb.c
+++ b/drivers/ruby/arasan_emac_ahb.c
@@ -149,7 +149,7 @@
 	}
 	if (!skb) {
 		size_t size;
-#if defined(TOPAZ_PLATFORM) && TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT
+#if TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT
 		size = TOPAZ_HBM_BUF_EMAC_RX_SIZE / 2;
 #else
 		size = qtn_rx_buf_size();
@@ -1036,7 +1036,7 @@
 
 	emac_lib_phy_start(dev);
 	netif_start_queue(dev);
-	emac_lib_pm_add_notifier(dev);
+	emac_lib_pm_emac_add_notifier(dev);
 
 	return 0;
 
@@ -1049,7 +1049,7 @@
 {
 	struct emac_private *arap = netdev_priv(dev);
 
-	emac_lib_pm_remove_notifier(dev);
+	emac_lib_pm_emac_remove_notifier(dev);
 
 	napi_disable(&arap->napi);
 
diff --git a/drivers/ruby/board_config.c b/drivers/ruby/board_config.c
index e551a73..08841a3 100644
--- a/drivers/ruby/board_config.c
+++ b/drivers/ruby/board_config.c
@@ -30,6 +30,7 @@
 static int			global_spi_protect_mode = 0;
 static int			g_slow_ethernet = 0;
 static const board_cfg_t	g_board_cfg_table[] = QTN_BOARD_DB;
+static ruby_bda_t bda_copy;
 
 #define MEM_SIZE_128MB (128 * 1024 * 1024)
 
@@ -74,17 +75,18 @@
 void __init
 qtn_set_spi_protect_config(u32 mode)
 {
-        global_spi_protect_mode = mode;
+	global_spi_protect_mode = mode;
 }
 
 int qtn_get_spi_protect_config(void)
 {
-        return global_spi_protect_mode;
+	return global_spi_protect_mode;
 }
 EXPORT_SYMBOL(qtn_get_spi_protect_config);
 
-static ruby_bda_t *get_bda(void) {
-	return (ruby_bda_t *)(CONFIG_ARC_CONF_BASE);
+static const ruby_bda_t *get_bda(void)
+{
+	return &bda_copy;
 }
 
 static int
@@ -132,9 +134,9 @@
 
 	  case BOARD_CFG_FLASH_SIZE:
 		{
-			ruby_bda_t *bda = get_bda();
-			if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
-				*p_board_config_value = bda->bda_flashsz;
+			if (global_board_id == QTN_RUBY_AUTOCONFIG_ID ||
+					global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
+				*p_board_config_value = get_bda()->bda_flashsz;
 			} else {
 				*p_board_config_value = 0;
 			}
@@ -160,14 +162,10 @@
 		return( -1 );
 	}
 
-	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
-		ruby_bda_t *bda = get_bda();
-
-		/* need to fixup address VA on LHOST as it may be different to one on uboot */
-		bda->bda_boardcfg.bc_name = bda->bda_boardname;
-
-		return lookup_config(&bda->bda_boardcfg,
-			board_config_param, p_board_config_value );
+	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID ||
+			global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
+		return lookup_config(&get_bda()->bda_boardcfg, board_config_param,
+					p_board_config_value);
 	}
 	//printk("get_board_config:board ID %d param %d\n",global_board_id,board_config_param);
 	for (iter = 0; iter < sizeof( g_board_cfg_table ) / sizeof( g_board_cfg_table[ 0 ] ) && (found_entry == 0); iter++) {
@@ -219,41 +217,51 @@
 EXPORT_SYMBOL(board_napi_budget);
 
 int
-get_all_board_params( char *p )
+get_all_board_params(char *p)
 {
 	int iter;
-	char *temp=p;
-	board_cfg_t *board = NULL;
+	int ch_printed;
+	const board_cfg_t *board = NULL;
 
-	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID || global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
-		ruby_bda_t *bda = (ruby_bda_t *)(CONFIG_ARC_CONF_BASE);
-		board = &bda->bda_boardcfg;
+	if (global_board_id == QTN_RUBY_AUTOCONFIG_ID ||
+			global_board_id == QTN_RUBY_UNIVERSAL_BOARD_ID) {
+		board = &get_bda()->bda_boardcfg;
 	} else {
-		for (iter = 0; iter < sizeof( g_board_cfg_table ) / sizeof( g_board_cfg_table[ 0 ] ); iter++) {
-			if (global_board_id == g_board_cfg_table[ iter ].bc_board_id) {
-				board = (board_cfg_t *)&g_board_cfg_table[ iter ];
+		for (iter = 0; iter < ARRAY_SIZE(g_board_cfg_table); iter++) {
+			if (global_board_id == g_board_cfg_table[iter].bc_board_id) {
+				board = &g_board_cfg_table[iter];
 				break;
 			}
 		}
 	}
 
-	if (board) {
-		temp += sprintf( temp, "board_id\t%d\n", board->bc_board_id);
-			temp += sprintf( temp, "name\t%s\n", board->bc_name);
-			temp += sprintf( temp, "ddr_type\t%d\n", board->bc_ddr_type);
-			temp += sprintf( temp, "ddr_speed\t%d\n", board->bc_ddr_speed);
-			temp += sprintf( temp, "ddr_size\t%d\n", board->bc_ddr_size);
-			temp += sprintf( temp, "emac0\t%d\n", board->bc_emac0);
-			temp += sprintf( temp, "emac1\t%d\n", board->bc_emac1);
-			temp += sprintf( temp, "phy0_addr\t%d\n", board->bc_phy0_addr);
-			temp += sprintf( temp, "phy1_addr\t%d\n", board->bc_phy1_addr);
-			temp += sprintf( temp, "spi1\t%d\n", board->bc_spi1);
-			temp += sprintf( temp, "wifi_hw\t%d\n", board->bc_wifi_hw);
-			temp += sprintf( temp, "uart1\t%d\n", board->bc_uart1);
-			temp += sprintf( temp, "bd_pcie\t%d\n", board->bc_pcie);
-			temp += sprintf( temp, "rgmii_timing\t%d\n", board->bc_rgmii_timing);
-		}
-	return (temp-p);
+	if (!board)
+		return 0;
+
+	ch_printed = snprintf(p, PAGE_SIZE,
+				"board_id\t%d\n"
+				"name\t%s\n"
+				"ddr_type\t%d\n"
+				"ddr_speed\t%d\n"
+				"ddr_size\t%d\n"
+				"emac0\t%d\n"
+				"emac1\t%d\n"
+				"phy0_addr\t%d\n"
+				"phy1_addr\t%d\n"
+				"spi1\t%d\n"
+				"wifi_hw\t%d\n"
+				"uart1\t%d\n"
+				"bd_pcie\t%d\n"
+				"rgmii_timing\t%d\n",
+				board->bc_board_id, board->bc_name,
+				board->bc_ddr_type, board->bc_ddr_speed, board->bc_ddr_size,
+				board->bc_emac0, board->bc_emac1, board->bc_phy0_addr,
+				board->bc_phy1_addr, board->bc_spi1, board->bc_wifi_hw,
+				board->bc_uart1, board->bc_pcie, board->bc_rgmii_timing);
+	if (ch_printed < 0)
+		ch_printed = 0;
+
+	return ch_printed;
 }
 EXPORT_SYMBOL(get_all_board_params);
 
@@ -281,4 +289,12 @@
 
 	/* update DDR size */
 	update_ddr_size();
+
+	/*
+	 * Copy bda structure so that it doesn't get overwritten by an A-MSDU with
+	 * a size greater than CONFIG_ARC_CONF_SIZE
+	 */
+	memcpy(&bda_copy, (void *)CONFIG_ARC_CONF_BASE, sizeof(bda_copy));
+	bda_copy.bda_boardcfg.bc_name = bda_copy.bda_boardname;
 }
+
diff --git a/drivers/ruby/emac_lib.c b/drivers/ruby/emac_lib.c
index 872c271..d74559a 100644
--- a/drivers/ruby/emac_lib.c
+++ b/drivers/ruby/emac_lib.c
@@ -54,16 +54,13 @@
 #define PHY_PW_PROC_FILE_NAME	"phy_pw"
 #define PHY_PW_CMD_MAX_LEN	20
 
-static inline bool emac_lib_rtl_switch(uint32_t cfg)
-{
-	return cfg & (EMAC_PHY_RTL8363SB_P0 | EMAC_PHY_RTL8363SB_P1 | EMAC_PHY_RTL8365MB);
-}
-
 static int mdio_use_noops = 0;
 module_param(mdio_use_noops, int, 0);
 int mdc_clk_divisor = 1;
 module_param(mdc_clk_divisor, int, 0644);
 
+static uint32_t emac_lib_dual_emac;
+
 static ssize_t show_mdio_use_noops(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	return snprintf(buf, PAGE_SIZE, "%d\n", mdio_use_noops);
@@ -186,7 +183,8 @@
 		ret = 0;
 	} else if(time_after_eq(jiffies + msecs_to_jiffies(ms_warn), deadline)) {
 		if (func) {
-			printk(KERN_WARNING "%s %s: warn: system is overloaded : spend more ~%lums!\n",
+			if (printk_ratelimit())
+				printk(KERN_WARNING "%s %s: warn: system is overloaded : spend more ~%lums!\n",
 					privc->dev->name, func, ms_warn);
 		}
 	}
@@ -269,36 +267,6 @@
 			printk(KERN_WARNING "%s: Speed (%d) is not supported\n", dev->name, speed);
 			break;
 	}
-
-#ifndef TOPAZ_PLATFORM
-	/*
-	 * These flags impact on peak EMAC performance on Topaz boards,
-	 * however these are required for ZPER on Ruby
-	 */
-
-	val = emac_rd(privc, EMAC_MAC_TX_CTRL);
-	if (duplex == DUPLEX_FULL) {
-		val &= ~MacTxAutoRetry;
-	} else {
-		val |= MacTxAutoRetry;
-	}
-	emac_wr(privc, EMAC_MAC_TX_CTRL, val);
-
-	val = emac_rd(privc, EMAC_DMA_CONFIG);
-	if (speed == SPEED_1000) {
-		/*
-		 * Without this settings we see dropped frames in case of bidir traffic.
-		 * Settings this bit cause EMAC performance degradation, but in case of 1G phy
-		 * we cannot reach maximum level even after degradation.
-		 */
-		emac_wr(privc, EMAC_DMA_CONFIG, val | DmaWait4Done);
-	} else {
-		/*
-		 * Reset bit, otherwise maximum rate is degraded.
-		 */
-		emac_wr(privc, EMAC_DMA_CONFIG, val & ~DmaWait4Done);
-	}
-#endif
 }
 
 static void emac_lib_adjust_link(struct net_device *dev)
@@ -972,37 +940,6 @@
 }
 EXPORT_SYMBOL(emac_lib_set_rx_mode);
 
-static void emac_update_phydev_state_queue(struct net_device *dev, int to_enable)
-{
-	int i, j;
-	struct emac_common * privc = netdev_priv(dev);
-
-	if (!privc)
-		return;
-
-	for (i = 0; i < PHY_MAX_ADDR; i++) {
-		struct phy_device *pdev = privc->mii_bus->phy_map[i];
-		int in_use = 0;
-
-		if (!pdev)
-			continue;
-
-		for (j = 0; j < ARRAY_SIZE(phydev_addr_inuse); j++) {
-			if (phydev_addr_inuse[j] == pdev->addr) {
-				in_use = 1;
-				break;
-			}
-		}
-
-		if (in_use) {
-			if (!to_enable)
-				cancel_delayed_work_sync(&pdev->state_queue);
-			else
-				schedule_delayed_work(&pdev->state_queue, HZ);
-		}
-	}
-}
-
 static void emac_pm_enter_to_halt(struct phy_device *phy_dev)
 {
 	if (phy_dev && phy_dev->state != PHY_HALTED) {
@@ -1023,6 +960,17 @@
 	mdelay(50);
 }
 
+static unsigned long emac_pm_power_save_level = PM_QOS_DEFAULT_VALUE;
+static int emac_pm_adjust_level(const int pm_emac_level, struct phy_device *phy_dev)
+{
+	if (pm_emac_level != BOARD_PM_LEVEL_NO &&
+			(phy_dev->state == PHY_HALTED || emac_lib_dual_emac)) {
+		return pm_emac_level;
+	}
+
+	return emac_pm_power_save_level;
+}
+
 static void emac_pm_level(struct emac_common *arapc, int level)
 {
 	struct phy_device *phy_dev = arapc->phy_dev;
@@ -1033,7 +981,7 @@
 		return;
 	}
 
-	emac_update_phydev_state_queue(arapc->dev, 0);
+	level = emac_pm_adjust_level(level, phy_dev);
 
 	if (level >= BOARD_PM_LEVEL_SUSPEND) {
 		if (phy_dev->state != PHY_HALTED) {
@@ -1042,7 +990,6 @@
 			printk(KERN_INFO "%s: emac halted\n", DRV_NAME);
 		}
 	} else if (level >= BOARD_PM_LEVEL_IDLE) {
-
 		emac_pm_return_from_halt(phy_dev);
 
 		if (!arapc->pm_adv_mode) {
@@ -1053,21 +1000,20 @@
 			const uint32_t adv_1G_F = SUPPORTED_1000baseT_Full;
 			const uint32_t adv_1G_H = SUPPORTED_1000baseT_Half;
 			uint32_t clear_adv = 0;
-			uint32_t restore_adv = 0;
 
 			if (phy_dev->advertising & (adv_10M_F | adv_10M_H)) {
 				clear_adv = adv_10M_H | adv_100M_F | adv_100M_H | adv_1G_F | adv_1G_H;
-				restore_adv = adv_100M_F | adv_1G_F;
 			} else if (phy_dev->advertising & (adv_100M_F | adv_100M_H)) {
 				clear_adv = (adv_1G_H | adv_1G_F);
-				restore_adv = adv_1G_F;
 			}
 
 			if (clear_adv) {
-				arapc->pm_adv_mode = phy_dev->advertising & restore_adv;
+				arapc->pm_adv_mode = 1;
+				mutex_lock(&phy_dev->lock);
 				phy_dev->advertising &= ~clear_adv;
-				phy_start_aneg(phy_dev);
-
+				phy_dev->state = PHY_QTNPM;
+				phy_dev->link = 0;
+				mutex_unlock(&phy_dev->lock);
 			}
 
 			printk(KERN_INFO "%s: emac slowed down\n", DRV_NAME);
@@ -1076,17 +1022,21 @@
 		emac_pm_return_from_halt(phy_dev);
 
 		if (arapc->pm_adv_mode) {
-			phy_dev->advertising |= arapc->pm_adv_mode;
 			arapc->pm_adv_mode = 0;
-			phy_start_aneg(phy_dev);
+			mutex_lock(&phy_dev->lock);
+			phy_dev->advertising = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
+				SUPPORTED_100baseT_Half | SUPPORTED_10baseT_Full | \
+				SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+			phy_dev->state = PHY_QTNPM;
+			phy_dev->link = 0;
+			mutex_unlock(&phy_dev->lock);
 
 			printk(KERN_INFO "%s: emac resumed from slow down\n", DRV_NAME);
 		}
 	}
-	emac_update_phydev_state_queue(arapc->dev, 1);
 }
 
-static int emac_pm_notify(struct notifier_block *b, unsigned long level, void *v)
+static int emac_lib_pm_emac_notify(struct notifier_block *b, unsigned long level, void *v)
 {
 	struct emac_common *arapc = container_of(b, struct emac_common, pm_notifier);
 
@@ -1095,22 +1045,53 @@
 	return NOTIFY_OK;
 }
 
-void emac_lib_pm_add_notifier(struct net_device *dev)
+void emac_lib_pm_emac_add_notifier(struct net_device *dev)
 {
 	struct emac_common *arapc = netdev_priv(dev);
 
-	arapc->pm_notifier.notifier_call = emac_pm_notify;
-	pm_qos_add_notifier(PM_QOS_POWER_SAVE, &arapc->pm_notifier);
+	arapc->pm_notifier.notifier_call = emac_lib_pm_emac_notify;
+	pm_qos_add_notifier(PM_QOS_POWER_EMAC, &arapc->pm_notifier);
 }
-EXPORT_SYMBOL(emac_lib_pm_add_notifier);
+EXPORT_SYMBOL(emac_lib_pm_emac_add_notifier);
 
-void emac_lib_pm_remove_notifier(struct net_device *dev)
+void emac_lib_pm_emac_remove_notifier(struct net_device *dev)
 {
 	struct emac_common *arapc = netdev_priv(dev);
 
-	pm_qos_remove_notifier(PM_QOS_POWER_SAVE, &arapc->pm_notifier);
+	pm_qos_remove_notifier(PM_QOS_POWER_EMAC, &arapc->pm_notifier);
 }
-EXPORT_SYMBOL(emac_lib_pm_remove_notifier);
+EXPORT_SYMBOL(emac_lib_pm_emac_remove_notifier);
+
+static int emac_pm_save_notify(struct notifier_block *b, unsigned long level, void *v)
+{
+	emac_pm_power_save_level = level;
+	pm_qos_refresh_notifiers(PM_QOS_POWER_EMAC);
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block pm_save_notifier = {
+	.notifier_call = emac_pm_save_notify,
+};
+
+void emac_lib_pm_save_add_notifier(void)
+{
+	pm_qos_add_notifier(PM_QOS_POWER_SAVE, &pm_save_notifier);
+}
+EXPORT_SYMBOL(emac_lib_pm_save_add_notifier);
+
+void emac_lib_pm_save_remove_notifier(void)
+{
+	pm_qos_remove_notifier(PM_QOS_POWER_SAVE, &pm_save_notifier);
+}
+EXPORT_SYMBOL(emac_lib_pm_save_remove_notifier);
+
+void emac_lib_update_link_vars(const uint32_t dual_link)
+{
+	emac_lib_dual_emac = dual_link;
+	pm_qos_refresh_notifiers(PM_QOS_POWER_EMAC);
+}
+EXPORT_SYMBOL(emac_lib_update_link_vars);
 
 static struct phy_device *phy_power_get_phy(struct net_device *dev)
 {
@@ -1659,7 +1640,6 @@
 	EMACR(EMAC_MAC_RX_START_THRESHOLD),
 	EMACR(EMAC_MAC_INT),
 	EMACR(EMAC_MAC_INT_ENABLE),
-#ifdef TOPAZ_PLATFORM
 	EMACR(TOPAZ_EMAC_WRAP_CTRL),
 	EMACR(TOPAZ_EMAC_RXP_CTRL),
 	EMACR(TOPAZ_EMAC_TXP_CTRL),
@@ -1693,7 +1673,6 @@
 	EMACRR(TOPAZ_EMAC_RX_DPI_FIELD_GROUP(0), TOPAZ_EMAC_NUM_DPI_FILTERS),
 	EMACRR(TOPAZ_EMAC_RX_DPI_OUT_CTRL(0), TOPAZ_EMAC_NUM_DPI_FILTERS),
 	EMACRR(TOPAZ_EMAC_RX_DPI_IPT_GROUP(0), TOPAZ_EMAC_NUM_DPI_FILTERS),
-#endif
 };
 
 void emac_lib_reg_debug(u32 base) {
diff --git a/drivers/ruby/emac_lib.h b/drivers/ruby/emac_lib.h
index 9c1b5df..efa0234 100644
--- a/drivers/ruby/emac_lib.h
+++ b/drivers/ruby/emac_lib.h
@@ -95,6 +95,11 @@
 	readl(RUBY_SYS_CTL_BASE_ADDR);
 }
 
+static inline bool emac_lib_rtl_switch(uint32_t cfg)
+{
+	return cfg & (EMAC_PHY_RTL8363SB_P0 | EMAC_PHY_RTL8363SB_P1 | EMAC_PHY_RTL8365MB);
+}
+
 /*
  * Utility functions for reading/writing registers in the MDIO
  */
@@ -157,13 +162,16 @@
 int emac_lib_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 struct net_device_stats *emac_lib_stats(struct net_device *dev);
 int emac_lib_stats_sprintf(char *buf, struct net_device *dev);
-void emac_lib_pm_add_notifier(struct net_device *dev);
-void emac_lib_pm_remove_notifier(struct net_device *dev);
+void emac_lib_pm_save_add_notifier(void);
+void emac_lib_pm_save_remove_notifier(void);
 int emac_lib_phy_power_create_proc(struct net_device *dev);
 void emac_lib_phy_power_remove_proc(struct net_device *dev);
 int emac_lib_phy_reg_create_proc(struct net_device *dev);
 void emac_lib_phy_reg_remove_proc(struct net_device *dev);
 
+void emac_lib_update_link_vars(const uint32_t dual_link);
+void emac_lib_pm_emac_add_notifier(struct net_device *dev);
+void emac_lib_pm_emac_remove_notifier(struct net_device *dev);
 
 #if EMAC_REG_DEBUG
 void emac_lib_reg_debug(u32 base);
diff --git a/drivers/ruby/gpio.c b/drivers/ruby/gpio.c
index 615f148..e195c06 100644
--- a/drivers/ruby/gpio.c
+++ b/drivers/ruby/gpio.c
@@ -165,43 +165,73 @@
 
 void gpio_wowlan_output(uint32_t pin, uint32_t value)
 {
+#ifndef TOPAZ_AMBER_IP
 	struct arc_gpio_controller *__iomem g =
 			(struct arc_gpio_controller *) RUBY_GPIO_REGS_ADDR;
 	gpio_output(g, pin, value);
-
+#else
+	/*
+	 * In Amber WOWLAN is handled by WIFI2SOC interrupt.
+	 */
+#endif
 }
 EXPORT_SYMBOL(gpio_wowlan_output);
 
 void gpio_uart0_config(void)
 {
+#ifndef TOPAZ_AMBER_IP
 	gpio_config(RUBY_GPIO_UART0_SO, RUBY_GPIO_ALT_OUTPUT);
 	gpio_config(RUBY_GPIO_UART0_SI, RUBY_GPIO_ALT_INPUT);
+#else
+	/*
+	 * In Amber GPIO pins are not shared. No need to set up alternate function.
+	 */
+#endif
 }
 
 void gpio_uart1_config(void)
 {
+#ifndef TOPAZ_AMBER_IP
 	gpio_config(RUBY_GPIO_UART1_SO, RUBY_GPIO_ALT_OUTPUT);
 	gpio_config(RUBY_GPIO_UART1_SI, RUBY_GPIO_ALT_INPUT);
+#else
+	/*
+	 * In Amber GPIO pins are not shared. No need to set up alternate function.
+	 */
+#endif
 }
 
 void gpio_spi_flash_config(void)
 {
+#ifndef TOPAZ_AMBER_IP
 	gpio_config(RUBY_GPIO_SPI_MISO, RUBY_GPIO_ALT_OUTPUT);
 	gpio_config(RUBY_GPIO_SPI_MOSI, RUBY_GPIO_ALT_INPUT);
 	gpio_config(RUBY_GPIO_SPI_SCK, RUBY_GPIO_ALT_OUTPUT);
 	gpio_config(RUBY_GPIO_SPI_nCS, RUBY_GPIO_ALT_OUTPUT);
+#else
+	/*
+	 * In Amber GPIO pins are not shared. No need to set up alternate function.
+	 */
+#endif
 }
 EXPORT_SYMBOL(gpio_spi_flash_config);
 
 void gpio_lna_toggle_config(void)
 {
+#ifndef TOPAZ_AMBER_IP
 	gpio_config(RUBY_GPIO_LNA_TOGGLE, RUBY_GPIO_ALT_OUTPUT);
+#else
+	/*
+	 * In Amber GPIO pins are not shared. No need to set up alternate function.
+	 */
+#endif
 }
 EXPORT_SYMBOL(gpio_lna_toggle_config);
 
 inline static uint32_t _gpio_pin_pwm_reg(uint32_t pin)
 {
 	switch(pin) {
+#ifndef TOPAZ_AMBER_IP
 		case RUBY_GPIO_PIN1:
 			return RUBY_GPIO1_PWM0;
 		case RUBY_GPIO_PIN3:
@@ -216,6 +246,22 @@
 			return RUBY_GPIO15_PWM5;
 		case RUBY_GPIO_PIN16:
 			return RUBY_GPIO16_PWM6;
+#else
+		case RUBY_GPIO_PIN11:
+			return AMBER_GPIO11_PWM0;
+		case RUBY_GPIO_PIN12:
+			return AMBER_GPIO12_PWM1;
+		case RUBY_GPIO_PIN13:
+			return AMBER_GPIO13_PWM2;
+		case RUBY_GPIO_PIN14:
+			return AMBER_GPIO14_PWM3;
+		case RUBY_GPIO_PIN15:
+			return AMBER_GPIO15_PWM4;
+		case RUBY_GPIO_PIN16:
+			return AMBER_GPIO16_PWM5;
+		case RUBY_GPIO_PIN17:
+			return AMBER_GPIO17_PWM6;
+#endif
 	}
 	return 0;
 }
diff --git a/drivers/ruby/irq.c b/drivers/ruby/irq.c
index d5d1b0f..36091df 100644
--- a/drivers/ruby/irq.c
+++ b/drivers/ruby/irq.c
@@ -102,11 +102,7 @@
 #define ASSERT(expr)
 #endif
 
-#ifdef TOPAZ_PLATFORM
 #define TIMER_INT_MSK(t)	TOPAZ_SYS_CTL_INTR_TIMER_MSK(t)
-#else
-#define TIMER_INT_MSK(t)        RUBY_SYS_CTL_INTR_TIMER_MSK(t)
-#endif
 
 enum toggle_irq {
 	DISABLE,
@@ -473,6 +469,7 @@
 }
 #endif
 
+#ifndef TOPAZ_AMBER_IP
 /*
  *
  * Some checking to prevent registration of isrs on gpio lines that are in use
@@ -488,7 +485,7 @@
 
 	return use_uart1;
 }
-
+#endif
 
 static struct disallowed_isr {
 	int	irq;
@@ -498,12 +495,14 @@
 }
 disallowed_isrs[] =
 {
+#ifndef TOPAZ_AMBER_IP
 	{ -1,	RUBY_GPIO_UART0_SI,	"uart0 rx",	NULL			},
 	{ -1,	RUBY_GPIO_UART0_SO,	"uart0 tx",	NULL			},
 	{ -1,	RUBY_GPIO_UART1_SI,	"uart1 rx",	&check_uart1_use	},
 	{ -1,	RUBY_GPIO_UART1_SO,	"uart1 tx",	&check_uart1_use	},
 	{ -1,	RUBY_GPIO_I2C_SCL,	"i2c scl",	NULL			},
 	{ -1,	RUBY_GPIO_I2C_SDA,	"i2c sda",	NULL			},
+#endif /*TOPAZ_AMBER_IP*/
 	{ RUBY_IRQ_TIMER0,	-1,	"ruby timer0",	NULL			},
 };
 
diff --git a/drivers/ruby/machine.c b/drivers/ruby/machine.c
index 39a7115..ef788da 100644
--- a/drivers/ruby/machine.c
+++ b/drivers/ruby/machine.c
@@ -23,6 +23,10 @@
 
 #include <asm/board/platform.h>
 
+#ifdef TOPAZ_AMBER_IP
+#include <qtn/amber.h>
+#endif
+
 static inline void machine_restart_watchdog(unsigned long delay)
 {
 	writel(RUBY_WDT_ENABLE, RUBY_WDT_CTL);
@@ -39,16 +43,25 @@
 
 void machine_restart(char *__unused)
 {
+#ifndef TOPAZ_AMBER_IP
 	/* Be paranoid - use both watchdog and sysctl to reset */
 	machine_restart_watchdog(RUBY_WDT_RESET_TIMEOUT);
 	machine_restart_sysctrl(RUBY_SYS_CTL_RESET_ALL);
 
 	/* Board must be resetted before this point! */
 	while(1);
+#else
+	machine_halt();
+#endif
 }
 
 void machine_halt(void)
 {
+#ifdef TOPAZ_AMPER_IP
+	local_irq_disable();
+	/* Tell ST HOST we have been halted */
+	amber_shutdown();
+#endif
 	/* Halt the processor */
 	__asm__ __volatile__("flag  %0"::"i"(STATUS_H_MASK));
 }
diff --git a/drivers/ruby/pcibios.c b/drivers/ruby/pcibios.c
index 2603d43..9549094 100644
--- a/drivers/ruby/pcibios.c
+++ b/drivers/ruby/pcibios.c
@@ -42,11 +42,7 @@
 #include "pcibios.h"
 
 #define BUS_SCAN_TRY_MAX		1000
-#ifdef TOPAZ_PLATFORM
 #define PCIE_DEV_LINKUP_MASK TOPAZ_PCIE_LINKUP
-#else
-#define PCIE_DEV_LINKUP_MASK	0x700
-#endif
 
 
 static int
@@ -240,7 +236,6 @@
 	return 0;
 }
 
-#ifdef TOPAZ_PLATFORM
 static int
 rpcic_find_capability(int cap)
 {
@@ -258,7 +253,6 @@
 
 	return pos;
 }
-#endif
 /*
  *  PCI bus scan and initialization
  */
@@ -275,11 +269,7 @@
 	rpcic->mem_res.start = RUBY_PCI_RC_MEM_START;
 	rpcic->mem_res.end	= RUBY_PCI_RC_MEM_START + RUBY_PCI_RC_MEM_WINDOW -1;
 	rpcic->mem_res.flags = IORESOURCE_MEM;
-#ifdef TOPAZ_PLATFORM
 	rpcic->irq = TOPAZ_IRQ_PCIE;
-#else
-	rpcic->irq = RUBY_IRQ_INTA;
-#endif
 
 	if (request_resource(&iomem_resource, &rpcic->mem_res) < 0) {
 		printk(KERN_WARNING "WARNING: Failed to alloc IOMem!\n");
@@ -288,11 +278,7 @@
 
 	/* waiting for end point linked up in the PCI bus */
 	for (i = 0; i < BUS_SCAN_TRY_MAX; i++) {
-#ifdef TOPAZ_PLATFORM
 		ep_up = readl(TOPAZ_PCIE_STAT);
-#else
-		ep_up = readl(RUBY_SYS_CTL_CSR);
-#endif
 		if ( (ep_up & PCIE_DEV_LINKUP_MASK) == PCIE_DEV_LINKUP_MASK ) {
 			break;
 		}
@@ -303,7 +289,6 @@
 	}
 
 	/* Set RC Max_Payload_Size to 256 for topaz */
-#ifdef TOPAZ_PLATFORM
 	int pos;
 	uint32_t dev_ctl_sts;
 	pos = rpcic_find_capability(PCI_CAP_ID_EXP);
@@ -314,7 +299,6 @@
 		dev_ctl_sts = ((dev_ctl_sts & ~PCI_EXP_DEVCTL_PAYLOAD) | BIT(5));
 		writel(dev_ctl_sts, RUBY_PCIE_REG_BASE + pos + PCI_EXP_DEVCTL);
 	}
-#endif
 
 	if ( (ep_up & PCIE_DEV_LINKUP_MASK) == PCIE_DEV_LINKUP_MASK ) {
 		rpcic->bus = pci_scan_bus(0, &rpcic_ops, rpcic);
@@ -515,13 +499,11 @@
 	if (!pos) {
 		printk(KERN_ERR "Error locating MSI capability position, using INTx instead\n");
 	} else {
-#ifdef TOPAZ_PLATFORM
 		/* Setup msi generation info */
 		writel(TOPAZ_PCIE_MSI_REGION, TOPAZ_MSI_ADDR_LOWER);
 		writel(0, TOPAZ_MSI_ADDR_UPPER);
 		writel(BIT(0), TOPAZ_MSI_INT_ENABLE);
 		writel(0, TOPAZ_PCIE_MSI_MASK);
-#endif
 	}
 
 	return 0;
diff --git a/drivers/ruby/pm.c b/drivers/ruby/pm.c
index 65463bd..5a1246b 100644
--- a/drivers/ruby/pm.c
+++ b/drivers/ruby/pm.c
@@ -33,6 +33,7 @@
 #define STR(x)				STR_HELPER(x)
 
 #define PM_PROC_FILE_NAME		"soc_pm"
+#define PM_EMAC_PROC_FILE_NAME		"emac_pm"
 
 #define PM_PROC_ADD_CMD			"add"
 #define PM_PROC_UPDATE_CMD		"update"
@@ -46,8 +47,10 @@
 
 static struct workqueue_struct *pm_wq;
 static DEFINE_SPINLOCK(pm_wq_lock);
+static struct pm_qos_request_list *pm_emac_req;
 
-static int pm_write_proc(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static int pm_write_proc(struct file *file, const char __user *buffer,
+				unsigned long count, void *data)
 {
 	char cmd[PM_MAX_NAME_LEN + 32];
 	char name[PM_MAX_NAME_LEN + 1];
@@ -63,14 +66,28 @@
 	}
 	cmd[count] = '\0';
 
-	if (sscanf(cmd, PM_PROC_PARSE_ADD_CMD, name, &val) == 2) {
-		ret = pm_qos_add_requirement(PM_QOS_POWER_SAVE, name, val);
-	} else if (sscanf(cmd, PM_PROC_PARSE_UPDATE_CMD, name, &val) == 2) {
-		ret = pm_qos_update_requirement(PM_QOS_POWER_SAVE, name, val);
-	} else if (sscanf(cmd, PM_PROC_PARSE_REMOVE_CMD, name) == 1) {
-		pm_qos_remove_requirement(PM_QOS_POWER_SAVE, name);
-	} else {
+	switch ((int)data) {
+	case PM_QOS_POWER_SAVE:
+		if (sscanf(cmd, PM_PROC_PARSE_ADD_CMD, name, &val) == 2) {
+			ret = pm_qos_add_requirement(PM_QOS_POWER_SAVE, name, val);
+		} else if (sscanf(cmd, PM_PROC_PARSE_UPDATE_CMD, name, &val) == 2) {
+			ret = pm_qos_update_requirement(PM_QOS_POWER_SAVE, name, val);
+		} else if (sscanf(cmd, PM_PROC_PARSE_REMOVE_CMD, name) == 1) {
+			pm_qos_remove_requirement(PM_QOS_POWER_SAVE, name);
+		} else {
+			ret = -EINVAL;
+		}
+		break;
+	case PM_QOS_POWER_EMAC:
+		if (sscanf(cmd, "%d", &val) == 1) {
+			pm_qos_update_request(pm_emac_req, val);
+		} else {
+			ret = -EINVAL;
+		}
+		break;
+	default:
 		ret = -EINVAL;
+		break;
 	}
 
 	return ret ? ret : count;
@@ -78,7 +95,41 @@
 
 static int pm_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
 {
-	return sprintf(page, "%d", pm_qos_requirement(PM_QOS_POWER_SAVE));
+	return sprintf(page, "%d", pm_qos_requirement((int)data));
+}
+
+static int __init pm_create_proc(void)
+{
+	struct proc_dir_entry *entry;
+	struct proc_dir_entry *emac_proc_entry;
+	/*
+	 * Proc interface to change power save levels.
+	 * Main purpose is debugging.
+	 * Other kernel modules can directly use pm_qos_*() functions.
+	 * User-space application (safe way) can open misc character device
+	 * (major number 10, minor see by "cat /proc/misc")
+	 * provided by PM QoS kernel module and control through it.
+	 * It is safe because 'name' is chosen based on PID,
+	 * and when application quit all its requests are removed.
+	 */
+
+	entry = create_proc_entry(PM_PROC_FILE_NAME, 0600, NULL);
+	if (!entry) {
+		return -ENOMEM;
+	}
+	entry->write_proc = pm_write_proc;
+	entry->read_proc = pm_read_proc;
+	entry->data = (void *)PM_QOS_POWER_SAVE;
+
+	emac_proc_entry = create_proc_entry(PM_EMAC_PROC_FILE_NAME, 0600, NULL);
+	if (!emac_proc_entry) {
+		return -ENOMEM;
+	}
+	emac_proc_entry->write_proc = pm_write_proc;
+	emac_proc_entry->read_proc = pm_read_proc;
+	emac_proc_entry->data = (void *)PM_QOS_POWER_EMAC;
+
+	return 0;
 }
 
 static void __init pm_create_wq(void)
@@ -86,31 +137,13 @@
 	pm_wq = create_rt_workqueue("ruby_pm");
 }
 
-static int __init pm_create_proc(void)
-{
-	/*
-	 * Proc interface to change power save levels.
-	 * Main purpose is debugging.
-	 * Other kernel modules can directly use pm_qos_*() functions.
-	 * User-space application (safe way) can open misc character device (major number 10, minor see by "cat /proc/misc")
-	 * provided by PM QoS kernel module and control through it. It is safe because 'name' is chosen based on PID,
-	 * and when application quit all its requests are removed.
-	 */
-
-	struct proc_dir_entry *entry = create_proc_entry(PM_PROC_FILE_NAME, 0600, NULL);
-	if (!entry) {
-		return -ENOMEM;
-	}
-
-	entry->write_proc = pm_write_proc;
-	entry->read_proc = pm_read_proc;
-
-	return 0;
-}
-
 static int __init pm_init(void)
 {
 	pm_qos_add_requirement(PM_QOS_POWER_SAVE, BOARD_PM_GOVERNOR_QCSAPI, BOARD_PM_LEVEL_INIT);
+	pm_emac_req = pm_qos_add_request(PM_QOS_POWER_EMAC, BOARD_PM_LEVEL_NO);
+	if (!pm_emac_req)
+		return -ENOMEM;
+
 	pm_create_wq();
 	return pm_create_proc();
 }
diff --git a/drivers/ruby/serial.c b/drivers/ruby/serial.c
index 5398385..387da7d 100644
--- a/drivers/ruby/serial.c
+++ b/drivers/ruby/serial.c
@@ -31,12 +31,8 @@
 static struct plat_serial8250_port ruby_data[] =
 {
 	{
-#ifdef TOPAZ_PLATFORM
 		.iotype		= UPIO_DWAPB,
 		.private_data	= (void*)RUBY_UART0_USR,
-#else
-		.iotype		= UPIO_MEM,
-#endif
 		.flags		= (UPF_BOOT_AUTOCONF | UPF_SPD_FLAG),
 		.mapbase	= RUBY_UART0_BASE_ADDR,
 		.membase	= (void*)RUBY_UART0_BASE_ADDR,
@@ -45,12 +41,8 @@
 		.regshift	= 2,
 	},
 	{
-#ifdef TOPAZ_PLATFORM
 		.iotype		= UPIO_DWAPB,
 		.private_data	= (void*)RUBY_UART1_USR,
-#else
-		.iotype		= UPIO_MEM,
-#endif
 		.flags		= (UPF_BOOT_AUTOCONF | UPF_SPD_FLAG),
 		.mapbase	= RUBY_UART1_BASE_ADDR,
 		.membase	= (void*)RUBY_UART1_BASE_ADDR,
diff --git a/drivers/ruby/spi_api.c b/drivers/ruby/spi_api.c
index d868159..abc3539 100644
--- a/drivers/ruby/spi_api.c
+++ b/drivers/ruby/spi_api.c
@@ -459,7 +459,11 @@
                                         return -1;
                                 }
                                 spi_flash_write_enable();
-                                writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_20);
+				if ( device->sector_size * device->n_sectors > RUBY_SPI_BOUNDARY_4B ){
+					writel(SPI_MEM_ADDR_4B(flash_addr), RUBY_SPI_SECTOR_ERASE_20_4B);
+				} else {
+					writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_20);
+				}
 				ret = spi_flash_wait_ready(device);
 				if (ret || device->sector_size == SPI_SECTOR_4K)
 					break;
@@ -473,17 +477,29 @@
                                 return -1;
                         }
                         spi_flash_write_enable();
-                        writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_D8);
+			if ( device->sector_size * device->n_sectors > RUBY_SPI_BOUNDARY_4B ){
+				writel(SPI_MEM_ADDR_4B(flash_addr), RUBY_SPI_SECTOR_ERASE_D8_4B);
+			} else {
+				writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_D8);
+			}
                 }
                 break;
 
         default:
                 spi_flash_write_enable();
-                if (device->flags & SECTOR_ERASE_OP20) {
-                        writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_20);
-                } else {
-                        writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_D8);
-                }
+		if ( device->sector_size * device->n_sectors > RUBY_SPI_BOUNDARY_4B ){
+			if (device->flags & SECTOR_ERASE_OP20) {
+				writel(SPI_MEM_ADDR_4B(flash_addr), RUBY_SPI_SECTOR_ERASE_20_4B);
+			} else {
+				writel(SPI_MEM_ADDR_4B(flash_addr), RUBY_SPI_SECTOR_ERASE_D8_4B);
+			}
+		} else {
+			if (device->flags & SECTOR_ERASE_OP20) {
+				writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_20);
+			} else {
+				writel(SPI_MEM_ADDR(flash_addr), RUBY_SPI_SECTOR_ERASE_D8);
+			}
+		}
         }
 
         return ret;
diff --git a/drivers/ruby/spi_flash.c b/drivers/ruby/spi_flash.c
index 9694f9d..4822376 100644
--- a/drivers/ruby/spi_flash.c
+++ b/drivers/ruby/spi_flash.c
@@ -58,17 +58,6 @@
 /* Each flash chip has same page size */
 #define SPI_PAGE_SIZE			256
 
-/*
- *
- * Ruby uses 3 msb bytes to form addresses.
- * Topaz uses all 4 bytes, just skip first msb if in 3-bytes address mode.
- *
- */
-#ifdef TOPAZ_PLATFORM
-        #define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF))
-#else
-        #define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF) << 8)
-#endif
 
 /* Set zero if want to disable log messages */
 #define SPI_FLASH_DEBUG			0
@@ -432,7 +421,11 @@
 			break;
 		}
 		spi_flash_write_enable();
-		writel(spi_flash_addr(write_begin), IO_ADDRESS(RUBY_SPI_PAGE_PROGRAM));
+		if ( flash->info->sector_size * flash->info->n_sectors > RUBY_SPI_BOUNDARY_4B ){
+			writel(SPI_MEM_ADDR_4B(write_begin), IO_ADDRESS(RUBY_SPI_PAGE_PROGRAM_4B));
+		} else {
+			writel(spi_flash_addr(write_begin), IO_ADDRESS(RUBY_SPI_PAGE_PROGRAM));
+		}
 
 		/*
 		 * memcpy((u_char *)flash->mem_write_nocache + write_begin, buf, iter_write_len);
@@ -588,14 +581,25 @@
 	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
 };
 
+#ifdef FLASH_SUPPORT_256KB
+static struct mtd_partition __initdata parts_256K[] = {
+        RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,   F256K_UBOOT_PIGGY_PARTITION_SIZE, 0),
+        RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,   F256K_ENV_PARTITION_SIZE,        MTDPART_OFS_NXTBLK),
+        RUBY_MTD_PART(MTD_PARTNAME_DATA,        MTDPART_SIZ_FULL,               MTDPART_OFS_NXTBLK),
+};
+#endif
 static struct mtd_partition __initdata parts_2M[] = {
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV_BAK,UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
 	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
 };
-
-#ifdef TOPAZ_PLATFORM
+static struct mtd_partition __initdata parts_4M[] = {
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV_BAK,UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
+};
 static struct mtd_partition __initdata parts_8M[] = {
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
@@ -603,16 +607,6 @@
 	RUBY_MTD_PART(MTD_PARTNAME_LINUX_LIVE,	IMG_SIZE_8M_FLASH_1_IMG,	MTDPART_OFS_NXTBLK),
 	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
 };
-#else
-static struct mtd_partition __initdata parts_8M[] = {
-	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
-	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
-	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV_BAK,UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
-	RUBY_MTD_PART(MTD_PARTNAME_LINUX_SAFETY,IMG_SIZE_8M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
-	RUBY_MTD_PART(MTD_PARTNAME_LINUX_LIVE,	IMG_SIZE_8M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
-	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
-};
-#endif
 
 static struct mtd_partition __initdata parts_16M[] = {
 	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
@@ -623,6 +617,26 @@
 	RUBY_MTD_PART(MTD_PARTNAME_DATA,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
 };
 
+static struct mtd_partition __initdata parts_32M[] = {
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV_BAK,UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_LINUX_SAFETY,IMG_SIZE_16M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_LINUX_LIVE,	IMG_SIZE_16M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_DATA,	RUBY_MIN_DATA_PARTITION_SIZE,		MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_EXTEND,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
+};
+
+static struct mtd_partition __initdata parts_64M[] = {
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_BIN,	UBOOT_TEXT_PARTITION_SIZE,	0),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV,	UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_UBOOT_ENV_BAK,UBOOT_ENV_PARTITION_SIZE,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_LINUX_SAFETY,IMG_SIZE_16M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_LINUX_LIVE,	IMG_SIZE_16M_FLASH_2_IMG,	MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_DATA,	RUBY_MIN_DATA_PARTITION_SIZE,		MTDPART_OFS_NXTBLK),
+	RUBY_MTD_PART(MTD_PARTNAME_EXTEND,	MTDPART_SIZ_FULL,		MTDPART_OFS_NXTBLK),
+};
+
 struct mtd_partition_table {
 	int flashsz;
 	struct mtd_partition *parts;
@@ -630,9 +644,15 @@
 };
 
 static const struct mtd_partition_table partition_tables[] = {
+	{ FLASH_64MB,	parts_64M,	ARRAY_SIZE(parts_64M)	},
+	{ FLASH_32MB,	parts_32M,	ARRAY_SIZE(parts_32M)	},
 	{ FLASH_16MB,	parts_16M,	ARRAY_SIZE(parts_16M)	},
 	{ FLASH_8MB,	parts_8M,	ARRAY_SIZE(parts_8M)	},
+	{ FLASH_4MB,	parts_4M,	ARRAY_SIZE(parts_4M)	},
 	{ FLASH_2MB,	parts_2M,	ARRAY_SIZE(parts_2M)	},
+#ifdef FLASH_SUPPORT_256KB
+        { FLASH_256KB,  parts_256K,     ARRAY_SIZE(parts_256K)   },
+#endif
 	{ FLASH_64KB,	parts_64K,	ARRAY_SIZE(parts_64K)	},
 };
 
@@ -704,6 +724,9 @@
 		goto error;
 	}
 
+	if ( flash->info->sector_size * flash->info->n_sectors > RUBY_SPI_BOUNDARY_4B ){
+		writel(RUBY_SPI_ADDRESS_MODE_4B, RUBY_SPI_CONTROL);
+	}
 
 	*flash_ret = flash;
 
diff --git a/drivers/ruby/troubleshoot.h b/drivers/ruby/troubleshoot.h
index 048b8e0..9850303 100644
--- a/drivers/ruby/troubleshoot.h
+++ b/drivers/ruby/troubleshoot.h
@@ -23,12 +23,14 @@
 #include <linux/types.h>
 #include <common/topaz_platform.h>
 
-#define QTN_SAFE_SRAM_MAGIC 0xF0
+#define HEADER_CORE_DUMP	(0xDEAD)
 
 typedef int (*arc_troubleshoot_start_hook_cbk)(void *in_ctx);
 
 void arc_set_sram_safe_area(unsigned long sram_start, unsigned long sram_end);
 
+void arc_save_to_sram_safe_area(int compress_ratio);
+
 void arc_set_troubleshoot_start_hook(arc_troubleshoot_start_hook_cbk in_troubleshoot_start, void *in_ctx);
 
 /* Inside printk.c - not the ideal header for this, but since it's Quantenna added, is
diff --git a/drivers/topaz/Makefile b/drivers/topaz/Makefile
index 2a2c8e1..5364550 100644
--- a/drivers/topaz/Makefile
+++ b/drivers/topaz/Makefile
@@ -17,6 +17,7 @@
 ifeq ($(QTN_EXTERNAL_MODULES),y)
 obj-$(CONFIG_ARCH_TOPAZ_FWT) += fwt_if.o
 obj-$(CONFIG_ARCH_TOPAZ_TQE) += switch_tqe.o
+obj-$(CONFIG_ARCH_TOPAZ_TQE) += switch_vlan.o
 obj-$(CONFIG_ARCH_TOPAZ_EMAC) += dpi.o
 obj-$(CONFIG_ARCH_TOPAZ_EMAC) += switch_emac.o
 endif
diff --git a/drivers/topaz/amber.c b/drivers/topaz/amber.c
new file mode 100644
index 0000000..3f41926
--- /dev/null
+++ b/drivers/topaz/amber.c
@@ -0,0 +1,401 @@
+/*
+ * (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
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>	/* for copy_from_user */
+#include <asm/gpio.h>
+#include <asm/hardware.h>
+
+#include <qtn/amber.h>
+#include <common/topaz_platform.h>
+#include <linux/delay.h>
+
+#define PROC_AMBER_DIR_NAME "amber"
+#define PROC_AMBER_WIFI2SOC_INT_FILE_NAME "wifi2soc_int"
+
+static struct proc_dir_entry *amber_dir;
+static struct proc_dir_entry *amber_wifi2soc_file;
+
+static unsigned long interrupt_errors_mask = 0;
+static unsigned long interrupt_errors_store = 0;
+
+static struct timer_list amber_timer;
+static DEFINE_SPINLOCK(wifi2soc_lock);
+static int initialized = 0;
+
+static struct {
+	const char *token;
+	const int val;
+} wifi2soc_int_token_map[] =
+{
+	{"SYSTEM_READY",	TOPAZ_AMBER_WIFI2SOC_SYSTEM_READY},
+	{"CAL_COMPLETE",	TOPAZ_AMBER_WIFI2SOC_CAL_COMPLETE},
+	{"CAL_CHANGE_REQ",	TOPAZ_AMBER_WIFI2SOC_CAL_CHANGE_REQ},
+	{"SHUTDOWN",		TOPAZ_AMBER_WIFI2SOC_SHUTDOWN},
+	{"WATCHDOG",		TOPAZ_AMBER_WIFI2SOC_WATCHDOG},
+	{"EMERGENCY",		TOPAZ_AMBER_WIFI2SOC_EMERGENCY},
+	{"NFS_MOUNT_FAILURE",	TOPAZ_AMBER_WIFI2SOC_NFS_MOUNT_FAILURE},
+	{"NFS_ACCESS_FAILURE",	TOPAZ_AMBER_WIFI2SOC_NFS_ACCESS_FAILURE},
+	{"NFS_INTEGRITY_FAILURE",TOPAZ_AMBER_WIFI2SOC_NFS_INTEGRITY_FAILURE},
+	{"WAKE_ON_WLAN",	TOPAZ_AMBER_WIFI2SOC_WAKE_ON_WLAN}
+};
+
+static enum amber_shutdown_code shutdown_code = AMBER_SD_CODE_GRACEFUL;
+
+void amber_set_shutdown_code(enum amber_shutdown_code code)
+{
+	shutdown_code = code;
+}
+EXPORT_SYMBOL(amber_set_shutdown_code);
+
+int amber_trigger_wifi2soc_interrupt_sync(unsigned long interrupt_code)
+{
+	interrupt_code &= interrupt_errors_mask;
+
+	if (interrupt_code == 0) {
+		return 0;
+	}
+
+	while (readl(IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_ERROR_REG)) & interrupt_errors_mask) {
+		/*
+		 * Idle wait for the previous error codes to be cleared by ST Host.
+		 * If we get stuck here, this means ST Host is hung, so it does not matter
+		 * where we halt - here, or few cycles later in machine_halt().
+		 */
+	};
+
+	writel(interrupt_code, IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_ERROR_REG));
+	writel(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT, IO_ADDRESS(GPIO_OUTPUT_MASK));
+	writel(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT, IO_ADDRESS(GPIO_OUTPUT));
+	udelay(1);
+	writel(0, IO_ADDRESS(GPIO_OUTPUT));
+	writel(0, IO_ADDRESS(GPIO_OUTPUT_MASK));
+
+	return 0;
+}
+
+void amber_shutdown(void)
+{
+	unsigned long interrupt_code = 0;
+
+	if (!initialized) {
+		/* Any early reboot is considered emergency */
+		interrupt_code = TOPAZ_AMBER_WIFI2SOC_EMERGENCY;
+		interrupt_errors_mask = readl(IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_MASK_REG));
+	} else {
+		switch (shutdown_code) {
+		case AMBER_SD_CODE_GRACEFUL:
+			interrupt_code = TOPAZ_AMBER_WIFI2SOC_SHUTDOWN;
+			break;
+		case AMBER_SD_CODE_EMERGENCY:
+			interrupt_code = TOPAZ_AMBER_WIFI2SOC_EMERGENCY;
+			break;
+		case AMBER_SD_CODE_NONE:
+		default:
+			/* Don't send any error code */
+			interrupt_code = 0;
+			break;
+		}
+	}
+
+	amber_trigger_wifi2soc_interrupt_sync(interrupt_code);
+}
+EXPORT_SYMBOL(amber_shutdown);
+
+static int amber_post_stored_interrupts(void)
+{
+	int need_timer = 0;
+
+	if (interrupt_errors_store == 0) {
+		return 0;
+	}
+
+	if ((readl(IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_ERROR_REG)) & interrupt_errors_mask) == 0) {
+
+		writel(interrupt_errors_store, IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_ERROR_REG));
+
+		interrupt_errors_store = 0;
+
+		/*
+		 * Pulse WIFI2SOC_INT_O. Minimal pulse width is 5 ns.
+		 * The below two calls compile to JL instructions to call gpio_set_value(),
+		 * which in turn indirectly calls gpio set handler.
+		 * This means the number of 500 MHz cycles between line assert and de-assert is
+		 * sufficiently large to fulfill the minimal pulse width requirement.
+		 */
+
+		gpio_set_value(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT, 1);
+		gpio_set_value(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT, 0);
+
+		need_timer = 0;
+	} else {
+		need_timer = 1;
+	}
+
+	return need_timer;
+}
+
+static void amber_timer_func(unsigned long data)
+{
+	amber_trigger_wifi2soc_interrupt(0);
+}
+
+int amber_trigger_wifi2soc_interrupt(unsigned long interrupt_code)
+{
+	int need_timer = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wifi2soc_lock, flags);
+	interrupt_errors_store |= interrupt_code & interrupt_errors_mask;
+	need_timer = amber_post_stored_interrupts();
+	spin_unlock_irqrestore(&wifi2soc_lock, flags);
+
+	if (need_timer) {
+		mod_timer(&amber_timer, jiffies + AMBER_TIMER_PERIOD_JIFFIES);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(amber_trigger_wifi2soc_interrupt);
+
+static int amber_wifi2soc_int_proc_read(char *buffer,
+		  char **buffer_location, off_t offset,
+		  int buffer_length, int *eof, void *data)
+{
+	int i;
+	int written = 0;
+	unsigned long interrupt_code = readl(IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_ERROR_REG));
+
+	*eof = 1;
+
+	for (i = 0; i < ARRAY_SIZE(wifi2soc_int_token_map); i++) {
+		if (interrupt_code & wifi2soc_int_token_map[i].val) {
+			int ret = snprintf(buffer + written,buffer_length - written, "%s\n",
+					wifi2soc_int_token_map[i].token);
+
+			if (ret < 0) {
+				break;
+			}
+
+			if (ret + written > buffer_length) {
+				*eof = 0;
+				written = buffer_length;
+				break;
+			}
+
+			written += ret;
+		}
+	}
+
+	return written;
+}
+
+static int amber_wifi2soc_int_proc_write(struct file *file, const char *buffer,
+		       unsigned long count, void *data)
+{
+	char *procfs_buffer;
+	char *ptr;
+	char *token;
+	char found_token = 0;
+	int i;
+
+	procfs_buffer = kmalloc(count, GFP_KERNEL);
+
+	if (procfs_buffer == NULL) {
+		printk("AMBER: wifi2soc error - out of memory\n");
+		return -ENOMEM;
+	}
+
+	/* write data to the buffer */
+	if (copy_from_user(procfs_buffer, buffer, count)) {
+		goto bail;
+	}
+
+	ptr = (char *)procfs_buffer;
+	ptr[count - 1] = '\0';
+	token = strsep(&ptr, "\n");
+
+	for (i = 0; i < ARRAY_SIZE(wifi2soc_int_token_map); i++) {
+		if (strcmp(token, wifi2soc_int_token_map[i].token) == 0) {
+			amber_trigger_wifi2soc_interrupt(wifi2soc_int_token_map[i].val);
+			found_token = 1;
+			break;
+		}
+	}
+
+	if (!found_token) {
+		printk(KERN_ERR "AMBER: wifi2soc error - unable to parse token %s\n", token);
+	}
+
+bail:
+	kfree(procfs_buffer);
+	return count;
+}
+
+static int amber_panic_notifier(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	amber_set_shutdown_code(AMBER_SD_CODE_EMERGENCY);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block amber_panic_block = {
+	.notifier_call = amber_panic_notifier,
+};
+
+static void amber_soc2wifi_panic_work(struct work_struct *work)
+{
+	printk("AMBER: SoC host panic - halting Amber kernel\n");
+	amber_set_shutdown_code(AMBER_SD_CODE_NONE);
+	kernel_halt();
+}
+
+static DECLARE_WORK(amber_soc2wifi_panic_wq, &amber_soc2wifi_panic_work);
+
+static void amber_soc2wifi_wake_on_lan_work(struct work_struct *work)
+{
+	printk("AMBER: SoC host - waking up on LAN\n");
+}
+
+static DECLARE_WORK(amber_soc2wifi_wake_on_lan_wq, &amber_soc2wifi_wake_on_lan_work);
+
+static irqreturn_t amber_soc2wifi_irq_handler(int irq, void *dev_id)
+{
+	unsigned long int_status = readl(IO_ADDRESS(TOPAZ_AMBER_GPIO_IRQ_STATUS));
+	unsigned long int_code;
+
+	if ((int_status & (1 << TOPAZ_AMBER_SOC2WIFI_INT_INPUT)) == 0) {
+		/* Filter other GPIO interrupts */
+		return IRQ_NONE;
+	}
+
+	int_code = readl(IO_ADDRESS(TOPAZ_AMBER_SOC2WIFI_ERROR_REG));
+
+	if (int_code & TOPAZ_AMBER_SOC2WIFI_KERNEL_PANIC) {
+		/*
+		 * Clear the mask to prevent anymore wifi2soc interrupts posting
+		 * and halt the kernel.
+		 */
+		interrupt_errors_mask = 0;
+		schedule_work(&amber_soc2wifi_panic_wq);
+	}
+
+	if (int_code & TOPAZ_AMBER_SOC2WIFI_WAKE_ON_LAN) {
+		schedule_work(&amber_soc2wifi_wake_on_lan_wq);
+	}
+
+	writel(1 << TOPAZ_AMBER_SOC2WIFI_INT_INPUT, IO_ADDRESS(TOPAZ_AMBER_GPIO_IRQ_CLEAR));
+
+	return IRQ_HANDLED;
+}
+
+static int __init amber_init(void)
+{
+	int err;
+
+	amber_dir = proc_mkdir(PROC_AMBER_DIR_NAME, NULL);
+
+	amber_wifi2soc_file = create_proc_entry(PROC_AMBER_WIFI2SOC_INT_FILE_NAME, 0x644, amber_dir);
+
+	if (amber_wifi2soc_file == NULL) {
+		printk(KERN_ERR "AMBER: unable to create /proc/%s/%s\n", PROC_AMBER_DIR_NAME,
+			PROC_AMBER_WIFI2SOC_INT_FILE_NAME);
+		err = -ENOMEM;
+		goto out_exit_wifi2soc_proc;
+	}
+
+	amber_wifi2soc_file->read_proc = amber_wifi2soc_int_proc_read;
+	amber_wifi2soc_file->write_proc = amber_wifi2soc_int_proc_write;
+	amber_wifi2soc_file->mode = S_IFREG | S_IRUGO;
+	amber_wifi2soc_file->uid = 0;
+	amber_wifi2soc_file->gid = 0;
+	amber_wifi2soc_file->size = 0x1000;
+	amber_wifi2soc_file->data = NULL;
+
+	spin_lock_init(&wifi2soc_lock);
+	setup_timer(&amber_timer, amber_timer_func, 0);
+
+	interrupt_errors_mask = readl(IO_ADDRESS(TOPAZ_AMBER_WIFI2SOC_MASK_REG));
+
+	err = gpio_request(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT, "WIFI2SOC_INT_OUTPUT");
+
+	if (err < 0) {
+		printk(KERN_INFO "AMBER: failed to request GPIO %d for WIFI2SOC_INT_OUTPUT\n",
+			TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT);
+		goto out_exit_wifi2soc_gpio;
+	}
+
+	ruby_set_gpio_irq_sel(TOPAZ_AMBER_SOC2WIFI_INT_INPUT);
+
+	err = request_irq(GPIO2IRQ(TOPAZ_AMBER_SOC2WIFI_INT_INPUT), amber_soc2wifi_irq_handler, 0,
+		"amber_soc2wifi", NULL);
+
+	if (err) {
+		printk(KERN_INFO "AMBER: failed to register IRQ %d\n",
+			GPIO2IRQ(TOPAZ_AMBER_SOC2WIFI_INT_INPUT));
+		goto out_exit_wifi2soc_irq;
+	}
+
+	atomic_notifier_chain_register(&panic_notifier_list, &amber_panic_block);
+
+	initialized = 1;
+
+	printk("AMBER: initialized successfully\n");
+
+	return 0;
+
+out_exit_wifi2soc_irq:
+	gpio_free(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT);
+
+out_exit_wifi2soc_gpio:
+	remove_proc_entry(PROC_AMBER_WIFI2SOC_INT_FILE_NAME, amber_dir);
+
+out_exit_wifi2soc_proc:
+	remove_proc_entry(PROC_AMBER_DIR_NAME, NULL);
+
+	return err;
+}
+
+static void __exit amber_exit(void)
+{
+	del_timer_sync(&amber_timer);
+
+	atomic_notifier_chain_unregister(&panic_notifier_list, &amber_panic_block);
+
+	free_irq(GPIO2IRQ(TOPAZ_AMBER_SOC2WIFI_INT_INPUT), NULL);
+	gpio_free(TOPAZ_AMBER_WIFI2SOC_INT_OUTPUT);
+
+	remove_proc_entry(PROC_AMBER_WIFI2SOC_INT_FILE_NAME, amber_dir);
+	remove_proc_entry(PROC_AMBER_DIR_NAME, NULL);
+}
+
+module_init(amber_init);
+module_exit(amber_exit);
+
+MODULE_DESCRIPTION("Amber Driver");
+MODULE_AUTHOR("Quantenna");
+MODULE_LICENSE("GPL");
diff --git a/drivers/topaz/fwt_if.c b/drivers/topaz/fwt_if.c
index 1ad2687..661496c 100755
--- a/drivers/topaz/fwt_if.c
+++ b/drivers/topaz/fwt_if.c
@@ -55,37 +55,45 @@
 /* Error definition in FWT Interface is return negative value */
 #define FWT_IF_ERROR(x)		(!(FWT_IF_SUCCESS(x)))
 
-/* specific commands keywords */
-#define FWT_IF_KEY_CLEAR	"clear"
-#define FWT_IF_KEY_ON		"on"
-#define FWT_IF_KEY_OFF		"off"
-#define FWT_IF_KEY_PRINT	"print"
-#define FWT_IF_KEY_ADD		"add"
-#define FWT_IF_KEY_DELETE	"del"
-#define FWT_IF_KEY_AUTO		"auto"
-#define FWT_IF_KEY_MANUAL	"manual"
-#define FWT_IF_KEY_NODE		"node"
-#define FWT_IF_KEY_4ADDR	"4addr"
-#define FWT_IF_KEY_HELP		"help"
-#define FWT_IF_KEY_DEBUG	"debug"
-#define FWT_IF_KEY_AGEING	"ageing"
+/* specific commands keywords - must match fwt_if_usr_cmd */
+#define FWT_IF_KEY_CLEAR		"clear"
+#define FWT_IF_KEY_ON			"on"
+#define FWT_IF_KEY_OFF			"off"
+#define FWT_IF_KEY_PRINT		"print"
+#define FWT_IF_KEY_ADD_STATIC_MC	"add_static_mc"
+#define FWT_IF_KEY_DEL_STATIC_MC	"del_static_mc"
+#define FWT_IF_KEY_GET_MC_LIST		"get_mc_list"
+#define FWT_IF_KEY_ADD			"add"
+#define FWT_IF_KEY_DELETE		"del"
+#define FWT_IF_KEY_AUTO			"auto"
+#define FWT_IF_KEY_MANUAL		"manual"
+#define FWT_IF_KEY_NODE			"node"
+#define FWT_IF_KEY_4ADDR		"4addr"
+#define FWT_IF_KEY_HELP			"help"
+#define FWT_IF_KEY_DEBUG		"debug"
+#define FWT_IF_KEY_AGEING		"ageing"
 
 /* additional keywords */
-#define FWT_IF_KEY_PORT		"port"
-#define FWT_IF_KEY_ENABLE	"enable"
+#define FWT_IF_KEY_PORT			"port"
+#define FWT_IF_KEY_ENABLE		"enable"
+#define FWT_IF_KEY_MAC			"mac"
 
 #define PRINT_FWT(a...)		do { if (g_debug) { printk(a); } } while(0)
 
 const char *g_port_names[] = TOPAZ_TQE_PORT_NAMES;
-
 static fwt_if_sw_cmd_hook g_fwt_if_cmd_hook = NULL;
+static char *fwt_if_outbuf = NULL;
+static spinlock_t fwt_if_outbuf_lock;	/* synchronise use of fwt_if_outbuf */
 
 /* set command keywords */
-static char* str_cmd[FWT_IF_MAX_CMD] = {
+static char *fwt_str_cmd[FWT_IF_MAX_CMD] = {
 		FWT_IF_KEY_CLEAR,
 		FWT_IF_KEY_ON,
 		FWT_IF_KEY_OFF,
 		FWT_IF_KEY_PRINT,
+		FWT_IF_KEY_ADD_STATIC_MC,
+		FWT_IF_KEY_DEL_STATIC_MC,
+		FWT_IF_KEY_GET_MC_LIST,
 		FWT_IF_KEY_ADD,
 		FWT_IF_KEY_DELETE,
 		FWT_IF_KEY_AUTO,
@@ -93,15 +101,17 @@
 		FWT_IF_KEY_4ADDR,
 		FWT_IF_KEY_DEBUG,
 		FWT_IF_KEY_HELP,
-		FWT_IF_KEY_AGEING
+		FWT_IF_KEY_AGEING,
 };
 
 /* value of extracted keywords from user */
 typedef	enum {
 	FWT_IF_ID,
+	FWT_IF_MAC,
 	FWT_IF_PORT,
 	FWT_IF_NODE,
 	FWT_IF_ENABLE,
+	FWT_IF_VALUE,
 	FWT_IF_MAX_PARAM,
 } fwt_if_usr_str;
 
@@ -157,7 +167,20 @@
 	}
 
 	switch (cmd) {
+	case FWT_IF_MAC:
+		id = var;
+		mac = id->mac_be;
+		if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+					&mac[0], &mac[1], &mac[2],
+					&mac[3], &mac[4], &mac[5]) != ETH_ALEN) {
+			return -EINVAL;
+		}
+		break;
 	case FWT_IF_ID:
+		/*
+		 * This keyword takes a MAC address or an IPv4 or IPv6 address. If it is a multicast
+		 * IP address it is also converted into a multicast layer 2 (MAC) address.
+		 */
 		id = var;
 		ip6 = id->ip.u.ip6.in6_u.u6_addr16;
 		ip4 = (void *) &id->ip.u.ip4;
@@ -168,7 +191,8 @@
 					&ip6[0], &ip6[1], &ip6[2], &ip6[3],
 					&ip6[4], &ip6[5], &ip6[6], &ip6[7]) == 8) {
 			id->ip.proto = htons(ETHERTYPE_IPV6);
-			fwt_mcast_to_mac(mac, &id->ip);
+			if (IPUTIL_V6_ADDR_MULTICAST(*ip6))
+				fwt_mcast_to_mac(mac, &id->ip);
 		} else if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
 					&mac[0], &mac[1], &mac[2],
 					&mac[3], &mac[4], &mac[5]) == ETH_ALEN) {
@@ -176,7 +200,8 @@
 					&ip4[0], &ip4[1], &ip4[2],
 					&ip4[3]) == FWT_DB_IPV4_SIZE) {
 			id->ip.proto = htons(ETHERTYPE_IP);
-			fwt_mcast_to_mac(mac, &id->ip);
+			if (IPUTIL_V4_ADDR_MULTICAST(*ip4))
+				fwt_mcast_to_mac(mac, &id->ip);
 		} else {
 			return -EINVAL;
 		}
@@ -214,12 +239,17 @@
 			return -EINVAL;
 		}
 		break;
+	case FWT_IF_VALUE:
+		sscanf(str, "%d", &param);
+		*((int32_t*)var) = param;
+		break;
 	default:
 		return -EINVAL;
 	}
 
 	return 1;
 }
+
 /*
  * Get the current value that attached to keyword definition
  * @param str: the string to find keyword
@@ -247,10 +277,19 @@
 	printk("on           enable the FWT interface\n");
 	printk("off          disable the FWT interface\n");
 	printk("print        print the contents of the SW FWT\n");
+	printk("add_static_mc <ip> mac <mac>\n");
+	printk("             add a static multicast entry\n");
+	printk("del_static_mc <ip> mac <mac>\n");
+	printk("             delete a static multicast entry\n");
+	printk("get_mc_list  return a list of multicast addresses\n");
 	printk("add <mac> port <port> node <node>\n");
-	printk("             add an entry to the FWT\n");
-	printk("               e.g. add 01:ab:ac:34:67:20 port wmac node 3\n");
+	printk("             add a unicast entry to the FWT\n");
+	printk("             e.g. add 01:ab:ac:34:67:20 port wmac node 3\n");
+	printk("add <ip> port <port> node <node>\n");
+	printk("             add a multicast entry to the FWT\n");
+	printk("             e.g. add 224.1.2.3 port wmac node 3\n");
 	printk("del <mac>    delete a table entry by MAC address\n");
+	printk("del <ip>     delete a table entry by IP address\n");
 	printk("auto         enable automatic generation of table entries by the bridge module\n");
 	printk("manual       enable manual-only creation of table entries, with no restrictions\n");
 	printk("4addr <mac> enable {0|1}\n");
@@ -345,7 +384,6 @@
 	char *str_val = NULL;
 	struct fwt_if_common data;
 
-	/* Clear node array */
 	memset(data.node, FWT_DB_INVALID_NODE, sizeof(data.node));
 
 	/* ADD example: "add ab:34:be:af:34:42 port lhost node 2:4:3" */
@@ -374,6 +412,123 @@
 
 	return 1;
 }
+
+static int fwt_if_apply_user_add_static_mc(char **words, uint8_t word_count)
+{
+	int rc;
+	char *str_val = NULL;
+	struct fwt_if_common data;
+	struct fwt_if_id *id = &data.id;
+
+	memset(data.node, FWT_DB_INVALID_NODE, sizeof(data.node));
+
+	/* ADD_STATIC_MC example: "add_static_mc 224.51.2.3 mac ab:34:be:af:34:42*/
+	str_val = fwt_if_get_val_from_keyword(FWT_IF_KEY_ADD_STATIC_MC, words, word_count);
+	rc = fwt_if_extract_parm(str_val, FWT_IF_ID, id);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	str_val = fwt_if_get_val_from_keyword(FWT_IF_KEY_MAC, words, word_count);
+	rc = fwt_if_extract_parm(str_val, FWT_IF_MAC, id);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	switch (id->ip.proto) {
+	case htons(ETHERTYPE_IP):
+		if (!IPUTIL_V4_ADDR_MULTICAST(id->ip.u.ip4))
+			return -EINVAL;
+		break;
+	case htons(ETHERTYPE_IPV6):
+		if (!IPUTIL_V6_ADDR_MULTICAST(*id->ip.u.ip6.in6_u.u6_addr16))
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	rc = fwt_if_set_sw_cmd(FWT_IF_CMD_ADD_STATIC_MC, &data);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	return 1;
+}
+
+static int fwt_if_apply_user_del_static_mc(char **words, uint8_t word_count)
+{
+	int rc;
+	char *str_val = NULL;
+	struct fwt_if_common data;
+	struct fwt_if_id *id = &data.id;
+
+	memset(data.node, FWT_DB_INVALID_NODE, sizeof(data.node));
+
+	/* DEL_STATIC_MC example: "del_static_mc 224.51.2.3 mac ab:34:be:af:34:42*/
+	str_val = fwt_if_get_val_from_keyword(FWT_IF_KEY_DEL_STATIC_MC, words, word_count);
+	rc = fwt_if_extract_parm(str_val, FWT_IF_ID, id);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	str_val = fwt_if_get_val_from_keyword(FWT_IF_KEY_MAC, words, word_count);
+	rc = fwt_if_extract_parm(str_val, FWT_IF_MAC, id);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	switch (id->ip.proto) {
+	case htons(ETHERTYPE_IP):
+		if (!IPUTIL_V4_ADDR_MULTICAST(id->ip.u.ip4))
+			return -EINVAL;
+		break;
+	case htons(ETHERTYPE_IPV6):
+		if (!IPUTIL_V6_ADDR_MULTICAST(*id->ip.u.ip6.in6_u.u6_addr16))
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	rc = fwt_if_set_sw_cmd(FWT_IF_CMD_DEL_STATIC_MC, &data);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	return 1;
+}
+
+#define FWT_IF_OUTBUF_LEN_MIN	32
+#define FWT_IF_OUTBUF_LEN_MAX	8192
+
+/* Must be called with the fwt_if_outbuf_lock held */
+static int fwt_if_get_mc_list(char **words, uint8_t word_count)
+{
+	int rc;
+	struct fwt_if_common data;
+	char *str_val = NULL;
+
+	if (fwt_if_outbuf) {
+		/* a command was issued previously but the output was not retrieved */
+		kfree(fwt_if_outbuf);
+		fwt_if_outbuf = NULL;
+	}
+
+	str_val = fwt_if_get_val_from_keyword(FWT_IF_KEY_GET_MC_LIST, words, word_count);
+	rc = fwt_if_extract_parm(str_val, FWT_IF_VALUE, &data.param);
+	if (FWT_IF_ERROR(rc))
+		return rc;
+
+	if (data.param <= FWT_IF_OUTBUF_LEN_MIN || data.param > FWT_IF_OUTBUF_LEN_MAX)
+		return -EINVAL;
+
+	fwt_if_outbuf = kmalloc(data.param, GFP_KERNEL);
+	if (!fwt_if_outbuf)
+		return -ENOMEM;
+
+	memset(fwt_if_outbuf, 0, data.param);
+	data.extra = fwt_if_outbuf;
+
+	fwt_if_set_sw_cmd(FWT_IF_CMD_GET_MC_LIST, &data);
+
+	return 1;
+}
+
 /* Apply user command.
  * User command can control the FWT interface.
  * @param cmd_num: command number
@@ -386,9 +541,9 @@
 	int rc = -EINVAL;
 	struct fwt_if_common data;
 
-	if ((word_count == 0) || (!words)) {
+	if ((word_count == 0) || (!words))
 		goto cmd_failure;
-	}
+
 	memset(&data, 0, sizeof(data));
 
 	switch(cmd_num) {
@@ -400,6 +555,11 @@
 		case FWT_IF_CMD_MANUAL:
 			rc = fwt_if_set_sw_cmd(cmd_num, &data);
 			break;
+		case FWT_IF_CMD_GET_MC_LIST:
+			spin_lock(&fwt_if_outbuf_lock);
+			rc = fwt_if_get_mc_list(words, word_count);
+			spin_unlock(&fwt_if_outbuf_lock);
+			break;
 		case FWT_IF_CMD_ADD:
 			rc = fwt_if_apply_user_add_entry(words, word_count);
 			break;
@@ -407,6 +567,12 @@
 			/* Delete example: "del ab:34:be:af:34:42" */
 			rc = fwt_if_apply_user_del_entry(words, word_count);
 			break;
+		case FWT_IF_CMD_ADD_STATIC_MC:
+			rc = fwt_if_apply_user_add_static_mc(words, word_count);
+			break;
+		case FWT_IF_CMD_DEL_STATIC_MC:
+			rc = fwt_if_apply_user_del_static_mc(words, word_count);
+			break;
 		case FWT_IF_CMD_4ADDR:
 			rc = fwt_if_apply_user_4addr_mode(words, word_count);
 			break;
@@ -425,21 +591,43 @@
 		break;
 	}
 
-	if (FWT_IF_ERROR(rc)) {
+	if (FWT_IF_ERROR(rc))
 		goto cmd_failure;
-	}
 
 	return 1;
 
 cmd_failure:
-	if (words)
-		printk(KERN_INFO "Failed to parse command:%s, word count:%d\n", *words, word_count);
+	if (word_count)
+		printk(KERN_INFO "Failed to parse command: %s\n", *words);
 	else
-		printk(KERN_INFO "Failed to parse command:(NULL)\n");
+		fwt_if_apply_user_print_help();
 
 	return -EPERM;
 }
 
+static int fwt_if_read_proc(char *page, char **start, off_t off, int count, int *eof, void *_unused)
+{
+	int printed = 0;
+
+	spin_lock(&fwt_if_outbuf_lock);
+
+	if (fwt_if_outbuf) {
+		printed = strnlen(fwt_if_outbuf, count - 1);
+		strncpy(page, fwt_if_outbuf, printed);
+		kfree(fwt_if_outbuf);
+		fwt_if_outbuf = NULL;
+	} else {
+		page[0] = '\0';
+	}
+
+	spin_unlock(&fwt_if_outbuf_lock);
+
+	page[count - 1] = '\0';
+	*eof = 1;
+
+	return printed;
+}
+
 static int fwt_if_write_proc(struct file *file, const char __user *buffer,
 		unsigned long count, void *_unused)
 {
@@ -461,19 +649,14 @@
 		goto out;
 	}
 
-	/* Set null at last byte, note that count already gives +1 byte count*/
 	cmd[count - 1] = '\0';
 
 	word_count = fwt_if_split_words(words, cmd);
 	for (i = 0; i < FWT_IF_MAX_CMD; i++, cmd_num++) {
-		/* Extract command from first word */
-		if (strcmp(words[0], str_cmd[i]) == 0) {
-			printk(KERN_INFO"FWT user command:%s  \n", str_cmd[i]);
+		if (strcmp(words[0], fwt_str_cmd[i]) == 0)
 			break;
-		}
 	}
 
-	/* Exclude softirqs whilst manipulating forwarding table */
 	local_bh_disable();
 
 	rc = fwt_if_apply_user_command(cmd_num, words, word_count);
@@ -504,12 +687,12 @@
 static int __init topaz_fwt_if_create_proc(void)
 {
 	struct proc_dir_entry *entry = create_proc_entry(PROC_NAME, 0600, NULL);
-	if (!entry) {
+
+	if (!entry)
 		return -ENOMEM;
-	}
 
 	entry->write_proc = fwt_if_write_proc;
-	entry->read_proc = NULL;
+	entry->read_proc = fwt_if_read_proc;
 
 	return 0;
 }
@@ -517,10 +700,12 @@
 static int __init fwt_if_init(void)
 {
 	int rc;
+
 	rc = topaz_fwt_if_create_proc();
-	if (rc) {
+	if (rc)
 		return rc;
-	}
+
+	spin_lock_init(&fwt_if_outbuf_lock);
 
 	return 0;
 }
diff --git a/drivers/topaz/hbm.c b/drivers/topaz/hbm.c
index e027425..25c9260 100644
--- a/drivers/topaz/hbm.c
+++ b/drivers/topaz/hbm.c
@@ -35,9 +35,6 @@
 
 #include <common/queue.h>
 
-#ifndef TOPAZ_PLATFORM
-	#include <qtn/ruby_sbm.h>
-#endif
 #include <qtn/topaz_hbm.h>
 #include <qtn/dmautil.h>
 
@@ -155,7 +152,6 @@
 	uint32_t wr_ptr;
 	uint32_t rd_ptr;
 
-#ifdef TOPAZ_PLATFORM
 	int req_rel_diff = 0;
 	int req_rel_perpool_diff[TOPAZ_HBM_POOL_COUNT];
 	int master, pool;
@@ -205,14 +201,6 @@
 		p += sprintf(p, "pool %d req rel diff %d, available %u\n", pool, req_rel_perpool_diff[pool],
 				topaz_hbm_pool_available(pool));
 	}
-#else	/* ruby sbm */
-	int i;
-	for (i = 0; i < ARRAY_SIZE(sbm_pools); i++) {
-		struct sbm_pool *pool = &sbm_pools[i];
-		p += sprintf(p, "sbm pool %d readp %u writep %u count %lu ptr pool %p\n",
-				i, pool->read, pool->write, BIT(pool->ptr_s), pool->ptrs);
-	}
-#endif
 
 	*eof = 1;
 	return p - page;
@@ -287,10 +275,6 @@
 			payload_size, payload_count);
 }
 
-#ifndef TOPAZ_PLATFORM
-struct sbm_pool sbm_pools[4];
-#endif
-
 static int g_pools_inited = 0;
 
 static void topaz_hbm_init_payload_pools(void)
@@ -529,6 +513,8 @@
 	void *buf_bus = (void *) virt_to_bus(skb->head);
 	const int8_t pool = topaz_hbm_payload_get_free_pool_bus(buf_bus);
 
+	buf_bus = topaz_hbm_payload_store_align_bus(buf_bus,
+		topaz_hbm_payload_get_pool_bus(buf_bus), 0);
 	kmem_cache_free(shinfo_cache, skb_shinfo(skb));
 
 	if (topaz_hbm_pool_valid(pool)) {
@@ -560,7 +546,7 @@
 
 #define QTN_HBM_MAX_FRAME_LEN	12000	/* 12000 is over maximum vht frame size,
 					and there is no rx frame whose size is over 12000 */
-struct sk_buff *_topaz_hbm_attach_skb(void *buf_virt, int8_t pool
+struct sk_buff *_topaz_hbm_attach_skb(void *buf_virt, int8_t pool, int inv, uint8_t headroom
 		QTN_SKB_ALLOC_TRACE_ARGS)
 {
 	struct sk_buff *skb;
@@ -568,6 +554,12 @@
 	uint32_t buf_size;
 	uint8_t *buf_head;
 
+	if (unlikely(headroom > TOPAZ_HBM_PAYLOAD_HEADROOM)) {
+		printk(KERN_WARNING "specified headroom(%u) should be smaller than %u\n",
+			headroom, TOPAZ_HBM_PAYLOAD_HEADROOM);
+		return NULL;
+	}
+
 	shinfo = kmem_cache_alloc(shinfo_cache, GFP_ATOMIC);
 	if (!shinfo) {
 		return NULL;
@@ -584,10 +576,11 @@
 	 * if we set skb buffer size as 17K
 	 */
 	buf_size = min((int)topaz_hbm_pool_buf_max_size(pool), QTN_HBM_MAX_FRAME_LEN);
-	buf_head = topaz_hbm_payload_store_align_virt(buf_virt, pool, 0);
+	buf_head = topaz_hbm_payload_store_align_virt(buf_virt, pool, 0) - headroom;
 
 	/* invalidate all packet dcache before passing to the kernel */
-	inv_dcache_sizerange_safe(buf_head, buf_size);
+	if (inv)
+		inv_dcache_sizerange_safe(buf_head, buf_size);
 
 	__alloc_skb_init(skb, shinfo, buf_head,
 			buf_size, 0, &topaz_hbm_skb_allocator
@@ -1119,8 +1112,8 @@
 		hm->unflow_flag = 0;
 	} else {
 		if ((hm->wmac_pl.pool_depleted_cnt > HBM_BUF_DEPLETION_TH) ||
-			(hm->wmac_pl.pool_depleted_cnt > HBM_BUF_DEPLETION_TH)) {
-			panic("HBM pool is depleted, wmac pool:%d, emac rx poll:%d\n",
+			(hm->emac_pl.pool_depleted_cnt > HBM_BUF_DEPLETION_TH)) {
+			panic("HBM pool is depleted, wmac pool:%u, emac rx pool:%u\n",
 				topaz_hbm_pool_available(TOPAZ_HBM_BUF_WMAC_RX_POOL),
 				topaz_hbm_pool_available(TOPAZ_HBM_BUF_EMAC_RX_POOL));
 		}
diff --git a/drivers/topaz/switch_emac.c b/drivers/topaz/switch_emac.c
index 073c3b0..bd5f5c7 100644
--- a/drivers/topaz/switch_emac.c
+++ b/drivers/topaz/switch_emac.c
@@ -41,6 +41,11 @@
 #include <qtn/qtn_buffers.h>
 #include <qtn/qdrv_sch.h>
 #include <qtn/qtn_wmm_ac.h>
+#include <qtn/qtn_vlan.h>
+#include <qtn/hardware_revision.h>
+#include <qtn/shared_params.h>
+
+#include <asm/board/pm.h>
 
 #ifdef CONFIG_QVSP
 #include "qtn/qvsp.h"
@@ -70,6 +75,10 @@
 static int dscp_value         = 0;
 static int emac_xflow_disable = 0;
 
+#define EMAC_WBSP_CTRL_DISABLED	0
+#define EMAC_WBSP_CTRL_ENABLED	1
+#define EMAC_WBSP_CTRL_SWAPPED	2
+static int emac_wbsp_ctrl = EMAC_WBSP_CTRL_DISABLED;
 
 static const struct emac_port_info iflist[] = {
 	{
@@ -89,6 +98,9 @@
 };
 
 static struct net_device *topaz_emacs[ARRAY_SIZE(iflist)];
+static int topaz_emac_on[ARRAY_SIZE(iflist)];
+static unsigned int topaz_emac_prev_two_connected;
+static struct delayed_work topaz_emac_dual_emac_work;
 
 struct topaz_emac_priv {
 	struct emac_common com;
@@ -99,6 +111,18 @@
 module_param(bonding, int, 0644);
 MODULE_PARM_DESC(bonding, "using bonding for emac0 and emac1");
 
+static inline bool is_qtn_oui_packet(unsigned char *pkt_header)
+{
+	if ((pkt_header[0] == (QTN_OUI & 0xFF)) &&
+		(pkt_header[1] == ((QTN_OUI >> 8) & 0xFF)) &&
+		(pkt_header[2] == ((QTN_OUI >> 16) & 0xFF)) &&
+		(pkt_header[3] >= QTN_OUIE_WIFI_CONTROL_MIN) &&
+		(pkt_header[3] <= QTN_OUIE_WIFI_CONTROL_MAX))
+		return true;
+	else
+		return false;
+}
+
 static void topaz_emac_start(struct net_device *dev)
 {
 	struct topaz_emac_priv *priv = netdev_priv(dev);
@@ -270,7 +294,7 @@
 
 	emac_lib_set_rx_mode(dev);
 	topaz_emac_start(dev);
-	emac_lib_pm_add_notifier(dev);
+	emac_lib_pm_emac_add_notifier(dev);
 	topaz_emac_enable_ints(dev);
 	emac_lib_phy_start(dev);
 	netif_start_queue(dev);
@@ -283,7 +307,7 @@
 static int topaz_emac_ndo_stop(struct net_device *dev)
 {
 	topaz_emac_disable_ints(dev);
-	emac_lib_pm_remove_notifier(dev);
+	emac_lib_pm_emac_remove_notifier(dev);
 	netif_stop_queue(dev);
 	emac_lib_phy_stop(dev);
 	topaz_emac_stop(dev);
@@ -297,7 +321,7 @@
 	union topaz_tqe_cpuif_ppctl ctl;
 	int8_t pool = TOPAZ_HBM_EMAC_TX_DONE_POOL;
 	int interface;
-
+	struct sk_buff *skb2;
 
 	for (interface = 0; interface < EMAC_MAX_INTERFACE; interface++){
 		/* In order to drop a packet, the following conditions has to be met:
@@ -306,17 +330,48 @@
 		 * skb->skb_iif the interface is Rx from emac0 or emac1
 		 */
 
-		if ((emac_xflow_disable) && (skb->skb_iif) && 
+		if ((emac_xflow_disable) && (skb->skb_iif) &&
 		    ((skb->skb_iif) == eth_ifindex[interface])){
 			dev_kfree_skb(skb);
 			return NETDEV_TX_OK;
 		}
         }
+
+	/*
+	 * restore VLAN tag to packet if needed
+	 */
+	skb2 = switch_vlan_restore_tag(skb, 1);
+	if (!skb2) {
+		printk(KERN_WARNING "failed to add VLAN tag back to header\n");
+		return NETDEV_TX_OK;
+	}
+
+	/*
+	 * VLAN egress check, for EMAC ports
+	 */
+	if (vlan_enabled
+			&& !switch_vlan_is_local(skb2->data)
+			&& !qtn_vlan_egress(vport_tbl_lhost[priv->tqe_port], 0, skb2->data)) {
+		dev_kfree_skb(skb2);
+		return NETDEV_TX_OK;
+	}
+
+	/* drop any WBSP control packet towards emac1 (Ethernet type 88b7)
+	Quantenna OUI (00 26 86) is located at data[14-16] followed by 1-byte type field [17] */
+	if ((emac_wbsp_ctrl == EMAC_WBSP_CTRL_ENABLED && dev->ifindex == eth_ifindex[1]) ||
+		(emac_wbsp_ctrl == EMAC_WBSP_CTRL_SWAPPED && dev->ifindex == eth_ifindex[0])) {
+		if (skb2->protocol == __constant_htons(ETHERTYPE_802A) &&
+			skb2->len > 17 && is_qtn_oui_packet(&skb2->data[14])) {
+			dev_kfree_skb(skb2);
+			return NETDEV_TX_OK;
+		}
+	}
+
 	topaz_tqe_cpuif_ppctl_init(&ctl,
 			priv->tqe_port, NULL, 1, 0,
 			0, 1, pool, 1, 0);
 
-	return tqe_tx(&ctl, skb);
+	return tqe_tx(&ctl, skb2);
 }
 
 static const struct net_device_ops topaz_emac_ndo = {
@@ -589,6 +644,37 @@
 	return mac_be[5] % 2;
 }
 
+static ssize_t topaz_emacx_wbsp_ctrl_sysfs_show(struct device *dev, struct device_attribute *attr,
+						char *buff)
+{
+	int count = 0;
+
+	count += sprintf(buff + count, "%d\n", emac_wbsp_ctrl);
+
+	return count;
+}
+
+static ssize_t topaz_emacx_wbsp_ctrl_sysfs_update(struct device *dev, struct device_attribute *attr,
+                const char *buf, size_t count)
+{
+        if (buf[0] == '0') {
+		emac_wbsp_ctrl = EMAC_WBSP_CTRL_DISABLED;
+        } else if (buf[0] == '1') {
+		emac_wbsp_ctrl = EMAC_WBSP_CTRL_ENABLED;
+	} else if (buf[0] == '2') {
+		emac_wbsp_ctrl = EMAC_WBSP_CTRL_SWAPPED;
+	}
+        return count;
+}
+
+static DEVICE_ATTR(device_emacx_wbsp_ctrl, S_IRUGO | S_IWUGO,
+		topaz_emacx_wbsp_ctrl_sysfs_show, topaz_emacx_wbsp_ctrl_sysfs_update);
+
+static int topaz_emacs_wbsp_ctrl_sysfs_create(struct net_device *net_dev)
+{
+	return sysfs_create_file(&net_dev->dev.kobj, &dev_attr_device_emacx_wbsp_ctrl.attr);
+}
+
 static void topaz_emac_tqe_rx_handler(void *token,
 		const union topaz_tqe_cpuif_descr *descr,
 		struct sk_buff *skb, uint8_t *whole_frm_hdr)
@@ -597,6 +683,20 @@
 
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, skb->dev);
+
+	/* discard WBSP control packet coming from emac1 (Ethernet type 88b7)
+	Note that in this receive routine, header has been removed from data buffer, so
+	Quantenna OUI (00 26 86) is now located at data[0-2] followed by 1-byte type field [3] */
+	if ((emac_wbsp_ctrl == EMAC_WBSP_CTRL_ENABLED && dev->ifindex == eth_ifindex[1]) ||
+		(emac_wbsp_ctrl == EMAC_WBSP_CTRL_SWAPPED && dev->ifindex == eth_ifindex[0])) {
+		if (skb->protocol == __constant_htons(ETHERTYPE_802A) &&
+			skb->len > 3 && is_qtn_oui_packet(&skb->data[0])) {
+			dev_kfree_skb(skb);
+			return;
+		}
+	}
+
+	switch_vlan_strip_tag(skb, 0);
 	netif_receive_skb(skb);
 }
 
@@ -651,6 +751,48 @@
 	return 0;
 }
 
+static void topaz_emac_set_outport(struct net_device *ndev, uint32_t enable)
+{
+#define TOPAZ_EMAC_OUTPORT_ENABLE	1
+#define TOPAZ_EMAC_OUTPORT_DISABLE	0
+	struct emac_common *privc;
+	union topaz_emac_rxp_outport_ctrl outport;
+	unsigned long flags;
+
+	privc = netdev_priv(ndev);
+
+	local_irq_save(flags);
+	outport.raw.word0 = emac_rd(privc, TOPAZ_EMAC_RXP_OUTPORT_CTRL);
+	if (enable) {
+		outport.data.static_port_sel = TOPAZ_TQE_LHOST_PORT;
+		outport.data.static_mode_en = TOPAZ_EMAC_OUTPORT_ENABLE;
+	} else {
+		outport.data.static_port_sel = 0;
+		outport.data.static_mode_en = TOPAZ_EMAC_OUTPORT_DISABLE;
+	}
+	emac_wr(privc, TOPAZ_EMAC_RXP_OUTPORT_CTRL, outport.raw.word0);
+	local_irq_restore(flags);
+}
+
+void topaz_emac_to_lhost(uint32_t enable)
+{
+	struct net_device *dev;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(iflist); i++) {
+		dev = topaz_emacs[i];
+		if (dev)
+			topaz_emac_set_outport(dev, enable);
+	}
+}
+EXPORT_SYMBOL(topaz_emac_to_lhost);
+
+int topaz_emac_get_bonding()
+{
+	return bonding;
+}
+EXPORT_SYMBOL(topaz_emac_get_bonding);
+
 static inline void topaz_emac_stop_rx(void)
 {
 	struct net_device *dev;
@@ -740,6 +882,7 @@
 	struct topaz_dpi_filter_request req;
 	struct topaz_dpi_field_def field;
 
+	/* ARP */
 	memset(&req, 0, sizeof(req));
 	memset(&field, 0, sizeof(field));
 
@@ -757,6 +900,23 @@
 	field.mask = 0xffff0000;
 
         topaz_dpi_filter_add(port_num, &req);
+
+	/* 8021Q && ARP */
+	memset(&req, 0, sizeof(req));
+	memset(&field, 0, sizeof(field));
+
+	req.fields = &field;
+	req.field_count = 1;
+	req.out_port = TOPAZ_TQE_LHOST_PORT;
+
+	field.ctrl.data.enable = TOPAZ_DPI_ENABLE;
+	field.ctrl.data.anchor = TOPAZ_DPI_ANCHOR_VLAN0;
+	field.ctrl.data.cmp_op = TOPAZ_DPI_CMPOP_EQ;
+	field.ctrl.data.offset = 1;
+	field.val = (ETH_P_ARP << 16);
+	field.mask = 0xffff0000;
+
+	topaz_dpi_filter_add(port_num, &req);
 }
 
 static void __init topaz_dpi_filter_dhcp(int port_num)
@@ -920,9 +1080,16 @@
 		goto netdev_register_error;
 	}
 
+	BUG_ON(priv->tqe_port != port_num);
+
+	if (switch_alloc_vlan_dev(port_num, EMAC_VDEV_IDX(port_num), dev->ifindex) == NULL) {
+		printk(KERN_ERR "%s: switch_alloc_vlan_dev returns error\n", __FUNCTION__);
+		goto tqe_register_error;
+	}
+
 	if (tqe_port_add_handler(port->tqe_port, &topaz_emac_tqe_rx_handler, dev)) {
 		printk(KERN_ERR "%s: topaz_port_add_handler returns error\n", __FUNCTION__);
-		goto tqe_register_error;
+		goto switch_vlan_alloc_error;
 	}
 
 	/* Send EMAC through soft reset */
@@ -953,6 +1120,7 @@
 	emac_lib_phy_power_create_proc(dev);
 	emac_lib_mdio_sysfs_create(dev);
 	topaz_emac_vlan_sel_sysfs_create(dev);
+	emac_lib_phy_reg_create_proc(dev);
 
 	if (bonding) {
 		fwt_sw_register_port_remapper(port->tqe_port, topaz_emac_fwt_sw_remap_port);
@@ -972,8 +1140,12 @@
 	topaz_emac_dscp_update_sysfs_create(dev);
 	topaz_emacs_update_sysfs_create(dev);
 
+	topaz_emacs_wbsp_ctrl_sysfs_create(dev);
+
 	return dev;
 
+switch_vlan_alloc_error:
+	switch_free_vlan_dev_by_idx(EMAC_VDEV_IDX(port_num));
 tqe_register_error:
 	unregister_netdev(dev);
 netdev_register_error:
@@ -996,6 +1168,7 @@
 
 	topaz_emac_ndo_stop(dev);
 
+	emac_lib_phy_reg_remove_proc(dev);
 	topaz_emac_vlan_sel_sysfs_remove(dev);
 	emac_lib_mdio_sysfs_remove(dev);
 	emac_lib_phy_power_remove_proc(dev);
@@ -1003,6 +1176,7 @@
 
 	tqe_port_unregister(priv->tqe_port);
 	tqe_port_remove_handler(priv->tqe_port);
+	switch_free_vlan_dev_by_idx(EMAC_VDEV_IDX(privc->mac_id));
 	unregister_netdev(dev);
 
 	emac_bufs_free(dev);
@@ -1023,10 +1197,75 @@
 	writel(ctrl, TOPAZ_TQE_EMAC_TDES_1_CNTL);
 }
 
+static int topaz_emac_find_emac(const struct net_device *const dev)
+{
+	int idx = 0;
+
+	while (idx < ARRAY_SIZE(iflist)) {
+		if (topaz_emacs[idx] == dev)
+			return idx;
+		++idx;
+	}
+
+	return -1;
+}
+
+static int topaz_emacs_connected_num(void)
+{
+	int idx = 0;
+	int in_use = 0;
+
+	while (idx < ARRAY_SIZE(iflist)) {
+		if (topaz_emac_on[idx])
+			++in_use;
+		++idx;
+	}
+
+	return in_use;
+}
+
+#define TOPAZ_EMAC_LINK_CHECK_PERIOD	5
+static int topaz_emac_link_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	unsigned int two_emacs_connected;
+	struct net_device *dev = ptr;
+	int emac_idx;
+
+	if (event != NETDEV_CHANGE) {
+		return NOTIFY_DONE;
+	}
+
+	emac_idx = topaz_emac_find_emac(dev);
+	if (emac_idx < 0)
+		return NOTIFY_DONE;
+
+	topaz_emac_on[emac_idx] = netif_carrier_ok(dev);
+
+	two_emacs_connected = (topaz_emacs_connected_num() > 1);
+	if (topaz_emac_prev_two_connected != two_emacs_connected) {
+		pm_flush_work(&topaz_emac_dual_emac_work);
+		topaz_emac_prev_two_connected = two_emacs_connected;
+		pm_queue_work(&topaz_emac_dual_emac_work, HZ * TOPAZ_EMAC_LINK_CHECK_PERIOD);
+	}
+
+	return NOTIFY_DONE;
+}
+
+void topaz_emac_work_fn(struct work_struct *work)
+{
+	emac_lib_update_link_vars(topaz_emac_prev_two_connected);
+}
+
+static struct notifier_block topaz_link_notifier = {
+	.notifier_call = topaz_emac_link_event,
+};
+
 static int __init topaz_emac_module_init(void)
 {
 	int i;
 	int found = 0;
+	int emac_cfg_p0, emac_cfg_p1;
+	int emac_phy;
 
 	if (!TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT) {
 		printk(KERN_ERR "%s: switch_emac should be used with topaz hbm skb allocator only\n", __FUNCTION__);
@@ -1039,7 +1278,21 @@
 	topaz_hbm_emac_rx_pool_intr_init();
 	topaz_hbm_emac_rx_pool_uf_intr_en();
 #endif
-	emac_lib_enable(1);
+	emac_lib_board_cfg(0, &emac_cfg_p0, &emac_phy);
+	emac_lib_board_cfg(1, &emac_cfg_p1, &emac_phy);
+
+	if (_read_hardware_revision() >= HARDWARE_REVISION_TOPAZ_A2) {
+		topaz_tqe_emac_reflect_to(TOPAZ_TQE_LHOST_PORT, bonding);
+		printk("enable A2 %s\n", bonding ? "(bonded)":"(single)");
+	}
+
+	/* We only use rtl switch as PHY, do not do reset which will restore
+	 * to switch mode again. Only do so when using rtl ethernet tranceiver.
+	 */
+	if (!emac_lib_rtl_switch(emac_cfg_p0 | emac_cfg_p1)) {
+		/* Reset ext PHY. This is for bug#11906 */
+		emac_lib_enable(1);
+	}
 
 	topaz_emac_init_tqe();
 	topaz_vlan_clear_all_entries();
@@ -1047,6 +1300,7 @@
 	for (i = 0; i < ARRAY_SIZE(iflist); i++) {
 		topaz_emacs[i] = topaz_emac_init(i);
 		if (topaz_emacs[i]) {
+			topaz_emac_on[i] = netif_carrier_ok(topaz_emacs[i]);
 			found++;
 		}
 	}
@@ -1056,6 +1310,12 @@
 		free_irq(TOPAZ_IRQ_HBM, topaz_emacs);
 #endif
 		return -ENODEV;
+	} else {
+		if (found > 1) {
+			INIT_DELAYED_WORK(&topaz_emac_dual_emac_work, topaz_emac_work_fn);
+			register_netdevice_notifier(&topaz_link_notifier);
+		}
+		emac_lib_pm_save_add_notifier();
 	}
 
 	return 0;
@@ -1064,12 +1324,23 @@
 static void __exit topaz_emac_module_exit(void)
 {
 	int i;
+	int found = 0;
 
 	for (i = 0; i < ARRAY_SIZE(iflist); i++) {
 		if (topaz_emacs[i]) {
 			topaz_emac_exit(topaz_emacs[i]);
+			++found;
 		}
 	}
+
+	if (found) {
+		emac_lib_pm_save_remove_notifier();
+	}
+
+	if (found > 1) {
+		unregister_netdevice_notifier(&topaz_link_notifier);
+		pm_flush_work(&topaz_emac_dual_emac_work);
+	}
 #ifdef TOPAZ_EMAC_NULL_BUF_WR
 	free_irq(TOPAZ_IRQ_HBM, topaz_emacs);
 #endif
diff --git a/drivers/topaz/switch_tqe.c b/drivers/topaz/switch_tqe.c
index 74b5a8a..96a9275 100644
--- a/drivers/topaz/switch_tqe.c
+++ b/drivers/topaz/switch_tqe.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/io.h>
+#include <linux/kernel.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -44,6 +45,7 @@
 #include <qtn/qtn_wowlan.h>
 #include <qtn/iputil.h>
 #include <qtn/mproc_sync.h>
+#include <qtn/qtn_vlan.h>
 
 int g_dscp_flag = 0;
 int g_dscp_value[2];
@@ -51,6 +53,10 @@
 uint16_t g_wowlan_match_type = 0;
 uint16_t g_wowlan_l2_ether_type = 0x0842;
 uint16_t g_wowlan_l3_udp_port = 0xffff;
+uint8_t g_l2_ext_filter = 0;
+uint8_t g_l2_ext_filter_port = TOPAZ_TQE_NUM_PORTS;
+EXPORT_SYMBOL(g_l2_ext_filter);
+EXPORT_SYMBOL(g_l2_ext_filter_port);
 EXPORT_SYMBOL(g_wowlan_host_state);
 EXPORT_SYMBOL(g_wowlan_match_type);
 EXPORT_SYMBOL(g_wowlan_l2_ether_type);
@@ -73,6 +79,11 @@
 static tqe_fwt_get_mcast_hook g_tqe_fwt_get_mcast_hook = NULL;
 static tqe_fwt_get_mcast_ff_hook g_tqe_fwt_get_mcast_ff_hook = NULL;
 static tqe_fwt_get_ucast_hook g_tqe_fwt_get_ucast_hook = NULL;
+static tqe_fwt_false_miss_hook g_tqe_fwt_false_miss_hook = NULL;
+static tqe_fwt_get_from_mac_hook g_tqe_fwt_get_from_mac_hook = NULL;
+
+static tqe_mac_reserved_hook g_tqe_mac_reserved_hook = NULL;
+static inline void __sram_text tqe_rx_pkt_drop(const union topaz_tqe_cpuif_descr *desc);
 
 static struct {
 	tqe_port_handler handler;
@@ -232,7 +243,7 @@
 		return 1;
 
 	prtcnt = 0;
-	while (_qtn_mproc_3way_sem_down(TOPAZ_MPROC_TQE_SEM_LHOST) == 0) {
+	while (_qtn_mproc_3way_tqe_sem_down(TOPAZ_MPROC_TQE_SEM_LHOST) == 0) {
 		if ((prtcnt & 0xff) == 0)
 			printk("%s line %d fail to get tqe semaphore\n", funcname, linenum);
 		prtcnt++;
@@ -248,10 +259,10 @@
 	if (tqe_sem_en == 0)
 		return 1;
 
-	if (_qtn_mproc_3way_sem_up(TOPAZ_MPROC_TQE_SEM_LHOST)) {
+	if (_qtn_mproc_3way_tqe_sem_up(TOPAZ_MPROC_TQE_SEM_LHOST)) {
 		return 1;
 	} else {
-		panic("switch tqe fail to relese HW semaphore\n");
+		WARN_ONCE(1, "%s failed to relese HW semaphore\n", __func__);
 		return 0;
 	}
 }
@@ -348,6 +359,19 @@
 	const uint16_t misc_user = 0;
 	void *queue = token2;
 	uint8_t tqe_free = queue ? 0 : 1;
+	struct qtn_vlan_dev *vdev;
+
+	/*
+	 * VLAN egress check -- multicast forwarding
+	 * for out_port==WMAC, AuC handles egress
+	 */
+	if (vlan_enabled && TOPAZ_TQE_PORT_IS_EMAC(port)) {
+		vdev = vport_tbl_lhost[port];
+		if (!qtn_vlan_egress(vdev, 0, bus_to_virt((uintptr_t)desc->data.pkt))) {
+			tqe_rx_pkt_drop(desc);
+			return;
+		}
+	}
 
 	topaz_tqe_cpuif_ppctl_init(&ppctl,
 			port, &node, 1, tid,
@@ -447,6 +471,27 @@
 	return 0;
 }
 
+inline
+const uint16_t *
+tqe_rx_ether_type_skip_vlan(const struct ether_header *eh, uint32_t len)
+{
+	const uint16_t *ether_type = &eh->ether_type;
+
+	if (len < sizeof(struct ether_header)) {
+		return NULL;
+	}
+
+	while(qtn_ether_type_is_vlan(*ether_type)) {
+		if (len < sizeof(struct ether_header) + VLAN_HLEN) {
+			return NULL;
+		}
+		ether_type += VLAN_HLEN / sizeof(*ether_type);
+		len -= VLAN_HLEN;
+	}
+
+	return ether_type;
+}
+
 int __sram_text tqe_rx_multicast(void *congest_queue, const union topaz_tqe_cpuif_descr *desc)
 {
 	int timeout;
@@ -456,21 +501,27 @@
 	const enum topaz_tqe_port in_port = desc->data.in_port;
 	const void *ipaddr = NULL;
 	uint8_t tid = 0;
-	const uint16_t *ether_type = &eh->ether_type;
+	const uint16_t *ether_type = tqe_rx_ether_type_skip_vlan(eh, desc->data.length);
 	const void *iphdr = NULL;
 	uint8_t vlan_index;
 	uint8_t in_node = 0;
 	uint32_t header_access_bytes = 0;
+	uint32_t ether_payload_length = 0;
+	uint8_t false_miss = 0;
 
-	while (*ether_type == __constant_htons(ETH_P_8021Q))
-		ether_type += 2;
+	if (unlikely(!ether_type)) {
+		printk(KERN_WARNING "%s: malformed packet in_port %u\n", __FUNCTION__, in_port);
+		return 0;
+	}
 
 	iphdr = ether_type + 1;
+	ether_payload_length = desc->data.length - ((char *)iphdr - (char *)eh);
 	header_access_bytes = iphdr - (const void *)eh;
 
 	/* FIXME: this won't work for 802.3 frames */
 	if (*ether_type == __constant_htons(ETH_P_IP)
-			&& iputil_mac_is_v4_multicast(eh->ether_dhost)) {
+			&& iputil_mac_is_v4_multicast(eh->ether_dhost)
+			&& (ether_payload_length >= sizeof(struct qtn_ipv4))) {
 		const struct qtn_ipv4 *ipv4 = (const struct qtn_ipv4 *)iphdr;
 		/* do not accelerate IGMP */
 		if (ipv4->proto == QTN_IP_PROTO_IGMP) {
@@ -481,7 +532,8 @@
 		/* Option field doesn't take into account because they are not accessed */
 		header_access_bytes += sizeof (struct qtn_ipv4);
 	} else if (*ether_type == __constant_htons(ETH_P_IPV6)
-			&& iputil_mac_is_v6_multicast(eh->ether_dhost)) {
+			&& iputil_mac_is_v6_multicast(eh->ether_dhost)
+			&& (ether_payload_length >= sizeof(struct qtn_ipv6))) {
 		const struct qtn_ipv6 *ipv6 = (const struct qtn_ipv6 *)iphdr;
 		ipaddr = &ipv6->dstip;
 
@@ -490,10 +542,17 @@
 
 	if (ipaddr) {
 		topaz_tqe_vlan_gettid(desc->data.pkt, &tid, &vlan_index);
-		fwt_lu = __topaz_fwt_hw_lookup_wait_be(eh->ether_dhost, &timeout);
-		if (fwt_lu.data.valid && !timeout && g_tqe_fwt_get_mcast_hook) {
-			mcast_ent = g_tqe_fwt_get_mcast_hook(fwt_lu.data.entry_addr,
-					ipaddr, *ether_type, vlan_index);
+		fwt_lu = topaz_fwt_hw_lookup_wait_be(eh->ether_dhost, &timeout, &false_miss);
+		if (fwt_lu.data.valid && !timeout) {
+#ifndef TOPAZ_DISABLE_FWT_WAR
+			if (unlikely(false_miss && g_tqe_fwt_false_miss_hook))
+				g_tqe_fwt_false_miss_hook(fwt_lu.data.entry_addr, false_miss);
+#endif
+
+			if (g_tqe_fwt_get_mcast_hook)
+				mcast_ent = g_tqe_fwt_get_mcast_hook(fwt_lu.data.entry_addr,
+						ipaddr, *ether_type, vlan_index);
+
 			if (mcast_ent) {
 				if ((mcast_ent->flood_forward) && (in_port == TOPAZ_TQE_MUC_PORT)) {
 					in_node = tqe_rx_get_node_id(eh);
@@ -525,14 +584,11 @@
 	local_irq_restore(flags);
 }
 
-static inline int __sram_text tqe_rx_vlan_terminate(const union topaz_tqe_cpuif_descr *desc)
+void tqe_register_mac_reserved_cbk(tqe_mac_reserved_hook cbk_func)
 {
-	if (desc->data.misc_user & TQE_MISCUSER_M2L_DROP) {
-		tqe_rx_pkt_drop(desc);
-		return 1;
-	}
-	return 0;
+	g_tqe_mac_reserved_hook = cbk_func;
 }
+EXPORT_SYMBOL(tqe_register_mac_reserved_cbk);
 
 void tqe_register_ucastfwt_cbk(tqe_fwt_get_ucast_hook cbk_func)
 {
@@ -540,6 +596,12 @@
 }
 EXPORT_SYMBOL(tqe_register_ucastfwt_cbk);
 
+void tqe_register_macfwt_cbk(tqe_fwt_get_from_mac_hook cbk_func)
+{
+	 g_tqe_fwt_get_from_mac_hook = cbk_func;
+}
+EXPORT_SYMBOL(tqe_register_macfwt_cbk);
+
 static int topaz_swfwd_tqe_xmit(const fwt_db_entry *fwt_ent,
 				const union topaz_tqe_cpuif_descr *desc,
 				void *queue)
@@ -552,11 +614,24 @@
 	uint8_t portal;
 	uint8_t vlan_index;
 	uint8_t tqe_free = queue ? 0 : 1;
+	struct qtn_vlan_dev *vdev;
 
 	if (fwt_ent->out_port == TOPAZ_TQE_LHOST_PORT)
 		return 0;
 
-	if ((desc->data.in_port == TOPAZ_TQE_EMAC_0_PORT) || (desc->data.in_port == TOPAZ_TQE_EMAC_1_PORT)){
+	/*
+	 * VLAN egress check -- unicast forwarding
+	 * for out_port==WMAC, AuC handles egress
+	 */
+	if (vlan_enabled && TOPAZ_TQE_PORT_IS_EMAC(fwt_ent->out_port)) {
+		vdev = vport_tbl_lhost[fwt_ent->out_port];
+		if (!qtn_vlan_egress(vdev, 0, bus_to_virt((uintptr_t)desc->data.pkt))) {
+			tqe_rx_pkt_drop(desc);
+			return 1;
+		}
+	}
+
+	if (TOPAZ_TQE_PORT_IS_EMAC(desc->data.in_port)) {
 		if(g_dscp_flag){
 			tid = (g_dscp_value[desc->data.in_port] & 0xFF);
 		} else {
@@ -697,16 +772,25 @@
 int wowlan_magic_packet_check(const union topaz_tqe_cpuif_descr *desc)
 {
 	const struct ether_header *eh = bus_to_virt((uintptr_t) desc->data.pkt);
-	const uint16_t *ether_type = &eh->ether_type;
+	const uint16_t *ether_type = NULL;
 	const void *iphdr = NULL;
+	uint32_t ether_payload_length = 0;
 
 	if (likely(!g_wowlan_host_state) ||
 			(desc->data.in_port != TOPAZ_TQE_MUC_PORT))
 		return 0;
 
-	while (*ether_type == __constant_htons(ETH_P_8021Q))
-		ether_type += 2;
+	ether_type = tqe_rx_ether_type_skip_vlan(eh, desc->data.length);
+	if (unlikely(!ether_type)) {
+		return 0;
+	}
+
 	iphdr = (void *)(ether_type + 1);
+	ether_payload_length = desc->data.length - ((char *)iphdr - (char *)eh);
+	if ((*ether_type == __constant_htons(ETH_P_IP))
+			&& (ether_payload_length < sizeof(struct iphdr))) {
+		return 0;
+	}
 
 	return wowlan_is_magic_packet(*ether_type, eh, iphdr,
 			g_wowlan_match_type,
@@ -714,13 +798,61 @@
 			g_wowlan_l3_udp_port);
 }
 
-static int __sram_text tqe_rx_desc_handler(const struct tqe_netdev_priv *priv, const union topaz_tqe_cpuif_descr *desc)
+static int tqe_rx_l2_ext_filter_handler(union topaz_tqe_cpuif_descr *desc, struct sk_buff *skb)
+{
+	enum topaz_tqe_port in_port = desc->data.in_port;
+	const struct fwt_db_entry *fwt_ent;
+	const struct ether_header *eh = bus_to_virt((uintptr_t) desc->data.pkt);
+
+	if (in_port != g_l2_ext_filter_port)
+		return 0;
+
+	if (unlikely(!g_tqe_fwt_get_from_mac_hook))
+		return 0;
+
+	fwt_ent = g_tqe_fwt_get_from_mac_hook(eh->ether_shost);
+	if (unlikely(!fwt_ent))
+		return 0;
+
+	if (TOPAZ_TQE_PORT_IS_WMAC(fwt_ent->out_port)) {
+		/* Change the in port to prevent FWT updates */
+		desc->data.in_port = TOPAZ_TQE_MUC_PORT;
+		desc->data.misc_user = fwt_ent->out_node;
+		skb->ext_l2_filter = 1;
+		return 1;
+	}
+
+	return 0;
+}
+
+int __sram_text tqe_rx_l2_ext_filter(union topaz_tqe_cpuif_descr *desc, struct sk_buff *skb)
+{
+	if (unlikely(g_l2_ext_filter))
+		return tqe_rx_l2_ext_filter_handler(desc, skb);
+
+	return 0;
+}
+EXPORT_SYMBOL(tqe_rx_l2_ext_filter);
+
+void __sram_text tqe_rx_call_port_handler(union topaz_tqe_cpuif_descr *desc,
+		struct sk_buff *skb, uint8_t *whole_frm_hdr)
+{
+	enum topaz_tqe_port in_port = desc->data.in_port;
+
+	tqe_port_handlers[in_port].handler(tqe_port_handlers[in_port].token,
+						desc, skb, whole_frm_hdr);
+}
+EXPORT_SYMBOL(tqe_rx_call_port_handler);
+
+static int __sram_text tqe_rx_desc_handler(const struct tqe_netdev_priv *priv, union topaz_tqe_cpuif_descr *desc)
 {
 	enum topaz_tqe_port in_port = desc->data.in_port;
 	void *buf_bus_rx = desc->data.pkt;
 	void *buf_virt_rx = bus_to_virt((unsigned long) buf_bus_rx);
 	uint16_t buflen = desc->data.length;
 	const int8_t pool = topaz_hbm_payload_get_pool_bus(buf_bus_rx);
+	const struct ether_header *eh = bus_to_virt((uintptr_t) desc->data.pkt);
+	uint8_t vinfo_hdr = 0;
 
 	if (unlikely(buf_bus_rx == NULL)) {
 		if (printk_ratelimit()) {
@@ -730,6 +862,13 @@
 		return -1;
 	}
 
+	if (unlikely(buflen < ETH_HLEN)) {
+		printk(KERN_WARNING
+			"%s: buffer from TQE smaller than ethernet header, len %u, in port %u",
+							__FUNCTION__, buflen, in_port);
+		return -1;
+	}
+
 	if (unlikely(!topaz_hbm_pool_valid(pool))) {
 		printk(KERN_CRIT "%s: invalid pool buffer from TQE: 0x%p", __FUNCTION__, buf_bus_rx);
 		return -1;
@@ -748,9 +887,30 @@
 #if defined(CONFIG_ARCH_TOPAZ_SWITCH_TEST) || defined(CONFIG_ARCH_TOPAZ_SWITCH_TEST_MODULE)
 		topaz_tqe_test_ctrl(buf_virt_rx);
 #endif
-		if (likely(!wowlan_magic_packet_check(desc))) {
-			if (tqe_rx_vlan_terminate(desc))
+		if (TOPAZ_TQE_PORT_IS_EMAC(in_port)) {
+			if (vlan_enabled) {
+				struct qtn_vlan_dev *vdev = vport_tbl_lhost[in_port];
+				BUG_ON(vdev == NULL);
+
+				if (!qtn_vlan_ingress(vdev, 0,
+						buf_virt_rx, 0, 1)) {
+					tqe_rx_pkt_drop(desc);
+					return 0;
+				}
+			}
+		} else if (unlikely(((in_port == TOPAZ_TQE_WMAC_PORT) || (in_port == TOPAZ_TQE_MUC_PORT)))) {
+			if (g_tqe_mac_reserved_hook && g_tqe_mac_reserved_hook(eh->ether_shost)) {
+				tqe_rx_pkt_drop(desc);
 				return 0;
+			}
+		} else {
+			BUG_ON(1);
+		}
+
+		if (vlan_enabled)
+			vinfo_hdr = QVLAN_PKTCTRL_LEN;
+
+		if (likely(!wowlan_magic_packet_check(desc))) {
 #ifdef CONFIG_TOPAZ_PCIE_HOST
 			if (tqe_rx_multicast(NULL, desc))
 #else
@@ -775,13 +935,26 @@
 		else
 #endif
 		{
-			skb = topaz_hbm_attach_skb(buf_virt_rx, pool);
+			skb = topaz_hbm_attach_skb((uint8_t *)buf_virt_rx, pool, vinfo_hdr);
 			whole_frm_hdr = skb->head;
 		}
 		if (skb) {
+			/* attach VLAN information to skb */
 			skb_put(skb, buflen);
-			tqe_port_handlers[in_port].handler(
-				tqe_port_handlers[in_port].token, desc, skb, whole_frm_hdr);
+			if (vlan_enabled) {
+				struct qtn_vlan_pkt *pkt = qtn_vlan_get_info(skb->data);
+				if (unlikely(pkt->magic != QVLAN_PKT_MAGIC)) {
+					printk(KERN_WARNING "WARNING: pkt(%p) magic not right. 0x%04x\n", skb->data, pkt->magic);
+				} else {
+					skb->vlan_tci = pkt->vlan_info & QVLAN_MASK_VID;
+				}
+				M_FLAG_SET(skb, M_VLAN_TAGGED);
+			}
+
+			/* Frame received from external L2 filter will not have MAC header */
+			if (tqe_rx_l2_ext_filter(desc, skb))
+				whole_frm_hdr = NULL;
+			tqe_rx_call_port_handler(desc, skb, whole_frm_hdr);
 			return 0;
 		}
 
@@ -901,10 +1074,12 @@
 }
 
 void tqe_register_fwt_cbk(tqe_fwt_get_mcast_hook get_mcast_cbk_func,
-				tqe_fwt_get_mcast_ff_hook get_mcast_ff_cbk_func)
+				tqe_fwt_get_mcast_ff_hook get_mcast_ff_cbk_func,
+				tqe_fwt_false_miss_hook false_miss_func)
 {
 	g_tqe_fwt_get_mcast_hook = get_mcast_cbk_func;
 	g_tqe_fwt_get_mcast_ff_hook = get_mcast_ff_cbk_func;
+	g_tqe_fwt_false_miss_hook = false_miss_func;
 }
 EXPORT_SYMBOL(tqe_register_fwt_cbk);
 
@@ -913,8 +1088,10 @@
 	unsigned int data_len = skb->len;
 	void *buf_virt = skb->data;
 	void *buf_bus = (void *) virt_to_bus(buf_virt);
+	void *buf_virt_vlan;
 	int8_t pool = topaz_hbm_payload_get_pool_bus(buf_bus);
-	const bool hbm_can_use = topaz_hbm_pool_valid(pool) &&
+	const bool hbm_can_use = !vlan_enabled &&
+		topaz_hbm_pool_valid(pool) &&
 		(atomic_read(&skb->users) == 1) &&
 		(atomic_read(&skb_shinfo(skb)->dataref) == 1);
 
@@ -930,6 +1107,11 @@
 		void *hbm_buf_virt;
 		uintptr_t flush_start;
 		size_t flush_size;
+		int from_local = 0;
+
+		if (vlan_enabled && ppctl->data.out_port == TOPAZ_TQE_WMAC_PORT) {
+			from_local = switch_vlan_is_local(buf_virt);
+		}
 
 		if (data_len < TOPAZ_HBM_BUF_EMAC_RX_SIZE) {
 			pool = TOPAZ_HBM_BUF_EMAC_RX_POOL;
@@ -957,8 +1139,24 @@
 		memcpy(hbm_buf_virt, buf_virt, data_len);
 		buf_virt = hbm_buf_virt;
 
-		flush_start = (uintptr_t) align_buf_cache(buf_virt);
-		flush_size = align_buf_cache_size(buf_virt, data_len);
+		if (from_local) {
+			struct qtn_vlan_pkt *pkt = (struct qtn_vlan_pkt *)((uint8_t *)buf_virt - QVLAN_PKTCTRL_LEN);
+			pkt->magic = QVLAN_PKT_MAGIC;
+			pkt->vlan_info = QVLAN_SKIP_CHECK;
+
+			flush_start = (uintptr_t) align_buf_cache((uint8_t *)buf_virt - QVLAN_PKTCTRL_LEN);
+			flush_size = align_buf_cache_size((uint8_t *)buf_virt - QVLAN_PKTCTRL_LEN, data_len + QVLAN_PKTCTRL_LEN);
+		} else if (M_FLAG_ISSET(skb, M_VLAN_TAGGED)) {
+			buf_virt_vlan = qtn_vlan_get_info(buf_virt);
+			memcpy(buf_virt_vlan, (uint8_t *)qtn_vlan_get_info(skb->data),
+					QVLAN_PKTCTRL_LEN);
+			flush_start = (uintptr_t) align_buf_cache(buf_virt_vlan);
+			flush_size = align_buf_cache_size(buf_virt_vlan, data_len + QVLAN_PKTCTRL_LEN);
+		} else {
+			flush_start = (uintptr_t) align_buf_cache(buf_virt);
+			flush_size = align_buf_cache_size(buf_virt, data_len);
+		}
+
 		flush_and_inv_dcache_range(flush_start, flush_start + flush_size);
 	}
 	dev_kfree_skb(skb);
@@ -1138,6 +1336,7 @@
 	tqe_irq_enable();
 
 	device_create_file(&dev->dev, &dev_attr_dbg);
+
 	return dev;
 
 netdev_register_error:
diff --git a/drivers/topaz/switch_vlan.c b/drivers/topaz/switch_vlan.c
new file mode 100644
index 0000000..89914c3
--- /dev/null
+++ b/drivers/topaz/switch_vlan.c
@@ -0,0 +1,658 @@
+/**
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ **/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_vlan.h>
+#include <linux/spinlock.h>
+
+#include <net80211/if_ethersubr.h>
+#include <qtn/topaz_tqe_cpuif.h>
+#include <qtn/qtn_skb_cb.h>
+#include <qtn/qtn_vlan.h>
+#include <qtn/lhost_muc_comm.h>
+#include <drivers/ruby/emac_lib.h>
+
+__sram_data uint8_t vlan_enabled;
+EXPORT_SYMBOL(vlan_enabled);
+
+__sram_data struct qtn_vlan_dev *vdev_tbl_lhost[VLAN_INTERFACE_MAX];
+EXPORT_SYMBOL(vdev_tbl_lhost);
+
+__sram_data struct qtn_vlan_dev *vdev_tbl_bus[VLAN_INTERFACE_MAX];
+EXPORT_SYMBOL(vdev_tbl_bus);
+
+__sram_data struct qtn_vlan_dev *vport_tbl_lhost[TOPAZ_TQE_NUM_PORTS];
+EXPORT_SYMBOL(vport_tbl_lhost);
+
+__sram_data struct qtn_vlan_dev *vport_tbl_bus[TOPAZ_TQE_NUM_PORTS];
+EXPORT_SYMBOL(vport_tbl_bus);
+
+struct qtn_vlan_info qtn_vlan_info;
+EXPORT_SYMBOL(qtn_vlan_info);
+
+static DEFINE_SPINLOCK(lock);
+
+#define         SWITCH_VLAN_LOCAL_INTERFACE_NAME    "br0"
+#define		SWITCH_VLAN_PROC	"topaz_vlan"
+
+static inline void __switch_vlan_add_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	set_bit_a(vdev->u.member_bitmap, vid);
+}
+
+static inline void __switch_vlan_del_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	clr_bit_a(vdev->u.member_bitmap, vid);
+}
+
+static inline void __switch_vlan_tag_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	set_bit_a(vdev->tag_bitmap, vid);
+}
+
+static inline void __switch_vlan_untag_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	clr_bit_a(vdev->tag_bitmap, vid);
+}
+
+static inline void
+switch_vlan_set_tagrx(struct qtn_vlan_info *vlan_info, uint16_t vlanid, uint8_t tagrx)
+{
+	uint32_t *tagrx_bitmap = vlan_info->vlan_tagrx_bitmap;
+	tagrx = tagrx & QVLAN_TAGRX_BITMASK;
+
+	tagrx_bitmap[qvlan_tagrx_index(vlanid)] &=
+		~(QVLAN_TAGRX_BITMASK << qvlan_tagrx_shift(vlanid));
+
+	tagrx_bitmap[qvlan_tagrx_index(vlanid)] |=
+		tagrx << (qvlan_tagrx_shift(vlanid));
+}
+
+static inline int switch_vlan_manage_tagrx(struct qtn_vlan_dev *vdev,
+		uint16_t vlanid, uint8_t tag, uint32_t member_quit)
+{
+	struct qtn_vlan_dev *other_dev;
+
+	if (vdev->port == TOPAZ_TQE_EMAC_0_PORT)
+		other_dev = vport_tbl_lhost[TOPAZ_TQE_EMAC_1_PORT];
+	else if (vdev->port == TOPAZ_TQE_EMAC_1_PORT)
+		other_dev = vport_tbl_lhost[TOPAZ_TQE_EMAC_0_PORT];
+	else if (vdev->port == TOPAZ_TQE_PCIE_PORT || vdev->port == TOPAZ_TQE_DSP_PORT) {
+		other_dev = NULL;
+	} else {
+		return qtn_vlan_get_tagrx(qtn_vlan_info.vlan_tagrx_bitmap, vlanid);
+	}
+
+	if (other_dev && !member_quit
+			&& qtn_vlan_is_member(other_dev, vlanid)
+			&& qtn_vlan_is_tagged_member(other_dev, vlanid) != !!tag) {
+		/*
+		 * NOTE: All ethernet ports should have the same tag/untag config
+		 * for one VLAN ID. This is to avoid confusion for multicast packets
+		 * destined for multiple ethernet ports.
+		 */
+		printk(KERN_INFO"Warning:port %u forced to %s VLAN %u packets\n",
+			other_dev->port, tag ? "tag" : "untag", vlanid);
+
+		if (tag)
+			__switch_vlan_tag_member(other_dev, vlanid);
+		else
+			__switch_vlan_untag_member(other_dev, vlanid);
+	} else if (member_quit) {
+		if (!other_dev || !qtn_vlan_is_member(other_dev, vlanid))
+			return QVLAN_TAGRX_UNTOUCH;
+		else
+			return qtn_vlan_get_tagrx(qtn_vlan_info.vlan_tagrx_bitmap, vlanid);
+	}
+
+	return (tag ? QVLAN_TAGRX_TAG : QVLAN_TAGRX_STRIP);
+}
+
+static void switch_vlan_add(struct qtn_vlan_dev *vdev, uint16_t vlanid, uint8_t tag)
+{
+	int tagrx;
+
+	if (!qtn_vlan_is_member(vdev, vlanid)) {
+		__switch_vlan_add_member(vdev, vlanid);
+	}
+
+	/* update tag bitmap */
+	if (tag)
+		__switch_vlan_tag_member(vdev, vlanid);
+	else
+		__switch_vlan_untag_member(vdev, vlanid);
+
+	tagrx = switch_vlan_manage_tagrx(vdev, vlanid, tag, 0);
+	switch_vlan_set_tagrx(&qtn_vlan_info, vlanid, tagrx);
+}
+
+static void switch_vlan_del(struct qtn_vlan_dev *vdev, uint16_t vlanid)
+{
+	int tagrx;
+	if (!qtn_vlan_is_member(vdev, vlanid))
+		return;
+
+	tagrx = switch_vlan_manage_tagrx(vdev, vlanid, 0, 1);
+	switch_vlan_set_tagrx(&qtn_vlan_info, vlanid, tagrx);
+
+	__switch_vlan_del_member(vdev, vlanid);
+	__switch_vlan_untag_member(vdev, vlanid);
+}
+
+struct qtn_vlan_dev *switch_alloc_vlan_dev(uint8_t port, uint8_t idx, int ifindex)
+{
+	struct qtn_vlan_dev *vdev = NULL;
+	struct qtn_vlan_user_interface *vintf = NULL;
+	dma_addr_t bus_addr, bus_addr2;
+
+	spin_lock_bh(&lock);
+
+	if (vdev_tbl_lhost[idx] != NULL)
+		goto out;
+
+	vdev = (struct qtn_vlan_dev *)dma_alloc_coherent(NULL,
+		sizeof(struct qtn_vlan_dev), &bus_addr, GFP_ATOMIC);
+	if (!vdev)
+		goto out;
+
+	memset(vdev, 0, sizeof(*vdev));
+	vdev->pvid = QVLAN_DEF_PVID;
+	vdev->bus_addr = (unsigned long)bus_addr;
+	vdev->port = port;
+	vdev->idx = idx;
+	vdev->ifindex = ifindex;
+
+	vintf = (struct qtn_vlan_user_interface *)dma_alloc_coherent(NULL,
+		sizeof(struct qtn_vlan_user_interface), &bus_addr2, GFP_ATOMIC);
+	if (!vintf)
+		goto out;
+
+	memset(vintf, 0, sizeof(*vintf));
+	vintf->bus_addr = bus_addr2;
+	vintf->mode = QVLAN_MODE_ACCESS;
+	vdev->user_data = (void *)vintf;
+
+	arc_write_uncached_32((uint32_t *)&vdev_tbl_lhost[idx], (uint32_t)vdev);
+	arc_write_uncached_32((uint32_t *)&vdev_tbl_bus[idx], (uint32_t)bus_addr);
+
+	if (qtn_vlan_port_indexable(port)) {
+		arc_write_uncached_32((uint32_t *)&vport_tbl_lhost[port], (uint32_t)vdev);
+		arc_write_uncached_32((uint32_t *)&vport_tbl_bus[port], (uint32_t)bus_addr);
+	}
+
+	switch_vlan_add(vdev, vdev->pvid, 0);
+
+	spin_unlock_bh(&lock);
+	return vdev;
+
+out:
+	if (vdev)
+		dma_free_coherent(NULL, sizeof(struct qtn_vlan_dev), vdev, (dma_addr_t)(vdev->bus_addr));
+	spin_unlock_bh(&lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(switch_alloc_vlan_dev);
+
+void switch_free_vlan_dev(struct qtn_vlan_dev *vdev)
+{
+	struct qtn_vlan_user_interface *vintf = (struct qtn_vlan_user_interface *)vdev->user_data;
+
+	spin_lock_bh(&lock);
+	/* vlan_info_tbl[info->idx] = NULL; */
+	arc_write_uncached_32((uint32_t *)&vdev_tbl_lhost[vdev->idx], (uint32_t)NULL);
+	arc_write_uncached_32((uint32_t *)&vdev_tbl_bus[vdev->idx], (uint32_t)NULL);
+
+	if (qtn_vlan_port_indexable(vdev->port)) {
+		arc_write_uncached_32((uint32_t *)&vport_tbl_lhost[vdev->idx], (uint32_t)NULL);
+		arc_write_uncached_32((uint32_t *)&vport_tbl_bus[vdev->idx], (uint32_t)NULL);
+	}
+	spin_unlock_bh(&lock);
+
+	dma_free_coherent(NULL, sizeof(struct qtn_vlan_dev), vdev, (dma_addr_t)(vdev->bus_addr));
+	dma_free_coherent(NULL, sizeof(struct qtn_vlan_user_interface), vintf, (dma_addr_t)(vintf->bus_addr));
+}
+EXPORT_SYMBOL(switch_free_vlan_dev);
+
+void switch_free_vlan_dev_by_idx(uint8_t idx)
+{
+	BUG_ON(idx >= VLAN_INTERFACE_MAX);
+
+	switch_free_vlan_dev(vdev_tbl_lhost[idx]);
+}
+EXPORT_SYMBOL(switch_free_vlan_dev_by_idx);
+
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+static enum topaz_tqe_port g_topaz_tqe_pcie_rel_port = TOPAZ_TQE_DUMMY_PORT;
+void tqe_register_pcie_rel_port(const enum topaz_tqe_port tqe_port)
+{
+	g_topaz_tqe_pcie_rel_port = tqe_port;
+}
+EXPORT_SYMBOL(tqe_register_pcie_rel_port);
+#endif
+
+struct qtn_vlan_dev*
+switch_vlan_dev_get_by_port(uint8_t port)
+{
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+	uint8_t dev_id = EXTRACT_DEV_ID_FROM_PORT_ID(port);
+
+	port = EXTRACT_PORT_ID_FROM_PORT_ID(port);
+
+	if (port == g_topaz_tqe_pcie_rel_port)
+		return vdev_tbl_lhost[QFP_VDEV_IDX(dev_id)];
+#endif
+	return vport_tbl_lhost[port];
+}
+EXPORT_SYMBOL(switch_vlan_dev_get_by_port);
+
+struct qtn_vlan_dev*
+switch_vlan_dev_get_by_idx(uint8_t idx)
+{
+	return vdev_tbl_lhost[idx];
+}
+EXPORT_SYMBOL(switch_vlan_dev_get_by_idx);
+
+typedef void (*_fn_vlan_member)(struct qtn_vlan_dev *vdev,
+			uint16_t vid, uint8_t tag);
+static int switch_vlan_member_comm(struct qtn_vlan_dev *vdev, uint16_t vid,
+		uint8_t tag, _fn_vlan_member handler)
+{
+	if (vid == QVLAN_VID_ALL) {
+		for (vid = 0; vid < QVLAN_VID_MAX; vid++)
+			handler(vdev, vid, tag);
+	} else if (vid < QVLAN_VID_MAX) {
+		handler(vdev, vid, tag);
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void _vlan_add_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t tag)
+{
+	spin_lock_bh(&lock);
+	switch_vlan_add(vdev, vid, tag);
+	spin_unlock_bh(&lock);
+}
+
+int switch_vlan_add_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t tag)
+{
+	return switch_vlan_member_comm(vdev, vid, tag, _vlan_add_member);
+}
+EXPORT_SYMBOL(switch_vlan_add_member);
+
+static void _vlan_del_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t arg)
+{
+	spin_lock_bh(&lock);
+	switch_vlan_del(vdev, vid);
+	spin_unlock_bh(&lock);
+}
+
+int switch_vlan_del_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	return switch_vlan_member_comm(vdev, vid, 0, _vlan_del_member);
+}
+EXPORT_SYMBOL(switch_vlan_del_member);
+
+static void _vlan_tag_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t arg)
+{
+	int tagrx;
+	spin_lock_bh(&lock);
+	if (!qtn_vlan_is_member(vdev, vid))
+		goto out;
+
+	__switch_vlan_tag_member(vdev, vid);
+	tagrx = switch_vlan_manage_tagrx(vdev, vid, 1, 0);
+	switch_vlan_set_tagrx(&qtn_vlan_info, vid, tagrx);
+out:
+	spin_unlock_bh(&lock);
+}
+
+int switch_vlan_tag_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	return switch_vlan_member_comm(vdev, vid, 0, _vlan_tag_member);
+}
+EXPORT_SYMBOL(switch_vlan_tag_member);
+
+static void _vlan_untag_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t arg)
+{
+	int tagrx;
+	spin_lock_bh(&lock);
+	if (!qtn_vlan_is_member(vdev, vid))
+		goto out;
+
+	__switch_vlan_untag_member(vdev, vid);
+	tagrx = switch_vlan_manage_tagrx(vdev, vid, 0, 0);
+	switch_vlan_set_tagrx(&qtn_vlan_info, vid, tagrx);
+out:
+	spin_unlock_bh(&lock);
+}
+
+int switch_vlan_untag_member(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	return switch_vlan_member_comm(vdev, vid, 0, _vlan_untag_member);
+}
+EXPORT_SYMBOL(switch_vlan_untag_member);
+
+int switch_vlan_set_pvid(struct qtn_vlan_dev *vdev, uint16_t vid)
+{
+	if (vid >= QVLAN_VID_MAX)
+		return -EINVAL;
+
+	spin_lock_bh(&lock);
+
+	switch_vlan_del(vdev, vdev->pvid);
+	switch_vlan_add(vdev, vid, 0);
+
+	vdev->pvid = vid;
+
+	spin_unlock_bh(&lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(switch_vlan_set_pvid);
+
+int switch_vlan_set_mode(struct qtn_vlan_dev *vdev, uint8_t mode)
+{
+	if (mode >= QVLAN_MODE_MAX)
+		return -EINVAL;
+
+	spin_lock_bh(&lock);
+	if (qtn_vlan_is_mode(vdev, mode))
+		goto out;
+
+	((struct qtn_vlan_user_interface *)vdev->user_data)->mode = mode;
+out:
+	spin_unlock_bh(&lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(switch_vlan_set_mode);
+
+static inline void __switch_vlan_clear_dev(struct qtn_vlan_dev *vdev)
+{
+	memset(&vdev->u, 0, sizeof(vdev->u));
+	memset(&vdev->tag_bitmap, 0, sizeof(vdev->tag_bitmap));
+	memset(&vdev->ig_pass, 0, sizeof(vdev->ig_pass));
+	memset(&vdev->ig_drop, 0, sizeof(vdev->ig_drop));
+	memset(&vdev->eg_pass, 0, sizeof(vdev->eg_pass));
+	memset(&vdev->eg_drop, 0, sizeof(vdev->eg_drop));
+	vdev->pvid = QVLAN_DEF_PVID;
+	vdev->flags = 0;
+}
+
+void switch_vlan_dyn_enable(struct qtn_vlan_dev *vdev)
+{
+	spin_lock_bh(&lock);
+
+	__switch_vlan_clear_dev(vdev);
+	vdev->flags |= QVLAN_DEV_F_DYNAMIC;
+
+	spin_unlock_bh(&lock);
+}
+EXPORT_SYMBOL(switch_vlan_dyn_enable);
+
+void switch_vlan_dyn_disable(struct qtn_vlan_dev *vdev)
+{
+	spin_lock_bh(&lock);
+
+	__switch_vlan_clear_dev(vdev);
+	vdev->pvid = QVLAN_DEF_PVID;
+	switch_vlan_add(vdev, vdev->pvid, 0);
+
+	spin_unlock_bh(&lock);
+}
+EXPORT_SYMBOL(switch_vlan_dyn_disable);
+
+int switch_vlan_set_node(struct qtn_vlan_dev *vdev, uint16_t ncidx, uint16_t vlanid)
+{
+	int ret = 0;
+
+	spin_lock_bh(&lock);
+
+	if (!QVLAN_IS_DYNAMIC(vdev)
+			|| ncidx >= QTN_NCIDX_MAX
+			|| !qtn_vlan_is_valid(vlanid)
+			|| vdev->port != TOPAZ_TQE_WMAC_PORT) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	vdev->u.node_vlan[ncidx] = vlanid;
+
+out:
+	spin_unlock_bh(&lock);
+	return ret;
+}
+EXPORT_SYMBOL(switch_vlan_set_node);
+
+int switch_vlan_clr_node(struct qtn_vlan_dev *vdev, uint16_t ncidx)
+{
+	int ret = 0;
+
+	spin_lock_bh(&lock);
+
+	if (!QVLAN_IS_DYNAMIC(vdev)
+			|| ncidx >= QTN_NCIDX_MAX
+			|| vdev->port != TOPAZ_TQE_WMAC_PORT) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	vdev->u.node_vlan[ncidx] = QVLAN_VID_ALL;
+
+out:
+	spin_unlock_bh(&lock);
+	return ret;
+}
+EXPORT_SYMBOL(switch_vlan_clr_node);
+
+int switch_vlan_is_local(const uint8_t *data)
+{
+	const struct ethhdr *eth = (struct ethhdr *)data;
+	struct net_device *brdev = dev_get_by_name(&init_net, SWITCH_VLAN_LOCAL_INTERFACE_NAME);
+	int ret = 0;
+
+	if (likely(brdev)) {
+		ret = !compare_ether_addr(eth->h_source, brdev->dev_addr);
+		dev_put(brdev);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(switch_vlan_is_local);
+
+struct sk_buff *switch_vlan_strip_tag(struct sk_buff *skb, int copy)
+{
+	struct sk_buff *skb2;
+	struct vlan_ethhdr *veth;
+	uint16_t vlan_id;
+	struct net_device *brdev;
+
+	BUG_ON(!skb_mac_header_was_set(skb));
+
+	if (!vlan_enabled)
+		return skb;
+
+	veth = vlan_eth_hdr(skb);
+	if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q))
+		return skb;
+
+	brdev = dev_get_by_name(&init_net, SWITCH_VLAN_LOCAL_INTERFACE_NAME);
+	if (likely(brdev)) {
+		vlan_id = ntohs(veth->h_vlan_TCI) & VLAN_VID_MASK;
+		if (vlan_check_vlan_exist(brdev, vlan_id)) {
+			dev_put(brdev);
+
+			return skb;
+		}
+
+		dev_put(brdev);
+	}
+
+	if (copy) {
+		skb2 = skb_copy(skb, GFP_ATOMIC);
+		dev_kfree_skb(skb);
+	} else {
+		skb2 = skb;
+	}
+
+	if (!skb2)
+		return NULL;
+
+	veth = vlan_eth_hdr(skb2);
+	memmove((uint8_t *)veth - QVLAN_PKTCTRL_LEN + VLAN_HLEN,
+		(uint8_t *)veth - QVLAN_PKTCTRL_LEN,
+		QVLAN_PKTCTRL_LEN + 2 * VLAN_ETH_ALEN);
+
+	skb_push(skb2, ETH_HLEN - VLAN_HLEN);
+	skb2->protocol = eth_type_trans(skb2, skb2->dev);
+	M_FLAG_SET(skb2, M_VLAN_TAG_OWE);
+
+	return skb2;
+}
+EXPORT_SYMBOL(switch_vlan_strip_tag);
+
+struct sk_buff *switch_vlan_restore_tag(struct sk_buff *skb, int copy)
+{
+	struct sk_buff *skb2;
+	struct qtn_vlan_pkt pkt;
+
+	if (!M_FLAG_ISSET(skb, M_VLAN_TAG_OWE))
+		return skb;
+
+	if (copy) {
+		skb2 = skb_copy(skb, GFP_ATOMIC);
+		dev_kfree_skb(skb);
+	} else {
+		skb2 = skb;
+	}
+
+	if (!skb2)
+		return NULL;
+
+	memcpy(&pkt, qtn_vlan_get_info(skb2->data), sizeof(pkt));
+	BUG_ON(pkt.magic != QVLAN_PKT_MAGIC);
+
+	skb2 = __vlan_put_tag(skb2, pkt.vlan_info & QVLAN_MASK_VID);
+	if (!skb2)
+		return NULL;
+
+	if (unlikely(skb_headroom(skb2) < QVLAN_PKTCTRL_LEN)) {
+		dev_kfree_skb(skb2);
+		return NULL;
+	}
+
+	memcpy(qtn_vlan_get_info(skb2->data), &pkt, sizeof(pkt));
+
+	return skb2;
+}
+EXPORT_SYMBOL(switch_vlan_restore_tag);
+
+static int switch_vlan_stats_rd(char *page, char **start, off_t offset,
+		int count, int *eof, void *data)
+{
+	char *p = page;
+	struct qtn_vlan_dev *vdev;
+	struct net_device *ndev;
+	int i;
+
+	spin_lock_bh(&lock);
+
+	for (i = 0; i < VLAN_INTERFACE_MAX; i++) {
+		vdev = vdev_tbl_lhost[i];
+		if (!vdev)
+			continue;
+
+		ndev = dev_get_by_index(&init_net, vdev->ifindex);
+		if (unlikely(!ndev))
+			continue;
+
+		p += sprintf(p, "%s\ti-pass\t\te-pass\t\ti-drop\t\te-drop\n", ndev->name);
+		p += sprintf(p, "Lhost\t%u\t\t%u\t\t%u\t\t%u\n", vdev->ig_pass.lhost, vdev->eg_pass.lhost,
+				vdev->ig_drop.lhost, vdev->eg_drop.lhost);
+		p += sprintf(p, "AuC\t%u\t\t%u\t\t%u\t\t%u\n", vdev->ig_pass.auc, vdev->eg_pass.auc,
+				vdev->ig_drop.auc, vdev->eg_drop.auc);
+		p += sprintf(p, "MuC\t%u\t\t%u\t\t%u\t\t%u\n", vdev->ig_pass.muc, vdev->eg_pass.muc,
+				vdev->ig_drop.muc, vdev->eg_drop.muc);
+
+		dev_put(ndev);
+	}
+
+	spin_unlock_bh(&lock);
+
+	*eof = 1;
+	return p - page;
+}
+
+void switch_vlan_dev_reset(struct qtn_vlan_dev *vdev, uint8_t mode)
+{
+	uint32_t i;
+
+	spin_lock_bh(&lock);
+	for (i = 0; i < QVLAN_VID_MAX; i++) {
+		if (qtn_vlan_is_member(vdev, i))
+			switch_vlan_del(vdev, i);
+	}
+
+	memset(vdev->u.member_bitmap, 0, sizeof(vdev->u.member_bitmap));
+	memset(vdev->tag_bitmap, 0, sizeof(vdev->tag_bitmap));
+	spin_unlock_bh(&lock);
+
+	switch_vlan_set_pvid(vdev, QVLAN_DEF_PVID);
+	switch_vlan_set_mode(vdev, mode);
+}
+EXPORT_SYMBOL(switch_vlan_dev_reset);
+
+void switch_vlan_reset(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < VLAN_INTERFACE_MAX; i++) {
+		if (vdev_tbl_lhost[i])
+			switch_vlan_dev_reset(vdev_tbl_lhost[i], QVLAN_MODE_ACCESS);
+	}
+}
+EXPORT_SYMBOL(switch_vlan_reset);
+
+static int __init switch_vlan_module_init(void)
+{
+	if (!create_proc_read_entry(SWITCH_VLAN_PROC, 0,
+			NULL, switch_vlan_stats_rd, 0))
+		return -EEXIST;
+
+	return 0;
+}
+
+static void __exit switch_vlan_module_exit(void)
+{
+	remove_proc_entry(SWITCH_VLAN_PROC, 0);
+}
+
+module_init(switch_vlan_module_init);
+module_exit(switch_vlan_module_exit);
+
+MODULE_DESCRIPTION("VLAN control panel");
+MODULE_AUTHOR("Quantenna");
+MODULE_LICENSE("GPL");
diff --git a/drivers/topaz/topaz_congest_queue.c b/drivers/topaz/topaz_congest_queue.c
index 7a7c6c3..005f114 100644
--- a/drivers/topaz/topaz_congest_queue.c
+++ b/drivers/topaz/topaz_congest_queue.c
@@ -59,12 +59,12 @@
 EXPORT_SYMBOL(topaz_congest_dump);
 
 struct reg_congest_stats {
-	void (*fn)(void *ctx, uint8_t q_num, uint32_t q_len);
+	void (*fn)(void *ctx, uint32_t type, uint8_t q_num, uint32_t q_value);
 	void *ctx;
 };
 
 struct reg_congest_stats pktlog_update_cgq_stats;
-void reg_congest_queue_stats(void (*fn)(void *, uint8_t, uint32_t), void *ctx)
+void reg_congest_queue_stats(void (*fn)(void *, uint32_t, uint8_t, uint32_t), void *ctx)
 {
 	pktlog_update_cgq_stats.fn = fn;
 	pktlog_update_cgq_stats.ctx = ctx;
@@ -87,16 +87,23 @@
 	}
 }
 
+void topaz_congest_set_unicast_queue_count(uint32_t qnum)
+{
+	if (qnum <= TOPAZ_CONGEST_QUEUE_NUM)
+		topaz_congest_queue_get()->max_unicast_qcount = qnum;
+}
+EXPORT_SYMBOL(topaz_congest_set_unicast_queue_count);
+
 struct topaz_congest_q_desc* topaz_congest_alloc_unicast_queue(struct topaz_congest_queue *congest_queue,
 														uint32_t node_id,
 														uint32_t tid)
 {
 	struct topaz_congest_q_desc* unicast_queue;
 
-	if (get_active_tid_num() > 1)
+	if (get_active_tid_num() > congest_queue->max_unicast_qcount)
 		return NULL;
 
-	if (congest_queue->unicast_qcount >= TOPAZ_CONGEST_QUEUE_UNICAST_NUM)
+	if (congest_queue->unicast_qcount >= congest_queue->max_unicast_qcount)
 		return NULL;
 
 	unicast_queue = topaz_congest_alloc_queue(congest_queue, node_id, tid);
@@ -153,17 +160,20 @@
 	struct topaz_congest_q_elem *ptr;
 	uint32_t index;
 	int8_t pool;
+	int ret = 0;
 
 	if ((queue->qlen >= TOPAZ_CONGEST_PKT_MAX) ||
 			(queue->congest_queue->total_qlen >= TOPAZ_CONGEST_TOTAL_PKT_MAX)) {
 		queue->congest_enq_fail++;
-		return NET_XMIT_CN;
+		ret = NET_XMIT_CN;
+		goto make_stats;
 	}
 
 	pool = topaz_hbm_payload_get_pool_bus(ppctl->data.pkt);
 	if (topaz_hbm_pool_available(pool) <= TOPAZ_HBM_POOL_THRESHOLD) {
 		queue->congest_enq_fail++;
-		return NET_XMIT_CN;
+		ret = NET_XMIT_CN;
+		goto make_stats;
 	}
 
 	queue->congest_queue->logs[queue->qlen]++;
@@ -184,10 +194,20 @@
 	queue->tail = index;
 	queue->qlen++;
 	queue->congest_queue->total_qlen++;
-	if (pktlog_update_cgq_stats.fn)
-		pktlog_update_cgq_stats.fn(pktlog_update_cgq_stats.ctx, queue->index, queue->qlen);
 
-	return 0;
+make_stats:
+	if (pktlog_update_cgq_stats.fn) {
+		pktlog_update_cgq_stats.fn(pktlog_update_cgq_stats.ctx,
+					TOPAZ_CONGEST_QUEUE_STATS_QLEN,
+					queue->index,
+					queue->qlen);
+		pktlog_update_cgq_stats.fn(pktlog_update_cgq_stats.ctx,
+					TOPAZ_CONGEST_QUEUE_STATS_ENQFAIL,
+					queue->index,
+					queue->congest_enq_fail);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(topaz_congest_enqueue);
 
@@ -234,7 +254,7 @@
 	queue->qlen--;
 	queue->congest_queue->total_qlen--;
 	if (pktlog_update_cgq_stats.fn)
-		pktlog_update_cgq_stats.fn(pktlog_update_cgq_stats.ctx, queue->index, queue->qlen);
+		pktlog_update_cgq_stats.fn(pktlog_update_cgq_stats.ctx, TOPAZ_CONGEST_QUEUE_STATS_QLEN, queue->index, queue->qlen);
 
 	/* Initial status setting */
 	queue->last_retry_success = 1;
@@ -254,7 +274,7 @@
 }
 EXPORT_SYMBOL(topaz_hbm_congest_queue_put_buf);
 
-inline static void topaz_congest_queue_clear(struct topaz_congest_q_desc *queue)
+noinline static void topaz_congest_queue_clear(struct topaz_congest_q_desc *queue)
 {
 	struct topaz_congest_q_elem *ptr;
 
@@ -270,16 +290,17 @@
 __attribute__((section(".sram.text"))) int topaz_congest_queue_xmit(struct topaz_congest_q_desc *queue, uint32_t budget)
 {
 	union topaz_tqe_cpuif_ppctl *pp_cntl;
+	struct topaz_congest_queue *congest_queue = queue->congest_queue;
 	int re_sched = 0;
 	int ret;
 
+	congest_queue->xmit_entry++;
+
 	if (queue->last_retry_success == 0) {
 		if (time_after(jiffies, queue->retry_timeout)) {
 			/* PNPT queue very likely is gone */
 			topaz_congest_queue_clear(queue);
 			return 0;
-		} else if (get_timestamp() - queue->last_retry_stamp < 100) {
-			return 1;
 		}
 	}
 
@@ -288,9 +309,9 @@
 		if (!pp_cntl)
 			break;
 
-		queue->congest_queue->cnt_retries++;
+		congest_queue->cnt_retries++;
 
-		ret = queue->congest_queue->xmit_func(pp_cntl);
+		ret = congest_queue->xmit_func(pp_cntl);
 
 		if (ret == NET_XMIT_CN) {
 			queue->last_retry_success = 0;
@@ -298,7 +319,7 @@
 			break;
 		}
 
-		queue->retry_timeout = jiffies + queue->congest_queue->congest_timeout;
+		queue->retry_timeout = jiffies + congest_queue->congest_timeout;
 		queue->congest_xmit++;
 
 		/* Transmit successfully */
@@ -308,8 +329,6 @@
 			break;
 	}
 
-	queue->last_retry_stamp = get_timestamp();
-
 	if (budget == 0)
 		re_sched = 1;
 
@@ -321,9 +340,6 @@
 {
 	struct topaz_congest_queue *congest_queue = (struct topaz_congest_queue *)data;
 	struct topaz_congest_q_desc *queue;
-#if TOPAZ_VNET_WR_STAGING
-	struct vmac_priv *vmp = congest_queue->vmp;
-#endif
 	int re_sched = 0;
 	int ret;
 	int i;
@@ -341,11 +357,6 @@
 			re_sched = 1;
 	}
 
-#if TOPAZ_VNET_WR_STAGING
-	if (congest_queue->tasklet_extra_proc)
-		congest_queue->tasklet_extra_proc(vmp);
-#endif
-
 	if (re_sched == 1) {
 		tasklet_schedule(&congest_queue->congest_tx);
 	}
@@ -373,6 +384,7 @@
 	tasklet_init(&queue->congest_tx, congest_tx_tasklet, (unsigned long)queue);
 	queue->xmit_func = NULL;
 	queue->tasklet_extra_proc = NULL;
+	queue->max_unicast_qcount = TOPAZ_CONGEST_MAX_UNICAST_QCOUNT;
 
 	return queue;
 }
diff --git a/drivers/topaz/tqe.c b/drivers/topaz/tqe.c
index 7772ddf..a57bb6b 100644
--- a/drivers/topaz/tqe.c
+++ b/drivers/topaz/tqe.c
@@ -16,7 +16,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  **/
-#ifdef TOPAZ_PLATFORM
 
 #include <linux/module.h>
 #include <linux/proc_fs.h>
@@ -79,5 +78,4 @@
 MODULE_AUTHOR("Quantenna");
 MODULE_LICENSE("GPL");
 
-#endif
 
diff --git a/include/common/common_mem.h b/include/common/common_mem.h
index 797c31a..61b106e 100644
--- a/include/common/common_mem.h
+++ b/include/common/common_mem.h
@@ -42,14 +42,8 @@
 #define RUBY_SRAM_NOFLIP_NOCACHE_BEGIN		0x60000000
 #define RUBY_SRAM_BANK_SIZE			(64 * 1024)
 
-#ifdef TOPAZ_PLATFORM
-	#define RUBY_SRAM_SIZE			(8 * RUBY_SRAM_BANK_SIZE)
-	#define RUBY_SRAM_BANK_SAFE_SIZE	RUBY_SRAM_BANK_SIZE
-#else
-	#define RUBY_SRAM_END_BANK_GUARD_SIZE	32
-	#define RUBY_SRAM_SIZE			(4 * RUBY_SRAM_BANK_SIZE)
-	#define RUBY_SRAM_BANK_SAFE_SIZE	(RUBY_SRAM_BANK_SIZE - RUBY_SRAM_END_BANK_GUARD_SIZE)
-#endif
+#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
@@ -103,6 +97,9 @@
 
 #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)
@@ -134,19 +131,18 @@
 
 #define CONFIG_ARC_MUC_STACK_INIT_UBOOT		(RUBY_SRAM_BEGIN + CONFIG_ARC_MUC_STACK_OFFSET_UBOOT)
 
-#ifdef TOPAZ_PLATFORM
-	/* Must be equal to RUBY_CRUMBS_OFFSET */
-	#define RUBY_CRUMBS_OFFSET_UBOOT	(0x0003FFC0)
-#else
-	#define RUBY_CRUMBS_OFFSET_UBOOT	(0x0003FFA0)
-#endif
+/* 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 SRAM. Each core can use it to
+ * 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;
diff --git a/include/common/current_platform.h b/include/common/current_platform.h
index bc0d20f..bcd3ab4 100644
--- a/include/common/current_platform.h
+++ b/include/common/current_platform.h
@@ -5,4 +5,6 @@
 #define PLATFORM_WMAC_MODE ap
 #undef PLATFORM_DEFAULT_BOARD_ID
 #define ARC_HW_REV_NEEDS_TLBMISS_FIX
-#define TOPAZ_VNET_WR_STAGING 0
+#define FLASH_SUPPORT_64KB
+#define WPA_TKIP_SUPPORT 0
+#define SIGMA_TESTBED_SUPPORT 0
diff --git a/include/common/doxygen/Doxyfile_pdf b/include/common/doxygen/Doxyfile_pdf
index 38c633b..6bf43ed 100644
--- a/include/common/doxygen/Doxyfile_pdf
+++ b/include/common/doxygen/Doxyfile_pdf
@@ -189,11 +189,17 @@
 # will result in a user-defined paragraph with heading "Side Effects:". 
 # You can put \n's in the value part of an alias to insert newlines.
 
-ALIASES = persistent="\par <b>Persistency:</b> this API is <b>persistent</b> across reboot\n"
-ALIASES	+= nonpersistent="\par <b>Persistency:</b> this API is <b>non-persistent</b> across reboot\n"
 ALIASES += callqcsapi="<b><c>call_qcsapi</c> interface:</b><br>"
-ALIASES += wifi0="the interface to perform the action on. (Generally wifi0)"
+ALIASES += wifi0="the interface to perform the action on. (e.g. wifi0)."
+ALIASES += wifi0only="the primary WiFi interface, wifi0 only."
 ALIASES += wifiX="the interface to perform the action on. wifiX, For X=0,1,..."
+ALIASES += wifi_wds="the interface to perform the action on. (e.g. wifi0 or wds0)."
+ALIASES += wifi_wds_eth="the interface to perform the action on. (e.g. wifi0 or wds0 or eth1_0)."
+ALIASES += aponly="This API can only be used in AP mode."
+ALIASES += staonly="This API can only be used in STA mode."
+ALIASES += nonpersistent="The value(s) set by this API are not persistent and must be reapplied if the device reboots."
+ALIASES += primarywifi="This API can only be used on the primary interface (wifi0)"
+ALIASES += hotspot_api="Refer to the WiFi Alliance Hotspot 2.0 (Release 2) Technical Specification for further information."
 
 # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
 # sources only. Doxygen will then generate output that is more tailored for C. 
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.1-v37.3.0.2 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.1-v37.3.0.2
index d32b13b..7f40d09 100644
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.1-v37.3.0.2
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.1-v37.3.0.2
@@ -6,10 +6,20 @@
  * \subsection v37_3_0_1_TO_v37_3_0_2Added Added functions
  *
  * The following functions were added between versions v37.3.0.1 and v37.3.0.2
- *
  * \li \ref qcsapi_wifi_get_scan_buf_max_size
  * \li \ref qcsapi_calcmd_get_info
+ * \li \ref qcsapi_wifi_set_scan_buf_max_size
  * \li \ref qcsapi_wifi_get_scan_table_max_len
  * \li \ref qcsapi_wifi_set_scan_table_max_len
- * \li \ref qcsapi_wifi_set_scan_buf_max_size
+ *
+ * \subsection v37_3_0_1_TO_v37_3_0_2Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.1 and v37.3.0.2
+ *  - \ref qcsapi_wifi_get_auth_state
+ *    - Old prototype: int qcsapi_wifi_get_auth_state(const char *ifname, char *mac_addr, int *auth_state);
+ *    - New prototype: int qcsapi_wifi_get_auth_state(const char *ifname, const char *mac_addr, int *auth_state);
+ *  - \ref qcsapi_wifi_get_wpa_status
+ *    - Old prototype: int qcsapi_wifi_get_wpa_status(const char *ifname, char *wpa_status, char *mac_addr, const qcsapi_unsigned_int max_len);
+ *    - New prototype: int qcsapi_wifi_get_wpa_status(const char *ifname, char *wpa_status, const char *mac_addr, const qcsapi_unsigned_int max_len);
  */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.10-v37.3.0.11 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.10-v37.3.0.11
index fcaadc7..576eb38 100644
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.10-v37.3.0.11
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.10-v37.3.0.11
@@ -6,6 +6,13 @@
  * \subsection v37_3_0_10_TO_v37_3_0_11Added Added functions
  *
  * The following functions were added between versions v37.3.0.10 and v37.3.0.11
- *
  * \li \ref qcsapi_wifi_enable_tdls_over_qhop
+ *
+ * \subsection v37_3_0_10_TO_v37_3_0_11Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.10 and v37.3.0.11
+ *  - \ref qcsapi_wifi_tdls_operate
+ *    - Old prototype: int qcsapi_wifi_tdls_operate(const char *ifname, qcsapi_tdls_oper operate, const char *mac_addr_str);
+ *    - New prototype: int qcsapi_wifi_tdls_operate(const char *ifname, qcsapi_tdls_oper operate, const char *mac_addr_str, int cs_interval);
  */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.12-v37.3.0.13 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.12-v37.3.0.13
index 0abf9be..6939006 100644
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.12-v37.3.0.13
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.12-v37.3.0.13
@@ -6,22 +6,46 @@
  * \subsection v37_3_0_12_TO_v37_3_0_13Added Added functions
  *
  * The following functions were added between versions v37.3.0.12 and v37.3.0.13
- *
- * \li \ref qcsapi_security_add_hs20_conn_capab
- * \li \ref qcsapi_security_add_venue_name
- * \li \ref qcsapi_security_del_hs20_conn_capab
- * \li \ref qcsapi_security_get_venue_name
  * \li \ref qcsapi_security_add_oper_friendly_name
- * \li \ref qcsapi_verify_numeric
- * \li \ref qcsapi_security_del_oper_friendly_name
- * \li \ref qcsapi_security_get_hs20_conn_capab
  * \li \ref qcsapi_security_del_venue_name
+ * \li \ref qcsapi_security_get_hs20_conn_capab
+ * \li \ref qcsapi_security_get_venue_name
+ * \li \ref qcsapi_security_add_venue_name
  * \li \ref qcsapi_security_get_oper_friendly_name
+ * \li \ref qcsapi_security_del_oper_friendly_name
+ * \li \ref qcsapi_security_del_hs20_conn_capab
+ * \li \ref qcsapi_verify_numeric
+ * \li \ref qcsapi_security_add_hs20_conn_capab
  *
  * \subsection v37_3_0_12_TO_v37_3_0_13Removed Removed functions
  *
  * The following functions were removed between versions v37.3.0.12 and v37.3.0.13
+ * \li \ref qcsapi_wifi_set_venue_info
+ * \li \ref qcsapi_wifi_get_venue_info
  *
- * \li qcsapi_wifi_set_venue_info
- * \li qcsapi_wifi_get_venue_info
+ * \subsection v37_3_0_12_TO_v37_3_0_13Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.12 and v37.3.0.13
+ *  - \ref qcsapi_security_add_roaming_consortium
+ *    - Old prototype: int qcsapi_security_add_roaming_consortium(const char *ifname, const string_32 p_value);
+ *    - New prototype: int qcsapi_security_add_roaming_consortium(const char *ifname, const char *p_value);
+ *  - \ref qcsapi_security_get_nai_realms
+ *    - Old prototype: int qcsapi_security_get_nai_realms(const char *ifname, string_1024 p_value);
+ *    - New prototype: int qcsapi_security_get_nai_realms(const char *ifname, string_4096 p_value);
+ *  - \ref qcsapi_wifi_set_80211u_params
+ *    - Old prototype: int qcsapi_wifi_set_80211u_params(const char *ifname, const string_32 param, const string_32 p_value);
+ *    - New prototype: int qcsapi_wifi_set_80211u_params(const char *ifname, const string_32 param, const string_256 value1, const string_32 value2);
+ *  - \ref qcsapi_security_del_nai_realm
+ *    - Old prototype: int qcsapi_security_del_nai_realm(const char *ifname, const string_32 p_value);
+ *    - New prototype: int qcsapi_security_del_nai_realm(const char *ifname, const char *nai_realm);
+ *  - \ref qcsapi_get_temperature_info
+ *    - Old prototype: int qcsapi_get_temperature_info(int *temp_external, int *temp_internal);
+ *    - New prototype: int qcsapi_get_temperature_info(int *temp_external, int *temp_internal, int *temp_bb_internal);
+ *  - \ref qcsapi_security_del_roaming_consortium
+ *    - Old prototype: int qcsapi_security_del_roaming_consortium(const char *ifname, const string_32 p_value);
+ *    - New prototype: int qcsapi_security_del_roaming_consortium(const char *ifname, const char *p_value);
+ *  - \ref qcsapi_wifi_get_80211u_params
+ *    - Old prototype: int qcsapi_wifi_get_80211u_params(const char *ifname, const string_32 param, string_32 p_value);
+ *    - New prototype: int qcsapi_wifi_get_80211u_params(const char *ifname, const string_32 param, string_256 p_value);
  */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.16-v37.3.0.17 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.16-v37.3.0.17
index afa4dd9..0dc105e 100644
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.16-v37.3.0.17
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.16-v37.3.0.17
@@ -6,13 +6,20 @@
  * \subsection v37_3_0_16_TO_v37_3_0_17Added Added functions
  *
  * The following functions were added between versions v37.3.0.16 and v37.3.0.17
- *
- * \li \ref qcsapi_wifi_get_mu_use_precode
  * \li \ref qcsapi_wifi_set_enable_mu
  * \li \ref qcsapi_wifi_get_mu_use_eq
+ * \li \ref qcsapi_wifi_get_mu_use_precode
  * \li \ref qcsapi_wifi_get_enable_mu
  * \li \ref qcsapi_wifi_set_mu_use_eq
- * \li \ref qcsapi_wifi_set_mu_use_precode
  * \li \ref qcsapi_wfa_cert_mode_enable
  * \li \ref qcsapi_wifi_get_mu_groups
+ * \li \ref qcsapi_wifi_set_mu_use_precode
+ *
+ * \subsection v37_3_0_16_TO_v37_3_0_17Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.16 and v37.3.0.17
+ *  - \ref qcsapi_wifi_set_phy_mode
+ *    - Old prototype: int qcsapi_wifi_set_phy_mode(const char *ifname, char *new_phy_mode);
+ *    - New prototype: int qcsapi_wifi_set_phy_mode(const char *ifname, const char *new_phy_mode);
  */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.17-v37.3.0.18 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.17-v37.3.0.18
new file mode 100644
index 0000000..db4753d
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.17-v37.3.0.18
@@ -0,0 +1,16 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_3_0_17_TO_v37_3_0_18 Version v37.3.0.17 to version v37.3.0.18 changes
+ *
+ * \subsection v37_3_0_17_TO_v37_3_0_18Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.17 and v37.3.0.18
+ *  - \ref qcsapi_wifi_rfstatus
+ *    - Old prototype: int qcsapi_wifi_rfstatus(const char *ifname, qcsapi_unsigned_int *rfstatus);
+ *    - New prototype: int qcsapi_wifi_rfstatus(qcsapi_unsigned_int *rfstatus);
+ *  - \ref qcsapi_wifi_rfenable
+ *    - Old prototype: int qcsapi_wifi_rfenable(const char *ifname, const qcsapi_unsigned_int onoff);
+ *    - New prototype: int qcsapi_wifi_rfenable(const qcsapi_unsigned_int onoff);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.18-v37.3.0.19 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.18-v37.3.0.19
index 47f120a..7a6b3c0 100644
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.18-v37.3.0.19
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.18-v37.3.0.19
@@ -6,7 +6,17 @@
  * \subsection v37_3_0_18_TO_v37_3_0_19Added Added functions
  *
  * The following functions were added between versions v37.3.0.18 and v37.3.0.19
- *
  * \li \ref qcsapi_wifi_set_l2_ext_filter
  * \li \ref qcsapi_wifi_get_l2_ext_filter
+ *
+ * \subsection v37_3_0_18_TO_v37_3_0_19Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.18 and v37.3.0.19
+ *  - \ref qcsapi_get_service_action_enum
+ *    - Old prototype: int qcsapi_get_service_action_enum(string_32 lookup_action, qcsapi_service_action *serv_action);
+ *    - New prototype: int qcsapi_get_service_action_enum(const char *lookup_action, qcsapi_service_action *serv_action);
+ *  - \ref qcsapi_get_service_name_enum
+ *    - Old prototype: int qcsapi_get_service_name_enum(string_32 lookup_service, qcsapi_service_name *serv_name);
+ *    - New prototype: int qcsapi_get_service_name_enum(const char *lookup_service, qcsapi_service_name *serv_name);
  */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.20-v37.3.0.21 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.20-v37.3.0.21
new file mode 100644
index 0000000..7876698
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.20-v37.3.0.21
@@ -0,0 +1,13 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_3_0_20_TO_v37_3_0_21 Version v37.3.0.20 to version v37.3.0.21 changes
+ *
+ * \subsection v37_3_0_20_TO_v37_3_0_21Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.3.0.20 and v37.3.0.21
+ *  - \ref qcsapi_wifi_set_hs20_params
+ *    - Old prototype: int qcsapi_wifi_set_hs20_params(const char *ifname, const string_32 param, const string_64 p_value);
+ *    - New prototype: int qcsapi_wifi_set_hs20_params(const char *ifname, const string_32 param, const string_64 value1, const string_64 value2, const string_64 value3, const string_64 value4, const string_64 value5, const string_64 value6);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.21-v37.4.0.0 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.21-v37.4.0.0
new file mode 100644
index 0000000..9972a0f
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.21-v37.4.0.0
@@ -0,0 +1,13 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_3_0_21_TO_v37_4_0_0 Version v37.3.0.21 to version v37.4.0.0 changes
+ *
+ * \subsection v37_3_0_21_TO_v37_4_0_0Added Added functions
+ *
+ * The following functions were added between versions v37.3.0.21 and v37.4.0.0
+ *
+ * \li \ref qcsapi_wifi_set_dfs_s_radio_wea_cac_time
+ * \li \ref qcsapi_str_to_uint32
+ * \li \ref qcsapi_wifi_set_dfs_s_radio_wea_duration
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.22-v37.3.0.23 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.22-v37.3.0.23
deleted file mode 100644
index b270967..0000000
--- a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.3.0.22-v37.3.0.23
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * \page ChangeLog
- *
- * \section v37_3_0_22_TO_v37_3_0_23 Version v37.3.0.22 to version v37.3.0.23 changes
- *
- * \subsection v37_3_0_22_TO_v37_3_0_23Added Added functions
- *
- * The following functions were added between versions v37.3.0.22 and v37.3.0.23
- *
- * \li \ref qcsapi_wifi_set_dfs_s_radio_wea_cac_time
- * \li \ref qcsapi_str_to_uint32
- * \li \ref qcsapi_wifi_set_dfs_s_radio_wea_duration
- */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.1-v37.4.0.2 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.1-v37.4.0.2
new file mode 100644
index 0000000..c42ae35
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.1-v37.4.0.2
@@ -0,0 +1,25 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_1_TO_v37_4_0_2 Version v37.4.0.1 to version v37.4.0.2 changes
+ *
+ * \subsection v37_4_0_1_TO_v37_4_0_2Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.1 and v37.4.0.2
+ *  - \ref qcsapi_security_del_venue_name
+ *    - Old prototype: int qcsapi_security_del_venue_name(const char *ifname, char *lang_code, char *venue_name);
+ *    - New prototype: int qcsapi_security_del_venue_name(const char *ifname, const char *lang_code, const char *venue_name);
+ *  - \ref qcsapi_security_add_venue_name
+ *    - Old prototype: int qcsapi_security_add_venue_name(const char *ifname, char *lang_code, char *venue_name);
+ *    - New prototype: int qcsapi_security_add_venue_name(const char *ifname, const char *lang_code, const char *venue_name);
+ *  - \ref qcsapi_security_del_oper_friendly_name
+ *    - Old prototype: int qcsapi_security_del_oper_friendly_name(const char *ifname, char *lang_code, char *oper_friendly_name);
+ *    - New prototype: int qcsapi_security_del_oper_friendly_name(const char *ifname, const char *lang_code, const char *oper_friendly_name);
+ *  - \ref qcsapi_security_add_nai_realm
+ *    - Old prototype: int qcsapi_security_add_nai_realm(const char *ifname, int encoding, char *nai_realm, char *eap_method);
+ *    - New prototype: int qcsapi_security_add_nai_realm(const char *ifname, const int encoding, const char *nai_realm, const char *eap_method);
+ *  - \ref qcsapi_security_add_oper_friendly_name
+ *    - Old prototype: int qcsapi_security_add_oper_friendly_name(const char *ifname, char *lang_code, char *oper_friendly_name);
+ *    - New prototype: int qcsapi_security_add_oper_friendly_name(const char *ifname, const char *lang_code, const char *oper_friendly_name);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.11-v37.4.0.12 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.11-v37.4.0.12
new file mode 100644
index 0000000..477a85b
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.11-v37.4.0.12
@@ -0,0 +1,11 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_11_TO_v37_4_0_12 Version v37.4.0.11 to version v37.4.0.12 changes
+ *
+ * \subsection v37_4_0_11_TO_v37_4_0_12Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.11 and v37.4.0.12
+ *
+ * \li \ref qcsapi_wifi_block_bss
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.12-v37.4.0.13 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.12-v37.4.0.13
new file mode 100644
index 0000000..da9c881
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.12-v37.4.0.13
@@ -0,0 +1,12 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_12_TO_v37_4_0_13 Version v37.4.0.12 to version v37.4.0.13 changes
+ *
+ * \subsection v37_4_0_12_TO_v37_4_0_13Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.12 and v37.4.0.13
+ *
+ * \li \ref qcsapi_wifi_chan_control
+ * \li \ref qcsapi_wifi_get_chan_disabled
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.16-v37.4.0.17 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.16-v37.4.0.17
new file mode 100644
index 0000000..e05ebc0
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.16-v37.4.0.17
@@ -0,0 +1,56 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_16_TO_v37_4_0_17 Version v37.4.0.16 to version v37.4.0.17 changes
+ *
+ * \subsection v37_4_0_16_TO_v37_4_0_17Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.16 and v37.4.0.17
+ * \li \ref qcsapi_wifi_set_txba_disable
+ * \li \ref qcsapi_security_del_hs20_icon
+ * \li \ref qcsapi_wifi_get_pairwise_key_interval
+ * \li \ref qcsapi_wifi_get_vap_state
+ * \li \ref qcsapi_wifi_set_vap_default_state
+ * \li \ref qcsapi_wifi_send_qos_map_conf
+ * \li \ref qcsapi_wifi_set_chan_pri_inactive_ext
+ * \li \ref qcsapi_wifi_get_txburst
+ * \li \ref qcsapi_wifi_get_supported_freq_bands
+ * \li \ref qcsapi_wifi_get_qos_map
+ * \li \ref qcsapi_security_del_osu_server_uri
+ * \li \ref qcsapi_wifi_get_sec_chan
+ * \li \ref qcsapi_wifi_get_dscp_tid_map
+ * \li \ref qcsapi_wifi_get_rxba_decline
+ * \li \ref qcsapi_wifi_del_qos_map
+ * \li \ref qcsapi_wifi_set_pairwise_key_interval
+ * \li \ref qcsapi_security_add_osu_server_uri
+ * \li \ref qcsapi_security_get_osu_server_uri
+ * \li \ref qcsapi_security_get_osu_server_param
+ * \li \ref qcsapi_wifi_set_vap_state
+ * \li \ref qcsapi_wifi_get_txba_disable
+ * \li \ref qcsapi_security_del_osu_server_param
+ * \li \ref qcsapi_security_get_hs20_icon
+ * \li \ref qcsapi_wifi_set_qos_map
+ * \li \ref qcsapi_wifi_set_rxba_decline
+ * \li \ref qcsapi_wifi_set_txburst
+ * \li \ref qcsapi_wifi_set_sec_chan
+ * \li \ref qcsapi_security_add_osu_server_param
+ * \li \ref qcsapi_security_add_hs20_icon
+ * \li \ref qcsapi_wifi_get_vap_default_state
+ *
+ * \subsection v37_4_0_16_TO_v37_4_0_17Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.16 and v37.4.0.17
+ *  - \ref qcsapi_wifi_set_group_key_interval
+ *    - Old prototype: int qcsapi_wifi_set_group_key_interval(const char *ifname, const string_16 group_key_interval);
+ *    - New prototype: int qcsapi_wifi_set_group_key_interval(const char *ifname, const unsigned int key_interval);
+ *  - \ref qcsapi_wifi_show_vlan_config
+ *    - Old prototype: int qcsapi_wifi_show_vlan_config(const char *ifname, string_1024 vcfg);
+ *    - New prototype: int qcsapi_wifi_show_vlan_config(const char *ifname, string_2048 vcfg, const char *flag);
+ *  - \ref qcsapi_wifi_get_group_key_interval
+ *    - Old prototype: int qcsapi_wifi_get_group_key_interval(const char *ifname, string_16 group_key_interval);
+ *    - New prototype: int qcsapi_wifi_get_group_key_interval(const char *ifname, unsigned int *p_key_interval);
+ *  - \ref qcsapi_wifi_vlan_config
+ *    - Old prototype: int qcsapi_wifi_vlan_config(const char *ifname, qcsapi_vlan_cmd cmd, uint32_t vlanid, uint32_t flags);
+ *    - New prototype: int qcsapi_wifi_vlan_config(const char *ifname, qcsapi_vlan_cmd cmd, uint32_t vlanid);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.19-v37.4.0.20 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.19-v37.4.0.20
new file mode 100644
index 0000000..87dca00
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.19-v37.4.0.20
@@ -0,0 +1,18 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_19_TO_v37_4_0_20 Version v37.4.0.19 to version v37.4.0.20 changes
+ *
+ * \subsection v37_4_0_19_TO_v37_4_0_20Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.19 and v37.4.0.20
+ * \li \ref qcsapi_wifi_get_24g_bw
+ * \li \ref qcsapi_wifi_set_24g_bw
+ *
+ * \subsection v37_4_0_19_TO_v37_4_0_20Removed Removed functions
+ *
+ * The following functions were removed between versions v37.4.0.19 and v37.4.0.20
+ * \li \ref qcsapi_wifi_get_2_4ghz_bw
+ * \li \ref qcsapi_wifi_set_2_4ghz_bw
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.2-v37.4.0.3 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.2-v37.4.0.3
new file mode 100644
index 0000000..0b9c149
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.2-v37.4.0.3
@@ -0,0 +1,11 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_2_TO_v37_4_0_3 Version v37.4.0.2 to version v37.4.0.3 changes
+ *
+ * \subsection v37_4_0_2_TO_v37_4_0_3Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.2 and v37.4.0.3
+ *
+ * \li \ref qcsapi_wifi_set_optim_stats
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.20-v37.4.0.21 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.20-v37.4.0.21
new file mode 100644
index 0000000..6796837
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.20-v37.4.0.21
@@ -0,0 +1,11 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_20_TO_v37_4_0_21 Version v37.4.0.20 to version v37.4.0.21 changes
+ *
+ * \subsection v37_4_0_20_TO_v37_4_0_21Removed Removed functions
+ *
+ * The following functions were removed between versions v37.4.0.20 and v37.4.0.21
+ * \li \ref qcsapi_enable_vlan_pass_through
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.21-v37.4.0.22 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.21-v37.4.0.22
new file mode 100644
index 0000000..0e569b1
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.21-v37.4.0.22
@@ -0,0 +1,6 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_21_TO_v37_4_0_22 Version v37.4.0.21 to version v37.4.0.22 changes
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.22-v37.4.0.23 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.22-v37.4.0.23
new file mode 100644
index 0000000..69036c6
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.22-v37.4.0.23
@@ -0,0 +1,6 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_22_TO_v37_4_0_23 Version v37.4.0.22 to version v37.4.0.23 changes
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.23-v37.4.0.24 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.23-v37.4.0.24
new file mode 100644
index 0000000..4a9329d
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.23-v37.4.0.24
@@ -0,0 +1,6 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_23_TO_v37_4_0_24 Version v37.4.0.23 to version v37.4.0.24 changes
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.24-v37.4.0.25 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.24-v37.4.0.25
new file mode 100644
index 0000000..5819cd0
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.24-v37.4.0.25
@@ -0,0 +1,6 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_24_TO_v37_4_0_25 Version v37.4.0.24 to version v37.4.0.25 changes
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.26-v37.4.0.27 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.26-v37.4.0.27
new file mode 100644
index 0000000..94ef05d
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.26-v37.4.0.27
@@ -0,0 +1,12 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_26_TO_v37_4_0_27 Version v37.4.0.26 to version v37.4.0.27 changes
+ *
+ * \subsection v37_4_0_26_TO_v37_4_0_27Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.26 and v37.4.0.27
+ * \li \ref qcsapi_qwe_command
+ * \li \ref qcsapi_wifi_get_scan_IEs
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.27-v37.4.0.28 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.27-v37.4.0.28
new file mode 100644
index 0000000..73bb8fd
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.27-v37.4.0.28
@@ -0,0 +1,13 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_27_TO_v37_4_0_28 Version v37.4.0.27 to version v37.4.0.28 changes
+ *
+ * \subsection v37_4_0_27_TO_v37_4_0_28Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.27 and v37.4.0.28
+ *  - \ref qcsapi_wifi_get_node_param
+ *    - Old prototype: int qcsapi_wifi_get_node_param(const char *ifname, const uint32_t node_index, qcsapi_per_assoc_param param_type, int local_remote_flag, string_128 input_param_str, qcsapi_measure_report_result *report_result);
+ *    - New prototype: int qcsapi_wifi_get_node_param(const char *ifname, const uint32_t node_index, qcsapi_per_assoc_param param_type, int local_remote_flag, const string_128 input_param_str, qcsapi_measure_report_result *report_result);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.28-v37.4.0.29 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.28-v37.4.0.29
new file mode 100644
index 0000000..254ebe1
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.28-v37.4.0.29
@@ -0,0 +1,12 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_28_TO_v37_4_0_29 Version v37.4.0.28 to version v37.4.0.29 changes
+ *
+ * \subsection v37_4_0_28_TO_v37_4_0_29Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.28 and v37.4.0.29
+ * \li \ref qcsapi_pm_dual_emac_get_mode
+ * \li \ref qcsapi_pm_dual_emac_set_mode
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.29-v37.4.0.30 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.29-v37.4.0.30
new file mode 100644
index 0000000..2a70842
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.29-v37.4.0.30
@@ -0,0 +1,18 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_29_TO_v37_4_0_30 Version v37.4.0.29 to version v37.4.0.30 changes
+ *
+ * \subsection v37_4_0_29_TO_v37_4_0_30Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.29 and v37.4.0.30
+ * \li \ref qcsapi_wifi_get_block_bss
+ * \li \ref qcsapi_qtm_safe_get_rule
+ * \li \ref qcsapi_qtm_safe_get_stats
+ * \li \ref qcsapi_qtm_safe_del_rule
+ * \li \ref qcsapi_qtm_safe_get_strm
+ * \li \ref qcsapi_qtm_safe_get_config_all
+ * \li \ref qcsapi_qtm_safe_add_rule
+ * \li \ref qcsapi_qtm_safe_get_state_all
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.32-v37.4.0.33 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.32-v37.4.0.33
new file mode 100644
index 0000000..c0150e7
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.32-v37.4.0.33
@@ -0,0 +1,14 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_32_TO_v37_4_0_33 Version v37.4.0.32 to version v37.4.0.33 changes
+ *
+ * \subsection v37_4_0_32_TO_v37_4_0_33Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.32 and v37.4.0.33
+ * \li \ref qcsapi_wifi_get_supp_chans
+ * \li \ref qcsapi_get_client_mac_list
+ * \li \ref qcsapi_get_core_dump
+ * \li \ref qcsapi_get_core_dump_size
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.34-v37.4.0.35 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.34-v37.4.0.35
new file mode 100644
index 0000000..94ffb56
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.34-v37.4.0.35
@@ -0,0 +1,12 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_34_TO_v37_4_0_35 Version v37.4.0.34 to version v37.4.0.35 changes
+ *
+ * \subsection v37_4_0_34_TO_v37_4_0_35Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.34 and v37.4.0.35
+ * \li \ref qcsapi_wifi_get_per_assoc_data
+ * \li \ref qcsapi_wifi_sample_all_clients
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.35-v37.4.0.36 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.35-v37.4.0.36
new file mode 100644
index 0000000..5d91180
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.35-v37.4.0.36
@@ -0,0 +1,20 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_35_TO_v37_4_0_36 Version v37.4.0.35 to version v37.4.0.36 changes
+ *
+ * \subsection v37_4_0_35_TO_v37_4_0_36Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.35 and v37.4.0.36
+ * \li \ref qcsapi_wifi_get_multicast_list
+ * \li \ref qcsapi_wifi_add_multicast
+ * \li \ref qcsapi_wifi_del_multicast
+ *
+ * \subsection v37_4_0_35_TO_v37_4_0_36Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.35 and v37.4.0.36
+ *  - \ref qcsapi_qtm_safe_get_strm
+ *    - Old prototype: int qcsapi_qtm_safe_get_strm(const char *ifname, struct qcsapi_int_array1024 *entries, unsigned int max_entries, int show_all);
+ *    - New prototype: int qcsapi_qtm_safe_get_strm(const char *ifname, struct qvsp_strms *strms, int show_all);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.4-v37.4.0.5 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.4-v37.4.0.5
new file mode 100644
index 0000000..ad6a0c7
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.4-v37.4.0.5
@@ -0,0 +1,21 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_4_TO_v37_4_0_5 Version v37.4.0.4 to version v37.4.0.5 changes
+ *
+ * \subsection v37_4_0_4_TO_v37_4_0_5Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.4 and v37.4.0.5
+ *
+ * \li \ref qcsapi_wifi_set_sys_time
+ * \li \ref qcsapi_wifi_set_2_4ghz_bw
+ * \li \ref qcsapi_wifi_get_mac_address_reserve
+ * \li \ref qcsapi_wifi_set_vco_lock_detect_mode
+ * \li \ref qcsapi_wifi_clear_mac_address_reserve
+ * \li \ref qcsapi_wifi_set_mac_address_reserve
+ * \li \ref qcsapi_wifi_get_vco_lock_detect_mode
+ * \li \ref qcsapi_wifi_get_sys_time
+ * \li \ref qcsapi_wifi_set_pref_band
+ * \li \ref qcsapi_wifi_get_2_4ghz_bw
+ * \li \ref qcsapi_wifi_get_pref_band
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.40-v37.4.0.41 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.40-v37.4.0.41
new file mode 100644
index 0000000..fbb6ecd
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.40-v37.4.0.41
@@ -0,0 +1,17 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_40_TO_v37_4_0_41 Version v37.4.0.40 to version v37.4.0.41 changes
+ *
+ * \subsection v37_4_0_40_TO_v37_4_0_41Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.40 and v37.4.0.41
+ * \li \ref qcsapi_get_igmp_snooping_state
+ * \li \ref qcsapi_wifi_remove_mac_address_list
+ * \li \ref qcsapi_wifi_is_ready
+ * \li \ref qcsapi_get_ep_status
+ * \li \ref qcsapi_wifi_authorize_mac_address_list
+ * \li \ref qcsapi_set_igmp_snooping_state
+ * \li \ref qcsapi_wifi_deny_mac_address_list
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.41-v37.4.0.42 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.41-v37.4.0.42
new file mode 100644
index 0000000..6da031d
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.41-v37.4.0.42
@@ -0,0 +1,13 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_41_TO_v37_4_0_42 Version v37.4.0.41 to version v37.4.0.42 changes
+ *
+ * \subsection v37_4_0_41_TO_v37_4_0_42Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.41 and v37.4.0.42
+ * \li \ref qcsapi_wifi_set_max_bcast_pps
+ * \li \ref qcsapi_wifi_update_bss_cfg
+ * \li \ref qcsapi_wifi_set_dfs_s_radio_wea_dwell_time
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.42-v37.4.0.43 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.42-v37.4.0.43
new file mode 100644
index 0000000..96f2223
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.42-v37.4.0.43
@@ -0,0 +1,11 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_42_TO_v37_4_0_43 Version v37.4.0.42 to version v37.4.0.43 changes
+ *
+ * \subsection v37_4_0_42_TO_v37_4_0_43Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.42 and v37.4.0.43
+ * \li \ref qcsapi_wifi_get_chan_pri_inactive
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.43-v37.4.0.44 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.43-v37.4.0.44
new file mode 100644
index 0000000..0658a86
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.43-v37.4.0.44
@@ -0,0 +1,32 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_43_TO_v37_4_0_44 Version v37.4.0.43 to version v37.4.0.44 changes
+ *
+ * \subsection v37_4_0_43_TO_v37_4_0_44Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.43 and v37.4.0.44
+ * \li \ref qcsapi_wifi_set_SSID_group_id
+ * \li \ref qcsapi_wifi_get_SSID_assoc_reserve
+ * \li \ref qcsapi_wifi_set_scs_leavedfs_chan_mtrc_mrgn
+ * \li \ref qcsapi_wifi_get_SSID_group_id
+ * \li \ref qcsapi_wifi_set_max_boot_cac_duration
+ * \li \ref qcsapi_set_custom_value
+ * \li \ref qcsapi_wifi_set_SSID_assoc_reserve
+ *
+ * \subsection v37_4_0_43_TO_v37_4_0_44Removed Removed functions
+ *
+ * The following functions were removed between versions v37.4.0.43 and v37.4.0.44
+ * \li \ref qcsapi_wifi_fget
+ *
+ * \subsection v37_4_0_43_TO_v37_4_0_44Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.43 and v37.4.0.44
+ *  - \ref qcsapi_wifi_set_bss_assoc_limit
+ *    - Old prototype: int qcsapi_wifi_set_bss_assoc_limit(const char *ifname, qcsapi_unsigned_int assoc_limit);
+ *    - New prototype: int qcsapi_wifi_set_bss_assoc_limit(const qcsapi_unsigned_int group, const qcsapi_unsigned_int limit);
+ *  - \ref qcsapi_wifi_get_bss_assoc_limit
+ *    - Old prototype: int qcsapi_wifi_get_bss_assoc_limit(const char *ifname, qcsapi_unsigned_int *p_assoc_limit);
+ *    - New prototype: int qcsapi_wifi_get_bss_assoc_limit(qcsapi_unsigned_int group, qcsapi_unsigned_int *p_assoc_limit);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.5-v37.4.0.6 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.5-v37.4.0.6
new file mode 100644
index 0000000..0075dc7
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.5-v37.4.0.6
@@ -0,0 +1,13 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_5_TO_v37_4_0_6 Version v37.4.0.5 to version v37.4.0.6 changes
+ *
+ * \subsection v37_4_0_5_TO_v37_4_0_6Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.5 and v37.4.0.6
+ *
+ * \li \ref qcsapi_wifi_ssid_get_bssid
+ * \li \ref qcsapi_wifi_ssid_set_bssid
+ * \li \ref qcsapi_get_eth_info
+ */
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.6-v37.4.0.7 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.6-v37.4.0.7
new file mode 100644
index 0000000..f8e25c5
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.6-v37.4.0.7
@@ -0,0 +1,20 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_6_TO_v37_4_0_7 Version v37.4.0.6 to version v37.4.0.7 changes
+ *
+ * \subsection v37_4_0_6_TO_v37_4_0_7Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.6 and v37.4.0.7
+ * \li \ref qcsapi_wifi_get_chan_power_table
+ * \li \ref qcsapi_wifi_get_scs_score_report
+ * \li \ref qcsapi_wifi_set_chan_power_table
+ *
+ * \subsection v37_4_0_6_TO_v37_4_0_7Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.6 and v37.4.0.7
+ *  - \ref qcsapi_enable_vlan_pass_through
+ *    - Old prototype: int qcsapi_enable_vlan_pass_through(int enabled);
+ *    - New prototype: int qcsapi_enable_vlan_pass_through(const char *ifname, int enabled);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.8-v37.4.0.9 b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.8-v37.4.0.9
new file mode 100644
index 0000000..294b5ff
--- /dev/null
+++ b/include/common/doxygen/qcsapi_doc/changelog/changes-v37.4.0.8-v37.4.0.9
@@ -0,0 +1,20 @@
+/**
+ * \page ChangeLog
+ *
+ * \section v37_4_0_8_TO_v37_4_0_9 Version v37.4.0.8 to version v37.4.0.9 changes
+ *
+ * \subsection v37_4_0_8_TO_v37_4_0_9Added Added functions
+ *
+ * The following functions were added between versions v37.4.0.8 and v37.4.0.9
+ * \li \ref qcsapi_wifi_get_ap_interface_name
+ * \li \ref qcsapi_wifi_set_ap_interface_name
+ * \li \ref qcsapi_wifi_verify_repeater_mode
+ *
+ * \subsection v37_4_0_8_TO_v37_4_0_9Proto Function prototype changes
+ *
+ * The following function prototypes were modified between versions v37.4.0.8 and v37.4.0.9
+ *  - \ref qcsapi_get_uboot_info
+ *    - Old prototype: int qcsapi_get_uboot_info(char *info, qcsapi_unsigned_int uboot_info);
+ *    - New prototype: int qcsapi_get_uboot_info(string_32 uboot_version, struct early_flash_config *ef_config);
+ */
+
diff --git a/include/common/doxygen/qcsapi_doc/groupdefine.txt b/include/common/doxygen/qcsapi_doc/groupdefine.txt
index f1d2d95..44dced9 100644
--- a/include/common/doxygen/qcsapi_doc/groupdefine.txt
+++ b/include/common/doxygen/qcsapi_doc/groupdefine.txt
@@ -58,8 +58,9 @@
  * <TABLE>
  * <TR>	<TD>\b Parameter</TD>  <TD>\b Explanation    </TD>	<TD><b> Valid value</b></TD>	</TR>
  * <TR>	<TD>mode     </TD>  <TD>wifi mode            </TD>	<TD>ap<br>sta	</TD>		</TR>
- * <TR>	<TD>bw       </TD>  <TD>Bandwidth (802.11n)  </TD>	<TD>20<br>40	</TD>		</TR>
+ * <TR>	<TD>bw       </TD>  <TD>Bandwidth (802.11n)<br>Bandwidth (802.11ac)  </TD>	<TD>20/40<br>20/40/80	</TD>		</TR>
  * <TR>	<TD>channel  </TD>  <TD>WiFi channel (802.11)</TD>	<TD>Range:0 - 255</TD>		</TR>
+ * <TR>	<TD>pmf  </TD>  <TD>PMF capability (802.11w)</TD>	<TD>0 (disabled), 1 (optional) or 2 (disabled)</TD>		</TR>
  * </TABLE>
  * Special note regarding the WiFi channel parameter check - this should be considered a sanity check,
  * as the list of valid WiFi channels is much more restricted than the range [0 - 255].<br>
@@ -140,8 +141,8 @@
  *
  * <TABLE>
  * <TR><TD>\b ACname</TD><TD>\b ACindex</TD><TD>\b Priority</TD><TD>\b Description</TD></TR>
- * <TR><TD>AC_BK</TD><TD>0</TD><TD>Lowest</TD><TD>Background traffic</TD></TR>
- * <TR><TD>AC_BE</TD><TD>1</TD><TD> </TD><TD>Best effort traffic</TD></TR>
+ * <TR><TD>AC_BK</TD><TD>1</TD><TD>Lowest</TD><TD>Background traffic</TD></TR>
+ * <TR><TD>AC_BE</TD><TD>0</TD><TD> </TD><TD>Best effort traffic</TD></TR>
  * <TR><TD>AC_VI</TD><TD>2</TD><TD> </TD><TD>Video traffic</TD></TR>
  * <TR><TD>AC_VO</TD><TD>3</TD><TD>Highest</TD><TD>Voice traffic</TD></TR>
  * </TABLE>
@@ -301,14 +302,34 @@
  * \note All MAC Address Filtering APIs work with security configuration files.
  * Their location is determined by the get file path configuration API (section @ref File_Path_conf "File Path configuration").
  * Results from these APIs may be inconsistent or incorrect if the file path to this security configuration files has not been correctly configured.
- * 
+ *
  * @section mysection9_1 Data Type to Configure MAC Address Filtering
- * 
+ *
  * @section mysection9_2 Error Codes from MAC Address Filtering APIs
  * The API that returns a list of authorized MAC addresses will fail with an error code of Configuration Error if the MAC address filtering is not set to Deny Unless Authorized.
  * The API that returns a list of denied or blocked MAC addresses will fail with error code Configuration Error if the MAC address filtering is not set to Authorize Unless Denied.<br>
  * Both of those APIs will fail with an error code of Buffer Overflow if the length of the string is too short to store all MAC addresses. <br>
- * See @ref mysection4_1_4 "section here" for more details on error codes and error messages.
+ * See @ref mysection4_1_4 "QCSAPI Return Values" for more details on error codes and error messages.
+ */
+
+/**@defgroup MACReserveAPIs MAC Address Reservation APIs
+ * @brief MAC address reservation can be used to prevent associated WiFi devices and downstream
+ * devices from hijacking MAC addresses that belong to core network devices.
+ *
+ * MAC address reservation is implemented on an Access Point by configuring a list of up to six
+ * reserved MAC addresses.  An optional mask can be supplied with each entry in order to reserve a
+ * range of MAC addresses.
+ *
+ * The following example reserves 1c:6f:65:d1:bf:01 and the 16 MAC addresses from 1c:6f:65:d1:bf:10
+ * to 1c:6f:65:d1:bf:1f are reserved for devices on the wired side of the Access Point.
+ *
+ * <c>call_qcsapi set_macaddr_reserve wifi0 1c:6f:65:d1:bf:01</c>
+ *
+ * <c>call_qcsapi set_macaddr_reserve wifi0 1c:6f:65:d1:bf:10 ff:ff:ff:ff:ff:f0</c>
+ *
+ * Any association request with a source address that matches an entry in the reserved MAC address
+ * list is refused, and any Ethernet packet with a source address that matches an entry in the
+ * reserved MAC address list is dropped.
  */
 
 /**@defgroup OptionsAPIs Options
@@ -339,6 +360,14 @@
  * <TR>		<TD>qcsapi_GI_probing</TD>		<TD>GI_probing</TD>	</TR>
  * <TR>		<TD>qcsapi_GI_fixed</TD>		<TD>GI_fixed</TD>	</TR>
  * <TR>		<TD>qcsapi_stbc</TD>		<TD>stbc</TD>	</TR>
+ * <TR>		<TD>qcsapi_beamforming</TD>		<TD>beamforming</TD>	</TR>
+ * <TR>		<TD>qcsapi_short_slot</TD>		<TD>short_slot</TD>	</TR>
+ * <TR>		<TD>qcsapi_short_preamble</TD>		<TD>short_preamble</TD>	</TR>
+ * <TR>		<TD>qcsapi_rts_cts</TD>		<TD>rts_cts</TD>	</TR>
+ * <TR>		<TD>qcsapi_40M_only</TD>		<TD>40M_bw_only</TD>	</TR>
+ * <TR>		<TD>qcsapi_obss_coexist</TD>		<TD>obss_coexist</TD>	</TR>
+ * <TR>		<TD>qcsapi_11g_protection</TD>		<TD>11g_protection</TD>	</TR>
+ * <TR>		<TD>qcsapi_11n_protection</TD>		<TD>11n_protection</TD>	</TR>
  * </TABLE>
  * To access the get option API enter:<br>
  * <c>call_qcsapi get_option wifi0 \<option\>	</c><br>
@@ -678,16 +707,20 @@
  * 20 MHz.  Boot parameter <c>calstate</c> must be set to 1.
  */
 
-/**@defgroup DFSAPIs DFS / Radar APIs
+/**@defgroup DFSAPIs DFS, Radar and OCAC APIs
  * Selected channels in the 5 GHz frequency range are also used by weather and military radar.
  * To prevent unwanted interference, WiFi devices using those channels are required to follow special protocols, as describe in 802.11h.
  * APIs are available that list channels that are subject to the DFS protocols and channels that are not subject to those protocols.
  * A separate API reports whether a particular channel is subject to DFS protocols.
  * As the exact DFS-related regulations are determined by the regulatory authority,
  * the regulatory region is a required parameter for all these APIs.
+ *
+ * @section mysection16_1 OCAC
+ * OCAC is a feature where the DFS master device will periodically scan off-channel in order to detect radar on a channel different to
+ * the current operating channel. This feature is limited to operation with up to 2 BSSes only.
  */
 
-/**@defgroup ScanAPIs Reporting on the Results of a Scan for APs on the STA
+/**@defgroup ScanAPIs Scan APIs
  * This section describes APIs that report on properties of APs that were found when the STA scanned the WiFi channels.<br>
  * When a WiFi device configured as a STA starts up, it typically scans the WiFi channels for APs in its neighborhood.
  *
@@ -837,10 +870,6 @@
  * \brief These APIs are used to configure and get status for the Quantenna Smart Channel Select (SCS) feature.
  */
 
-/**@defgroup ParameterOCACAPIs Off Channel CAC APIs
- * \brief These APIs are used to configure, control and obtain status for off-channel CAC.
- */
-
 /**@defgroup VLANAPIs VLAN APIs
  * \brief These APIs are used to configure, control and obtain status for VLANs within the Quantenna device.
  *
@@ -892,3 +921,27 @@
 /**@defgroup StatisticsAPIs Statistics APIs
  * \brief These APIs are used to obtain statistics from the device.
  */
+
+/**@defgroup ServicesAPIs Linux Services APIs
+ * \brief These APIs are used for Linux daemon control.
+ */
+
+/**@defgroup QTM_group Quantenna Traffic Management (QTM) APIs
+ * \brief These APIs are used for Quantenna Traffic Management (QTM) configuration.
+ */
+
+/**@defgroup TDLS_group TDLS APIs
+ * \brief These APIs are used for configuration and control of TDLS.
+ */
+
+/**@defgroup MU_group Multi-user MIMO APIs
+ * \brief These APIs are used for debugging and display of MU details.
+ */
+
+/**@defgroup WOWLAN_group Wake on WLAN (WoWLAN) APIs
+ * \brief These APIs are used for Wake on WLAN configuration and control.
+ */
+
+/**@defgroup ANDROID_group Android APIs
+ * \brief These APIs are used for integrating QTN firmware with Android host.
+ */
diff --git a/include/common/doxygen/qcsapi_doc/vsp_doc.c b/include/common/doxygen/qcsapi_doc/vsp_doc.c
index 3f51cf7..f74a81a 100644
--- a/include/common/doxygen/qcsapi_doc/vsp_doc.c
+++ b/include/common/doxygen/qcsapi_doc/vsp_doc.c
@@ -310,7 +310,7 @@
 
 int main(int argc, char **argv)
 {
-	printf("/** \\addtogroup vsp_group\n\n");
+	printf("/** @addtogroup vsp_group\n\n");
 	create_cfg_table();
 	create_rule_table();
 	printf(" */\n");
diff --git a/include/common/ruby_arasan_emac_ahb.h b/include/common/ruby_arasan_emac_ahb.h
index 4e91368..2d36410 100755
--- a/include/common/ruby_arasan_emac_ahb.h
+++ b/include/common/ruby_arasan_emac_ahb.h
@@ -23,6 +23,10 @@
 #ifndef __COMMON_RUBY_ARASAN_EMAC_AHB_H
 #define __COMMON_RUBY_ARASAN_EMAC_AHB_H	1
 
+#ifdef TOPAZ_AMBER_IP
+#include <include/qtn/amber.h>
+#endif
+
 extern __inline__ void __mydelay(unsigned long loops)
 {
 	__asm__ __volatile__ ( "1: \n\t"
@@ -347,9 +351,13 @@
 
 	/* 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 (emac_cfg & EMAC_PHY_MII) {
-		writel(RUBY_SYS_CTL_MASK_MII, RUBY_SYS_CTL_CTRL);
-	} else {
+	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 */
@@ -377,14 +385,13 @@
 	} else if (emac0_cfg & EMAC_IN_USE) {
 		reset_mask = RUBY_SYS_CTL_RESET_ENET0;
 	}
-#ifdef TOPAZ_PLATFORM
+#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) {
-#else
-	if (reset_mask) {
-#endif
 		writel(reset_mask, RUBY_SYS_CTL_CPU_VEC_MASK);
 		if (ext_reset) {
 			writel(RUBY_SYS_CTL_RESET_EXT, RUBY_SYS_CTL_CPU_VEC);
@@ -400,6 +407,9 @@
 
 	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
diff --git a/include/common/ruby_board_cfg.h b/include/common/ruby_board_cfg.h
index 8011d68..dc5275a 100644
--- a/include/common/ruby_board_cfg.h
+++ b/include/common/ruby_board_cfg.h
@@ -25,17 +25,6 @@
 
 #include "ruby_platform.h"
 
-#ifndef TOPAZ_PLATFORM
-
-	#ifdef PLATFORM_DEFAULT_BOARD_ID
-		#define DEFAULT_BOARD_ID        PLATFORM_DEFAULT_BOARD_ID
-	#else
-        	/* Default board id used to match Ruby settings if there is no SPI Flash */
-        	#define  DEFAULT_BOARD_ID	QTN_RUBY_BOARD_TYPE_DEFAULT
-	#endif /* #ifdef PLATFORM_DEFAULT_BOARD_ID */
-
-#endif /* #ifndef TOPAZ_PLATFORM */
-
 #define	SPI1_NOT_IN_USE			(0)
 #define	SPI1_IN_USE			(BIT(0))
 
diff --git a/include/common/ruby_board_db.h b/include/common/ruby_board_db.h
index df2b056..da7883d 100644
--- a/include/common/ruby_board_db.h
+++ b/include/common/ruby_board_db.h
@@ -140,10 +140,17 @@
 	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),
 	{ "DEFAULT_WIFI_HW", QTN_RUBY_REF_RWPA },
 	{ 0 , 0 }
 };
@@ -228,9 +235,11 @@
 
 #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 }
 };
diff --git a/include/common/ruby_config.h b/include/common/ruby_config.h
index 0595381..c50e98a 100644
--- a/include/common/ruby_config.h
+++ b/include/common/ruby_config.h
@@ -120,11 +120,13 @@
 #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)
diff --git a/include/common/ruby_mem.h b/include/common/ruby_mem.h
index ed84487..013e07b 100644
--- a/include/common/ruby_mem.h
+++ b/include/common/ruby_mem.h
@@ -38,82 +38,60 @@
 #define RUBY_DSP_XYMEM_END			0xDFFFFFFF
 
 /* SRAM layout */
-#define RUBY_CRUMBS_SIZE		64	/* bytes at the very end of sram for crash tracing */
 
-#ifdef TOPAZ_PLATFORM
 #ifdef QTN_RC_ENABLE_HDP
-	#define TOPAZ_HBM_BUF_EMAC_RX_COUNT_S		(14)
-	#define TOPAZ_HBM_BUF_WMAC_RX_COUNT_S		(0)
+#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)
+#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_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)
+#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_ARC_KERNEL_SRAM_B1_BASE		ROUNDUP(TOPAZ_FWT_SW_END, CONFIG_ARC_KERNEL_PAGE_SIZE)
-	#define CONFIG_ARC_KERNEL_SRAM_B1_SIZE		(30 * 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) -	\
-							 ROUNDUP(TOPAZ_VNET_WR_STAGING_RESERVE, CONFIG_ARC_KERNEL_PAGE_SIZE))
-	#define CONFIG_ARC_KERNEL_SRAM_B2_SIZE		(CONFIG_ARC_KERNEL_SRAM_B2_END - CONFIG_ARC_KERNEL_SRAM_B2_BASE)
-	#define TOPAZ_VNET_WR_STAGING_1_START		CONFIG_ARC_KERNEL_SRAM_B2_END
-	#define TOPAZ_VNET_WR_STAGING_1_SIZE		TOPAZ_VNET_WR_STAGING_RESERVE
-	#define TOPAZ_VNET_WR_STAGING_1_END		(TOPAZ_VNET_WR_STAGING_1_START + TOPAZ_VNET_WR_STAGING_1_SIZE)
-	#define TOPAZ_VNET_WR_STAGING_2_START		ROUNDUP(TOPAZ_VNET_WR_STAGING_1_END, RUBY_SRAM_BANK_SIZE)
-	#define TOPAZ_VNET_WR_STAGING_2_SIZE		TOPAZ_VNET_WR_STAGING_RESERVE
-	#define TOPAZ_VNET_WR_STAGING_2_END		(TOPAZ_VNET_WR_STAGING_2_START + TOPAZ_VNET_WR_STAGING_2_SIZE)
-	#if TOPAZ_VNET_WR_STAGING_2_START != (2 * RUBY_SRAM_BANK_SIZE)
-		#error SRAM linkmap error forming topaz sram wr staging
-	#endif
-	#define CONFIG_ARC_MUC_SRAM_B1_BASE		ROUNDUP(TOPAZ_VNET_WR_STAGING_2_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_SRAM_SIZE		(3 * RUBY_SRAM_BANK_SIZE)
-	#define CONFIG_ARC_AUC_SRAM_END			(CONFIG_ARC_AUC_SRAM_BASE + CONFIG_ARC_AUC_SRAM_SIZE)
-	#define CONFIG_ARC_SRAM_END			CONFIG_ARC_AUC_SRAM_END
+/* 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)
 
-	/* MU TxBF qmatrix is stored at the last bank of SRAM, DSP writes to it, has to use SRAM BUS addr */
-        #define CONFIG_ARC_MU_QMAT_BASE			(RUBY_SRAM_BUS_BEGIN + 0X70000)
-	#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_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)
 
-#else	/* Ruby */
-	#define CONFIG_ARC_KERNEL_SRAM_B1_BASE		0x00000000
-	#define CONFIG_ARC_KERNEL_SRAM_B1_SIZE		RUBY_SRAM_BANK_SAFE_SIZE
-	#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_BASE + RUBY_SRAM_BANK_SIZE)
-	#define CONFIG_ARC_KERNEL_SRAM_B2_SIZE		RUBY_SRAM_BANK_SAFE_SIZE
-	#define CONFIG_ARC_KERNEL_SRAM_B2_END		(CONFIG_ARC_KERNEL_SRAM_B2_BASE + CONFIG_ARC_KERNEL_SRAM_B2_SIZE)
-	#define CONFIG_ARC_MUC_SRAM_B1_BASE		ROUNDUP(CONFIG_ARC_KERNEL_SRAM_B2_END, RUBY_SRAM_BANK_SIZE)
-	#define CONFIG_ARC_MUC_SRAM_B1_SIZE		RUBY_SRAM_BANK_SAFE_SIZE
-	#define CONFIG_ARC_MUC_SRAM_B1_END		(CONFIG_ARC_MUC_SRAM_B1_BASE + CONFIG_ARC_MUC_SRAM_B1_SIZE)
-	#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)
-#endif /* TOPAZ_PLATFORM */
+#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_SRAM_SIZE		(3 * RUBY_SRAM_BANK_SIZE)
+#define CONFIG_ARC_AUC_SRAM_END			(CONFIG_ARC_AUC_SRAM_BASE + CONFIG_ARC_AUC_SRAM_SIZE)
+#define CONFIG_ARC_SRAM_END			CONFIG_ARC_AUC_SRAM_END
+
+/* MU TxBF qmatrix is stored at the last bank of SRAM, DSP writes to it, has to use SRAM BUS addr */
+#define CONFIG_ARC_MU_QMAT_BASE			(RUBY_SRAM_BUS_BEGIN + 0X70000)
+#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)
 
 #if TOPAZ_RX_ACCELERATE
 	/* TODO FIXME - MuC crashed when copying data between SRAM and DDR */
@@ -142,107 +120,100 @@
 #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_PLATFORM
 #ifdef TOPAZ_128_NODE_MODE
-#define CONFIG_ARC_MUC_SIZE		((3 * 1024 * 1024) + (368 * 1024))
+#define CONFIG_ARC_MUC_SIZE		((3 * 1024 * 1024) + (580 * 1024))
 #else
 #define CONFIG_ARC_MUC_SIZE		((2 * 1024 * 1024) + (768 * 1024))
 #endif
-#else
-#define CONFIG_ARC_MUC_SIZE             ((1 * 1024 * 1024) + (640 * 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)
-#ifdef TOPAZ_PLATFORM
-	#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 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_SIZE	(4 * 1024)
-	#define TOPAZ_HBM_BUF_WMAC_RX_SIZE	(17 * 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_META_SIZE		64		/* keep it 2^n */
-	#define TOPAZ_HBM_POOL_GUARD_SIZE	(64 * 1024)
+#define TOPAZ_HBM_BUF_EMAC_RX_SIZE	(4 * 1024)
+#define TOPAZ_HBM_BUF_WMAC_RX_SIZE	(17 * 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_SIZE		64		/* keep it 2^n */
+#define TOPAZ_HBM_POOL_GUARD_SIZE	(64 * 1024)
 
-	#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_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_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_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_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_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_BASE		ROUNDUP(TOPAZ_HBM_BUF_META_END, TOPAZ_HBM_BUF_ALIGN)
+#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_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_BASE		ROUNDUP(TOPAZ_HBM_BUF_META_END, TOPAZ_HBM_BUF_ALIGN)
 
-	#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_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_END		(TOPAZ_HBM_BUF_WMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
+#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_FWT_MCAST_ENTRIES		2048
-	#define TOPAZ_FWT_MCAST_FF_ENTRIES	8	/* one per vap */
-	#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_HBM_BUF_END		(TOPAZ_HBM_BUF_WMAC_RX_END + TOPAZ_HBM_POOL_GUARD_SIZE)
 
-	#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
+#define TOPAZ_FWT_MCAST_ENTRIES		2048
+#define TOPAZ_FWT_MCAST_FF_ENTRIES	8	/* one per vap */
+#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)
 
-	/* Offset from DDR beginning, from which memory start to belong to Linux */
-	#define CONFIG_ARC_KERNEL_MEM_BASE	TOPAZ_FWT_MCAST_END
+#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
 
-	#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
-#else
-	/* Offset from DDR beginning, from which memory start to belong to Linux */
-	#define CONFIG_ARC_KERNEL_MEM_BASE	CONFIG_ARC_MUC_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)
 
@@ -277,13 +248,8 @@
 			/* 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"
-			#if defined(PROFILE_LINUX_EP) || defined(TOPAZ_PLATFORM)
-			# define __sram_text
-			# define __sram_data
-			#else
-			# define __sram_text		__attribute__ ((__section__ (__sram_text_sect_name)))
-			# define __sram_data		__attribute__ ((__section__ (__sram_data_sect_name)))
-			#endif
+			#define __sram_text
+			#define __sram_data
 		#else
 			#define __sram_text_sect_name	".text"
 			#define __sram_data_sect_name	".data"
diff --git a/include/common/ruby_partitions.h b/include/common/ruby_partitions.h
index 4d1fa71..1af2bc5 100644
--- a/include/common/ruby_partitions.h
+++ b/include/common/ruby_partitions.h
@@ -29,26 +29,39 @@
 #define __RUBY_PARTITIONS_H
 
 #define F64K_UBOOT_PIGGY_PARTITION_SIZE	0x5000
-#if defined(TOPAZ_PLATFORM)
-	#define F64K_ENV_PARTITION_SIZE		0x6000
-#else
-	#define F64K_ENV_PARTITION_SIZE         0x4000
+
+#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
-#define UBOOT_ENV_PARTITION_SIZE	0x10000
 
 /*
  * Make sure CONFIG_ENV_SIZE in file carve_env_partition.sh is the same value
  */
-#if defined(TOPAZ_PLATFORM)
+#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			(16 * 1024)
+	#define BOOT_CFG_SIZE			(64 * 1024)
 #endif
 
-#define BOOT_CFG_BASE_SIZE              (16 * 1024)
+#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)
 
@@ -57,23 +70,32 @@
 #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"
 
-#if defined(TOPAZ_PLATFORM)
-	#define IMG_SIZE_LIMIT_PLATFORM	IMG_SIZE_16M_FLASH_2_IMG
-#else
-	#define IMG_SIZE_LIMIT_PLATFORM	IMG_SIZE_8M_FLASH_2_IMG
-#endif
+#define IMG_SIZE_LIMIT_PLATFORM	IMG_SIZE_16M_FLASH_2_IMG
 
 #endif // #ifndef __RUBY_PARTITIONS_H
 
diff --git a/include/common/ruby_platform.h b/include/common/ruby_platform.h
index f6d030c..9708d63 100644
--- a/include/common/ruby_platform.h
+++ b/include/common/ruby_platform.h
@@ -89,6 +89,7 @@
 #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)
@@ -109,7 +110,13 @@
 #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)
 
 /*****************************************************************************/
@@ -407,17 +414,7 @@
 #define RUBY_SYS_CTL_MASK_DDRCLK	(0x7 << 22)
 #define RUBY_SYS_CTL_MASK_LINUX_MAP	(0x1 << 31)
 
-#if !TOPAZ_FPGA_PLATFORM
-#define RUBY_SYS_CTL_CFG0_PCIE_RC	(0x4)
-#else
-#define RUBY_SYS_CTL_CFG0_PCIE_RC	(0x14)
-#endif
-
-#if defined(TOPAZ_PLATFORM)
-# define RUBY_RESET_CAUSE_UART_SHIFT	(7)
-#else
-# define RUBY_RESET_CAUSE_UART_SHIFT	(24)
-#endif
+#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 */
@@ -474,6 +471,11 @@
 #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
 
 /*
  * UBOOT_VERSION_LOCATION:
@@ -560,19 +562,14 @@
 #define RUBY_IRQ_GPIO			(25)
 #define RUBY_IRQ_TIMER			(26)
 #define RUBY_IRQ_MISC			(27)
-#if defined(TOPAZ_PLATFORM)
-	/* 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
-#else
-	#define RUBY_IRQ_MSI			(28)
-	#define RUBY_IRQ_INTA			(29)
-#endif
+/* 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)
@@ -610,13 +607,8 @@
 #define RUBY_IRQ_MISC_EXT_IRQ_START		(56)
 #define RUBY_IRQ_MISC_RST_CAUSE_START	(26)
 
-#if defined(TOPAZ_PLATFORM)
 #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
-#else
-#define QTN_IRQ_MISC_EXT_IRQ_COUNT		RUBY_IRQ_MISC_EXT_IRQ_COUNT
-#define QTN_IRQ_MISC_RST_CAUSE_START	RUBY_IRQ_MISC_RST_CAUSE_START
-#endif
 
 #define RUBY_MAX_IRQ_EXT_VECTOR		(63)
 #define RUBY_IRQ_EXT_VECTORS_NUM	(RUBY_MAX_IRQ_EXT_VECTOR + 1)
diff --git a/include/common/ruby_pm.h b/include/common/ruby_pm.h
index c12b8cc..052b46e 100644
--- a/include/common/ruby_pm.h
+++ b/include/common/ruby_pm.h
@@ -44,6 +44,7 @@
 
 /* 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)
 
 /* qdisc parameters to switch between modes */
@@ -93,6 +94,7 @@
 	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) */
diff --git a/include/common/ruby_spi_api.h b/include/common/ruby_spi_api.h
index d12ba3d..1612a0d 100644
--- a/include/common/ruby_spi_api.h
+++ b/include/common/ruby_spi_api.h
@@ -86,12 +86,8 @@
 * Topaz uses all 4 bytes, just skip first msb if in 3-bytes address mode.
 *
 */
-#ifdef TOPAZ_PLATFORM
-        #define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF))
-#else
-        #define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF) << 8)
-#endif
-
+#define SPI_MEM_ADDR(addr)      (((addr) & 0x00FFFFFF))
+#define SPI_MEM_ADDR_4B(addr)	(((addr) & 0xFFFFFFFF))
 
 enum SPI_TYPES{
 	NOT_SUPPORTED,
@@ -103,6 +99,7 @@
 	MACRONIX,
 	ESMT,
 	EON,
+	MICRON,
 	GD
 };
 
diff --git a/include/common/ruby_spi_flash_data.h b/include/common/ruby_spi_flash_data.h
index a8d79e0..3006f73 100644
--- a/include/common/ruby_spi_flash_data.h
+++ b/include/common/ruby_spi_flash_data.h
@@ -78,9 +78,13 @@
 	{ "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 },
-	{ "s25sl032a", 0x010215, 64 * 1024, 64, 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 },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
 	{ "sst25vf040b", 0xbf258d, 64 * 1024, 8, 0, FREQ_UNKNOWN, SST },
@@ -122,7 +126,8 @@
 	{ "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 },
-	{ "mx25l25635", 0xc22019, 64 * 1024, 256, 0, FREQ_MHZ(50), MACRONIX },
+	{ "mx25l25635f", 0xc22019, 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 },
diff --git a/include/common/ruby_version.h b/include/common/ruby_version.h
index b7b34dc..7664b11 100644
--- a/include/common/ruby_version.h
+++ b/include/common/ruby_version.h
@@ -1,5 +1,5 @@
 #ifndef __RUBY_RELEASE_H__
-#define __RUBY_RELEASE__H__
+#define __RUBY_RELEASE_H__
 /*
  * Copyright (c) 2011 Quantenna Communications, Inc.
  * All rights reserved.
@@ -12,6 +12,6 @@
 // Defines
 ////////////////////////////////////////////////////////////////////////////
 
-#define RUBY_UBOOT_VERSION	"v37.3.0.22"
+#define RUBY_UBOOT_VERSION	"v37.4.0.28"
 
 #endif // __RUBY_RELEASE_H__
diff --git a/include/common/topaz_config.h b/include/common/topaz_config.h
index bc488bc..5be0113 100644
--- a/include/common/topaz_config.h
+++ b/include/common/topaz_config.h
@@ -30,32 +30,20 @@
 
 #include "current_platform.h"
 
-#ifdef TOPAZ_PLATFORM
 #if !TOPAZ_FPGA_PLATFORM
 #undef TOPAZ_ICACHE_WORKAROUND
 #endif
-#endif
 
 /*
  * Control registers move depending on unified + alias bit
  */
 
-#ifdef TOPAZ_PLATFORM
-	#define TOPAZ_MMAP_UNIFIED	0
-	#define TOPAZ_MMAP_ALIAS	0
-	#define TOPAZ_RX_ACCELERATE	1
-#else
-	#define TOPAZ_MMAP_UNIFIED	0
-	#define TOPAZ_MMAP_ALIAS	0
-	#define TOPAZ_RX_ACCELERATE	0
-#endif
+#define TOPAZ_MMAP_UNIFIED	0
+#define TOPAZ_MMAP_ALIAS	0
+#define TOPAZ_RX_ACCELERATE	1
 
 /* If MU-MIMO done in HDP or SDP */
-#ifdef TOPAZ_PLATFORM
-	#define QTN_HDP_MU		1
-#else
-	#define QTN_HDP_MU		0
-#endif
+#define QTN_HDP_MU		1
 
 #if QTN_HDP_MU
 #define QTN_HDP_MU_FCS_WORKROUND	1
@@ -85,105 +73,66 @@
 	#define TOPAZ_FPGA_PLATFORM	0
 #endif
 
-#ifndef TOPAZ_VNET_WR_STAGING
-	#define TOPAZ_VNET_WR_STAGING	0
-#endif
-#define TOPAZ_VNET_WR_DMA_CHANNELS			2
-#define TOPAZ_VNET_WR_STAGING_BUF_COUNT_PER_CHAIN	10
-#define TOPAZ_VNET_WR_STAGING_BUF_SIZE			0x600
-#if TOPAZ_VNET_WR_STAGING
-	#define TOPAZ_VNET_WR_STAGING_ALIGN			0x80
-	#define TOPAZ_VNET_WR_STAGING_GAP			TOPAZ_VNET_WR_STAGING_ALIGN
-	#define TOPAZ_VNET_WR_STAGING_RESERVE			((TOPAZ_VNET_WR_STAGING_BUF_COUNT_PER_CHAIN * \
-								  TOPAZ_VNET_WR_STAGING_BUF_SIZE) + \
-								 TOPAZ_VNET_WR_STAGING_GAP)
+/* 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_VNET_WR_STAGING_RESERVE			0
+	#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
 
-#ifdef TOPAZ_PLATFORM
-	/* 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 */
+#define CONFIG_RUBY_BROKEN_IPC_IRQS	0
 
-	/*
-	 * 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
+#define RUBY_IPC_HI_IRQ(bit_num)	((bit_num) + 8)
+#define RUBY_M2L_IPC_HI_IRQ(bit_num)	(bit_num)
 
-	/*
-	 * 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
+#define PLATFORM_REG_SWITCH(reg1, reg2)	(reg2)
 
-	#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 */
+#define writel_topaz(a, b)		writel(a, b)
+#define writel_ruby(a, b)
 
-	#ifndef PLATFORM_ARC7_MMU_VER
-		#define PLATFORM_ARC7_MMU_VER	2
-	#endif
+#define QTN_VLAN_LLC_ENCAP		1
 
-	#define CONFIG_RUBY_BROKEN_IPC_IRQS	0
+#define TOPAZ_128_NODE_MODE		1
 
-	#define RUBY_IPC_HI_IRQ(bit_num)	((bit_num) + 8)
-	#define RUBY_M2L_IPC_HI_IRQ(bit_num)	(bit_num)
+#define TOPAZ_ETH_REFLECT_SW_FWD	0
 
-	#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
-#else
-	#ifndef PLATFORM_ARC7_MMU_VER
-		#define PLATFORM_ARC7_MMU_VER	2
-	#endif
-
-	/*
-	 * For BBIC3.
-	 * Workaround for IPC interrupt hw flaw. When receiver dynamically masks/unmasks
-	 * interrupt, the transmitter cannot distinguish whether interrupt was acked or just masked.
-	 */
-	#define CONFIG_RUBY_BROKEN_IPC_IRQS	1
-
-	#define RUBY_IPC_HI_IRQ(bit_num)	((bit_num) + 16)
-	#define RUBY_M2L_IPC_HI_IRQ(bit_num)	((bit_num) + 16)
-
-	#define PLATFORM_REG_SWITCH(reg1, reg2)	(reg1)
-
-	#define writel_topaz(a, b)
-	#define writel_ruby(a, b)		writel(a, b)
-
-	#define QTN_VLAN_LLC_ENCAP		0
-#endif /* #ifdef TOPAZ_PLATFORM */
+#define DSP_ENABLE_STATS		1
 
 #endif /* #ifndef __TOPAZ_CONFIG_H */
 
diff --git a/include/common/topaz_emac.h b/include/common/topaz_emac.h
index 2120feb..b6c0bcc 100644
--- a/include/common/topaz_emac.h
+++ b/include/common/topaz_emac.h
@@ -274,5 +274,8 @@
 #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/include/common/topaz_platform.h b/include/common/topaz_platform.h
index 3f94e51..be27da5 100644
--- a/include/common/topaz_platform.h
+++ b/include/common/topaz_platform.h
@@ -37,6 +37,14 @@
 #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))
@@ -117,8 +125,10 @@
 #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 reflected pkts */
+#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)
@@ -463,6 +473,16 @@
 #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)
diff --git a/include/common/topaz_reset.h b/include/common/topaz_reset.h
new file mode 100644
index 0000000..fab7393
--- /dev/null
+++ b/include/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/include/common/topaz_rfic6_config b/include/common/topaz_rfic6_config
new file mode 100644
index 0000000..0b7d498
--- /dev/null
+++ b/include/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/include/common/uboot_header.h b/include/common/uboot_header.h
index 57e4fda..478cf06 100644
--- a/include/common/uboot_header.h
+++ b/include/common/uboot_header.h
@@ -18,6 +18,10 @@
  *
  * 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            */
 
@@ -47,3 +51,20 @@
 	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/include/kernel/net80211/ieee80211_linux.h b/include/kernel/net80211/ieee80211_linux.h
index 03c1edf..67285ae 100644
--- a/include/kernel/net80211/ieee80211_linux.h
+++ b/include/kernel/net80211/ieee80211_linux.h
@@ -528,6 +528,7 @@
 
 void ieee80211_ioctl_vattach(struct ieee80211vap *);
 void ieee80211_ioctl_vdetach(struct ieee80211vap *);
+void sample_rel_client_data(struct ieee80211vap *vap);
 struct ifreq;
 int ieee80211_ioctl_create_vap(struct ieee80211com *, struct ifreq *,
 	struct net_device *);
diff --git a/include/kernel/net80211/ieee80211_node.h b/include/kernel/net80211/ieee80211_node.h
index 19f88b9..778303e 100644
--- a/include/kernel/net80211/ieee80211_node.h
+++ b/include/kernel/net80211/ieee80211_node.h
@@ -40,9 +40,7 @@
 #include "qtn/muc_phy_stats.h"
 #include "qtn/shared_defs.h"
 #include "qtn/qdrv_sch_data.h"
-#ifdef TOPAZ_PLATFORM
 #include "qtn/topaz_shared_params.h"
-#endif
 
 /* #define IEEE80211_DEBUG_REFCNT */
 #define IEEE80211_NODEREF_INCR	1
@@ -83,7 +81,7 @@
 #define	IEEE80211_INACT_WAIT	5		/* inactivity interval (secs) */
 #define	IEEE80211_INACT_INIT	(30/IEEE80211_INACT_WAIT)	/* initial */
 #define	IEEE80211_INACT_AUTH	(30/IEEE80211_INACT_WAIT)	/* associated but not authorized */
-#define	IEEE80211_INACT_RUN	(30 /IEEE80211_INACT_WAIT)	/* authorized */
+#define	IEEE80211_INACT_RUN	(90 /IEEE80211_INACT_WAIT)	/* authorized */
 #define	IEEE80211_INACT_PROBE	(10/IEEE80211_INACT_WAIT)	/* probe */
 #define	IEEE80211_INACT_SCAN	(300/IEEE80211_INACT_WAIT)	/* scanned */
 #define IEEE80211_INACT_SEND_PKT_THRSH	3			/* The threshold that starts to send detection packet */
@@ -132,8 +130,6 @@
 	u_int8_t		dlg_out;
 	u_int8_t		dlg_in;
 	u_int16_t		flags;
-	u_int8_t                dtls_present; /* detected DTLS session */
-	unsigned long           dtls_jiffies; /* DTLS detect timestamp */
 #ifdef CONFIG_QVSP
 	struct ieee80211_ba_throt ba_throt;
 #endif
@@ -304,6 +300,7 @@
 	u_int32_t *ni_challenge;			/* shared-key challenge */
 	u_int8_t *ni_wpa_ie;			/* captured WPA ie */
 	u_int8_t *ni_rsn_ie;			/* captured RSN ie */
+	u_int8_t *ni_osen_ie;			/* captured OSEN ie */
 	u_int8_t *ni_wme_ie;			/* captured WME ie */
 	u_int8_t *ni_wsc_ie;			/* captured WSC ie */
 	u_int8_t *ni_ath_ie;			/* captured Atheros ie */
@@ -524,10 +521,17 @@
 	uint8_t ni_used_auth_algo;
 	int32_t	rssi_avg_dbm;
 	uint8_t ni_wifi_mode;
+	uint8_t ni_vhtop_notif_mode;
 
 #ifdef IEEE80211_DEBUG_REFCNT
 	struct node_refdebug_info *ni_refdebug_info_p;
 #endif
+	uint8_t ni_coex;
+	uint8_t ni_obss_scan;
+	struct ieee80211_obss_scan_ie ni_obss_ie;
+#define IEEE80211_NODE_OBSS_CAPABLE	0x00000001
+#define IEEE80211_NODE_OBSS_RUNNING	0x00000002
+#define IEEE80211_NODE_OBSS_NOT_RUN	0x00000004
 };
 MALLOC_DECLARE(M_80211_NODE);
 
@@ -616,7 +620,7 @@
 void ieee80211_node_unauthorize(struct ieee80211_node *);
 void ieee80211_tdls_add_rate_detection(struct ieee80211_node *);
 void ieee80211_node_training_start(struct ieee80211_node *ni, int immediate);
-
+void ieee80211_restore_bw(struct ieee80211vap *vap, struct ieee80211com *ic);
 void ieee80211_create_bss(struct ieee80211vap *, struct ieee80211_channel *);
 void ieee80211_reset_bss(struct ieee80211vap *);
 int ieee80211_ibss_merge(struct ieee80211_node *);
@@ -629,7 +633,10 @@
 void ieee80211_send_vht_opmode_action(struct ieee80211vap *vap,
                                        struct ieee80211_node *ni,
                                        uint8_t bw, uint8_t rx_nss);
-
+int ieee80211_send_20_40_bss_coex(struct ieee80211vap *vap);
+int ieee80211_check_mode(struct ieee80211vap *vap);
+void ieee80211_nonqtn_sta_join(struct ieee80211vap *vap, struct ieee80211_node *ni);
+void ieee80211_nonqtn_sta_leave(struct ieee80211vap *vap, struct ieee80211_node *ni);
 
 #define WDS_AGING_TIME		600   /* 10 minutes */
 #define WDS_AGING_COUNT		2
diff --git a/include/kernel/net80211/ieee80211_proto.h b/include/kernel/net80211/ieee80211_proto.h
index e678dca..99a7cd5 100644
--- a/include/kernel/net80211/ieee80211_proto.h
+++ b/include/kernel/net80211/ieee80211_proto.h
@@ -71,7 +71,7 @@
 	const u_int8_t *, int);
 int ieee80211_parse_htcap(struct ieee80211_node *ni, u_int8_t *ie);
 int ieee80211_parse_htinfo(struct ieee80211_node *ni, u_int8_t *ie);
-int ieee80211_parse_vhtcap(struct ieee80211_node *ni, u_int8_t *ie);
+void ieee80211_parse_vhtcap(struct ieee80211_node *ni, u_int8_t *ie);
 int ieee80211_parse_vhtop(struct ieee80211_node *ni, u_int8_t *ie);
 int ieee80211_parse_rates(struct ieee80211_node *ni,
 	const u_int8_t *rates, const u_int8_t *xrates);
@@ -80,6 +80,7 @@
 void ieee80211_saveath(struct ieee80211_node *, u_int8_t *);
 int ieee80211_input_tdls_qtnie(struct ieee80211_node *ni, struct ieee80211vap *vap,
 				struct ieee80211_ie_qtn *qtnie);
+void ieee80211_update_current_mode(struct ieee80211_node *ni);
 #if TOPAZ_RX_ACCELERATE
 int ieee80211_tdls_tqe_path_check(struct ieee80211_node *ni, struct sk_buff *skb, int rssi, uint16_t ether_type);
 #endif
@@ -87,11 +88,13 @@
 	int, int, u_int32_t);
 void ieee80211_sta_pwrsave(struct ieee80211vap *, int);
 void ieee80211_parent_queue_xmit(struct sk_buff *);
+struct sk_buff * ieee80211_get_nulldata(struct ieee80211_node *ni);
 int ieee80211_send_nulldata(struct ieee80211_node *);
 int ieee80211_send_qosnulldata(struct ieee80211_node *, int);
 int ieee80211_send_qosnulldata_ext(struct ieee80211com *ic, uint8_t *mac, int pwr);
 void ieee80211_send_csa_frame(struct ieee80211vap *vap, u_int8_t csa_mode,
 	u_int8_t csa_chan, u_int8_t csa_count, u_int64_t tsf);
+void ieee80211_get_channel_bw_offset(struct ieee80211com *ic, int16_t *is_40, int16_t *offset);
 int ieee80211_send_mgmt(struct ieee80211_node *, int, int);
 void ieee80211_mgmt_output(struct ieee80211_node *ni, struct sk_buff *skb, int type,
 	const u_int8_t da[IEEE80211_ADDR_LEN]);
@@ -490,15 +493,16 @@
 	u_int8_t *bo_erp;		/* start of ERP element */
 	u_int8_t *bo_appie_buf;		/* start of APP IE buf */
 	u_int16_t bo_appie_buf_len;	/* APP IE buf length in bytes */
-	u_int16_t bo_chanswitch_trailerlen;
 };
 struct sk_buff *ieee80211_beacon_alloc(struct ieee80211_node *,
 	struct ieee80211_beacon_offsets *);
 int ieee80211_beacon_update(struct ieee80211_node *,
 	struct ieee80211_beacon_offsets *, struct sk_buff *, int);
+void ieee80211_beacon_update_all(struct ieee80211com *);
 
 /* XXX exposed due to of beacon code botch */
 u_int8_t *ieee80211_add_rates(u_int8_t *, const struct ieee80211_rateset *);
+u_int8_t *ieee80211_add_supported_chans(uint8_t *frm, struct ieee80211com *ic);
 u_int8_t *ieee80211_add_xrates(u_int8_t *, const struct ieee80211_rateset *);
 u_int8_t *ieee80211_add_bss_load(u_int8_t *, struct ieee80211vap *);
 u_int8_t *ieee80211_add_extcap(u_int8_t *);
@@ -524,8 +528,9 @@
 u_int8_t *ieee80211_add_htcap(struct ieee80211_node *, u_int8_t *, struct ieee80211_htcap *, int subtype);
 u_int8_t *ieee80211_add_htinfo(struct ieee80211_node *, u_int8_t *, struct ieee80211_htinfo *);
 
-u_int8_t *ieee80211_add_vhtcap(struct ieee80211_node *, u_int8_t *, struct ieee80211_vhtcap *);
+u_int8_t *ieee80211_add_vhtcap(struct ieee80211_node *, u_int8_t *, struct ieee80211_vhtcap *, uint8_t);
 u_int8_t *ieee80211_add_vhtop(struct ieee80211_node *, u_int8_t *, struct ieee80211_vhtop *);
+uint8_t *ieee80211_add_vhtop_notif(uint8_t *frm, struct ieee80211com *ic, int band_24g);
 
 /* MU MIMO */
 void
@@ -535,13 +540,20 @@
 				  uint8_t pos, uint8_t delete);
 struct ieee80211_node *ieee80211_find_node_by_aid(struct ieee80211com *ic, uint8_t aid);
 
+u_int8_t * ieee80211_add_20_40_bss_coex_ie(u_int8_t *frm, u_int8_t coex);
+void ieee80211_get_20_40_bss_into_chan_list(struct ieee80211com *ic, struct ieee80211vap *vap,
+					u_int16_t *pp_ch_list);
+u_int8_t * ieee80211_add_20_40_bss_into_ch_rep(u_int8_t *frm,
+	struct ieee80211com *ic, u_int16_t ch_list);
+u_int8_t * ieee80211_add_obss_scan_ie(u_int8_t *frm, struct ieee80211_obss_scan_ie *obss_ie);
 u_int8_t *ieee80211_add_qtn_extender_role_ie(uint8_t *frm, uint8_t role);
 u_int8_t *ieee80211_add_qtn_extender_bssid_ie(struct ieee80211vap *vap, uint8_t *frm);
+u_int8_t *ieee80211_add_qtn_extender_state_ie(uint8_t *frm, uint8_t ocac);
 int ieee80211_extender_send_event(struct ieee80211vap *vap,
 	const struct qtn_wds_ext_event_data *p_wds_event_data, uint8_t *ie);
-struct ieee80211_extender_wds_info *ieee80211_extender_find_peer_wds_info(struct ieee80211vap *,
-	uint8_t *);
-int ieee80211_extender_remove_peer_wds_info(struct ieee80211vap *vap, uint8_t *mac_addr);
+struct ieee80211_extender_wds_info *ieee80211_extender_find_peer_wds_info(struct ieee80211com *ic,
+	uint8_t *mac_addr);
+int ieee80211_extender_remove_peer_wds_info(struct ieee80211com *ic, uint8_t *mac_addr);
 void ieee80211_extender_notify_ext_role(struct ieee80211_node *ni);
 void ieee80211_extender_sta_update_info(struct ieee80211_node *ni,
 		const struct ieee80211_qtn_ext_role *ie_role,
diff --git a/include/kernel/net80211/ieee80211_scan.h b/include/kernel/net80211/ieee80211_scan.h
index d06729d..a66d477 100644
--- a/include/kernel/net80211/ieee80211_scan.h
+++ b/include/kernel/net80211/ieee80211_scan.h
@@ -49,17 +49,28 @@
 	void *ss_priv;				/* scanner private state */
 	void *ss_scs_priv;			/* scs private state independent of the scan state */
 	u_int16_t ss_flags;
-#define	IEEE80211_SCAN_NOPICK	0x0001		/* scan only, no selection */
-#define	IEEE80211_SCAN_ACTIVE	0x0002		/* active scan (probe req) */
-#define	IEEE80211_SCAN_PICK1ST	0x0004		/* ``hey sailor'' mode */
-#define	IEEE80211_SCAN_BGSCAN	0x0008		/* bg scan, exit ps at end */
-#define	IEEE80211_SCAN_ONCE	0x0010		/* do one complete pass */
-#define	IEEE80211_SCAN_NO_DFS	0x0020		/* avoid DFS channels, AP only */
-#define IEEE80211_SCAN_DFS_ACTION	0x0040	/* scan end, do DFS action */
-#define	IEEE80211_SCAN_GOTPICK	0x1000		/* got candidate, can stop */
-#define IEEE80211_SCAN_QTN_BGSCAN	0x0080	/* quantenna background scanning required */
-#define IEEE80211_SCAN_OPCHAN	0x0100		/* quantenna scanning on operating channel only */
-#define IEEE80211_SCAN_QTN_SEARCH_MBS	0x0200	/* seach MBS, no action on scan end */
+#define	IEEE80211_SCAN_NOPICK			0x0001	/* scan only, no selection */
+#define	IEEE80211_SCAN_ACTIVE			0x0002	/* active scan (probe req) */
+#define	IEEE80211_SCAN_PICK1ST			0x0004	/* ``hey sailor'' mode */
+#define	IEEE80211_SCAN_BGSCAN			0x0008	/* bg scan, exit ps at end */
+#define	IEEE80211_SCAN_ONCE			0x0010	/* do one complete pass */
+#define	IEEE80211_SCAN_NO_DFS			0x0020	/* avoid DFS channels, AP only */
+#define IEEE80211_SCAN_DFS_ACTION		0x0040	/* scan end, do DFS action */
+#define IEEE80211_SCAN_QTN_BGSCAN		0x0080	/* quantenna background scanning required */
+#define IEEE80211_SCAN_OPCHAN			0x0100	/* quantenna scanning on operating channel only */
+#define IEEE80211_SCAN_QTN_SEARCH_MBS		0x0200	/* seach MBS, no action on scan end */
+#define IEEE80211_SCAN_OBSS			0x0400	/* OBSS scan */
+/* Note: top 4 bits for internal use only */
+#define	IEEE80211_SCAN_GOTPICK			0x1000	/* got candidate, can stop */
+
+/* Prefer selecting DFS only channels for bootup CAC*/
+#define IEEE80211_SCAN_PICK_NOT_AVAILABLE_DFS_ONLY		0x0011
+
+/* Select channel from DFS and non-DFS sets which are available only*/
+/* All Non-DFS channels are available by default,
+ * DFS channels are available only after CAC-Completion events
+ */
+#define IEEE80211_SCAN_PICK_AVAILABLE_ANY_CHANNEL		0x0012
 
 	u_int16_t ss_pick_flags;			/* pick a channel via a algorithm in a special domain */
 
@@ -105,7 +116,7 @@
 #define	STA_FAILS_MAX	2		/* assoc failures before ignored */
 #define	STA_FAILS_AGE	(2 * 60)	/* time before clearing fails (secs) */
 #define	STA_PURGE_SCANS	2		/* age for purging sta entries (scans) */
-#define	AP_PURGE_SCANS	2		/* age for purging ap entries (scans) */
+#define	AP_PURGE_SCANS	8		/* age for purging ap entries (scans) */
 
 #define RSSI_LPF_LEN	10
 #define	RSSI_EP_MULTIPLIER	(1<<7)	/* pow2 to optimize out * and / */
@@ -138,6 +149,7 @@
 int ieee80211_check_scan(struct ieee80211vap *, int, u_int, u_int,
 	const struct ieee80211_scan_ssid ssids[],
 	int (*action)(struct ieee80211vap *, const struct ieee80211_scan_entry *));
+int ieee80211_should_scan(struct ieee80211vap *vap);
 int ieee80211_bg_scan(struct ieee80211vap *);
 void ieee80211_cancel_scan(struct ieee80211vap *);
 void ieee80211_cancel_scan_no_wait(struct ieee80211vap *vap);
@@ -203,6 +215,7 @@
 	u_int8_t *vhtcap;
 	u_int8_t *vhtop;
 	u_int8_t *pwr_constraint;
+	u_int8_t *obss_scan;
 	int8_t	local_max_txpwr;
 	struct ieee80211_channel *rxchan;
 	uint8_t extender_role;
@@ -336,6 +349,7 @@
 
 struct ap_state {
 	unsigned int as_numbeacons[IEEE80211_CHAN_MAX];
+	uint8_t as_obss_chanlayout[IEEE80211_CHAN_MAX];
 
 	int as_maxrssi[IEEE80211_CHAN_MAX];
 	int as_cci[IEEE80211_CHAN_MAX];		/* CCI, Co-Channel Interference */
@@ -381,10 +395,14 @@
 	int32_t as_dfs_reentry_level;
 };
 
-void ieee8011_add_scan_entry(struct ieee80211_scan_entry *ise,
+void ieee80211_add_scan_entry(struct ieee80211_scan_entry *ise,
 			const struct ieee80211_scanparams *sp,
 			const struct ieee80211_frame *wh,
 			int subtype, int rssi, int rstamp);
+void ieee80211_scan_check_secondary_channel(struct ieee80211_scan_state *ss,
+			struct ieee80211_scan_entry *ise);
+struct ieee80211_channel *ieee80211_scan_switch_pri_chan(struct ieee80211_scan_state *ss,
+			struct ieee80211_channel *chan_pri);
 int ieee80211_wps_active(uint8_t *wsc_ie);
 void ieee80211_dump_scan_res(struct ieee80211_scan_state *ss);
 
diff --git a/include/kernel/net80211/ieee80211_tdls.h b/include/kernel/net80211/ieee80211_tdls.h
index bc153dc..907f669 100644
--- a/include/kernel/net80211/ieee80211_tdls.h
+++ b/include/kernel/net80211/ieee80211_tdls.h
@@ -119,8 +119,8 @@
 #define DEFAULT_TDLS_PATH_SEL_MODE		0
 #define DEFAULT_TDLS_PATH_SEL_PPS_THRSHLD	20
 #define DEFAULT_TDLS_PATH_SEL_RATE_THRSHLD	24
-#define DEFAULT_TDLS_RATE_DETECTION_PKT_CNT	16
-#define DEFAULT_TDLS_RATE_DETECTION_BURST_CNT	2
+#define DEFAULT_TDLS_RATE_DETECTION_PKT_CNT	1024
+#define DEFAULT_TDLS_RATE_DETECTION_BURST_CNT	4
 #define DEFAULT_TDLS_RATE_DETECTION_WAITING_T	12
 #define DEFAULT_TDLS_LINK_WEIGHT		5
 #define DEFAULT_TDLS_LINK_DISABLE_SCALE		2
@@ -137,7 +137,7 @@
 #define DEFAULT_TDLS_CH_SW_TX_TIME		1500
 #define	DEFAULT_TDLS_FIXED_OFF_CHAN		TDLS_INVALID_CHANNEL_NUM
 
-#define	DEFAULT_TDLS_UAPSD_INDICATION_WND	(2)
+#define	DEFAULT_TDLS_UAPSD_INDICATION_WND	(150)
 #define	DEFAULT_TDLS_SETUP_EXPIRE_DURATION	(20)
 
 const char *
@@ -156,6 +156,9 @@
 ieee80211_tdls_get_smoothed_rssi(struct ieee80211vap *vap, struct ieee80211_node *ni);
 
 int
+ieee80211_tdls_add_bridge_entry_for_peer(struct ieee80211_node *peer_ni);
+
+int
 ieee80211_tdls_disable_peer_link(struct ieee80211_node *ni);
 
 void
diff --git a/include/kernel/net80211/ieee80211_var.h b/include/kernel/net80211/ieee80211_var.h
index 1accce5..42b8745 100644
--- a/include/kernel/net80211/ieee80211_var.h
+++ b/include/kernel/net80211/ieee80211_var.h
@@ -71,6 +71,11 @@
 #define	IEEE80211_BGSCAN_IDLE_MIN	100	/* min idle time (ms) */
 #define	IEEE80211_BGSCAN_IDLE_DEFAULT	250	/* default idle time (ms) */
 
+#define IEEE80211_USE_QTN_BGSCAN(vap)	\
+	(((vap->iv_ic)->ic_flags_ext & IEEE80211_FEXT_REPEATER) &&	\
+	((vap)->iv_opmode == IEEE80211_M_STA) &&	\
+	((vap)->iv_ic->ic_bsschan != IEEE80211_CHAN_ANYC))
+
 #define IEEE80211_COVERAGE_CLASS_MAX	31	/* max coverage class */
 #define IEEE80211_REGCLASSIDS_MAX	10	/* max regclass id list */
 
@@ -99,11 +104,14 @@
 #define IEEE80211_USEC_TO_MS(x)		((x) / 1000)
 #define IEEE80211_MS_TO_JIFFIES(x)	((x) * HZ / 1000)
 
-#define IEEE80211_SCS_PICK_DFS_ONLY		0x1
-#define IEEE80211_SCS_PICK_NON_DFS_ONLY		0x2
-#define IEEE80211_SCS_PICK_ANYWAY		0x4
+#define IEEE80211_SCS_PICK_DFS_ONLY			0x1/* Pick channels from DFS set only*/
+#define IEEE80211_SCS_PICK_NON_DFS_ONLY			0x2/* Pick channels from Non-DFS set only*/
+#define IEEE80211_SCS_PICK_AVAILABLE_ANY_CHANNEL	0x4/* Pick channels from DFS and Non-DFS sets*/
+#define IEEE80211_SCS_PICK_ANYWAY			0x8/* Omit channel margins during channel pick*/
+#define IEEE80211_SCS_PICK_NOT_AVAILABLE_DFS_ONLY	0x10
 
-#define IEEE80211_RX_AGG_TIMEOUT_DEFAULT						 (IEEE80211_USEC_TO_MS(QTN_RX_REORDER_BUF_TIMEOUT_US))
+
+#define IEEE80211_RX_AGG_TIMEOUT_DEFAULT	(IEEE80211_USEC_TO_MS(QTN_RX_REORDER_BUF_TIMEOUT_US))
 
 #define IEEE80211_MAX_AMPDU_SUBFRAMES			(64)
 #define IEEE80211_TX_BA_REQUEST_RETRY_TIMEOUT		(5 * HZ)
@@ -135,6 +143,8 @@
 #define	MAX(_a, _b)	((_a)>(_b)?(_a):(_b))
 #define ABS(_x)		(((_x) > 0) ? (_x) : (0 - (_x)))
 
+#define IS_MULTIPLE_BITS_SET(_x)	(((unsigned)(_x)) & (((unsigned)(_x)) - 1))
+
 /* For Little-endian */
 #define ntohll(x)  be64_to_cpu(x)
 #define htonll(x)  cpu_to_be64(x)
@@ -159,6 +169,7 @@
 #define	IEEE80211_EXTENDER_DEFAULT_RBS_WGT		6
 #define IEEE80211_EXTENDER_DEFAULT_MBS_BEST_RSSI	20
 #define	IEEE80211_EXTENDER_DEFAULT_RBS_BEST_RSSI	20
+#define IEEE80211_EXTENDER_DEFAULT_MBS_RSSI_MARGIN	6
 
 #define IEEE80211_EXTWDS_MAX_PSEUDO_RSSI		70
 #define IEEE80211_EXTWDS_MIN_PSEUDO_RSSI		0
@@ -209,6 +220,7 @@
 	uint8_t s_addr[IEEE80211_ADDR_LEN];	/* Sender address */
 	uint8_t r_addr[IEEE80211_ADDR_LEN];	/* Receiver address */
 	uint16_t tx_time;	/* Tx time - us */
+	uint16_t is_latest;	/* latest statistics data flag */
 } __packed;
 
 struct ieee80211_tdls_scs_entry {
@@ -238,6 +250,8 @@
 	uint32_t		scs_cca_intf_hi_thrshld;
 	uint32_t		scs_cca_intf_lo_thrshld;
 	uint32_t		scs_cca_intf_ratio;
+	uint32_t		scs_cca_intf_dfs_margin;
+	uint32_t		scs_pmbl_err_thrshld;
 	uint32_t		scs_cca_sample_dur;
 #define SCS_CCA_INTF_SMTH_FCTR_NOXP		0
 #define SCS_CCA_INTF_SMTH_FCTR_XPED		1
@@ -248,8 +262,10 @@
 #define SCS_RSSI_SMTH_FCTR_NUM			2
 	uint8_t			scs_rssi_smth_fctr[SCS_RSSI_SMTH_FCTR_NUM];
 	uint8_t			scs_chan_mtrc_mrgn;
+	uint8_t			scs_leavedfs_chan_mtrc_mrgn;/* DFS-to-Non-DFS channel switch margin */
 	int8_t			scs_atten_adjust;
 	uint32_t		scs_cnt[IEEE80211_SCS_CNT_MAX];
+	uint16_t		scs_atten_sw_enable;
 	int16_t			scs_last_smpl_chan;	/* index into the channel array */
 	struct brcm_rxglitch_thrshld_pair *scs_brcm_rxglitch_thrshlds;
 	uint32_t		scs_brcm_rxglitch_thrshlds_scale;
@@ -270,6 +286,8 @@
 	uint16_t		scs_pmp_stats_clear_interval;
 	uint16_t		scs_as_rx_time_smth_fctr;
 	uint16_t		scs_as_tx_time_smth_fctr;
+	uint16_t		scs_cca_idle_smthed;
+	uint16_t		scs_cca_idle_smth_fctr;
 
 	ATH_LIST_HEAD(, ieee80211_tdls_scs_entry) scs_tdls_list[IEEE80211_NODE_HASHSIZE];
 	spinlock_t		scs_tdls_lock;
@@ -282,10 +300,12 @@
 #define IEEE80211_SCS_MEASURE_INIT_TIMER	3
 #define IEEE80211_SCS_MEASURE_TIMER_INTVAL	5
 #define IEEE80211_MAX_STA_CCA_ENABLED		2
-#define IEEE80211_CCA_IDLE_THRSHLD		50
-#define IEEE80211_CCA_INTFR_HIGH_THRSHLD	30
+#define IEEE80211_CCA_IDLE_THRSHLD		40
+#define IEEE80211_CCA_INTFR_HIGH_THRSHLD	50
 #define IEEE80211_CCA_INTFR_LOW_THRSHLD		30
 #define IEEE80211_CCA_INTFR_RATIO		20
+#define IEEE80211_CCA_INTFR_DFS_MARGIN		0
+#define IEEE80211_PMBL_ERR_THRSHLD		300
 
 #define SCS_NODE_TRAFFIC_IDLE        0
 #define SCS_NODE_TRAFFIC_LOADED      1
@@ -305,7 +325,8 @@
 	uint32_t		set_bcn_intval;
 	uint32_t		restore_bcn_intval;
 	uint32_t		pm_update;
-	uint32_t		mbssid_enabled;
+	uint32_t		unsupported_mbssid;
+	uint32_t		beacon_scheme0;
 	uint32_t		wds_exist;
 	uint32_t		set_run;
 	uint32_t		set_pend;
@@ -334,14 +355,16 @@
 
 struct ieee80211_ocac_params {
 	uint16_t		traffic_ctrl;	/* use qosnull frame to control the traffic */
-	uint16_t		dwell_time_ms;	/* milliseconds, the time on off channel
-							within 1 beacon interval */
 	uint16_t		secure_dwell_ms;	/* milliseconds, the time on off channel
 								within one off-channel action, using qosnull
 								with large NAV to protect the traffic */
+	uint16_t		dwell_time_ms;	/* milliseconds, the time on off channel
+							within 1 beacon interval */
 	uint16_t		duration_secs;	/* seconds, the total time for one channel */
 	uint16_t		cac_time_secs;	/* seconds, the total time on off channel
 							for one channel */
+	uint16_t		wea_dwell_time_ms;	/* milliseconds, the time on weather channel
+							within 1 beacon interval */
 	uint32_t		wea_duration_secs;	/* seconds, the total time for weather channel */
 	uint32_t		wea_cac_time_secs;	/* seconds, the total time on off channel
 							for weather channel */
@@ -395,9 +418,6 @@
 #define IEEE80211_SET_CHANNEL_DEFERRED_CANCEL	0x80000000
 #define IEEE80211_SET_CHANNEL_TSF_OFFSET	0x40000000
 
-#define IEEE80211_QTN_BGSCAN_DWELLTIME_ACTIVE	15 /* milliseconds */
-#define IEEE80211_QTN_BGSCAN_DWELLTIME_PASSIVE	15 /* milliseconds */
-
 enum ieee80211_scan_frame_flags {
 	IEEE80211_SCAN_FRAME_START = 0,
 	IEEE80211_SCAN_FRAME_PRBREQ = 1,
@@ -408,6 +428,12 @@
 struct qtn_bgscan_param	{
 	u_int16_t	dwell_msecs_active;
 	u_int16_t	dwell_msecs_passive;
+	u_int16_t	duration_msecs_active;
+	u_int16_t	duration_msecs_passive_fast;
+	u_int16_t	duration_msecs_passive_normal;
+	u_int16_t	duration_msecs_passive_slow;
+	u_int16_t	thrshld_fat_passive_fast;
+	u_int16_t	thrshld_fat_passive_normal;
 	u_int16_t	debug_flags;
 };
 
@@ -499,6 +525,80 @@
 	uint32_t times[IEEE80211_CHAN_MAX];	/* number of times channel was used */
 };
 
+#define DM_TXPOWER_FACTOR_MAX	8
+#define DM_TXPOWER_FACTOR_MIN	0
+#define DM_ACI_FACTOR_MAX	0
+#define DM_ACI_FACTOR_MIN	-4
+#define DM_CCI_FACTOR_MAX	0
+#define DM_CCI_FACTOR_MIN	-4
+#define DM_DFS_FACTOR_MAX	32
+#define DM_DFS_FACTOR_MIN	0
+#define DM_BEACON_FACTOR_MAX	0
+#define DM_BEACON_FACTOR_MIN	-4
+
+#define DM_FLAG_TXPOWER_FACTOR_PRESENT	0x1
+#define DM_FLAG_ACI_FACTOR_PRESENT	0x2
+#define DM_FLAG_CCI_FACTOR_PRESENT	0x4
+#define DM_FLAG_DFS_FACTOR_PRESENT	0x8
+#define DM_FLAG_BEACON_FACTOR_PRESENT	0x10
+
+struct ieee80211_dm_factor {
+	uint32_t flags;
+	int txpower_factor;
+	int aci_factor;
+	int cci_factor;
+	int dfs_factor;
+	int beacon_factor;
+};
+
+#if defined(QBMPS_ENABLE)
+
+#define BMPS_MODE_OFF		0
+#define BMPS_MODE_MANUAL	1
+#define BMPS_MODE_AUTO		2
+
+#define	BMPS_TPUT_THRESHOLD_UPPER	8000	/* 8 mbps */
+#define	BMPS_TPUT_THRESHOLD_LOWER	4000	/* 4 mbps */
+#define BMPS_TPUT_MEASURE_PERIOD_MS	5000	/* 5 seconds */
+
+struct bmps_tput_measure {
+	struct timer_list tput_timer;		/* STA BMPS timer for TX/RX */
+						/* tput measurement */
+	uint32_t prev_tx_bytes;			/* # of TX bytes in previous measurement */
+	uint32_t prev_rx_bytes;			/* # of RX bytes in previous measurement */
+	uint32_t tput_kbps;			/* TX & RX overall throughput in kbps */
+};
+#endif
+
+/*
+ * Operating class table for regulatory region to operating class conversion.
+ */
+struct operating_class_table {
+	uint8_t index;
+	uint8_t global_index;
+	uint8_t bandwidth;
+	uint8_t chan_set[IEEE80211_CHAN_BYTES];
+	uint16_t behavior;
+};
+
+struct region_to_oper_class {
+	const char *region_name;
+	uint8_t class_num_5g;
+	uint8_t classes_5g[IEEE80211_OPER_CLASS_BYTES];
+	uint8_t class_num_24g;
+	uint8_t classes_24g[IEEE80211_OPER_CLASS_BYTES_24G];
+	const struct operating_class_table * const class_table;
+};
+
+/*
+ * Logical SSID group used for defining association limits per group of VAPs.
+ */
+struct ssid_logical_group {
+	u_int16_t limit;
+	u_int16_t reserve;
+	u_int16_t assocs;
+};
+
 struct ieee80211com {
 	/* MATS FIX The member ic_dev is not used in QDRV and should be removed */
 	struct net_device *ic_dev;		/* associated device */
@@ -524,8 +624,10 @@
 	u_int32_t ic_flags_ext;			/* extension of state flags */
 	u_int32_t ic_flags_qtn;			/* Quantenna specific flags */
 	u_int32_t ic_caps;			/* capabilities */
-	u_int8_t ic_ht_nss_cap;			/* HT Max spatial streams */
-	enum ieee80211_vht_nss ic_vht_nss_cap;	/* VHT Max spatial streams */
+	enum ieee80211_vht_mcs_supported ic_vht_mcs_cap;	/* VHT MCS capability */
+	enum ieee80211_ht_nss ic_ht_nss_cap;	/* Current HT Max spatial streams */
+	enum ieee80211_vht_nss ic_vht_nss_cap;	/* Current VHT Max spatial streams */
+	enum ieee80211_vht_nss ic_vht_nss_cap_24g;	/* Current 2.4G VHT Max spatial streams*/
 	u_int8_t ic_ath_cap;			/* Atheros adv. capabilities */
 	u_int8_t ic_promisc;			/* vap's needing promisc mode */
 	u_int8_t ic_allmulti;			/* vap's needing all multicast*/
@@ -565,7 +667,11 @@
 
 	int ic_txbf_period;
 
-	/* 11ac capabilities */
+	/* 2.4G band vht capabilities */
+	struct ieee80211_vhtcap ic_vhtcap_24g;
+	struct ieee80211_vhtop  ic_vhtop_24g;
+
+	/* 5G band capabilities */
 	struct ieee80211_vhtcap ic_vhtcap;
 	struct ieee80211_vhtop	ic_vhtop;
 
@@ -593,6 +699,8 @@
 	uint8_t ic_dyn_wmm;		/* Dynamic WMM enabled */
 	uint8_t ic_emi_power_switch_enable;
 	uint8_t ic_dfs_channels_deactive; /* Deactive all DFS channels */
+	uint16_t ic_vht_opmode_notif;	/* Override OpMode Notification IE, for WFA Testbed */
+	uint8_t ic_beaconing_scheme;
 
 	/*
 	 * Channel state:
@@ -623,14 +731,33 @@
 	struct ieee80211_assoc_history ic_assoc_history;
 	u_int8_t ic_chan_avail[IEEE80211_CHAN_BYTES];
 	u_int8_t ic_chan_active[IEEE80211_CHAN_BYTES];
+
+	/* All DFS channels are marked with CAC_NOT_DONE by default */
+#define IEEE80211_CHANNEL_STATUS_NOT_AVAILABLE_CAC_NOT_DONE	(0x1)
+
+#define IEEE80211_CHANNEL_STATUS_NOT_AVAILABLE_RADAR_DETECTED	(0x2)
+
+	/* --> All Non-DFS channels are AVAILABLE by default
+	 * --> Any DFS Channel is set to AVAILABLE
+	 *	(i) only after CAC_DONE,
+	 *      (ii) and no radar was found
+	 */
+#define IEEE80211_CHANNEL_STATUS_AVAILABLE			(0x4)
+
+	u_int8_t ic_chan_availability_status[IEEE80211_CHAN_MAX+1];
+
 	u_int8_t ic_chan_pri_inactive[IEEE80211_CHAN_BYTES];	/* channel not used as primary */
+	u_int8_t ic_is_inactive_usercfg[IEEE80211_CHAN_BYTES];  /* 0x1-regulatory 0x2-user override */
+	u_int8_t ic_is_inactive_autochan_only[IEEE80211_CHAN_BYTES];
 	u_int8_t ic_chan_dfs_required[IEEE80211_CHAN_BYTES];	/* channel is DFS required */
 	u_int8_t ic_chan_weather_radar[IEEE80211_CHAN_BYTES];	/* weather radar channel */
+	u_int8_t ic_chan_disabled[IEEE80211_CHAN_BYTES];	/* channels are disabled */
 
 	u_int8_t ic_chan_active_20[IEEE80211_CHAN_BYTES];
 	u_int8_t ic_chan_active_40[IEEE80211_CHAN_BYTES];
 	u_int8_t ic_chan_active_80[IEEE80211_CHAN_BYTES];
 	u_int8_t ic_max_system_bw;
+	u_int8_t ic_bss_bw;			/* BSS channel width, in station mode only */
 
 	struct ieee80211_channel *ic_curchan;	/* current channel */
 	struct ieee80211_channel *ic_bsschan;	/* bss channel */
@@ -638,6 +765,9 @@
 	struct ieee80211_channel *ic_scanchan;	/* scanning channel */
 	int16_t ic_channoise;			/* current channel noise in dBm */
 	struct ieee80211_channel *ic_des_chan;	/* desired channel */
+	int ic_des_chan_after_init_cac;	/* Saved desired chan to switch after Initial CAC */
+	int ic_des_chan_after_init_scan;/* Saved desired chan to switch after Initial Scan */
+
 	int ic_chan_is_set;
 	u_int16_t ic_des_mode;			/* desired mode */
 	/* regulatory class ids */
@@ -672,6 +802,8 @@
 	u_int16_t ic_xr_sta_assoc;		/* XR stations associated */
 	u_int16_t ic_nonqtn_sta;		/* Non-Quantenna peers */
 
+	struct ssid_logical_group ic_ssid_grp[IEEE80211_MAX_BSS_GROUP]; /* VAPs logical group assocication limits */
+
 	/* dwell times for channel scanning */
 	u_int16_t ic_mindwell_active;
 	u_int16_t ic_mindwell_passive;
@@ -689,6 +821,7 @@
 	int ic_country_outdoor;
 	struct ieee80211_ie_country ic_country_ie; /* country info element */
 	uint8_t ic_oper_class[IEEE80211_OPER_CLASS_BYTES];	/* Supported operating class */
+	const struct region_to_oper_class *ic_oper_class_table;
 	/*
 	 *  current channel power constraint for Power Constraint IE.
 	 *
@@ -723,6 +856,11 @@
 	u_int8_t ic_ieee_alt_chan;		/* if not zero jump to this channel if radar is detected */
 	u_int32_t ic_non_occupancy_period;	/* radar non-occupancy period. */
 
+	/* boot time CAC*/
+	int32_t ic_max_boot_cac_duration;
+	unsigned long ic_boot_cac_end_jiffy;
+        struct timer_list icac_timer;
+
 	u_int8_t ic_mode_get_phy_stats;
 
 	u_int8_t ic_legacy_retry_limit;
@@ -734,11 +872,18 @@
 	u_int32_t ic_tx_max_ampdu_size;
 
 	u_int16_t ic_mu_debug_level;
+	u_int8_t  ic_mu_enable;
+
+	u_int8_t ic_rts_bw_dyn;
+	u_int8_t ic_cts_bw;
+	u_int8_t use_non_ht_duplicate_for_mu;
+	u_int8_t rx_bws_support_for_mu_ndpa;
 
 	/* virtual ap create/delete */
 	struct ieee80211vap *(*ic_vap_create)(struct ieee80211com *,
 		const char *, int, int, int, struct net_device *);
 	void (*ic_vap_delete)(struct ieee80211vap *);
+	uint8_t (*ic_get_vap_idx)(struct ieee80211vap *);
 	/* send/recv 802.11 management frame */
 	int (*ic_send_mgmt)(struct ieee80211_node *, int, int);
 	void (*ic_recv_mgmt)(struct ieee80211_node *, struct sk_buff *, int,
@@ -755,6 +900,7 @@
 	/* new station association callback/notification */
 	void (*ic_newassoc)(struct ieee80211_node *, int);
 	void (*ic_disassoc)(struct ieee80211_node *);
+	void (*ic_node_update)(struct ieee80211_node *);
 	/* node state management */
 	struct ieee80211_node *(*ic_node_alloc)(struct ieee80211_node_table *,
 		struct ieee80211vap *, const uint8_t *, uint8_t tmp_node);
@@ -779,17 +925,14 @@
 	void (*ic_set_channel)(struct ieee80211com *);
 	void (*ic_bridge_set_dest_addr)(struct sk_buff *skb, void *eh1);
 	void (*ic_get_tsf)(uint64_t *tsf);
-	int (*ic_scs_set_frame)(struct ieee80211com *ic, struct ieee80211_node *ni,
+	int (*ic_bmps_set_frame)(struct ieee80211com *ic, struct ieee80211_node *ni,
 				struct sk_buff *skb);
-	int (*ic_scs_release_frame)(struct ieee80211com *ic);
+	int (*ic_bmps_release_frame)(struct ieee80211com *ic);
 	void (*ic_scs_update_scan_stats)(struct ieee80211com *ic);
-	int (*ic_sample_channel)(struct ieee80211com *ic, struct ieee80211_channel *chan);
+	int (*ic_sample_channel)(struct ieee80211vap *vap, struct ieee80211_channel *chan);
 	int (*ic_bgscan_start)(struct ieee80211com *ic);
-	int (*ic_bgscan_set_frame)(struct ieee80211com *ic, struct ieee80211_node *ni,
-				   struct sk_buff *skb, int frm_flag);
-	int (*ic_bgscan_release_frame)(struct ieee80211com *ic, int frm_flag);
-	int (*ic_bgscan_channel)(struct ieee80211com *ic, struct ieee80211_channel *chan,
-				 int active_scan, int dwelltime);
+	int (*ic_bgscan_channel)(struct ieee80211vap *vap, struct ieee80211_channel *chan,
+				 int scan_mode, int dwelltime);
 	void (*ic_set_channel_deferred)(struct ieee80211com *, u_int64_t tsf, int flags);
 	int  (*ic_set_start_cca_measurement)(struct ieee80211com *ic,
 					     const struct ieee80211_channel *cca_channel,
@@ -828,8 +971,13 @@
 		const u_int8_t mac[IEEE80211_ADDR_LEN]);
 
 	/* L2 external filter */
+	int (*ic_set_l2_ext_filter)(struct ieee80211vap *, int);
+	int (*ic_set_l2_ext_filter_port)(struct ieee80211vap *, int);
+	int (*ic_get_l2_ext_filter_port)(void);
 	void (*ic_send_to_l2_ext_filter)(struct ieee80211vap *, struct sk_buff *);
 
+	int (*ic_mac_reserved)(const uint8_t *addr);
+
 	/* Stats support */
 	void (*ic_get_wlanstats)(struct ieee80211com *, struct iw_statistics *);
 	/* Change of the MIMO power save mode for the STA */
@@ -842,6 +990,26 @@
 	struct ieee80211_channel *(*ic_select_channel)(u_int8_t new_ieee);
 	/* DFS action when channel scan is done*/
 	void (*ic_dfs_action_scan_done)(void);
+	/* Check if current region belongs to EU region */
+	bool (*ic_dfs_is_eu_region)(void);
+
+
+	void (*ic_mark_channel_availability_status)(struct ieee80211com *ic, struct ieee80211_channel *chan, uint8_t usable);
+	void (*ic_mark_channel_dfs_cac_status)(struct ieee80211com *ic, struct ieee80211_channel *chan, u_int32_t cac_flag, bool set);
+	void (*ic_dump_available_channels)(struct ieee80211com *ic, const char *offending_func);
+
+	void (*ic_ap_next_cac)(struct ieee80211com *ic, struct ieee80211vap *vap,
+			unsigned long cac_period,
+			struct ieee80211_channel **qdrv_radar_cb_cac_chan,
+			u_int32_t flags);
+
+	bool (*ic_dfs_chans_available_for_cac)(struct ieee80211com *ic, struct ieee80211_channel *ch);
+	int  (*ic_get_init_cac_duration)(struct ieee80211com *ic);
+	void (*ic_set_init_cac_duration)(struct ieee80211com *ic, int val);
+	void (*ic_start_icac_procedure)(struct ieee80211com *ic);
+	void (*ic_stop_icac_procedure)(struct ieee80211com *ic);
+
+
 	/* DFS select channel */
 	void (*ic_dfs_select_channel)(int channel);
 	void (*ic_wmm_params_update)(struct ieee80211vap *);
@@ -885,6 +1053,7 @@
 	void (*ic_set_radar)(int enable);
 	void (*ic_enable_sta_dfs)(int enable);
 	int (*ic_radar_detections_num)(uint32_t chan);
+	void (*ic_complete_cac)(void);
 	int (*ic_config_channel_list)(struct ieee80211com *ic, int ic_nchans);
 	void (*ic_set_11g_erp)(struct ieee80211vap *vap, int on);
 #ifdef CONFIG_QVSP
@@ -935,6 +1104,9 @@
 	int ic_pm_state[QTN_PM_IOCTL_MAX];
 	struct timer_list ic_pm_period_change;	/* CoC period change timer */
 
+#if defined(QBMPS_ENABLE)
+	struct bmps_tput_measure ic_bmps_tput_check;	/* for BMPS tput measurement */
+#endif
 	/* hold the calling task until the scan completes */
 	wait_queue_head_t	ic_scan_comp;
 
@@ -953,14 +1125,15 @@
 	/* measurement request */
 	struct ieee80211_global_measure_info ic_measure_info;
 
-#ifdef TOPAZ_PLATFORM
 	int (*ic_get_shared_vap_stats)(struct ieee80211vap *vap);
 	int (*ic_reset_shared_vap_stats)(struct ieee80211vap *vap);
 	int (*ic_get_shared_node_stats)(struct ieee80211_node *ni);
 	int (*ic_reset_shared_node_stats)(struct ieee80211_node *ni);
-#endif
 	void (*ic_get_dscp2ac_map)(const uint8_t vapid, uint8_t *dscp2ac);
 	void (*ic_set_dscp2ac_map)(const uint8_t vapid, uint8_t *ip_dscp, uint8_t listlen, uint8_t ac);
+	void (*ic_set_dscp2tid_map)(const uint8_t vapid, const uint8_t *dscp2tid);
+	void (*ic_get_dscp2tid_map)(const uint8_t vapid, uint8_t *dscp2tid);
+
 	struct timer_list	ic_ba_setup_detect;	/*timer for detecting whether it is suitable to enable/disable AMPDU*/
 
 	int (*ic_get_cca_adjusting_status)(void);
@@ -972,7 +1145,9 @@
 	uint8_t ic_extender_mbs_best_rssi;	/* MBS best RSSI threshold */
 	uint8_t ic_extender_rbs_best_rssi;	/* MBS best RSSI threshold */
 	uint8_t ic_extender_verbose;	/* EXTENDER Debug Level */
+	uint8_t ic_extender_mbs_rssi_margin;	/* MBS RSSI margin, used in link down detection only */
 	uint8_t ic_extender_mbs_bssid[IEEE80211_ADDR_LEN];
+	uint8_t ic_extender_mbs_ocac;
 	uint8_t ic_extender_rbs_num;
 	uint8_t ic_extender_rbs_bssid[QTN_MAX_RBS_NUM][IEEE80211_ADDR_LEN];
 	unsigned long ic_extender_mbs_detected_jiffies;
@@ -981,18 +1156,33 @@
 	struct timer_list ic_extender_scan_timer;	/* timer used by RBS to search MBS */
 	uint32_t ic_scan_opchan_enable;
 	uint32_t ic_extender_bgscanintvl;
+	uint8_t  ic_extender_rbs_bw;		/* recorded bandwidth of RBS */
 	uint32_t ic_tqew_descr_limit;		/* tqew desc limit */
 
 	uint32_t ic_scan_tbl_len_max;
 
 	int ic_scan_results_check;
 	struct timer_list ic_scan_results_expire; /* scan results expire timer */
+	int hostap_wpa_state;
+
 	/* VHT related callbacks */
 	void (*ic_send_vht_grp_id_act)(struct ieee80211vap *vap, struct ieee80211_node *ni);
 	void (*ic_node_mu_grp_update)(struct ieee80211_node *ni, uint8_t grp,
 				      uint8_t pos, uint8_t delete);
 	void (*ic_mu_grp_qmat_update)(struct ieee80211_node *ni, uint8_t grp_id,
 					int delete, int feedback);
+	struct timer_list ic_obss_timer;
+	uint8_t ic_obss_scan_enable;
+	uint8_t ic_obss_scan_count;
+	struct ieee80211_obss_scan_ie ic_obss_ie;
+	void (*ic_coex_stats_update)(struct ieee80211com *ic, uint32_t value);
+	struct ieee80211_dm_factor ic_dm_factor;
+	uint32_t ic_vap_default_state;	/* 1 - enabled, 0 - disabled*/
+
+	/* tx airtime callbacks */
+	uint32_t (*ic_tx_airtime)(const struct ieee80211_node *ni);
+	uint32_t (*ic_tx_accum_airtime)(const struct ieee80211_node *ni);
+	void     (*ic_tx_airtime_control)(struct ieee80211vap *vap, uint32_t value);
 };
 
 static __inline__ uint32_t ieee80211_pm_period_tu(const struct ieee80211com *ic)
@@ -1015,7 +1205,7 @@
         u_int8_t mac[IW_MAX_SPY * IEEE80211_ADDR_LEN];
         u_int32_t ts_rssi[IW_MAX_SPY];   /* ts of rssi value from last read */
         u_int8_t thr_low;	/* 1 byte rssi value, 0 = threshold is off */
-        u_int8_t thr_high;	/* 1 byte rssi value */   
+        u_int8_t thr_high;	/* 1 byte rssi value */
         u_int8_t num;
 };
 
@@ -1061,6 +1251,11 @@
 	PPQ_FAIL_MAX,
 };
 
+enum coex_bw_switch{
+	WLAN_COEX_STATS_BW_ACTION,
+	WLAN_COEX_STATS_BW_ASSOC,
+	WLAN_COEX_STATS_BW_SCAN,
+};
 struct ieee80211_pairing_pending_entry {
 	struct ieee80211_pairing_pending_entry *next;
 
@@ -1137,6 +1332,28 @@
 	uint8_t hessid[IEEE80211_ADDR_LEN];     /* homogeneous essid */
 };
 
+/*
+ * Station profile specific to dual band mode.
+ * Each band will maintain profile to be referred while band change.
+ * Station profile is initialized while bootup from user configurations.
+ */
+struct ieee80211_sta_profile {
+        int phy_mode;
+        int vht;
+        int bw;
+        int vsp;
+        int scs;
+        int pmf;
+};
+
+struct bcast_pps_info {
+	u_int16_t	max_bcast_pps;		/* Max broadcast packets allowed per second */
+	u_int16_t	rx_bcast_counter;	/* Counter to record no. of broadcast packets processed in wireless ingress path */
+	unsigned long	rx_bcast_pps_start_time;/* Timestamp in jiffies referred to, to reset the rx_bcast_counter */
+	u_int16_t	tx_bcast_counter;	/* Counter to record no. of broadcast packets processed in EMAC/PCIe ingress path */
+	unsigned long	tx_bcast_pps_start_time;/* Timestamp in jiffies referred to, to reset the tx_bcast_counter */
+};
+
 #define IEEE80211_RX_AMSDU_THRESHOLD_CCA	500
 #define IEEE80211_RX_AMSDU_THRESHOLD_PMBL	1000
 #define IEEE80211_RX_AMSDU_PMBL_WF_SP		10
@@ -1152,6 +1369,9 @@
 	struct proc_dir_entry *iv_proc;
 	struct ieee80211_proc_entry *iv_proc_entries;
 	struct vlan_group *iv_vlgrp;		/* vlan group state */
+        struct ieee80211_sta_profile    iv_2_4ghz_prof;	/* 2.4ghz station profile */
+        struct ieee80211_sta_profile    iv_5ghz_prof;	/* 5ghz station profile */
+	enum ieee80211_pref_band        iv_pref_band;   /* preferred band in dual band mode */
 
 	TAILQ_ENTRY(ieee80211vap) iv_next;	/* list of vap instances */
 	u_int iv_unit;				/* virtual AP unit */
@@ -1293,6 +1513,10 @@
 	u_int16_t iv_swbmiss_warnings;
 	int		  iv_bcn_miss_thr;			/* Beacon miss threshold */
 	u_int8_t  iv_link_loss_enabled;		/* Link loss - Controlled by user. By default is on */
+#if defined(QBMPS_ENABLE)
+	u_int8_t  iv_swbmiss_bmps_warning;	/* swbmiss warning for STA power-saving */
+	int8_t  iv_bmps_tput_high;		/* tput indication for STA power-saving */
+#endif
 
 	u_int8_t  iv_qtn_ap_cap;			    /* Quantenna flags from bcn/probe resp (station only) */
 	u_int8_t  iv_qtn_flags;					/* Quantenna capability flags */
@@ -1305,21 +1529,13 @@
 	struct ieee80211_nsparams iv_nsparams;	/* new state parameters for tasklet for stajoin1 */
 	struct IEEE80211_TQ_STRUCT iv_stajoin1tq; /* tasklet for newstate action called from stajoin1tq */
 	uint16_t iv_vapnode_idx;		/* node_idx to use for tx of non specifically targetted frames */
-#define MIN_PRIORITY_PER_VAP 0
-#define MAX_PRIORITY_PER_VAP 8
-	uint8_t iv_ssid_pri;			/* Priority assigned for per SSID */
+	uint8_t iv_ssid_group;			/* Logical group assigned for SSID, used for BSS association limits */
 	struct timer_list iv_sta_fast_rejoin;
 	uint8_t iv_sta_fast_rejoin_bssid[IEEE80211_ADDR_LEN];
 	uint8_t wds_mac[IEEE80211_ADDR_LEN];
 	struct ieee80211_key iv_wds_peer_key;
 
-#define IEEE80211_QTN_WDS_ONLY		0x0	/* 0 = Plain WDS; No WDS Extender */
-#define	IEEE80211_QTN_WDS_MASK		0x0003
-
-#define	IEEE80211_QTN_WDS_MBS		0x0001	/* 1 = MBS-Master Base Station */
-#define	IEEE80211_QTN_WDS_RBS		0x0002	/* 2 = RBS-Repeater/Remote Base Station */
-
-	uint16_t		iv_wds_flags;
+	uint16_t		iv_extdr_flags;
 
 	struct ieee80211_spy iv_spy;            /* IWSPY support */
 	unsigned int		iv_nsdone;	/* Done with scheduled newstate tasklet */
@@ -1338,7 +1554,7 @@
 	u_int8_t		iv_dual_cts_required;	/* HT dual CTS protection is required */
 	u_int8_t		iv_lsig_txop_ok;	/* is lsig in TXOP ok */
 	u_int8_t		iv_stbc_beacon;		/* is current beacon a stbc beacon */
-	u_int16_t		iv_smps_force;          /* The overridden value for SMPS for the STA. */
+	u_int16_t		iv_smps_force;		/* The overridden value for SMPS for the STA. */
 	u_int8_t		iv_implicit_ba;		/* Implicit block ack flags for the VAP. */
 	u_int16_t		iv_ba_control;		/* Block ack control - zero indicates accept no BAs,
 							   bit in position 'n' indicates accept and send BA for the given TID */
@@ -1347,8 +1563,12 @@
 	u_int16_t		iv_max_ba_win_size;	/* Maximum window size allowable */
 	u_int32_t		iv_rate_training_count; /* Rate training to new STAs - number of bursts */
 	u_int32_t		iv_rate_training_burst_count; /* Rate training to new STAs - packets per burst */
-	u_int8_t		iv_mc_legacy_rate;      /* Multicast legacy rates */
-	u_int8_t		iv_forward_unknown_mc;  /* Forward packets even if we have no bridge entry for them */
+	u_int8_t		iv_mc_legacy_rate;	/* Multicast legacy rates */
+	u_int8_t		iv_forward_unknown_mc;	/* Forward packets even if we have no bridge entry for them */
+	u_int8_t		iv_mc_to_uc;		/* Forward mcast/bcast as unicast */
+#define	IEEE80211_QTN_MC_TO_UC_LEGACY	0
+#define	IEEE80211_QTN_MC_TO_UC_NEVER	1
+#define	IEEE80211_QTN_MC_TO_UC_ALWAYS	2		/* For WFA testing only */
 	u_int8_t		iv_reliable_bcst;
 	u_int8_t		iv_ap_fwd_lncb;
 #if defined(CONFIG_QTN_80211K_SUPPORT)
@@ -1360,10 +1580,8 @@
 
 	struct timer_list	iv_test_traffic;	/* timer to start xr */
 	u_int32_t		iv_test_traffic_period;		/* Interval of periodically sending NULL packet to all associated STAs. 0 means disable */
-#ifdef TOPAZ_PLATFORM
 	uint32_t iv_11ac_enabled;	/* Enable/disable 11AC feature on Topaz */
 	uint8_t	iv_pri;			/* vap priority, used to calculate priority for per node per tid queue */
-#endif
 	uint8_t iv_pmf;                 /* VAP PMF/802.11w capability options */
 	u_int8_t		iv_local_max_txpow;	/* local max transmit power, equal to regulatory max power minus power constraint */
 	u_int16_t iv_disassoc_reason;
@@ -1380,9 +1598,28 @@
 	uint8_t			hs20_enable;		/* Enable/Disable HS2.0 */
 	uint8_t			disable_dgaf;		/* Disable Downstream Group-Addressed Forwarding - used by HS2.0 */
 	uint8_t			proxy_arp;		/* 1 - Enabled,  0- Disabled */
+	uint8_t			iv_coex;
+	uint8_t			allow_tkip_for_vht;	/* 1 - TKIP is allowed, 0 - TKIP is not allowed */
+	uint8_t			is_block_all_assoc;	/* 1 - block, 0 - unblock */
+	uint8_t			tx_ba_disable;		/* 1 - TXBA disable, 0 - TXBA permitted */
+	uint8_t			rx_ba_decline;		/* 1 - RXBA decline, 0 - RXBA permitted */
+	uint8_t			iv_vap_state;		/* 1 - enabled, 0 - disabled */
+	uint8_t			iv_osen;		/* 1/0 - OSEN enabled/disabled */
+
+	uint8_t			sample_sta_count;
+	spinlock_t		sample_sta_lock;
+	struct list_head	sample_sta_list;
+	struct bcast_pps_info	bcast_pps;
 };
 MALLOC_DECLARE(M_80211_VAP);
 
+#define IEEE80211_BAND_IDX_MAX	7
+struct ieee80211_band_info {
+	uint8_t		band_chan_step;			/* step to next channel */
+	uint8_t		band_first_chan;		/* first channel in the band */
+	int16_t		band_chan_cnt;			/* channels in the band */
+};
+
 /*
  * Note: A node table lock must be acquired or IRQ disabled to maintain atomic
  * when calling this function, and must not be released until a node ref is taken
@@ -1472,7 +1709,7 @@
 #define IEEE80211_FEXT_SWBMISS 0x00000400	/* CONF: use software beacon timer */
 #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800      /* CONF: drop unencrypted eapol frames */
 #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000	/* STATE: beacon APP IE updated */
-#define IEEE80211_FEXT_FAST_CC		0x00002000	/* CONF: Fast channel change */
+#define IEEE80211_FEXT_11N_PROTECT	0x00002000	/* Enable 11n protection */
 #define IEEE80211_FEXT_AMPDU		0x00004000	/* CONF: A-MPDU supported */
 #define IEEE80211_FEXT_AMSDU		0x00008000	/* CONF: A-MSDU supported */
 #define IEEE80211_FEXT_USEHT20		0x00010000	/* use HT20 channel in 20/40 mode*/
@@ -1490,6 +1727,8 @@
 #define	IEEE80211_FEXT_AP_TDLS_PROHIB	0x08000000	/* AP prohibit TDLS function */
 #define IEEE80211_FEXT_SPECIFIC_SCAN	0x10000000	/* Just perform specific SSID scan */
 #define IEEE80211_FEXT_SCAN_40		0x20000000	/* Temporarily use 40MHz channel when changing channel */
+#define IEEE80211_FEXT_24GVHT		0x40000000	/* VHT support(256-QAM) on 2.4G band  */
+#define IEEE80211_FEXT_BG_PROTECT	0x80000000	/* 802.11bg protect */
 
 #define IEEE80211_FEXT_TDLS_DISABLED	(IEEE80211_FEXT_AP_TDLS_PROHIB | IEEE80211_FEXT_TDLS_PROHIB)
 
@@ -1499,7 +1738,18 @@
 #define IEEE80211_QTN_PRINT_CH_INUSE	0x00000004	/* Enable printing of channels in Use. */
 #define IEEE80211_QTN_BGSCAN		0x00000008	/* Quantenna background scanning */
 #define IEEE80211_QTN_MONITOR		0x00000010	/* Quantenna sniffer mode */
+#define IEEE80211_QTN_BMPS		0x00000020	/* Quantenna STA BMPS (power-saving) mode */
+#define IEEE80211_QTN_SAMP_CHAN		0x00000040	/* Quantenna SCS sample channel */
 
+static inline int
+ieee80211_is_repeater(struct ieee80211com *ic)
+{
+
+	if (!(ic->ic_flags_ext & IEEE80211_FEXT_REPEATER))
+		return 0;
+
+	return 1;
+}
 
 #define IEEE80211_COM_UAPSD_ENABLE(_ic)		((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
 #define IEEE80211_COM_UAPSD_DISABLE(_ic)	((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
@@ -1512,6 +1762,9 @@
 #define IEEE80211_COM_WDS_IS_RBS(_ic)		((_ic)->ic_extender_role == IEEE80211_EXTENDER_ROLE_RBS)
 #define IEEE80211_COM_WDS_IS_MBS(_ic)		((_ic)->ic_extender_role == IEEE80211_EXTENDER_ROLE_MBS)
 
+#define IEEE80211_BG_PROTECT_ENABLED(_ic)	((_ic)->ic_flags_ext & IEEE80211_FEXT_BG_PROTECT)
+#define IEEE80211_11N_PROTECT_ENABLED(_ic)	((_ic)->ic_flags_ext & IEEE80211_FEXT_11N_PROTECT)
+
 #define IEEE80211_VAP_UAPSD_ENABLE(_v)	((_v)->iv_flags_ext |= IEEE80211_FEXT_UAPSD)
 #define IEEE80211_VAP_UAPSD_DISABLE(_v)	((_v)->iv_flags_ext &= ~IEEE80211_FEXT_UAPSD)
 #define IEEE80211_VAP_UAPSD_ENABLED(_v)	((_v)->iv_flags_ext & IEEE80211_FEXT_UAPSD)
@@ -1527,18 +1780,41 @@
 
 #define IEEE80211_VAP_WDS_ANY(_v)	((_v)->iv_opmode == IEEE80211_M_WDS)
 #define IEEE80211_VAP_WDS_IS_RBS(_v)	(((_v)->iv_opmode == IEEE80211_M_WDS) && \
-					(((_v)->iv_wds_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_RBS))
+					(((_v)->iv_extdr_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_RBS))
 #define IEEE80211_VAP_WDS_IS_MBS(_v)	(((_v)->iv_opmode == IEEE80211_M_WDS) && \
-					(((_v)->iv_wds_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_MBS))
+					(((_v)->iv_extdr_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_MBS))
 #define IEEE80211_VAP_WDS_BASIC(_v)   (((_v)->iv_opmode == IEEE80211_M_WDS) && \
-					(((_v)->iv_wds_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_ONLY))
+					(((_v)->iv_extdr_flags & IEEE80211_QTN_WDS_MASK) == IEEE80211_QTN_WDS_ONLY))
 
-#define	IEEE80211_VAP_WDS_SET_RBS(_v)	do {(_v)->iv_wds_flags &= ~IEEE80211_QTN_WDS_MASK; \
-					     (_v)->iv_wds_flags |= IEEE80211_QTN_WDS_RBS ;} while(0)
-#define	IEEE80211_VAP_WDS_SET_MBS(_v)	do {(_v)->iv_wds_flags &= ~IEEE80211_QTN_WDS_MASK; \
-					     (_v)->iv_wds_flags |= IEEE80211_QTN_WDS_MBS;} while(0)
-#define IEEE80211_VAP_WDS_SET_NONE(_v)	do {(_v)->iv_wds_flags &= ~IEEE80211_QTN_WDS_MASK; \
-					     (_v)->iv_wds_flags |= IEEE80211_QTN_WDS_ONLY;} while(0)
+static __inline__ uint16_t ieee80211_extdr_get_flags(uint32_t comb)
+{
+	return (comb & IEEE80211_QTN_EXTDR_ALLMASK);
+}
+
+static __inline__ uint16_t ieee80211_extdr_get_mask(uint32_t comb)
+{
+	return ((comb >> IEEE80211_QTN_EXTDR_MASK_SHIFT) & IEEE80211_QTN_EXTDR_ALLMASK);
+}
+
+static inline void
+ieee80211_vap_set_extdr_flags(struct ieee80211vap *vap, uint32_t etdr_comb)
+{
+	int flags;
+	int mask;
+
+	flags = ieee80211_extdr_get_flags(etdr_comb);
+	mask = ieee80211_extdr_get_mask(etdr_comb);
+
+	vap->iv_extdr_flags &= ~mask;
+	vap->iv_extdr_flags |= flags;
+}
+
+#define	IEEE80211_VAP_WDS_SET_RBS(_v)	do {(_v)->iv_extdr_flags &= ~IEEE80211_QTN_WDS_MASK; \
+					     (_v)->iv_extdr_flags |= IEEE80211_QTN_WDS_RBS ;} while(0)
+#define	IEEE80211_VAP_WDS_SET_MBS(_v)	do {(_v)->iv_extdr_flags &= ~IEEE80211_QTN_WDS_MASK; \
+					     (_v)->iv_extdr_flags |= IEEE80211_QTN_WDS_MBS;} while(0)
+#define IEEE80211_VAP_WDS_SET_NONE(_v)	do {(_v)->iv_extdr_flags &= ~IEEE80211_QTN_WDS_MASK; \
+					     (_v)->iv_extdr_flags |= IEEE80211_QTN_WDS_ONLY;} while(0)
 
 /* ic_caps */
 #define	IEEE80211_C_WEP		0x00000001	/* CAPABILITY: WEP available */
@@ -1635,8 +1911,6 @@
 int ieee80211_vap_attach(struct ieee80211vap *, ifm_change_cb_t, ifm_stat_cb_t);
 void ieee80211_vap_detach(struct ieee80211vap *);
 void ieee80211_vap_detach_late(struct ieee80211vap *);
-void ieee80211_mark_dfs(struct ieee80211com *, struct ieee80211_channel *);
-void ieee80211_dfs_test_return(struct ieee80211com *, u_int8_t);
 void ieee80211_announce(struct ieee80211com *);
 void ieee80211_announce_channels(struct ieee80211com *);
 int ieee80211_media_change(void *);
@@ -1645,7 +1919,7 @@
 int ieee80211_media2rate(int);
 int ieee80211_mcs2media(struct ieee80211com*, int, enum ieee80211_phymode);
 int ieee80211_media2mcs(int);
-int ieee80211_mcs2rate(int mcs, int mode, int sgi);
+int ieee80211_mcs2rate(int mcs, int mode, int sgi, int vht);
 int ieee80211_rate2mcs(int rate, int mode, int sgi);
 u_int ieee80211_get_chanflags(enum ieee80211_phymode mode);
 u_int ieee80211_mhz2ieee(u_int, u_int);
@@ -1658,6 +1932,8 @@
 int ieee80211_country_string_to_countryid( const char *input_str, u_int16_t *p_iso_code );
 int ieee80211_countryid_to_country_string( const u_int16_t iso_code, char *output_str );
 int ieee80211_region_to_operating_class(struct ieee80211com *ic, char *region_str);
+void ieee80211_get_prichan_list_by_operating_class(struct ieee80211com *ic, int bw,
+			uint8_t *chan_list, uint32_t flag);
 int ieee80211_get_current_operating_class(uint16_t iso_code, int chan, int bw);
 void ieee80211_build_countryie(struct ieee80211com *);
 int ieee80211_media_setup(struct ieee80211com *, struct ifmedia *, u_int32_t,
@@ -1693,28 +1969,46 @@
 void ieee80211_scs_show_ranking_stats(struct ieee80211com *ic, int show_input, int show_result);
 void ieee80211_show_initial_ranking_stats(struct ieee80211com *ic);
 void ieee80211_scs_update_ranking_table_by_scan(struct ieee80211com *ic);
+int ieee80211_dual_sec_chan_supported(struct ieee80211vap *vap, int chan);
+void ieee80211_update_sec_chan_offset(struct ieee80211_channel *chan, int offset);
 int ieee80211_get_bw(struct ieee80211com *ic);
+int ieee80211_get_cap_bw(struct ieee80211com *ic);
+int ieee80211_get_max_ap_bw(const struct ieee80211_scan_entry *se);
+int ieee80211_get_max_node_bw(struct ieee80211_node *ni);
+int ieee80211_get_max_system_bw(struct ieee80211com *ic);
+int ieee80211_get_max_channel_bw(struct ieee80211com *ic, int channel);
+int ieee80211_get_max_bw(struct ieee80211vap *vap, struct ieee80211_node *ni, uint32_t chan);
 int ieee80211_get_mu_grp(struct ieee80211com *ic,
 	struct qtn_mu_grp_args *mu_grp_tbl);
 int ieee80211_find_sec_chan(struct ieee80211_channel *chan);
 int ieee80211_find_sec40u_chan(struct ieee80211_channel *chan);
 int ieee80211_find_sec40l_chan(struct ieee80211_channel *chan);
+int ieee80211_find_sec_chan_by_operating_class(struct ieee80211com *ic, int chan, uint32_t preference);
 
 int ieee80211_rst_dev_stats(struct ieee80211vap *vap);
 
 int ieee80211_swfeat_is_supported(uint16_t feat, uint8_t print_msg);
 
+void ieee80211_finish_csa(unsigned long arg);
 int ieee80211_enter_csa(struct ieee80211com *ic, struct ieee80211_channel *chan,
 		void (*finish_csa)(unsigned long arg), uint8_t reason,
 		uint8_t csa_count, uint8_t csa_mode, uint32_t flag);
-void ieee80211_finish_csa(unsigned long arg);
-
-int ieee80211_scs_pick_channel(struct ieee80211com *ic, int pick_flags);
+void ieee80211_obss_scan_timer(unsigned long arg);
+void ieee80211_start_obss_scan_timer(struct ieee80211vap *vap);
+int ieee80211_scs_pick_channel(struct ieee80211com *ic, int pick_flags, uint32_t cc_flag);
 void ieee80211_parse_cipher_key(struct ieee80211vap *vap, void *ie, uint16_t len);
 
 int ieee80211_vap_wds_mode_change(struct ieee80211vap *vap);
 char *ieee80211_wireless_get_hw_desc(void);
+struct ieee80211_channel *ieee80211_find_channel_by_ieee(struct ieee80211com *ic, int chan_ieee);
+void ieee80211_add_sec_chan_off(u_int8_t **frm, struct ieee80211com *ic, u_int8_t csa_chan);
+uint8_t ieee80211_wband_chanswitch_ie_len(uint32_t bw);
+uint8_t ieee80211_sec_chan_off_ie_len(void);
 
+void ieee80211_find_ht_pri_sec_chan(struct ieee80211vap *vap,
+		struct ieee80211_scan_entry *se, uint8_t *pri_chan, uint8_t *sec_chan);
+int ieee80211_20_40_operation_permitted(struct ieee80211vap *vap,
+				uint8_t se_pri_chan, uint8_t se_sec_chan);
 /*
  * Key update synchronization methods.  XXX should not be visible.
  */
@@ -1808,6 +2102,7 @@
 #define	IEEE80211_MSG_VSP	0x00000008	/* VSP */
 #define IEEE80211_MSG_VHT	0x00000004	/* 11ac mode debug-VHT*/
 #define	IEEE80211_MSG_TDLS	0x00000002	/* TDLS */
+#define	IEEE80211_MSG_EXTDR	0x00000001	/* Extender: QHOP or Repeater */
 
 #define	IEEE80211_MSG_ANY	0xffffffff	/* anything */
 
@@ -1905,9 +2200,19 @@
 #ifdef CONFIG_QHOP
 /* Some prototypes QHOP implementation */
 extern int  ieee80211_scs_is_wds_rbs_node(struct ieee80211com *ic);
-extern void ieee80211_qhop_send_csa(struct ieee80211vap *vap, uint8_t new_chan);
+extern void ieee80211_dfs_send_csa(struct ieee80211vap *vap, uint8_t new_chan);
 #endif
 
+struct ieee80211_band_info *ieee80211_get_band_info(int band_idx);
+
+#if defined(QBMPS_ENABLE)
+extern int ieee80211_wireless_set_sta_bmps(struct ieee80211vap *vap, struct ieee80211com *ic, int value);
+extern int ieee80211_sta_bmps_update(struct ieee80211vap *vap);
+#endif
+
+extern int ieee80211_is_idle_state(struct ieee80211com *ic);
+extern int ieee80211_is_on_weather_channel(struct ieee80211com *ic, struct ieee80211_channel *chan);
+
 extern uint8_t g_l2_ext_filter;
 extern uint8_t g_l2_ext_filter_port;
 #endif /* _NET80211_IEEE80211_VAR_H_ */
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 3d870fd..fab522c 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -126,7 +126,7 @@
 extern gro_result_t
 vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
 	       unsigned int vlan_tci);
-
+extern int vlan_check_vlan_exist(struct net_device *dev, u16 vlan_id);
 #else
 static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
 {
@@ -165,6 +165,12 @@
 {
 	return GRO_DROP;
 }
+
+static inline int
+vlan_check_vlan_exist(struct net_device *dev, u16 vlan_id)
+{
+	return 0;
+}
 #endif
 
 /**
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 987e111..12b2516 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -231,7 +231,8 @@
 	PHY_FORCING,
 	PHY_CHANGELINK,
 	PHY_HALTED,
-	PHY_RESUMING
+	PHY_RESUMING,
+	PHY_QTNPM
 };
 
 /* phy_device: An instance of a PHY
diff --git a/include/linux/pm_qos_params.h b/include/linux/pm_qos_params.h
index a317e8a..312c27f 100644
--- a/include/linux/pm_qos_params.h
+++ b/include/linux/pm_qos_params.h
@@ -11,8 +11,9 @@
 #define PM_QOS_NETWORK_LATENCY 2
 #define PM_QOS_NETWORK_THROUGHPUT 3
 #define PM_QOS_POWER_SAVE 4
+#define PM_QOS_POWER_EMAC 5
 
-#define PM_QOS_NUM_CLASSES 5
+#define PM_QOS_NUM_CLASSES 6
 #define PM_QOS_DEFAULT_VALUE -1
 
 struct pm_qos_request_list;
@@ -31,3 +32,5 @@
 int pm_qos_requirement(int pm_qos_class);
 int pm_qos_add_requirement(int pm_qos_class, const char *name, s32 value);
 int pm_qos_update_requirement(int pm_qos_class, const char *name, s32 new_value);
+
+void pm_qos_refresh_notifiers(const int pm_qos_class);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 0915573..74ecbc5 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -394,6 +394,9 @@
 	__u8			is_recyclable:1,
 				cache_is_cleaned:1,
 				hbm_no_free:1;
+
+	__u8			ext_l2_filter:1;
+
 	kmemcheck_bitfield_end(flags1);
 	__be16			protocol;
 
diff --git a/include/linux/watch64.h b/include/linux/watch64.h
index fc63f8c..42ec9a4 100644
--- a/include/linux/watch64.h
+++ b/include/linux/watch64.h
@@ -65,6 +65,9 @@
 inline struct watch64* __watch64_find(unsigned long* ptr);
 int watch64_disable(unsigned long* ptr, struct watch64* st);
 inline int __watch64_disable(unsigned long* ptr, struct watch64* st);
+inline int __watch64_write(unsigned long* ptr, struct watch64* st, int enable_flag);
+int watch64_reset(unsigned long* ptr, struct watch64* st);
+inline int __watch64_reset(unsigned long* ptr, struct watch64* st);
 int watch64_enable(unsigned long* ptr, struct watch64* st);
 inline int __watch64_enable(unsigned long* ptr, struct watch64* st);
 int watch64_toggle(unsigned long* ptr, struct watch64* st);
diff --git a/include/qtn/auc_debug_stats.h b/include/qtn/auc_debug_stats.h
index 3bc1d3c..7323ddc 100755
--- a/include/qtn/auc_debug_stats.h
+++ b/include/qtn/auc_debug_stats.h
@@ -17,53 +17,25 @@
 {
 	/* pktlogger expects task_alive_counters to be the first member of this struct */
 	uint32_t task_alive_counters[AUC_TID_NUM];
-	uint32_t task_reschedule[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_tac_pri_preempt;
-	uint32_t tqew_tac_pri_mercy;
-	uint32_t tqew_airfair_state;
-	uint32_t tqew_air_qos;
-	uint32_t tqew_air_fairness;
-	uint32_t tqew_air_swap;
 	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_fsm_no_resource;
 	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_pop_global_buf_limit;
 	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_rx_delba;
-	uint32_t wmac_rx_bb_underflow;
-	uint32_t wmac_rx_bb_overflow;
-	uint32_t wmac_rx_ipc_clean;
-	uint32_t wmac_rx_ipc_replenish;
-	uint32_t wmac_rx_ipc_sreset_recover;
-	uint32_t wmac_rx_prepare;
-	uint32_t wmac_rx_reschedule;
-	uint32_t wmac_rx_hbm_tail_overrun;
-	uint32_t wmac_rxq_intr[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_fill[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_nobuf[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_stop[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_pkt[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_bad_status[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_pkt_oversize[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rxq_pkt_delivered[AUC_FW_WMAC_RX_QNUM];
-	uint32_t wmac_rx_data_last_seqfrag;
-	uint32_t wmac_rx_data_last_ip_id;
 	uint32_t wmac_tx_done[4];
 	uint32_t agg_aggregate_flag;
 	uint32_t agg_aggressive_agg;
@@ -138,6 +110,7 @@
 	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;
@@ -184,6 +157,7 @@
 	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;
 
@@ -207,10 +181,6 @@
 	uint32_t mu_tx_wmac_0_done_succ;
 	uint32_t mu_tx_wmac_0_done_fail;
 
-	uint32_t mu_tx_wmac_1_done_count;
-	uint32_t mu_tx_wmac_1_bitmap_non_zero;
-	uint32_t mu_tx_wmac_1_bitmap_zero;
-	uint32_t mu_tx_wmac_1_done_timeout;
 	uint32_t mu_tx_wmac_1_done_succ;
 	uint32_t mu_tx_wmac_1_done_fail;
 
diff --git a/include/qtn/dmautil.h b/include/qtn/dmautil.h
index d9692cc..26cceba 100644
--- a/include/qtn/dmautil.h
+++ b/include/qtn/dmautil.h
@@ -66,7 +66,7 @@
 }
 __always_inline static unsigned long align_buf_dma_offset(void *addr)
 {
-	return (align_buf_dma(addr) - addr);
+	return ((char *)align_buf_dma(addr) - (char *)addr);
 }
 __always_inline static void* align_buf_cache(void *addr)
 {
@@ -74,7 +74,7 @@
 }
 __always_inline static unsigned long align_buf_cache_offset(void *addr)
 {
-	return (addr - align_buf_cache(addr));
+	return ((char *)addr - (char *)align_buf_cache(addr));
 }
 __always_inline static unsigned long align_buf_cache_size(void *addr, unsigned long size)
 {
diff --git a/include/qtn/hardware_revision.h b/include/qtn/hardware_revision.h
index 66ceba5..d754fbd 100644
--- a/include/qtn/hardware_revision.h
+++ b/include/qtn/hardware_revision.h
@@ -37,6 +37,38 @@
 	}
 }
 
+#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/include/qtn/iputil.h b/include/qtn/iputil.h
index 041d18f..39ff354 100644
--- a/include/qtn/iputil.h
+++ b/include/qtn/iputil.h
@@ -60,7 +60,7 @@
 
 #define IPUTIL_V4_ADDR_SSDP		htonl(0xEFFFFFFA) /* 239.255.255.250 */
 #define IPUTIL_V4_ADDR_MULTICAST(_addr)	\
-	((_addr & htonl(0xFF000000)) == htonl(0xE0000000)) /* 224.0.0.0/4 */
+	((_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)	\
@@ -311,7 +311,7 @@
 }
 
 /* Multicast data traffic, with the most common types of non-streaming mc filtered out */
-static inline int iputil_is_mc_data(struct ether_header *eh, void *iph)
+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) &&
diff --git a/include/qtn/lhost_muc_comm.h b/include/qtn/lhost_muc_comm.h
index 2c1a6ff..1c147f6 100644
--- a/include/qtn/lhost_muc_comm.h
+++ b/include/qtn/lhost_muc_comm.h
@@ -155,6 +155,7 @@
 #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 */
@@ -306,7 +307,6 @@
 #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_UPDATE_DTLS_PRESENT   45      /* update wheather DTLS session deteced or not */
 #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 */
@@ -322,12 +322,17 @@
 #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_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
@@ -460,8 +465,7 @@
 	uint32_t meas_dur_ms;
 	union {
 		struct {
-			uint32_t cca_pri_cnt;
-			uint32_t cca_sec_cnt;
+			uint32_t cca_busy_cnt;
 			uint32_t cca_try_cnt;
 			uint32_t cca_try_ms;
 			uint32_t cca_busy_ms;
@@ -644,8 +648,13 @@
 #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	muc_status;		/* written only by MuC */
-#define QTN_SCAN_CHAN_FLAG_ACTIVE		0x1
+#define QTN_SCAN_CHAN_FLAG_ACTIVE		0x00000001
+#define QTN_SCNA_CHAN_FLAG_PASSIVE_FAST		0x00000002
+#define QTN_SCNA_CHAN_FLAG_PASSIVE_NORMAL	0x00000004
+#define QTN_SCNA_CHAN_FLAG_PASSIVE_SLOW		0x00000008
+#define QTN_SCAN_CHAN_TURNOFF_RF		0x00000010
 	uint32_t	scan_flags;
 	uint32_t	start_txdesc_host;	/* The frame sent before go scan channel,
 						 * e.g. pwrsav frame in STA mode */
@@ -696,12 +705,43 @@
 	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 *gain_entry_tbl;
 	uint8_t lna_on_indx;
 	uint8_t max_gain_idx;
-	uint16_t cs_threshold_value;
+	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 */
@@ -754,6 +794,31 @@
 #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",	         \
+}
+#else
 #define LHOST_CAL_FILES		{	\
 	NULL,				\
 	"/proc/bootcfg/bf_factor",	\
@@ -768,10 +833,11 @@
 	"/mnt/jffs2/profile_dcache_muc",\
 	"/mnt/jffs2/profile_iptr_muc",	\
 	"/proc/bootcfg/env",		\
-	"/etc/mtest",			\
+  "/etc/mtest",           \
 	"/proc/bootcfg/rx_iq.cal",	\
 	"/mnt/jffs2/profile_iptr_auc",	\
 }
+#endif
 
 #define MUC_CAL_FILES		{	\
 	NULL,				\
diff --git a/include/qtn/mproc_sync.h b/include/qtn/mproc_sync.h
index 291bfaf..5f1f9ae 100644
--- a/include/qtn/mproc_sync.h
+++ b/include/qtn/mproc_sync.h
@@ -109,56 +109,68 @@
 #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_sem_down(enum topaz_mproc_tqe_sem_id cpuid)
+_qtn_mproc_3way_tqe_sem_down(enum topaz_mproc_tqe_sem_id cpuid)
 {
 	uint32_t	sem_get_cnt = 0;
-	uint32_t	multi_proc_tqe_sem_reg;
-	uint32_t	multi_proc_tqe_sem_val;
+	uint32_t	value;
 
+	value = ((cpuid << QTN_MULTI_PROCESSOR_SEMA_KEY_SHIFT) | cpuid);
 	do {
-		multi_proc_tqe_sem_reg = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
-	} while (multi_proc_tqe_sem_reg && (sem_get_cnt++ < TQE_SEMA_GET_MAX));
+		/*
+		 * 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, value);
+		value = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
 
-	if (sem_get_cnt >= TQE_SEMA_GET_MAX) {
-		return 0;
-	} else {
-		multi_proc_tqe_sem_val = ((cpuid << 28) | cpuid);
-
-		do {
-			qtn_mproc_sync_mem_write(TOPAZ_MPROC_SEMA, multi_proc_tqe_sem_val);
-			multi_proc_tqe_sem_reg = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
-			multi_proc_tqe_sem_reg &= 0x0000000f;
-		} while ((multi_proc_tqe_sem_reg != cpuid) && (sem_get_cnt++ < TQE_SEMA_GET_MAX));
-
-		if (sem_get_cnt >= TQE_SEMA_GET_MAX) {
-			return 0;
-		} else {
+		if ((value & QTN_MULTI_PROCESS_TQE_SEMA) == cpuid)
 			return 1;
-		}
-	}
+		/*
+		 * Reading the semaphore returns a owner cpuid or zero in the field if is free.
+		 * Wait until no-one is holding the semaphore.
+		 */
+		do {
+			value = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
+			value &= QTN_MULTI_PROCESS_TQE_SEMA;
+		} while (value && (sem_get_cnt++ < TQE_SEMA_GET_MAX));
+
+	} while (sem_get_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_sem_up(enum topaz_mproc_tqe_sem_id cpuid)
+_qtn_mproc_3way_tqe_sem_up(enum topaz_mproc_tqe_sem_id cpuid)
 {
-	uint32_t	multi_proc_tqe_sem_reg;
-	uint32_t	multi_proc_tqe_sem_val;
+	uint32_t	value;
 
-	multi_proc_tqe_sem_reg = qtn_mproc_sync_mem_read(TOPAZ_MPROC_SEMA);
-	multi_proc_tqe_sem_reg &= 0x0000000f;
-	/* Anyway write current ID back to release HW semaphore */ 
-	multi_proc_tqe_sem_val = (multi_proc_tqe_sem_reg << 28) ;
-	qtn_mproc_sync_mem_write(TOPAZ_MPROC_SEMA, multi_proc_tqe_sem_val);
-
-	/* Return 1 mean success, Return 0 mean failure then pass to upper layer to do panic or halt */
-	if (multi_proc_tqe_sem_reg == cpuid) {
-		return 1;
-	} else {
+	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
@@ -687,8 +699,6 @@
 #endif
 }
 
-#ifdef TOPAZ_PLATFORM
-
 RUBY_INLINE void
 qtn_mproc_sync_irq_trigger(u_int32_t irq_reg, u_int32_t irqno)
 {
@@ -713,73 +723,6 @@
 	return qtn_mproc_sync_irq_ack_nolock(irq_reg, mask);
 }
 
-#else
-
-RUBY_WEAK(qtn_mproc_sync_irq_trigger) void
-qtn_mproc_sync_irq_trigger(u_int32_t irq_reg, u_int32_t irqno)
-{
-	unsigned long flags;
-	u_int32_t irq = (1 << irqno);
-	volatile u_int32_t *fixup_data = qtn_mproc_sync_irq_fixup_data_trigger(irq_reg);
-
-	local_irq_save(flags);
-
-	if (unlikely(fixup_data && ((fixup_data[0] & irq) != (fixup_data[1] & irq)))) {
-		/*
-		 * According to workaround interrupt is triggered already.
-		 *
-		 * Side which triggers interrupt flips bit of its own variable.
-		 * Side which acknowledge interrupt flips bit of its own variable.
-		 * So if side which triggers see that bits are different - it means
-		 * interrupt is already triggered and not yet acknowledged (e.g. masked).
-		 * In this case no need to trigger interrupt again - it can
-		 * be masked and it is impossible to distinguish from just reading registers
-		 * whether interrupt is acknowledged already or just keeping masked (in this case
-		 * triggering would mean acknowledging, interrupt losing).
-		 */
-	} else if (unlikely(qtn_mproc_sync_mem_read(irq_reg) & irq)) {
-		/* According to register state interrupt is triggered already */
-	} else {
-		qtn_mproc_sync_mem_write_wmb(irq_reg, irq);
-		if (likely(fixup_data != 0)) {
-			/* Record that interrupt triggered */
-			fixup_data[0] ^= irq;
-		}
-	}
-
-	local_irq_restore(flags);
-}
-
-RUBY_WEAK(qtn_mproc_sync_irq_ack_nolock) u_int32_t
-qtn_mproc_sync_irq_ack_nolock(u_int32_t irq_reg, u_int32_t mask)
-{
-	u_int32_t ret = qtn_mproc_sync_mem_read(irq_reg) & mask;
-	if (likely(ret)) {
-		volatile u_int32_t *fixup_data = qtn_mproc_sync_irq_fixup_data_ack(irq_reg);
-		qtn_mproc_sync_mem_write_wmb(irq_reg, ret);
-		if (likely(fixup_data != RUBY_BAD_VIRT_ADDR)) {
-			/* Record that interrupt acknowledged */
-			fixup_data[1] ^= ret;
-		}
-	}
-	return ret;
-}
-
-RUBY_INLINE u_int32_t
-qtn_mproc_sync_irq_ack(u_int32_t irq_reg, u_int32_t mask)
-{
-	unsigned long flags;
-	u_int32_t ret;
-
-	local_irq_save(flags);
-	ret = qtn_mproc_sync_irq_ack_nolock(irq_reg, mask);
-	local_irq_restore(flags);
-
-	return ret;
-}
-
-#endif // #ifdef TOPAZ_PLATFORM
-
 RUBY_INLINE u_int32_t
 qtn_mproc_sync_irq_ack_all(u_int32_t irq_reg)
 {
diff --git a/include/qtn/mproc_sync_base.h b/include/qtn/mproc_sync_base.h
index e194b78..3c5a5c9 100644
--- a/include/qtn/mproc_sync_base.h
+++ b/include/qtn/mproc_sync_base.h
@@ -65,9 +65,11 @@
 	extern int auc_os_printf(const char *fmt, ...);
 	auc_os_printf("AuC: %s\n", msg);
 #elif defined(ARCSHELL)
-#else
+#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)
 }
 
diff --git a/include/qtn/muc_phy_stats.h b/include/qtn/muc_phy_stats.h
index eb2d203..396a796 100644
--- a/include/qtn/muc_phy_stats.h
+++ b/include/qtn/muc_phy_stats.h
@@ -20,7 +20,7 @@
 /**
  * \defgroup PHYSTATS PHY generated statistics
  */
-/* @{ */
+/** @{ */
 
 #define QTN_STATS_MCS_SGI	0x40000000
 #define QTN_STATS_MCS_BW40	0x80000000
@@ -70,6 +70,8 @@
 	uint32_t pkts_per_sec;
 	uint32_t avg_tx_phy_rate;
 	uint32_t acks;
+	uint32_t tx_airtime;
+	uint32_t tx_accum_airtime;
 };
 
 struct qtn_node_shared_stats_rx {
@@ -110,7 +112,11 @@
 	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;
+	uint32_t tim_set;
+	uint32_t dtim_set;
 	uint16_t beacon_interval;
 	TAILQ_ENTRY(qtn_node_shared_stats) next;
 };
@@ -269,7 +275,7 @@
 	u_int32_t rate;		/* this field must be last for stat_parser.pl */
 };
 
-/* @} */
+/** @} */
 
 struct qtn_stats {
 	u_int32_t tstamp;
diff --git a/include/qtn/muc_share_def.h b/include/qtn/muc_share_def.h
index a9a5e97..2b4c64d 100755
--- a/include/qtn/muc_share_def.h
+++ b/include/qtn/muc_share_def.h
@@ -11,9 +11,9 @@
 #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	8
-#define QTN_FW_WMAC_RX_QDEEP_CTRL	8
-#define QTN_FW_WMAC_RX_QDEEP_DATA	280
+#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)
 
diff --git a/include/qtn/muc_txrx_stats.h b/include/qtn/muc_txrx_stats.h
index 85de25c..e103114 100644
--- a/include/qtn/muc_txrx_stats.h
+++ b/include/qtn/muc_txrx_stats.h
@@ -27,7 +27,7 @@
 /**
  * \defgroup MUCSTATS MuC generated statistics
  */
-/* @{ */
+/** @{ */
 
 /**
  * \brief MuC transmit statistics
@@ -175,6 +175,8 @@
 	u_int32_t	txdone_mgmt;
 	u_int32_t	txdone_data;
 	u_int32_t	tx_pwr;
+	u_int32_t	bcn_scheme_power_save;
+	u_int32_t	bcn_scheme;
 
 	/**
 	 * This counter shows the number of multicast frames sent while a
@@ -236,27 +238,20 @@
 	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_qtn_hardstart;
-	uint32_t	mu_no_buddy;
-	uint32_t	mu_buddy_mgmt;
-	uint32_t	mu_buddy_mismatch;
-	uint32_t	mu_push_to_hw;
-	uint32_t	mu_to_su_hw;
-	uint32_t	mu_txdone_buddy;
-	uint32_t	mu_no_bar;
-	uint32_t	mu_bar_acquire;
-	uint32_t	mu_bar_release;
-	uint32_t	mu_wmac0_retry;
-	uint32_t	mu_wmac1_retry;
-	uint32_t	mu_reservetx_fail;
 	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;
@@ -295,6 +290,22 @@
 	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	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;
 };
 
 /**
@@ -314,7 +325,6 @@
 	 * This counter shows the number of descriptors pushed to the hardware
 	 * for receive buffers.
 	 */
-	u_int32_t	rxdesc_push_to_hw;
 	u_int32_t	rxdesc_get_from_queue;
 	u_int32_t	rxdesc_push_to_host;
 	u_int32_t	rxdesc_non_aggr_push_to_host;
@@ -804,6 +814,7 @@
 	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;
 
@@ -819,8 +830,11 @@
 	 * 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 {
@@ -830,22 +844,32 @@
 
 #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;
@@ -876,7 +900,7 @@
 /**
  * \addtogroup MUCSTATS
  */
-/* @{ */
+/** @{ */
 struct qtn_rate_stats_mcs_data {
 	uint16_t	mcs_rate;
 	uint16_t	rate_index;
@@ -919,6 +943,6 @@
 	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/include/qtn/qdrv_sch.h b/include/qtn/qdrv_sch.h
index 0b39c77..e761234 100644
--- a/include/qtn/qdrv_sch.h
+++ b/include/qtn/qdrv_sch.h
@@ -64,16 +64,12 @@
 #include "qdrv_sch_const.h"
 #include <qtn/iputil.h>
 #include <qtn/qtn_net_packet.h>
-#if defined(TOPAZ_PLATFORM)
 #include <qtn/topaz_tqe_cpuif.h>
 #include <qtn/topaz_vlan_cpuif.h>
 #include <common/topaz_emac.h>
 #include <asm/hardware.h>
-#endif
 #define ETHER_TYPE_UNKNOWN			0XFFFF
 #define IPTOS_PREC_SHIFT			5
-#define IEEE8021P_PRIORITY_NUM			8
-#define IP_DSCP_NUM				64
 
 #define IP_DSCP_SHIFT		2
 #define IP_DSCP(_pri)           (((_pri) & 0xFF) >> IP_DSCP_SHIFT)
@@ -94,7 +90,6 @@
 extern __sram_data uint8_t qdrv_sch_tos2ac[];
 extern __sram_data uint8_t qdrv_sch_dscp2dot1p[];
 extern __sram_data uint8_t qdrv_vap_vlan_max;
-#if defined(TOPAZ_PLATFORM)
 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];
 
@@ -119,7 +114,6 @@
 	return readl(IO_ADDRESS(vbase + reg));
 }
 
-#endif
 static inline struct Qdisc *qdrv_tx_sch_vap_get_qdisc(const struct net_device *dev)
 {
 	/* This assumes 1 tx netdev queue per vap */
@@ -285,7 +279,7 @@
 		    (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 *)(eh + 1) - sizeof(ether_type) + LLC_SNAPFRAMELEN;
+			return (void *)((char *)(eh + 1) - sizeof(ether_type) + LLC_SNAPFRAMELEN);
 		} else {
 			*ether_type = ETHER_TYPE_UNKNOWN;
 			return (void *)(eh + 1);
@@ -301,7 +295,6 @@
 	}
 }
 
-#if defined(TOPAZ_PLATFORM)
 static inline uint8_t qdrv_dscp2tid_default(const uint8_t dscp)
 {
 	const uint8_t tclass = dscp << IP_DSCP_SHIFT;
@@ -470,7 +463,6 @@
 
 	*tid = qdrv_sch_mask_gettid(*vlan_index, ip_dscp);
 }
-#endif/* TOPAZ_PLATFORM */
 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,
@@ -491,9 +483,12 @@
 void qdrv_sch_set_8021p_map(uint8_t ip_dscp, uint8_t dot1p_up);
 uint8_t qdrv_sch_get_8021p_map(uint8_t ip_dscp);
 
-int qdrv_sch_set_dscp2tid_map(const uint8_t vapid, uint8_t *ip_dscp, uint8_t listlen, uint8_t ac);
+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);
diff --git a/include/qtn/qtn_auc_stats_fields.h b/include/qtn/qtn_auc_stats_fields.h
index 4a457b2..2016fc5 100644
--- a/include/qtn/qtn_auc_stats_fields.h
+++ b/include/qtn/qtn_auc_stats_fields.h
@@ -1,299 +1,234 @@
 	{ 0xe5101248, "sleep" },
-	{ 0xe510127c, "jiffies" },
-	{ 0xe510333c, "IRQ_0" },
-	{ 0xe5103340, "IRQ_1" },
-	{ 0xe5103344, "IRQ_2" },
-	{ 0xe5103348, "IRQ_3" },
-	{ 0xe510334c, "IRQ_4" },
-	{ 0xe5103350, "IRQ_5" },
-	{ 0xe5103354, "IRQ_6" },
-	{ 0xe5103358, "IRQ_7" },
-	{ 0xe510335c, "IRQ_8" },
-	{ 0xe5103360, "IRQ_9" },
-	{ 0xe5103364, "IRQ_10" },
-	{ 0xe5103368, "IRQ_11" },
-	{ 0xe510336c, "IRQ_12" },
-	{ 0xe5103370, "IRQ_13" },
-	{ 0xe5103374, "IRQ_14" },
-	{ 0xe5103378, "IRQ_15" },
-	{ 0xe510337c, "IRQ_16" },
-	{ 0xe5103380, "IRQ_17" },
-	{ 0xe5103384, "IRQ_18" },
-	{ 0xe5103388, "IRQ_19" },
-	{ 0xe5103398,	"task_alive_counters[0]" },
-	{ 0xe510339c,	"task_alive_counters[1]" },
-	{ 0xe51033a0,	"task_alive_counters[2]" },
-	{ 0xe51033a4,	"task_alive_counters[3]" },
-	{ 0xe51033a8,	"task_alive_counters[4]" },
-	{ 0xe51033ac,	"task_alive_counters[5]" },
-	{ 0xe51033b0,	"task_alive_counters[6]" },
-	{ 0xe51033b4,	"task_alive_counters[7]" },
-	{ 0xe51033b8,	"task_alive_counters[8]" },
-	{ 0xe51033bc,	"task_alive_counters[9]" },
-	{ 0xe51033c0,	"task_alive_counters[10]" },
-	{ 0xe51033c4,	"task_alive_counters[11]" },
-	{ 0xe51033c8,	"task_alive_counters[12]" },
-	{ 0xe51033cc,	"task_alive_counters[13]" },
-	{ 0xe51033d0,	"task_alive_counters[14]" },
-	{ 0xe51033d4,	"task_alive_counters[15]" },
-	{ 0xe51033d8,	"task_alive_counters[16]" },
-	{ 0xe51033dc,	"task_alive_counters[17]" },
-	{ 0xe51033e0,	"task_alive_counters[18]" },
-	{ 0xe51033e4,	"task_alive_counters[19]" },
-	{ 0xe51033e8,	"task_reschedule[0]" },
-	{ 0xe51033ec,	"task_reschedule[1]" },
-	{ 0xe51033f0,	"task_reschedule[2]" },
-	{ 0xe51033f4,	"task_reschedule[3]" },
-	{ 0xe51033f8,	"task_reschedule[4]" },
-	{ 0xe51033fc,	"task_reschedule[5]" },
-	{ 0xe5103400,	"task_reschedule[6]" },
-	{ 0xe5103404,	"task_reschedule[7]" },
-	{ 0xe5103408,	"task_reschedule[8]" },
-	{ 0xe510340c,	"task_reschedule[9]" },
-	{ 0xe5103410,	"task_reschedule[10]" },
-	{ 0xe5103414,	"task_reschedule[11]" },
-	{ 0xe5103418,	"task_reschedule[12]" },
-	{ 0xe510341c,	"task_reschedule[13]" },
-	{ 0xe5103420,	"task_reschedule[14]" },
-	{ 0xe5103424,	"task_reschedule[15]" },
-	{ 0xe5103428,	"task_reschedule[16]" },
-	{ 0xe510342c,	"task_reschedule[17]" },
-	{ 0xe5103430,	"task_reschedule[18]" },
-	{ 0xe5103434,	"task_reschedule[19]" },
-	{ 0xe5103438,	"task_false_trigger[0]" },
-	{ 0xe510343c,	"task_false_trigger[1]" },
-	{ 0xe5103440,	"task_false_trigger[2]" },
-	{ 0xe5103444,	"task_false_trigger[3]" },
-	{ 0xe5103448,	"task_false_trigger[4]" },
-	{ 0xe510344c,	"task_false_trigger[5]" },
-	{ 0xe5103450,	"task_false_trigger[6]" },
-	{ 0xe5103454,	"task_false_trigger[7]" },
-	{ 0xe5103458,	"task_false_trigger[8]" },
-	{ 0xe510345c,	"task_false_trigger[9]" },
-	{ 0xe5103460,	"task_false_trigger[10]" },
-	{ 0xe5103464,	"task_false_trigger[11]" },
-	{ 0xe5103468,	"task_false_trigger[12]" },
-	{ 0xe510346c,	"task_false_trigger[13]" },
-	{ 0xe5103470,	"task_false_trigger[14]" },
-	{ 0xe5103474,	"task_false_trigger[15]" },
-	{ 0xe5103478,	"task_false_trigger[16]" },
-	{ 0xe510347c,	"task_false_trigger[17]" },
-	{ 0xe5103480,	"task_false_trigger[18]" },
-	{ 0xe5103484,	"task_false_trigger[19]" },
-	{ 0xe5103488,	"tqew_ac[0]" },
-	{ 0xe510348c,	"tqew_ac[1]" },
-	{ 0xe5103490,	"tqew_ac[2]" },
-	{ 0xe5103494,	"tqew_ac[3]" },
-	{ 0xe5103498,	"tqew_ac_avail[0]" },
-	{ 0xe510349c,	"tqew_ac_avail[1]" },
-	{ 0xe51034a0,	"tqew_ac_avail[2]" },
-	{ 0xe51034a4,	"tqew_ac_avail[3]" },
-	{ 0xe51034a8,	"tqew_tac_pri_preempt" },
-	{ 0xe51034ac,	"tqew_tac_pri_mercy" },
-	{ 0xe51034b0,	"tqew_airfair_state" },
-	{ 0xe51034b4,	"tqew_air_qos" },
-	{ 0xe51034b8,	"tqew_air_fairness" },
-	{ 0xe51034bc,	"tqew_air_swap" },
-	{ 0xe51034c0,	"tqew_air_humble" },
-	{ 0xe51034c4,	"tqew_air_suppress" },
-	{ 0xe51034c8,	"tqew_air_use_idletime" },
-	{ 0xe51034cc,	"tqew_air_dequeue_only" },
-	{ 0xe51034d0,	"tqew_fsm_no_resource" },
-	{ 0xe51034d4,	"tqew_pkt_pending_for_txdone" },
-	{ 0xe51034d8,	"tqew_descr_alloc_fail" },
-	{ 0xe51034dc,	"tqew_ring_alloc_fail" },
-	{ 0xe51034e0,	"tqew_pop_alloc_fail" },
-	{ 0xe51034e4,	"tqew_pop_sw_limit" },
-	{ 0xe51034e8,	"tqew_pop_empty" },
-	{ 0xe51034ec,	"tqew_pop_global_buf_limit" },
-	{ 0xe51034f0,	"tqew_available_set" },
-	{ 0xe51034f4,	"tqew_available_reset" },
-	{ 0xe51034f8,	"tqew_rx" },
-	{ 0xe51034fc,	"tqew_drop" },
-	{ 0xe5103500,	"tqew_free" },
-	{ 0xe5103504,	"tqew_buf_invalid" },
-	{ 0xe5103508,	"wmac_rx_delba" },
-	{ 0xe510350c,	"wmac_rx_bb_underflow" },
-	{ 0xe5103510,	"wmac_rx_bb_overflow" },
-	{ 0xe5103514,	"wmac_rx_ipc_clean" },
-	{ 0xe5103518,	"wmac_rx_ipc_replenish" },
-	{ 0xe510351c,	"wmac_rx_ipc_sreset_recover" },
-	{ 0xe5103520,	"wmac_rx_prepare" },
-	{ 0xe5103524,	"wmac_rx_reschedule" },
-	{ 0xe5103528,	"wmac_rx_hbm_tail_overrun" },
-	{ 0xe510352c,	"wmac_rxq_intr[0]" },
-	{ 0xe5103530,	"wmac_rxq_intr[1]" },
-	{ 0xe5103534,	"wmac_rxq_intr[2]" },
-	{ 0xe5103538,	"wmac_rxq_fill[0]" },
-	{ 0xe510353c,	"wmac_rxq_fill[1]" },
-	{ 0xe5103540,	"wmac_rxq_fill[2]" },
-	{ 0xe5103544,	"wmac_rxq_nobuf[0]" },
-	{ 0xe5103548,	"wmac_rxq_nobuf[1]" },
-	{ 0xe510354c,	"wmac_rxq_nobuf[2]" },
-	{ 0xe5103550,	"wmac_rxq_stop[0]" },
-	{ 0xe5103554,	"wmac_rxq_stop[1]" },
-	{ 0xe5103558,	"wmac_rxq_stop[2]" },
-	{ 0xe510355c,	"wmac_rxq_pkt[0]" },
-	{ 0xe5103560,	"wmac_rxq_pkt[1]" },
-	{ 0xe5103564,	"wmac_rxq_pkt[2]" },
-	{ 0xe5103568,	"wmac_rxq_bad_status[0]" },
-	{ 0xe510356c,	"wmac_rxq_bad_status[1]" },
-	{ 0xe5103570,	"wmac_rxq_bad_status[2]" },
-	{ 0xe5103574,	"wmac_rxq_pkt_oversize[0]" },
-	{ 0xe5103578,	"wmac_rxq_pkt_oversize[1]" },
-	{ 0xe510357c,	"wmac_rxq_pkt_oversize[2]" },
-	{ 0xe5103580,	"wmac_rxq_pkt_delivered[0]" },
-	{ 0xe5103584,	"wmac_rxq_pkt_delivered[1]" },
-	{ 0xe5103588,	"wmac_rxq_pkt_delivered[2]" },
-	{ 0xe510358c,	"wmac_rx_data_last_seqfrag" },
-	{ 0xe5103590,	"wmac_rx_data_last_ip_id" },
-	{ 0xe5103594,	"wmac_tx_done[0]" },
-	{ 0xe5103598,	"wmac_tx_done[1]" },
-	{ 0xe510359c,	"wmac_tx_done[2]" },
-	{ 0xe51035a0,	"wmac_tx_done[3]" },
-	{ 0xe51035a4,	"agg_aggregate_flag" },
-	{ 0xe51035a8,	"agg_aggressive_agg" },
-	{ 0xe51035ac,	"hdrs_available_recent_min" },
-	{ 0xe51035b0,	"agg_states[0]" },
-	{ 0xe51035b4,	"agg_states[1]" },
-	{ 0xe51035b8,	"agg_states[2]" },
-	{ 0xe51035bc,	"agg_states[3]" },
-	{ 0xe51035c0,	"agg_states[4]" },
-	{ 0xe51035c4,	"ethq_push" },
-	{ 0xe51035c8,	"ethq_pop" },
-	{ 0xe51035cc,	"agg_aggregate_mpdu" },
-	{ 0xe51035d0,	"agg_aggregate_msdu" },
-	{ 0xe51035d4,	"agg_singleton_mpdu" },
-	{ 0xe51035d8,	"agg_singleton_mgmt" },
-	{ 0xe51035dc,	"agg_singleton_ctl" },
-	{ 0xe51035e0,	"agg_singleton_probe" },
-	{ 0xe51035e4,	"agg_4K_amsdu" },
-	{ 0xe51035e8,	"agg_8K_amsdu" },
-	{ 0xe51035ec,	"agg_11K_amsdu" },
-	{ 0xe51035f0,	"tx_feedback_success" },
-	{ 0xe51035f4,	"tx_feedback_fail" },
-	{ 0xe51035f8,	"tx_done_status_success" },
-	{ 0xe51035fc,	"tx_done_status_timeout" },
-	{ 0xe5103600,	"tx_done_status_xretry" },
-	{ 0xe5103604,	"tx_done_status_timeout_xretry" },
-	{ 0xe5103608,	"tx_done_pkt_chain_reset" },
-	{ 0xe510360c,	"tx_done_pkt_chain_success" },
-	{ 0xe5103610,	"tx_done_pkt_chain_drop_tid_down" },
-	{ 0xe5103614,	"tx_done_pkt_chain_drop_xattempts" },
-	{ 0xe5103618,	"tx_done_singleton_finish" },
-	{ 0xe510361c,	"tx_done_singleton_swretry" },
-	{ 0xe5103620,	"tx_done_aggregate_finish" },
-	{ 0xe5103624,	"tx_done_aggregate_hwretry" },
-	{ 0xe5103628,	"tx_done_aggregate_swretry" },
-	{ 0xe510362c,	"tx_done_mpdu_swretry" },
-	{ 0xe5103630,	"tx_sample" },
-	{ 0xe5103634,	"tx_bw_sample" },
-	{ 0xe5103638,	"tx_swretry_lower_bw" },
-	{ 0xe510363c,	"tx_swretry_agg_exceed" },
-	{ 0xe5103640,	"tx_scale_base_20m" },
-	{ 0xe5103644,	"tx_scale_base_40m" },
-	{ 0xe5103648,	"tx_scale_base_80m" },
-	{ 0xe510364c,	"tx_scale_max" },
-	{ 0xe5103650,	"tx_scale_overstep" },
-	{ 0xe5103654,	"alloc_tqew_fast" },
-	{ 0xe5103658,	"free_tqew_fast" },
-	{ 0xe510365c,	"alloc_tqew_slow" },
-	{ 0xe5103660,	"free_tqew_slow" },
-	{ 0xe5103664,	"alloc_tqew_local" },
-	{ 0xe5103668,	"free_tqew_local" },
-	{ 0xe510366c,	"alloc_hdr_fast" },
-	{ 0xe5103670,	"free_hdr_fast" },
-	{ 0xe5103674,	"alloc_hdr_slow" },
-	{ 0xe5103678,	"free_hdr_slow" },
-	{ 0xe510367c,	"alloc_msdu_hdr_failed" },
-	{ 0xe5103680,	"alloc_mpdu_hdr_failed" },
-	{ 0xe5103684,	"alloc_tid_superfast" },
-	{ 0xe5103688,	"free_tid_superfast" },
-	{ 0xe510368c,	"alloc_tid_fast" },
-	{ 0xe5103690,	"free_tid_fast" },
-	{ 0xe5103694,	"alloc_tid_slow" },
-	{ 0xe5103698,	"free_tid_slow" },
-	{ 0xe510369c,	"alloc_node_rate_fast" },
-	{ 0xe51036a0,	"free_node_rate_fast" },
-	{ 0xe51036a4,	"alloc_node_rate_slow" },
-	{ 0xe51036a8,	"free_node_rate_slow" },
-	{ 0xe51036ac,	"alloc_node_superfast" },
-	{ 0xe51036b0,	"free_node_superfast" },
-	{ 0xe51036b4,	"alloc_node_fast" },
-	{ 0xe51036b8,	"free_node_fast" },
-	{ 0xe51036bc,	"alloc_fcs" },
-	{ 0xe51036c0,	"free_fcs" },
-	{ 0xe51036c4,	"alloc_mac_descr" },
-	{ 0xe51036c8,	"free_mac_descr" },
-	{ 0xe51036cc,	"tx_mac_push" },
-	{ 0xe51036d0,	"tx_mac_idle" },
-	{ 0xe51036d4,	"tx_mac_rts" },
-	{ 0xe51036d8,	"tx_vlan_drop" },
-	{ 0xe51036dc,	"tx_acm_drop" },
-	{ 0xe51036e0,	"tx_ps_drop" },
-	{ 0xe51036e4,	"ocs_tx_suspend" },
-	{ 0xe51036e8,	"ocs_tx_resume" },
-	{ 0xe51036ec,	"ocs_singleton_suspend" },
-	{ 0xe51036f0,	"ocs_ampdu_suspend" },
-	{ 0xe51036f4,	"ocs_frame_created" },
-	{ 0xe51036f8,	"pwr_mgmt_awake" },
-	{ 0xe51036fc,	"pwr_mgmt_sleep" },
-	{ 0xe5103700,	"pwr_mgmt_tx" },
-	{ 0xe5103704,	"pspoll_rx" },
-	{ 0xe5103708,	"dtim_q_push" },
-	{ 0xe510370c,	"dtim_q_pop" },
-	{ 0xe5103710,	"dtim_trigger" },
-	{ 0xe5103714,	"dtim_q_overflow" },
-	{ 0xe5103718,	"tx_restrict_dropped" },
-	{ 0xe510371c,	"tx_throt_dropped" },
-	{ 0xe5103720,	"tx_block_singleton" },
-	{ 0xe5103724,	"tx_force_unblock_tid" },
-	{ 0xe5103728,	"tx_ctl_pkt_hbm_alloc_fails" },
-	{ 0xe510372c,	"tx_ctl_pkt_alloc_descr_fails" },
-	{ 0xe5103730,	"tx_bar_alloc_ctl_pkt_fails" },
-	{ 0xe5103734,	"wmm_ps_tx" },
-	{ 0xe5103738,	"wmm_ps_tx_null_frames" },
-	{ 0xe510373c,	"wmm_ps_tx_more_data_frames" },
-	{ 0xe5103740,	"wmm_ps_tx_eosp_frames" },
-	{ 0xe5103744,	"mu_tx_su_count" },
-	{ 0xe5103748,	"mu_tx_send_mu_fail" },
-	{ 0xe510374c,	"mu_tx_push_count" },
-	{ 0xe5103750,	"mu_tx_done_count" },
-	{ 0xe5103754,	"mu_tx_done_succ" },
-	{ 0xe5103758,	"mu_tx_done_fail" },
-	{ 0xe510375c,	"mu_tx_sample" },
-	{ 0xe5103760,	"mu_bar_bitmap_non_zero" },
-	{ 0xe5103764,	"mu_bar_bitmap_zero" },
-	{ 0xe5103768,	"mu_mac_wmac1_ipc_push" },
-	{ 0xe510376c,	"mu_mac_wmac1_auc_push" },
-	{ 0xe5103770,	"mu_tx_swretry_agg_exceed" },
-	{ 0xe5103774,	"mu_tx_buddy_try" },
-	{ 0xe5103778,	"mu_tx_buddy_fail_wmac" },
-	{ 0xe510377c,	"mu_tx_buddy_fail_ptid" },
-	{ 0xe5103780,	"mu_tx_buddy_fail_rate" },
-	{ 0xe5103784,	"mu_tx_buddy_fail_create_agg" },
-	{ 0xe5103788,	"mu_tx_buddy_mu_only_timeout" },
-	{ 0xe510378c,	"mu_tx_another_q_push_succ" },
-	{ 0xe5103790,	"mu_tx_another_q_push_fail" },
-	{ 0xe5103794,	"mu_tx_buddy_multi_tid" },
-	{ 0xe5103798,	"mu_tx_wmac_0_done_count" },
-	{ 0xe510379c,	"mu_tx_wmac_0_bitmap_non_zero" },
-	{ 0xe51037a0,	"mu_tx_wmac_0_bitmap_zero" },
-	{ 0xe51037a4,	"mu_tx_wmac_0_done_timeout" },
-	{ 0xe51037a8,	"mu_tx_wmac_0_done_succ" },
-	{ 0xe51037ac,	"mu_tx_wmac_0_done_fail" },
-	{ 0xe51037b0,	"mu_tx_wmac_1_done_count" },
-	{ 0xe51037b4,	"mu_tx_wmac_1_bitmap_non_zero" },
-	{ 0xe51037b8,	"mu_tx_wmac_1_bitmap_zero" },
-	{ 0xe51037bc,	"mu_tx_wmac_1_done_timeout" },
-	{ 0xe51037c0,	"mu_tx_wmac_1_done_succ" },
-	{ 0xe51037c4,	"mu_tx_wmac_1_done_fail" },
-	{ 0xe51037c8,	"mu_tx_wmac_0_mpdu_total" },
-	{ 0xe51037cc,	"mu_tx_wmac_0_mpdu_succ" },
-	{ 0xe51037d0,	"mu_tx_wmac_1_mpdu_total" },
-	{ 0xe51037d4,	"mu_tx_wmac_1_mpdu_succ" },
-	{ 0xe51037d8,	"mu_tx_qnum[0]" },
-	{ 0xe51037dc,	"mu_tx_qnum[1]" },
-	{ 0xe51037e0,	"mu_tx_qnum[2]" },
-	{ 0xe51037e4,	"mu_tx_qnum[3]" },
-	{ 0xe51037e8,	"tqe_sema_fails" },
+	{ 0xe5101280, "jiffies" },
+	{ 0xe5103344, "IRQ_0" },
+	{ 0xe5103348, "IRQ_1" },
+	{ 0xe510334c, "IRQ_2" },
+	{ 0xe5103350, "IRQ_3" },
+	{ 0xe5103354, "IRQ_4" },
+	{ 0xe5103358, "IRQ_5" },
+	{ 0xe510335c, "IRQ_6" },
+	{ 0xe5103360, "IRQ_7" },
+	{ 0xe5103364, "IRQ_8" },
+	{ 0xe5103368, "IRQ_9" },
+	{ 0xe510336c, "IRQ_10" },
+	{ 0xe5103370, "IRQ_11" },
+	{ 0xe5103374, "IRQ_12" },
+	{ 0xe5103378, "IRQ_13" },
+	{ 0xe510337c, "IRQ_14" },
+	{ 0xe5103380, "IRQ_15" },
+	{ 0xe5103384, "IRQ_16" },
+	{ 0xe5103388, "IRQ_17" },
+	{ 0xe510338c, "IRQ_18" },
+	{ 0xe5103390, "IRQ_19" },
+	{ 0xe51033a0,	"task_alive_counters[0]" },
+	{ 0xe51033a4,	"task_alive_counters[1]" },
+	{ 0xe51033a8,	"task_alive_counters[2]" },
+	{ 0xe51033ac,	"task_alive_counters[3]" },
+	{ 0xe51033b0,	"task_alive_counters[4]" },
+	{ 0xe51033b4,	"task_alive_counters[5]" },
+	{ 0xe51033b8,	"task_alive_counters[6]" },
+	{ 0xe51033bc,	"task_alive_counters[7]" },
+	{ 0xe51033c0,	"task_alive_counters[8]" },
+	{ 0xe51033c4,	"task_alive_counters[9]" },
+	{ 0xe51033c8,	"task_alive_counters[10]" },
+	{ 0xe51033cc,	"task_alive_counters[11]" },
+	{ 0xe51033d0,	"task_alive_counters[12]" },
+	{ 0xe51033d4,	"task_alive_counters[13]" },
+	{ 0xe51033d8,	"task_alive_counters[14]" },
+	{ 0xe51033dc,	"task_alive_counters[15]" },
+	{ 0xe51033e0,	"task_alive_counters[16]" },
+	{ 0xe51033e4,	"task_alive_counters[17]" },
+	{ 0xe51033e8,	"task_alive_counters[18]" },
+	{ 0xe51033ec,	"task_alive_counters[19]" },
+	{ 0xe51033f0,	"task_false_trigger[0]" },
+	{ 0xe51033f4,	"task_false_trigger[1]" },
+	{ 0xe51033f8,	"task_false_trigger[2]" },
+	{ 0xe51033fc,	"task_false_trigger[3]" },
+	{ 0xe5103400,	"task_false_trigger[4]" },
+	{ 0xe5103404,	"task_false_trigger[5]" },
+	{ 0xe5103408,	"task_false_trigger[6]" },
+	{ 0xe510340c,	"task_false_trigger[7]" },
+	{ 0xe5103410,	"task_false_trigger[8]" },
+	{ 0xe5103414,	"task_false_trigger[9]" },
+	{ 0xe5103418,	"task_false_trigger[10]" },
+	{ 0xe510341c,	"task_false_trigger[11]" },
+	{ 0xe5103420,	"task_false_trigger[12]" },
+	{ 0xe5103424,	"task_false_trigger[13]" },
+	{ 0xe5103428,	"task_false_trigger[14]" },
+	{ 0xe510342c,	"task_false_trigger[15]" },
+	{ 0xe5103430,	"task_false_trigger[16]" },
+	{ 0xe5103434,	"task_false_trigger[17]" },
+	{ 0xe5103438,	"task_false_trigger[18]" },
+	{ 0xe510343c,	"task_false_trigger[19]" },
+	{ 0xe5103440,	"tqew_ac[0]" },
+	{ 0xe5103444,	"tqew_ac[1]" },
+	{ 0xe5103448,	"tqew_ac[2]" },
+	{ 0xe510344c,	"tqew_ac[3]" },
+	{ 0xe5103450,	"tqew_ac_avail[0]" },
+	{ 0xe5103454,	"tqew_ac_avail[1]" },
+	{ 0xe5103458,	"tqew_ac_avail[2]" },
+	{ 0xe510345c,	"tqew_ac_avail[3]" },
+	{ 0xe5103460,	"tqew_air_humble" },
+	{ 0xe5103464,	"tqew_air_suppress" },
+	{ 0xe5103468,	"tqew_air_use_idletime" },
+	{ 0xe510346c,	"tqew_air_dequeue_only" },
+	{ 0xe5103470,	"tqew_pkt_pending_for_txdone" },
+	{ 0xe5103474,	"tqew_descr_alloc_fail" },
+	{ 0xe5103478,	"tqew_ring_alloc_fail" },
+	{ 0xe510347c,	"tqew_pop_alloc_fail" },
+	{ 0xe5103480,	"tqew_pop_sw_limit" },
+	{ 0xe5103484,	"tqew_pop_empty" },
+	{ 0xe5103488,	"tqew_available_set" },
+	{ 0xe510348c,	"tqew_available_reset" },
+	{ 0xe5103490,	"tqew_rx" },
+	{ 0xe5103494,	"tqew_drop" },
+	{ 0xe5103498,	"tqew_free" },
+	{ 0xe510349c,	"tqew_buf_invalid" },
+	{ 0xe51034a0,	"wmac_tx_done[0]" },
+	{ 0xe51034a4,	"wmac_tx_done[1]" },
+	{ 0xe51034a8,	"wmac_tx_done[2]" },
+	{ 0xe51034ac,	"wmac_tx_done[3]" },
+	{ 0xe51034b0,	"agg_aggregate_flag" },
+	{ 0xe51034b4,	"agg_aggressive_agg" },
+	{ 0xe51034b8,	"hdrs_available_recent_min" },
+	{ 0xe51034bc,	"agg_states[0]" },
+	{ 0xe51034c0,	"agg_states[1]" },
+	{ 0xe51034c4,	"agg_states[2]" },
+	{ 0xe51034c8,	"agg_states[3]" },
+	{ 0xe51034cc,	"agg_states[4]" },
+	{ 0xe51034d0,	"ethq_push" },
+	{ 0xe51034d4,	"ethq_pop" },
+	{ 0xe51034d8,	"agg_aggregate_mpdu" },
+	{ 0xe51034dc,	"agg_aggregate_msdu" },
+	{ 0xe51034e0,	"agg_singleton_mpdu" },
+	{ 0xe51034e4,	"agg_singleton_mgmt" },
+	{ 0xe51034e8,	"agg_singleton_ctl" },
+	{ 0xe51034ec,	"agg_singleton_probe" },
+	{ 0xe51034f0,	"agg_4K_amsdu" },
+	{ 0xe51034f4,	"agg_8K_amsdu" },
+	{ 0xe51034f8,	"agg_11K_amsdu" },
+	{ 0xe51034fc,	"tx_feedback_success" },
+	{ 0xe5103500,	"tx_feedback_fail" },
+	{ 0xe5103504,	"tx_done_status_success" },
+	{ 0xe5103508,	"tx_done_status_timeout" },
+	{ 0xe510350c,	"tx_done_status_xretry" },
+	{ 0xe5103510,	"tx_done_status_timeout_xretry" },
+	{ 0xe5103514,	"tx_done_pkt_chain_reset" },
+	{ 0xe5103518,	"tx_done_pkt_chain_success" },
+	{ 0xe510351c,	"tx_done_pkt_chain_drop_tid_down" },
+	{ 0xe5103520,	"tx_done_pkt_chain_drop_xattempts" },
+	{ 0xe5103524,	"tx_done_singleton_finish" },
+	{ 0xe5103528,	"tx_done_singleton_swretry" },
+	{ 0xe510352c,	"tx_done_aggregate_finish" },
+	{ 0xe5103530,	"tx_done_aggregate_hwretry" },
+	{ 0xe5103534,	"tx_done_aggregate_swretry" },
+	{ 0xe5103538,	"tx_done_mpdu_swretry" },
+	{ 0xe510353c,	"tx_sample" },
+	{ 0xe5103540,	"tx_bw_sample" },
+	{ 0xe5103544,	"tx_swretry_lower_bw" },
+	{ 0xe5103548,	"tx_swretry_agg_exceed" },
+	{ 0xe510354c,	"tx_scale_base_20m" },
+	{ 0xe5103550,	"tx_scale_base_40m" },
+	{ 0xe5103554,	"tx_scale_base_80m" },
+	{ 0xe5103558,	"tx_scale_max" },
+	{ 0xe510355c,	"tx_scale_overstep" },
+	{ 0xe5103560,	"alloc_tqew_fast" },
+	{ 0xe5103564,	"free_tqew_fast" },
+	{ 0xe5103568,	"alloc_tqew_slow" },
+	{ 0xe510356c,	"free_tqew_slow" },
+	{ 0xe5103570,	"alloc_tqew_local" },
+	{ 0xe5103574,	"free_tqew_local" },
+	{ 0xe5103578,	"alloc_hdr_fast" },
+	{ 0xe510357c,	"free_hdr_fast" },
+	{ 0xe5103580,	"alloc_hdr_slow" },
+	{ 0xe5103584,	"free_hdr_slow" },
+	{ 0xe5103588,	"alloc_msdu_hdr_failed" },
+	{ 0xe510358c,	"alloc_mpdu_hdr_failed" },
+	{ 0xe5103590,	"alloc_tid_superfast" },
+	{ 0xe5103594,	"free_tid_superfast" },
+	{ 0xe5103598,	"alloc_tid_fast" },
+	{ 0xe510359c,	"free_tid_fast" },
+	{ 0xe51035a0,	"alloc_tid_slow" },
+	{ 0xe51035a4,	"free_tid_slow" },
+	{ 0xe51035a8,	"alloc_node_rate_fast" },
+	{ 0xe51035ac,	"free_node_rate_fast" },
+	{ 0xe51035b0,	"alloc_node_rate_slow" },
+	{ 0xe51035b4,	"free_node_rate_slow" },
+	{ 0xe51035b8,	"alloc_node_superfast" },
+	{ 0xe51035bc,	"free_node_superfast" },
+	{ 0xe51035c0,	"alloc_node_fast" },
+	{ 0xe51035c4,	"free_node_fast" },
+	{ 0xe51035c8,	"alloc_fcs" },
+	{ 0xe51035cc,	"free_fcs" },
+	{ 0xe51035d0,	"alloc_mac_descr" },
+	{ 0xe51035d4,	"free_mac_descr" },
+	{ 0xe51035d8,	"tx_mac_push" },
+	{ 0xe51035dc,	"tx_mac_idle" },
+	{ 0xe51035e0,	"tx_mac_rts" },
+	{ 0xe51035e4,	"tx_mac_cts2self" },
+	{ 0xe51035e8,	"tx_vlan_drop" },
+	{ 0xe51035ec,	"tx_acm_drop" },
+	{ 0xe51035f0,	"tx_ps_drop" },
+	{ 0xe51035f4,	"ocs_tx_suspend" },
+	{ 0xe51035f8,	"ocs_tx_resume" },
+	{ 0xe51035fc,	"ocs_singleton_suspend" },
+	{ 0xe5103600,	"ocs_ampdu_suspend" },
+	{ 0xe5103604,	"ocs_frame_created" },
+	{ 0xe5103608,	"pwr_mgmt_awake" },
+	{ 0xe510360c,	"pwr_mgmt_sleep" },
+	{ 0xe5103610,	"pwr_mgmt_tx" },
+	{ 0xe5103614,	"pspoll_rx" },
+	{ 0xe5103618,	"dtim_q_push" },
+	{ 0xe510361c,	"dtim_q_pop" },
+	{ 0xe5103620,	"dtim_trigger" },
+	{ 0xe5103624,	"dtim_q_overflow" },
+	{ 0xe5103628,	"tx_restrict_dropped" },
+	{ 0xe510362c,	"tx_throt_dropped" },
+	{ 0xe5103630,	"tx_block_singleton" },
+	{ 0xe5103634,	"tx_force_unblock_tid" },
+	{ 0xe5103638,	"tx_ctl_pkt_hbm_alloc_fails" },
+	{ 0xe510363c,	"tx_ctl_pkt_alloc_descr_fails" },
+	{ 0xe5103640,	"tx_bar_alloc_ctl_pkt_fails" },
+	{ 0xe5103644,	"wmm_ps_tx" },
+	{ 0xe5103648,	"wmm_ps_tx_null_frames" },
+	{ 0xe510364c,	"wmm_ps_tx_more_data_frames" },
+	{ 0xe5103650,	"wmm_ps_tx_eosp_frames" },
+	{ 0xe5103654,	"mu_tx_su_count" },
+	{ 0xe5103658,	"mu_tx_send_mu_fail" },
+	{ 0xe510365c,	"mu_tx_push_count" },
+	{ 0xe5103660,	"mu_tx_done_count" },
+	{ 0xe5103664,	"mu_tx_done_succ" },
+	{ 0xe5103668,	"mu_tx_done_fail" },
+	{ 0xe510366c,	"mu_tx_sample" },
+	{ 0xe5103670,	"mu_bar_bitmap_non_zero" },
+	{ 0xe5103674,	"mu_bar_bitmap_zero" },
+	{ 0xe5103678,	"mu_mac_wmac1_ipc_push" },
+	{ 0xe510367c,	"mu_mac_wmac1_auc_push" },
+	{ 0xe5103680,	"mu_wmac1_resets" },
+	{ 0xe5103684,	"mu_tx_swretry_agg_exceed" },
+	{ 0xe5103688,	"mu_tx_buddy_try" },
+	{ 0xe510368c,	"mu_tx_buddy_fail_wmac" },
+	{ 0xe5103690,	"mu_tx_buddy_fail_ptid" },
+	{ 0xe5103694,	"mu_tx_buddy_fail_rate" },
+	{ 0xe5103698,	"mu_tx_buddy_fail_create_agg" },
+	{ 0xe510369c,	"mu_tx_buddy_mu_only_timeout" },
+	{ 0xe51036a0,	"mu_tx_another_q_push_succ" },
+	{ 0xe51036a4,	"mu_tx_another_q_push_fail" },
+	{ 0xe51036a8,	"mu_tx_buddy_multi_tid" },
+	{ 0xe51036ac,	"mu_tx_wmac_0_done_count" },
+	{ 0xe51036b0,	"mu_tx_wmac_0_bitmap_non_zero" },
+	{ 0xe51036b4,	"mu_tx_wmac_0_bitmap_zero" },
+	{ 0xe51036b8,	"mu_tx_wmac_0_done_timeout" },
+	{ 0xe51036bc,	"mu_tx_wmac_0_done_succ" },
+	{ 0xe51036c0,	"mu_tx_wmac_0_done_fail" },
+	{ 0xe51036c4,	"mu_tx_wmac_1_done_succ" },
+	{ 0xe51036c8,	"mu_tx_wmac_1_done_fail" },
+	{ 0xe51036cc,	"mu_tx_wmac_0_mpdu_total" },
+	{ 0xe51036d0,	"mu_tx_wmac_0_mpdu_succ" },
+	{ 0xe51036d4,	"mu_tx_wmac_1_mpdu_total" },
+	{ 0xe51036d8,	"mu_tx_wmac_1_mpdu_succ" },
+	{ 0xe51036dc,	"mu_tx_qnum[0]" },
+	{ 0xe51036e0,	"mu_tx_qnum[1]" },
+	{ 0xe51036e4,	"mu_tx_qnum[2]" },
+	{ 0xe51036e8,	"mu_tx_qnum[3]" },
+	{ 0xe51036ec,	"tqe_sema_fails" },
diff --git a/include/qtn/qtn_buffers.h b/include/qtn/qtn_buffers.h
index ca69c88..de0540d 100644
--- a/include/qtn/qtn_buffers.h
+++ b/include/qtn/qtn_buffers.h
@@ -25,19 +25,12 @@
 
 #include <common/topaz_config.h>
 
-#if defined(TOPAZ_PLATFORM)
 #define QTN_BUF_USE_11AC_SIZE			1
 #define TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT		1
-#else
-#define QTN_BUF_USE_11AC_SIZE			0
-#define TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT		0
-#endif
 
 #define TOPAZ_HBM_SKB_ALLOCATOR			2
 
-#if !defined(TOPAZ_PLATFORM) && QTN_BUF_USE_11AC_SIZE
-	#error Cannot use QTN_BUF_USE_11AC_SIZE on Ruby, insufficient DDR
-#elif defined(TOPAZ_PLATFORM) && TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT
+#if TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT
 	/*
 	 * Buffer allocation in Topaz when using the switch must be extremely
 	 * careful such that the sum of all possible buffer pileup does not
@@ -51,7 +44,7 @@
 	#define QTN_BUFS_WMAC_TX_NON_LHOST_S	9
 	#define QTN_BUFS_WMAC_TX_QDISC_S	10
 	#define QDRV_TX_SCH_RED_MASK		((1 << 7) - 1)
-#elif defined(TOPAZ_PLATFORM) && QTN_BUF_USE_11AC_SIZE
+#elif QTN_BUF_USE_11AC_SIZE
 	/* Topaz with 11ac buffers, no acceleration */
 	#define TOPAZ_HBM_PAYLOAD_COUNT_S	TOPAZ_HBM_BUF_EMAC_RX_COUNT_S
 	#define QTN_BUFS_EMAC_TX_RING_S		9
@@ -104,7 +97,7 @@
 #define QTN_BUFS_WMAC_TOTAL		(1 * (QTN_BUFS_WMAC_RX_RING + QTN_BUFS_WMAC_TX_NON_LHOST + QTN_BUFS_WMAC_TX_QDISC + QDRV_MAX_QUEUED_MGMT_FRAMES))
 #define QTN_BUFS_ALLOC_TOTAL		(QTN_BUFS_CPUS_TOTAL /*+ QTN_BUFS_EMAC_TOTAL*/ + QTN_BUFS_WMAC_TOTAL)
 
-#if defined(TOPAZ_PLATFORM) && TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT && (TOPAZ_HBM_PAYLOAD_COUNT <= QTN_BUFS_ALLOC_TOTAL)
+#if TOPAZ_HBM_SKB_ALLOCATOR_DEFAULT && (TOPAZ_HBM_PAYLOAD_COUNT <= QTN_BUFS_ALLOC_TOTAL)
 	#error "Payload buffers distribution error"
 #endif
 
diff --git a/include/qtn/qtn_config.h b/include/qtn/qtn_config.h
deleted file mode 100644
index f660f93..0000000
--- a/include/qtn/qtn_config.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*SH1
-*******************************************************************************
-**                                                                           **
-**         Copyright (c) 2012 Quantenna Communications, Inc                  **
-**                            All Rights Reserved                            **
-**                                                                           **
-**  Author      : Quantenna Communications Inc                               **
-**  File        : qtn_config.h                                               **
-**  Description :                                                            **
-**                                                                           **
-*******************************************************************************
-**                                                                           **
-**  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 _QTN_CONFIG_H_
-#define _QTN_CONFIG_H_
-
-#define TXBF_6_STA_BF
-
-#endif /* _QTN_CONFIG_H_ */
diff --git a/include/qtn/qtn_debug.h b/include/qtn/qtn_debug.h
index d2b6f7a..3f1b55e 100644
--- a/include/qtn/qtn_debug.h
+++ b/include/qtn/qtn_debug.h
@@ -52,11 +52,7 @@
 stack size is limited to 32.
 When set to 0 AuC formats the output, pass the formatted line to the LHOST that
 prints it. */
-#ifdef TOPAZ_PLATFORM
-	#define AUC_LHOST_PRINT_FORMAT	1
-#else
-	#define AUC_LHOST_PRINT_FORMAT	0
-#endif
+#define AUC_LHOST_PRINT_FORMAT	1
 #define PRINT_STACK_SIZE	32
 
 #if defined(MUC_BUILD)
diff --git a/include/qtn/qtn_decap.h b/include/qtn/qtn_decap.h
index 8389e95..9afffc8 100644
--- a/include/qtn/qtn_decap.h
+++ b/include/qtn/qtn_decap.h
@@ -6,6 +6,7 @@
 #include <net80211/if_llc.h>
 
 #include <qtn/qtn_net_packet.h>
+#include <qtn/qtn_vlan.h>
 
 /*
  * Length of received frame that requires dcache invalidate on receive.
@@ -30,6 +31,7 @@
 	uint16_t	l3_ether_type;		/* l3 header type (may not match eh.ether_type for 802.3 */
 	int8_t		tid;
 	int8_t		nvlans;
+	uint16_t	vlanid;			/* to which VLAN te msdu belongs */
 	uint8_t		first_msdu	:1,	/* first msdu in an amsdu */
 			last_msdu	:1,	/* last msdu in an amsdu */
 			decapped	:1,	/* start is decapped eh, not wireless header */
@@ -81,7 +83,8 @@
  */
 static __inline__ void *
 qtn_rx_decap_set_eth_hdr(struct qtn_rx_decap_info *di, const uint8_t *llc, const uint16_t llclen,
-				uint16_t vlan_mode, uint16_t vid, void *token, void **rate_train)
+				uint16_t pvid, struct qtn_vlan_info *vlan_info, uint8_t vlan_enabled,
+				void *token, void **rate_train)
 {
 	uint16_t *newhdrp = &di->eh.ether_type;
 	int8_t llc_l3_gap = 0;
@@ -90,21 +93,41 @@
 	uint8_t last_byte = llc[5];
 	uint16_t ether_type_eh;
 	bool is_llc_snap_e;
+	uint8_t vlan_hdr = 0;
+	int tagrx;
 
 	ether_type_l3 = (llc[6] << 0) | (llc[7] << 8);
 	ether_type_eh = ether_type_l3;
 
 	di->nvlans = 0;
+	di->vlanid = 0;
+
+	if (ether_type_l3 == htons(ETHERTYPE_8021Q)) {
+		pvid = ((llc[9] << 0) | (llc[8] << 8)) & QVLAN_MASK_VID;
+	}
 
 	/*
 	 * For EAPOL and VLAN frames we do not want to add 802.1Q header.
 	 * Otherwise, the frame won't go through a driver.
 	 */
-	if (vlan_mode && ether_type_l3 != htons(ETHERTYPE_8021Q) &&
-			ether_type_l3 != htons(ETHERTYPE_PAE)) {
-		*newhdrp++ = htons(ETHERTYPE_8021Q);
-		*newhdrp++ = htons(vid);
-		di->nvlans++;
+	if (vlan_enabled) {
+		di->vlanid = pvid;
+		tagrx = qtn_vlan_get_tagrx(vlan_info->vlan_tagrx_bitmap, pvid);
+
+		if (tagrx == QVLAN_TAGRX_TAG) {
+			if (ether_type_l3 != htons(ETHERTYPE_8021Q) &&
+					ether_type_l3 != htons(ETHERTYPE_PAE)) {
+				*newhdrp++ = htons(ETHERTYPE_8021Q);
+				*newhdrp++ = htons(pvid);
+				di->nvlans++;
+			}
+		} else if (tagrx == QVLAN_TAGRX_STRIP) {
+			if (ether_type_l3 == htons(ETHERTYPE_8021Q)) {
+				ether_type_l3 = ((llc[10] << 0) | (llc[11] << 8)) & QVLAN_MASK_VID;
+				ether_type_eh = ether_type_l3;
+				vlan_hdr = 4;
+			}
+		}
 	}
 
 	/*
@@ -132,7 +155,7 @@
 			}
 		}
 
-		llc += LLC_SNAPFRAMELEN;
+		llc += (LLC_SNAPFRAMELEN + vlan_hdr);
 		*newhdrp++ = ether_type_eh;
 	} else {
 		ether_type_eh = htons(llclen);
@@ -170,7 +193,7 @@
 
 QTN_RX_DECAP_FNQUAL int qtn_rx_decap(const struct ieee80211_qosframe_addr4 *const wh_copy,
 		const void *const rxdata, const uint16_t rxlen,
-		const uint16_t vlan_mode, const uint16_t vid,
+		uint16_t pvid, struct qtn_vlan_info *vlan_info, uint8_t vlan_enabled,
 		decap_handler_t handler, void *token, void **rate_train)
 {
 	const uint8_t *llc;
@@ -247,7 +270,7 @@
 		IEEE80211_ADDR_COPY(di->eh.ether_shost, wh_eth_src);
 		llc = ((uint8_t *) rxdata) + header_size;
 		decap_start = qtn_rx_decap_set_eth_hdr(di, llc, rxlen - header_size,
-							vlan_mode, vid, token, rate_train);
+							pvid, vlan_info, vlan_enabled, token, rate_train);
 		if (unlikely(!decap_start)) {
 			return QTN_RX_DECAP_TRAINING;
 		}
@@ -293,7 +316,7 @@
 			/* decapped length includes subframe padding */
 			total_decapped_len = ((uint8_t *)next_msdu_header) - ((uint8_t *)rxdata);
 
-			decap_start = qtn_rx_decap_set_eth_hdr(di, llc, msdu_len, vlan_mode, vid,
+			decap_start = qtn_rx_decap_set_eth_hdr(di, llc, msdu_len, pvid, vlan_info, vlan_enabled,
 								token, rate_train);
 			if (unlikely(!decap_start)) {
 				return QTN_RX_DECAP_TRAINING;
diff --git a/include/qtn/qtn_global.h b/include/qtn/qtn_global.h
index 5c941ec..c1f5aba 100644
--- a/include/qtn/qtn_global.h
+++ b/include/qtn/qtn_global.h
@@ -23,8 +23,13 @@
 #define QTN_AC_BE_INHERIT_Q2Q_DISABLE		0
 #define QTN_TXBF_IOT_DISABLE                    0
 #define QTN_TXBF_IOT_ENABLE                     1
-#define QTN_GLOBAL_MU_ENABLE                    1
-#define QTN_GLOBAL_MU_DISABLE                   0
+#define QTN_GLOBAL_MU_ENABLE			1
+#define QTN_GLOBAL_MU_DISABLE			0
+#define QTN_GLOBAL_MU_INITIAL_STATE		QTN_GLOBAL_MU_DISABLE
+
+#define QTN_AUTO_CS_ENABLE			1
+#define QTN_AUTO_CS_DISABLE			0
+
 /*
  * The MuC TX Queuing algorithm is selected by setting
  * g_tx_queuing_alg. Values are:
@@ -51,7 +56,8 @@
 #define QDRV_TX_LOW_RATE_TOKENS_MAX		QTN_TX_BUF_RETURN_MIN + 28
 
 #define QTN_GLOBAL_RATE_NSS_MAX		4
-#define QTN_2X2_GLOBAL_RATE_NSS_MAX     2
+#define QTN_2X2_GLOBAL_RATE_NSS_MAX	2
+#define QTN_3X3_GLOBAL_RATE_NSS_MAX	3
 #define QTN_RX_REORDER_BUF_TIMEOUT_US	800000
 #define QTN_PROBE_RES_MAX_RETRY_COUNT	4
 #define QTN_TX_SWRETRY_AGG_MAX		8	/* high value for zero PER */
@@ -73,19 +79,10 @@
 #define QTN_TX_AMSDU_ADAPTIVE		1
 #define QTN_TX_AMSDU_FIXED		0xff
 
-#ifdef TOPAZ_PLATFORM
 #define QTN_SEL_PPPC_STEP_DEF		1
 #define QTN_SEL_PPPC_MAX_STEPS		4
-#else
-#define QTN_SEL_PPPC_STEP_DEF		2
-#define QTN_SEL_PPPC_MAX_STEPS		3
-#endif
 
-#ifdef TOPAZ_PLATFORM
 #define QTN_TX_AUC_DEFAULT		1
-#else
-#define QTN_TX_AUC_DEFAULT		0
-#endif
 
 #define QTN_INST_1SS_DEF_MAT_THRESH_DEFAULT	2	/* dbm */
 
@@ -105,6 +102,7 @@
 #define QTN_DBG_MODE_TX_PKT_LOSS		0x00000004
 #define QTN_DBG_MODE_DELBA_ON_TX_PKT_LOSS	0x00000008
 #define QTN_DBG_MODE_CCA_FORCE			0x00000010
+#define QTN_DBG_MODE_INJECT_INV_NDP		0x00000020
 
 #define QTN_DBG_FD_CHECK_PERIODIC	0x00000001
 #define QTN_DBG_FD_DUMP_OLD		0x00000002
@@ -123,6 +121,9 @@
 #define QTN_RX_GAIN_MIN_THRESHOLD		16
 #define QTN_RX_GAIN_MAX_THRESHOLD		44
 #define QTN_RX_GAIN_TIMER_INTV			1000 /* msecs */
+/* counter for delay in RFIC6 500Mhz */
+#define QTN_RFIC6_DELAY_MICRO_S			500
+#define QTN_RFIC6_DELAY_MILI_S			QTN_RFIC6_DELAY_MICRO_S * 1000
 
 #define SIZE_D1(x)	(sizeof(x)/sizeof(x[0]))
 #define SIZE_D2(x)	(sizeof(x[0])/sizeof(x[0][0]))
@@ -154,9 +155,8 @@
 	uint32_t	oc_sp_cnt;
 	uint32_t	oc_cca_pri;
 	uint32_t	oc_cca_sec;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	oc_cca_sec40;
-#endif
+	uint32_t	oc_cca_busy;
 	uint32_t	oc_cca_smpl;
 	uint32_t	oc_cca_try;
 	uint32_t	oc_bcn_recvd;
@@ -165,17 +165,15 @@
 struct qtn_cca_counts {
 	uint32_t	cca_pri_cnt;
 	uint32_t	cca_sec_cnt;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	cca_sec40_cnt;
-#endif
+	uint32_t	cca_busy_cnt;
 	uint32_t	cca_sample_cnt;
 	uint32_t	cca_try_cnt;
 	uint32_t	cca_csw_cnt;
 	uint32_t	cca_off_pri_cnt;
 	uint32_t	cca_off_sec_cnt;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	cca_off_sec40_cnt;
-#endif
+	uint32_t	cca_off_busy_cnt;
 	uint32_t	cca_off_sample_cnt;
 	uint32_t	cca_off_res_cnt;
 	uint32_t	cca_off_try_cnt;
@@ -186,9 +184,7 @@
 	uint32_t	cca_sample_period;
 	uint32_t	cca_pri_cnt;
 	uint32_t	cca_sec_cnt;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	cca_sec40_cnt;
-#endif
 	uint32_t	cca_sample_cnt;
 	uint32_t	cca_try_cnt;
 	uint32_t	cca_csw_cnt;
@@ -199,6 +195,10 @@
 	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;
@@ -207,9 +207,8 @@
 struct qtn_scs_params {
 	uint32_t	cca_pri_cnt;
 	uint32_t	cca_sec_cnt;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	cca_sec40_cnt;
-#endif
+	uint32_t	cca_busy_cnt;
 	uint32_t	cca_sample_cnt;
 	uint32_t	cca_try_cnt;
 	uint32_t	cca_csw_cnt;
@@ -237,9 +236,8 @@
 	uint32_t	intf_ms;
 	uint32_t	cca_pri_cnt;
 	uint32_t	cca_sec_cnt;
-#ifdef TOPAZ_PLATFORM
 	uint32_t	cca_sec40_cnt;
-#endif
+	uint32_t	cca_busy_cnt;
 	uint32_t	cca_sample_cnt;
 	uint32_t	cca_try_cnt;
 	uint32_t	cca_csw_cnt;
@@ -257,6 +255,7 @@
 
 
 struct qtn_auto_cca_params {
+#define QTN_AUTO_CCA_FLAGS_DISABLE			0x0
 #define QTN_AUTO_CCA_FLAGS_ENABLE			0x1
 #define QTN_AUTO_CCA_FLAGS_DEBUG			0x2
 #define QTN_AUTO_CCA_FLAGS_SAMPLE_ONLY			0x4
@@ -348,6 +347,11 @@
 	uint8_t		g_l2_ext_filter;	/* L2 external filter */
 	uint8_t		g_l2_ext_filter_port;	/* L2 external filter port */
 	uint8_t		g_rate_train_dbg;
+	uint8_t		g_rx_optim_pkt_stats;
+	uint8_t		g_mrc_enable;
+	uint32_t	g_auto_cs_enable;	/* enable/disable auto cs threshold */
+	uint8_t		g_beaconing_scheme;
+	uint32_t	g_muc_sys_dbg;
 	char		*g_last_field;		/* Add all new fields before this one */
 };
 
@@ -413,15 +417,20 @@
 	QTN_AUTO_CCA_PARARMS_DEFAULT,		\
 	{0, 0, 0x0842, 0xffff},			\
 	0,					\
-	QTN_AUC_AIRFAIR_DFT,					\
+	QTN_AUC_AIRFAIR_DFT,			\
 	0,					\
 	QTN_NDPA_IN_LEGACY_FORMAT,		\
 	1,					\
 	QTN_INST_1SS_DEF_MAT_THRESH_DEFAULT,	\
-	QTN_GLOBAL_MU_DISABLE,			\
+	QTN_GLOBAL_MU_INITIAL_STATE,		\
 	0,					\
 	TOPAZ_TQE_EMAC_0_PORT,			\
 	0,					\
+	0,					\
+	1,					\
+	QTN_AUTO_CS_ENABLE,			\
+	0,					\
+	0,					\
 	"end"					\
 }
 
@@ -432,6 +441,7 @@
 extern uint32_t g_qtn_rxtime_usecs;
 extern uint32_t g_qtn_txtime_usecs;
 extern uint32_t g_rf_xmit_status;
+extern int vlan_enabled_bus;
 
 #endif	/* defined(MUC_BUILD) */
 
@@ -446,21 +456,20 @@
 #define M_AGE_SUB(skb,adj)	(skb->skb_age -= adj)
 
 #define QTN_2G_FIRST_OPERATING_CHAN 1
-#define QTN_2G_LAST_OPERATING_CHAN  13
+#define QTN_2G_LAST_OPERATING_CHAN  14
 #define QTN_5G_FIRST_OPERATING_CHAN 36
 #define QTN_5G_LAST_UNII1_OPERATING_CHAN 48
 #define QTN_5G_LAST_UNII2_OPERATING_CHAN 140
 #define QTN_5G_LAST_OPERATING_CHAN  169
 
-/* RFIC5 chip ID */
+/* RFIC chip ID */
 #define RFIC5_EAGLE_PROJ_ID (2)
+#define RFIC6_PROJ_ID (3)
 
 /* MU-MIMO WMAC index */
 enum {
 	WMAC_ID_0	= 0,
-#ifdef TOPAZ_PLATFORM
 	WMAC_ID_1	= 1,
-#endif
 	WMAC_ID_MAX
 };
 
diff --git a/include/qtn/qtn_muc_stats_print.h b/include/qtn/qtn_muc_stats_print.h
index c62e81d..6c663f9 100644
--- a/include/qtn/qtn_muc_stats_print.h
+++ b/include/qtn/qtn_muc_stats_print.h
@@ -53,6 +53,8 @@
 	"txdone_mgmt", \
 	"txdone_data", \
 	"tx_pwr", \
+	"bcn_scheme_power_save", \
+	"bcn_scheme", \
 	"tx_mcast_pwr", \
 	"tx_mcast_defer", \
 	"tx_mcast_defer_hwq", \
@@ -100,24 +102,17 @@
 	"off_chan_sample", \
 	"off_chan_scan", \
 	"off_chan_cac", \
+	"cca_pri", \
+	"cca_sec", \
+	"cca_sec40", \
+	"cca_busy", \
 	"cca_fat", \
 	"cca_intf", \
 	"cca_trfc", \
-	"mu_qtn_hardstart", \
-	"mu_no_buddy", \
-	"mu_buddy_mgmt", \
-	"mu_buddy_mismatch", \
-	"mu_push_to_hw", \
-	"mu_to_su_hw", \
-	"mu_txdone_buddy", \
-	"mu_no_bar", \
-	"mu_bar_acquire", \
-	"mu_bar_release", \
-	"mu_wmac0_retry", \
-	"mu_wmac1_retry", \
-	"mu_reservetx_fail", \
 	"mu_prec_snd_tx", \
+	"mu_prec_snd_wait_done", \
 	"mu_grp_sel_snd_tx", \
+	"mu_grp_sel_snd_wait_done", \
 	"oc_auctx_timeout", \
 	"oc_auctx_overwrite", \
 	"oc_auctx_fail", \
@@ -155,11 +150,26 @@
 	"sfs_dyn_wmm_flags", \
 	"auc_wmm_ps_notify", \
 	"tx_wmm_ps_null_frames", \
+	"qtn_bcn_stop", \
+	"mu_grp_snd_queue_is_not_empty", \
+	"mu_prec_snd_queue_is_not_empty", \
+	"autocs_sample_bits", \
+	"autocs_adjust_bits", \
+	"autocs_step_size", \
+	"autocs_cs_thresh", \
+	"autocs_min_rssi", \
+	"bmps_null_tx_success", \
+	"bmps_null_tx_fail", \
+	"bmps_null_tx_timeout", \
+	"txqueue_g1q0_deadline_frozen", \
+	"auc_ipc_retry", \
+	"auc_ipc_hwm", \
+	"auc_ipc_send_delay", \
+	"auc_ipc_send_delay_hwm", \
 }
 
 #define MUC_RX_STATS_NAMES_TABLE { \
 	"rxdesc_pop_from_host", \
-	"rxdesc_push_to_hw", \
 	"rxdesc_get_from_queue", \
 	"rxdesc_push_to_host", \
 	"rxdesc_non_aggr_push_to_host", \
@@ -402,9 +412,13 @@
 	"rxq_process_limited[0]", \
 	"rxq_process_limited[1]", \
 	"rxq_process_limited[2]", \
+	"rxq_desc_chain_empty[0]", \
+	"rxq_desc_chain_empty[1]", \
+	"rxq_desc_chain_empty[2]", \
 	"rx_data_last_seqfrag", \
 	"rx_data_last_ip_id", \
 	"accel_l2_ext_filter", \
 	"accel_mc_send_l2_ext_filter", \
 	"accel_mc_drop_l2_ext_filter", \
+	"rx_frame_addressed_to_wrong_bss", \
 }
diff --git a/include/qtn/qtn_net_packet.h b/include/qtn/qtn_net_packet.h
index f60e1c2..3ebc872 100644
--- a/include/qtn/qtn_net_packet.h
+++ b/include/qtn/qtn_net_packet.h
@@ -3,15 +3,45 @@
 
 #include <qtn/qtn_global.h>
 
+#ifndef ETHERTYPE_ARP
 #define	ETHERTYPE_ARP	0x0806		/* ARP protocol */
+#endif
+
+#ifndef ETHERTYPE_AARP
 #define ETHERTYPE_AARP	0x80f3		/* Appletalk AARP */
+#endif
+
+#ifndef ETHERTYPE_PAE
 #define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
+#endif
+
+#ifndef ETHERTYPE_IP
 #define	ETHERTYPE_IP	0x0800		/* IP protocol */
+#endif
+
+#ifndef ETHERTYPE_IPV6
 #define	ETHERTYPE_IPV6	0x86DD		/* IPv6 protocol */
+#endif
+
+#ifndef ETHERTYPE_IPX
 #define ETHERTYPE_IPX	0x8137		/* IPX over DIX */
+#endif
+
+#ifndef ETHERTYPE_802A
 #define ETHERTYPE_802A	0x88B7
+#endif
+
+#ifndef ETHERTYPE_8021Q
 #define	ETHERTYPE_8021Q	0x8100          /* 802.1Q VLAN header */
+#endif
+
+#ifndef ETHERTYPE_8021AD
+#define ETHERTYPE_8021AD	0x88A8  /* 802.1AD VLAN S-TAG header */
+#endif
+
+#ifndef ETHERTYPE_WAKE_ON_LAN
 #define ETHERTYPE_WAKE_ON_LAN	0X0842
+#endif
 
 union qtn_ipv4_addr {
 	uint32_t ip32;
@@ -131,5 +161,11 @@
 	return ((ipv4[1] >> 7) | (ipv4[0] & 0xF) << 1);
 }
 
+RUBY_INLINE uint8_t qtn_ether_type_is_vlan(const uint16_t type)
+{
+	return ((type == htons(ETHERTYPE_8021Q))
+			|| (type == htons(ETHERTYPE_8021AD)));
+}
+
 #endif	// __QTN_NET_PACKET_H__
 
diff --git a/include/qtn/qtn_skb_cb.h b/include/qtn/qtn_skb_cb.h
index d27a36f..41da785 100644
--- a/include/qtn/qtn_skb_cb.h
+++ b/include/qtn/qtn_skb_cb.h
@@ -38,6 +38,8 @@
 #define M_ENQUEUED_SCH		0x0800	/* Enqueued in qdrv_sch */
 #define M_ENQUEUED_MUC		0x1000	/* Enqueued to MuC */
 #define	M_TX_DONE_IMM_INT	0x2000	/* Immediately interrupt lhost when tx done */
+#define M_VLAN_TAGGED		0x4000	/* skb belongs to some VLAN */
+#define M_VLAN_TAG_OWE		0x8000	/* VLAN tag is stripped of this skb */
 };
 
 #define QTN_SKB_ENCAP_ETH		0
diff --git a/include/qtn/qtn_uc_comm.h b/include/qtn/qtn_uc_comm.h
index 9f11482..3c35434 100644
--- a/include/qtn/qtn_uc_comm.h
+++ b/include/qtn/qtn_uc_comm.h
@@ -7,7 +7,7 @@
 
 #define MAC_UNITS		1
 
-#if defined(TOPAZ_PLATFORM) && defined(TOPAZ_128_NODE_MODE)
+#if defined(TOPAZ_128_NODE_MODE)
 #define QTN_NCIDX_MAX			128
 #define QTN_NODE_TBL_SIZE_LHOST		118
 #define QTN_NODETID_NODE_SHIFT		7
diff --git a/include/qtn/qtn_vlan.h b/include/qtn/qtn_vlan.h
index f48bf23..f9d71e4 100644
--- a/include/qtn/qtn_vlan.h
+++ b/include/qtn/qtn_vlan.h
@@ -9,10 +9,19 @@
 #include "../common/ruby_mem.h"
 #include <qtn/qtn_debug.h>
 #include <qtn/qtn_uc_comm.h>
+#include <qtn/qtn_net_packet.h>
+#if defined(__KERNEL__) || defined(MUC_BUILD) || defined(AUC_BUILD)
+#include <qtn/topaz_tqe_cpuif.h>
+#endif
+#if defined(__KERNEL__)
+#include <qtn/dmautil.h>
+#endif
 
-#define QVLAN_MODE_PTHRU		0
-#define QVLAN_MODE_MBSS			1
-#define QVLAN_MODE_DYNAMIC		2
+#define QVLAN_MODE_ACCESS		0
+#define QVLAN_MODE_TRUNK		1
+#define QVLAN_MODE_HYBRID		2
+#define QVLAN_MODE_DYNAMIC		3
+#define QVLAN_MODE_MAX			QVLAN_MODE_DYNAMIC
 #define QVLAN_SHIFT_MODE		16
 #define QVLAN_MASK_MODE			0xffff0000
 #define QVLAN_MASK_VID			0x00000fff
@@ -20,19 +29,9 @@
 #define QVLAN_MODE(x)			(uint16_t)((x) >> QVLAN_SHIFT_MODE)
 #define QVLAN_VID(x)			(uint16_t)((x) & QVLAN_MASK_VID)
 
-#define QVLAN_CMD_PTHRU			0
-#define QVLAN_CMD_UNPTHRU		1
-#define QVLAN_CMD_PTHRU_ALL		2
-#define QVLAN_CMD_UNPTHRU_ALL		3
-#define QVLAN_CMD_BIND			4
-#define QVLAN_CMD_UNBIND		5
-#define QVLAN_CMD_ENABLE		6
-#define QVLAN_CMD_DISABLE		7
-#define QVLAN_CMD_DYNAMIC		8
-#define QVLAN_CMD_UNDYNAMIC		9
-
-#define QVLAN_MODE_STR_BIND	"MBSS (Access) mode"
-#define QVLAN_MODE_STR_PTHRU	"Passthrough (Trunk) mode"
+#define QVLAN_MODE_STR_ACCESS	"Access mode"
+#define QVLAN_MODE_STR_TRUNK	"Trunk mode"
+#define QVLAN_MODE_STR_HYBRID	"Hybrid mode"
 #define QVLAN_MODE_STR_DYNAMIC	"Dynamic mode"
 
 /* default port vlan id */
@@ -42,9 +41,112 @@
 #define QVLAN_VID_MAX_S			12
 #define QVLAN_VID_ALL			0xffff
 
+#ifndef NBBY
+#define NBBY		8
+#endif
+
+#ifndef NBDW
+#define NBDW		32
+#endif
+
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+#define VLAN_INTERFACE_MAX	(QTN_MAX_VAPS + 2 + MAX_QFP_NETDEV)
+#define QFP_VDEV_IDX(dev_id)	(QTN_MAX_VAPS + 2 + (dev_id))
+#else
+#define VLAN_INTERFACE_MAX	(QTN_MAX_VAPS + 2)
+#endif
+#define WMAC_VDEV_IDX_MAX	QTN_MAX_VAPS
+#define EMAC_VDEV_IDX(port)	(QTN_MAX_VAPS + (port))
+#define PCIE_VDEV_IDX		(QTN_MAX_VAPS + 0)
+
+#ifndef howmany
+#define howmany(x, y)			(((x) + ((y) - 1)) / (y))
+#endif
+
+#define bitsz_var(var)			(sizeof(var) * 8)
+#define bitsz_ptr(ptr)			bitsz_var((ptr)[0])
+
+#define set_bit_a(a, i)			((a)[(i) / bitsz_ptr(a)] |= 1 << ((i) % bitsz_ptr(a)))
+#define clr_bit_a(a, i)			((a)[(i) / bitsz_ptr(a)] &= ~(1 << ((i) % bitsz_ptr(a))))
+#define is_set_a(a, i)			((a)[(i) / bitsz_ptr(a)] & (1 << ((i) % bitsz_ptr(a))))
+#define is_clr_a(a, i)			(is_set_a(a, i) == 0)
+
+struct qtn_vlan_stats {
+	uint32_t lhost;
+	uint32_t auc;
+	uint32_t muc;
+};
+
+struct qtn_vlan_user_interface {
+	unsigned long bus_addr;
+	uint8_t mode;
+};
+
+struct qtn_vlan_dev {
+	uint8_t		idx;
+	uint8_t		port;
+	uint16_t	pvid;
+#define QVLAN_DEV_F_DYNAMIC	BIT(0)
+	uint32_t	flags;
+	unsigned long	bus_addr;
+	int		ifindex;
+	union {
+		uint32_t	member_bitmap[howmany(QVLAN_VID_MAX, NBDW)];
+		uint16_t	node_vlan[QTN_NCIDX_MAX];
+	}u;
+	uint32_t	tag_bitmap[howmany(QVLAN_VID_MAX, NBDW)];
+	struct qtn_vlan_stats ig_pass;
+	struct qtn_vlan_stats ig_drop;
+	struct qtn_vlan_stats eg_pass;
+	struct qtn_vlan_stats eg_drop;
+	void		*user_data;
+};
+#define QVLAN_IS_DYNAMIC(vdev)		((vdev)->flags & QVLAN_DEV_F_DYNAMIC)
+
+struct qtn_vlan_pkt {
+#define QVLAN_PKT_MAGIC			0x1234
+	uint16_t	magic;
+#define QVLAN_TAGGED			0x8000
+#define QVLAN_SKIP_CHECK		0x4000
+	uint16_t	vlan_info;
+} __packed;
+
+#define QVLAN_PKTCTRL_LEN	sizeof(struct qtn_vlan_pkt)
+
+struct qtn_vlan_info {
+#define QVLAN_TAGRX_UNTOUCH		0
+#define QVLAN_TAGRX_STRIP		1
+#define QVLAN_TAGRX_TAG			2
+#define QVLAN_TAGRX_BITMASK		0x3
+#define QVLAN_TAGRX_BITWIDTH		2
+#define QVLAN_TAGRX_BITSHIFT		1
+#define QVLAN_TAGRX_NUM_PER_DW		(32 / QVLAN_TAGRX_BITWIDTH)
+#define QVLAN_TAGRX_NUM_PER_DW_S	4
+	uint32_t vlan_tagrx_bitmap[howmany(QVLAN_VID_MAX * QVLAN_TAGRX_BITWIDTH, NBDW)];
+};
+
+RUBY_INLINE int qvlan_tagrx_index(int vid)
+{
+	return (vid >> QVLAN_TAGRX_NUM_PER_DW_S);
+}
+
+RUBY_INLINE int qvlan_tagrx_shift(int vid)
+{
+	int shift;
+
+	shift = vid & (QVLAN_TAGRX_NUM_PER_DW - 1);
+	return (shift << QVLAN_TAGRX_BITSHIFT);
+}
+
 struct qtn_vlan_config {
-	uint32_t vlan_cfg;
-	uint8_t vlan_bitmap[QVLAN_VID_MAX / 7 + 1];
+	uint32_t	vlan_cfg;
+	union {
+		struct vlan_dev_config {
+			uint32_t	member_bitmap[howmany(QVLAN_VID_MAX, NBDW)];
+			uint32_t	tag_bitmap[howmany(QVLAN_VID_MAX, NBDW)];
+		} dev_config;
+		uint32_t	tagrx_config[howmany(QVLAN_VID_MAX * QVLAN_TAGRX_BITWIDTH, NBDW)];
+	} u;
 };
 
 /*
@@ -71,25 +173,51 @@
 RUBY_INLINE int
 qtn_vlan_is_valid(int vid)
 {
-	return (vid >= 0 && vid < QVLAN_VID_MAX);
+	/* VLAN ID 0 is reserved */
+	return (vid > 0 && vid < QVLAN_VID_MAX);
 }
 
 RUBY_INLINE int
-qtn_vlan_is_allowed(volatile uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
+qtn_vlan_is_member(volatile struct qtn_vlan_dev *vdev, uint16_t vid)
 {
-	return !!(vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] & BIT(vapid & (8 - 1)));
+	return !!is_set_a(vdev->u.member_bitmap, vid);
 }
 
-RUBY_INLINE void
-qtn_vlan_allow(uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
+RUBY_INLINE int
+qtn_vlan_is_tagged_member(volatile struct qtn_vlan_dev *vdev, uint16_t vid)
 {
-	vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] |= BIT(vapid & (8 - 1));
+	return !!is_set_a(vdev->tag_bitmap, vid);
 }
 
-RUBY_INLINE void
-qtn_vlan_disallow(uint8_t *vlan_bitmap, uint16_t vid, uint8_t vapid)
+RUBY_INLINE int
+qtn_vlan_is_pvid(volatile struct qtn_vlan_dev *vdev, uint16_t vid)
 {
-	vlan_bitmap[(vid << QVLAN_BYTES_PER_VID_SHIFT) + (vapid >> 3)] &= ~BIT(vapid & (8 - 1));
+	return vdev->pvid == vid;
+}
+
+RUBY_INLINE int
+qtn_vlan_is_mode(volatile struct qtn_vlan_dev *vdev, uint16_t mode)
+{
+	return ((struct qtn_vlan_user_interface *)vdev->user_data)->mode == mode;
+}
+
+#if defined(__KERNEL__) || defined(MUC_BUILD) || defined(AUC_BUILD)
+RUBY_INLINE int
+qtn_vlan_port_indexable(uint8_t port)
+{
+	return ((port == TOPAZ_TQE_EMAC_0_PORT)
+		|| (port == TOPAZ_TQE_EMAC_1_PORT)
+		|| (port == TOPAZ_TQE_PCIE_PORT)
+		|| (port == TOPAZ_TQE_DSP_PORT));
+}
+#endif
+
+RUBY_INLINE int
+qtn_vlan_get_tagrx(uint32_t *tagrx_bitmap, uint16_t vlanid)
+{
+	return (tagrx_bitmap[vlanid >> QVLAN_TAGRX_NUM_PER_DW_S] >>
+				((vlanid & (QVLAN_TAGRX_NUM_PER_DW - 1)) << QVLAN_TAGRX_BITSHIFT)) &
+		QVLAN_TAGRX_BITMASK;
 }
 
 RUBY_INLINE void
@@ -115,4 +243,165 @@
 		&& mac[4] != 0xff);
 }
 
+#if defined(__KERNEL__) || defined(MUC_BUILD) || defined(AUC_BUILD)
+RUBY_INLINE struct qtn_vlan_pkt*
+qtn_vlan_get_info(const void *data)
+{
+	struct qtn_vlan_pkt *pkt;
+#if defined(AUC_BUILD)
+#pragma Off(Behaved)
+#endif
+	pkt = (struct qtn_vlan_pkt *)((const uint8_t *)data - QVLAN_PKTCTRL_LEN);
+#if defined(AUC_BUILD)
+#pragma On(Behaved)
+#endif
+	return pkt;
+}
+
+RUBY_INLINE int
+qtn_vlan_magic_check(struct qtn_vlan_pkt *pkt)
+{
+#define QVLAN_EGRESS_MAGIC_MSG	"VLAN-egress: magic number incorrect(0x%04x)\n"
+
+	if (unlikely(pkt->magic != QVLAN_PKT_MAGIC)) {
+#if defined (__KERNEL__)
+		printk(KERN_WARNING QVLAN_EGRESS_MAGIC_MSG, pkt->magic);
+#elif defined(AUC_BUILD)
+		auc_os_printf(QVLAN_EGRESS_MAGIC_MSG, pkt->magic);
+#elif defined(MUC_BUILD)
+		uc_printk(QVLAN_EGRESS_MAGIC_MSG, pkt->magic);
+#endif
+		return 0;
+	}
+
+	return 1;
+}
+
+RUBY_INLINE void
+qtn_vlan_inc_stats(struct qtn_vlan_stats *stats) {
+#if defined(__KERNEL__)
+	stats->lhost++;
+#elif defined(AUC_BUILD)
+	stats->auc++;
+#elif defined(MUC_BUILD)
+	stats->muc++;
+#endif
+}
+
+RUBY_INLINE int
+qtn_vlan_vlanid_check(struct qtn_vlan_dev *vdev, uint16_t ncidx, uint16_t vlanid)
+{
+	if (QVLAN_IS_DYNAMIC(vdev))
+		return (vdev->u.node_vlan[ncidx] == vlanid);
+	else
+		return qtn_vlan_is_member(vdev, vlanid);
+}
+
+RUBY_INLINE int
+qtn_vlan_egress(struct qtn_vlan_dev *outdev, uint16_t ncidx, void *data)
+{
+	struct qtn_vlan_pkt *pkt = qtn_vlan_get_info(data);
+
+	if (!qtn_vlan_magic_check(pkt)
+			|| (pkt->vlan_info & QVLAN_SKIP_CHECK)
+			|| qtn_vlan_vlanid_check(outdev, ncidx, pkt->vlan_info & QVLAN_MASK_VID)) {
+		qtn_vlan_inc_stats(&outdev->eg_pass);
+		return 1;
+	}
+
+	qtn_vlan_inc_stats(&outdev->eg_drop);
+	return 0;
+}
+#endif
+
+#if defined(__KERNEL__) || defined(MUC_BUILD)
+RUBY_INLINE int
+qtn_vlan_ingress(struct qtn_vlan_dev *indev, uint16_t ncidx,
+		void *data, uint16_t known_vlanid, uint8_t cache_op)
+{
+	struct ether_header *eh = (struct ether_header *)data;
+	struct qtn_vlan_pkt *pkt = qtn_vlan_get_info(data);
+	uint16_t vlanid;
+	const uint16_t magic = QVLAN_PKT_MAGIC;
+
+	if (eh->ether_type == htons(ETHERTYPE_8021Q)) {
+		vlanid = ntohs(*(uint16_t *)(eh + 1)) & QVLAN_MASK_VID;
+
+		if (!qtn_vlan_vlanid_check(indev, ncidx, vlanid)) {
+			qtn_vlan_inc_stats(&indev->ig_drop);
+			return 0;
+		}
+
+		vlanid |= QVLAN_TAGGED;
+	} else if (known_vlanid) {
+		vlanid = known_vlanid;
+
+		if (!qtn_vlan_vlanid_check(indev, ncidx, vlanid)) {
+			qtn_vlan_inc_stats(&indev->ig_drop);
+			return 0;
+		}
+	} else {
+		vlanid = indev->pvid;
+	}
+
+	pkt->magic = magic;
+	pkt->vlan_info = vlanid;
+
+	if (cache_op) {
+#if defined(__KERNEL__)
+		flush_and_inv_dcache_sizerange_safe(pkt, QVLAN_PKTCTRL_LEN);
+#elif defined(MUC_BUILD)
+		flush_and_inv_dcache_range_safe(pkt, QVLAN_PKTCTRL_LEN);
+#endif
+	}
+
+	qtn_vlan_inc_stats(&indev->ig_pass);
+	return 1;
+}
+#endif
+
+RUBY_INLINE int
+qtn_vlancfg_reform(struct qtn_vlan_config *vcfg)
+{
+	/* remove 0,15,16,31 bits to restore vlan_cfg */
+	vcfg->vlan_cfg &= 0x7ffe7ffe;
+	vcfg->vlan_cfg >>= 1;
+
+	return ((vcfg->vlan_cfg & QVLAN_MASK_MODE) >> QVLAN_SHIFT_MODE);
+}
+
+#if defined(__KERNEL__)
+extern uint8_t vlan_enabled;
+extern struct qtn_vlan_dev *vdev_tbl_lhost[VLAN_INTERFACE_MAX];
+extern struct qtn_vlan_dev *vdev_tbl_bus[VLAN_INTERFACE_MAX];
+extern struct qtn_vlan_dev *vport_tbl_lhost[TOPAZ_TQE_NUM_PORTS];
+extern struct qtn_vlan_dev *vport_tbl_bus[TOPAZ_TQE_NUM_PORTS];
+extern struct qtn_vlan_info qtn_vlan_info;
+
+extern struct qtn_vlan_dev *switch_alloc_vlan_dev(uint8_t port, uint8_t idx, int ifindex);
+extern void switch_free_vlan_dev(struct qtn_vlan_dev *dev);
+extern void switch_free_vlan_dev_by_idx(uint8_t idx);
+extern struct qtn_vlan_dev *switch_vlan_dev_get_by_port(uint8_t port);
+extern struct qtn_vlan_dev *switch_vlan_dev_get_by_idx(uint8_t idx);
+
+extern int switch_vlan_add_member(struct qtn_vlan_dev *vdev, uint16_t vid, uint8_t tag);
+extern int switch_vlan_del_member(struct qtn_vlan_dev *vdev, uint16_t vid);
+extern int switch_vlan_tag_member(struct qtn_vlan_dev *vdev, uint16_t vid);
+extern int switch_vlan_untag_member(struct qtn_vlan_dev *vdev, uint16_t vid);
+extern int switch_vlan_set_pvid(struct qtn_vlan_dev *vdev, uint16_t vid);
+
+/* dynamic VLAN support */
+extern void switch_vlan_dyn_enable(struct qtn_vlan_dev *vdev);
+extern void switch_vlan_dyn_disable(struct qtn_vlan_dev *vdev);
+extern int switch_vlan_set_node(struct qtn_vlan_dev *vdev, uint16_t ncidx, uint16_t vlan);
+extern int switch_vlan_clr_node(struct qtn_vlan_dev *vdev, uint16_t ncidx);
+
+extern int switch_vlan_is_local(const uint8_t *data);
+extern struct sk_buff *switch_vlan_strip_tag(struct sk_buff *, int copy);
+extern struct sk_buff *switch_vlan_restore_tag(struct sk_buff *, int copy);
+extern void switch_vlan_reset(void);
+extern void switch_vlan_dev_reset(struct qtn_vlan_dev *vdev, uint8_t mode);
+extern void switch_vlan_emac_to_lhost(uint32_t enable);
+#endif
+
 #endif
diff --git a/include/qtn/qtn_wmm_ac.h b/include/qtn/qtn_wmm_ac.h
index a2b12a0..bab24ee 100644
--- a/include/qtn/qtn_wmm_ac.h
+++ b/include/qtn/qtn_wmm_ac.h
@@ -71,4 +71,9 @@
 	 ((_ac) == WME_AC_BK) ? 0 :	\
 	  (_ac))
 
+#define QTN_TID_MAP_UNUSED(_tid) ( \
+	(_tid == QTN_TID_2) ? QTN_TID_BK : \
+	(_tid == QTN_TID_3) ? QTN_TID_BE : \
+	(_tid))
+
 #endif	/* _QTN_WMM_AC_H */
diff --git a/include/qtn/shared_defs.h b/include/qtn/shared_defs.h
index d3fb651..ee1483a 100644
--- a/include/qtn/shared_defs.h
+++ b/include/qtn/shared_defs.h
@@ -49,11 +49,7 @@
 
 #include "shared_defs_common.h"
 
-#ifdef TOPAZ_PLATFORM
 #define QTN_SWITCH_CHANNEL_TIME_AVG	3750	/* microseconds */
-#else
-#define QTN_SWITCH_CHANNEL_TIME_AVG	3500	/* microseconds */
-#endif
 
 #define IEEE80211_MAX_NAV	32767
 
@@ -89,6 +85,7 @@
 	IEEE80211_SCS_SET_CHAN_MTRC_MRGN,
 	IEEE80211_SCS_SET_RSSI_SMTH_FCTR,
 	IEEE80211_SCS_SET_ATTEN_ADJUST,
+	IEEE80211_SCS_SET_ATTEN_SWITCH_ENABLE,
 	IEEE80211_SCS_SET_THRSHLD_ATTEN_INC,
 	IEEE80211_SCS_SET_THRSHLD_DFS_REENTRY,
 	IEEE80211_SCS_SET_THRSHLD_DFS_REENTRY_MINRATE,
@@ -113,6 +110,10 @@
 	IEEE80211_SCS_SET_AS_RX_TIME_SMTH_FCTR,
 	IEEE80211_SCS_SET_AS_TX_TIME_SMTH_FCTR,
 	IEEE80211_SCS_SET_STATS_START,
+	IEEE80211_SCS_SET_CCA_IDLE_SMTH_FCTR,
+	IEEE80211_SCS_SET_PMBL_ERR_THRSHLD,
+	IEEE80211_SCS_SET_CCA_INTF_DFS_MARGIN,
+	IEEE80211_SCS_SET_LEAVE_DFS_CHAN_MTRC_MRGN,
 	IEEE80211_SCS_SET_MAX
 };
 
@@ -138,13 +139,12 @@
 #define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_DEFAULT	16	/* packet number */
 #define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_MAX	1000	/* packet number */
 #define IEEE80211_SCS_THRSHLD_SMPL_PKTNUM_MIN	1	/* packet number */
-#ifdef TOPAZ_PLATFORM
-#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_DEFAULT	100	/* ms */
-#else
-#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_DEFAULT	300	/* ms */
-#endif
+#define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_DEFAULT	200	/* ms */
 #define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_MAX	1000	/* ms */
 #define IEEE80211_SCS_THRSHLD_SMPL_AIRTIME_MIN	1	/* ms */
+#define IEEE80211_SCS_THRSHLD_PMBL_ERR_MAX	10000	/* count */
+#define IEEE80211_SCS_THRSHLD_PMBL_ERR_MIN	1	/* count */
+
 /*
  * Packet rate threshold is determined by how many packets we can hold in buffer without drop
  * during off-channel period. It is limited by:
@@ -184,7 +184,8 @@
 #define IEEE80211_CCA_INTF_SMTH_FCTR_MIN	0
 #define IEEE80211_CCA_INTF_SMTH_FCTR_MAX	100
 #define IEEE80211_SCS_CHAN_MTRC_MRGN_MAX	100
-#define IEEE80211_SCS_CHAN_MTRC_MRGN_DFT	5
+#define IEEE80211_SCS_CHAN_MTRC_MRGN_DFT	15
+#define IEEE80211_SCS_LEAVE_DFS_CHAN_MTRC_MRGN_DFT	25
 #define IEEE80211_SCS_RSSI_SMTH_FCTR_UP_DFT	75
 #define IEEE80211_SCS_RSSI_SMTH_FCTR_DOWN_DFT	25
 #define IEEE80211_SCS_RSSI_SMTH_FCTR_MAX	100
@@ -195,6 +196,9 @@
 #define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_MIN    0
 #define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_MAX    100
 #define IEEE80211_SCS_PMBL_ERR_SMTH_FCTR_DFT    66
+#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_MIN    0
+#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_MAX    100
+#define IEEE80211_SCS_CCA_IDLE_SMTH_FCTR_DFT    50
 #define IEEE80211_SCS_PMP_RPT_CCA_SMTH_FCTR_MAX    100
 #define IEEE80211_SCS_PMP_RPT_CCA_SMTH_FCTR_DFT    66
 #define IEEE80211_SCS_PMP_RX_TIME_SMTH_FCTR_MAX    100
@@ -246,6 +250,7 @@
 #define IEEE80211_SCS_COMMAND_S			16
 #define IEEE80211_SCS_COMMAND_M			0xffff
 
+#define IEEE80211_SCS_NA_CC			0x0
 #define IEEE80211_SCS_STA_CCA_REQ_CC		0x1
 #define IEEE80211_SCS_SELF_CCA_CC               0x2
 #define IEEE80211_SCS_ATTEN_INC_CC		0x4
@@ -301,6 +306,7 @@
 	IEEE80211_OCAC_SET_BEACON_INTERVAL,
 	IEEE80211_OCAC_SET_WEATHER_DURATION,
 	IEEE80211_OCAC_SET_WEATHER_CAC_TIME,
+	IEEE80211_OCAC_SET_WEATHER_DWELL_TIME,
 	IEEE80211_OCAC_SET_MAX
 };
 
@@ -316,7 +322,8 @@
 
 #define IEEE80211_OCAC_DWELL_TIME_MIN		5	/* milliseconds */
 #define IEEE80211_OCAC_DWELL_TIME_MAX		200	/* milliseconds */
-#define IEEE80211_OCAC_DWELL_TIME_DEFAULT	50	/* milliseconds */
+#define IEEE80211_OCAC_DWELL_TIME_DEFAULT	40	/* milliseconds */
+#define IEEE80211_OCAC_WEA_DWELL_TIME_DEFAULT	20	/* milliseconds */
 
 #define IEEE80211_OCAC_SECURE_DWELL_TIME_MIN		5	/* milliseconds */
 #define IEEE80211_OCAC_SECURE_DWELL_TIME_MAX		23	/* milliseconds */
@@ -324,25 +331,27 @@
 
 #define IEEE80211_OCAC_DURATION_MIN		1	/* seconds */
 #define IEEE80211_OCAC_DURATION_MAX		64800	/* seconds */
-#define IEEE80211_OCAC_DURATION_DEFAULT		360	/* seconds */
+#define IEEE80211_OCAC_DURATION_DEFAULT		720	/* seconds */
 
 #define IEEE80211_OCAC_CAC_TIME_MIN		1	/* seconds */
 #define IEEE80211_OCAC_CAC_TIME_MAX		64800	/* seconds */
-#define IEEE80211_OCAC_CAC_TIME_DEFAULT		145	/* seconds */
+#define IEEE80211_OCAC_CAC_TIME_DEFAULT		240	/* seconds */
 
 #define IEEE80211_OCAC_WEA_DURATION_MIN		60	/* seconds */
 #define IEEE80211_OCAC_WEA_DURATION_MAX		86400	/* seconds */
+#define IEEE80211_OCAC_WEA_DURATION_DEFAULT	11520	/* seconds */
 
 #define IEEE80211_OCAC_WEA_CAC_TIME_MIN		1	/* seconds */
 #define IEEE80211_OCAC_WEA_CAC_TIME_MAX		86400	/* seconds */
+#define IEEE80211_OCAC_WEA_CAC_TIME_DEFAULT	1920	/* seconds */
 
 #define IEEE80211_OCAC_THRESHOLD_FAT_MIN	1	/* percent */
 #define IEEE80211_OCAC_THRESHOLD_FAT_MAX	100	/* percent */
-#define IEEE80211_OCAC_THRESHOLD_FAT_DEFAULT	65	/* percent */
+#define IEEE80211_OCAC_THRESHOLD_FAT_DEFAULT	90	/* percent */
 
 #define IEEE80211_OCAC_THRESHOLD_TRAFFIC_MIN		1	/* percent */
 #define IEEE80211_OCAC_THRESHOLD_TRAFFIC_MAX		100	/* percent */
-#define IEEE80211_OCAC_THRESHOLD_TRAFFIC_DEFAULT	35	/* percent */
+#define IEEE80211_OCAC_THRESHOLD_TRAFFIC_DEFAULT	30	/* percent */
 
 #define IEEE80211_OCAC_OFFSET_TXHALT_MIN		2	/* milliseconds */
 #define IEEE80211_OCAC_OFFSET_TXHALT_MAX		80	/* milliseconds */
@@ -374,6 +383,13 @@
 #define IEEE80211_OCAC_TIMER_EXPIRE_INIT_MAX		65000	/* seconds */
 #define IEEE80211_OCAC_TIMER_EXPIRE_INIT_DEFAULT	2	/* seconds */
 
+#define	IEEE80211_OBSS_PASSIVE_DWELL_DEFAULT		20
+#define	IEEE80211_OBSS_ACTIVE_DWELL_DEFAULT		10
+#define	IEEE80211_OBSS_TRIGGER_INTERVAL_DEFAULT		200
+#define	IEEE80211_OBSS_PASSIVE_TOTAL_DEFAULT		200
+#define	IEEE80211_OBSS_ACTIVE_TOTAL_DEFAULT		20
+#define	IEEE80211_OBSS_CHANNEL_WIDTH_DELAY_DEFAULT	5
+#define	IEEE80211_OBSS_ACTIVITY_THRESHOLD_DEFAULT	25
 
 #define IEEE80211_OCAC_VALUE_S			0
 #define IEEE80211_OCAC_VALUE_M			0xffff
@@ -404,6 +420,7 @@
 #define	QTN_M2A_PS_EVENT_PS_POLL	4		/* ps poll */
 #define	QTN_M2A_EVENT_TYPE_UAPSD_SP	5		/* U-APSD SP */
 #define QTN_M2A_EVENT_PTID_FLAG_SET     6               /* Set per-TID flag(muc) */
+#define QTN_M2A_EVENT_TYPE_TXBA_DISABLE	7		/* per VAP TX BA est control */
 
 /* Common definitions for flags used to indicate ieee80211_node's states */
 #define	IEEE80211_NODE_AUTH		0x0001	/* authorized for data */
@@ -422,9 +439,12 @@
 #define IEEE80211_NODE_TPC		0x8000	/* indicate tpc capability */
 
 /* Common definitions for ext_flags */
-#define IEEE80211_NODE_TDLS_PTI_PENDING	0x0001	/* Should sending PTI request to peer */
-#define IEEE80211_NODE_TDLS_PTI_RESP	0x0002	/* PTI response frame received */
+#define IEEE80211_NODE_TDLS_PTI_REQ	0x0001	/* Should sending PTI request to peer */
+#define IEEE80211_NODE_TDLS_PTI_PENDING	0x0002	/* PTI request xmit to peer but not responsed */
 #define IEEE80211_NODE_UAPSD_SP_IN_PROGRESS	0x0004	/* U-APSD SP in progress */
+#define IEEE80211_NODE_TDLS_PTI_RESP	0x0008	/* PTI response frame received */
+
+#define	IEEE80211_NODE_TDLS_MASK	0x000B	/* Mask for TDLS bits */
 
 #define QTN_VAP_PRIORITY_RESERVED	2	/* reserve the low values for internal use */
 #define QTN_VAP_PRIORITY_NUM		4
@@ -435,27 +455,29 @@
 
 /* Quantenna specific flags (ni_qtn_flags), do not modify in Auc */
 #define QTN_IS_BCM_NODE			0x0000001
-#define QTN_IS_IPAD_NODE		0x0000002
-#define QTN_IS_IPHONE5_NODE		0x0000004
-#define QTN_IS_IPAD3_NODE		0x0000008
-#define QTN_IS_INTEL_5100_NODE		0x0000010
-#define QTN_IS_INTEL_5300_NODE		0x0000020
-#define QTN_IS_SAMSUNG_GALAXY_NODE	0x0000040
-#define QTN_IS_NOT_4ADDR_CAPABLE_NODE	0x0000080
-#define QTN_AC_BE_INHERITANCE_UPTO_VO	0x0000100
-#define QTN_AC_BE_INHERITANCE_UPTO_VI	0x0000200
-#define QTN_IS_INTEL_NODE		0x0000400
-#define QTN_IS_IPAD_AIR_NODE		0x0000800
-#define QTN_IS_IPAD4_NODE		0x0001000
-#define QTN_IS_REALTEK_NODE		0x0004000
-#define	QTN_NODE_TX_RESTRICTED		0x0008000 /* restricted tx enabled */
-#define	QTN_NODE_TX_RESTRICT_RTS	0x0010000 /* use RTS to confirm node is lost */
-#define QTN_IS_NO_RXAMSDU_NO_BF_NODE	0x0020000
-#define QTN_NODE_RXAMSDU_SUPPORT	0x0040000 /* node support TX amsdu */
-#define QTN_NODE_11N_TXAMSDU_OFF	0x0080000
-#define	QTN_NODE_TXOP_RESTRICTED	0x0100000
+#define QTN_IS_INTEL_5100_NODE		0x0000002
+#define QTN_IS_INTEL_5300_NODE		0x0000004
+#define QTN_IS_GALAXY_NOTE_4_NODE	0x0000008
+#define QTN_IS_NOT_4ADDR_CAPABLE_NODE	0x0000010
+#define QTN_AC_BE_INHERITANCE_UPTO_VO	0x0000020
+#define QTN_AC_BE_INHERITANCE_UPTO_VI	0x0000040
+#define QTN_IS_INTEL_NODE		0x0000080
+#define QTN_IS_REALTEK_NODE		0x0000100
+#define	QTN_NODE_TX_RESTRICTED		0x0000200 /* restricted tx enabled */
+#define	QTN_NODE_TX_RESTRICT_RTS	0x0000400 /* use RTS to confirm node is lost */
+#define QTN_IS_NO_RXAMSDU_NO_BF_NODE	0x0000800
+#define QTN_NODE_RXAMSDU_SUPPORT	0x0001000 /* node support TX amsdu */
+#define QTN_NODE_11N_TXAMSDU_OFF	0x0002000
+#define	QTN_NODE_TXOP_RESTRICTED	0x0004000
+/*
+ * Bits that can be updated again by Lhost after association creation. Explicit definition helps
+ * avoid overwriting bits maintained by MuC itself.
+ */
+#define QTN_FLAGS_UPDATABLE_BITS	(QTN_IS_INTEL_NODE)
 
-/* QTN bandwidth definition */
+/* QTN bandwidth definition - make sure this is up-to-date with regards
+ * to txbf_common.h
+ */
 #define QTN_BW_20M	0
 #define QTN_BW_40M	1
 #define QTN_BW_80M	2
@@ -545,11 +567,7 @@
  * 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.
  */
-#ifdef TOPAZ_PLATFORM
-	#define TOPAZ_QTM		1
-#else
-	#define TOPAZ_QTM		0
-#endif
+#define TOPAZ_QTM		1
 
 #define COMPILE_TIME_ASSERT(constant_expr)	\
 do {						\
@@ -628,6 +646,7 @@
 	SWFEAT_ID_VHT,
 	SWFEAT_ID_2X2,
 	SWFEAT_ID_2X4,
+	SWFEAT_ID_3X3,
 	SWFEAT_ID_4X4,
 	SWFEAT_ID_HS20,
 	SWFEAT_ID_WPA2_ENT,
@@ -654,4 +673,10 @@
 #define QDRV_TEMPSENS_COEFF    100000
 #define QDRV_TEMPSENS_COEFF10  (10 * QDRV_TEMPSENS_COEFF)
 
+/* Aligns the supplied size to the specified power_of_two */
+#define QTN_ALIGN_TO(size_to_align, power_of_two) \
+	(((size_to_align) + (power_of_two) - 1) & ~((power_of_two) - 1))
+
+#define FIELD_ARRAY_SIZE(t, a)	(sizeof((((t*)0)->a))/sizeof(((((t*)0)->a))[0]))
+
 #endif /* _SHARED_DEFS_H_ */
diff --git a/include/qtn/shared_defs_common.h b/include/qtn/shared_defs_common.h
index 16d2d4d..ef55d8c 100644
--- a/include/qtn/shared_defs_common.h
+++ b/include/qtn/shared_defs_common.h
@@ -144,6 +144,11 @@
 #define  QTN_TPZ_DBS					9	/* BBIC4 + RFIC6 */
 #define  QTN_TPZ_SE5502L				10	/* BBIC4 + RFIC5 */
 #define  QTN_TPZ_SKY85710_NG				11
+#define	 QTN_TPZ_DBS_5591				13	/* BBIC4 A2 + RFIC6 */
+#define	 QTN_TPZ_DBS_NXP_BGU7224_BGU7258		14	/* BBIC4 A2 + RFIC6  DBS support*/
+#define	 QTN_TPZ_2_4GHZ_NXP_BGU7224			15	/* BBIC4 A2 + RFIC6 2.4ghz only */
+#define	 QTN_TPZ_5GHZ_NXP_BGU7258			16	/* BBIC4 A2 + RFIC6 5ghz only */
+#define	 QTN_TPZ_5GHZ_SKY85728				17	/* BBIC4 A2 + RFIC4 5ghz only and BBIC4 A2 + RFIC6 5ghz only */
 
 #endif /* _SHARED_DEFS_COMMON_H_ */
 
diff --git a/include/qtn/shared_params.h b/include/qtn/shared_params.h
index 64eed8d..2b039c5 100644
--- a/include/qtn/shared_params.h
+++ b/include/qtn/shared_params.h
@@ -105,6 +105,7 @@
 #define HARDWARE_REVISION_TOPAZ_B	5
 #define HARDWARE_REVISION_TOPAZ_A2	6
 #define CHIP_ID_MASK			0xF0
+#define CHIP_ID_SW_MASK			0xC0	/* bits set in sw, for downgrade only */
 #define CHIP_REV_ID_MASK		0x0F
 
 #define HW_OPTION_BONDING_RUBY_PROD	(HARDWARE_REVISION_RUBY_D << 8)
@@ -113,24 +114,38 @@
 #define HW_OPTION_BONDING_RUBY_4SS	(HW_OPTION_BONDING_RUBY_PROD | 0x00000002)
 
 #define HW_PLAT_TOPAZ_QV860		0x00
+#define HW_PLAT_TOPAZ_QV860_2X2		0x80	/* downgrade only */
+#define HW_PLAT_TOPAZ_QV860_2X4		0x40	/* downgrade only */
+#define HW_PLAT_TOPAZ_QV860_3X3		0xF0	/* downgrade only */
 #define HW_PLAT_TOPAZ_QD840		0x01
 #define HW_PLAT_TOPAZ_QV880		0x32
+#define HW_PLAT_TOPAZ_QV880_2X2		0xb2	/* downgrade only */
+#define HW_PLAT_TOPAZ_QV880_2X4		0x72	/* downgrade only */
+#define HW_PLAT_TOPAZ_QV880_3X3		0xF2	/* downgrade only */
 #define HW_PLAT_TOPAZ_QV920		0x03
+#define HW_PLAT_TOPAZ_QV920_2X4		0x43	/* downgrade only */
 #define HW_PLAT_TOPAZ_QV840		0x04
+#define HW_PLAT_TOPAZ_QV840_2X4		0x44	/* downgrade only */
 #define HW_PLAT_TOPAZ_QV940		0x05
 #define HW_PLAT_TOPAZ_QV840C		0x06
-#define HW_PLAT_TOPAZ_QV950		0x07
 
 #define HW_OPTION_BONDING_TOPAZ_PROD	(HARDWARE_REVISION_TOPAZ_B << 8)
 enum hw_opt_t {
 	HW_OPTION_BONDING_TOPAZ_QV860 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV860),
+	HW_OPTION_BONDING_TOPAZ_QV860_2X2 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV860_2X2),
+	HW_OPTION_BONDING_TOPAZ_QV860_2X4 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV860_2X4),
+	HW_OPTION_BONDING_TOPAZ_QV860_3X3 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV860_3X3),
 	HW_OPTION_BONDING_TOPAZ_QD840 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QD840),
 	HW_OPTION_BONDING_TOPAZ_QV880 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV880),
+	HW_OPTION_BONDING_TOPAZ_QV880_2X2 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV880_2X2),
+	HW_OPTION_BONDING_TOPAZ_QV880_2X4 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV880_2X4),
+	HW_OPTION_BONDING_TOPAZ_QV880_3X3 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV880_3X3),
 	HW_OPTION_BONDING_TOPAZ_QV920 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV920),
+	HW_OPTION_BONDING_TOPAZ_QV920_2X4 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV920_2X4),
 	HW_OPTION_BONDING_TOPAZ_QV840 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV840),
+	HW_OPTION_BONDING_TOPAZ_QV840_2X4 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV840_2X4),
 	HW_OPTION_BONDING_TOPAZ_QV940 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV940),
 	HW_OPTION_BONDING_TOPAZ_QV840C = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV840C),
-	HW_OPTION_BONDING_TOPAZ_QV950 = (HW_OPTION_BONDING_TOPAZ_PROD | HW_PLAT_TOPAZ_QV950)
 };
 
 #define HW_OPTION_BONDING_NOT_SET	0xFFFFFFFF
@@ -139,6 +154,8 @@
 {
 	u_int32_t		tqe_sem_en; /*replaced for TQE SWR lh_flags; */
 	u_int16_t		lh_chip_id;
+	u_int8_t		rf_chip_id;
+	u_int8_t		vco_lock_detect_mode;
 	u_int8_t		lh_wifi_hw;
 	u_int8_t		lh_num_devices;
 	u_int8_t		lh_mac_0[ IEEE80211_ADDR_LEN ];
@@ -173,21 +190,11 @@
 #define QTN_IOT_BCM_MBA_AMSDU_TWEAK	0x00000200   /* MBA doesn't work with 7.9k AMSDU with security mode */
 #define QTN_IOT_RLNK_NO_3SS_MCS_TWEAK	0x00000400   /* Disable 3ss MCS for Ralink clients */
 #define QTN_IOT_RTK_NO_AMSDU_TWEAK	0x00000800   /* Disable A-MSDU for Realtek devices */
-#ifndef TOPAZ_PLATFORM
-#define QTN_IOT_DEFAULT_TWEAK		(QTN_IOT_INTEL5100_TWEAK | \
-					 QTN_IOT_INTEL6200_TWEAK | \
-					 QTN_IOT_INTEL6300_TWEAK | \
-					 QTN_IOT_INTEL_SEND_NCW_ACTION | \
-					 QTN_IOT_BCM_NO_3SS_MCS_TWEAK | \
-					 QTN_IOT_RLNK_NO_3SS_MCS_TWEAK \
-					)
-#else
 #define QTN_IOT_DEFAULT_TWEAK		(QTN_IOT_BCM_MBA_AMSDU_TWEAK | \
 					 QTN_IOT_BCM_AMSDU_DUTY_TWEAK | \
 					 QTN_IOT_RLNK_NO_3SS_MCS_TWEAK | \
 					 QTN_IOT_RTK_NO_AMSDU_TWEAK \
 					)
-#endif
 	uint32_t		iot_tweaks;
 
 	struct qtn_txbf_mbox*	txbf_mbox_lhost;
@@ -216,6 +223,9 @@
 	struct qtn_ocac_info*	ocac_lhost;
 	struct qtn_ocac_info*	ocac_bus;
 
+	struct qtn_bmps_info*	bmps_lhost;
+	struct qtn_bmps_info*	bmps_bus;
+
 	struct qtn_meas_chan_info*	chan_meas_lhost;
 	struct qtn_meas_chan_info*	chan_meas_bus;
 
@@ -224,13 +234,12 @@
 	struct qtn_sem_trace_log *sem_trace_log_bus;
 #endif
 
-#ifdef TOPAZ_PLATFORM
-	uint8_t	*vlan_bitmap_lhost;
-	uint8_t	*vlan_bitmap_bus;
-	int	*vlan_enabled_lhost;
-	int	*vlan_enabled_bus;
+	struct qtn_vlan_dev **vdev_lhost;
+	struct qtn_vlan_dev **vdev_bus;
+	struct qtn_vlan_dev **vport_lhost;
+	struct qtn_vlan_dev **vport_bus;
 	struct topaz_ipmac_uc_table *ipmac_table_bus;
-#endif
+	struct qtn_vlan_info *vlan_info;
 
 #if CONFIG_RUBY_BROKEN_IPC_IRQS
 	u_int32_t		m2l_irq[2];
@@ -253,10 +262,8 @@
 #define QTN_FW_VERSION_LENGTH	32
 	char			fw_version[QTN_FW_VERSION_LENGTH + 1];
 #ifndef SYSTEM_BUILD
-#ifdef TOPAZ_PLATFORM
 	shared_params_auc	auc;
 #endif
-#endif
 
 	int			cca_adjusting_flag;
 	int			active_tid_num;
@@ -264,6 +271,7 @@
 	uint32_t		cs_thresh_base_val;	/* Carrier sense threshold base value */
 	uint32_t		qtn_hal_pm_corrupt;
 	uint32_t		qtn_hal_pm_corrupt_debug;
+	uint32_t                free_airtime;		/* in ms */
 } shared_params;
 
 #define QTN_RATE_TRAIN_DATA_LEN		64
diff --git a/include/qtn/skb_recycle.h b/include/qtn/skb_recycle.h
index aaae2ec..b3f7494 100644
--- a/include/qtn/skb_recycle.h
+++ b/include/qtn/skb_recycle.h
@@ -41,16 +41,12 @@
 #define SKB_RECYCLE_STAT(x)
 #endif
 
-#if defined(TOPAZ_PLATFORM)
 #define QTN_SKB_RECYCLE_ENABLE		0
-#else
-#define QTN_SKB_RECYCLE_ENABLE		1
-#endif
 
 /**
  * \addtogroup LHOST_STATS
  */
-/* @{ */
+/** @{ */
 
 /**
  * \brief Linux SKB recycle statistics.
@@ -97,7 +93,7 @@
 	 */
 	u32 alloc_kmalloc;
 };
-/* @} */
+/** @} */
 
 struct qtn_skb_recycle_list {
 	struct sk_buff_head list;			/* Shared buffers between wireless and Ethernet driver */
diff --git a/include/qtn/topaz_congest_queue.h b/include/qtn/topaz_congest_queue.h
index 36a6bc5..f97c6cd 100644
--- a/include/qtn/topaz_congest_queue.h
+++ b/include/qtn/topaz_congest_queue.h
@@ -29,7 +29,7 @@
 /* Maximum number of packets in all congest queues */
 #define TOPAZ_CONGEST_TOTAL_PKT_MAX	(2048)
 /* Maximum number of congest queue for unicast frame */
-#define TOPAZ_CONGEST_QUEUE_UNICAST_NUM	(1)
+#define TOPAZ_CONGEST_MAX_UNICAST_QCOUNT	(3)
 
 /* Budget for packet number consmued at softirq at one time */
 #define TOPAZ_SOFTIRQ_BUDGET  8
@@ -37,6 +37,9 @@
 #define TOPAZ_PCIE_NODE_MAX	(128)
 #define TOPAZ_PCIE_TID_MAX	(16)
 
+#define TOPAZ_CONGEST_QUEUE_STATS_QLEN		0
+#define TOPAZ_CONGEST_QUEUE_STATS_ENQFAIL	1
+
 struct topaz_congest_q_elem {
 	union topaz_tqe_cpuif_ppctl ppctl;
 };
@@ -57,7 +60,6 @@
 	uint32_t congest_drop;	/* Packet number dropped due to transmission time-out */
 	uint32_t congest_enq_fail;	/* packet number dropped due to enqueue failure */
 
-	uint32_t last_retry_stamp;
 	uint32_t last_retry_success;	/* 0: Fail, 1: Success */
 	unsigned long retry_timeout;
 	uint32_t is_unicast;
@@ -81,6 +83,7 @@
 	/* Counters */
 	uint32_t func_entry;	/* tasklet hook function called count */
 	uint32_t cnt_retries;	/* tried times on triggering to TQE */
+	uint32_t xmit_entry;
 
 	int logs[TOPAZ_CONGEST_PKT_MAX]; /* Used to check queue fullness */
 
@@ -90,6 +93,7 @@
 	uint32_t total_qlen;	/* Total number of pending requests in all queues*/
 
 	uint32_t unicast_qcount;	/* Total congest queue count of unicast frame */
+	uint32_t max_unicast_qcount;	/* Max unicast congest queue count*/
 };
 
 struct qdrv_tqe_cgq {
@@ -141,9 +145,11 @@
 
 extern int topaz_congest_queue_xmit(struct topaz_congest_q_desc *queue, uint32_t budget);
 
-extern void reg_congest_queue_stats(void (*fn)(void *, uint8_t, uint32_t), void *ctx);
+extern void reg_congest_queue_stats(void (*fn)(void *, uint32_t, uint8_t, uint32_t), void *ctx);
 
 extern struct topaz_congest_queue* topaz_congest_queue_get(void);
 
 extern void topaz_hbm_congest_queue_put_buf(const union topaz_tqe_cpuif_ppctl *ppctl);
+
+extern void topaz_congest_set_unicast_queue_count(uint32_t qnum);
 #endif
diff --git a/include/qtn/topaz_dpi.h b/include/qtn/topaz_dpi.h
index 751fd4c..b96228c 100644
--- a/include/qtn/topaz_dpi.h
+++ b/include/qtn/topaz_dpi.h
@@ -28,8 +28,6 @@
 #include <linux/in6.h>
 #include <compat.h>
 
-#ifdef TOPAZ_PLATFORM
-
 struct topaz_dpi_field_def {
 	uint32_t val;
 	uint32_t mask;
@@ -94,7 +92,5 @@
 	topaz_dpi_iptuple_poll_complete(base);
 }
 
-#endif	/* TOPAZ_PLATFORM */
-
 #endif	/* __TOPAZ_DPI_H */
 
diff --git a/include/qtn/topaz_fwt.h b/include/qtn/topaz_fwt.h
index 0cb1afa..338815d 100644
--- a/include/qtn/topaz_fwt.h
+++ b/include/qtn/topaz_fwt.h
@@ -7,8 +7,6 @@
 
 #include <qtn/topaz_fwt_cpuif.h>
 
-#ifdef TOPAZ_PLATFORM
-
 typedef void (*fwt_notify_swap )( uint16_t dst_index, uint16_t src_index);
 
 /*
@@ -47,7 +45,6 @@
 
 int topaz_fwt_get_timestamp(uint16_t index);
 int topaz_fwt_init(void);
-#endif	/* TOPAZ_PLATFORM */
 
 #endif	/* __TOPAZ_FWT_H */
 
diff --git a/include/qtn/topaz_fwt_cpuif.h b/include/qtn/topaz_fwt_cpuif.h
index 344d962..f42926b 100644
--- a/include/qtn/topaz_fwt_cpuif.h
+++ b/include/qtn/topaz_fwt_cpuif.h
@@ -247,9 +247,38 @@
 	uint8_t port_bitmap;
 	uint8_t flood_forward;
 	uint8_t seen;
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+	uint8_t dev_bitmap;
+#else
 	uint8_t __pad[1];
+#endif
 };
 
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+RUBY_INLINE int topaz_fwt_sw_mcast_dev_is_set(struct topaz_fwt_sw_mcast_entry *const e,
+						const uint8_t dev_id)
+{
+	return (e->dev_bitmap & (1 << dev_id));
+}
+
+RUBY_INLINE int topaz_fwt_sw_mcast_dev_is_empty(struct topaz_fwt_sw_mcast_entry *const e)
+{
+	return (e->dev_bitmap == 0);
+}
+
+RUBY_INLINE void topaz_fwt_sw_mcast_dev_set(struct topaz_fwt_sw_mcast_entry *const e,
+						const uint8_t dev_id)
+{
+	e->dev_bitmap |= (1 << dev_id);
+}
+
+RUBY_INLINE void topaz_fwt_sw_mcast_dev_clear(struct topaz_fwt_sw_mcast_entry *const e,
+						const uint8_t dev_id)
+{
+	e->dev_bitmap &= ~(1 << dev_id);
+}
+#endif
+
 struct topaz_fwt_sw_alias_table {
 	int16_t mcast_entry_index[TOPAZ_FWT_SW_IP_ALIAS_ENTRIES];
 };
@@ -565,6 +594,33 @@
 	return zero_lookup;
 }
 
+RUBY_INLINE union topaz_fwt_lookup topaz_fwt_hw_lookup_wait_be(const uint8_t *mac_be, int *timeout, uint8_t *false_miss)
+{
+#ifndef TOPAZ_DISABLE_FWT_WAR
+	/*
+	 * This is to workaround the FWT lookup false issue:
+	 * It seems when EMAC is under heavy VLAN traffic, Lhost and MuC
+	 * may get false miss from FWT -- FWT returns invalid while a MAC
+	 * address truly exists in it. A double check reduces count of false
+	 * misses significantly.
+	 */
+	uint8_t retries = 1;
+#else
+	uint8_t retries = 0;
+#endif
+	union topaz_fwt_lookup u;
+
+	do {
+		u = __topaz_fwt_hw_lookup_wait_be(mac_be, timeout);
+	} while (!u.data.valid && retries--);
+
+#if !defined(TOPAZ_DISABLE_FWT_WAR) && !defined(MUC_BUILD)
+	*false_miss += (retries == 0);
+#endif
+
+	return u;
+}
+
 RUBY_INLINE uint32_t __topaz_fwt_cpu_access_rd(void)
 {
 	return qtn_mproc_sync_mem_read(TOPAZ_FWT_CPU_ACCESS);
diff --git a/include/qtn/topaz_fwt_db.h b/include/qtn/topaz_fwt_db.h
index 7c2834b..9f47d16 100644
--- a/include/qtn/topaz_fwt_db.h
+++ b/include/qtn/topaz_fwt_db.h
@@ -5,7 +5,6 @@
 #ifndef FWT_DB_H_
 #define FWT_DB_H_
 
-#ifdef TOPAZ_PLATFORM
 
 #ifndef CONSOLE_TEST
 #include <linux/types.h>
@@ -20,15 +19,6 @@
 #include <qtn/topaz_tqe_cpuif.h>
 #include <qtn/topaz_fwt_cpuif.h>
 #include <qtn/qtn_net_packet.h>
-#else
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include "unitest_fwt.h"
-#include "queue.h"
-#endif
 
 typedef enum
 {
@@ -59,9 +49,15 @@
 	uint8_t out_node;
 	int16_t fwt_index;
 	int16_t alias_table_index;
+	uint32_t false_miss;
 	uint8_t portal	:1,
 		valid	:1,
+#ifdef CONFIG_TOPAZ_DBDC_HOST
+		mcast	:1,
+		dev_id  :DEV_ID_BITS;
+#else
 		mcast	:1;
+#endif
 } fwt_db_entry;
 
 /* node list indexed by the fwt */
@@ -130,6 +126,10 @@
 	}
 }
 
+fwt_db_node_element *fwt_db_create_node_element(void);
+void fwt_db_free_node_element(fwt_db_node_element *node_element);
+int fwt_db_is_node_exists_list(uint8_t node_index, uint16_t table_index,
+		uint8_t ip_alias, uint8_t port);
 /*
  * Initialise the fwt_db database
  */
@@ -147,13 +147,20 @@
  * Print FWT Database to console
  * @return number of existing valid entries
  */
-int fwt_db_print(bool is_mult);
+int fwt_db_print(int is_mult);
 
 /*
  * Print FWT node hash lise to console
  * @return number of existing valid entries
  */
 int fwt_db_node_table_print(void);
+
+/*
+ * Print the FWT multicast entries to a buffer
+ * @return number of bytes written
+ */
+int fwt_db_get_mc_list(char *buf, int buflen);
+
 /*
  * Calculate ageing time by the FWT HW timestamp
  * @Param fwt_index: FWT table index
@@ -192,8 +199,8 @@
  * @param node_num:
  * @param table_index: the HW FWT table index
  */
-int fwt_db_add_new_node(uint8_t node_num, uint16_t table_index,
-		const struct br_ip *group, uint8_t port);
+void fwt_db_add_new_node(uint8_t node_num, uint16_t table_index,
+		const int8_t ip_alias, uint8_t port, fwt_db_node_element *const new_element);
 
 /* Remove specific node from the hash list,
  * Note: does not involve removing node from the fwt table.
@@ -244,7 +251,7 @@
  * Return the existing entry if present, otherwise create a new multicast entry
  */
 struct topaz_fwt_sw_mcast_entry *fwt_db_get_or_add_sw_mcast(struct fwt_db_entry *db,
-		const struct br_ip *group);
+		int8_t ip_alias);
 
 /*
  * Free multicast entry, and possibly the alias_table if it becomes empty.
@@ -252,6 +259,17 @@
  */
 int fwt_db_delete_sw_mcast(struct fwt_db_entry *db, uint8_t ipmap_index);
 
+/*
+ * Get mac addresses of nondes behind associated node
+ * @param index: node index
+ * @param num_entries: returns number of entries found
+ * @param max_req: maximum entries requested
+ * @param flags: bit 0 - results overflowed/truncated, bit 1 - 4addr node
+ * @param buf: buffer to store macs
+ */
+int fwt_db_get_macs_behind_node(const uint8_t index, uint32_t *num_entries, uint32_t max_req,
+					uint32_t *flags, uint8_t *buf);
+
 #endif // TOPAZ PLATFORM
 
 #endif /* FWT_DB_H_ */
diff --git a/include/qtn/topaz_fwt_if.h b/include/qtn/topaz_fwt_if.h
index 43cf2f5..746e275 100644
--- a/include/qtn/topaz_fwt_if.h
+++ b/include/qtn/topaz_fwt_if.h
@@ -43,14 +43,17 @@
 #ifndef FWT_INTERFACE_H_
 #define FWT_INTERFACE_H_
 
-#ifdef TOPAZ_PLATFORM
 #include <qtn/br_types.h>
 
+/* Must match FWT_IF_KEY_xxx macros */
 typedef enum fwt_if_usr_cmd {
 	FWT_IF_CMD_CLEAR = 0,
 	FWT_IF_CMD_ON,
 	FWT_IF_CMD_OFF,
 	FWT_IF_CMD_PRINT,
+	FWT_IF_CMD_ADD_STATIC_MC,
+	FWT_IF_CMD_DEL_STATIC_MC,
+	FWT_IF_CMD_GET_MC_LIST,
 	FWT_IF_CMD_ADD,
 	FWT_IF_CMD_DELETE,
 	FWT_IF_CMD_AUTO,
@@ -71,16 +74,16 @@
 	struct br_ip ip;
 };
 
-struct fwt_if_common{
+struct fwt_if_common {
 	struct fwt_if_id id;
 	uint8_t port;
 	uint8_t node[FWT_IF_USER_NODE_MAX];
-	uint8_t param;
+	uint32_t param;
+	void *extra;
 };
 
 typedef int (*fwt_if_sw_cmd_hook)(fwt_if_usr_cmd cmd, struct fwt_if_common *data);
 
 void fwt_if_register_cbk_t(fwt_if_sw_cmd_hook cbk_func);
 
-#endif /* TOPAZ PLATFORM */
 #endif /* FWT_INTERFACE_H_ */
diff --git a/include/qtn/topaz_fwt_sw.h b/include/qtn/topaz_fwt_sw.h
index 22700db..739413f 100644
--- a/include/qtn/topaz_fwt_sw.h
+++ b/include/qtn/topaz_fwt_sw.h
@@ -5,7 +5,6 @@
 #ifndef FWT_SW_H_
 #define FWT_SW_H_
 
-#ifdef TOPAZ_PLATFORM
 
 #include <linux/types.h>
 #include <qtn/topaz_fwt_db.h>
@@ -127,6 +126,16 @@
 
 int fwt_sw_get_index_from_mac_be(const uint8_t *mac_be);
 
+/*
+ * Fast way to get fwt entry for unicast packet
+ * @param src_mac_be: source mac address of the packet
+ * @param dst_mac_be: destination mac address of the packet
+ */
+fwt_db_entry *fwt_sw_fast_get_ucast_entry(const unsigned char *src_mac_be,
+		const unsigned char *dst_mac_be);
+
+void fwt_sw_update_false_miss(int index, uint8_t false_miss);
+
 int fwt_sw_get_ipff(char *buf, int buflen);
 
 extern dma_addr_t ipmac_hash_bus;
@@ -136,6 +145,4 @@
 
 void fwt_sw_remove_uc_ipmac(const uint8_t *ip, uint16_t type);
 
-#endif /* TOPAZ PLATFORM */
-
 #endif /* FWT_INTERFACE_H_ */
diff --git a/include/qtn/topaz_hbm.h b/include/qtn/topaz_hbm.h
index 0d06401..e9548cd 100644
--- a/include/qtn/topaz_hbm.h
+++ b/include/qtn/topaz_hbm.h
@@ -30,10 +30,13 @@
 #include <qtn/dmautil.h>
 #include <asm/cacheflush.h>
 
-#define topaz_hbm_attach_skb(buf_virt, pool)		\
-	_topaz_hbm_attach_skb((buf_virt), (pool)	\
+#define topaz_hbm_attach_skb(buf_virt, pool, headroom)		\
+	_topaz_hbm_attach_skb((buf_virt), (pool), 1, (headroom)	\
 			QTN_SKB_ALLOC_TRACE_ARGSRC)
-struct sk_buff *_topaz_hbm_attach_skb(void *buf_virt, int8_t pool
+#define topaz_hbm_attach_skb_no_invalidate(buf_virt, pool, headroom)		\
+	_topaz_hbm_attach_skb((buf_virt), (pool), 0, (headroom) 	\
+			QTN_SKB_ALLOC_TRACE_ARGSRC)
+struct sk_buff *_topaz_hbm_attach_skb(void *buf_virt, int8_t pool, int inv, uint8_t headroom
 		QTN_SKB_ALLOC_TRACE_ARGS);
 
 #define topaz_hbm_attach_skb_bus(buf_bus, pool)	\
@@ -54,7 +57,7 @@
 		return NULL;
 	}
 
-	return _topaz_hbm_attach_skb(buf_virt, pool
+	return _topaz_hbm_attach_skb(buf_virt, pool, 1, 0
 			QTN_SKB_ALLOC_TRACE_ARGVARS);
 }
 
diff --git a/include/qtn/topaz_hbm_cpuif.h b/include/qtn/topaz_hbm_cpuif.h
index 7a63cc0..daf2609 100644
--- a/include/qtn/topaz_hbm_cpuif.h
+++ b/include/qtn/topaz_hbm_cpuif.h
@@ -81,7 +81,7 @@
 #define TOPAZ_HBM_BUF_EXTERNAL_META		1	/* move meta data outside of buffer */
 #define TOPAZ_HBM_BUF_WMAC_RX_QUARANTINE	1	/* quarantine wmac rx buffers when deliver important packets */
 
-#if defined(CONFIG_TOPAZ_PCIE_TARGET)
+#if defined(CONFIG_TOPAZ_PCIE_TARGET) || defined(CONFIG_TOPAZ_DBDC_HOST)
 /*
  * Checking emac rx pool buffers lead to performance impact in PCIe, so limit
  * the check for wmac rx pool only.
@@ -301,8 +301,6 @@
 			align_virt ? (void *)virt_to_bus(align_virt) : NULL);
 }
 
-#if defined(TOPAZ_PLATFORM)
-
 RUBY_INLINE int __topaz_hbm_is_done(void)
 {
 	return qtn_mproc_sync_mem_read(TOPAZ_HBM_POOL_REQ(TOPAZ_HBM_LOCAL_CPU)) & TOPAZ_HBM_DONE;
@@ -385,7 +383,11 @@
 	__topaz_hbm_release_buf(buf, pool);
 }
 
+#if defined(MUC_BUILD)
+RUBY_INLINE void topaz_hbm_put_buf(void *buf, uint8_t pool)
+#else
 RUBY_WEAK(topaz_hbm_put_buf) void topaz_hbm_put_buf(void *buf, uint8_t pool)
+#endif
 {
 	unsigned long flags;
 
@@ -402,7 +404,11 @@
 	return __topaz_hbm_rd_buf(pool);
 }
 
+#if defined(MUC_BUILD)
+RUBY_INLINE void *topaz_hbm_get_buf(uint8_t pool)
+#else
 RUBY_WEAK(topaz_hbm_get_buf) void *topaz_hbm_get_buf(uint8_t pool)
+#endif
 {
 	unsigned long flags;
 	void *buf;
@@ -428,10 +434,6 @@
 	qtn_mproc_sync_mem_write_wmb(TOPAZ_HBM_CSR_REG, csr | TOPAZ_HBM_CSR_Q_EN(pool));
 }
 
-#endif	/* defined(TOPAZ_PLATFORM) */
-
-#if defined(TOPAZ_PLATFORM) || defined(RUBY_SOFTWARE_HBM)
-
 RUBY_INLINE uint32_t topaz_hbm_pool_buf_whole_size(int8_t pool)
 {
 	if (pool == TOPAZ_HBM_BUF_EMAC_RX_POOL) {
@@ -788,5 +790,4 @@
 #define topaz_hbm_debug_stamp(_buf, _port, _size)
 #endif /* TOPAZ_HBM_DEBUG_STAMPS */
 
-#endif	/* defined(TOPAZ_PLATFORM) || defined(RUBY_SOFTWARE_HBM) */
 #endif	/* __TOPAZ_HBM_CPUIF_PLATFORM_H */
diff --git a/include/qtn/topaz_ipprt.h b/include/qtn/topaz_ipprt.h
index ee6b07f..206f344 100644
--- a/include/qtn/topaz_ipprt.h
+++ b/include/qtn/topaz_ipprt.h
@@ -26,8 +26,6 @@
 #include <common/topaz_emac.h>
 #include <qtn/mproc_sync_base.h>
 
-#ifdef TOPAZ_PLATFORM
-
 union topaz_ipprt_entry {
 	uint32_t raw;
 	struct {
@@ -90,6 +88,5 @@
 	return 0;
 }
 
-#endif	/* TOPAZ_PLATFORM */
 #endif	/* __TOPAZ_IPPROTO_TABLE_H */
 
diff --git a/include/qtn/topaz_qfp.h b/include/qtn/topaz_qfp.h
new file mode 100644
index 0000000..f15a2e9
--- /dev/null
+++ b/include/qtn/topaz_qfp.h
@@ -0,0 +1,143 @@
+/*
+ * (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
+ */
+
+#ifndef __TOPAZ_QFP_H__
+#define __TOPAZ_QFP_H__
+
+
+#define ioremap ioremap_nocache
+
+/**
+ * \brief Initialize topaz PCIe QFP interface.
+ *
+ * Initialize topaz PCIe QFP interface. This function should be called before
+ * any other QFP API call.
+ *
+ * \param pci_dev pci_dev pci_dev structure point to PCIe adapter
+ * \param msi flag for using legacy interrupt (0) or MSI (1)
+ *
+ * \return 0 on success.
+ *
+ */
+extern int qfp_init(struct pci_dev * pci_dev, int msi);
+
+/**
+ * \brief De-initialize topaz PCIe QFP interface.
+ *
+ * De-initialize topaz PCIe QFP interface.
+ *
+ * \param pci_dev pci_dev pci_dev structure point to PCIe adapter
+ * \param msi flag for using legacy interrupt (0) or MSI (1)
+ *
+ *
+ */
+extern void qfp_deinit(struct pci_dev * pci_dev, int msi);
+
+/**
+ * \brief register master netdev to QFP
+ *
+ * Register master netdev to QFP. After calling this function, packets received
+ * or transmit through this netdef will be accelerated by QFP.
+ *
+ * The caller should call this function right before calling register_netdev()
+ * for the master netdev.
+ *
+ * \param netdev pointer to master netdev
+ *
+ * \return 0 on success and other for failure
+ */
+extern int qfp_register_netdev(struct net_device * net_dev);
+
+/**
+ * \brief un-register master netdev from QFP
+ *
+ * Un-register master netdev from QFP.
+ *
+ * The caller should call this function right after calling unregister_netdev()
+ * for the master netdev.
+ *
+ * \param netdev pointer to master netdev
+ *
+ * \return 0 on success and other for failure
+ */
+extern void qfp_unregister_netdev(struct net_device * net_dev);
+
+/**
+ * \brief register virtual netdev to QFP
+ *
+ * Register virtual netdev to QFP. After calling this function, packets
+ * received or transmit through this netdef will be accelerated by QFP. This
+ * function is used to create virtual netdev for VAP.
+ *
+ * The caller should call this function right before calling register_netdev()
+ * for the virtual netdev.
+ *
+ * \param netdev pointer to virtual netdev
+ *
+ * \return 0 on success and other for failure
+ */
+extern int qfp_register_virtual_netdev(struct net_device * net_dev);
+
+/**
+ * \brief un-register virtual netdev from QFP
+ *
+ * Un-register virtual netdev from QFP.
+ *
+ * The caller should call this function right after calling unregister_netdev()
+ * for the virtual netdev.
+ *
+ * \param netdev pointer to virtual netdev
+ *
+ * \return 0 on success and other for failure
+ */
+extern void qfp_unregister_virtual_netdev(struct net_device * net_dev);
+
+/**
+ * \brief allocate skb.
+ *
+ * Allocate a skb from QFP, and all skb will be received to QFP must allocate by
+ * calling this function. The caller should call this function instead of any
+ * linux skb allocation function for RX packets.
+ *
+ * \param size max size of bytes for payload of skb
+ *
+ * \return pointer to a skb or NULL for failure
+ */
+extern struct sk_buff * qfp_alloc_skb(unsigned int size);
+
+/**
+ * \brief Receive skb to QFP.
+ *
+ * Received a skb which allocate by calling qfp_alloc_skb() to QFP. The caller
+ * should call this function instead of calling netif_rx() or netif_receive_skb()
+ * The caller loses reference to the skb when this function return successfu. And
+ * caller should still call netif_rx() or netif_receive_skb() when this function
+ * return failure.
+ *
+ * \param skb pointer to skb need to received to QFP
+ *
+ * \return 0 on success; -1 on failure
+ */
+extern int qfp_rx(struct sk_buff * skb);
+
+#endif
+
diff --git a/include/qtn/topaz_shared_params.h b/include/qtn/topaz_shared_params.h
index b19c2c3..a673848 100644
--- a/include/qtn/topaz_shared_params.h
+++ b/include/qtn/topaz_shared_params.h
@@ -49,6 +49,7 @@
 
 #include <qtn/mproc_sync_mutex.h>
 #include <qtn/qtn_uc_comm.h>
+#include <qtn/qtn_wmm_ac.h>
 
 enum shared_params_auc_ipc_cmd
 {
@@ -75,14 +76,9 @@
 	SHARED_PARAMS_IPC_M2A_PAUSE_OFF_CMD,
 	SHARED_PARAMS_IPC_M2A_NODE_RATEDATA_CHANGE_CMD,
 	SHARED_PARAMS_IPC_M2A_FCS_GIVE_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_FIRST_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_SRESET_RECOVER_CMD = SHARED_PARAMS_IPC_M2A_RCV_FIRST_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_CLEAN_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_REPLENISH_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_DBG_CMD,
-	SHARED_PARAMS_IPC_M2A_RCV_LAST_CMD,
 	SHARED_PARAMS_IPC_M2A_OCS_TX_SUSPEND_CMD,
 	SHARED_PARAMS_IPC_M2A_TQEW_DESCR_LIMIT_CMD,
+	SHARED_PARAMS_IPC_M2A_ENABLE_VLAN_CMD,
 	SHARED_PARAMS_IPC_M2A_MU_GRP_UPDATE_CMD,
 	SHARED_PARAMS_IPC_M2A_MU_QMAT_UPDATE_CMD,
 	SHARED_PARAMS_IPC_M2A_MU_DBG_FLAG_UPDATE_CMD,
@@ -96,6 +92,8 @@
 	SHARED_PARAMS_IPC_A2M_AUC_BOOTED_CMD,
 	SHARED_PARAMS_IPC_A2M_BA_ADD_START_CMD,
 	SHARED_PARAMS_IPC_A2M_PANIC,
+	SHARED_PARAMS_IPC_A2M_TDLS_PTI_CMD,
+	SHARED_PARAMS_IPC_A2M_BB_RESET,
 #if QTN_HDP_MU_FCS_WORKROUND
 	SHARED_PARAMS_IPC_A2M_PUSH_WMAC1_FCS,
 #endif
@@ -217,6 +215,7 @@
 	uint32_t arg1;
 	uint32_t arg2;
 	uint32_t arg3;
+	uint32_t ret;
 } shared_params_auc_ipc;
 
 struct qtn_auc_per_node_data_s;
@@ -238,6 +237,11 @@
 
 	uint32_t qtn_tx_mcast; /* Lhost */
 	uint32_t qtn_muc_tx_mcast; /* Muc */
+	/*
+	 * The number of dropped data packets failed to transmit through
+	 * wireless media for each traffic category(TC).
+	 */
+	uint32_t qtn_tx_drop_data_msdu[WMM_AC_NUM]; /* AuC */
 } qtn_shared_node_stats_t;
 
 typedef struct qtn_shared_vap_stats {
@@ -282,11 +286,11 @@
 	uint32_t				*auc_last_ilink2_p;
 	qtn_shared_node_stats_t			*node_stats;
 	qtn_shared_vap_stats_t			*vap_stats;
-	uint8_t					*vlan_bitmap;
-	int					*vlan_enabled;
 	uint32_t				*per_ac_traffic_prev_second;
 	struct qtn_auc_mu_grp_tbl_elem_s	*mu_grp_tbl;
-	struct qtn_hal_tcm                      *hal_wmac1_tcm;	
+	struct qtn_hal_tcm                      *hal_wmac1_tcm;
+	struct qtn_vlan_dev			**vdev_bus;
+	struct qtn_vlan_dev			**vport_bus;
 } shared_params_auc;
 
 RUBY_INLINE void
@@ -302,6 +306,7 @@
 	ipc->arg1 = arg1;
 	ipc->arg2 = arg2;
 	ipc->arg3 = arg3;
+	ipc->ret = 0;
 }
 
 RUBY_INLINE uint32_t
diff --git a/include/qtn/topaz_tqe.h b/include/qtn/topaz_tqe.h
index 0aad47e..0cce989 100644
--- a/include/qtn/topaz_tqe.h
+++ b/include/qtn/topaz_tqe.h
@@ -27,7 +27,6 @@
 #include <linux/netdevice.h>
 #include <qtn/topaz_tqe_cpuif.h>
 
-#ifdef TOPAZ_PLATFORM
 
 typedef void (*tqe_port_handler)(void *token,
 		const union topaz_tqe_cpuif_descr *descr,
@@ -38,16 +37,23 @@
 					uint8_t vap_idx);
 typedef const struct fwt_db_entry*(
 		*tqe_fwt_get_ucast_hook)(const unsigned char *src_mac_be, const unsigned char *dst_mac_be);
+typedef const struct fwt_db_entry*(
+		*tqe_fwt_get_from_mac_hook)(const unsigned char *mac_be);
+typedef int(*tqe_mac_reserved_hook)(const uint8_t *addr);
 typedef struct topaz_fwt_sw_mcast_entry*(
 		*tqe_fwt_get_mcast_ff_hook)(uint8_t vap_idx);
 typedef void(*tqe_fwt_set_mcast_ff_hook)(uint8_t vap_idx);
+typedef void(*tqe_fwt_false_miss_hook)(int fwt_index, uint8_t false_miss);
 
 int tqe_port_add_handler(enum topaz_tqe_port port, tqe_port_handler handler, void *token);
 void tqe_port_remove_handler(enum topaz_tqe_port port);
 int tqe_tx(union topaz_tqe_cpuif_ppctl *ppctl, struct sk_buff *skb);
 void tqe_register_fwt_cbk(tqe_fwt_get_mcast_hook mcast_cbk_func,
-				tqe_fwt_get_mcast_ff_hook mcast_ff_get_cbk_func);
+				tqe_fwt_get_mcast_ff_hook mcast_ff_get_cbk_func,
+				tqe_fwt_false_miss_hook false_miss_func);
 void tqe_register_ucastfwt_cbk(tqe_fwt_get_ucast_hook cbk_func);
+void tqe_register_macfwt_cbk(tqe_fwt_get_from_mac_hook cbk_func);
+void tqe_register_mac_reserved_cbk(tqe_mac_reserved_hook cbk_func);
 int tqe_rx_multicast(void *queue, const union topaz_tqe_cpuif_descr *desc);
 void tqe_port_register(const enum topaz_tqe_port port);
 void tqe_port_unregister(const enum topaz_tqe_port port);
@@ -56,7 +62,9 @@
 void tqe_port_clear_group(const enum topaz_tqe_port port);
 uint32_t switch_tqe_multi_proc_sem_down(char * funcname, int linenum);
 uint32_t switch_tqe_multi_proc_sem_up(void);
-#endif	/* TOPAZ_PLATFORM */
+int tqe_rx_l2_ext_filter(union topaz_tqe_cpuif_descr *desc, struct sk_buff *skb);
+void tqe_rx_call_port_handler(union topaz_tqe_cpuif_descr *desc,
+		struct sk_buff *skb, uint8_t *whole_frm_hdr);
 
 #endif	/* __TOPAZ_TQE_H */
 
diff --git a/include/qtn/topaz_tqe_cpuif.h b/include/qtn/topaz_tqe_cpuif.h
index 9bffceb..80b8f58 100644
--- a/include/qtn/topaz_tqe_cpuif.h
+++ b/include/qtn/topaz_tqe_cpuif.h
@@ -37,7 +37,8 @@
 	TOPAZ_TQE_DSP_PORT	= 6,
 	TOPAZ_TQE_AUC_PORT	= 7,
 
-	TOPAZ_TQE_NUM_PORTS	= 8
+	TOPAZ_TQE_NUM_PORTS	= 8,
+	TOPAZ_TQE_DUMMY_PORT	= 15
 };
 
 enum topaz_mproc_tqe_sem_id
@@ -48,9 +49,32 @@
 	TOPAZ_MPROC_TQE_SEM_AUC		= 3
 };
 
+/* bits of port_id  */
+#define PORT_ID_BITS                       8
+/* high 3 bits in port_id is used to save dev_id for 2.4G VAP */
+#define DEV_ID_BITS                        3
+
+#define MAX_QFP_NETDEV                     (1 << DEV_ID_BITS)
+#define MAX_DEV_ID                         (1 << DEV_ID_BITS)
+#define MAX_PORT_ID                        (1 << (PORT_ID_BITS - DEV_ID_BITS))
+
+#define GET_BIT_FIELD(var, offset, width) \
+		(((var) >> (offset)) & ((1 << (width)) - 1))
+
+#define INJECT_DEV_ID_TO_PORT_ID(port_id, dev_id, target) \
+		do {\
+			BUG_ON((port_id) >= MAX_PORT_ID || (dev_id) >= MAX_DEV_ID); \
+			(target) = (port_id) | ((dev_id) << (PORT_ID_BITS - DEV_ID_BITS)); \
+		} while (0)
+#define EXTRACT_PORT_ID_FROM_PORT_ID(port_id) \
+		GET_BIT_FIELD((port_id), 0, (PORT_ID_BITS - DEV_ID_BITS))
+#define EXTRACT_DEV_ID_FROM_PORT_ID(port_id) \
+		GET_BIT_FIELD((port_id), (PORT_ID_BITS - DEV_ID_BITS), DEV_ID_BITS)
+
 #define TOPAZ_TQE_PORT_NAMES	{ "emac0", "emac1", "wmac", "pcie", "lhost", "muc", "dsp", "auc", }
 #define TOPAZ_TQE_PORT_IS_EMAC(_port)	(((_port) == TOPAZ_TQE_EMAC_0_PORT) || \
 						((_port) == TOPAZ_TQE_EMAC_1_PORT))
+#define TOPAZ_TQE_PORT_IS_WMAC(_port)	((_port) == TOPAZ_TQE_WMAC_PORT)
 
 #if defined(__linux__)
 	#define TOPAZ_TQE_LOCAL_CPU	TOPAZ_TQE_LHOST_PORT
@@ -479,7 +503,7 @@
 	qtn_mproc_sync_mem_write(TOPAZ_TQE_CPUIF_PPCTL2(num), ctl->raw.ppctl2);
 	qtn_mproc_sync_mem_write(TOPAZ_TQE_CPUIF_PPCTL3(num), ctl->raw.ppctl3);
 	qtn_mproc_sync_mem_write(TOPAZ_TQE_CPUIF_PPCTL4(num), ctl->raw.ppctl4);
-	qtn_mproc_sync_mem_write(TOPAZ_TQE_CPUIF_PPCTL5(num), ctl->raw.ppctl5);
+	qtn_mproc_sync_mem_write_wmb(TOPAZ_TQE_CPUIF_PPCTL5(num), ctl->raw.ppctl5);
 	return num;
 }
 
@@ -523,7 +547,7 @@
 	}
 }
 
-RUBY_INLINE void topaz_tqe_emac_reflect_to(const uint8_t out_port)
+RUBY_INLINE void topaz_tqe_emac_reflect_to(const uint8_t out_port, const int bonded)
 {
 	if (out_port < TOPAZ_TQE_NUM_PORTS) {
 		uint32_t done_dly = qtn_mproc_sync_mem_read(TOPAZ_TQE_MISC);
@@ -531,7 +555,13 @@
 		done_dly &= ~TOPAZ_TQE_MISC_RFLCT_OUT_PORT;
 		done_dly |= SM(out_port, TOPAZ_TQE_MISC_RFLCT_OUT_PORT) |
 						TOPAZ_TQE_MISC_RFLCT_OUT_PORT_ENABLE;
+		if (bonded) {
+			done_dly |= TOPAZ_TQE_MISC_RFLCT_2_OUT_PORT_ENABLE;
+		}
 		qtn_mproc_sync_mem_write(TOPAZ_TQE_MISC, done_dly);
+#if defined (__KERNEL__) && defined (DEBUG)
+		printk("TOPAZ_TQE_MISC: 0x%x\n", done_dly);
+#endif
 	}
 }
 #endif /* #ifndef __TOPAZ_TQE_CPUIF_PLATFORM_H */
diff --git a/include/qtn/txbf_common.h b/include/qtn/txbf_common.h
index d9eb782..89677e0 100644
--- a/include/qtn/txbf_common.h
+++ b/include/qtn/txbf_common.h
@@ -55,8 +55,6 @@
 #define TXBF_CANNED_QMAT
 #undef TXBF_CANNED_QMAT
 
-#include <qtn/qtn_config.h>
-
 /* Until we get 2 tx antennas working on a 2x4 station */
 #define HAL_2x4STA_USE_4_TX_ANTENNAS
 
@@ -67,8 +65,6 @@
  */
 #define QTN_TXBF_FFT_LOCK_MANUAL	(1)
 
-#ifdef TOPAZ_PLATFORM
-
 /* VHTTXBFTBD - 11ac BF enabled by default */
 #define TXBF_ENABLE_VHT_BF
 
@@ -76,8 +72,6 @@
 /* #define TXBF_VHT_SW_FEEDBACK */
 /* #define TXBF_VHT_SW_UNCOMPRESSED */	/* for debugging */
 
-#endif /* TOPAZ_PLATFORM */
-
 /* Expansion Matrix Modes */
 #define TXBF_MODE_NO_MATRIX		0
 #define TXBF_MODE_DEFAULT_MATRIX	1
@@ -90,17 +84,17 @@
 enum txbf_buff_state
 {
 	/* Tx BF buffer for the frame is free */
-	TXBF_BUFF_FREE,
+	TXBF_BUFF_FREE		= 0,
 	/* The frame is stored in Tx BF buffer for processing and can not be released*/
-	TXBF_BUFF_IN_USE,
+	TXBF_BUFF_IN_USE	= 1,
 	/* Not used */
-	TXBF_DMA_FROM_BB,
+	TXBF_DMA_FROM_BB	= 2,
 	/* NDP only. The frame is being processed by DSP */
-	TXBF_DSP_PROC,
+	TXBF_DSP_PROC		= 3,
 	/* DSP completes frame processing */
-	TXBF_DSP_DONE,
+	TXBF_DSP_DONE		= 4,
 	/* For action frame only. Action frame is stored in action frame cache */
-	TXBF_DSP_STORED
+	TXBF_DSP_STORED		= 5
 };
 
 #define TXBF_BF_VER1	1	/* Envy */
@@ -143,6 +137,7 @@
 #define QTN_TXBF_TRIG_MU_GRP_SEL_MSG	7
 #define QTN_TXBF_RATE_TRAIN_MSG		8
 #define QTN_TXBF_RATE_TRAIN_HASH_MSG	9
+#define QTN_TXBF_NDP_DISCARD_MSG	10
 
 #define QTN_TXBF_ACT_FRM_XTRA_HDR_LEN	10
 
@@ -153,6 +148,10 @@
 
 #define MU_NDPA_TOKEN_MASK		0x1F
 
+/* Number of 10ms timeslots used on the DSP to process feedback */
+#define QTN_TXBF_SU_DSP_TIMESLOTS	1
+#define QTN_TXBF_MU_DSP_TIMESLOTS	2
+
 /* We leave backward compatibility here. As SU token value was randomly chosen as 0x33
 we now say when bit 5 is set it indicates SU sounding. */
 #define MU_NDPA_SU_MASK			0x20
@@ -195,7 +194,9 @@
 	char act_frame_sa[6];
 	char act_frame_bssid[6];
 	char slot;
-	char mu_grp_id[QTN_MU_QMAT_MAX_SLOTS];
+	uint8_t mu_grp_id[QTN_MU_QMAT_MAX_SLOTS];
+	uint8_t vapid;
+	unsigned counter;
 };
 
 #define IEEE80211_ADDR_LEN	6
@@ -267,11 +268,7 @@
 #define QTN_MAX_STREAMS			4
 #define QTN_MAX_40M_VHT_STREAMS		2
 #define QTN_MAX_20M_VHT_STREAMS		2
-#ifdef TOPAZ_PLATFORM
 #define QTN_MAX_IOT_QMAT_STREAMS	3
-#else
-#define QTN_MAX_IOT_QMAT_STREAMS	2
-#endif
 
 /*
  * Default decimation used for matrices in Q memory. Some matrices
@@ -284,18 +281,8 @@
 
 #define NDP_START_DELAY		2		/* in seconds  */
 
-#ifdef TOPAZ_PLATFORM
 #define STVEC_SIZE_BYTES_1STRM_20M 0x100	/* Assumes NG 1 matrices */
 #define STVEC_MAX_NODES		10
-#else /* TOPAZ_PLATFORM */
-#ifdef TXBF_6_STA_BF
-#define STVEC_SIZE_BYTES_1STRM_20M 0x100	/* Assumes NG 1 matrices */
-#define STVEC_MAX_NODES		6
-#else
-#define STVEC_SIZE_BYTES_1STRM_20M 0x200	/* Assumes NG 0 matrices */
-#define STVEC_MAX_NODES		3
-#endif /* TXBF_6_STA_BF */
-#endif /* TOPAZ_PLATFORM */
 
 /*
  * Matrix sizes for NG 1 matrices
@@ -311,28 +298,24 @@
 #define STVEC_SIZE_BYTES_4STRM_20M (STVEC_SIZE_BYTES_2STRM_20M << 1)
 #define STVEC_SIZE_BYTES_4STRM_40M (STVEC_SIZE_BYTES_2STRM_40M << 1)
 #define STVEC_SIZE_BYTES_4STRM_80M (STVEC_SIZE_BYTES_4STRM_40M << 1)
-#ifdef TOPAZ_PLATFORM
 #define STVEC_SIZE_BYTES_1STRM_MAX STVEC_SIZE_BYTES_1STRM_80M
 #define STVEC_SIZE_BYTES_2STRM_MAX STVEC_SIZE_BYTES_2STRM_80M
 #define STVEC_SIZE_BYTES_3STRM_MAX STVEC_SIZE_BYTES_3STRM_80M
 #define STVEC_SIZE_BYTES_4STRM_MAX STVEC_SIZE_BYTES_4STRM_80M
-#else
-#define STVEC_SIZE_BYTES_1STRM_MAX STVEC_SIZE_BYTES_1STRM_40M
-#define STVEC_SIZE_BYTES_2STRM_MAX STVEC_SIZE_BYTES_2STRM_40M
-#define STVEC_SIZE_BYTES_3STRM_MAX STVEC_SIZE_BYTES_3STRM_40M
-#define STVEC_SIZE_BYTES_4STRM_MAX STVEC_SIZE_BYTES_4STRM_40M
-#endif
 
-#define NDP_SIZE_BYTES_20M   1024
-#define NDP_SIZE_BYTES_40M   (NDP_SIZE_BYTES_20M << 1)
-#ifdef TOPAZ_PLATFORM
-#define NDP_SIZE_BYTES_80M   (NDP_SIZE_BYTES_40M << 1)
-#define NDP_SIZE_BYTES_MAX   NDP_SIZE_BYTES_80M
-#else
-#define NDP_SIZE_BYTES_MAX   NDP_SIZE_BYTES_40M
+#ifndef QTN_BW_20M
+# define QTN_BW_20M 0
+# define QTN_BW_40M 1
+# define QTN_BW_80M 2
 #endif
+#define QTN_BW_SW_MAX QTN_BW_80M
 
-#ifdef TOPAZ_PLATFORM
+#define NDP_SIZE_BYTES_BASE	1024
+#define NDP_SIZE_BYTES_20M	(NDP_SIZE_BYTES_BASE << QTN_BW_20M)
+#define NDP_SIZE_BYTES_40M	(NDP_SIZE_BYTES_BASE << QTN_BW_40M)
+#define NDP_SIZE_BYTES_80M	(NDP_SIZE_BYTES_BASE << QTN_BW_80M)
+#define NDP_SIZE_BYTES_MAX	(NDP_SIZE_BYTES_BASE << QTN_BW_SW_MAX)
+
 /*
  * Q matrix defines for 80 MHz nodes using NG 1
  */
@@ -408,7 +391,6 @@
 							QTN_TXBF_QMAT80_NG2_2STRM_MAT_TOTAL + \
 							QTN_TXBF_QMAT80_NG2_3STRM_MAT_TOTAL + \
 							QTN_TXBF_QMAT80_NG2_4STRM_MAT_TOTAL)
-#endif
 /*
  * Q matrix defines for 40 MHz nodes using NG 1
  */
@@ -444,27 +426,15 @@
 /*
  * Defines for dividing Q memory into slots for nodes using standard BF
  */
-#ifdef TOPAZ_PLATFORM
 #define QTN_TXBF_QMAT_SLOT_SIZE			MAX(QTN_TXBF_QMAT40_TOTAL_SIZE, \
 							QTN_TXBF_QMAT80_TOTAL_SIZE / 2)
-#else
-#ifdef TXBF_6_STA_BF
-#define QTN_TXBF_QMAT_SLOT_SIZE			(QTN_TXBF_QMAT40_TOTAL_SIZE)
-#else
-#define QTN_TXBF_QMAT_SLOT_SIZE	10 * 1024
-#endif
-#endif
 
 #define QTN_TXBF_QMAT_SLOTS_USED(qn)	(MAX(1, ((qn)->qn_node.ni_bw_cap >>		\
 					MAX(((qn)->qn_expmat.ng - QTN_TXBF_DEFAULT_QMAT_NG), 0))))
 
 #define QTN_TXBF_QMAT_SLOT(idx)		((idx) * QTN_TXBF_QMAT_SLOT_SIZE)
 
-#ifdef TOPAZ_PLATFORM
 #define QTN_TXBF_QMAT_OFFSET_SHIFT		6
-#else
-#define QTN_TXBF_QMAT_OFFSET_SHIFT		5
-#endif
 
 /*
  * Defines for fixed matrix (BBF and default) sizes
@@ -497,7 +467,6 @@
 /*
  * Fixed 2x4 node matrix definitions
  */
-#ifdef TOPAZ_PLATFORM
 /*
  * 80MHz 2x4 matrices need to start in normal BF area to fit,
  * this is OK, as they are used on the station only at present
@@ -505,18 +474,9 @@
 #define QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET	(QTN_TXBF_QMAT_SLOT_SIZE * (STVEC_MAX_NODES - 1))
 #define QTN_TXBF_QMAT_2x4STA_2_STRM_OFFSET	(QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET + \
 						STVEC_SIZE_BYTES_1STRM_80M)
-#else
-/*
- * Both 2x4 and the standard matrices use the same start offset, since 2x4 matrices
- * are only loaded on stations and standard/BBF matrices are only loaded on APs
- */
-#define QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET	QTN_TXBF_QMAT_FIXED_MAT_START
-#define QTN_TXBF_QMAT_2x4STA_2_STRM_OFFSET	(QTN_TXBF_QMAT_2x4STA_1_STRM_OFFSET + \
-						STVEC_SIZE_BYTES_1STRM_40M)
-#endif
 
-#define QTN_TXBF_2x4STA_1SS_TONE_DATA	{0x007F007F, 0x00000000}
-#define QTN_TXBF_2x4STA_2SS_TONE_DATA	{0x0000007F, 0x007F0000, 0x00000000, 0x00000000}
+#define QTN_TXBF_2x4STA_1SS_TONE_DATA	{0x00400040, 0x00000000}
+#define QTN_TXBF_2x4STA_2SS_TONE_DATA	{0x00000040, 0x00400000, 0x00000000, 0x00000000}
 
 /*
  * Fixed default matrix offset definitions
@@ -532,11 +492,7 @@
 
 #define QTN_TXBF_IOT_QMAT_START			(QTN_TXBF_QMAT_STD_4_STRM_OFFSET + \
 						QTN_TXBF_IOT_QMAT_4SS_MEM)
-#ifdef TOPAZ_PLATFORM
 #define QTN_TXBF_IOT_QMAT_TONES			2	/* number of tones for fixed matrices */
-#else
-#define QTN_TXBF_IOT_QMAT_TONES			1	/* number of tones for fixed matrices */
-#endif
 
 /*
  * BBF slot and matrix offset definitions
@@ -574,11 +530,7 @@
 #define QTN_TXBF_TONES_PER_CHAN 64
 #define QTN_TXBF_MAX_TONES	128
 #define QTN_TXBF_MIN_TONES	1
-#ifdef TOPAZ_PLATFORM
 #define	QTN_TXBF_MODE	4 /* 80MHz Mode */
-#else
-#define	QTN_TXBF_MODE	2 /* 40MHz Mode */
-#endif
 
 enum {
 	SVD_MODE_STREAM_MIXING =0,
@@ -601,19 +553,53 @@
 	#define QT4_BB_MIMO_BF_RX_INIT_VAL	(QT3_BB_MIMO_BF_RX_INIT_VAL)
 #endif
 
-/* qmat SRAM mem layout */
-#define QTN_SRAM_QMAT_LEN_BYTES		8
-#define QTN_SRAM_MU_1SS_1SS_SIZE	(QTN_SRAM_QMAT_LEN_BYTES + STVEC_SIZE_BYTES_2STRM_80M)
-#define QTN_SRAM_MU_2SS_1SS_SIZE	(QTN_SRAM_QMAT_LEN_BYTES + STVEC_SIZE_BYTES_3STRM_80M)
-#define QTN_SRAM_MU_3SS_1SS_SIZE	(QTN_SRAM_QMAT_LEN_BYTES + STVEC_SIZE_BYTES_4STRM_80M)
-#define QTN_SRAM_MU_1SS_2SS_SIZE	QTN_SRAM_MU_2SS_1SS_SIZE
-#define QTN_SRAM_MU_1SS_3SS_SIZE	QTN_SRAM_MU_3SS_1SS_SIZE
-#define QTN_SRAM_MU_2SS_2SS_SIZE	(QTN_SRAM_QMAT_LEN_BYTES + STVEC_SIZE_BYTES_4STRM_80M)
+/* should be 64 bytes aligned (expmat ptr in TxVector drops lower 5 bits)*/
+struct phys_qmat_layout {
+	uint64_t length;
+	int8_t body[0];
+} __packed;
+
+// TODO: describe bodies as 2 dimensional arrays
+struct phys_qmat_1x1 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_2STRM_80M];
+} __packed;
+
+struct phys_qmat_2x1 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_3STRM_80M];
+} __packed;
+
+struct phys_qmat_3x1 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
+} __packed;
+
+struct phys_qmat_1x2 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_3STRM_80M];
+} __packed;
+
+struct phys_qmat_1x3 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
+} __packed;
+
+struct phys_qmat_2x2 {
+	uint64_t length;
+	int8_t body[STVEC_SIZE_BYTES_4STRM_80M];
+} __packed;
+
+struct phys_qmat_dummy {
+	uint64_t length;
+	int8_t body[0x10];
+} __packed;
+
 /* structure to hold MU group qmatrix info */
 struct qtn_sram_qmat {
 	uint8_t valid;   /* set to 1 when it is occupied, 0 indicates it is free */
 	uint8_t grp_id;  /* MU group id */
-	uint8_t padding[2];
+	uint16_t tk;	/* Token */
 	uint16_t u0_aid;  /* user position 0 AID */
 	uint16_t u1_aid;  /* user position 1 AID */
 	int32_t rank;
@@ -626,6 +612,7 @@
 	uint32_t u0_1ss_u1_2ss;
 	uint32_t u0_1ss_u1_3ss;
 	uint32_t u0_2ss_u1_2ss;
+	uint32_t dsp_cnt;
 } __packed;
 
 struct qtn_grp_rank {
@@ -643,36 +630,20 @@
 #define TXBF_EXPMAT_TYPE_2_QMEM_MODE 2
 #define TXBF_EXPMAT_TYPE_5_QREG_MODE 5
 
-#ifdef TOPAZ_PLATFORM
-#define QTN_TXBF_QMAT_STD_1SS_TONE_DATA	{0x007F007F, 0x007F007F, 0x007F007F, 0x007F007F}
-#define QTN_TXBF_QMAT_STD_2SS_TONE_DATA	{0x005B005B, 0x5B00005B, 0x00A5005B, 0xA500005B, \
-					0x005B005B, 0x5B00005B, 0x00A5005B, 0xA500005B}
-#define QTN_TXBF_QMAT_STD_3SS_TONE_DATA	{0x004A004A, 0x004A004A, 0x00B64A00, 0x00B6004A, \
-					0x004A004A, 0x00B6B600, 0x004A004A, 0x004A004A, \
-					0x00B64A00, 0x00B6004A, 0x004A004A, 0x00B6B600}
-#define QTN_TXBF_QMAT_STD_4SS_TONE_DATA	{0x0000007F, 0x00000000, 0x007F0000, 0x00000000, \
-					0x00000000, 0x0000007F, 0x00000000, 0x007F0000, \
-					0x0000007F, 0x00000000, 0x007F0000, 0x00000000, \
-					0x00000000, 0x0000007F, 0x00000000, 0x007F0000}
-#else
-#define QTN_TXBF_QMAT_STD_1SS_TONE_DATA	{0x007F007F, 0x007F007F}
-#define QTN_TXBF_QMAT_STD_2SS_TONE_DATA	{0x005B005B, 0x5B00005B, 0x00A5005B, 0xA500005B}
-#define QTN_TXBF_QMAT_STD_3SS_TONE_DATA	{0x004A004A, 0x004A004A, 0x00B64A00, 0x00B6004A, \
-					0x004A004A, 0x00B6B600}
-#define QTN_TXBF_QMAT_STD_4SS_TONE_DATA	{0x0000007F, 0x00000000, 0x007F0000, 0x00000000, \
-					0x00000000, 0x0000007F, 0x00000000, 0x007F0000}
-#endif
-
-#ifndef QTN_BW_20M
-#define QTN_BW_20M 0
-#define QTN_BW_40M 1
-#define QTN_BW_80M 2
-#endif
+#define QTN_TXBF_QMAT_STD_1SS_TONE_DATA	{0x00400040, 0x00400040, 0x00400040, 0x00400040}
+#define QTN_TXBF_QMAT_STD_2SS_TONE_DATA	{0x002D002D, 0x2D00002D, 0x00D3002D, 0xD300002D, \
+					0x002D002D, 0x2D00002D, 0x00D3002D, 0xD300002D}
+#define QTN_TXBF_QMAT_STD_3SS_TONE_DATA	{0x00250025, 0x00250025, 0x00DB2500, 0x00DB0025, \
+					0x00250025, 0x00DBDB00, 0x00250025, 0x00250025, \
+					0x00DB2500, 0x00DB0025, 0x00250025, 0x00DBDB00}
+#define QTN_TXBF_QMAT_STD_4SS_TONE_DATA	{0x00000040, 0x00000000, 0x00400000, 0x00000000, \
+					0x00000000, 0x00000040, 0x00000000, 0x00400000, \
+					0x00000040, 0x00000000, 0x00400000, 0x00000000, \
+					0x00000000, 0x00000040, 0x00000000, 0x00400000}
 
 static __inline__ uint8_t qtn_txbf_get_bf_qmat_offsets(uint32_t *expmat_ss, uint8_t max,
 		uint32_t qmat_base_offset, uint8_t node_bw, uint8_t bw, uint8_t ng)
 {
-#ifdef TOPAZ_PLATFORM
 	if ((bw == QTN_BW_40M) && (node_bw == QTN_BW_80M)) {
 		if (ng == QTN_TXBF_DEFAULT_QMAT_NG) {
 			expmat_ss[0] = QTN_TXBF_QMAT80_1STRM_40M_OFFSET(qmat_base_offset);
@@ -718,20 +689,7 @@
 			expmat_ss[3] = QTN_TXBF_QMAT40_4STRM_OFFSET(qmat_base_offset);
 		}
 	}
-#else
-	if ((bw == QTN_BW_20M) && (node_bw > QTN_BW_20M)) {
-		expmat_ss[0] = QTN_TXBF_QMAT40_1STRM_20M_OFFSET(qmat_base_offset);
-		expmat_ss[1] = QTN_TXBF_QMAT40_2STRM_20M_OFFSET(qmat_base_offset);
-	} else {
-		expmat_ss[0] = QTN_TXBF_QMAT40_1STRM_OFFSET(qmat_base_offset);
-		expmat_ss[1] = QTN_TXBF_QMAT40_2STRM_OFFSET(qmat_base_offset);
-		if (max == QTN_MAX_STREAMS) {
-			expmat_ss[2] = QTN_TXBF_QMAT40_3STRM_OFFSET(qmat_base_offset);
-			expmat_ss[3] = QTN_TXBF_QMAT40_4STRM_OFFSET(qmat_base_offset);
-		}
-	}
 
-#endif
 	return (QTN_MAX_STREAMS - 1);
 }
 
diff --git a/include/qtn/txbf_mbox.h b/include/qtn/txbf_mbox.h
index df129f5..7051987 100644
--- a/include/qtn/txbf_mbox.h
+++ b/include/qtn/txbf_mbox.h
@@ -62,60 +62,144 @@
 #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_sram_qmat_num;
+/* Number or 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;
-
-	uint32_t dsp_ipc_int_in;
-	uint32_t dsp_ipc_int_out;
+	/* 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;
 
-	/* lock counters */
-	uint32_t dsp_txbf_msg_lock;
-
 	int16_t dspmu_D_user1[4];
 	int16_t dspmu_D_user2[4];
 	int16_t dspmu_max_intf_user1;
 	int16_t dspmu_max_intf_user2;
-
-	uint32_t dsp_act_rx_grp_sel;
-	uint32_t dsp_act_rx_precoding;
+	int16_t rank_criteria;
 	uint32_t dsp_trig_mu_grp_sel;
 	uint32_t dsp_mu_rank_success;
-	uint32_t dsp_mu_rank_negative;
 	uint32_t dsp_mu_rank_fail;
-	uint32_t dsp_mu_grp_inst_success;
+
+	/* 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_mu_node_del;
-	uint32_t dsp_mu_locked_cache_op;
+	uint32_t dsp_mu_node_del;
 
-	uint32_t dsp_su_act_rx;
-	uint32_t dsp_mu_act_rx;
-	uint32_t dsp_act_frm_bad;
 	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
 
@@ -142,22 +226,26 @@
 #define DEBUG_LVL_ALL	1
 	volatile uint32_t debug_level;
 
-#define MU_QMAT_FREEZE		0x00000001
-#define MU_MANUAL_RANK		0x00000002
-#define MU_FREEZE_RANK		0x00000004
-#define MU_QMAT_ZERO_STA0	0x00000010
-#define MU_QMAT_ZERO_STA1	0x00000020
-#define MU_QMAT_PRINT_CHMAT	0x00000100
-#define MU_QMAT_PRINT_PRECMAT	0x00000200
-#define MU_QMAT_PRINT_SNR	0x00000400
-#define MU_QMAT_PRINT_RANK	0x00000800
-#define MU_QMAT_PRINT_STUFFMEM  0x00001000
-#define MU_QMAT_PRINT_ACTFRM    0x00002000
-#define MU_PROJ_PREC_MUEQ_NEED_MASK	0x000F0000
-#define MU_PROJ_PREC_MUEQ_NEED_NC0_MASK	0x00030000
+#define MU_QMAT_FREEZE				0x00000001
+#define MU_MANUAL_RANK				0x00000002