From 17baf0f415bbe0b1dbccad50af5a8c5d5f288cc6 Mon Sep 17 00:00:00 2001
From: Sven Eckelmann <sven@narfation.org>
Date: Sun, 22 Nov 2020 14:02:32 +0100
Subject: [PATCH] ipq40xx: add support for Plasma Cloud PA1200

---
 docs/user/supported_devices.rst               |   4 +
 .../luasrc/lib/gluon/upgrade/010-primary-mac  |   1 +
 .../luasrc/usr/lib/lua/gluon/platform.lua     |   5 +-
 ...-for-openmesh.sh-to-vendor-free-name.patch | 249 +++++++++
 ...-add-support-for-Plasma-Cloud-PA1200.patch | 477 ++++++++++++++++++
 targets/ipq40xx-generic                       |   5 +
 6 files changed, 740 insertions(+), 1 deletion(-)
 create mode 100644 patches/openwrt/0021-ipq40xx-Change-name-for-openmesh.sh-to-vendor-free-name.patch
 create mode 100644 patches/openwrt/0022-ipq40xx-add-support-for-Plasma-Cloud-PA1200.patch

diff --git a/docs/user/supported_devices.rst b/docs/user/supported_devices.rst
index f7375c28..c49c7a55 100644
--- a/docs/user/supported_devices.rst
+++ b/docs/user/supported_devices.rst
@@ -260,6 +260,10 @@ ipq40xx-generic
   - A42
   - A62
 
