Merge sdk-v37.4.2.89
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 374aaf5..b10037a 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -95,8 +95,8 @@
 
 #New platform adds here
 source "arch/arc/plat-qtn/Kconfig"
-source "../drivers/ruby/Kconfig"
-source "../drivers/topaz/Kconfig"
+source "drivers/qtn/ruby/Kconfig"
+source "drivers/qtn/topaz/Kconfig"
 
 endmenu
 
diff --git a/arch/arc/Makefile b/arch/arc/Makefile
index b58c73e..ab521e6 100644
--- a/arch/arc/Makefile
+++ b/arch/arc/Makefile
@@ -45,9 +45,9 @@
 # any kernel headers, and missing the r25 global register
 # Can't do unconditionally because of recursive include issues
 # due to <linux/thread_info.h>
-LINUXINCLUDE	+=  -include ${src}/arch/arc/include/asm/current.h -I$(srctree)/../ -I$(srctree)/../include/
-LINUXINCLUDE	+=  -include $(src)/../common/ruby_mem.h
-LINUXINCLUDE	+=  -include $(src)/../common/current_platform.h -include $(src)/../common/common_mem.h
+LINUXINCLUDE	+=  -include ${src}/arch/arc/include/asm/current.h -I$(srctree)/arch/arc/plat-qtn/sdk-qsr1000/ -I$(srctree)/arch/arc/plat-qtn/sdk-qsr1000/include/
+LINUXINCLUDE	+=  -include $(src)/arch/arc/plat-qtn/sdk-qsr1000/common/ruby_mem.h
+LINUXINCLUDE	+=  -include $(src)/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h -include $(src)/arch/arc/plat-qtn/sdk-qsr1000/common/common_mem.h
 endif
 
 upto_gcc44    :=  $(call cc-ifversion, -le, 0404, y)
@@ -109,8 +109,8 @@
 KBUILD_CFLAGS	+= -Iarch/arc/include/asm/board-$(PLATFORM)
 KBUILD_AFLAGS	+= $(KBUILD_CFLAGS)
 LDFLAGS		+= $(ldflags-y)
-KBUILD_CFLAGS	+= -I../drivers/include/kernel
-KBUILD_CFLAGS	+= -I../drivers/include/shared
+KBUILD_CFLAGS	+= -Idrivers/qtn/include/kernel
+KBUILD_CFLAGS	+= -Idrivers/qtn/include/shared
 
 ifdef CONFIG_ARC_PLAT_QTN
 KBUILD_CPPFLAGS += -I$(srctree)/arch/arc/plat-qtn/include/
@@ -130,11 +130,13 @@
 ARCH_CFLAGS += -mmedium-calls
 endif
 
-drivers-$(CONFIG_QUANTENNA_RUBY)	+= ../drivers/ruby/
+drivers-y				+= drivers/qtn/
 
-ifeq ($(CONFIG_QUANTENNA_TOPAZ),y)
-drivers-$(CONFIG_QUANTENNA_TOPAZ)	+= ../drivers/topaz/
-endif
+# drivers-$(CONFIG_QUANTENNA_RUBY)	+= drivers/qtn/ruby/
+
+# ifeq ($(CONFIG_QUANTENNA_TOPAZ),y)
+# drivers-$(CONFIG_QUANTENNA_TOPAZ)	+= drivers/qtn/topaz/
+# endif
 
 drivers-$(CONFIG_OPROFILE)	+= arch/arc/oprofile/
 
diff --git a/arch/arc/boot/dts/prowl.dts b/arch/arc/boot/dts/prowl.dts
new file mode 100644
index 0000000..57b88d9
--- /dev/null
+++ b/arch/arc/boot/dts/prowl.dts
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+	compatible = "qtn,qsr1000";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&core_intc>;
+
+	aliases {
+		serial0 = &uart0;
+	};
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+	memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0x00000000 0x80000000 0x40000000>;
+		device_type = "memory";
+		reg = <0x80000000 0x10000000>;
+	};
+	core_clk: core_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <500000000>;  /* 500 MHZ */
+	};
+	core_intc: arc700-intc@cpu {
+		compatible = "snps,arc700-intc";
+		interrupt-controller;
+		#interrupt-cells = <1>;
+	};
+	uart0: dw-apb-uart {
+		compatible = "snps,dw-apb-uart", "ns16550a";
+		reg = <0xF0000000 0x100>;
+		clock-frequency = <125000000>;
+		interrupt-parent = <&core_intc>;
+		interrupts = <24>;
+		baud = <115200>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+	};
+	pcie: pcie@e9000000 {
+		compatible = "snps,dw-pcie";
+		reg = <0xe9000000 0x2000>,   /* Controller registers */
+		      <0xcf000000 0x10000>;  /* PCI config space */
+		reg-names = "ctrlreg", "config";
+		device_type = "pci";
+		num-lanes = <1>;
+		interrupt-parent = <&core_intc>;
+		interrupts = <28>, <18>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges = <0x82000000 0 0xc0000000 0xc0000000 0 0x01000000
+		          0x83000000 0 0xc1000000 0xc1000000 0 0x01000000>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0x0 0 0 1>;
+		interrupt-map = <0x0 0 0 1 &core_intc 28>;
+	};
+};
diff --git a/arch/arc/configs/gfrg240_defconfig b/arch/arc/configs/gfrg240_defconfig
new file mode 100644
index 0000000..6dbbe40
--- /dev/null
+++ b/arch/arc/configs/gfrg240_defconfig
@@ -0,0 +1,232 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="Prowl"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="/usr/local/google/home/danielmentz/hdd1/import_quantenna_kernel/rootfs.arc-linux-uclibc.cpio"
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARC_PLAT_QTN=y
+CONFIG_ARCH_QSR1000=y
+CONFIG_ARCH_RUBY_NUMA=y
+CONFIG_QVSP=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_ARCH_RUBY_EMAC_LIB=m
+CONFIG_ARCH_RUBY_EMAC=m
+CONFIG_QUANTENNA_TOPAZ=y
+CONFIG_ARCH_TOPAZ_FWT=m
+CONFIG_ARCH_TOPAZ_TQE=m
+CONFIG_ARCH_TOPAZ_EMAC=m
+CONFIG_ARC_CPU_750D=y
+CONFIG_ARC_CACHE_LINE_SHIFT=5
+# CONFIG_ARC_HAS_SWAPE is not set
+CONFIG_ARC_EMUL_UNALIGNED=y
+CONFIG_HZ=200
+CONFIG_ARC_UBOOT_SUPPORT=y
+CONFIG_ARC_BUILTIN_DTB_NAME="prowl"
+# CONFIG_COMPACTION is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MROUTE=y
+CONFIG_NETFILTER=y
+# CONFIG_BRIDGE_NETFILTER is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_NAT_REDIRECT=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_BRIDGE=y
+CONFIG_NET_DSA=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SWITCHDEV=y
+CONFIG_NET_L3_MASTER_DEV=y
+CONFIG_CFG80211=m
+CONFIG_CFG80211_DEVELOPER_WARNINGS=y
+CONFIG_CFG80211_CERTIFICATION_ONUS=y
+# CONFIG_CFG80211_DEFAULT_PS is not set
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_MTD_UBI_BLOCK=y
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_PCIE=m
+# CONFIG_WLAN_VENDOR_MEDIATEK is not set
+# CONFIG_WLAN_VENDOR_RALINK is not set
+# CONFIG_WLAN_VENDOR_REALTEK is not set
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+# CONFIG_HWMON is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RAS=y
+CONFIG_NVMEM=y
+CONFIG_PCI=y
+CONFIG_HOTPLUG_PCI_PCIE=y
+# CONFIG_PCIEAER is not set
+# CONFIG_PCIEASPM is not set
+CONFIG_PCI_MSI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_PCIE_DW_PLAT=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PANIC_TIMEOUT=3
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_TRACING_EVENTS_GPIO is not set
+CONFIG_XZ_DEC=y
diff --git a/arch/arc/include/asm/board b/arch/arc/include/asm/board
new file mode 120000
index 0000000..c39b576
--- /dev/null
+++ b/arch/arc/include/asm/board
@@ -0,0 +1 @@
+board-ruby
\ No newline at end of file
diff --git a/arch/arc/include/asm/processor.h b/arch/arc/include/asm/processor.h
index 3f85f73..dd7ac0a 100644
--- a/arch/arc/include/asm/processor.h
+++ b/arch/arc/include/asm/processor.h
@@ -177,6 +177,6 @@
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE      (TASK_SIZE / 3)
+#define TASK_UNMAPPED_BASE      ( ( TASK_SIZE / 3) & PAGE_MASK)
 
 #endif /* __ASM_ARC_PROCESSOR_H */
diff --git a/arch/arc/plat-qtn/Kconfig b/arch/arc/plat-qtn/Kconfig
index a5434f1..3d0e274 100644
--- a/arch/arc/plat-qtn/Kconfig
+++ b/arch/arc/plat-qtn/Kconfig
@@ -13,10 +13,12 @@
 	select ARCH_REQUIRE_GPIOLIB
 	select MIGHT_HAVE_PCI
 	select ARC_PLAT_NEEDS_PHYS_TO_DMA
-	select QTN_PLATFORM_MISALIGN_WAR
 	help
 	  Support for Quantenna platforms
 
+config QTN_PLATFORM_MISALIGN_WAR
+	bool
+
 if ARC_PLAT_QTN
 
 config ARCH_QSR1000
diff --git a/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h b/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h
index 13899f3..e8e3e34 100644
--- a/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h
+++ b/arch/arc/plat-qtn/sdk-qsr1000/common/current_platform.h
@@ -5,8 +5,8 @@
 #define PLATFORM_WMAC_MODE ap
 #undef PLATFORM_DEFAULT_BOARD_ID
 #define ARC_HW_REV_NEEDS_TLBMISS_FIX
-#define TOPAZ_SUPPORT_UMM 0
-#define TOPAZ_SUPPORT_256MB_DDR 0
+#define TOPAZ_SUPPORT_UMM 1
+#define TOPAZ_SUPPORT_256MB_DDR 1
 #define FLASH_SUPPORT_64KB
 #define WPA_TKIP_SUPPORT 0
 #define SIGMA_TESTBED_SUPPORT 0
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 0c7937e..b4306d3 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2783,6 +2783,10 @@
 		}
 	}
 
+#ifdef CONFIG_ARCH_QSR1000
+	pdev->irq = 28;
+#endif
+
 	if (pci_enable_msi(pdev) != 0)
 		pci_disable_msi(pdev);
 	else
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
index 2592e63..b07333b 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.h
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
@@ -258,7 +258,11 @@
 	.fw_dump_end = 0xcff,
 	.fw_dump_host_ready = 0xcc,
 	.fw_dump_read_done = 0xdd,
+#ifdef CONFIG_ARCH_QSR1000
+	.msix_support = 0,
+#else
 	.msix_support = 1,