+* Plasma Cloud
+
+  - PA1200
+
 * ZyXEL
 
   - NBG6617
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
index f4cbfdab..e1d3b97f 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
@@ -113,6 +113,7 @@ local primary_addrs = {
 		{'brcm2708'},
 		{'ipq40xx', 'generic', {
 			'avm,fritzbox-4040',
+			'plasmacloud,pa1200',
 		}},
 		{'ipq806x', 'generic', {
 			'netgear,r7800',
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
index fb569903..bcd0bf6f 100644
--- a/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
@@ -59,7 +59,10 @@ function M.is_outdoor_device()
 	}) then
 		return true
 
-	elseif M.match('ipq40xx', 'generic', {'engenius,ens620ext'}) then
+	elseif M.match('ipq40xx', 'generic', {
+		'engenius,ens620ext',
+		'plasmacloud,pa1200',
+	}) then
 		return true
 	end
 
diff --git a/patches/openwrt/0021-ipq40xx-Change-name-for-openmesh.sh-to-vendor-free-name.patch b/patches/openwrt/0021-ipq40xx-Change-name-for-openmesh.sh-to-vendor-free-name.patch
new file mode 100644
index 00000000..ebe4581a
--- /dev/null
+++ b/patches/openwrt/0021-ipq40xx-Change-name-for-openmesh.sh-to-vendor-free-name.patch
@@ -0,0 +1,249 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 21 Nov 2020 22:27:11 +0100
+Subject: ipq40xx: Change name for openmesh.sh to vendor-free name
+
+Other vendors are using functionality similar to the ones OpenMesh used to
+implement two areas on the flash to store the default image and a fallback
+image. So just change the name to dualboot_datachk.sh to avoid duplicated
+code just to have the same script for different vendors.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Origin: backport, https://github.com/openwrt/openwrt/commit/8a891bfaa01d9592ea86c6b0cbbd5c04688c09f8
+
+diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh b/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh
+new file mode 100644
+index 0000000000000000000000000000000000000000..807a85d43ccd57642b52e7c1a7f92295cb6cd036
+--- /dev/null
++++ b/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh
+@@ -0,0 +1,106 @@
++# The U-Boot loader with the datachk patchset for dualbooting requires image
++# sizes and checksums to be provided in the U-Boot environment.
++# The devices come with 2 main partitions - while one is active
++# sysupgrade will flash the other. The boot order is changed to boot the
++# newly flashed partition. If the new partition can't be booted due to
++# upgrade failures the previously used partition is loaded.
++
++platform_do_upgrade_dualboot_datachk() {
++	local tar_file="$1"
++	local restore_backup
++	local primary_kernel_mtd
++
++	local setenv_script="/tmp/fw_env_upgrade"
++
++	local kernel_mtd="$(find_mtd_index $PART_NAME)"
++	local kernel_offset="$(cat /sys/class/mtd/mtd${kernel_mtd}/offset)"
++	local total_size="$(cat /sys/class/mtd/mtd${kernel_mtd}/size)"
++
++	# detect to which flash region the new image is written to.
++	#
++	# 1. check what is the mtd index for the first flash region on this
++	#    device
++	# 2. check if the target partition ("inactive") has the mtd index of
++	#    the first flash region
++	#
++	#    - when it is: the new bootseq will be 1,2 and the first region is
++	#      modified
++	#    - when it isnt: bootseq will be 2,1 and the second region is
++	#      modified
++	#
++	# The detection has to be done via the hardcoded mtd partition because
++	# the current boot might be done with the fallback region. Let us
++	# assume that the current bootseq is 1,2. The bootloader detected that
++	# the image in flash region 1 is corrupt and thus switches to flash
++	# region 2. The bootseq in the u-boot-env is now still the same and
++	# the sysupgrade code can now only rely on the actual mtd indexes and
++	# not the bootseq variable to detect the currently booted flash
++	# region/image.
++	#
++	# In the above example, an implementation which uses bootseq ("1,2") to
++	# detect the currently booted image would assume that region 1 is booted
++	# and then overwrite the variables for the wrong flash region (aka the
++	# one which isn't modified). This could result in a device which doesn't
++	# boot anymore to Linux until it was reflashed with ap51-flash.
++	local next_boot_part="1"
++	case "$(board_name)" in
++	openmesh,a42)
++		primary_kernel_mtd=8
++		;;
++	openmesh,a62)
++		primary_kernel_mtd=10
++		;;
++	*)
++		echo "failed to detect primary kernel mtd partition for board"
++		return 1
++		;;
++	esac
++	[ "$kernel_mtd" = "$primary_kernel_mtd" ] || next_boot_part="2"
++
++	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
++	board_dir=${board_dir%/}
++
++	local kernel_length=$(tar xf $tar_file ${board_dir}/kernel -O | wc -c)
++	local rootfs_length=$(tar xf $tar_file ${board_dir}/root -O | wc -c)
++	# rootfs without EOF marker
++	rootfs_length=$((rootfs_length-4))
++
++	local kernel_md5=$(tar xf $tar_file ${board_dir}/kernel -O | md5sum); kernel_md5="${kernel_md5%% *}"
++	# md5 checksum of rootfs with EOF marker
++	local rootfs_md5=$(tar xf $tar_file ${board_dir}/root -O | dd bs=1 count=$rootfs_length | md5sum); rootfs_md5="${rootfs_md5%% *}"
++
++	#
++	# add tar support to get_image() to use default_do_upgrade() instead?
++	#
++
++	# take care of restoring a saved config
++	[ -n "$UPGRADE_BACKUP" ] && restore_backup="${MTD_CONFIG_ARGS} -j ${UPGRADE_BACKUP}"
++
++	mtd -q erase inactive
++	tar xf $tar_file ${board_dir}/root -O | mtd -n -p $kernel_length $restore_backup write - $PART_NAME
++	tar xf $tar_file ${board_dir}/kernel -O | mtd -n write - $PART_NAME
++
++	# prepare new u-boot env
++	if [ "$next_boot_part" = "1" ]; then
++		echo "bootseq 1,2" > $setenv_script
++	else
++		echo "bootseq 2,1" > $setenv_script
++	fi
++
++	printf "kernel_size_%i 0x%08x\n" $next_boot_part $kernel_length >> $setenv_script
++	printf "vmlinux_start_addr 0x%08x\n" ${kernel_offset} >> $setenv_script
++	printf "vmlinux_size 0x%08x\n" ${kernel_length} >> $setenv_script
++	printf "vmlinux_checksum %s\n" ${kernel_md5} >> $setenv_script
++
++	printf "rootfs_size_%i 0x%08x\n" $next_boot_part $((total_size-kernel_length)) >> $setenv_script
++	printf "rootfs_start_addr 0x%08x\n" $((kernel_offset+kernel_length)) >> $setenv_script
++	printf "rootfs_size 0x%08x\n" ${rootfs_length} >> $setenv_script
++	printf "rootfs_checksum %s\n" ${rootfs_md5} >> $setenv_script
++
++	# store u-boot env changes
++	mkdir -p /var/lock
++	fw_setenv -s $setenv_script || {
++		echo "failed to update U-Boot environment"
++		return 1
++	}
++}
+diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh b/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh
+deleted file mode 100644
+index 8e02186eb81b17d56d0cb8ceba95dbe506e2984b..0000000000000000000000000000000000000000
+--- a/target/linux/ipq40xx/base-files/lib/upgrade/openmesh.sh
++++ /dev/null
+@@ -1,106 +0,0 @@
+-# The U-Boot loader of the OpenMesh devices requires image sizes and
+-# checksums to be provided in the U-Boot environment.
+-# The OpenMesh devices come with 2 main partitions - while one is active
+-# sysupgrade will flash the other. The boot order is changed to boot the
+-# newly flashed partition. If the new partition can't be booted due to
+-# upgrade failures the previously used partition is loaded.
+-
+-platform_do_upgrade_openmesh() {
+-	local tar_file="$1"
+-	local restore_backup
+-	local primary_kernel_mtd
+-
+-	local setenv_script="/tmp/fw_env_upgrade"
+-
+-	local kernel_mtd="$(find_mtd_index $PART_NAME)"
+-	local kernel_offset="$(cat /sys/class/mtd/mtd${kernel_mtd}/offset)"
+-	local total_size="$(cat /sys/class/mtd/mtd${kernel_mtd}/size)"
+-
+-	# detect to which flash region the new image is written to.
+-	#
+-	# 1. check what is the mtd index for the first flash region on this
+-	#    device
+-	# 2. check if the target partition ("inactive") has the mtd index of
+-	#    the first flash region
+-	#
+-	#    - when it is: the new bootseq will be 1,2 and the first region is
+-	#      modified
+-	#    - when it isnt: bootseq will be 2,1 and the second region is
+-	#      modified
+-	#
+-	# The detection has to be done via the hardcoded mtd partition because
+-	# the current boot might be done with the fallback region. Let us
+-	# assume that the current bootseq is 1,2. The bootloader detected that
+-	# the image in flash region 1 is corrupt and thus switches to flash
+-	# region 2. The bootseq in the u-boot-env is now still the same and
+-	# the sysupgrade code can now only rely on the actual mtd indexes and
+-	# not the bootseq variable to detect the currently booted flash
+-	# region/image.
+-	#
+-	# In the above example, an implementation which uses bootseq ("1,2") to
+-	# detect the currently booted image would assume that region 1 is booted
+-	# and then overwrite the variables for the wrong flash region (aka the
+-	# one which isn't modified). This could result in a device which doesn't
+-	# boot anymore to Linux until it was reflashed with ap51-flash.
+-	local next_boot_part="1"
+-	case "$(board_name)" in
+-	openmesh,a42)
+-		primary_kernel_mtd=8
+-		;;
+-	openmesh,a62)
+-		primary_kernel_mtd=10
+-		;;
+-	*)
+-		echo "failed to detect primary kernel mtd partition for board"
+-		return 1
+-		;;
+-	esac
+-	[ "$kernel_mtd" = "$primary_kernel_mtd" ] || next_boot_part="2"
+-
+-	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
+-	board_dir=${board_dir%/}
+-
+-	local kernel_length=$(tar xf $tar_file ${board_dir}/kernel -O | wc -c)
+-	local rootfs_length=$(tar xf $tar_file ${board_dir}/root -O | wc -c)
+-	# rootfs without EOF marker
+-	rootfs_length=$((rootfs_length-4))
+-
+-	local kernel_md5=$(tar xf $tar_file ${board_dir}/kernel -O | md5sum); kernel_md5="${kernel_md5%% *}"
+-	# md5 checksum of rootfs with EOF marker
+-	local rootfs_md5=$(tar xf $tar_file ${board_dir}/root -O | dd bs=1 count=$rootfs_length | md5sum); rootfs_md5="${rootfs_md5%% *}"
+-
+-	#
+-	# add tar support to get_image() to use default_do_upgrade() instead?
+-	#
+-
+-	# take care of restoring a saved config
+-	[ -n "$UPGRADE_BACKUP" ] && restore_backup="${MTD_CONFIG_ARGS} -j ${UPGRADE_BACKUP}"
+-
+-	mtd -q erase inactive
+-	tar xf $tar_file ${board_dir}/root -O | mtd -n -p $kernel_length $restore_backup write - $PART_NAME
+-	tar xf $tar_file ${board_dir}/kernel -O | mtd -n write - $PART_NAME
+-
+-	# prepare new u-boot env
+-	if [ "$next_boot_part" = "1" ]; then
+-		echo "bootseq 1,2" > $setenv_script
+-	else
+-		echo "bootseq 2,1" > $setenv_script
+-	fi
+-
+-	printf "kernel_size_%i 0x%08x\n" $next_boot_part $kernel_length >> $setenv_script
+-	printf "vmlinux_start_addr 0x%08x\n" ${kernel_offset} >> $setenv_script
+-	printf "vmlinux_size 0x%08x\n" ${kernel_length} >> $setenv_script
+-	printf "vmlinux_checksum %s\n" ${kernel_md5} >> $setenv_script
+-
+-	printf "rootfs_size_%i 0x%08x\n" $next_boot_part $((total_size-kernel_length)) >> $setenv_script
+-	printf "rootfs_start_addr 0x%08x\n" $((kernel_offset+kernel_length)) >> $setenv_script
+-	printf "rootfs_size 0x%08x\n" ${rootfs_length} >> $setenv_script
+-	printf "rootfs_checksum %s\n" ${rootfs_md5} >> $setenv_script
+-
+-	# store u-boot env changes
+-	mkdir -p /var/lock
+-	fw_setenv -s $setenv_script || {
+-		echo "failed to update U-Boot environment"
+-		return 1
+-	}
+-}
+diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+index 7253139497a8a8b9fab49cef3fce5eabe98d8002..66e23b77a7bb0a484e88a11eed9d526e4fc04b50 100644
+--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
++++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+@@ -75,7 +75,7 @@ platform_do_upgrade() {
+ 	openmesh,a42 |\
+ 	openmesh,a62)
+ 		PART_NAME="inactive"
+-		platform_do_upgrade_openmesh "$1"
++		platform_do_upgrade_dualboot_datachk "$1"
+ 		;;
+ 	zyxel,nbg6617)
+ 		zyxel_do_upgrade "$1"
diff --git a/patches/openwrt/0022-ipq40xx-add-support-for-Plasma-Cloud-PA1200.patch b/patches/openwrt/0022-ipq40xx-add-support-for-Plasma-Cloud-PA1200.patch
new file mode 100644
index 00000000..aec18d51
--- /dev/null
+++ b/patches/openwrt/0022-ipq40xx-add-support-for-Plasma-Cloud-PA1200.patch
@@ -0,0 +1,477 @@
+From: Marek Lindner <marek.lindner@kaiwoo.ai>
+Date: Sun, 25 Nov 2018 21:46:54 +0800
+Subject: ipq40xx: add support for Plasma Cloud PA1200
+
+Device specifications:
+
+* QCA IPQ4018
+* 256 MB of RAM
+* 32 MB of SPI NOR flash (w25q256)
+  - 2x 15 MB available; but one of the 15 MB regions is the recovery image
+* 2T2R 2.4 GHz
+  - QCA4019 hw1.0 (SoC)
+  - requires special BDF in QCA4019/hw1.0/board-2.bin with
+    bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=PlasmaCloud-PA1200
+* 2T2R 5 GHz
+  - QCA4019 hw1.0 (SoC)
+  - requires special BDF in QCA4019/hw1.0/board-2.bin with
+    bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=PlasmaCloud-PA1200
+* 3x GPIO-LEDs for status (cyan, purple, yellow)
+* 1x GPIO-button (reset)
+* 1x USB (xHCI)
+* TTL pins are on board (arrow points to VCC, then follows: GND, TX, RX)
+* 2x gigabit ethernet
+  - phy@mdio4:
+    + Label: Ethernet 1
+    + gmac0 (ethaddr) in original firmware
+    + used as LAN interface
+  - phy@mdio3:
+    + Label: Ethernet 2
+    + gmac1 (eth1addr) in original firmware
+    + 802.3af/at POE(+)
+    + used as WAN interface
+* 12V/24V 1A DC
+
+Flashing instructions:
+
+The tool ap51-flash (https://github.com/ap51-flash/ap51-flash) should be
+used to transfer the factory image to the u-boot when the device boots up.
+
+Signed-off-by: Marek Lindner <marek.lindner@kaiwoo.ai>
+[sven@narfation.org: prepare commit message, rebase, use all LEDs, switch
+to dualboot_datachk upgrade script, use eth1 as designated WAN interface]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Origin: backport, https://github.com/openwrt/openwrt/commit/ea5bb6bbfee06f44f714aff40c8929505face221
+
+diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
+index 7bcad00b010bfef49790c2699995c00573ed53ad..3d31de8083b63516322ca33e9de792a592cf4bf1 100644
+--- a/package/boot/uboot-envtools/files/ipq40xx
++++ b/package/boot/uboot-envtools/files/ipq40xx
+@@ -34,7 +34,8 @@ case "$board" in
+ alfa-network,ap120c-ac |\
+ glinet,gl-b1300 |\
+ openmesh,a42 |\
+-openmesh,a62)
++openmesh,a62 |\
++plasmacloud,pa1200)
+ 	ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x10000" "0x10000"
+ 	;;
+ linksys,ea6350v3)
+diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
+index cc0505b97c6a04bafd88972cf6ce7890a637c33b..5e181f67437ec644d07d8fc4882908549d3d60ef 100644
+--- a/package/firmware/ipq-wifi/Makefile
++++ b/package/firmware/ipq-wifi/Makefile
+@@ -34,6 +34,7 @@ ALLWIFIBOARDS:= \
+ 	engenius_ens620ext \
+ 	linksys_ea6350v3 \
+ 	linksys_ea8300 \
++	plasmacloud_pa1200 \
+ 	qxwlan_e2600ac
+ 
+ ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD))
+@@ -107,6 +108,7 @@ $(eval $(call generate-ipq-wifi-package,engenius_eap1300,EnGenius EAP1300))
+ $(eval $(call generate-ipq-wifi-package,engenius_ens620ext,EnGenius ENS620EXT))
+ $(eval $(call generate-ipq-wifi-package,linksys_ea6350v3,Linksys EA6350v3))
+ $(eval $(call generate-ipq-wifi-package,linksys_ea8300,Linksys EA8300))
++$(eval $(call generate-ipq-wifi-package,plasmacloud_pa1200,Plasma Cloud PA1200))
+ $(eval $(call generate-ipq-wifi-package,qxwlan_e2600ac,Qxwlan E2600AC))
+ 
+ $(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))
+diff --git a/package/firmware/ipq-wifi/board-plasmacloud_pa1200.qca4019 b/package/firmware/ipq-wifi/board-plasmacloud_pa1200.qca4019
+new file mode 100644
+index 0000000000000000000000000000000000000000..99d6df8c8c2bd6ed8058b290e00aef09d74dbfb8
+GIT binary patch
+literal 24324
+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
+
+literal 0
+HcmV?d00001
+
+diff --git a/scripts/om-fwupgradecfg-gen.sh b/scripts/om-fwupgradecfg-gen.sh
+index e271fa0dacad837191eaab7683ad8880d183a75e..552ed31f147df442926a39f7e2c8b3bd7b706571 100755
+--- a/scripts/om-fwupgradecfg-gen.sh
++++ b/scripts/om-fwupgradecfg-gen.sh
+@@ -7,7 +7,7 @@
+ #
+ 
+ usage() {
+-	echo "Usage: $0 <OM2P|OM5P|OM5PAC|MR600|MR900|MR1750|A60|A42|A62|PA300> <out file path> <kernel path> <rootfs path>"
++	echo "Usage: $0 <OM2P|OM5P|OM5PAC|MR600|MR900|MR1750|A60|A42|A62|PA300|PA1200> <out file path> <kernel path> <rootfs path>"
+ 	rm -f $CFG_OUT
+ 	exit 1
+ }
+@@ -37,7 +37,7 @@ case $CE_TYPE in
+ 		SIZE_FACTOR=1
+ 		SIZE_FORMAT="%d"
+ 		;;
+-	A42)
++	A42|PA1200)
+ 		MAX_PART_SIZE=15616
+ 		KERNEL_FLASH_ADDR=0x180000
+ 		FLASH_BS=65536
+diff --git a/target/linux/ipq40xx/base-files/etc/board.d/02_network b/target/linux/ipq40xx/base-files/etc/board.d/02_network
+index 49dd570242533068adf2c9df89e78560ba5f70eb..f446c04a00c863173c8fcb8242f7b2db1569acb3 100755
+--- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
++++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
+@@ -14,7 +14,8 @@ ipq40xx_setup_interfaces()
+ 	case "$board" in
+ 	8dev,jalapeno|\
+ 	alfa-network,ap120c-ac|\
+-	engenius,ens620ext)
++	engenius,ens620ext|\
++	plasmacloud,pa1200)
+ 		ucidef_set_interfaces_lan_wan "eth0" "eth1"
+ 		;;
+ 	asus,map-ac2200|\
+diff --git a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+index 15a2f2c09f8a92cc0accfbf9a977dbeb3355570d..28c34f6d0f9ebb47d0b2705e2edd5a55cc2e22eb 100644
+--- a/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
++++ b/target/linux/ipq40xx/base-files/etc/hotplug.d/firmware/11-ath10k-caldata
+@@ -165,6 +165,7 @@ case "$FIRMWARE" in
+ 	engenius,eap1300 |\
+ 	openmesh,a42 |\
+ 	openmesh,a62 |\
++	plasmacloud,pa1200 |\
+ 	qxwlan,e2600ac-c1 |\
+ 	qxwlan,e2600ac-c2)
+ 		ath10kcal_extract "0:ART" 4096 12064
+@@ -231,6 +232,7 @@ case "$FIRMWARE" in
+ 	engenius,eap1300 |\
+ 	openmesh,a42 |\
+ 	openmesh,a62 |\
++	plasmacloud,pa1200 |\
+ 	qxwlan,e2600ac-c1 |\
+ 	qxwlan,e2600ac-c2)
+ 		ath10kcal_extract "0:ART" 20480 12064
+diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh b/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh
+index 807a85d43ccd57642b52e7c1a7f92295cb6cd036..60886071c9748407746ca9adfab52a1da9e524f2 100644
+--- a/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh
++++ b/target/linux/ipq40xx/base-files/lib/upgrade/dualboot_datachk.sh
+@@ -44,6 +44,7 @@ platform_do_upgrade_dualboot_datachk() {
+ 	# boot anymore to Linux until it was reflashed with ap51-flash.
+ 	local next_boot_part="1"
+ 	case "$(board_name)" in
++	plasmacloud,pa1200|\
+ 	openmesh,a42)
+ 		primary_kernel_mtd=8
+ 		;;
+diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+index 66e23b77a7bb0a484e88a11eed9d526e4fc04b50..6ec538cfd4cced656130169522cac1622a3b4ef2 100644
+--- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
++++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
+@@ -73,7 +73,8 @@ platform_do_upgrade() {
+ 		nand_do_upgrade "$1"
+ 		;;
+ 	openmesh,a42 |\
+-	openmesh,a62)
++	openmesh,a62 |\
++	plasmacloud,pa1200)
+ 		PART_NAME="inactive"
+ 		platform_do_upgrade_dualboot_datachk "$1"
+ 		;;
+diff --git a/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-pa1200.dts b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-pa1200.dts
+new file mode 100644
+index 0000000000000000000000000000000000000000..bcb9552ce777d1d522c7642649e22ec26f04d7d2
+--- /dev/null
++++ b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-pa1200.dts
+@@ -0,0 +1,197 @@
++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
++/* Copyright (c) 2017-2020, Sven Eckelmann <sven@narfation.org>
++ * Copyright (c) 2018, Marek Lindner <marek.lindner@kaiwoo.ai>
++ */
++
++#include "qcom-ipq4019.dtsi"
++#include <dt-bindings/gpio/gpio.h>
++#include <dt-bindings/input/input.h>
++#include <dt-bindings/soc/qcom,tcsr.h>
++
++/ {
++	model = "Plasma Cloud PA1200";
++	compatible = "plasmacloud,pa1200";
++
++	soc {
++		rng@22000 {
++			status = "okay";
++		};
++
++		mdio@90000 {
++			status = "okay";
++		};
++
++		ess-psgmii@98000 {
++			status = "okay";
++		};
++
++		tcsr@194b000 {
++			/* select hostmode */
++			compatible = "qcom,tcsr";
++			reg = <0x194b000 0x100>;
++			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
++			status = "okay";
++		};
++
++		tcsr@1949000 {
++			compatible = "qcom,tcsr";
++			reg = <0x1949000 0x100>;
++			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
++		};
++
++		ess_tcsr@1953000 {
++			compatible = "qcom,tcsr";
++			reg = <0x1953000 0x1000>;
++			qcom,ess-interface-select = <TCSR_ESS_PSGMII>;
++		};
++
++		tcsr@1957000 {
++			compatible = "qcom,tcsr";
++			reg = <0x1957000 0x100>;
++			qcom,wifi_noc_memtype_m0_m2 = <TCSR_WIFI_NOC_MEMTYPE_M0_M2>;
++		};
++
++		usb2: usb2@60f8800 {
++			status = "okay";
++		};
++
++		crypto@8e3a000 {
++			status = "okay";
++		};
++
++		watchdog@b017000 {
++			status = "okay";
++		};
++
++		ess-switch@c000000 {
++			status = "okay";
++		};
++
++		edma@c080000 {
++			status = "okay";
++		};
++	};
++
++	keys {
++		compatible = "gpio-keys";
++
++		reset {
++			label = "reset";
++			gpios = <&tlmm 59 GPIO_ACTIVE_LOW>;
++			linux,code = <KEY_RESTART>;
++		};
++	};
++
++	aliases {
++		led-boot = &led_status_purple;
++		led-failsafe = &led_status_yellow;
++		led-running = &led_status_cyan;
++		led-upgrade = &led_status_yellow;
++	};
++
++	leds {
++		compatible = "gpio-leds";
++
++		led_status_cyan: status_cyan {
++			label = "cyan:status";
++			gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
++		};
++
++		led_status_purple: status_purple {
++			label = "purple:status";
++			gpios = <&tlmm 1 GPIO_ACTIVE_HIGH>;
++		};
++
++		led_status_yellow: status_yellow {
++			label = "yellow:status";
++			gpios = <&tlmm 2 GPIO_ACTIVE_HIGH>;
++		};
++	};
++
++};
++
++&tlmm {
++	serial_pins: serial_pinmux {
++		mux {
++			pins = "gpio60", "gpio61";
++			function = "blsp_uart0";
++			bias-disable;
++		};
++	};
++
++	spi_0_pins: spi_0_pinmux {
++		pin {
++			function = "blsp_spi0";
++			pins = "gpio55", "gpio56", "gpio57";
++			drive-strength = <12>;
++			bias-disable;
++		};
++		pin_cs {
++			function = "gpio";
++			pins = "gpio54";
++			drive-strength = <2>;
++			bias-disable;
++			output-high;
++		};
++	};
++};
++
++&blsp_dma {
++	status = "okay";
++};
++
++&blsp1_spi1 {
++	pinctrl-0 = <&spi_0_pins>;
++	pinctrl-names = "default";
++	status = "okay";
++	cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
++
++	flash@0 {
++		#address-cells = <1>;
++		#size-cells = <1>;
++		compatible = "jedec,spi-nor";
++		reg = <0>;
++		spi-max-frequency = <24000000>;
++		/* partitions are passed via bootloader */
++	};
++};
++
++&blsp1_uart1 {
++	pinctrl-0 = <&serial_pins>;
++	pinctrl-names = "default";
++	status = "okay";
++};
++
++&cryptobam {
++	status = "okay";
++};
++
++&gmac0 {
++	qcom,phy_mdio_addr = <4>;
++	qcom,poll_required = <1>;
++	qcom,forced_speed = <1000>;
++	qcom,forced_duplex = <1>;
++	vlan_tag = <2 0x20>;
++};
++
++&gmac1 {
++	qcom,phy_mdio_addr = <3>;
++	qcom,poll_required = <1>;
++	qcom,forced_speed = <1000>;
++	qcom,forced_duplex = <1>;
++	vlan_tag = <1 0x10>;
++};
++
++&usb2_hs_phy {
++	status = "okay";
++};
++
++&wifi0 {
++	status = "okay";
++	qcom,ath10k-calibration-variant = "PlasmaCloud-PA1200";
++};
++
++&wifi1 {
++	status = "okay";
++	qcom,ath10k-calibration-variant = "PlasmaCloud-PA1200";
++};
+diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
+index 68dcbc59a42f6d8360b87c7b4e74cd34f697b465..e14d00ad08b8caf2dae935d573f0ba7bb0433c23 100644
+--- a/target/linux/ipq40xx/image/Makefile
++++ b/target/linux/ipq40xx/image/Makefile
+@@ -345,6 +345,21 @@ endef
+ 
+ TARGET_DEVICES += openmesh_a62
+ 
++define Device/plasmacloud_pa1200
++	$(call Device/FitImageLzma)
++	DEVICE_DTS := qcom-ipq4018-pa1200
++	DEVICE_DTS_CONFIG := config@pc.pa1200
++	BLOCKSIZE := 64k
++	DEVICE_TITLE := Plasma Cloud PA1200
++	KERNEL = kernel-bin | lzma | fit lzma $$(DTS_DIR)/$$(DEVICE_DTS).dtb | pad-to $$(BLOCKSIZE)
++	IMAGE_SIZE := 15616k
++	IMAGES = factory.bin sysupgrade.bin
++	IMAGE/factory.bin := append-rootfs | pad-rootfs | openmesh-image ce_type=PA1200
++	IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | sysupgrade-tar rootfs=$$$$@ | append-metadata
++	DEVICE_PACKAGES := uboot-envtools ipq-wifi-plasmacloud-pa1200
++endef
++TARGET_DEVICES += plasmacloud_pa1200
++
+ define Device/qcom_ap-dk01.1-c1
+ 	DEVICE_TITLE := QCA AP-DK01.1-C1
+ 	BOARD_NAME := ap-dk01.1-c1
+diff --git a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
+index fc8a88336491c2ac7c2a93fafb1f2b6fd38695be..cd0cd4164207f0a851d19a42fce07ad54fec8939 100644
+--- a/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
++++ b/target/linux/ipq40xx/patches-4.14/901-arm-boot-add-dts-files.patch
+@@ -10,7 +10,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ 
+ --- a/arch/arm/boot/dts/Makefile
+ +++ b/arch/arm/boot/dts/Makefile
+-@@ -697,7 +697,32 @@ dtb-$(CONFIG_ARCH_QCOM) += \
++@@ -697,7 +697,33 @@ dtb-$(CONFIG_ARCH_QCOM) += \
+  	qcom-apq8074-dragonboard.dtb \
+  	qcom-apq8084-ifc6540.dtb \
+  	qcom-apq8084-mtp.dtb \
+@@ -24,6 +24,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
+ +	qcom-ipq4018-fritz4040.dtb \
+ +	qcom-ipq4018-jalapeno.dtb \
+ +	qcom-ipq4018-nbg6617.dtb \
+++	qcom-ipq4018-pa1200.dtb \
+ +	qcom-ipq4018-rt-ac58u.dtb \
+ +	qcom-ipq4018-wre6606.dtb \
+  	qcom-ipq4019-ap.dk01.1-c1.dtb \
diff --git a/targets/ipq40xx-generic b/targets/ipq40xx-generic
index b533ed2d..e40c6822 100644
--- a/targets/ipq40xx-generic
+++ b/targets/ipq40xx-generic
@@ -90,6 +90,11 @@ device('openmesh-a62', 'openmesh_a62', {
 })
 
 
+-- Plasma Cloud
+
+device('plasma-cloud-pa1200', 'plasmacloud_pa1200')
+
+
 -- ZyXEL
 
 device('zyxel-nbg6617', 'zyxel_nbg6617')
-- 
GitLab