+#endif
 };
 
 static struct memory_type_mapping mem_type_mapping_tbl_w8897[] = {
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index aafd766..7cd1bf9 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -79,6 +79,28 @@
 
 int dw_pcie_cfg_read(void __iomem *addr, int size, u32 *val)
 {
+#ifdef CONFIG_ARCH_QSR1000
+	u32 reg_val;
+	void *walker = &reg_val;
+	u32 where = (u32) addr;
+
+	walker += (where & 0x3);
+	addr = (void __iomem *) (where & ~0x3);
+	reg_val = readl(addr);
+
+	if (size == 1)
+		*val = *(u8 __force *) walker;
+	else if (size == 2)
+		*val = *(u16 __force *) walker;
+	else if (size == 4)
+		*val = reg_val;
+	else {
+		*val = 0;
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+#else
 	if ((uintptr_t)addr & (size - 1)) {
 		*val = 0;
 		return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -96,10 +118,34 @@
 	}
 
 	return PCIBIOS_SUCCESSFUL;
+#endif
 }
 
 int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val)
 {
+#ifdef CONFIG_ARCH_QSR1000
+	u32 reg_val;
+	void *walker = &reg_val;
+	u32 where = (u32) addr;
+
+	walker += (where & 0x3);
+	addr = (void __iomem *) (where & ~0x3);
+
+	if (size == 4)
+		writel(val, addr);
+	else if (size == 2) {
+		reg_val = readl(addr);
+		*(u16 __force *) walker = val;
+		writel(reg_val, addr);
+	} else if (size == 1) {
+		reg_val = readl(addr);
+		*(u8 __force *) walker = val;
+		writel(reg_val, addr);
+	} else
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	return PCIBIOS_SUCCESSFUL;
+#else
 	if ((uintptr_t)addr & (size - 1))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
@@ -113,6 +159,7 @@
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
 	return PCIBIOS_SUCCESSFUL;
+#endif
 }
 
 static inline void dw_pcie_readl_rc(struct pcie_port *pp, u32 reg, u32 *val)
@@ -599,13 +646,17 @@
 		va_cfg_base = pp->va_cfg1_base;
 	}
 
+#ifndef CONFIG_ARCH_QSR1000
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
 				  type, cpu_addr,
 				  busdev, cfg_size);
+#endif
 	ret = dw_pcie_cfg_read(va_cfg_base + where, size, val);
+#ifndef CONFIG_ARCH_QSR1000
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
 				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
+#endif
 
 	return ret;
 }
@@ -636,13 +687,17 @@
 		va_cfg_base = pp->va_cfg1_base;
 	}
 
+#ifndef CONFIG_ARCH_QSR1000
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
 				  type, cpu_addr,
 				  busdev, cfg_size);
+#endif
 	ret = dw_pcie_cfg_write(va_cfg_base + where, size, val);
+#ifndef CONFIG_ARCH_QSR1000
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
 				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
+#endif
 
 	return ret;
 }
@@ -778,10 +833,12 @@
 	 * uses its own address translation component rather than ATU, so
 	 * we should not program the ATU here.
 	 */
+#ifndef CONFIG_ARCH_QSR1000
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
 					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
+#endif
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
 
diff --git a/drivers/qtn/Makefile b/drivers/qtn/Makefile
index f30443a..ff09620 100644
--- a/drivers/qtn/Makefile
+++ b/drivers/qtn/Makefile
@@ -2,19 +2,15 @@
 QTN_EXTERNAL_MODULES=y
 export QTN_EXTERNAL_MODULES
 
-ifneq ($(KERNELRELEASE),)
-ifeq ($(CONFIG_QUANTENNA_RUBY),y)
-obj-m += ruby/
-endif
-ifeq ($(CONFIG_QUANTENNA_TOPAZ),y)
-obj-m += topaz/
+obj-$(CONFIG_QUANTENNA_RUBY) += ruby/
+obj-$(CONFIG_QUANTENNA_TOPAZ) += topaz/
+
 #
 # Check for fwt_ctrl.ko source code
 #
 ifneq ($(wildcard $(src)/fwt/Makefile),)
 obj-m += fwt/
 endif
-endif
 
 ifeq ($(filter topaz_host_config,$(board_config)),)
 obj-m += qdrv/
@@ -27,22 +23,3 @@
 ifeq ($(CONFIG_TOPAZ_PCIE_HOST), y)
 obj-m += pcie2/host/quantenna/
 endif
-else
-KERNELDIR	= ../linux
-CROSS		= ARCH=arc
-INSTALL		= INSTALL_MOD_PATH=../linux/modules
-MDIR		= ../drivers/
-EXTRA_CFLAGS	+= -Wall -Werror -I../include -I$(KERNELDIR)/include
-
-default: force
-	$(MAKE) -C $(KERNELDIR) $(CROSS) M=$(MDIR) modules KBUILD_EXTRA_SYMBOLS=$(MDIR)/extra_kos.symvers
-
-install: force
-	$(MAKE) -C $(KERNELDIR) $(CROSS) $(INSTALL) M=$(MDIR) modules_install
-
-clean: force
-	$(MAKE) -C $(KERNELDIR) $(CROSS) M=$(MDIR) clean
-
-force:
-
-endif
diff --git a/drivers/qtn/i2cbus/Makefile b/drivers/qtn/i2cbus/Makefile
index aac3173..ea8a771 100644
--- a/drivers/qtn/i2cbus/Makefile
+++ b/drivers/qtn/i2cbus/Makefile
@@ -6,7 +6,7 @@
 #
 
 EXTRA_CFLAGS	+= -Wall -Werror	\
-					-I../drivers	\
+					-Idrivers/qtn	\
 
 ifneq ($(KERNELRELEASE),)
 
diff --git a/drivers/qtn/include/kernel/net80211/ieee80211_linux.h b/drivers/qtn/include/kernel/net80211/ieee80211_linux.h
index f17217a..c6545b8 100644
--- a/drivers/qtn/include/kernel/net80211/ieee80211_linux.h
+++ b/drivers/qtn/include/kernel/net80211/ieee80211_linux.h
@@ -32,7 +32,7 @@
 #include <linux/version.h>
 #include <linux/wireless.h>
 #include <linux/fs.h>
-#include "linux/net/8021q/vlan.h"
+#include "../../../../linux/net/8021q/vlan.h"
 #include "compat.h"
 
 /*
diff --git a/drivers/qtn/include/kernel/net80211/ieee80211_var.h b/drivers/qtn/include/kernel/net80211/ieee80211_var.h
index 986d9f9..c12c084 100644
--- a/drivers/qtn/include/kernel/net80211/ieee80211_var.h
+++ b/drivers/qtn/include/kernel/net80211/ieee80211_var.h
@@ -63,7 +63,7 @@
 #include "net80211/ieee80211_chan_select.h"
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #include <linux/if_bridge.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../../../net/bridge/br_public.h"
 #endif
 
 #define	IEEE80211_BGSCAN_INTVAL_MIN	15	/* min bg scan intvl (secs) */
diff --git a/drivers/qtn/qdrv/Makefile b/drivers/qtn/qdrv/Makefile
index c210ae6..e6a15a6 100644
--- a/drivers/qtn/qdrv/Makefile
+++ b/drivers/qtn/qdrv/Makefile
@@ -7,7 +7,7 @@
 CLEAN_FILES+=$(QDRV_SLAB_H)
 
 EXTRA_CFLAGS += -Wall -Werror -Wno-unknown-pragmas -DQDRV \
-		-I../drivers -I../include -I../drivers/include/shared -I../drivers/include/kernel
+		-Idrivers/qtn -Iarch/arc/plat-qtn/sdk-qsr1000/include -Idrivers/qtn/include/shared -Idrivers/qtn/include/kernel
 EXTRA_CFLAGS += -mlong-calls
 EXTRA_CFLAGS += -DQTN_ENABLE_TRACE_BUFFER=0 -DQSCS_ENABLED -DQTN_BG_SCAN -DQBMPS_ENABLE
 EXTRA_CFLAGS += -DCONFIG_QTN_80211K_SUPPORT -DCONFIG_NAC_MONITOR
diff --git a/drivers/qtn/qdrv/qdrv_config.h b/drivers/qtn/qdrv/qdrv_config.h
index a500532..57861563 100644
--- a/drivers/qtn/qdrv/qdrv_config.h
+++ b/drivers/qtn/qdrv/qdrv_config.h
@@ -1,3 +1,3 @@
 /* Automatically generated file. Do not edit. */
-#define QDRV_CFG_PLATFORM_ID 466
-#define QDRV_CFG_TYPE "topaz_config"
+#define QDRV_CFG_PLATFORM_ID 467
+#define QDRV_CFG_TYPE "topaz_umm_config"
diff --git a/drivers/qtn/qdrv/qdrv_control.c b/drivers/qtn/qdrv/qdrv_control.c
index dd300d8..fcd3964 100644
--- a/drivers/qtn/qdrv/qdrv_control.c
+++ b/drivers/qtn/qdrv/qdrv_control.c
@@ -69,7 +69,7 @@
 #include <qtn/qtn_muc_stats_print.h>
 #include <qtn/qtn_vlan.h>
 #include <asm/board/troubleshoot.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 #include "qdrv_show.h"
 #include <qtn/txbf_mbox.h>
 #include <net/iw_handler.h> /* wireless_send_event(..) */
diff --git a/drivers/qtn/qdrv/qdrv_rx.c b/drivers/qtn/qdrv/qdrv_rx.c
index 59c46f1..db348b4 100644
--- a/drivers/qtn/qdrv/qdrv_rx.c
+++ b/drivers/qtn/qdrv/qdrv_rx.c
@@ -65,7 +65,7 @@
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #include "qtn/qdrv_sch.h"
 #include <linux/if_bridge.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 #endif
 
 #include <qtn/qtn_decap.h>
diff --git a/drivers/qtn/qdrv/qdrv_wlan.c b/drivers/qtn/qdrv/qdrv_wlan.c
index 2a6f096..5b1c60b 100644
--- a/drivers/qtn/qdrv/qdrv_wlan.c
+++ b/drivers/qtn/qdrv/qdrv_wlan.c
@@ -31,7 +31,7 @@
 #include <net/sch_generic.h>
 #include <asm/hardware.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 #include <linux/gpio.h>
 #else
 #include <asm/gpio.h>
diff --git a/drivers/qtn/qdrv/qdrv_wlan.h b/drivers/qtn/qdrv/qdrv_wlan.h
index bb22362..fe2ac8c 100644
--- a/drivers/qtn/qdrv/qdrv_wlan.h
+++ b/drivers/qtn/qdrv/qdrv_wlan.h
@@ -23,7 +23,7 @@
 
 #include <linux/version.h>
 #include <linux/interrupt.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../../../net/bridge/br_public.h"
 
 /* Include the WLAN 802.11 layer here */
 #include <linux/skbuff.h>
@@ -36,7 +36,7 @@
 #include "qdrv_comm.h"
 #include "qdrv_debug.h"
 #include "qtn/qtn_pcap.h"
-#include "qdrv/qdrv_bridge.h"
+#include "qdrv_bridge.h"
 #include "qtn/muc_txrx_stats.h"
 #include "qtn/muc_phy_stats.h"
 #include "qtn/dsp_stats.h"
diff --git a/drivers/qtn/ruby/Makefile b/drivers/qtn/ruby/Makefile
index cf844ed..8c9aab8 100644
--- a/drivers/qtn/ruby/Makefile
+++ b/drivers/qtn/ruby/Makefile
@@ -1,8 +1,8 @@
 EXTRA_CFLAGS +=	-Wall -Werror \
-		-I../include \
-		-I../common \
-		-I../drivers/include/shared \
-		-I../drivers/include/kernel
+		-Iarch/arc/plat-qtn/sdk-qsr1000/include \
+		-Iarch/arc/plat-qtn/sdk-qsr1000/common \
+		-Idrivers/include/shared \
+		-Idrivers/include/kernel
 
 obj-y += \
 	board_config.o \
diff --git a/drivers/qtn/ruby/board_config.c b/drivers/qtn/ruby/board_config.c
index b8f44c6..8cdec5d 100644
--- a/drivers/qtn/ruby/board_config.c
+++ b/drivers/qtn/ruby/board_config.c
@@ -28,7 +28,7 @@
 #include <common/ruby_board_db.h>
 #include <common/ruby_partitions.h>
 
-static int			global_board_id = -1;
+static int			global_board_id = QTN_RUBY_UNIVERSAL_BOARD_ID;
 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;
diff --git a/drivers/qtn/ruby/emac_lib.c b/drivers/qtn/ruby/emac_lib.c
index a8fcc21..b482e41 100644
--- a/drivers/qtn/ruby/emac_lib.c
+++ b/drivers/qtn/ruby/emac_lib.c
@@ -718,10 +718,8 @@
 			rtl8367b_exit();
 		}
 #endif
-		if (mii->irq) {
-			kfree(mii->irq);
-		}
-		mdiobus_unregister(mii);
+		if ((privc->emac_cfg & EMAC_PHY_NOT_IN_USE) == 0)
+			mdiobus_unregister(mii);
 		mdiobus_free(mii);
 	}
 
diff --git a/drivers/qtn/topaz/Makefile b/drivers/qtn/topaz/Makefile
index 8966938..775f52a 100644
--- a/drivers/qtn/topaz/Makefile
+++ b/drivers/qtn/topaz/Makefile
@@ -1,8 +1,8 @@
 EXTRA_CFLAGS +=	-Wall -Werror -Wno-unknown-pragmas -mlong-calls \
-		-I../include \
-		-I../ \
-		-I../drivers/include/shared \
-		-I../drivers/include/kernel
+		-Iarch/arc/plat-qtn/sdk-qsr1000/include \
+		-Iarch/arc/plat-qtn/sdk-qsr1000/ \
+		-Idrivers/include/shared \
+		-Idrivers/include/kernel
 
 ifeq ($(board_config),topaz_config)
 	EXTRA_CFLAGS += -DTOPAZ_VB_CONFIG -DTOPAZ_CONGE_CONFIG -DTOPAZ_SRAM_CONFIG
diff --git a/drivers/qtn/topaz/fwt_if.c b/drivers/qtn/topaz/fwt_if.c
index 168656d..b61c1f6 100755
--- a/drivers/qtn/topaz/fwt_if.c
+++ b/drivers/qtn/topaz/fwt_if.c
@@ -28,7 +28,7 @@
 #include <linux/ctype.h>
 #include <linux/if_ether.h>
 #include <linux/inet.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 
 #include <net80211/if_ethersubr.h>
 #include <net80211/ieee80211.h>
diff --git a/drivers/qtn/topaz/switch_emac.c b/drivers/qtn/topaz/switch_emac.c
index a0a338f..894fa89 100644
--- a/drivers/qtn/topaz/switch_emac.c
+++ b/drivers/qtn/topaz/switch_emac.c
@@ -35,7 +35,7 @@
 
 #include <qtn/topaz_dpi.h>
 #include <common/topaz_emac.h>
-#include <drivers/ruby/emac_lib.h>
+#include "../ruby/emac_lib.h"
 
 #include <qtn/topaz_fwt_sw.h>
 #include <qtn/qtn_buffers.h>
diff --git a/drivers/qtn/topaz/switch_tqe.c b/drivers/qtn/topaz/switch_tqe.c
index 1e09715..2a0f435 100644
--- a/drivers/qtn/topaz/switch_tqe.c
+++ b/drivers/qtn/topaz/switch_tqe.c
@@ -31,7 +31,7 @@
 #endif
 
 #include <qtn/dmautil.h>
-#include <drivers/ruby/dma_cache_ops.h>
+#include <asm/board/dma_cache_ops.h>
 
 #include "topaz_test.h"
 #include <qtn/topaz_fwt_sw.h>
@@ -51,7 +51,7 @@
 #include <qtn/iputil.h>
 #include <qtn/mproc_sync.h>
 #include <qtn/qtn_vlan.h>
-#include "linux/net/bridge/br_public.h"
+#include "../../net/bridge/br_public.h"
 
 int g_dscp_flag = 0;
 int g_dscp_value[2];
diff --git a/drivers/qtn/topaz/switch_vlan.c b/drivers/qtn/topaz/switch_vlan.c
index 4b7d9d3..6ef756e 100644
--- a/drivers/qtn/topaz/switch_vlan.c
+++ b/drivers/qtn/topaz/switch_vlan.c
@@ -28,14 +28,14 @@
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
 #include <linux/spinlock.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.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>
+#include "../ruby/emac_lib.h"
 
 __sram_data uint8_t vlan_enabled;
 EXPORT_SYMBOL(vlan_enabled);
diff --git a/drivers/qtn/wlan/ieee80211.c b/drivers/qtn/wlan/ieee80211.c
index b4a10b3..bb45fad 100644
--- a/drivers/qtn/wlan/ieee80211.c
+++ b/drivers/qtn/wlan/ieee80211.c
@@ -57,7 +57,7 @@
 
 #include <qtn/qtn_buffers.h>
 #include <qtn/qtn_global.h>
-#include <qdrv/qdrv_vap.h>
+#include "../qdrv/qdrv_vap.h"
 
 const char *ieee80211_phymode_name[] = {
 	"auto",		/* IEEE80211_MODE_AUTO */
diff --git a/drivers/qtn/wlan/ieee80211_beacon_desc.c b/drivers/qtn/wlan/ieee80211_beacon_desc.c
index 8f0488a..628045e 100644
--- a/drivers/qtn/wlan/ieee80211_beacon_desc.c
+++ b/drivers/qtn/wlan/ieee80211_beacon_desc.c
@@ -28,12 +28,12 @@
 #include <linux/dma-mapping.h>
 #include <linux/dmapool.h>
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
-#include <ruby/plat_dma_addr.h>
+#include <asm/board/plat_dma_addr.h>
 #endif
 
 #include "net80211/ieee80211_var.h"
 #include "net80211/ieee80211_beacon_desc.h"
-#include "qdrv/qdrv_vap.h"
+#include "../qdrv/qdrv_vap.h"
 
 /* This fucntion allocates a beacon ie and associate the beacon ie buffer. */
 static void ieee80211_beacon_associate_ie(struct beacon_shared_ie_t *ie, uint8_t *frm, uint8_t size)
diff --git a/drivers/qtn/wlan/ieee80211_input.c b/drivers/qtn/wlan/ieee80211_input.c
index 250c5d8..68d4035 100644
--- a/drivers/qtn/wlan/ieee80211_input.c
+++ b/drivers/qtn/wlan/ieee80211_input.c
@@ -69,13 +69,13 @@
 #include "qtn/qtn_global.h"
 #include "qtn_logging.h"
 
-#include <qdrv/qdrv_debug.h>
+#include "../qdrv/qdrv_debug.h"
 #include <qtn/shared_params.h>
 #include <qtn/hardware_revision.h>
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #include <linux/if_bridge.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 #endif
 
 #if defined(CONFIG_QTN_BSA_SUPPORT)
diff --git a/drivers/qtn/wlan/ieee80211_tdls.c b/drivers/qtn/wlan/ieee80211_tdls.c
index 1544d66..1db88b4 100755
--- a/drivers/qtn/wlan/ieee80211_tdls.c
+++ b/drivers/qtn/wlan/ieee80211_tdls.c
@@ -67,7 +67,7 @@
 
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
 #include <linux/if_bridge.h>
-#include "linux/net/bridge/br_private.h"
+#include "../../net/bridge/br_private.h"
 #endif
 
 #define IEEE80211_TDLS_FRAME_MAX 512
diff --git a/drivers/qtn/wlan/ieee80211_wireless.c b/drivers/qtn/wlan/ieee80211_wireless.c
index 2f971ca..3dca6c3 100644
--- a/drivers/qtn/wlan/ieee80211_wireless.c
+++ b/drivers/qtn/wlan/ieee80211_wireless.c
@@ -84,18 +84,18 @@
 #include "net80211/ieee80211_mlme_statistics.h"
 #include "qtn_logging.h"
 
-#include <qdrv/qdrv_vap.h>
+#include "../qdrv/qdrv_vap.h"
 #include <qtn/qtn_debug.h>
 #include <qtn/shared_params.h>
 #include <qtn/qtn_bb_mutex.h>
 #include <qtn/qtn_vlan.h>
-#include <linux/net/bridge/br_public.h>
+#include "../../net/bridge/br_public.h"
 
 #include "qtn/wlan_ioctl.h"
 
 #include "soc.h"
 
-#include <qdrv/qdrv_mac.h>
+#include "../qdrv/qdrv_mac.h"
 #include <qtn/txbf_mbox.h>
 
 #include <qtn/topaz_tqe_cpuif.h>
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 730d856..af5b139 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -341,7 +341,7 @@
 	ipv6_addr_set(solicited,
 		      htonl(0xFF020000), 0,
 		      htonl(0x1),
-		      htonl(0xFF000000) | addr->s6_addr32[3]);
+		      htonl(0xFF000000) | get_unaligned(&addr->s6_addr32[3]));
 }
 
 static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
@@ -350,9 +350,9 @@
 	__be64 *p = (__be64 *)addr;
 	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(1))) == 0UL;
 #else
-	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
-		addr->s6_addr32[1] | addr->s6_addr32[2] |
-		(addr->s6_addr32[3] ^ htonl(0x00000001))) == 0;
+	return ((get_unaligned(&addr->s6_addr32[0]) ^ htonl(0xff020000)) |
+		get_unaligned(&addr->s6_addr32[1]) | get_unaligned(&addr->s6_addr32[2]) |
+		(get_unaligned(&addr->s6_addr32[3]) ^ htonl(0x00000001))) == 0;
 #endif
 }
 
@@ -362,15 +362,15 @@
 	__be64 *p = (__be64 *)addr;
 	return ((p[0] ^ cpu_to_be64(0xff02000000000000UL)) | (p[1] ^ cpu_to_be64(2))) == 0UL;
 #else
-	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
-		addr->s6_addr32[1] | addr->s6_addr32[2] |
-		(addr->s6_addr32[3] ^ htonl(0x00000002))) == 0;
+	return ((get_unaligned(&addr->s6_addr32[0]) ^ htonl(0xff020000)) |
+		get_unaligned(&addr->s6_addr32[1]) | get_unaligned(&addr->s6_addr32[2]) |
+		(get_unaligned(&addr->s6_addr32[3]) ^ htonl(0x00000002))) == 0;
 #endif
 }
 
 static inline bool ipv6_addr_is_isatap(const struct in6_addr *addr)
 {
-	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
+	return (get_unaligned(&addr->s6_addr32[2]) | htonl(0x02000000)) == htonl(0x02005EFE);
 }
 
 static inline bool ipv6_addr_is_solict_mult(const struct in6_addr *addr)
@@ -381,9 +381,9 @@
 		((p[1] ^ cpu_to_be64(0x00000001ff000000UL)) &
 		 cpu_to_be64(0xffffffffff000000UL))) == 0UL;
 #else
-	return ((addr->s6_addr32[0] ^ htonl(0xff020000)) |
-		addr->s6_addr32[1] |
-		(addr->s6_addr32[2] ^ htonl(0x00000001)) |
+	return ((get_unaligned(&addr->s6_addr32[0]) ^ htonl(0xff020000)) |
+		get_unaligned(&addr->s6_addr32[1]) |
+		(get_unaligned(&addr->s6_addr32[2]) ^ htonl(0x00000001)) |
 		(addr->s6_addr[12] ^ 0xff)) == 0;
 #endif
 }
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 11a0452..8d8cc40 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -21,6 +21,7 @@
 #include <net/flow.h>
 #include <net/flow_dissector.h>
 #include <net/snmp.h>
+#include <asm/unaligned.h>
 
 #define SIN6_LEN_RFC2133	24
 
@@ -462,10 +463,10 @@
 
 	return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL;
 #else
-	return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
-		(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
-		(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
-		(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
+	return ((get_unaligned(&a1->s6_addr32[0]) ^ get_unaligned(&a2->s6_addr32[0])) |
+		(get_unaligned(&a1->s6_addr32[1]) ^ get_unaligned(&a2->s6_addr32[1])) |
+		(get_unaligned(&a1->s6_addr32[2]) ^ get_unaligned(&a2->s6_addr32[2])) |
+		(get_unaligned(&a1->s6_addr32[3]) ^ get_unaligned(&a2->s6_addr32[3]))) == 0;
 #endif
 }
 
@@ -580,8 +581,8 @@
 
 	return (u32)(x ^ (x >> 32));
 #else
-	return (__force u32)(a->s6_addr32[0] ^ a->s6_addr32[1] ^
-			     a->s6_addr32[2] ^ a->s6_addr32[3]);
+	return (__force u32)(get_unaligned(&a->s6_addr32[0]) ^ get_unaligned(&a->s6_addr32[1]) ^
+			     get_unaligned(&a->s6_addr32[2]) ^ get_unaligned(&a->s6_addr32[3]));
 #endif
 }
 
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index e3f6f1f..965853a 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -72,7 +72,7 @@
 		return 0;
 	switch (a->proto) {
 	case htons(ETH_P_IP):
-		return a->u.ip4 == b->u.ip4;
+		return get_unaligned(&a->u.ip4) == get_unaligned(&b->u.ip4);
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
 		return ipv6_addr_equal(&a->u.ip6, &b->u.ip6);
@@ -102,7 +102,7 @@
 {
 	switch (ip->proto) {
 	case htons(ETH_P_IP):
-		return __br_ip4_hash(mdb, ip->u.ip4, ip->vid);
+		return __br_ip4_hash(mdb, get_unaligned(&ip->u.ip4), ip->vid);
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
 		return __br_ip6_hash(mdb, &ip->u.ip6, ip->vid);
@@ -175,7 +175,7 @@
 
 	switch (ip.proto) {
 	case htons(ETH_P_IP):
-		ip.u.ip4 = ip_hdr(skb)->daddr;
+		ip.u.ip4 = get_unaligned(&ip_hdr(skb)->daddr);
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
@@ -875,7 +875,7 @@
 	if (ipv6_addr_is_ll_all_nodes(group))
 		return 0;
 
-	br_group.u.ip6 = *group;
+	memcpy(&br_group.u.ip6, &group, sizeof(*group));
 	br_group.proto = htons(ETH_P_IPV6);
 	br_group.vid = vid;
 
@@ -1161,7 +1161,7 @@
 			return -EINVAL;
 
 		grec = (void *)(skb->data + len - sizeof(*grec));
-		group = grec->grec_mca;
+		group = get_unaligned(&grec->grec_mca);
 		type = grec->grec_type;
 
 		len += ntohs(grec->grec_nsrcs) * 4;
@@ -1838,7 +1838,7 @@
 
 	own_query = port ? &port->ip6_own_query : &br->ip6_own_query;
 
-	br_group.u.ip6 = *group;
+	memcpy(&br_group.u.ip6, group, sizeof(*group));
 	br_group.proto = htons(ETH_P_IPV6);
 	br_group.vid = vid;
 
@@ -1884,7 +1884,7 @@
 	case IGMPV2_HOST_MEMBERSHIP_REPORT:
 		BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
 		err = br_ip4_multicast_add_group(br, port,
-					src_mac, skb->src_port, ih->group, vid);
+					src_mac, skb->src_port, get_unaligned(&ih->group), vid);
 		break;
 	case IGMPV3_HOST_MEMBERSHIP_REPORT:
 		err = br_ip4_multicast_igmp3_report(br, port, skb_trimmed, vid);
@@ -1894,7 +1894,7 @@
 		break;
 	case IGMP_HOST_LEAVE_MESSAGE:
 		br_ip4_multicast_leave_group(br, port,
-					src_mac, skb->src_port, ih->group, vid);
+					src_mac, skb->src_port, get_unaligned(&ih->group), vid);
 		break;
 	}
 
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 73c33de..6abd5a7 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -340,7 +340,7 @@
 	 *	how the packet travels inside Linux networking.
 	 */
 	if (!skb_valid_dst(skb)) {
-		int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
+		int err = ip_route_input_noref(skb, get_unaligned(&iph->daddr), get_unaligned(&iph->saddr),
 					       iph->tos, skb->dev);
 		if (unlikely(err)) {
 			if (err == -EXDEV)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 4aed8fc..22f0e79 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1322,7 +1322,7 @@
 	if (sin) {
 		sin->sin_family = AF_INET;
 		sin->sin_port = udp_hdr(skb)->source;
-		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
+		sin->sin_addr.s_addr = get_unaligned(&ip_hdr(skb)->saddr);
 		memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 		*addr_len = sizeof(*sin);
 	}
@@ -1745,8 +1745,8 @@
 
 	uh   = udp_hdr(skb);
 	ulen = ntohs(uh->len);
-	saddr = ip_hdr(skb)->saddr;
-	daddr = ip_hdr(skb)->daddr;
+	saddr = get_unaligned(&ip_hdr(skb)->saddr);
+	daddr = get_unaligned(&ip_hdr(skb)->daddr);
 
 	if (ulen > skb->len)
 		goto short_packet;
@@ -1926,17 +1926,17 @@
 
 		/* we are supposed to accept bcast packets */
 		if (skb->pkt_type == PACKET_MULTICAST) {
-			ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr,
+			ours = ip_check_mc_rcu(in_dev, get_unaligned(&iph->daddr), get_unaligned(&iph->saddr),
 					       iph->protocol);
 			if (!ours)
 				return;
 		}
 
-		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr,
-						   uh->source, iph->saddr, dif);
+		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, get_unaligned(&iph->daddr),
+						   uh->source, get_unaligned(&iph->saddr), dif);
 	} else if (skb->pkt_type == PACKET_HOST) {
-		sk = __udp4_lib_demux_lookup(net, uh->dest, iph->daddr,
-					     uh->source, iph->saddr, dif);
+		sk = __udp4_lib_demux_lookup(net, uh->dest, get_unaligned(&iph->daddr),
+					     uh->source, get_unaligned(&iph->saddr), dif);
 	}
 
 	if (!sk || !atomic_inc_not_zero_hint(&sk->sk_refcnt, 2))
diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c
index c0cbcb2..505e1e0 100644
--- a/net/ipv6/ip6_checksum.c
+++ b/net/ipv6/ip6_checksum.c
@@ -14,36 +14,36 @@
 	__u32 uproto;
 	__u32 sum = (__force u32)csum;
 
-	sum += (__force u32)saddr->s6_addr32[0];
-	carry = (sum < (__force u32)saddr->s6_addr32[0]);
+	sum += (__force u32)get_unaligned(&saddr->s6_addr32[0]);
+	carry = (sum < (__force u32)get_unaligned(&saddr->s6_addr32[0]));
 	sum += carry;
 
-	sum += (__force u32)saddr->s6_addr32[1];
-	carry = (sum < (__force u32)saddr->s6_addr32[1]);
+	sum += (__force u32)get_unaligned(&saddr->s6_addr32[1]);
+	carry = (sum < (__force u32)get_unaligned(&saddr->s6_addr32[1]));
 	sum += carry;
 
-	sum += (__force u32)saddr->s6_addr32[2];
-	carry = (sum < (__force u32)saddr->s6_addr32[2]);
+	sum += (__force u32)get_unaligned(&saddr->s6_addr32[2]);
+	carry = (sum < (__force u32)get_unaligned(&saddr->s6_addr32[2]));
 	sum += carry;
 
-	sum += (__force u32)saddr->s6_addr32[3];
-	carry = (sum < (__force u32)saddr->s6_addr32[3]);
+	sum += (__force u32)get_unaligned(&saddr->s6_addr32[3]);
+	carry = (sum < (__force u32)get_unaligned(&saddr->s6_addr32[3]));
 	sum += carry;
 
-	sum += (__force u32)daddr->s6_addr32[0];
-	carry = (sum < (__force u32)daddr->s6_addr32[0]);
+	sum += (__force u32)get_unaligned(&daddr->s6_addr32[0]);
+	carry = (sum < (__force u32)get_unaligned(&daddr->s6_addr32[0]));
 	sum += carry;
 
-	sum += (__force u32)daddr->s6_addr32[1];
-	carry = (sum < (__force u32)daddr->s6_addr32[1]);
+	sum += (__force u32)get_unaligned(&daddr->s6_addr32[1]);
+	carry = (sum < (__force u32)get_unaligned(&daddr->s6_addr32[1]));
 	sum += carry;
 
-	sum += (__force u32)daddr->s6_addr32[2];
-	carry = (sum < (__force u32)daddr->s6_addr32[2]);
+	sum += (__force u32)get_unaligned(&daddr->s6_addr32[2]);
+	carry = (sum < (__force u32)get_unaligned(&daddr->s6_addr32[2]));
 	sum += carry;
 
-	sum += (__force u32)daddr->s6_addr32[3];
-	carry = (sum < (__force u32)daddr->s6_addr32[3]);
+	sum += (__force u32)get_unaligned(&daddr->s6_addr32[3]);
+	carry = (sum < (__force u32)get_unaligned(&daddr->s6_addr32[3]));
 	sum += carry;
 
 	ulen = (__force u32)htonl((__u32) len);