From 966f3987822cfec257e17efbb40b0e875788222b Mon Sep 17 00:00:00 2001
From: David Bauer <mail@david-bauer.net>
Date: Tue, 23 Jul 2019 00:00:45 +0200
Subject: [PATCH] modules: switch to OpenWrt 19.07

---
 modules                                       |   16 +-
 .../luasrc/lib/gluon/upgrade/500-opkg         |    2 +-
 ...lways-allow-password-less-root-login.patch |   38 +-
 ...or-VXLAN-over-link-local-IPv6-to-4.9.patch |  464 --------
 ...-support-for-ICMP-IGMP-type-matches.patch} |    0
 ...ath10k-ct-reduce-memory-consumption.patch} |    0
 ...xx-add-support-for-the-ZyXEL-NBG6617.patch | 1023 -----------------
 .../openwrt/0009-build-add-mkrasimage.patch   |  782 -------------
 ...0010-ipq40xx-fix-NBG6617-LED-mapping.patch |   27 -
 ...s-mktplinkfw2-add-split-uboot-layout.patch |   26 -
 ...ramips-add-support-for-Archer-C50-v4.patch |  370 ------
 ...ulticast-and-management-rate-control.patch |  420 -------
 ...ulticast-and-management-rate-control.patch |  316 -----
 ...ramips-add-support-for-Netgear-R6120.patch |  271 -----
 .../openwrt/0017-tools-add-zip-utility.patch  |  465 --------
 ...mware-utils-add-sercomm-netgear-tool.patch |  469 --------
 ...ect-multicast-broadcast-rate-setting.patch |  113 --
 ...ect-multicast-broadcast-rate-setting.patch |   60 -
 .../0021-ramips-fix-R6120-factory-image.patch |   26 -
 ...tils-tplink-safeloader-Add-CPE210-v3.patch |   58 -
 ...xx-Add-support-for-TP-Link-CPE210-v3.patch |  141 ---
 ...ramips-add-support-for-ASUS-RT-AC57U.patch |  292 -----
 ...ixes-for-bootloader-image-generation.patch |  111 --
 23 files changed, 28 insertions(+), 5462 deletions(-)
 delete mode 100644 patches/openwrt/0006-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6-to-4.9.patch
 rename patches/openwrt/{0007-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch => 0006-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch} (100%)
 rename patches/openwrt/{0011-ath10k-ct-reduce-memory-consumption.patch => 0007-ath10k-ct-reduce-memory-consumption.patch} (100%)
 delete mode 100644 patches/openwrt/0008-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch
 delete mode 100644 patches/openwrt/0009-build-add-mkrasimage.patch
 delete mode 100644 patches/openwrt/0010-ipq40xx-fix-NBG6617-LED-mapping.patch
 delete mode 100644 patches/openwrt/0012-tools-mktplinkfw2-add-split-uboot-layout.patch
 delete mode 100644 patches/openwrt/0013-ramips-add-support-for-Archer-C50-v4.patch
 delete mode 100644 patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch
 delete mode 100644 patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch
 delete mode 100644 patches/openwrt/0016-ramips-add-support-for-Netgear-R6120.patch
 delete mode 100644 patches/openwrt/0017-tools-add-zip-utility.patch
 delete mode 100644 patches/openwrt/0018-firmware-utils-add-sercomm-netgear-tool.patch
 delete mode 100644 patches/openwrt/0019-ath10k-ct-fix-incorrect-multicast-broadcast-rate-setting.patch
 delete mode 100644 patches/openwrt/0020-mac80211-ath10k-fix-incorrect-multicast-broadcast-rate-setting.patch
 delete mode 100644 patches/openwrt/0021-ramips-fix-R6120-factory-image.patch
 delete mode 100644 patches/openwrt/0022-firmware-utils-tplink-safeloader-Add-CPE210-v3.patch
 delete mode 100644 patches/openwrt/0023-ar71xx-Add-support-for-TP-Link-CPE210-v3.patch
 delete mode 100644 patches/openwrt/0024-ramips-add-support-for-ASUS-RT-AC57U.patch
 delete mode 100644 patches/openwrt/0025-uboot-fritz4040-add-fixes-for-bootloader-image-generation.patch

diff --git a/modules b/modules
index 06a2eae9d..e37d10bcd 100644
--- a/modules
+++ b/modules
@@ -1,20 +1,20 @@
 GLUON_FEEDS='packages routing luci gluon'
 
 OPENWRT_REPO=https://git.openwrt.org/openwrt/openwrt.git
-OPENWRT_BRANCH=openwrt-18.06
-OPENWRT_COMMIT=89808e211cd5ef5989bd0becb8cd45f9340610ff
+OPENWRT_BRANCH=openwrt-19.07
+OPENWRT_COMMIT=8cf67728d3b41c47ee5e322bb8c2908696380f24
 
 PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git
-PACKAGES_PACKAGES_BRANCH=openwrt-18.06
-PACKAGES_PACKAGES_COMMIT=1eeea30fda0f573e57cd00bd3560f7af63fa6d10
+PACKAGES_PACKAGES_BRANCH=openwrt-19.07
+PACKAGES_PACKAGES_COMMIT=702c655874db358706b7858445b06dba09c90cd6
 
 PACKAGES_ROUTING_REPO=https://github.com/openwrt-routing/packages.git
-PACKAGES_ROUTING_BRANCH=openwrt-18.06
-PACKAGES_ROUTING_COMMIT=7589804a56baac804421b492c93004c28a627abb
+PACKAGES_ROUTING_BRANCH=openwrt-19.07
+PACKAGES_ROUTING_COMMIT=8d5ee29f088e9dfaa49dc74573edb1919f14dbf4
 
 PACKAGES_LUCI_REPO=https://github.com/openwrt/luci.git
-PACKAGES_LUCI_BRANCH=openwrt-18.06
-PACKAGES_LUCI_COMMIT=b99e77d5c36a9d51559bae3bb61a138695d60b95
+PACKAGES_LUCI_BRANCH=openwrt-19.07
+PACKAGES_LUCI_COMMIT=7542d02cd23208ca2ed89ea5341d323ca3dc4e58
 
 PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git
 PACKAGES_GLUON_COMMIT=de7b228cae72e87f2dfb3eed5b0354bd7cec4ca7
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg
index eecedaf3a..bf0d15dcb 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg
@@ -14,7 +14,7 @@ local util = require 'gluon.util'
 local subst = {}
 
 
-local f = io.popen('. /etc/os-release; echo "$ID"; echo "$VERSION_ID"; echo "$LEDE_BOARD"; echo "$LEDE_ARCH"')
+local f = io.popen('. /etc/os-release; echo "$ID"; echo "$VERSION_ID"; echo "$OPENWRT_BOARD"; echo "$OPENWRT_ARCH"')
 subst['%%d'] = f:read()
 subst['%%v'] = f:read():gsub('-snapshot', '')
 subst['%%S'] = f:read()
diff --git a/patches/openwrt/0005-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch b/patches/openwrt/0005-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch
index a6e9213bf..d2010181b 100644
--- a/patches/openwrt/0005-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch
+++ b/patches/openwrt/0005-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch
@@ -6,24 +6,13 @@ Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
 
 diff --git a/package/network/services/dropbear/patches/700-failsafe-mode.patch b/package/network/services/dropbear/patches/700-failsafe-mode.patch
 new file mode 100644
-index 0000000000000000000000000000000000000000..d379da0d0a7890e0a25d87e227c2e065cd2750ee
+index 0000000000000000000000000000000000000000..bd9cf1ce4234d94bcc5b782cc753f59993f999bc
 --- /dev/null
 +++ b/package/network/services/dropbear/patches/700-failsafe-mode.patch
 @@ -0,0 +1,57 @@
-+--- a/runopts.h
-++++ b/runopts.h
-+@@ -98,6 +98,8 @@ typedef struct svr_runopts {
-+ 	int allowblankpass;
-+ 	unsigned int maxauthtries;
-+ 
-++	int failsafe_mode;
-++
-+ #ifdef ENABLE_SVR_REMOTETCPFWD
-+ 	int noremotetcp;
-+ #endif
 +--- a/svr-auth.c
 ++++ b/svr-auth.c
-+@@ -149,10 +149,11 @@ void recv_msg_userauth_request() {
++@@ -125,10 +125,11 @@ void recv_msg_userauth_request() {
 + 				AUTH_METHOD_NONE_LEN) == 0) {
 + 		TRACE(("recv_msg_userauth_request: 'none' request"))
 + 		if (valid_user
@@ -41,23 +30,23 @@ index 0000000000000000000000000000000000000000..d379da0d0a7890e0a25d87e227c2e065
 + 					"Auth succeeded with blank password for '%s' from %s",
 +--- a/svr-runopts.c
 ++++ b/svr-runopts.c
-+@@ -72,6 +72,7 @@ static void printhelp(const char * progn
++@@ -77,6 +77,7 @@ static void printhelp(const char * progn
 + 					"-s		Disable password logins\n"
 + 					"-g		Disable password logins for root\n"
 + 					"-B		Allow blank password logins\n"
 ++					"-f		Failsafe mode: always allow password-less root login\n"
 + #endif
-+ 					"-T <1 to %d> 	Maximum authentication tries (default %d)\n"
-+ #ifdef ENABLE_SVR_LOCALTCPFWD
-+@@ -133,6 +134,7 @@ void svr_getopts(int argc, char ** argv)
++ 					"-T		Maximum authentication tries (default %d)\n"
++ #if DROPBEAR_SVR_LOCALTCPFWD
++@@ -144,6 +145,7 @@ void svr_getopts(int argc, char ** argv)
 + 	svr_opts.noauthpass = 0;
 + 	svr_opts.norootpass = 0;
 + 	svr_opts.allowblankpass = 0;
 ++	svr_opts.failsafe_mode = 0;
-+ 	svr_opts.maxauthtries = DEFAULT_AUTH_TRIES;
++ 	svr_opts.maxauthtries = MAX_AUTH_TRIES;
 + 	svr_opts.inetdmode = 0;
 + 	svr_opts.portcount = 0;
-+@@ -251,6 +253,9 @@ void svr_getopts(int argc, char ** argv)
++@@ -266,6 +268,9 @@ void svr_getopts(int argc, char ** argv)
 + 				case 'B':
 + 					svr_opts.allowblankpass = 1;
 + 					break;
@@ -67,3 +56,14 @@ index 0000000000000000000000000000000000000000..d379da0d0a7890e0a25d87e227c2e065
 + #endif
 + 				case 'h':
 + 					printhelp(argv[0]);
++--- a/runopts.h
+++++ b/runopts.h
++@@ -106,6 +106,8 @@ typedef struct svr_runopts {
++ 	int allowblankpass;
++ 	unsigned int maxauthtries;
++ 
+++	int failsafe_mode;
+++
++ #if DROPBEAR_SVR_REMOTETCPFWD
++ 	int noremotetcp;
++ #endif
diff --git a/patches/openwrt/0006-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6-to-4.9.patch b/patches/openwrt/0006-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6-to-4.9.patch
deleted file mode 100644
index ccc1623ed..000000000
--- a/patches/openwrt/0006-generic-vxlan-backport-support-for-VXLAN-over-link-local-IPv6-to-4.9.patch
+++ /dev/null
@@ -1,464 +0,0 @@
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Tue, 9 Jan 2018 22:38:19 +0100
-Subject: generic: vxlan: backport support for VXLAN over link-local IPv6 to 4.9
-
-Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-
-diff --git a/target/linux/generic/backport-4.9/095-0001-vxlan-improve-validation-of-address-family-configura.patch b/target/linux/generic/backport-4.9/095-0001-vxlan-improve-validation-of-address-family-configura.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..2114562536675cd59450928f591e70d66f8fc7b9
---- /dev/null
-+++ b/target/linux/generic/backport-4.9/095-0001-vxlan-improve-validation-of-address-family-configura.patch
-@@ -0,0 +1,73 @@
-+From f45ba82cd83d27b5d44d3dc417e0e480ba0d3703 Mon Sep 17 00:00:00 2001
-+Message-Id: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Mon, 19 Jun 2017 10:03:57 +0200
-+Subject: [PATCH 1/4] vxlan: improve validation of address family configuration
-+
-+Address families of source and destination addresses must match, and
-+changelink operations can't change the address family.
-+
-+In addition, always use the VXLAN_F_IPV6 to check if a VXLAN device uses
-+IPv4 or IPv6.
-+
-+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-+Signed-off-by: David S. Miller <davem@davemloft.net>
-+[Matthias Schiffer: rebase to v4.9.y]
-+---
-+ drivers/net/vxlan.c | 23 +++++++++++++++--------
-+ 1 file changed, 15 insertions(+), 8 deletions(-)
-+
-+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
-+index 983e941bdf29..fbe8da7fa296 100644
-+--- a/drivers/net/vxlan.c
-++++ b/drivers/net/vxlan.c
-+@@ -2867,12 +2867,20 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
-+ 
-+ 	memcpy(&dst->remote_ip, &conf->remote_ip, sizeof(conf->remote_ip));
-+ 
-+-	/* Unless IPv6 is explicitly requested, assume IPv4 */
-+-	if (!dst->remote_ip.sa.sa_family)
-++	if (!dst->remote_ip.sa.sa_family && !conf->saddr.sa.sa_family) {
-++		/* Unless IPv6 is explicitly requested, assume IPv4 */
-+ 		dst->remote_ip.sa.sa_family = AF_INET;
-++		conf->saddr.sa.sa_family = AF_INET;
-++	} else if (!dst->remote_ip.sa.sa_family) {
-++		dst->remote_ip.sa.sa_family = conf->saddr.sa.sa_family;
-++	} else if (!conf->saddr.sa.sa_family) {
-++		conf->saddr.sa.sa_family = dst->remote_ip.sa.sa_family;
-++	}
-++
-++	if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
-++		return -EINVAL;
-+ 
-+-	if (dst->remote_ip.sa.sa_family == AF_INET6 ||
-+-	    vxlan->cfg.saddr.sa.sa_family == AF_INET6) {
-++	if (conf->saddr.sa.sa_family == AF_INET6) {
-+ 		if (!IS_ENABLED(CONFIG_IPV6))
-+ 			return -EPFNOSUPPORT;
-+ 		use_ipv6 = true;
-+@@ -2938,11 +2946,9 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
-+ 
-+ 	list_for_each_entry(tmp, &vn->vxlan_list, next) {
-+ 		if (tmp->cfg.vni == conf->vni &&
-+-		    (tmp->default_dst.remote_ip.sa.sa_family == AF_INET6 ||
-+-		     tmp->cfg.saddr.sa.sa_family == AF_INET6) == use_ipv6 &&
-+ 		    tmp->cfg.dst_port == vxlan->cfg.dst_port &&
-+-		    (tmp->flags & VXLAN_F_RCV_FLAGS) ==
-+-		    (vxlan->flags & VXLAN_F_RCV_FLAGS)) {
-++		    (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
-++		    (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6))) {
-+ 			pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni));
-+ 			return -EEXIST;
-+ 		}
-+@@ -2987,6 +2993,7 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
-+ 
-+ 	if (data[IFLA_VXLAN_GROUP]) {
-+ 		conf.remote_ip.sin.sin_addr.s_addr = nla_get_in_addr(data[IFLA_VXLAN_GROUP]);
-++		conf.remote_ip.sa.sa_family = AF_INET;
-+ 	} else if (data[IFLA_VXLAN_GROUP6]) {
-+ 		if (!IS_ENABLED(CONFIG_IPV6))
-+ 			return -EPFNOSUPPORT;
-+-- 
-+2.15.1
-+
-diff --git a/target/linux/generic/backport-4.9/095-0002-vxlan-check-valid-combinations-of-address-scopes.patch b/target/linux/generic/backport-4.9/095-0002-vxlan-check-valid-combinations-of-address-scopes.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..b38b9977bca192eafe9a0d9b8c36a120b3a2c590
---- /dev/null
-+++ b/target/linux/generic/backport-4.9/095-0002-vxlan-check-valid-combinations-of-address-scopes.patch
-@@ -0,0 +1,91 @@
-+From 0eb4ccfc77e07fb4bfc7b1778a7ecb136b47aba4 Mon Sep 17 00:00:00 2001
-+Message-Id: <0eb4ccfc77e07fb4bfc7b1778a7ecb136b47aba4.1515533863.git.mschiffer@universe-factory.net>
-+In-Reply-To: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+References: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Mon, 19 Jun 2017 10:03:58 +0200
-+Subject: [PATCH 2/4] vxlan: check valid combinations of address scopes
-+
-+* Multicast addresses are never valid as local address
-+* Link-local IPv6 unicast addresses may only be used as remote when the
-+  local address is link-local as well
-+* Don't allow link-local IPv6 local/remote addresses without interface
-+
-+We also store in the flags field if link-local addresses are used for the
-+follow-up patches that actually make VXLAN over link-local IPv6 work.
-+
-+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-+Signed-off-by: David S. Miller <davem@davemloft.net>
-+[Matthias Schiffer: rebase to v4.9.y]
-+---
-+ drivers/net/vxlan.c | 29 +++++++++++++++++++++++++++++
-+ include/net/vxlan.h |  1 +
-+ 2 files changed, 30 insertions(+)
-+
-+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
-+index fbe8da7fa296..863d9528b900 100644
-+--- a/drivers/net/vxlan.c
-++++ b/drivers/net/vxlan.c
-+@@ -2880,11 +2880,35 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
-+ 	if (conf->saddr.sa.sa_family != dst->remote_ip.sa.sa_family)
-+ 		return -EINVAL;
-+ 
-++	if (vxlan_addr_multicast(&conf->saddr))
-++		return -EINVAL;
-++
-+ 	if (conf->saddr.sa.sa_family == AF_INET6) {
-+ 		if (!IS_ENABLED(CONFIG_IPV6))
-+ 			return -EPFNOSUPPORT;
-+ 		use_ipv6 = true;
-+ 		vxlan->flags |= VXLAN_F_IPV6;
-++
-++		if (!(conf->flags & VXLAN_F_COLLECT_METADATA)) {
-++			int local_type =
-++				ipv6_addr_type(&conf->saddr.sin6.sin6_addr);
-++			int remote_type =
-++				ipv6_addr_type(&dst->remote_ip.sin6.sin6_addr);
-++
-++			if (local_type & IPV6_ADDR_LINKLOCAL) {
-++				if (!(remote_type & IPV6_ADDR_LINKLOCAL) &&
-++				    (remote_type != IPV6_ADDR_ANY))
-++					return -EINVAL;
-++
-++				vxlan->flags |= VXLAN_F_IPV6_LINKLOCAL;
-++			} else {
-++				if (remote_type ==
-++				    (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL))
-++					return -EINVAL;
-++
-++				vxlan->flags &= ~VXLAN_F_IPV6_LINKLOCAL;
-++			}
-++		}
-+ 	}
-+ 
-+ 	if (conf->label && !use_ipv6) {
-+@@ -2918,6 +2942,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
-+ 	} else if (vxlan_addr_multicast(&dst->remote_ip)) {
-+ 		pr_info("multicast destination requires interface to be specified\n");
-+ 		return -EINVAL;
-++	} else {
-++#if IS_ENABLED(CONFIG_IPV6)
-++		if (vxlan->flags & VXLAN_F_IPV6_LINKLOCAL)
-++			return -EINVAL;
-++#endif
-+ 	}
-+ 
-+ 	if (conf->mtu) {
-+diff --git a/include/net/vxlan.h b/include/net/vxlan.h
-+index 9fce47e3e13e..c1c0d03e3456 100644
-+--- a/include/net/vxlan.h
-++++ b/include/net/vxlan.h
-+@@ -267,6 +267,7 @@ struct vxlan_dev {
-+ #define VXLAN_F_REMCSUM_NOPARTIAL	0x1000
-+ #define VXLAN_F_COLLECT_METADATA	0x2000
-+ #define VXLAN_F_GPE			0x4000
-++#define VXLAN_F_IPV6_LINKLOCAL		0x8000
-+ 
-+ /* Flags that are used in the receive path. These flags must match in
-+  * order for a socket to be shareable
-+-- 
-+2.15.1
-+
-diff --git a/target/linux/generic/backport-4.9/095-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch b/target/linux/generic/backport-4.9/095-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..89523ac027b227a9f84b1130db06a7fc67ff68ce
---- /dev/null
-+++ b/target/linux/generic/backport-4.9/095-0003-vxlan-fix-snooping-for-link-local-IPv6-addresses.patch
-@@ -0,0 +1,88 @@
-+From 010b2b541d958e12d78ba1c79734c700f169610b Mon Sep 17 00:00:00 2001
-+Message-Id: <010b2b541d958e12d78ba1c79734c700f169610b.1515533863.git.mschiffer@universe-factory.net>
-+In-Reply-To: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+References: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Mon, 19 Jun 2017 10:03:59 +0200
-+Subject: [PATCH 3/4] vxlan: fix snooping for link-local IPv6 addresses
-+
-+If VXLAN is run over link-local IPv6 addresses, it is necessary to store
-+the ifindex in the FDB entries. Otherwise, the used interface is undefined
-+and unicast communication will most likely fail.
-+
-+Support for link-local IPv4 addresses should be possible as well, but as
-+the semantics aren't as well defined as for IPv6, and there doesn't seem to
-+be much interest in having the support, it's not implemented for now.
-+
-+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-+Signed-off-by: David S. Miller <davem@davemloft.net>
-+[Matthias Schiffer: rebase to v4.9.y]
-+---
-+ drivers/net/vxlan.c | 20 +++++++++++++++-----
-+ 1 file changed, 15 insertions(+), 5 deletions(-)
-+
-+--- a/drivers/net/vxlan.c
-++++ b/drivers/net/vxlan.c
-+@@ -917,16 +917,25 @@ out:
-+  * Return true if packet is bogus and should be dropped.
-+  */
-+ static bool vxlan_snoop(struct net_device *dev,
-+-			union vxlan_addr *src_ip, const u8 *src_mac)
-++			union vxlan_addr *src_ip, const u8 *src_mac,
-++			u32 src_ifindex)
-+ {
-+ 	struct vxlan_dev *vxlan = netdev_priv(dev);
-+ 	struct vxlan_fdb *f;
-++	u32 ifindex = 0;
-++
-++#if IS_ENABLED(CONFIG_IPV6)
-++	if (src_ip->sa.sa_family == AF_INET6 &&
-++	    (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL))
-++		ifindex = src_ifindex;
-++#endif
-+ 
-+ 	f = vxlan_find_mac(vxlan, src_mac);
-+ 	if (likely(f)) {
-+ 		struct vxlan_rdst *rdst = first_remote_rcu(f);
-+ 
-+-		if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip)))
-++		if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
-++			   rdst->remote_ifindex == ifindex))
-+ 			return false;
-+ 
-+ 		/* Don't migrate static entries, drop packets */
-+@@ -952,7 +961,7 @@ static bool vxlan_snoop(struct net_devic
-+ 					 NLM_F_EXCL|NLM_F_CREATE,
-+ 					 vxlan->cfg.dst_port,
-+ 					 vxlan->default_dst.remote_vni,
-+-					 0, NTF_SELF);
-++					 ifindex, NTF_SELF);
-+ 		spin_unlock(&vxlan->hash_lock);
-+ 	}
-+ 
-+@@ -1223,6 +1232,7 @@ static bool vxlan_set_mac(struct vxlan_d
-+ 			  struct sk_buff *skb)
-+ {
-+ 	union vxlan_addr saddr;
-++	u32 ifindex = skb->dev->ifindex;
-+ 
-+ 	skb_reset_mac_header(skb);
-+ 	skb->protocol = eth_type_trans(skb, vxlan->dev);
-+@@ -1244,7 +1254,7 @@ static bool vxlan_set_mac(struct vxlan_d
-+ 	}
-+ 
-+ 	if ((vxlan->flags & VXLAN_F_LEARN) &&
-+-	    vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source))
-++	    vxlan_snoop(skb->dev, &saddr, eth_hdr(skb)->h_source, ifindex))
-+ 		return false;
-+ 
-+ 	return true;
-+@@ -1939,7 +1949,7 @@ static void vxlan_encap_bypass(struct sk
-+ 	}
-+ 
-+ 	if (dst_vxlan->flags & VXLAN_F_LEARN)
-+-		vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source);
-++		vxlan_snoop(dev, &loopback, eth_hdr(skb)->h_source, 0);
-+ 
-+ 	u64_stats_update_begin(&tx_stats->syncp);
-+ 	tx_stats->tx_packets++;
-diff --git a/target/linux/generic/backport-4.9/095-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch b/target/linux/generic/backport-4.9/095-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..18ae230a3b04d2b57184109fa14f9533f0fb7192
---- /dev/null
-+++ b/target/linux/generic/backport-4.9/095-0004-vxlan-allow-multiple-VXLANs-with-same-VNI-for-IPv6-l.patch
-@@ -0,0 +1,182 @@
-+From 95583c75a95449dade713e1dad4ed0a8dcc1b391 Mon Sep 17 00:00:00 2001
-+Message-Id: <95583c75a95449dade713e1dad4ed0a8dcc1b391.1515533863.git.mschiffer@universe-factory.net>
-+In-Reply-To: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+References: <f45ba82cd83d27b5d44d3dc417e0e480ba0d3703.1515533863.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Mon, 19 Jun 2017 10:04:00 +0200
-+Subject: [PATCH 4/4] vxlan: allow multiple VXLANs with same VNI for IPv6
-+ link-local addresses
-+
-+As link-local addresses are only valid for a single interface, we can allow
-+to use the same VNI for multiple independent VXLANs, as long as the used
-+interfaces are distinct. This way, VXLANs can always be used as a drop-in
-+replacement for VLANs with greater ID space.
-+
-+This also extends VNI lookup to respect the ifindex when link-local IPv6
-+addresses are used, so using the same VNI on multiple interfaces can
-+actually work.
-+
-+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-+Signed-off-by: David S. Miller <davem@davemloft.net>
-+[Matthias Schiffer: rebase to v4.9.y]
-+---
-+ drivers/net/vxlan.c | 60 ++++++++++++++++++++++++++++++++++++-----------------
-+ 1 file changed, 41 insertions(+), 19 deletions(-)
-+
-+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
-+index c28c6f34b3b3..9208e3d9ec43 100644
-+--- a/drivers/net/vxlan.c
-++++ b/drivers/net/vxlan.c
-+@@ -225,7 +225,8 @@ static struct vxlan_sock *vxlan_find_sock(struct net *net, sa_family_t family,
-+ 	return NULL;
-+ }
-+ 
-+-static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
-++static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, int ifindex,
-++					   __be32 vni)
-+ {
-+ 	struct vxlan_dev_node *node;
-+ 
-+@@ -234,17 +235,27 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
-+ 		vni = 0;
-+ 
-+ 	hlist_for_each_entry_rcu(node, vni_head(vs, vni), hlist) {
-+-		if (node->vxlan->default_dst.remote_vni == vni)
-+-			return node->vxlan;
-++		if (node->vxlan->default_dst.remote_vni != vni)
-++			continue;
-++
-++		if (IS_ENABLED(CONFIG_IPV6)) {
-++			const struct vxlan_config *cfg = &node->vxlan->cfg;
-++
-++			if ((node->vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
-++			    cfg->remote_ifindex != ifindex)
-++				continue;
-++		}
-++
-++		return node->vxlan;
-+ 	}
-+ 
-+ 	return NULL;
-+ }
-+ 
-+ /* Look up VNI in a per net namespace table */
-+-static struct vxlan_dev *vxlan_find_vni(struct net *net, __be32 vni,
-+-					sa_family_t family, __be16 port,
-+-					u32 flags)
-++static struct vxlan_dev *vxlan_find_vni(struct net *net, int ifindex,
-++				        __be32 vni, sa_family_t family,
-++					__be16 port, u32 flags)
-+ {
-+ 	struct vxlan_sock *vs;
-+ 
-+@@ -252,7 +263,7 @@ static struct vxlan_dev *vxlan_find_vni(struct net *net, __be32 vni,
-+ 	if (!vs)
-+ 		return NULL;
-+ 
-+-	return vxlan_vs_find_vni(vs, vni);
-++	return vxlan_vs_find_vni(vs, ifindex, vni);
-+ }
-+ 
-+ /* Fill in neighbour message in skbuff. */
-+@@ -1317,7 +1328,8 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
-+ 	if (!vs)
-+ 		goto drop;
-+ 
-+-	vxlan = vxlan_vs_find_vni(vs, vxlan_vni(vxlan_hdr(skb)->vx_vni));
-++	vxlan = vxlan_vs_find_vni(vs, skb->dev->ifindex,
-++                                  vxlan_vni(vxlan_hdr(skb)->vx_vni));
-+ 	if (!vxlan)
-+ 		goto drop;
-+ 
-+@@ -1976,6 +1988,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 	__be32 vni, label;
-+ 	__be16 df = 0;
-+ 	__u8 tos, ttl;
-++	int ifindex;
-+ 	int err;
-+ 	u32 flags = vxlan->flags;
-+ 	bool udp_sum = false;
-+@@ -1987,6 +2000,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 	if (rdst) {
-+ 		dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port;
-+ 		vni = rdst->remote_vni;
-++		ifindex = rdst->remote_ifindex;
-+ 		dst = &rdst->remote_ip;
-+ 		local_ip = vxlan->cfg.saddr;
-+ 		dst_cache = &rdst->dst_cache;
-+@@ -1998,6 +2012,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 		}
-+ 		dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port;
-+ 		vni = tunnel_id_to_key32(info->key.tun_id);
-++		ifindex = 0;
-+ 		remote_ip.sa.sa_family = ip_tunnel_info_af(info);
-+ 		if (remote_ip.sa.sa_family == AF_INET) {
-+ 			remote_ip.sin.sin_addr.s_addr = info->key.u.ipv4.dst;
-+@@ -2053,7 +2068,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 		sk = sock4->sock->sk;
-+ 
-+ 		rt = vxlan_get_route(vxlan, skb,
-+-				     rdst ? rdst->remote_ifindex : 0, tos,
-++				     ifindex, tos,
-+ 				     dst->sin.sin_addr.s_addr,
-+ 				     &local_ip.sin.sin_addr.s_addr,
-+ 				     dst_cache, info);
-+@@ -2077,7 +2092,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 			struct vxlan_dev *dst_vxlan;
-+ 
-+ 			ip_rt_put(rt);
-+-			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
-++			dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
-+ 						   dst->sa.sa_family, dst_port,
-+ 						   vxlan->flags);
-+ 			if (!dst_vxlan)
-+@@ -2112,7 +2127,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 		sk = sock6->sock->sk;
-+ 
-+ 		ndst = vxlan6_get_route(vxlan, skb,
-+-					rdst ? rdst->remote_ifindex : 0, tos,
-++					ifindex, tos,
-+ 					label, &dst->sin6.sin6_addr,
-+ 					&local_ip.sin6.sin6_addr,
-+ 					dst_cache, info);
-+@@ -2138,7 +2153,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
-+ 			struct vxlan_dev *dst_vxlan;
-+ 
-+ 			dst_release(ndst);
-+-			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
-++			dst_vxlan = vxlan_find_vni(vxlan->net, ifindex, vni,
-+ 						   dst->sa.sa_family, dst_port,
-+ 						   vxlan->flags);
-+ 			if (!dst_vxlan)
-+@@ -2984,13 +2999,20 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
-+ 		vxlan->cfg.age_interval = FDB_AGE_DEFAULT;
-+ 
-+ 	list_for_each_entry(tmp, &vn->vxlan_list, next) {
-+-		if (tmp->cfg.vni == conf->vni &&
-+-		    tmp->cfg.dst_port == vxlan->cfg.dst_port &&
-+-		    (tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) ==
-+-		    (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6))) {
-+-			pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni));
-+-			return -EEXIST;
-+-		}
-++		if (tmp->cfg.vni != conf->vni)
-++			continue;
-++		if (tmp->cfg.dst_port != vxlan->cfg.dst_port)
-++			continue;
-++		if ((tmp->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)) !=
-++		    (vxlan->flags & (VXLAN_F_RCV_FLAGS | VXLAN_F_IPV6)))
-++			continue;
-++
-++		if ((vxlan->flags & VXLAN_F_IPV6_LINKLOCAL) &&
-++		    tmp->cfg.remote_ifindex != vxlan->cfg.remote_ifindex)
-++			continue;
-++
-++		pr_info("duplicate VNI %u\n", be32_to_cpu(conf->vni));
-++		return -EEXIST;
-+ 	}
-+ 
-+ 	dev->ethtool_ops = &vxlan_ethtool_ops;
-+-- 
-+2.15.1
-+
diff --git a/patches/openwrt/0007-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch b/patches/openwrt/0006-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch
similarity index 100%
rename from patches/openwrt/0007-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch
rename to patches/openwrt/0006-kernel-ebtables-add-support-for-ICMP-IGMP-type-matches.patch
diff --git a/patches/openwrt/0011-ath10k-ct-reduce-memory-consumption.patch b/patches/openwrt/0007-ath10k-ct-reduce-memory-consumption.patch
similarity index 100%
rename from patches/openwrt/0011-ath10k-ct-reduce-memory-consumption.patch
rename to patches/openwrt/0007-ath10k-ct-reduce-memory-consumption.patch
diff --git a/patches/openwrt/0008-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch b/patches/openwrt/0008-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch
deleted file mode 100644
index d80a24de0..000000000
--- a/patches/openwrt/0008-ipq40xx-add-support-for-the-ZyXEL-NBG6617.patch
+++ /dev/null
@@ -1,1023 +0,0 @@
-From: Christian Lamparter <chunkeey@googlemail.com>
-Date: Thu, 21 Jun 2018 14:24:59 +0200
-Subject: ipq40xx: add support for the ZyXEL NBG6617
-
-This patch adds support for ZyXEL NBG6617
-
-Hardware highlights:
-
-SOC:    IPQ4018 / QCA Dakota
-CPU:    Quad-Core ARMv7 Processor rev 5 (v7l) Cortex-A7
-DRAM:   256 MiB DDR3L-1600/1866 Nanya NT5CC128M16IP-DI @ 537 MHz
-NOR:    32 MiB Macronix MX25L25635F
-ETH:    Qualcomm Atheros QCA8075 Gigabit Switch (4 x LAN, 1 x WAN)
-USB:    1 x 3.0 (via Synopsys DesignWare DWC3 controller in the SoC)
-WLAN1:  Qualcomm Atheros QCA4018 2.4GHz 802.11bgn 2:2x2
-WLAN2:  Qualcomm Atheros QCA4018 5GHz 802.11a/n/ac 2:2x2
-INPUT:  RESET Button, WIFI/Rfkill Togglebutton, WPS Button
-LEDS:   Power, WAN, LAN 1-4, WLAN 2.4GHz, WLAN 5GHz, USB, WPS
-
-Serial:
-	WARNING: The serial port needs a TTL/RS-232 3.3v level converter!
-	The Serial setting is 115200-8-N-1. The 1x4 .1" header comes
-	pre-soldered. Pinout:
-	  1. 3v3 (Label printed on the PCB), 2. RX, 3. GND, 4. TX
-
-first install / debricking / restore stock:
- 0. Have a PC running a tftp-server @ 192.168.1.99/24
- 1. connect the PC to any LAN-Ports
- 2. put the openwrt...-factory.bin (or V1.00(ABCT.X).bin for stock) file
-    into the tftp-server root directory and rename it to just "ras.bin".
- 3. power-cycle the router and hold down the the WPS button (for 30sek)
- 4. Wait (for a long time - the serial console provides some progress
-    reports. The u-boot says it best: "Please be patient".
- 5. Once the power LED starts to flashes slowly and the USB + WPS LEDs
-    flashes fast at the same time. You have to reboot the device and
-    it should then come right up.
-
-Installation via Web-UI:
- 0. Connect a PC to the powered-on router. It will assign your PC a
-    IP-address via DHCP
- 1. Access the Web-UI at 192.168.1.1 (Default Passwort: 1234)
- 2. Go to the "Expert Mode"
- 3. Under "Maintenance", select "Firmware-Upgrade"
- 4. Upload the OpenWRT factory image
- 5. Wait for the Device to finish.
-    It will reboot into OpenWRT without any additional actions needed.
-
-To open the ZyXEL NBG6617:
- 0. remove the four rubber feet glued on the backside
- 1. remove the four philips screws and pry open the top cover
-    (by applying force between the plastic top housing from the
-    backside/lan-port side)
-
-Access the real u-boot shell:
-ZyXEL uses a proprietary loader/shell on top of u-boot: "ZyXEL zloader v2.02"
-When the device is starting up, the user can enter the the loader shell
-by simply pressing a key within the 3 seconds once the following string
-appears on the serial console:
-
-|   Hit any key to stop autoboot:  3
-
-The user is then dropped to a locked shell.
-
-|NBG6617> HELP
-|ATEN    x[,y]     set BootExtension Debug Flag (y=password)
-|ATSE    x         show the seed of password generator
-|ATSH              dump manufacturer related data in ROM
-|ATRT    [x,y,z,u] RAM read/write test (x=level, y=start addr, z=end addr, u=iterations)
-|ATGO              boot up whole system
-|ATUR    x         upgrade RAS image (filename)
-|NBG6617>
-
-In order to escape/unlock a password challenge has to be passed.
-Note: the value is dynamic! you have to calculate your own!
-
-First use ATSE $MODELNAME (MODELNAME is the hostname in u-boot env)
-to get the challange value/seed.
-
-|NBG6617> ATSE NBG6617
-|012345678901
-
-This seed/value can be converted to the password with the help of this
-bash script (Thanks to http://www.adslayuda.com/Zyxel650-9.html authors):
-
-- tool.sh -
-ror32() {
-  echo $(( ($1 >> $2) | (($1 << (32 - $2) & (2**32-1)) ) ))
-}
-v="0x$1"
-a="0x${v:2:6}"
-b=$(( $a + 0x10F0A563))
-c=$(( 0x${v:12:14} & 7 ))
-p=$(( $(ror32 $b $c) ^ $a ))
-printf "ATEN 1,%X\n" $p
-- end of tool.sh -
-
-|# bash ./tool.sh 012345678901
-|
-|ATEN 1,879C711
-
-copy and paste the result into the shell to unlock zloader.
-
-|NBG6617> ATEN 1,0046B0017430
-
-If the entered code was correct the shell will change to
-use the ATGU command to enter the real u-boot shell.
-
-|NBG6617> ATGU
-|NBG6617#
-
-Co-authored-by: David Bauer <mail@david-bauer.net>
-Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/include/image-commands.mk b/include/image-commands.mk
-index 4d3f025b123f44cfd48d5b6cf081ae7633577277..28b39c310e499caea4fe8a6d9ad6dceb5d95363b 100644
---- a/include/image-commands.mk
-+++ b/include/image-commands.mk
-@@ -49,6 +49,19 @@ define Build/eva-image
- 	mv $@.new $@
- endef
- 
-+define Build/make-ras
-+	let \
-+		newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
-+		$(TOPDIR)/scripts/make-ras.sh \
-+			--board $(RAS_BOARD) \
-+			--version $(RAS_VERSION) \
-+			--kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
-+			--rootfs $@ \
-+			--rootfssize $$newsize \
-+			$@.new
-+	@mv $@.new $@
-+endef
-+
- define Build/netgear-chk
- 	$(STAGING_DIR_HOST)/bin/mkchkimg \
- 		-o $@.new \
-diff --git a/package/boot/uboot-envtools/files/ipq40xx b/package/boot/uboot-envtools/files/ipq40xx
-index d475e566299416176af3b8646a7510cd3c9787e7..8cd4799b295fd38c9e846af5769c9fa9f5490f8b 100644
---- a/package/boot/uboot-envtools/files/ipq40xx
-+++ b/package/boot/uboot-envtools/files/ipq40xx
-@@ -35,6 +35,9 @@ openmesh,a42 |\
- openmesh,a62)
- 	ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x10000" "0x10000"
- 	;;
-+zyxel,nbg6617)
-+	ubootenv_add_uci_config "/dev/mtd6" "0x0" "0x10000" "0x10000"
-+	;;
- esac
- 
- config_load ubootenv
-diff --git a/package/firmware/ipq-wifi/Makefile b/package/firmware/ipq-wifi/Makefile
-index 1cfcc33de3af58e9773d22cdcbe0c95f1633e2d9..b1428f173ddb507f0c92313dcca7aae57284a0b8 100644
---- a/package/firmware/ipq-wifi/Makefile
-+++ b/package/firmware/ipq-wifi/Makefile
-@@ -14,7 +14,7 @@ define Build/Compile
- endef
- 
- #ALLWIFIBOARDS:=<devicename>
--ALLWIFIBOARDS:=zyxel_wre6606
-+ALLWIFIBOARDS:=zyxel_nbg6617 zyxel_wre6606
- ALLWIFIPACKAGES:=$(foreach BOARD,$(ALLWIFIBOARDS),ipq-wifi-$(BOARD))
- 
- define Package/ipq-wifi-default
-@@ -50,5 +50,6 @@ endef
- 
- $(eval $(call generate-ipq-wifi-package,zyxel_wre6606,board-zyxel_wre6606.bin,ZyXEL WRE6606))
- #$(eval $(call generate-ipq-wifi-package,<devicename>,<filename>,<displayname>))
-+$(eval $(call generate-ipq-wifi-package,zyxel_nbg6617,board-zyxel_nbg6617.bin,ZyXEL NBG6617))
- 
- $(foreach PACKAGE,$(ALLWIFIPACKAGES),$(eval $(call BuildPackage,$(PACKAGE))))
-diff --git a/package/firmware/ipq-wifi/board-zyxel_nbg6617.bin b/package/firmware/ipq-wifi/board-zyxel_nbg6617.bin
-new file mode 100644
-index 0000000000000000000000000000000000000000..ab4d43e8cbc949c06f74e332807b8d92239a7de0
-GIT binary patch
-literal 24276
-zcmeHPdr(tX8b3f3b+K|ohzNKIAwYr<AW#hwc}5x_1xpnPun5!#NsaO_AcQX1@j)RX
-z0<}O0pk+`VO%WN3FR)r$JEP40xwC(?JNxL)th07UyVK6>F7CNWZXS>;2@eZ$zi`g^
-z&f`1hJHLB!bMHMr?mLO`A@RFK;bEyE3F+|}LLisR0hFvzEC#?IhC)Tzj)J1X;6k}H
-z<h>$kafo#Pjxb%W@MuBlek>cl71}w#whU;;2(38j-~gOzsF9giA3;4Z$_HSbvnx~p
-zfbkm<I?Z~-;V`kT0Emc)`03d*2LWw0_~kF>V)5Wavu<ZY>D}pVn)D-q7f`0x5$896
-z6O4EeFQmY^=s$Q{%tu@|rLlAO*whKs))~iT0R6|J8fIuz^O9Jav$ON6RjZuL1b{ns
-z%+wurXCCM<ZywA?vqj$k#g=x<p-pk)5VmX#V(Ibtkh-DrKz3>}fBc%drBa@~J2_!|
-zKz*jZRQgWx*6~58l}R&_-~0v2gKs#2VEi+6ePv;GGOQd{H&sfrcO}P+_hZdq86O%n
-z)K_GSlcRM84+De1_*L~;IKtb>QRAOO1DVdC4|Y<Noyup!?wTu$vorW%27^FL|7OWm
-zLYbwBWi@GFiHG&v>wuE=nJur<-iCsTr~`qS-l_LmN^6qj+<oo|cLqw@lg_Y9J@VTJ
-zbK0ZMFv{Et`sxc5QH25TZce`4bfkKxG&sjS=Ij2-PtwnD%QnAvbFiZQ?S_yF?}MXf
-zi;l+};AA3Ew_rP=jGN;YbGc92CaT|3;Z=0wv-0lH8lPgf{N;rb=`D`HD(AJoS-$~s
-zbKkhhYcqbrH%qZ|?8^l9122fM$kEZ!0gIiS;Lq}EgE)`16^j@TKiI`XSu8*J=g;)@
-z^<(-nnVFO|z;K0v`$DFRk3d#dMjDgp0|)x~=Vw1oO<`9+e2%}LzU;q0{_zL%GOXcd
-z7iUKb<$ti<26(_s_RpU`eWGu>*j^V8!Rrw?NO4W$5EiiUA`QZW62=V<VzZZ~W(^wz
-zMUZ$j9tlUokzz$v&B>1%TiRwSfQ?B|P|$!;5g6pQQSmfLhf$%TR4(-q74bwpxt?NI
-z)D`hS6VL>1!lMKv1x?|mh~v;WM1=BC9+&rshipf;bGM7b&@hCL8lBKwvaSLaD@-r!
-zEAv-%vx5^13h1-0;?ooej5A(D)!QhYM$MZ*r5UBwsL{+->phsYbwk~rx*=Yu7uQRi
-zh$cQwL{iaIZmKu}jd&V?M5EE%XmM3dRSmv0^aq5=4Cq6<ULNaE(*s5r>)g}N%@FHc
-z)6c*VV{5ngBh8R`@Smrc{j^wBt$knSTJ}0zlah0=<>-?rkth)$KrRgeU@VGPBuW+t
-zkQovI5&;qc5&;qc5`h(rz((Fi#E1G8?=2*qx{bFDiKVW=1!NR9UmCe@9_#M4?T%)S
-zu@;vF8)F3@LUQVMBJg~M*xA8iHMez#z}9w)<>w;xE6y!ajXnkdrpHx1qmQSj@KG%G
-z>^p$PT;dw`)L8H7($tnHev7oM7OdMifB?52IJE$Tg8<0S34m-M79>G2VZhQRYB*pr
-zy}g;!q!pIWEM+otTUbC4>;Qf`3P7tf;t&@J0DBDr1VBK^UyT4qcgJ<PFm-j+Z8|R4
-zJjjlg9s)0hU1*M!{cr~Y?k+o0)_elxA{5-yF(~sX6KBDbYtQJnL}_4vKkL^F`kg!d
-zUY&k-PP}V(R&M_OB2`msTW3%2m7(F$u{&Qr`1Y~=6@bl|DcDZj7W*sgzWOCL@G!`<
-z(*=`BSYg;uqx%}gU<-8npkitrz7wk30~IIK;k%%^{ZBEk4&MQ_A4Eb6FcVu2M~Ch*
-zs~|p7%d3WP`Min>!X;{dg)Mu=X_<M48!vSAX|GRwL!@uU7NcIa%tv3SRRGBg9svd+
-z(&=<M4f}4hpb+V_DH`I9dUL(SG$5Q3B4Sj`6^n%+aw-xLpaQNy9BJkL8bvWEULM;r
-zQ%_HfsG*PPbjWssewt!KIggH@)FfUKl1AOi+ls_cvpcZQ%>MD;IXqo1w>b9l>$h3(
-z>yPjp93Z*=c$1Fp?cM_^NBNMa?W{)unT=mBvEbK(1?1OX!;b@=&Xr$}+24QU0)!6w
-z58fZnuSek|O`_+yJFj+HMKLnn0l5CcUfR74{Cd-%P+I_AKRmqwEZ_pav;YgZ*qL7s
-z1vi~*$|N+5qxH~!PrK{RpzosB(uYl65?WYR3>w6;lqhFOeIaT!d-;mowk0P$`@#TV
-z38G|++hiLO0TKZcf#r&Ti63u`U;m$f{Pj=YfBy$KIX&kd<JZ6V=imSQ<jLP)84<r;
-zAczdp^Yf>s{{63o=iHP0dhEUp-U1HbcVV}Uijh`tR7ifk5gj|Z_|_@$)=Le~Mqtuv
-zU7gj;mS-ieAHQClg+0{1^VsqZ!<3uty!ze9M60G;nJEeV?#6^#Q?1OC@F%WoE+|VR
-zNqql_5pAzZDU<NMvHuCXeK(K|ph1g9q1+?kP7Z6&tB%StBz*0trbi}|r166%zR)x)
-z<&p$G12edDFE9}3n#q)z%FM}|+D?^1_O4``_NMBBtW+fA^PoYC@-S{NelL&%CU0xI
-zROPVWHz$U*pQ@^55{W=Np;F6^iFUF*bR)bk%h9_uaSysQc|)t#oKVSSJ14GcFKOzb
-zahmp)s$Ett60yA|#xx)6T=KzOx_h6^0dT6_+H)F(Dj&L}(VSA1C?(pfnr@j~6weQx
-zyrsRQs+8^Jd+H510oWXxHC3vE$~0Knr8+L#B?*O&v?~>oR6b|&y0$}ADoYo!FoQ4e
-zaUe?9CfYS+sywA|atv0MDRX5h(9Mew%Q!v?YdbX+vP97)oxuY*2YX}*Uh0!B*>V6$
-zlt`2a5O^Jy2Eo+G;uVWP+sKj2v8^F>Uga0Hzf}v*1y*l5a_mCVNluApp-a-;-UDZM
-zDE$s?lw2G+b~&LXw9ZR0GJH^za(>J2ypEph$!rX-V#qe6ecgY!Ij+`Uz9~;Nyr-Lg
-z-lv)>tLx9}<ef$p)WWeVB^Tm8<djnP+#is(#Mb&9_Q<Oq+|w0O=UM(n!N73Er*Vz!
-z>WxJzb=s-$WA1y`@4V4p*u1@l@xFV`S2vUc>FU4}bh-Ab;!<=yvz)rGzCHbPWVwgL
-zMRaX&-^ct9edO+WeOhU^@Ek*d<o6GjX#}U3C9aau?$XA@>R>rN<KgEi4Z)S04!Z8`
-zA3oHR)Xb`)9c&vo(iK}DaGX|fxm{WpqX;_WmfCmaXh-x(zfxLWM}I+ke1mTpHLtZ#
-z+95dYSLT*`wsG$VkuqiuHEv{}tTXK_yTaqZid{J5#7P8R0|e&#whj2sE0b8k!}PWd
-ze}5MIgKyek`1$%WeKWz5dE3TJ?mJGeUt?u&9)A#HUpjLPoL;|n!N#xxKUqW~U=@KG
-z^!n%1n%PS3Sm<`s+*oN@l3x%1ci>ep@=1RE9KTv7UVSfoyClm6hBp9+gM9mSy_{NI
-z_{x;(IP#7Z14kY>2q8Z|D2i3$N(l$fwd)v`fx?)hQ>57|Kmg;vQy~96tL@5z#o)g$
-z_7sSC^?3QO$*sr6Ci(SdEPFy8v|;m&<k#z%`xsAn%K~!v?Ypa4x~&P9&#R~)T%z_@
-o*s^C##HlwgpAV<r+;*XkI1#7byqt(rZ(dIF>lgc1^X2{jAHkef%K!iX
-
-literal 0
-HcmV?d00001
-
-diff --git a/scripts/make-ras.sh b/scripts/make-ras.sh
-new file mode 100755
-index 0000000000000000000000000000000000000000..ccddaa0016b0c926d4737abb5757e7212b0a1157
---- /dev/null
-+++ b/scripts/make-ras.sh
-@@ -0,0 +1,196 @@
-+#!/usr/bin/env bash
-+#
-+# --- ZyXEL header format ---
-+# Original Version by Benjamin Berg <benjamin@sipsolutions.net>
-+#
-+# The firmware image prefixed with a header (which is written into the MTD device).
-+# The header is one erase block (~64KiB) in size, but the checksum only convers the
-+# first 2KiB. Padding is 0xff. All integers are in big-endian.
-+#
-+# The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
-+#
-+#   4 bytes:  checksum of the rootfs image
-+#   4 bytes:  length of the contained rootfs image file (big endian)
-+#  32 bytes:  Firmware Version string (NUL terminated, 0xff padded)
-+#   4 bytes:  checksum over the header partition (big endian - see below)
-+#  32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded)
-+#   4 bytes:  checksum of the kernel partition
-+#   4 bytes:  length of the contained kernel image file (big endian)
-+#      rest: 0xff padding
-+#
-+# The checksums are calculated by adding up all bytes and if a 16bit
-+# overflow occurs, one is added and the sum is masked to 16 bit:
-+#   csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
-+# Should the file have an odd number of bytes then the byte len-0x800 is
-+# used additionally.
-+#
-+# The checksum for the header is calculated over the first 2048 bytes with
-+# the rootfs image checksum as the placeholder during calculation.
-+#
-+# The header is padded with 0xff to the erase block size of the device.
-+#
-+board=""
-+version=""
-+kernel=""
-+rootfs=""
-+outfile=""
-+err=""
-+
-+while [ "$1" ]; do
-+	case "$1" in
-+	"--board")
-+		board="$2"
-+		shift
-+		shift
-+		continue
-+		;;
-+	"--version")
-+		version="$2"
-+		shift
-+		shift
-+		continue
-+		;;
-+	"--kernel")
-+		kernel="$2"
-+		shift
-+		shift
-+		continue
-+		;;
-+	"--rootfs")
-+		rootfs="$2"
-+		shift
-+		shift
-+		continue
-+		;;
-+	"--rootfssize")
-+		rootfssize="$2"
-+		shift
-+		shift
-+		continue
-+		;;
-+	*)
-+		if [ ! "$outfile" ]; then
-+			outfile=$1
-+			shift
-+			continue
-+		fi
-+		;;
-+	esac
-+done
-+
-+if [ ! -n "$board" -o ! -n "$version" -o ! -r "$kernel" -o ! -r "$rootfs" -o ! "$rootfssize" -o ! "$outfile" ]; then
-+	echo "syntax: $0 [--board ras-boardname] [--version ras-version] [--kernel kernelimage] [--rootfs rootfs] out"
-+	exit 1
-+fi
-+
-+rootfs_len=$(wc -c < "$rootfs")
-+
-+if [ "$rootfs_len" -lt "$rootfssize" ]; then
-+	dd if=$rootfs of=$rootfs.new bs=$rootfssize conv=sync
-+	mv $rootfs.new $rootfs
-+fi
-+
-+if [ ${#version} -ge 28 ]; then
-+	echo "version: '$version' is too long"
-+	exit 1
-+fi
-+
-+tmpdir="$( mktemp -d 2> /dev/null )"
-+if [ -z "$tmpdir" ]; then
-+	# try OSX signature
-+	tmpdir="$( mktemp -t 'ubitmp' -d )"
-+fi
-+
-+if [ -z "$tmpdir" ]; then
-+	exit 1
-+fi
-+
-+to_be() {
-+	local val="$1"
-+	local size="$2"
-+
-+	case "$size" in
-+	4)
-+		echo $(( "$val" >> 24 | ("$val" & 0xff0000) >> 8 | ("$val" & 0xff00) << 8 | ("$val" & 0xff) << 24 ))
-+		;;
-+	2)
-+		echo $(( "$val" >> 8 | ("$val" & 0xff) << 8))
-+		;;
-+	esac
-+}
-+
-+checksum_file() {
-+	local file=$1
-+
-+	# ZyXEL seems to use System V sum mode... Now this is classy, who would have thought?!
-+	echo $(sum -s ${file} | cut -f1 -d" ")
-+}
-+
-+append_bin() {
-+	local val=$1
-+	local size=$2
-+	local file=$3
-+
-+	while [ "$size" -ne 0 ]; do
-+		printf \\$(printf %o $(("$val" & 0xff)))  >> "$file"
-+		val=$(($val >> 8))
-+		let size-=1
-+	done
-+	return
-+}
-+
-+tf=${tmpdir}/out
-+pad=$(printf '%0.1s' $(printf "\xff"){1..64})
-+
-+rootfs_header_file="$tmpdir/rootfs_header"
-+rootfs_chksum=$(to_be $(checksum_file ${rootfs}) 4)
-+rootfs_len=$(to_be $(wc -c < "$rootfs") 4)
-+
-+versionpadlen=$(( 32 - ( ${#version} + 1) ))
-+
-+# 4 bytes:  checksum of the rootfs image
-+append_bin "$rootfs_chksum" 4 "$rootfs_header_file"
-+# 4 bytes:  length of the contained rootfs image file (big endian)
-+append_bin "$rootfs_len" 4 "$rootfs_header_file"
-+# 32 bytes:  Firmware Version string (NUL terminated, 0xff padded)
-+printf "%s\x00%.*s" "$version" "$versionpadlen" "$pad" >> "$rootfs_header_file"
-+
-+kernel_header_file="$tmpdir/kernel_header"
-+kernel_chksum=$(to_be $(checksum_file ${kernel}) 4)
-+kernel_len=$(to_be $(wc -c < "$kernel") 4)
-+
-+# 4 bytes:  checksum of the kernel image
-+append_bin "$kernel_chksum" 4 "$kernel_header_file"
-+# 4 bytes:  length of the contained kernel image file (big endian)
-+append_bin "$kernel_len" 4 "$kernel_header_file"
-+
-+board_header_file="$tmpdir/board_header"
-+board_file="$tmpdir/board"
-+boardpadlen=$(( 64 - ( ${#board} + 1) ))
-+# 32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded)
-+printf "%s\x00%.*s" "$board" "$boardpadlen" "$pad" > "$board_file"
-+cat "$kernel_header_file" >> "$board_file"
-+printf "%.12s" "$pad" >> "$board_file"
-+#      rest: 0xff padding
-+for i in {1..511}; do
-+	printf "%s%s" "$pad" "$pad" >> "$board_file"
-+done
-+
-+tmp_board_file="$tmpdir/tmp_board_file"
-+cat "$rootfs_header_file" > "$tmp_board_file"
-+
-+# The checksum for the header is calculated over the first 2048 bytes with
-+# the rootfs image checksum as the placeholder during calculation.
-+append_bin "$rootfs_chksum" 4 "$tmp_board_file"
-+cat "$board_file" >> "$tmp_board_file"
-+
-+truncate -s 2048 $tmp_board_file
-+board_chksum=$(to_be $(checksum_file ${tmp_board_file}) 4)
-+
-+# 4 bytes:  checksum over the header partition (big endian)
-+append_bin "$board_chksum" 4 "$board_header_file"
-+cat "$board_file" >> "$board_header_file"
-+
-+cat "$rootfs_header_file" "$board_header_file" "$rootfs" "$kernel" > "$outfile"
-+
-+rm -rf "$tmpdir"
-diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-index fcba2aea543cdead03ef372bc6b751481846fbf7..475a8623f705d683a7ee3521ee71f2b57fa2e44d 100755
---- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-+++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-@@ -34,6 +34,11 @@ netgear,ex6150v2)
- meraki,mr33)
- 	ucidef_set_interface_lan "eth0"
- 	;;
-+zyxel,nbg6617)
-+	ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2G" "phy0tpt"
-+	ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5G" "phy1tpt"
-+	ucidef_set_led_usbport "usb" "USB" "${board}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
-+	;;
- zyxel,wre6606)
- 	ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt"
- 	ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5g" "phy1tpt"
-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 03e0c0e16c33f43fafcbba9c5af4baf6dd73e425..5c90ef136fd7cbbe023001030d8c9003347bd249 100755
---- a/target/linux/ipq40xx/base-files/etc/board.d/02_network
-+++ b/target/linux/ipq40xx/base-files/etc/board.d/02_network
-@@ -48,6 +48,11 @@ netgear,ex6150v2 |\
- zyxel,wre6606)
- 	ucidef_set_interface_lan "eth0"
- 	;;
-+zyxel,nbg6617)
-+	ucidef_set_interfaces_lan_wan "eth0" "eth1"
-+	ucidef_add_switch "switch0" \
-+		"0u@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1"
-+	;;
- *)
- 	echo "Unsupported hardware. Network interfaces not intialized"
- 	;;
-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 d89ddf6e57ee9f759f6dcc7c7f8152c11305499b..1d4fd9cd8f9a3983ac3323ce72153c1dcc17a69a 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
-@@ -146,6 +146,7 @@ case "$FIRMWARE" in
- 	openmesh,a62)
- 		ath10kcal_extract "0:ART" 4096 12064
- 		;;
-+	zyxel,nbg6617 |\
- 	zyxel,wre6606)
- 		ath10kcal_extract "ART" 4096 12064
- 		ath10kcal_patch_mac_crc $(macaddr_add $(cat /sys/class/net/eth0/address) -2)
-@@ -181,6 +182,7 @@ case "$FIRMWARE" in
- 	openmesh,a62)
- 		ath10kcal_extract "0:ART" 20480 12064
- 		;;
-+	zyxel,nbg6617 |\
- 	zyxel,wre6606)
- 		ath10kcal_extract "ART" 20480 12064
- 		ath10kcal_patch_mac_crc $(macaddr_add $(cat /sys/class/net/eth0/address) -1)
-diff --git a/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh b/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
-index 1acd7366c81f7c70ef9018d97a833e4d355e8119..44e81ca366dd57d3d5d7fbb9065254925e94061a 100644
---- a/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
-+++ b/target/linux/ipq40xx/base-files/lib/preinit/05_set_iface_mac_ipq40xx.sh
-@@ -8,6 +8,10 @@ preinit_set_mac_address() {
- 		mac_lan=$(get_mac_binary "/sys/bus/i2c/devices/0-0050/eeprom" 102)
- 		[ -n "$mac_lan" ] && ip link set dev eth0 address "$mac_lan"
- 		;;
-+	zyxel,nbg6617)
-+		base_mac=$(cat /sys/class/net/eth0/address)
-+		ip link set dev eth0 address $(macaddr_add "$base_mac" +2)
-+		ip link set dev eth1 address $(macaddr_add "$base_mac" +3)
- 	esac
- }
- 
-diff --git a/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
-new file mode 100644
-index 0000000000000000000000000000000000000000..578ddbe4c4f6e91d925ea3a0de9e060daac82e72
---- /dev/null
-+++ b/target/linux/ipq40xx/base-files/lib/preinit/06_set_preinit_iface_ipq40xx.sh
-@@ -0,0 +1,19 @@
-+#!/bin/sh
-+
-+set_preinit_iface() {
-+	. /lib/functions.sh
-+
-+	case $(board_name) in
-+	asus,rt-ac58u| \
-+	avm,fritzbox-4040| \
-+	glinet,gl-b1300| \
-+	meraki,mr33| \
-+	zyxel,nbg6617)
-+		ifname=eth0
-+		;;
-+	*)
-+		;;
-+	esac
-+}
-+
-+boot_hook_add preinit_main set_preinit_iface
-diff --git a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
-index 4096e127ea9eaa8106475a3143b0b2ea796b5c7c..0e29302465fb5fca6f2a2194c751728f492053d5 100644
---- a/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ipq40xx/base-files/lib/upgrade/platform.sh
-@@ -29,6 +29,21 @@ EOF
- 	return 0;
- }
- 
-+zyxel_do_upgrade() {
-+	local tar_file="$1"
-+
-+	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
-+	board_dir=${board_dir%/}
-+
-+	tar Oxf $tar_file ${board_dir}/kernel | mtd write - kernel
-+
-+	if [ "$SAVE_CONFIG" -eq 1 ]; then
-+		tar Oxf $tar_file ${board_dir}/root | mtd -j "$CONF_TAR" write - rootfs
-+	else
-+		tar Oxf $tar_file ${board_dir}/root | mtd write - rootfs
-+	fi
-+}
-+
- platform_do_upgrade() {
- 	case "$(board_name)" in
- 	8dev,jalapeno)
-@@ -48,6 +63,9 @@ platform_do_upgrade() {
- 		CI_KERNPART="part.safe"
- 		nand_do_upgrade "$1"
- 		;;
-+	zyxel,nbg6617)
-+		zyxel_do_upgrade "$1"
-+		;;
- 	*)
- 		default_do_upgrade "$ARGV"
- 		;;
-diff --git a/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts
-new file mode 100644
-index 0000000000000000000000000000000000000000..d7f8c5955caee15d373a342b75c8c1947f5b8022
---- /dev/null
-+++ b/target/linux/ipq40xx/files-4.14/arch/arm/boot/dts/qcom-ipq4018-nbg6617.dts
-@@ -0,0 +1,321 @@
-+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ */
-+
-+#include "qcom-ipq4019.dtsi"
-+#include "qcom-ipq4019-bus.dtsi"
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+#include <dt-bindings/input/linux-event-codes.h>
-+#include <dt-bindings/soc/qcom,tcsr.h>
-+
-+/ {
-+	model = "ZyXEL NBG6617";
-+	compatible = "zyxel,nbg6617", "qcom,ipq4019";
-+
-+	chosen {
-+		/*
-+		 * the vendor u-boot adds root and mtdparts cmdline parameters
-+		 * which we don't want... but we have to overwrite them or else
-+		 * the kernel will take them at face value.
-+		 */
-+		bootargs-append = " mtdparts= root=31:13";
-+	};
-+
-+	aliases {
-+		led-boot = &power;
-+		led-failsafe = &power;
-+		led-running = &power;
-+		led-upgrade = &power;
-+	};
-+
-+	soc {
-+		mdio@90000 {
-+			status = "okay";
-+		};
-+
-+		ess-psgmii@98000 {
-+			status = "okay";
-+		};
-+
-+		tcsr@1949000 {
-+			compatible = "qcom,tcsr";
-+			reg = <0x1949000 0x100>;
-+			qcom,wifi_glb_cfg = <TCSR_WIFI_GLB_CFG>;
-+		};
-+
-+		tcsr@194b000 {
-+			compatible = "qcom,tcsr";
-+			reg = <0x194b000 0x100>;
-+			qcom,usb-hsphy-mode-select = <TCSR_USB_HSPHY_HOST_MODE>;
-+		};
-+
-+		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@60f8800 {
-+			status = "okay";
-+		};
-+
-+		serial@78af000 {
-+			pinctrl-0 = <&serial_pins>;
-+			pinctrl-names = "default";
-+			status = "okay";
-+		};
-+
-+		usb3@8af8800 {
-+			status = "okay";
-+		};
-+
-+		crypto@8e3a000 {
-+			status = "okay";
-+		};
-+
-+		watchdog@b017000 {
-+			status = "okay";
-+		};
-+
-+		ess-switch@c000000 {
-+			status = "okay";
-+		};
-+
-+		edma@c080000 {
-+			status = "okay";
-+		};
-+	};
-+
-+	gpio-keys {
-+		compatible = "gpio-keys";
-+
-+		wlan {
-+			label = "wlan";
-+			gpios = <&tlmm 2 GPIO_ACTIVE_HIGH>;
-+			linux,code = <KEY_RFKILL>;
-+			linux,input-type = <EV_SW>;
-+		};
-+
-+		wps {
-+			label = "wps";
-+			gpios = <&tlmm 63 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_WPS_BUTTON>;
-+		};
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+	};
-+
-+	gpio-leds {
-+		compatible = "gpio-leds";
-+		pinctrl-0 = <&led_pins>;
-+		pinctrl-names = "default";
-+
-+		power: power {
-+			label = "nbg6617:green:power";
-+			gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>;
-+		};
-+
-+		usb {
-+			label = "nbg6617:green:usb";
-+			gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
-+		};
-+
-+		wlan2G {
-+			label = "nbg6617:green:wlan2G";
-+			gpios = <&tlmm 58 GPIO_ACTIVE_HIGH>;
-+		};
-+
-+		wlan5G {
-+			label = "nbg6617:green:wlan5G";
-+			gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
-+		};
-+
-+		wps {
-+			label = "nbg6617:green:wps";
-+			gpios = <&tlmm 1 GPIO_ACTIVE_HIGH>;
-+		};
-+	};
-+};
-+
-+&tlmm {
-+	serial_pins: serial_pinmux {
-+		mux {
-+			pins = "gpio60", "gpio61";
-+			function = "blsp_uart0";
-+			bias-disable;
-+		};
-+	};
-+	spi_0_pins: spi_0_pinmux {
-+		mux {
-+			function = "blsp_spi0";
-+			pins = "gpio55", "gpio56", "gpio57";
-+			drive-strength = <12>;
-+			bias-disable;
-+		};
-+
-+		mux_cs {
-+			function = "gpio";
-+			pins = "gpio54";
-+			drive-strength = <2>;
-+			bias-disable;
-+			output-low;
-+		};
-+	};
-+	led_pins: led_pinmux  {
-+		mux {
-+			pins = "gpio0", "gpio1", "gpio3", "gpio5", "gpio58";
-+			drive-strength = <0x8>;
-+			bias-disable;
-+			output-low;
-+		};
-+	};
-+};
-+
-+&spi_0 { /* BLSP1 QUP1 */
-+	pinctrl-0 = <&spi_0_pins>;
-+	pinctrl-names = "default";
-+	status = "okay";
-+	cs-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
-+
-+	mx25l25635f@0 {
-+		compatible = "mx25l25635f", "jedec,spi-nor";
-+		#address-cells = <1>;
-+		#size-cells = <0>;
-+		reg = <0>;
-+		spi-max-frequency = <24000000>;
-+		status = "okay";
-+		m25p,fast-read;
-+
-+		partitions {
-+			compatible = "fixed-partitions";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			partition0@0 {
-+				label = "SBL1";
-+				reg = <0x00000000 0x00040000>;
-+				read-only;
-+			};
-+			partition1@40000 {
-+				label = "MIBIB";
-+				reg = <0x00040000 0x00020000>;
-+				read-only;
-+			};
-+			partition2@60000 {
-+				label = "QSEE";
-+				reg = <0x00060000 0x00060000>;
-+				read-only;
-+			};
-+			partition3@c0000 {
-+				label = "CDT";
-+				reg = <0x000c0000 0x00010000>;
-+				read-only;
-+			};
-+			partition4@d0000 {
-+				label = "DDRPARAMS";
-+				reg = <0x000d0000 0x00010000>;
-+				read-only;
-+			};
-+			partition5@e0000 {
-+				label = "APPSBL"; /* u-boot */
-+				reg = <0x000e0000 0x00080000>;
-+				/* U-Boot Standalone App "zloader" is located at 0x64000 */
-+				read-only;
-+			};
-+			partition6@160000 {
-+				label = "APPSBLENV"; /* u-boot env */
-+				reg = <0x00160000 0x00010000>;
-+			};
-+			partition7@170000 {
-+				/* make a backup of this partition! */
-+				label = "ART";
-+				reg = <0x00170000 0x00010000>;
-+				read-only;
-+			};
-+			partition8@180000 {
-+				label = "kernel";
-+				reg = <0x00180000 0x00400000>;
-+			};
-+			partition9@580000 {
-+				label = "dualflag";
-+				reg = <0x00580000 0x00010000>;
-+				read-only;
-+			};
-+			partition10@590000 {
-+				label = "header";
-+				reg = <0x00590000 0x00010000>;
-+			};
-+			partition11@5a0000 {
-+				label = "romd";
-+				reg = <0x005a0000 0x00100000>;
-+				read-only;
-+			};
-+			partition12@6a0000 {
-+				label = "not_root_data";
-+				/*
-+				 * for some strange reason, someone at ZyXEL
-+				 * had the "great" idea to put the rootfs_data
-+				 * in front of rootfs... Don't do that!
-+				 * As a result this one, full MebiByte remains
-+				 * unused.
-+				 */
-+				reg = <0x006a0000 0x00100000>;
-+			};
-+			partition13@7a0000 {
-+				label = "rootfs";
-+				reg = <0x007a0000 0x01860000>;
-+			};
-+		};
-+	};
-+};
-+
-+&cryptobam {
-+	status = "okay";
-+};
-+
-+&blsp_dma {
-+	status = "okay";
-+};
-+
-+&wifi0 {
-+	status = "okay";
-+};
-+
-+&wifi1 {
-+	status = "okay";
-+};
-+
-+&usb3_ss_phy {
-+	status = "okay";
-+};
-+
-+&usb3_hs_phy {
-+	status = "okay";
-+};
-+
-+&usb2_hs_phy {
-+	status = "okay";
-+};
-diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
-index 90d9dfeff0c228765ac24247ce72dec497dc63f0..cb79baccd21b3fa7f35df543bfca1a7d6ba8f83f 100644
---- a/target/linux/ipq40xx/image/Makefile
-+++ b/target/linux/ipq40xx/image/Makefile
-@@ -1,6 +1,8 @@
- include $(TOPDIR)/rules.mk
- include $(INCLUDE_DIR)/image.mk
- 
-+DEVICE_VARS += RAS_BOARD RAS_ROOTFS_SIZE RAS_VERSION
-+
- define Device/Default
- 	PROFILES := Default
- 	KERNEL_DEPENDS = $$(wildcard $(DTS_DIR)/$$(DEVICE_DTS).dts)
-@@ -205,6 +207,26 @@ define Device/qcom_ap-dk04.1-c1
- endef
- TARGET_DEVICES += qcom_ap-dk04.1-c1
- 
-+define Device/zyxel_nbg6617
-+	$(call Device/FitImageLzma)
-+	DEVICE_DTS := qcom-ipq4018-nbg6617
-+	DEVICE_TITLE := ZyXEL NBG6617
-+	ROOTFS_SIZE := 24960k
-+	RAS_BOARD := NBG6617
-+	RAS_ROOTFS_SIZE := 19840k
-+	RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
-+	IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | append-metadata
-+	IMAGES := sysupgrade.bin factory.bin
-+#	The ZyXEL firmware allows flashing thru the web-gui only when the rootfs is
-+#	at least as large as the one of the initial firmware image (not the current
-+#	one on the device). This only applies to the Web-UI, the bootlaoder ignores
-+#	this minimum-size. However, the larger image can be flashed both ways.
-+	IMAGE/factory.bin := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | make-ras
-+	IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata
-+	DEVICE_PACKAGES := ipq-wifi-zyxel_nbg6617 uboot-envtools
-+endef
-+TARGET_DEVICES += zyxel_nbg6617
-+
- define Device/zyxel_wre6606
- 	$(call Device/FitImage)
- 	DEVICE_TITLE := ZyXEL WRE6606
-diff --git a/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch b/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch
-index 3aa368be8381d9c48aefccbe6d4cc768b00dc41e..8066f986a4e030c9c8fe0ec4438e92d30daa77f0 100644
---- a/target/linux/ipq40xx/patches-4.14/069-arm-boot-add-dts-files.patch
-+++ b/target/linux/ipq40xx/patches-4.14/069-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,19 @@ dtb-$(CONFIG_ARCH_QCOM) += \
-+@@ -697,7 +697,20 @@ dtb-$(CONFIG_ARCH_QCOM) += \
-  	qcom-apq8074-dragonboard.dtb \
-  	qcom-apq8084-ifc6540.dtb \
-  	qcom-apq8084-mtp.dtb \
-@@ -19,6 +19,7 @@ Signed-off-by: John Crispin <john@phrozen.org>
- +	qcom-ipq4018-ex6150v2.dtb \
- +	qcom-ipq4018-fritz4040.dtb \
- +	qcom-ipq4018-jalapeno.dtb \
-++	qcom-ipq4018-nbg6617.dtb \
- +	qcom-ipq4018-rt-ac58u.dtb \
- +	qcom-ipq4018-wre6606.dtb \
-  	qcom-ipq4019-ap.dk01.1-c1.dtb \
-diff --git a/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch b/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..7c513a6ad8ec817bf388c67e1181f08982888fa5
---- /dev/null
-+++ b/target/linux/ipq40xx/patches-4.14/303-spi-nor-enable-4B-opcodes-for-mx25l25635f.patch
-@@ -0,0 +1,64 @@
-+Index: linux-4.14.50/drivers/mtd/spi-nor/spi-nor.c
-+===================================================================
-+--- linux-4.14.50.orig/drivers/mtd/spi-nor/spi-nor.c
-++++ linux-4.14.50/drivers/mtd/spi-nor/spi-nor.c
-+@@ -1025,6 +1025,7 @@ static const struct flash_info spi_nor_i
-+ 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
-+ 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-+ 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-++	{ "mx25l25635f", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
-+ 	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
-+ 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-+ 	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-+@@ -1189,11 +1190,12 @@ static const struct flash_info spi_nor_i
-+ 	{ },
-+ };
-+ 
-+-static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
-++static const struct flash_info *spi_nor_read_id(struct spi_nor *nor,
-++						const char *name)
-+ {
-+ 	int			tmp;
-+ 	u8			id[SPI_NOR_MAX_ID_LEN];
-+-	const struct flash_info	*info;
-++	const struct flash_info	*info, *first_match = NULL;
-+ 
-+ 	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
-+ 	if (tmp < 0) {
-+@@ -1204,10 +1206,16 @@ static const struct flash_info *spi_nor_
-+ 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
-+ 		info = &spi_nor_ids[tmp];
-+ 		if (info->id_len) {
-+-			if (!memcmp(info->id, id, info->id_len))
-+-				return &spi_nor_ids[tmp];
-++			if (!memcmp(info->id, id, info->id_len)) {
-++				if (!name || !strcmp(name, info->name))
-++					return info;
-++				if (!first_match)
-++					first_match = info;
-++			}
-+ 		}
-+ 	}
-++	if (first_match)
-++		return first_match;
-+ 	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
-+ 		id[0], id[1], id[2]);
-+ 	return ERR_PTR(-ENODEV);
-+@@ -2667,7 +2675,7 @@ int spi_nor_scan(struct spi_nor *nor, co
-+ 		info = spi_nor_match_id(name);
-+ 	/* Try to auto-detect if chip name wasn't specified or not found */
-+ 	if (!info)
-+-		info = spi_nor_read_id(nor);
-++		info = spi_nor_read_id(nor, NULL);
-+ 	if (IS_ERR_OR_NULL(info))
-+ 		return -ENOENT;
-+ 
-+@@ -2678,7 +2686,7 @@ int spi_nor_scan(struct spi_nor *nor, co
-+ 	if (name && info->id_len) {
-+ 		const struct flash_info *jinfo;
-+ 
-+-		jinfo = spi_nor_read_id(nor);
-++		jinfo = spi_nor_read_id(nor, name);
-+ 		if (IS_ERR(jinfo)) {
-+ 			return PTR_ERR(jinfo);
-+ 		} else if (jinfo != info) {
diff --git a/patches/openwrt/0009-build-add-mkrasimage.patch b/patches/openwrt/0009-build-add-mkrasimage.patch
deleted file mode 100644
index cd5ab7eb4..000000000
--- a/patches/openwrt/0009-build-add-mkrasimage.patch
+++ /dev/null
@@ -1,782 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Wed, 22 Aug 2018 17:30:44 +0200
-Subject: build: add mkrasimage
-
-The current make-ras.sh image generation script for the ZyXEL NBG6617
-has portability issues with bash. Because of this, factory images are
-currently not built correctly by the OpenWRT buildbots.
-
-This commit replaces the make-ras.sh by C-written mkrasimage.
-
-The new mkrasimage is also compatible with other ZyXEL devices using
-the ras image-format.
-This is not tested with the NBG6616 but it correctly builds the
-header for ZyXEL factory image.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/include/image-commands.mk b/include/image-commands.mk
-index 28b39c310e499caea4fe8a6d9ad6dceb5d95363b..552d8db1cbacf533c12d0d8e2e5cffbe5591adb4 100644
---- a/include/image-commands.mk
-+++ b/include/image-commands.mk
-@@ -49,17 +49,17 @@ define Build/eva-image
- 	mv $@.new $@
- endef
- 
--define Build/make-ras
-+define Build/zyxel-ras-image
- 	let \
- 		newsize="$(subst k,* 1024,$(RAS_ROOTFS_SIZE))"; \
--		$(TOPDIR)/scripts/make-ras.sh \
--			--board $(RAS_BOARD) \
--			--version $(RAS_VERSION) \
--			--kernel $(call param_get_default,kernel,$(1),$(IMAGE_KERNEL)) \
--			--rootfs $@ \
--			--rootfssize $$newsize \
--			$@.new
--	@mv $@.new $@
-+		$(STAGING_DIR_HOST)/bin/mkrasimage \
-+			-b $(RAS_BOARD) \
-+			-v $(RAS_VERSION) \
-+			-r $@ \
-+			-s $$newsize \
-+			-o $@.new \
-+			$(if $(findstring separate-kernel,$(word 1,$(1))),-k $(IMAGE_KERNEL)) \
-+		&& mv $@.new $@
- endef
- 
- define Build/netgear-chk
-diff --git a/scripts/make-ras.sh b/scripts/make-ras.sh
-deleted file mode 100755
-index ccddaa0016b0c926d4737abb5757e7212b0a1157..0000000000000000000000000000000000000000
---- a/scripts/make-ras.sh
-+++ /dev/null
-@@ -1,196 +0,0 @@
--#!/usr/bin/env bash
--#
--# --- ZyXEL header format ---
--# Original Version by Benjamin Berg <benjamin@sipsolutions.net>
--#
--# The firmware image prefixed with a header (which is written into the MTD device).
--# The header is one erase block (~64KiB) in size, but the checksum only convers the
--# first 2KiB. Padding is 0xff. All integers are in big-endian.
--#
--# The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
--#
--#   4 bytes:  checksum of the rootfs image
--#   4 bytes:  length of the contained rootfs image file (big endian)
--#  32 bytes:  Firmware Version string (NUL terminated, 0xff padded)
--#   4 bytes:  checksum over the header partition (big endian - see below)
--#  32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded)
--#   4 bytes:  checksum of the kernel partition
--#   4 bytes:  length of the contained kernel image file (big endian)
--#      rest: 0xff padding
--#
--# The checksums are calculated by adding up all bytes and if a 16bit
--# overflow occurs, one is added and the sum is masked to 16 bit:
--#   csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
--# Should the file have an odd number of bytes then the byte len-0x800 is
--# used additionally.
--#
--# The checksum for the header is calculated over the first 2048 bytes with
--# the rootfs image checksum as the placeholder during calculation.
--#
--# The header is padded with 0xff to the erase block size of the device.
--#
--board=""
--version=""
--kernel=""
--rootfs=""
--outfile=""
--err=""
--
--while [ "$1" ]; do
--	case "$1" in
--	"--board")
--		board="$2"
--		shift
--		shift
--		continue
--		;;
--	"--version")
--		version="$2"
--		shift
--		shift
--		continue
--		;;
--	"--kernel")
--		kernel="$2"
--		shift
--		shift
--		continue
--		;;
--	"--rootfs")
--		rootfs="$2"
--		shift
--		shift
--		continue
--		;;
--	"--rootfssize")
--		rootfssize="$2"
--		shift
--		shift
--		continue
--		;;
--	*)
--		if [ ! "$outfile" ]; then
--			outfile=$1
--			shift
--			continue
--		fi
--		;;
--	esac
--done
--
--if [ ! -n "$board" -o ! -n "$version" -o ! -r "$kernel" -o ! -r "$rootfs" -o ! "$rootfssize" -o ! "$outfile" ]; then
--	echo "syntax: $0 [--board ras-boardname] [--version ras-version] [--kernel kernelimage] [--rootfs rootfs] out"
--	exit 1
--fi
--
--rootfs_len=$(wc -c < "$rootfs")
--
--if [ "$rootfs_len" -lt "$rootfssize" ]; then
--	dd if=$rootfs of=$rootfs.new bs=$rootfssize conv=sync
--	mv $rootfs.new $rootfs
--fi
--
--if [ ${#version} -ge 28 ]; then
--	echo "version: '$version' is too long"
--	exit 1
--fi
--
--tmpdir="$( mktemp -d 2> /dev/null )"
--if [ -z "$tmpdir" ]; then
--	# try OSX signature
--	tmpdir="$( mktemp -t 'ubitmp' -d )"
--fi
--
--if [ -z "$tmpdir" ]; then
--	exit 1
--fi
--
--to_be() {
--	local val="$1"
--	local size="$2"
--
--	case "$size" in
--	4)
--		echo $(( "$val" >> 24 | ("$val" & 0xff0000) >> 8 | ("$val" & 0xff00) << 8 | ("$val" & 0xff) << 24 ))
--		;;
--	2)
--		echo $(( "$val" >> 8 | ("$val" & 0xff) << 8))
--		;;
--	esac
--}
--
--checksum_file() {
--	local file=$1
--
--	# ZyXEL seems to use System V sum mode... Now this is classy, who would have thought?!
--	echo $(sum -s ${file} | cut -f1 -d" ")
--}
--
--append_bin() {
--	local val=$1
--	local size=$2
--	local file=$3
--
--	while [ "$size" -ne 0 ]; do
--		printf \\$(printf %o $(("$val" & 0xff)))  >> "$file"
--		val=$(($val >> 8))
--		let size-=1
--	done
--	return
--}
--
--tf=${tmpdir}/out
--pad=$(printf '%0.1s' $(printf "\xff"){1..64})
--
--rootfs_header_file="$tmpdir/rootfs_header"
--rootfs_chksum=$(to_be $(checksum_file ${rootfs}) 4)
--rootfs_len=$(to_be $(wc -c < "$rootfs") 4)
--
--versionpadlen=$(( 32 - ( ${#version} + 1) ))
--
--# 4 bytes:  checksum of the rootfs image
--append_bin "$rootfs_chksum" 4 "$rootfs_header_file"
--# 4 bytes:  length of the contained rootfs image file (big endian)
--append_bin "$rootfs_len" 4 "$rootfs_header_file"
--# 32 bytes:  Firmware Version string (NUL terminated, 0xff padded)
--printf "%s\x00%.*s" "$version" "$versionpadlen" "$pad" >> "$rootfs_header_file"
--
--kernel_header_file="$tmpdir/kernel_header"
--kernel_chksum=$(to_be $(checksum_file ${kernel}) 4)
--kernel_len=$(to_be $(wc -c < "$kernel") 4)
--
--# 4 bytes:  checksum of the kernel image
--append_bin "$kernel_chksum" 4 "$kernel_header_file"
--# 4 bytes:  length of the contained kernel image file (big endian)
--append_bin "$kernel_len" 4 "$kernel_header_file"
--
--board_header_file="$tmpdir/board_header"
--board_file="$tmpdir/board"
--boardpadlen=$(( 64 - ( ${#board} + 1) ))
--# 32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded)
--printf "%s\x00%.*s" "$board" "$boardpadlen" "$pad" > "$board_file"
--cat "$kernel_header_file" >> "$board_file"
--printf "%.12s" "$pad" >> "$board_file"
--#      rest: 0xff padding
--for i in {1..511}; do
--	printf "%s%s" "$pad" "$pad" >> "$board_file"
--done
--
--tmp_board_file="$tmpdir/tmp_board_file"
--cat "$rootfs_header_file" > "$tmp_board_file"
--
--# The checksum for the header is calculated over the first 2048 bytes with
--# the rootfs image checksum as the placeholder during calculation.
--append_bin "$rootfs_chksum" 4 "$tmp_board_file"
--cat "$board_file" >> "$tmp_board_file"
--
--truncate -s 2048 $tmp_board_file
--board_chksum=$(to_be $(checksum_file ${tmp_board_file}) 4)
--
--# 4 bytes:  checksum over the header partition (big endian)
--append_bin "$board_chksum" 4 "$board_header_file"
--cat "$board_file" >> "$board_header_file"
--
--cat "$rootfs_header_file" "$board_header_file" "$rootfs" "$kernel" > "$outfile"
--
--rm -rf "$tmpdir"
-diff --git a/target/linux/ar71xx/image/generic.mk b/target/linux/ar71xx/image/generic.mk
-index 640557532c8a02f37bc6f84ade8cb34e7172162d..4568b656219419e9ca1156c6716bd2124074cb32 100644
---- a/target/linux/ar71xx/image/generic.mk
-+++ b/target/linux/ar71xx/image/generic.mk
-@@ -1086,8 +1086,12 @@ define Device/NBG6616
-   IMAGE_SIZE := 15323k
-   MTDPARTS := spi0.0:192k(u-boot)ro,64k(env)ro,64k(RFdata)ro,384k(zyxel_rfsd),384k(romd),64k(header),2048k(kernel),13184k(rootfs),15232k@0x120000(firmware)
-   CMDLINE += mem=128M
--  IMAGES := sysupgrade.bin
-+  RAS_BOARD := NBG6616
-+  RAS_ROOTFS_SIZE := 14464k
-+  RAS_VERSION := "$(VERSION_DIST) $(REVISION)"
-+  IMAGES := factory.bin sysupgrade.bin
-   KERNEL := kernel-bin | patch-cmdline | lzma | uImage lzma | jffs2 boot/vmlinux.lzma.uImage
-+  IMAGE/factory.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(IMAGE_SIZE) | zyxel-ras-image
-   IMAGE/sysupgrade.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-rootfs | pad-rootfs | check-size $$$$(IMAGE_SIZE)
-   # We cannot currently build a factory image. It is the sysupgrade image
-   # prefixed with a header (which is actually written into the MTD device).
-diff --git a/target/linux/ipq40xx/image/Makefile b/target/linux/ipq40xx/image/Makefile
-index cb79baccd21b3fa7f35df543bfca1a7d6ba8f83f..a0f81f7d631b6c53a5612dee172e752a9fecd06d 100644
---- a/target/linux/ipq40xx/image/Makefile
-+++ b/target/linux/ipq40xx/image/Makefile
-@@ -221,7 +221,7 @@ define Device/zyxel_nbg6617
- #	at least as large as the one of the initial firmware image (not the current
- #	one on the device). This only applies to the Web-UI, the bootlaoder ignores
- #	this minimum-size. However, the larger image can be flashed both ways.
--	IMAGE/factory.bin := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | make-ras
-+	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to 64k | check-size $$$$(ROOTFS_SIZE) | zyxel-ras-image separate-kernel
- 	IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-rootfs | check-size $$$$(ROOTFS_SIZE) | sysupgrade-tar rootfs=$$$$@ | append-metadata
- 	DEVICE_PACKAGES := ipq-wifi-zyxel_nbg6617 uboot-envtools
- endef
-diff --git a/target/linux/ipq806x/image/Makefile b/target/linux/ipq806x/image/Makefile
-index 2902af3231a87592e9c040e7e7e1e4e1958a01a5..a7f740ff62e05c7f6f24caa6da538302abee8d8f 100644
---- a/target/linux/ipq806x/image/Makefile
-+++ b/target/linux/ipq806x/image/Makefile
-@@ -67,7 +67,8 @@ define Device/ZyXELImage
- 	KERNEL_SUFFIX := -uImage
- 	KERNEL = kernel-bin | append-dtb | uImage none | pad-to $${KERNEL_SIZE}
- 	KERNEL_NAME := zImage
--	IMAGES := sysupgrade.bin mmcblk0p5-rootfs.bin mmcblk0p4-kernel.bin
-+	IMAGES := factory.bin sysupgrade.bin mmcblk0p5-rootfs.bin mmcblk0p4-kernel.bin
-+	IMAGE/factory.bin := append-rootfs | pad-rootfs | pad-to $$$$(BLOCKSIZE) | zyxel-ras-image separate-kernel
- 	IMAGE/sysupgrade.bin/squashfs := append-rootfs | pad-to $$$${BLOCKSIZE} | sysupgrade-tar rootfs=$$$$@ | append-metadata
- 	IMAGE/mmcblk0p5-rootfs.bin := append-rootfs | pad-rootfs | pad-to $$$${BLOCKSIZE}
- 	IMAGE/mmcblk0p4-kernel.bin := append-kernel
-@@ -245,6 +246,9 @@ define Device/zyxel_nbg6817
- 	KERNEL_SIZE := 4096k
- 	BLOCKSIZE := 64k
- 	BOARD_NAME := nbg6817
-+	RAS_BOARD := NBG6817
-+	RAS_ROOTFS_SIZE := 20934k
-+	RAS_VERSION := "V1.99(OWRT.9999)C0"
- 	SUPPORTED_DEVICES += nbg6817
- 	DEVICE_TITLE := ZyXEL NBG6817
- 	DEVICE_PACKAGES := ath10k-firmware-qca9984 e2fsprogs kmod-fs-ext4 losetup
-diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
-index 4b4af999088455e3d9231b227fecfa71c8284b2f..a6379e35eb01f1cbbe2b1ece3fc9eb20bcd68d90 100644
---- a/tools/firmware-utils/Makefile
-+++ b/tools/firmware-utils/Makefile
-@@ -70,6 +70,7 @@ define Host/Compile
- 	$(call cc,fix-u-media-header cyg_crc32,-Wall)
- 	$(call cc,hcsmakeimage bcmalgo)
- 	$(call cc,mkporayfw, -Wall)
-+	$(call cc,mkrasimage, --std=gnu99)
- 	$(call cc,mkhilinkfw, -lcrypto)
- 	$(call cc,mkdcs932, -Wall)
- 	$(call cc,mkheader_gemtek,-lz)
-diff --git a/tools/firmware-utils/src/mkrasimage.c b/tools/firmware-utils/src/mkrasimage.c
-new file mode 100644
-index 0000000000000000000000000000000000000000..8eee29cc086a04104b51e263aeac0e73340056ca
---- /dev/null
-+++ b/tools/firmware-utils/src/mkrasimage.c
-@@ -0,0 +1,459 @@
-+/*
-+ * --- ZyXEL header format ---
-+ * Original Version by Benjamin Berg <benjamin@sipsolutions.net>
-+ * C implementation based on generation-script by Christian Lamparter <chunkeey@gmail.com>
-+ *
-+ * The firmware image prefixed with a header (which is written into the MTD device).
-+ * The header is one erase block (~64KiB) in size, but the checksum only convers the
-+ * first 2KiB. Padding is 0xff. All integers are in big-endian.
-+ *
-+ * The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer.
-+ *
-+ *   4 bytes:  checksum of the rootfs image
-+ *   4 bytes:  length of the contained rootfs image file (big endian)
-+ *  32 bytes:  Firmware Version string (NUL terminated, 0xff padded)
-+ *   4 bytes:  checksum over the header partition (big endian - see below)
-+ *  64 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded)
-+ *   4 bytes:  checksum of the kernel partition
-+ *   4 bytes:  length of the contained kernel image file (big endian)
-+ *      rest:  0xff padding (To erase block size)
-+ *
-+ * The kernel partition checksum and length is not used for every device.
-+ * If it's notused, pad those 8 bytes with 0xFF.
-+ *
-+ * The checksums are calculated by adding up all bytes and if a 16bit
-+ * overflow occurs, one is added and the sum is masked to 16 bit:
-+ *   csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff };
-+ * Should the file have an odd number of bytes then the byte len-0x800 is
-+ * used additionally.
-+ *
-+ * The checksum for the header is calculated over the first 2048 bytes with
-+ * the rootfs image checksum as the placeholder during calculation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ */
-+#include <fcntl.h>
-+#include <getopt.h>
-+#include <libgen.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+
-+#include <sys/mman.h>
-+#include <sys/stat.h>
-+
-+#include <arpa/inet.h>
-+
-+#define VERSION_STRING_LEN 31
-+#define ROOTFS_HEADER_LEN 40
-+
-+#define KERNEL_HEADER_LEN 8
-+
-+#define BOARD_NAME_LEN 64
-+#define BOARD_HEADER_LEN 68
-+
-+#define HEADER_PARTITION_CALC_LENGTH 2048
-+#define HEADER_PARTITION_LENGTH 0x10000
-+
-+struct file_info {
-+    char *name;    /* name of the file */
-+    char *data;    /* file content */
-+    size_t size;   /* length of the file */
-+};
-+
-+static char *progname;
-+
-+static char *board_name = 0;
-+static char *version_name = 0;
-+static unsigned int rootfs_size = 0;
-+
-+static struct file_info kernel = { NULL, NULL, 0 };
-+static struct file_info rootfs = { NULL, NULL, 0 };
-+static struct file_info rootfs_out = { NULL, NULL, 0 };
-+static struct file_info out = { NULL, NULL, 0 };
-+
-+#define ERR(fmt, ...) do { \
-+    fprintf(stderr, "[%s] *** error: " fmt "\n", \
-+            progname, ## __VA_ARGS__ ); \
-+} while (0)
-+
-+void map_file(struct file_info *finfo)
-+{
-+    struct stat file_stat = {0};
-+    int fd;
-+
-+    fd = open(finfo->name, O_RDONLY, (mode_t)0600);
-+    if (fd == -1) {
-+        ERR("Error while opening file %s.", finfo->name);
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    if (fstat(fd, &file_stat) == -1) {
-+        ERR("Error getting file size for %s.", finfo->name);
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    finfo->size = file_stat.st_size;
-+    finfo->data = mmap(0, finfo->size, PROT_READ, MAP_SHARED, fd, 0);
-+
-+    if (finfo->data == MAP_FAILED) {
-+        ERR("Error mapping file %s.", finfo->name);
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    close(fd);
-+}
-+
-+void unmap_file(struct file_info *finfo)
-+{
-+    if(munmap(finfo->data, finfo->size) == -1) {
-+        ERR("Error unmapping file %s.", finfo->name);
-+        exit(EXIT_FAILURE);
-+    }
-+}
-+
-+void write_file(struct file_info *finfo)
-+{
-+    FILE *fout = fopen(finfo->name, "w");
-+
-+    fwrite(finfo->data, finfo->size, 1, fout);
-+
-+    if (ferror(fout)) {
-+        ERR("Wanted to write, but something went wrong.");
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    fclose(fout);
-+}
-+
-+void usage(int status)
-+{
-+    FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
-+
-+    fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
-+    fprintf(stream,
-+            "\n"
-+            "Options:\n"
-+            "  -k <kernel>     path for kernel image\n"
-+            "  -r <rootfs>     path for rootfs image\n"
-+            "  -s <rfssize>    size of output rootfs\n"
-+            "  -v <version>    version string\n"
-+            "  -b <boardname>  name of board to generate image for\n"
-+            "  -o <out_name>   name of output image\n"
-+            "  -h              show this screen\n"
-+    );
-+
-+    exit(status);
-+}
-+
-+static int sysv_chksm(const unsigned char *data, int size)
-+{
-+    int r;
-+    int checksum;
-+    unsigned int s = 0; /* The sum of all the input bytes, modulo (UINT_MAX + 1).  */
-+
-+
-+    for (int i = 0; i < size; i++) {
-+        s += data[i];
-+    }
-+
-+    r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
-+    checksum = (r & 0xffff) + (r >> 16);
-+
-+    return checksum;
-+}
-+
-+static int zyxel_chksm(const unsigned char *data, int size)
-+{
-+     return htonl(sysv_chksm(data, size));
-+}
-+
-+char *generate_rootfs_header(struct file_info filesystem, char *version)
-+{
-+    size_t version_string_length;
-+    unsigned int chksm, size;
-+    char *rootfs_header;
-+    size_t ptr = 0;
-+
-+    rootfs_header = malloc(ROOTFS_HEADER_LEN);
-+    if (!rootfs_header) {
-+        ERR("Couldn't allocate memory for rootfs header!");
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    /* Prepare padding for firmware-version string here */
-+    memset(rootfs_header, 0xff, ROOTFS_HEADER_LEN);
-+
-+    chksm = zyxel_chksm((const unsigned char *)filesystem.data, filesystem.size);
-+    size = htonl(filesystem.size);
-+
-+    /* 4 bytes:  checksum of the rootfs image */
-+    memcpy(rootfs_header + ptr, &chksm, 4);
-+    ptr += 4;
-+
-+    /* 4 bytes:  length of the contained rootfs image file (big endian) */
-+    memcpy(rootfs_header + ptr, &size, 4);
-+    ptr += 4;
-+
-+    /* 32 bytes:  Firmware Version string (NUL terminated, 0xff padded) */
-+    version_string_length = strlen(version) <= VERSION_STRING_LEN ? strlen(version) : VERSION_STRING_LEN;
-+    memcpy(rootfs_header + ptr, version, version_string_length);
-+    ptr += version_string_length;
-+    /* Add null-terminator */
-+    rootfs_header[ptr] = 0x0;
-+
-+    return rootfs_header;
-+}
-+
-+char *generate_kernel_header(struct file_info kernel)
-+{
-+    unsigned int chksm, size;
-+    char *kernel_header;
-+    size_t ptr = 0;
-+
-+    kernel_header = malloc(KERNEL_HEADER_LEN);
-+    if (!kernel_header) {
-+        ERR("Couldn't allocate memory for kernel header!");
-+        exit(EXIT_FAILURE);
-+    }
-+
-+    chksm = zyxel_chksm((const unsigned char *)kernel.data, kernel.size);
-+    size = htonl(kernel.size);
-+
-+    /* 4 bytes:  checksum of the kernel image */
-+    memcpy(kernel_header + ptr, &chksm, 4);
-+    ptr += 4;
-+
-+    /* 4 bytes:  length of the contained kernel image file (big endian) */
-+    memcpy(kernel_header + ptr, &size, 4);
-+
-+    return kernel_header;
-+}
-+
-+unsigned int generate_board_header_checksum(char *kernel_hdr, char *rootfs_hdr, char *boardname)
-+{
-+    char *board_hdr_tmp;
-+    unsigned int sum;
-+    size_t ptr = 0;
-+
-+    /*
-+     * The checksum of the board header is calculated over the first 2048 bytes of
-+     * the header partition with the rootfs checksum used as a placeholder for then
-+     * board checksum we calculate in this step. The checksum gained from this step
-+     * is then used for the final board header partition.
-+     */
-+
-+    board_hdr_tmp = malloc(HEADER_PARTITION_CALC_LENGTH);
-+    if (!board_hdr_tmp) {
-+        ERR("Couldn't allocate memory for temporary board header!");
-+        exit(EXIT_FAILURE);
-+    }
-+    memset(board_hdr_tmp, 0xff, HEADER_PARTITION_CALC_LENGTH);
-+
-+    /* 40 bytes:  RootFS header */
-+    memcpy(board_hdr_tmp, rootfs_hdr, ROOTFS_HEADER_LEN);
-+    ptr += ROOTFS_HEADER_LEN;
-+
-+    /* 4 bytes:  RootFS checksum (BE) as placeholder for board-header checksum */
-+    memcpy(board_hdr_tmp + ptr, rootfs_hdr, 4);
-+    ptr += 4;
-+
-+    /* 32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded) */
-+    memcpy(board_hdr_tmp + ptr, boardname, strlen(boardname));
-+    ptr += strlen(boardname);
-+    /* Add null-terminator */
-+    board_hdr_tmp[ptr] = 0x0;
-+    ptr = ROOTFS_HEADER_LEN + 4 + BOARD_NAME_LEN;
-+
-+    /* 8 bytes:  Kernel header */
-+    if (kernel_hdr)
-+        memcpy(board_hdr_tmp + ptr, kernel_hdr, 8);
-+
-+    /* Calculate the checksum over the first 2048 bytes */
-+    sum = zyxel_chksm((const unsigned char *)board_hdr_tmp, HEADER_PARTITION_CALC_LENGTH);
-+    free(board_hdr_tmp);
-+    return sum;
-+}
-+
-+char *generate_board_header(char *kernel_hdr, char *rootfs_hdr, char *boardname)
-+{
-+    unsigned int board_checksum;
-+    char *board_hdr;
-+
-+    board_hdr = malloc(BOARD_HEADER_LEN);
-+    if (!board_hdr) {
-+        ERR("Couldn't allocate memory for board header!");
-+        exit(EXIT_FAILURE);
-+    }
-+    memset(board_hdr, 0xff, BOARD_HEADER_LEN);
-+
-+    /* 4 bytes:  checksum over the header partition (big endian) */
-+    board_checksum = generate_board_header_checksum(kernel_hdr, rootfs_hdr, boardname);
-+    memcpy(board_hdr, &board_checksum, 4);
-+
-+    /* 32 bytes:  Model (e.g. "NBG6617", NUL termiated, 0xff padded) */
-+    memcpy(board_hdr + 4, boardname, strlen(boardname));
-+    board_hdr[4 + strlen(boardname)] = 0x0;
-+
-+    return board_hdr;
-+}
-+
-+int build_image()
-+{
-+    char *rootfs_header = NULL;
-+    char *kernel_header = NULL;
-+    char *board_header = NULL;
-+
-+    size_t ptr;
-+
-+    /* Load files */
-+    if (kernel.name)
-+        map_file(&kernel);
-+    map_file(&rootfs);
-+
-+    /*
-+     * Allocate memory and copy input rootfs for temporary output rootfs.
-+     * This is important as we have to generate the rootfs checksum over the
-+     * entire rootfs partition. As we might have to pad the partition to allow
-+     * for flashing via ZyXEL's Web-GUI, we prepare the rootfs partition for the
-+     * output image here (and also use it for calculating the rootfs checksum).
-+     *
-+     * The roofs padding has to be done with 0x00.
-+     */
-+    rootfs_out.data = calloc(rootfs_out.size, sizeof(char));
-+    memcpy(rootfs_out.data, rootfs.data, rootfs.size);
-+
-+    /* Prepare headers */
-+    rootfs_header = generate_rootfs_header(rootfs_out, version_name);
-+    if (kernel.name)
-+        kernel_header = generate_kernel_header(kernel);
-+    board_header = generate_board_header(kernel_header, rootfs_header, board_name);
-+
-+    /* Prepare output file */
-+    out.size = HEADER_PARTITION_LENGTH + rootfs_out.size;
-+    if (kernel.name)
-+        out.size += kernel.size;
-+    out.data = malloc(out.size);
-+    memset(out.data, 0xFF, out.size);
-+
-+    /* Build output image */
-+    memcpy(out.data, rootfs_header, ROOTFS_HEADER_LEN);
-+    memcpy(out.data + ROOTFS_HEADER_LEN, board_header, BOARD_HEADER_LEN);
-+    if (kernel.name)
-+        memcpy(out.data + ROOTFS_HEADER_LEN + BOARD_HEADER_LEN, kernel_header, KERNEL_HEADER_LEN);
-+    ptr = HEADER_PARTITION_LENGTH;
-+    memcpy(out.data + ptr, rootfs_out.data, rootfs_out.size);
-+    ptr += rootfs_out.size;
-+    if (kernel.name)
-+        memcpy(out.data + ptr, kernel.data, kernel.size);
-+
-+    /* Write back output image */
-+    write_file(&out);
-+
-+    /* Free allocated memory */
-+    if (kernel.name)
-+        unmap_file(&kernel);
-+    unmap_file(&rootfs);
-+    free(out.data);
-+    free(rootfs_out.data);
-+
-+    free(rootfs_header);
-+    if (kernel.name)
-+        free(kernel_header);
-+    free(board_header);
-+
-+    return 0;
-+}
-+
-+int check_options()
-+{
-+    if (!rootfs.name) {
-+        ERR("No rootfs filename supplied");
-+        return -2;
-+    }
-+
-+    if (!out.name) {
-+        ERR("No output filename supplied");
-+        return -3;
-+    }
-+
-+    if (!board_name) {
-+        ERR("No board-name supplied");
-+        return -4;
-+    }
-+
-+    if (!version_name) {
-+        ERR("No version supplied");
-+        return -5;
-+    }
-+
-+    if (rootfs_size <= 0) {
-+        ERR("Invalid rootfs size supplied");
-+        return -6;
-+    }
-+
-+    if (strlen(board_name) > 31) {
-+        ERR("Board name is to long");
-+        return -7;
-+    }
-+    return 0;
-+}
-+
-+int main(int argc, char *argv[])
-+{
-+    int ret;
-+    progname = basename(argv[0]);
-+    while (1) {
-+        int c;
-+
-+        c = getopt(argc, argv, "b:k:o:r:s:v:h");
-+        if (c == -1)
-+            break;
-+
-+        switch (c) {
-+            case 'b':
-+                board_name = optarg;
-+                break;
-+            case 'h':
-+                usage(EXIT_SUCCESS);
-+                break;
-+            case 'k':
-+                kernel.name = optarg;
-+                break;
-+            case 'o':
-+                out.name = optarg;
-+                break;
-+            case 'r':
-+                rootfs.name = optarg;
-+                break;
-+            case 's':
-+                sscanf(optarg, "%u", &rootfs_size);
-+                break;
-+            case 'v':
-+                version_name = optarg;
-+                break;
-+            default:
-+                usage(EXIT_FAILURE);
-+                break;
-+        }
-+    }
-+
-+    ret = check_options();
-+    if (ret)
-+        usage(EXIT_FAILURE);
-+
-+    /* As ZyXEL Web-GUI only accept images with a rootfs equal or larger than the first firmware shipped
-+     * for the device, we need to pad rootfs partition to this size. To perform further calculations, we
-+     * decide the size of this part here. In case the rootfs we want to integrate in our image is larger,
-+     * take it's size, otherwise the supplied size.
-+     *
-+     * Be careful! We rely on assertion of correct size to be performed beforehand. It is unknown if images
-+     * with a to large rootfs are accepted or not.
-+     */
-+    rootfs_out.size = rootfs_size < rootfs.size ? rootfs.size : rootfs_size;
-+    return build_image();
-+}
diff --git a/patches/openwrt/0010-ipq40xx-fix-NBG6617-LED-mapping.patch b/patches/openwrt/0010-ipq40xx-fix-NBG6617-LED-mapping.patch
deleted file mode 100644
index b3fff8d21..000000000
--- a/patches/openwrt/0010-ipq40xx-fix-NBG6617-LED-mapping.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 4 Nov 2018 01:00:18 +0100
-Subject: ipq40xx: fix NBG6617 LED mapping
-
-The NBG6617's LEDs are wrongly identified in the 01_leds boardinit
-script (board instead of boardname), thus referencing non-existant LEDs
-in UCI.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/target/linux/ipq40xx/base-files/etc/board.d/01_leds b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-index 475a8623f705d683a7ee3521ee71f2b57fa2e44d..ab2f77ee10a8e4371d8c52d6d6b6a35bae8aceb6 100755
---- a/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-+++ b/target/linux/ipq40xx/base-files/etc/board.d/01_leds
-@@ -35,9 +35,9 @@ meraki,mr33)
- 	ucidef_set_interface_lan "eth0"
- 	;;
- zyxel,nbg6617)
--	ucidef_set_led_wlan "wlan2g" "WLAN2G" "$board:green:wlan2G" "phy0tpt"
--	ucidef_set_led_wlan "wlan5g" "WLAN5G" "$board:green:wlan5G" "phy1tpt"
--	ucidef_set_led_usbport "usb" "USB" "${board}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
-+	ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2G" "phy0tpt"
-+	ucidef_set_led_wlan "wlan5g" "WLAN5G" "${boardname}:green:wlan5G" "phy1tpt"
-+	ucidef_set_led_usbport "usb" "USB" "${boardname}:green:usb" "usb1-port1" "usb2-port1" "usb3-port1" "usb4-port1"
- 	;;
- zyxel,wre6606)
- 	ucidef_set_led_wlan "wlan2g" "WLAN2G" "${boardname}:green:wlan2g" "phy0tpt"
diff --git a/patches/openwrt/0012-tools-mktplinkfw2-add-split-uboot-layout.patch b/patches/openwrt/0012-tools-mktplinkfw2-add-split-uboot-layout.patch
deleted file mode 100644
index 4df76cf66..000000000
--- a/patches/openwrt/0012-tools-mktplinkfw2-add-split-uboot-layout.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Wed, 28 Nov 2018 23:56:31 +0100
-Subject: tools: mktplinkfw2: add split-uboot layout
-
-This commit adds the split-uboot partition layout used by the
-Archer C50 v4 to mktplinkfw2.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/tools/firmware-utils/src/mktplinkfw2.c b/tools/firmware-utils/src/mktplinkfw2.c
-index dead49e7af8839bac5d1dee7445cf8921208c970..35db848bbab9f8315526dfa24ed351ad58878dde 100644
---- a/tools/firmware-utils/src/mktplinkfw2.c
-+++ b/tools/firmware-utils/src/mktplinkfw2.c
-@@ -146,6 +146,12 @@ static struct flash_layout layouts[] = {
- 		.kernel_la	= 0x80000000,
- 		.kernel_ep	= 0x80000000,
- 		.rootfs_ofs	= 0x140000,
-+	}, {
-+		.id		= "8MSUmtk", /* Split U-Boot OS */
-+		.fw_max_len	= 0x770000,
-+		.kernel_la	= 0x80000000,
-+		.kernel_ep	= 0x80000000,
-+		.rootfs_ofs	= 0x140000,
- 	}, {
- 		.id		= "8MLmtk",
- 		.fw_max_len	= 0x7b0000,
diff --git a/patches/openwrt/0013-ramips-add-support-for-Archer-C50-v4.patch b/patches/openwrt/0013-ramips-add-support-for-Archer-C50-v4.patch
deleted file mode 100644
index 52c5a9d6e..000000000
--- a/patches/openwrt/0013-ramips-add-support-for-Archer-C50-v4.patch
+++ /dev/null
@@ -1,370 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 3 Feb 2019 00:23:18 +0100
-Subject: ramips: add support for Archer C50 v4
-
-This adds support for the TP-Link Archer C50 v4.
-It uses the same hardware as the v3 variant, sharing the same FCC-ID.
-
-CPU:   MediaTek MT7628 (580MHz)
-RAM:   64M DDR2
-FLASH: 8M SPI
-WiFi:  2.4GHz 2x2 MT7628 b/g/n integrated
-WiFI:  5GHz 2x2 MT7612 a/n/ac
-ETH:   1x WAN 4x LAN
-LED:   Power, WiFi2, WiFi5, LAN, WAN, WPS
-BTN:   WPS/WiFi, RESET
-UART:  Near ETH ports, 115200 8n1, TP-Link pinout
-
-Create Factory image
---------------------
-As all installation methods require a U-Boot to be integrated into the
-Image (and we do not ship one with the image) we are not able to create
-an image in the OpenWRT build-process.
-
-Download a TP-Link image from their Wesite and a OpenWRT sysupgrade
-image for the device and build yourself a factory image like following:
-
-TP-Link image:             tpl.bin
-OpenWRT sysupgrade image:  owrt.bin
-
- > dd if=tpl.bin of=boot.bin bs=131584 count=1
- > cat owrt.bin >> boot.bin
-
-Installing via Web-UI
----------------------
-Upload the boot.bin via TP-Links firmware upgrade tool in the
-web-interface.
-
-Installing via Recovery
------------------------
-Activate Web-Recovery by beginning the upgrade Process with a
-Firmware-Image from TP-Link. After starting the Firmware Upgrade,
-wait ~3 seconds (When update status is switching to 0%), then
-disconnect the power supply from the device. Upgrade flag (which
-activates Web-Recovery) is written before the OS-image is touched and
-removed after write is succesfull, so this procedure should be safe.
-
-Plug the power back in. It will come up in Recovery-Mode on 192.168.0.1.
-When active, all LEDs but the WPS LED are off.
-Remeber to assign yourself a static IP-address as DHCP is not active in
-this mode.
-
-The boot.bin can now be uploaded and flashed using the web-recovery.
-
-Installing via TFTP
--------------------
-Prepare an image like following (Filenames from factory image steps
-apply here)
-
- > dd if=/dev/zero of=tp_recovery.bin bs=196608 count=1
- > dd if=tpl.bin of=tmp.bin bs=131584 count=1
- > dd if=tmp.bin of=boot.bin bs=512 skip=1
- > cat boot.bin >> tp_recovery.bin
- > cat owrt.bin >> tp_recovery.bin
-
-Place tp_recovery.bin in root directory of TFTP server and listen on
-192.168.0.66/24.
-
-Connect router LAN ports with your computer and power up the router
-while pressing the reset button. The router will download the image via
-tftp and after ~1 Minute reboot into OpenWRT.
-
-U-Boot CLI
-----------
-U-Boot CLI can be activated by holding down '4' on bootup.
-
-Dual U-Boot
------------
-This is the first TP-Link MediaTek device to feature a split-uboot
-design. The first (factory-uboot) provides recovery via TFTP and HTTP,
-jumping straight into the second (firmware-uboot) if no recovery needs
-to be performed. The firmware-uboot unpacks and executed the kernel.
-
-Web-Recovery
-------------
-TP-Link integrated a new Web-Recovery like the one on the Archer C7v4 /
-TL-WR1043v5. Stock-firmware sets a flag in the "romfile" partition
-before beginning to write and removes it afterwards. If the router boots
-with this flag set, bootloader will automatically start Web-recovery and
-listens on 192.168.0.1. This way, the vendor-firmware or an OpenWRT
-factory image can be written.
-
-It is important to note that Web-Recovery is only based on this flag. It
-can't detect e.g. a crashing kernel or other means. Once activated it
-won't boot the OS before a recovery action (either via TFTP or HTTP) is
-performed. This recovery-mode is indicated by an illuminated WPS-LED on
-boot.
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/target/linux/ramips/base-files/etc/board.d/01_leds b/target/linux/ramips/base-files/etc/board.d/01_leds
-index 6057275978591192e3b7799a8e6d97761c3e23a5..19386b9e139a25fd1ac29cd9a66b738b5b092cdf 100755
---- a/target/linux/ramips/base-files/etc/board.d/01_leds
-+++ b/target/linux/ramips/base-files/etc/board.d/01_leds
-@@ -410,7 +410,8 @@ tplink,c20-v4)
- 	ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
- 	ucidef_set_led_netdev "wlan2g" "wlan2g" "$boardname:green:wlan2g" "wlan0"
- 	;;
--tplink,c50-v3)
-+tplink,c50-v3|\
-+tplink,c50-v4)
- 	ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x1e"
- 	ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x01"
- 	ucidef_set_led_wlan "wlan2g" "wlan2g" "$boardname:green:wlan2g" "phy0tpt"
-diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
-index ebf40ad1fa874d324b43c8f0613bca53a19ab2d0..1c6cc6b0af745b43b81bbfffc9b5462c1b88defc 100755
---- a/target/linux/ramips/base-files/etc/board.d/02_network
-+++ b/target/linux/ramips/base-files/etc/board.d/02_network
-@@ -205,6 +205,7 @@ ramips_setup_interfaces()
- 	rt-n14u|\
- 	tplink,c20-v4|\
- 	tplink,c50-v3|\
-+	tplink,c50-v4|\
- 	tplink,tl-mr3420-v5|\
- 	tplink,tl-wr842n-v5|\
- 	tl-wr840n-v4|\
-diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh
-index 2f51add331fef4693e997433a4ab0e665da80e02..6d021b6def2f1fe7b71a67f36749c440f3bad1d4 100644
---- a/target/linux/ramips/base-files/etc/diag.sh
-+++ b/target/linux/ramips/base-files/etc/diag.sh
-@@ -42,6 +42,7 @@ get_status_led() {
- 	r6220|\
- 	tplink,c20-v4|\
- 	tplink,c50-v3|\
-+	tplink,c50-v4|\
- 	tplink,tl-mr3420-v5|\
- 	tplink,tl-wr842n-v5|\
- 	tplink,tl-wr902ac-v3|\
-diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-index ffdc5e73e0ede286c10396810954a230c8ea32fc..8055853508fc850a1826166c7e0cbdf443df27cb 100755
---- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-@@ -256,6 +256,7 @@ platform_check_image() {
- 	tplink,c20-v1|\
- 	tplink,c20-v4|\
- 	tplink,c50-v3|\
-+	tplink,c50-v4|\
- 	tplink,tl-mr3420-v5|\
- 	tplink,tl-wr842n-v5|\
- 	tplink,tl-wr902ac-v3|\
-diff --git a/target/linux/ramips/dts/ArcherC50V4.dts b/target/linux/ramips/dts/ArcherC50V4.dts
-new file mode 100644
-index 0000000000000000000000000000000000000000..bb4a65436fa435e5636aca3bf326b5a3ca61f7e3
---- /dev/null
-+++ b/target/linux/ramips/dts/ArcherC50V4.dts
-@@ -0,0 +1,93 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "TPLINK-8M-SPLIT-UBOOT.dtsi"
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	compatible = "tplink,c50-v4", "mediatek,mt7628an-soc";
-+	model = "TP-Link Archer C50 v4";
-+
-+	keys {
-+		compatible = "gpio-keys-polled";
-+		poll-interval = <20>;
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+
-+		rfkill {
-+			label = "rfkill";
-+			gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_RFKILL>;
-+		};
-+	};
-+
-+	leds {
-+		compatible = "gpio-leds";
-+
-+		led_power: power {
-+			label = "c50-v4:green:power";
-+			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wlan2 {
-+			label = "c50-v4:green:wlan2g";
-+			gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wlan5 {
-+			label = "c50-v4:green:wlan5g";
-+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		lan {
-+			label = "c50-v4:green:lan";
-+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wan {
-+			label = "c50-v4:green:wan";
-+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wan_orange {
-+			label = "c50-v4:orange:wan";
-+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wps {
-+			label = "c50-v4:green:wps";
-+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
-+		};
-+	};
-+};
-+
-+&pinctrl {
-+	state_default: pinctrl0 {
-+		gpio {
-+			ralink,group = "i2c", "p0led_an", "p1led_an", "p2led_an",
-+				       "p3led_an", "p4led_an", "wdt", "wled_an";
-+			ralink,function = "gpio";
-+		};
-+	};
-+};
-+
-+&pcie {
-+	status = "okay";
-+
-+	pcie-bridge {
-+		mt76@0,0 {
-+			reg = <0x0000 0 0 0 0>;
-+			device_type = "pci";
-+			mediatek,mtd-eeprom = <&radio 0x8000>;
-+			ieee80211-freq-limit = <5000000 6000000>;
-+			mtd-mac-address = <&rom 0xf100>;
-+			mtd-mac-address-increment = <(-1)>;
-+		};
-+	};
-+};
-\ No newline at end of file
-diff --git a/target/linux/ramips/dts/TPLINK-8M-SPLIT-UBOOT.dtsi b/target/linux/ramips/dts/TPLINK-8M-SPLIT-UBOOT.dtsi
-new file mode 100644
-index 0000000000000000000000000000000000000000..539f476dce6e1fe43769f3ed41ae94d5f6fbc2cc
---- /dev/null
-+++ b/target/linux/ramips/dts/TPLINK-8M-SPLIT-UBOOT.dtsi
-@@ -0,0 +1,90 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+#include "mt7628an.dtsi"
-+
-+/ {
-+	chosen {
-+		bootargs = "console=ttyS0,115200";
-+	};
-+
-+	memory@0 {
-+		device_type = "memory";
-+		reg = <0x0 0x4000000>;
-+	};
-+};
-+
-+&spi0 {
-+	status = "okay";
-+
-+	flash@0 {
-+		compatible = "jedec,spi-nor";
-+		reg = <0>;
-+		spi-max-frequency = <10000000>;
-+		m25p,chunked-io = <32>;
-+
-+		partitions {
-+			compatible = "fixed-partitions";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			partition@0 {
-+				label = "factory-uboot";
-+				reg = <0x0 0x30000>;
-+				read-only;
-+			};
-+
-+			partition@30000 {
-+				label = "boot";
-+				reg = <0x30000 0x20000>;
-+				read-only;
-+			};
-+
-+			partition@50000 {
-+				compatible = "tplink,firmware";
-+				label = "firmware";
-+				reg = <0x50000 0x770000>;
-+			};
-+
-+			partition@7c0000 {
-+				label = "config";
-+				reg = <0x7c0000 0x10000>;
-+				read-only;
-+			};
-+
-+			rom: partition@7d0000 {
-+				label = "rom";
-+				reg = <0x7d0000 0x10000>;
-+				read-only;
-+			};
-+
-+			partition@7e0000 {
-+				label = "romfile";
-+				reg = <0x7e0000 0x10000>;
-+			};
-+
-+			radio: partition@7f0000 {
-+				label = "radio";
-+				reg = <0x7f0000 0x10000>;
-+				read-only;
-+			};
-+		};
-+	};
-+};
-+
-+&ehci {
-+	status = "disabled";
-+};
-+
-+&ohci {
-+	status = "disabled";
-+};
-+
-+&wmac {
-+	status = "okay";
-+	mtd-mac-address = <&rom 0xf100>;
-+	mediatek,mtd-eeprom = <&radio 0x0>;
-+};
-+
-+&ethernet {
-+	mtd-mac-address = <&rom 0xf100>;
-+	mediatek,portmap = "llllw";
-+};
-diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
-index 21c5357a089fdd0675afa6f131ff5b34a9a8f54d..34bd662f3a9490bdb0fd125af5ffa8a0f77c5f16 100644
---- a/target/linux/ramips/image/mt76x8.mk
-+++ b/target/linux/ramips/image/mt76x8.mk
-@@ -182,6 +182,20 @@ define Device/tplink_c50-v3
- endef
- TARGET_DEVICES += tplink_c50-v3
- 
-+define Device/tplink_c50-v4
-+  $(Device/tplink)
-+  DTS := ArcherC50V4
-+  IMAGE_SIZE := 7616k
-+  DEVICE_TITLE := TP-Link ArcherC50 v4
-+  TPLINK_FLASHLAYOUT := 8MSUmtk
-+  TPLINK_HWID := 0x001D589B
-+  TPLINK_HWREV := 0x93
-+  TPLINK_HWREVADD := 0x2
-+  TPLINK_HVERSION := 3
-+  IMAGES := sysupgrade.bin
-+endef
-+TARGET_DEVICES += tplink_c50-v4
-+
- define Device/tplink_tl-mr3420-v5
-   $(Device/tplink)
-   DTS := TL-MR3420V5
diff --git a/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch b/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch
deleted file mode 100644
index e03d9042a..000000000
--- a/patches/openwrt/0014-mac80211-ath10k-support-for-multicast-and-management-rate-control.patch
+++ /dev/null
@@ -1,420 +0,0 @@
-From: Sven Eckelmann <sven@narfation.org>
-Date: Fri, 8 Feb 2019 21:20:20 +0100
-Subject: mac80211: ath10k: support for multicast and management rate control
-
-Drivers with software rate control can directly use the selected multicast
-rate for multicast/broadcast frames and the minimal basic rate for
-management frames. But drivers with offloaded rate control algorithms must
-be informed about such upper layer decisions to configure the
-hardware/firmware.
-
-A new BSS_CHANGED_MCAST_RATE is introduced in mac80211 to automatically
-inform all drivers. ath10k can detect this event and forward it via WMI to
-the driver. The already existing BSS_CHANGED_BASIC_RATES can be used to
-select the management rate.
-
-Without the WMI commands, a low rate (not necessarily one from the basic
-rates) is used for bcast/mcast/management frames. This means that the
-/etc/config/wireless settings basic_rate and mcast_rate would have no
-effect on the rates selected by this driver for the mentioned frames.
-
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-
-diff --git a/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch b/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..fb07fa23ecc0518d69eef1f5064328f5c5968360
---- /dev/null
-+++ b/package/kernel/mac80211/patches/975-mac80211-notify-driver-for-change-in-multicast-rates.patch
-@@ -0,0 +1,98 @@
-+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+Date: Thu, 22 Mar 2018 12:18:03 -0700
-+Subject: [PATCH] mac80211: notify driver for change in multicast rates
-+
-+With drivers implementing rate control in driver or firmware
-+rate_control_send_low() may not get called, and thus the
-+driver needs to know about changes in the multicast rate.
-+
-+Add and use a new BSS change flag for this.
-+
-+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+[rewrite commit message]
-+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=dcbe73ca55a42712bfd0e9966cd2d5a48355ace3
-+---
-+ include/net/mac80211.h | 3 +++
-+ net/mac80211/cfg.c     | 2 ++
-+ net/mac80211/ibss.c    | 2 +-
-+ net/mac80211/mesh.c    | 3 ++-
-+ net/mac80211/util.c    | 3 ++-
-+ 5 files changed, 10 insertions(+), 3 deletions(-)
-+
-+diff --git a/include/net/mac80211.h b/include/net/mac80211.h
-+index 885690fa39c8d8f4a48f2fa25447646d3d0a7856..48cfee4e26bdf3c7b7dbaaeecd6520492fa375a9 100644
-+--- a/include/net/mac80211.h
-++++ b/include/net/mac80211.h
-+@@ -301,6 +301,8 @@ struct ieee80211_vif_chanctx_switch {
-+  * @BSS_CHANGED_MU_GROUPS: VHT MU-MIMO group id or user position changed
-+  * @BSS_CHANGED_KEEP_ALIVE: keep alive options (idle period or protected
-+  *	keep alive) changed.
-++ * @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
-++ *
-+  */
-+ enum ieee80211_bss_change {
-+ 	BSS_CHANGED_ASSOC		= 1<<0,
-+@@ -328,6 +330,7 @@ enum ieee80211_bss_change {
-+ 	BSS_CHANGED_OCB                 = 1<<22,
-+ 	BSS_CHANGED_MU_GROUPS		= 1<<23,
-+ 	BSS_CHANGED_KEEP_ALIVE		= 1<<24,
-++	BSS_CHANGED_MCAST_RATE		= 1<<25,
-+ 
-+ 	/* when adding here, make sure to change ieee80211_reconfig */
-+ };
-+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
-+index fb15d3b97cb214078f1533f880350fe280b57c69..0b1984b8e3ab4184b009b6423c73dd0b6959d777 100644
-+--- a/net/mac80211/cfg.c
-++++ b/net/mac80211/cfg.c
-+@@ -2310,6 +2310,8 @@ static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev,
-+ 	memcpy(sdata->vif.bss_conf.mcast_rate, rate,
-+ 	       sizeof(int) * NUM_NL80211_BANDS);
-+ 
-++	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_MCAST_RATE);
-++
-+ 	return 0;
-+ }
-+ 
-+diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
-+index e9c6aa3ed05b8ddb8cf03decce82c00e59b4c0a7..f4b0634b80dedecfc3c05998132bdb6dcd043ed1 100644
-+--- a/net/mac80211/ibss.c
-++++ b/net/mac80211/ibss.c
-+@@ -1840,7 +1840,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
-+ 		  IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED
-+ 		| IEEE80211_HT_PARAM_RIFS_MODE;
-+ 
-+-	changed |= BSS_CHANGED_HT;
-++	changed |= BSS_CHANGED_HT | BSS_CHANGED_MCAST_RATE;
-+ 	ieee80211_bss_info_change_notify(sdata, changed);
-+ 
-+ 	sdata->smps_mode = IEEE80211_SMPS_OFF;
-+diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
-+index a550c707cd8a6130ef5756cedf2fa4738ae9a0e7..e9f5c2ae46a7bd83907d0b5ca1ceb0b8d6afd3fe 100644
-+--- a/net/mac80211/mesh.c
-++++ b/net/mac80211/mesh.c
-+@@ -880,7 +880,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
-+ 		      BSS_CHANGED_BEACON_ENABLED |
-+ 		      BSS_CHANGED_HT |
-+ 		      BSS_CHANGED_BASIC_RATES |
-+-		      BSS_CHANGED_BEACON_INT;
-++		      BSS_CHANGED_BEACON_INT |
-++		      BSS_CHANGED_MCAST_RATE;
-+ 
-+ 	local->fif_other_bss++;
-+ 	/* mesh ifaces must set allmulti to forward mcast traffic */
-+diff --git a/net/mac80211/util.c b/net/mac80211/util.c
-+index 6aef6793d05236c19afe00a51f4ddc91bc060a39..6594df0c3e7afe90cf103bac89580e0ad71ed045 100644
-+--- a/net/mac80211/util.c
-++++ b/net/mac80211/util.c
-+@@ -1971,7 +1971,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
-+ 			  BSS_CHANGED_CQM |
-+ 			  BSS_CHANGED_QOS |
-+ 			  BSS_CHANGED_IDLE |
-+-			  BSS_CHANGED_TXPOWER;
-++			  BSS_CHANGED_TXPOWER |
-++			  BSS_CHANGED_MCAST_RATE;
-+ 
-+ 		if (sdata->vif.mu_mimo_owner)
-+ 			changed |= BSS_CHANGED_MU_GROUPS;
-diff --git a/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch b/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..94bc108fb2e1a99f716135d842e0959f8c7cb602
---- /dev/null
-+++ b/package/kernel/mac80211/patches/976-ath10k-support-for-multicast-rate-control.patch
-@@ -0,0 +1,112 @@
-+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+Date: Wed, 25 Jul 2018 10:59:39 +0300
-+Subject: [PATCH] ath10k: support for multicast rate control
-+
-+Issues a wmi command to firmware when multicast rate change is received with the
-+new BSS_CHANGED_MCAST_RATE flag.  Also fixes the incorrect fixed_rate setting
-+for CCK rates which got introduced with addition of ath10k_rates_rev2 enum.
-+
-+Tested on QCA9984 with firmware ver 10.4-3.6-00104
-+
-+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd93b83ad927b2c7979e0add0343ace59328b461
-+---
-+ drivers/net/wireless/ath/ath10k/mac.c | 54 +++++++++++++++++++++++++--
-+ 1 file changed, 50 insertions(+), 4 deletions(-)
-+
-+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
-+index 5683f1a5330eedae677aad5bf2621a6232781346..1937526c8c18da85f7730429759391d47e12cf81 100644
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -100,6 +100,8 @@ static struct ieee80211_rate ath10k_rates_rev2[] = {
-+ #define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
-+ #define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
-+ 
-++#define ath10k_wmi_legacy_rates ath10k_rates
-++
-+ static bool ath10k_mac_bitrate_is_cck(int bitrate)
-+ {
-+ 	switch (bitrate) {
-+@@ -5389,8 +5391,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ {
-+ 	struct ath10k *ar = hw->priv;
-+ 	struct ath10k_vif *arvif = (void *)vif->drv_priv;
-+-	int ret = 0;
-++	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-++	u16 bitrate, hw_value;
-++	u8 rate;
-++	int rateidx, ret = 0;
-++	enum nl80211_band band;
-+ 
-+ 	mutex_lock(&ar->conf_mutex);
-+ 
-+@@ -5558,6 +5564,44 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 				    arvif->vdev_id, ret);
-+ 	}
-+ 
-++	if (changed & BSS_CHANGED_MCAST_RATE &&
-++	    !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
-++		band = def.chan->band;
-++		rateidx = vif->bss_conf.mcast_rate[band] - 1;
-++
-++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-++			rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
-++
-++		bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
-++		hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
-++		if (ath10k_mac_bitrate_is_cck(bitrate))
-++			preamble = WMI_RATE_PREAMBLE_CCK;
-++		else
-++			preamble = WMI_RATE_PREAMBLE_OFDM;
-++
-++		rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
-++
-++		ath10k_dbg(ar, ATH10K_DBG_MAC,
-++			   "mac vdev %d mcast_rate %x\n",
-++			   arvif->vdev_id, rate);
-++
-++		vdev_param = ar->wmi.vdev_param->mcast_data_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-++						vdev_param, rate);
-++		if (ret)
-++			ath10k_warn(ar,
-++				    "failed to set mcast rate on vdev %i: %d\n",
-++				    arvif->vdev_id,  ret);
-++
-++		vdev_param = ar->wmi.vdev_param->bcast_data_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-++						vdev_param, rate);
-++		if (ret)
-++			ath10k_warn(ar,
-++				    "failed to set bcast rate on vdev %i: %d\n",
-++				    arvif->vdev_id,  ret);
-++	}
-++
-+ 	mutex_unlock(&ar->conf_mutex);
-+ }
-+ 
-+@@ -6826,7 +6870,6 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
-+ 					const struct cfg80211_bitrate_mask *mask,
-+ 					u8 *rate, u8 *nss)
-+ {
-+-	struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
-+ 	int rate_idx;
-+ 	int i;
-+ 	u16 bitrate;
-+@@ -6836,8 +6879,11 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
-+ 	if (hweight32(mask->control[band].legacy) == 1) {
-+ 		rate_idx = ffs(mask->control[band].legacy) - 1;
-+ 
-+-		hw_rate = sband->bitrates[rate_idx].hw_value;
-+-		bitrate = sband->bitrates[rate_idx].bitrate;
-++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-++			rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
-++
-++		hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
-++		bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
-+ 
-+ 		if (ath10k_mac_bitrate_is_cck(bitrate))
-+ 			preamble = WMI_RATE_PREAMBLE_CCK;
-diff --git a/package/kernel/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..4b2aa5effdb19141178a5bb71eb9488ee7575b93
---- /dev/null
-+++ b/package/kernel/mac80211/patches/977-ath10k-add-support-for-configuring-management-packet.patch
-@@ -0,0 +1,94 @@
-+From: Sriram R <srirrama@codeaurora.org>
-+Date: Mon, 10 Sep 2018 11:09:40 +0530
-+Subject: [PATCH] ath10k: add support for configuring management packet rate
-+
-+By default the firmware uses 1Mbps and 6Mbps rate for management packets
-+in 2G and 5G bands respectively. But when the user selects different
-+basic rates from the userspace, we need to send the management
-+packets at the lowest basic rate selected by the user.
-+
-+This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the
-+management packets rate to the firmware.
-+
-+Chipsets Tested : QCA988X, QCA9887, QCA9984
-+FW Tested 	: 10.2.4-1.0-41, 10.4-3.6.104
-+
-+Signed-off-by: Sriram R <srirrama@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70
-+---
-+ drivers/net/wireless/ath/ath10k/mac.c | 45 +++++++++++++++++++++++++--
-+ 1 file changed, 43 insertions(+), 2 deletions(-)
-+
-+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
-+index 1937526c8c18da85f7730429759391d47e12cf81..47e5992afcd7564743f513eb250b57381aba3233 100644
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -155,6 +155,22 @@ u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
-+ 	return 0;
-+ }
-+ 
-++static int ath10k_mac_get_rate_hw_value(int bitrate)
-++{
-++	int i;
-++	u8 hw_value_prefix = 0;
-++
-++	if (ath10k_mac_bitrate_is_cck(bitrate))
-++		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
-++
-++	for (i = 0; i < sizeof(ath10k_rates); i++) {
-++		if (ath10k_rates[i].bitrate == bitrate)
-++			return hw_value_prefix | ath10k_rates[i].hw_value;
-++	}
-++
-++	return -EINVAL;
-++}
-++
-+ static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
-+ {
-+ 	switch ((mcs_map >> (2 * nss)) & 0x3) {
-+@@ -5394,9 +5410,10 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-+ 	u16 bitrate, hw_value;
-+-	u8 rate;
-+-	int rateidx, ret = 0;
-++	u8 rate, basic_rate_idx;
-++	int rateidx, ret = 0, hw_rate_code;
-+ 	enum nl80211_band band;
-++	const struct ieee80211_supported_band *sband;
-+ 
-+ 	mutex_lock(&ar->conf_mutex);
-+ 
-+@@ -5602,6 +5619,30 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 				    arvif->vdev_id,  ret);
-+ 	}
-+ 
-++	if (changed & BSS_CHANGED_BASIC_RATES) {
-++		if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
-++			mutex_unlock(&ar->conf_mutex);
-++			return;
-++		}
-++
-++	sband = ar->hw->wiphy->bands[def.chan->band];
-++	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-++	bitrate = sband->bitrates[basic_rate_idx].bitrate;
-++
-++	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-++	if (hw_rate_code < 0) {
-++		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-++		mutex_unlock(&ar->conf_mutex);
-++		return;
-++	}
-++
-++	vdev_param = ar->wmi.vdev_param->mgmt_rate;
-++	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-++					hw_rate_code);
-++	if (ret)
-++		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-++	}
-++
-+ 	mutex_unlock(&ar->conf_mutex);
-+ }
-+ 
-diff --git a/package/kernel/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..b496332574f93b1f6474226e8c09970d6fe0e2fe
---- /dev/null
-+++ b/package/kernel/mac80211/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
-@@ -0,0 +1,70 @@
-+From: Sriram R <srirrama@codeaurora.org>
-+Date: Wed, 3 Oct 2018 08:43:50 +0530
-+Subject: [PATCH] ath10k: fix possible out of bound access of ath10k_rates array
-+
-+While using 'ath10k_mac_get_rate_hw_value()' to obtain the hw value
-+from the passed bitrate, there is a chance of out of bound array access
-+when wrong bitrate is passed. This is fixed by comparing the bitrates
-+within the correct size of the ath10k_rates array.
-+
-+Fixes commit f279294e9ee2 ("ath10k: add support for configuring management
-+packet rate"). Also correction made to some indents used in the above commit.
-+
-+Signed-off-by: Sriram R <srirrama@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f
-+---
-+ drivers/net/wireless/ath/ath10k/mac.c | 30 +++++++++++++--------------
-+ 1 file changed, 15 insertions(+), 15 deletions(-)
-+
-+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
-+index 47e5992afcd7564743f513eb250b57381aba3233..e93b04c8e6fb2fa7968b910e0cc97ad8144bd7e8 100644
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -163,7 +163,7 @@ static int ath10k_mac_get_rate_hw_value(int bitrate)
-+ 	if (ath10k_mac_bitrate_is_cck(bitrate))
-+ 		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
-+ 
-+-	for (i = 0; i < sizeof(ath10k_rates); i++) {
-++	for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
-+ 		if (ath10k_rates[i].bitrate == bitrate)
-+ 			return hw_value_prefix | ath10k_rates[i].hw_value;
-+ 	}
-+@@ -5625,22 +5625,22 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 			return;
-+ 		}
-+ 
-+-	sband = ar->hw->wiphy->bands[def.chan->band];
-+-	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-+-	bitrate = sband->bitrates[basic_rate_idx].bitrate;
-++		sband = ar->hw->wiphy->bands[def.chan->band];
-++		basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-++		bitrate = sband->bitrates[basic_rate_idx].bitrate;
-+ 
-+-	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-+-	if (hw_rate_code < 0) {
-+-		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-+-		mutex_unlock(&ar->conf_mutex);
-+-		return;
-+-	}
-++		hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-++		if (hw_rate_code < 0) {
-++			ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-++			mutex_unlock(&ar->conf_mutex);
-++			return;
-++		}
-+ 
-+-	vdev_param = ar->wmi.vdev_param->mgmt_rate;
-+-	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-+-					hw_rate_code);
-+-	if (ret)
-+-		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-++		vdev_param = ar->wmi.vdev_param->mgmt_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-++						hw_rate_code);
-++		if (ret)
-++			ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-+ 	}
-+ 
-+ 	mutex_unlock(&ar->conf_mutex);
diff --git a/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch b/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch
deleted file mode 100644
index 8b2a67778..000000000
--- a/patches/openwrt/0015-ath10k-ct-support-for-multicast-and-management-rate-control.patch
+++ /dev/null
@@ -1,316 +0,0 @@
-From: Sven Eckelmann <sven@narfation.org>
-Date: Fri, 8 Feb 2019 21:20:20 +0100
-Subject: ath10k-ct: support for multicast and management rate control
-
-Drivers with software rate control can directly use the selected multicast
-rate for multicast/broadcast frames and the minimal basic rate for
-management frames. But drivers with offloaded rate control algorithms must
-be informed about such upper layer decisions to configure the
-hardware/firmware.
-
-A new BSS_CHANGED_MCAST_RATE is introduced in mac80211 to automatically
-inform all drivers. ath10k-ct can detect this event and forward it via WMI
-to the driver. The already existing BSS_CHANGED_BASIC_RATES can be used to
-select the management rate.
-
-Without the WMI commands, a low rate (not necessarily one from the basic
-rates) is used for bcast/mcast/management frames. This means that the
-/etc/config/wireless settings basic_rate and mcast_rate would have no
-effect on the rates selected by this driver for the mentioned frames.
-
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-
-diff --git a/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch b/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..bd60bf317dec3a2eec1fd9263037acc30d272e39
---- /dev/null
-+++ b/package/kernel/ath10k-ct/patches/976-ath10k-support-for-multicast-rate-control.patch
-@@ -0,0 +1,112 @@
-+From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+Date: Wed, 25 Jul 2018 10:59:39 +0300
-+Subject: [PATCH] ath10k: support for multicast rate control
-+
-+Issues a wmi command to firmware when multicast rate change is received with the
-+new BSS_CHANGED_MCAST_RATE flag.  Also fixes the incorrect fixed_rate setting
-+for CCK rates which got introduced with addition of ath10k_rates_rev2 enum.
-+
-+Tested on QCA9984 with firmware ver 10.4-3.6-00104
-+
-+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd93b83ad927b2c7979e0add0343ace59328b461
-+---
-+ ath10k-4.13/mac.c | 54 +++++++++++++++++++++++++--
-+ 1 file changed, 50 insertions(+), 4 deletions(-)
-+
-+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
-+index 5683f1a5330eedae677aad5bf2621a6232781346..1937526c8c18da85f7730429759391d47e12cf81 100644
-+--- a/ath10k-4.13/mac.c
-++++ b/ath10k-4.13/mac.c
-+@@ -100,6 +100,8 @@ static struct ieee80211_rate ath10k_rates_rev2[] = {
-+ #define ath10k_g_rates_rev2 (ath10k_rates_rev2 + 0)
-+ #define ath10k_g_rates_rev2_size (ARRAY_SIZE(ath10k_rates_rev2))
-+ 
-++#define ath10k_wmi_legacy_rates ath10k_rates
-++
-+ static bool ath10k_mac_bitrate_is_cck(int bitrate)
-+ {
-+ 	switch (bitrate) {
-+@@ -5389,8 +5391,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ {
-+ 	struct ath10k *ar = hw->priv;
-+ 	struct ath10k_vif *arvif = (void *)vif->drv_priv;
-+-	int ret = 0;
-++	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-++	u16 bitrate, hw_value;
-++	u8 rate;
-++	int rateidx, ret = 0;
-++	enum nl80211_band band;
-+ 
-+ 	mutex_lock(&ar->conf_mutex);
-+ 
-+@@ -5558,6 +5564,44 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 				    arvif->vdev_id, ret);
-+ 	}
-+ 
-++	if (changed & BSS_CHANGED_MCAST_RATE &&
-++	    !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
-++		band = def.chan->band;
-++		rateidx = vif->bss_conf.mcast_rate[band] - 1;
-++
-++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-++			rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
-++
-++		bitrate = ath10k_wmi_legacy_rates[rateidx].bitrate;
-++		hw_value = ath10k_wmi_legacy_rates[rateidx].hw_value;
-++		if (ath10k_mac_bitrate_is_cck(bitrate))
-++			preamble = WMI_RATE_PREAMBLE_CCK;
-++		else
-++			preamble = WMI_RATE_PREAMBLE_OFDM;
-++
-++		rate = ATH10K_HW_RATECODE(hw_value, 0, preamble);
-++
-++		ath10k_dbg(ar, ATH10K_DBG_MAC,
-++			   "mac vdev %d mcast_rate %x\n",
-++			   arvif->vdev_id, rate);
-++
-++		vdev_param = ar->wmi.vdev_param->mcast_data_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-++						vdev_param, rate);
-++		if (ret)
-++			ath10k_warn(ar,
-++				    "failed to set mcast rate on vdev %i: %d\n",
-++				    arvif->vdev_id,  ret);
-++
-++		vdev_param = ar->wmi.vdev_param->bcast_data_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-++						vdev_param, rate);
-++		if (ret)
-++			ath10k_warn(ar,
-++				    "failed to set bcast rate on vdev %i: %d\n",
-++				    arvif->vdev_id,  ret);
-++	}
-++
-+ 	mutex_unlock(&ar->conf_mutex);
-+ }
-+ 
-+@@ -6826,7 +6870,6 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
-+ 					const struct cfg80211_bitrate_mask *mask,
-+ 					u8 *rate, u8 *nss)
-+ {
-+-	struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
-+ 	int rate_idx;
-+ 	int i;
-+ 	u16 bitrate;
-+@@ -6836,8 +6879,11 @@ ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
-+ 	if (hweight32(mask->control[band].legacy) == 1) {
-+ 		rate_idx = ffs(mask->control[band].legacy) - 1;
-+ 
-+-		hw_rate = sband->bitrates[rate_idx].hw_value;
-+-		bitrate = sband->bitrates[rate_idx].bitrate;
-++		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-++			rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
-++
-++		hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
-++		bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
-+ 
-+ 		if (ath10k_mac_bitrate_is_cck(bitrate))
-+ 			preamble = WMI_RATE_PREAMBLE_CCK;
-diff --git a/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..6cc6df271fc73431b9467ac9878c360345e0754f
---- /dev/null
-+++ b/package/kernel/ath10k-ct/patches/977-ath10k-add-support-for-configuring-management-packet.patch
-@@ -0,0 +1,94 @@
-+From: Sriram R <srirrama@codeaurora.org>
-+Date: Mon, 10 Sep 2018 11:09:40 +0530
-+Subject: [PATCH] ath10k: add support for configuring management packet rate
-+
-+By default the firmware uses 1Mbps and 6Mbps rate for management packets
-+in 2G and 5G bands respectively. But when the user selects different
-+basic rates from the userspace, we need to send the management
-+packets at the lowest basic rate selected by the user.
-+
-+This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the
-+management packets rate to the firmware.
-+
-+Chipsets Tested : QCA988X, QCA9887, QCA9984
-+FW Tested 	: 10.2.4-1.0-41, 10.4-3.6.104
-+
-+Signed-off-by: Sriram R <srirrama@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70
-+---
-+ ath10k-4.13/mac.c | 45 +++++++++++++++++++++++++--
-+ 1 file changed, 43 insertions(+), 2 deletions(-)
-+
-+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
-+index 1937526c8c18da85f7730429759391d47e12cf81..47e5992afcd7564743f513eb250b57381aba3233 100644
-+--- a/ath10k-4.13/mac.c
-++++ b/ath10k-4.13/mac.c
-+@@ -155,6 +155,22 @@ u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
-+ 	return 0;
-+ }
-+ 
-++static int ath10k_mac_get_rate_hw_value(int bitrate)
-++{
-++	int i;
-++	u8 hw_value_prefix = 0;
-++
-++	if (ath10k_mac_bitrate_is_cck(bitrate))
-++		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
-++
-++	for (i = 0; i < sizeof(ath10k_rates); i++) {
-++		if (ath10k_rates[i].bitrate == bitrate)
-++			return hw_value_prefix | ath10k_rates[i].hw_value;
-++	}
-++
-++	return -EINVAL;
-++}
-++
-+ static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
-+ {
-+ 	switch ((mcs_map >> (2 * nss)) & 0x3) {
-+@@ -5394,9 +5410,10 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-+ 	u16 bitrate, hw_value;
-+-	u8 rate;
-+-	int rateidx, ret = 0;
-++	u8 rate, basic_rate_idx;
-++	int rateidx, ret = 0, hw_rate_code;
-+ 	enum nl80211_band band;
-++	const struct ieee80211_supported_band *sband;
-+ 
-+ 	mutex_lock(&ar->conf_mutex);
-+ 
-+@@ -5602,6 +5619,30 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 				    arvif->vdev_id,  ret);
-+ 	}
-+ 
-++	if (changed & BSS_CHANGED_BASIC_RATES) {
-++		if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
-++			mutex_unlock(&ar->conf_mutex);
-++			return;
-++		}
-++
-++	sband = ar->hw->wiphy->bands[def.chan->band];
-++	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-++	bitrate = sband->bitrates[basic_rate_idx].bitrate;
-++
-++	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-++	if (hw_rate_code < 0) {
-++		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-++		mutex_unlock(&ar->conf_mutex);
-++		return;
-++	}
-++
-++	vdev_param = ar->wmi.vdev_param->mgmt_rate;
-++	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-++					hw_rate_code);
-++	if (ret)
-++		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-++	}
-++
-+ 	mutex_unlock(&ar->conf_mutex);
-+ }
-+ 
-diff --git a/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..cc13e547aa7e983fcff6137de9463e0b706651c5
---- /dev/null
-+++ b/package/kernel/ath10k-ct/patches/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch
-@@ -0,0 +1,70 @@
-+From: Sriram R <srirrama@codeaurora.org>
-+Date: Wed, 3 Oct 2018 08:43:50 +0530
-+Subject: [PATCH] ath10k: fix possible out of bound access of ath10k_rates array
-+
-+While using 'ath10k_mac_get_rate_hw_value()' to obtain the hw value
-+from the passed bitrate, there is a chance of out of bound array access
-+when wrong bitrate is passed. This is fixed by comparing the bitrates
-+within the correct size of the ath10k_rates array.
-+
-+Fixes commit f279294e9ee2 ("ath10k: add support for configuring management
-+packet rate"). Also correction made to some indents used in the above commit.
-+
-+Signed-off-by: Sriram R <srirrama@codeaurora.org>
-+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-+
-+Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f
-+---
-+ ath10k-4.13/mac.c | 30 +++++++++++++--------------
-+ 1 file changed, 15 insertions(+), 15 deletions(-)
-+
-+diff --git a/ath10k-4.13/mac.c b/ath10k-4.13/mac.c
-+index 47e5992afcd7564743f513eb250b57381aba3233..e93b04c8e6fb2fa7968b910e0cc97ad8144bd7e8 100644
-+--- a/ath10k-4.13/mac.c
-++++ b/ath10k-4.13/mac.c
-+@@ -163,7 +163,7 @@ static int ath10k_mac_get_rate_hw_value(int bitrate)
-+ 	if (ath10k_mac_bitrate_is_cck(bitrate))
-+ 		hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
-+ 
-+-	for (i = 0; i < sizeof(ath10k_rates); i++) {
-++	for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
-+ 		if (ath10k_rates[i].bitrate == bitrate)
-+ 			return hw_value_prefix | ath10k_rates[i].hw_value;
-+ 	}
-+@@ -5625,22 +5625,22 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
-+ 			return;
-+ 		}
-+ 
-+-	sband = ar->hw->wiphy->bands[def.chan->band];
-+-	basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-+-	bitrate = sband->bitrates[basic_rate_idx].bitrate;
-++		sband = ar->hw->wiphy->bands[def.chan->band];
-++		basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
-++		bitrate = sband->bitrates[basic_rate_idx].bitrate;
-+ 
-+-	hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-+-	if (hw_rate_code < 0) {
-+-		ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-+-		mutex_unlock(&ar->conf_mutex);
-+-		return;
-+-	}
-++		hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
-++		if (hw_rate_code < 0) {
-++			ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
-++			mutex_unlock(&ar->conf_mutex);
-++			return;
-++		}
-+ 
-+-	vdev_param = ar->wmi.vdev_param->mgmt_rate;
-+-	ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-+-					hw_rate_code);
-+-	if (ret)
-+-		ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-++		vdev_param = ar->wmi.vdev_param->mgmt_rate;
-++		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-++						hw_rate_code);
-++		if (ret)
-++			ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
-+ 	}
-+ 
-+ 	mutex_unlock(&ar->conf_mutex);
diff --git a/patches/openwrt/0016-ramips-add-support-for-Netgear-R6120.patch b/patches/openwrt/0016-ramips-add-support-for-Netgear-R6120.patch
deleted file mode 100644
index 7367a81f0..000000000
--- a/patches/openwrt/0016-ramips-add-support-for-Netgear-R6120.patch
+++ /dev/null
@@ -1,271 +0,0 @@
-From: Ludwig Thomeczek <ledesrc@wxorx.net>
-Date: Tue, 12 Jun 2018 21:17:23 +0200
-Subject: ramips: add support for Netgear R6120
-
-This patch adds support for the Netgear R6120, aka Netgear AC1200.
-
-Specification:
-- SoC: MediaTek MT7628 (580 MHz)
-- Flash: 16 MiB
-- RAM: 64 MiB
-- Wireless: 2.4Ghz(builtin) and 5Ghz (MT7612E)
-- LAN speed: 10/100
-- LAN ports: 4
-- WAN speed: 10/100
-- WAN ports: 1
-- Serial baud rate of Bootloader and factory firmware: 57600
-
-To flash use nmrpflash with the provided factory.img.
-Flashing via webinterface will not work, for now.
-
-Signed-off-by: Ludwig Thomeczek <ledesrc@wxorx.net>
-
-diff --git a/target/linux/ramips/base-files/etc/board.d/01_leds b/target/linux/ramips/base-files/etc/board.d/01_leds
-index 19386b9e139a25fd1ac29cd9a66b738b5b092cdf..4203773b4fa3ec771f07b7a8c414a416a0da0f20 100755
---- a/target/linux/ramips/base-files/etc/board.d/01_leds
-+++ b/target/linux/ramips/base-files/etc/board.d/01_leds
-@@ -301,6 +301,11 @@ mzk-ex750np)
- na930)
- 	set_usb_led "$boardname:blue:status"
- 	;;
-+netgear,r6120)
-+	ucidef_set_led_switch "lan" "lan" "$boardname:green:lan" "switch0" "0x0f"
-+	ucidef_set_led_switch "wan" "wan" "$boardname:green:wan" "switch0" "0x10"
-+	ucidef_set_led_wlan "wlan2g" "WiFi 2.4GHz" "$boardname:green:wlan2g" "phy0tpt"
-+	;;
- newifi-d1)
- 	set_usb_led "$boardname:red:status"
- 	;;
-diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
-index 1c6cc6b0af745b43b81bbfffc9b5462c1b88defc..9424c7ddfd64f9149a24ff91e63b71990265d211 100755
---- a/target/linux/ramips/base-files/etc/board.d/02_network
-+++ b/target/linux/ramips/base-files/etc/board.d/02_network
-@@ -301,6 +301,10 @@ ramips_setup_interfaces()
- 			"0:lan" "1:lan" "2:lan" "3:lan" "6t@eth0"
- 		ucidef_set_interface_wan "usb0"
- 		;;
-+	netgear,r6120)
-+		ucidef_add_switch "switch0" \
-+			"0:lan:4" "1:lan:3" "2:lan:2" "3:lan:1" "4:wan" "6@eth0"
-+		;;
- 	mzk-dp150n|\
- 	vocore-8M|\
- 	vocore-16M)
-diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh
-index 6d021b6def2f1fe7b71a67f36749c440f3bad1d4..097cc6df569518f64dbfd641eeccc1a4b1b37a2b 100644
---- a/target/linux/ramips/base-files/etc/diag.sh
-+++ b/target/linux/ramips/base-files/etc/diag.sh
-@@ -38,6 +38,7 @@ get_status_led() {
- 	mzk-w300nh2|\
- 	nbg-419n|\
- 	nbg-419n2|\
-+	netgear,r6120|\
- 	pwh2004|\
- 	r6220|\
- 	tplink,c20-v4|\
-diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-index 8055853508fc850a1826166c7e0cbdf443df27cb..7213b22d0c2734488bd96bc34e921f08649b8c2f 100755
---- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-@@ -129,6 +129,7 @@ platform_check_image() {
- 	psr-680w|\
- 	px-4885-4M|\
- 	px-4885-8M|\
-+	netgear,r6120|\
- 	rb750gr3|\
- 	re6500|\
- 	rp-n53|\
-diff --git a/target/linux/ramips/dts/R6120.dts b/target/linux/ramips/dts/R6120.dts
-new file mode 100644
-index 0000000000000000000000000000000000000000..a0df0072379a7d8f974ec8025483410d5f9f1da1
---- /dev/null
-+++ b/target/linux/ramips/dts/R6120.dts
-@@ -0,0 +1,142 @@
-+/dts-v1/;
-+
-+#include "mt7628an.dtsi"
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	compatible = "netgear,r6120", "mediatek,mt7628an-soc";
-+	model = "Netgear R6120";
-+
-+	memory@0 {
-+		device_type = "memory";
-+		reg = <0x0 0x4000000>;
-+	};
-+
-+	gpio-keys-polled {
-+		compatible = "gpio-keys-polled";
-+		poll-interval = <20>;
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+	};
-+
-+	gpio-leds {
-+		compatible = "gpio-leds";
-+
-+		lan {
-+			label = "r6120:green:lan";
-+			gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		led_power: power {
-+			label = "r6120:green:power";
-+			gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wlan {
-+			label = "r6120:green:wlan2g";
-+			gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wlan_orange {
-+			label = "r6120:orange:wlan2g";
-+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wan {
-+			label = "r6120:green:wan";
-+			gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		wan_orange {
-+			label = "r6120:orange:wan";
-+			gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
-+		};
-+	};
-+};
-+
-+&pinctrl {
-+	state_default: pinctrl0 {
-+		gpio {
-+			ralink,group = "p0led_an", "p1led_an", "p2led_an",
-+				       "p3led_an", "p4led_an", "wdt", "wled_an";
-+			ralink,function = "gpio";
-+		};
-+	};
-+};
-+
-+&spi0 {
-+	status = "okay";
-+
-+	flash@0 {
-+		compatible = "jedec,spi-nor";
-+		reg = <0>;
-+		spi-max-frequency = <10000000>;
-+		m25p,chunked-io = <32>;
-+
-+		partitions {
-+			compatible = "fixed-partitions";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			partition@0 {
-+				label = "u-boot";
-+				reg = <0x0 0x40000>;
-+				read-only;
-+			};
-+
-+			factory: partition@40000 {
-+				label = "factory";
-+				reg = <0x40000 0x20000>;
-+				read-only;
-+			};
-+
-+			partition@60000 {
-+				label = "nvram";
-+				reg = <0x60000 0x30000>;
-+				read-only;
-+			};
-+
-+			partition@90000 {
-+				label = "firmware";
-+				reg = <0x90000 0xf60000>;
-+			};
-+
-+			partition@ff0000 {
-+				label = "reserved";
-+				reg = <0xff0000 0x10000>;
-+				read-only;
-+			};
-+		};
-+	};
-+};
-+
-+&wmac {
-+	status = "okay";
-+	mtd-mac-address = <&factory 0x4>;
-+	mediatek,mtd-eeprom = <&factory 0x0>;
-+};
-+
-+&ethernet {
-+	mtd-mac-address = <&factory 0x4>;
-+};
-+
-+&pcie {
-+	status = "okay";
-+
-+	pcie-bridge {
-+		mt76@0,0 {
-+			reg = <0x0000 0 0 0 0>;
-+			device_type = "pci";
-+			mediatek,mtd-eeprom = <&factory 0x8000>;
-+			ieee80211-freq-limit = <5000000 6000000>;
-+			mtd-mac-address = <&factory 0x4>;
-+			mtd-mac-address-increment = <(2)>;
-+		};
-+	};
-+};
-diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
-index 34bd662f3a9490bdb0fd125af5ffa8a0f77c5f16..bc282666d8c1a4b6ce5beabe2b492331fb48a23a 100644
---- a/target/linux/ramips/image/mt76x8.mk
-+++ b/target/linux/ramips/image/mt76x8.mk
-@@ -2,6 +2,17 @@
- # MT76x8 Profiles
- #
- 
-+DEVICE_VARS += SERCOMM_KERNEL_OFFSET SERCOMM_HWID SERCOMM_HWVER SERCOMM_SWVER
-+
-+define Build/mksercommfw
-+	$(STAGING_DIR_HOST)/bin/mksercommfw \
-+		$@ \
-+		$(SERCOMM_KERNEL_OFFSET) \
-+		$(SERCOMM_HWID) \
-+		$(SERCOMM_HWVER) \
-+		$(SERCOMM_SWVER)
-+endef
-+
- define Device/tplink
-   TPLINK_FLASHLAYOUT :=
-   TPLINK_HWID :=
-@@ -90,6 +101,23 @@ define Device/mt7628
- endef
- TARGET_DEVICES += mt7628
- 
-+define Device/netgear_r6120
-+  DTS := R6120
-+  BLOCKSIZE := 64k
-+  IMAGE_SIZE := $(ralink_default_fw_size_16M)
-+  DEVICE_TITLE := Netgear R6120
-+  DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
-+  SERCOMM_KERNEL_OFFSET := 90000
-+  SERCOMM_HWID := CGQ
-+  SERCOMM_HWVER := A001
-+  SERCOMM_SWVER := 0040
-+  IMAGES += factory.img
-+  IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE)| append-rootfs | pad-rootfs
-+  IMAGE/sysupgrade.bin := $$(IMAGE/default) | append-metadata | check-size $$$$(IMAGE_SIZE)
-+  IMAGE/factory.img := $$(IMAGE/default) | mksercommfw
-+endef
-+TARGET_DEVICES += netgear_r6120
-+
- define Device/omega2
-   DTS := OMEGA2
-   IMAGE_SIZE := $(ralink_default_fw_size_16M)
diff --git a/patches/openwrt/0017-tools-add-zip-utility.patch b/patches/openwrt/0017-tools-add-zip-utility.patch
deleted file mode 100644
index 60a39a3fa..000000000
--- a/patches/openwrt/0017-tools-add-zip-utility.patch
+++ /dev/null
@@ -1,465 +0,0 @@
-From: Mathias Kresin <dev@kresin.me>
-Date: Sat, 5 Jan 2019 20:51:00 +0100
-Subject: tools: add zip utility
-
-One image requires a zip compressed image, so add the zip util found in
-the packages feed, and extend it with some useful debian patches.
-
-Signed-off-by: Mathias Kresin <dev@kresin.me>
-
-tools: zip: add option for reproducible archives
-
-Add the option -mt/--mtime to pass a timestamp which is used as filedate
-for the containing files.
-
-So far, it isn't used for anything written to the extra fields,
-therefore requires the -X (eXclude eXtra file attributes) parameter to
-be effective.
-
-Signed-off-by: Mathias Kresin <dev@kresin.me>
-
-diff --git a/tools/Makefile b/tools/Makefile
-index d2b5daf18c233c8e94657fd61922c75770a3b35b..3ac3b226d35311c606e6dcc562fb8a2d31cec584 100644
---- a/tools/Makefile
-+++ b/tools/Makefile
-@@ -32,7 +32,7 @@ tools-$(CONFIG_TARGET_x86) += qemu
- tools-$(CONFIG_TARGET_mxs) += elftosb sdimage
- tools-$(CONFIG_TARGET_ar71xx) += lzma-old squashfs
- tools-$(CONFIG_USES_MINOR) += kernel2minor
--tools-y += lzma squashfs4
-+tools-y += lzma squashfs4 zip
- tools-$(BUILD_B43_TOOLS) += b43-tools
- tools-$(BUILD_ISL) += isl
- tools-$(CONFIG_USE_SPARSE) += sparse
-diff --git a/tools/zip/Makefile b/tools/zip/Makefile
-new file mode 100644
-index 0000000000000000000000000000000000000000..7dd81a1b8bc3bfeb5773d0770cb57c164f6db157
---- /dev/null
-+++ b/tools/zip/Makefile
-@@ -0,0 +1,36 @@
-+#
-+# Copyright (C) 2007-2016 OpenWrt.org
-+#
-+# This is free software, licensed under the GNU General Public License v2.
-+# See /LICENSE for more information.
-+#
-+
-+include $(TOPDIR)/rules.mk
-+
-+PKG_NAME:=zip
-+PKG_REV:=30
-+PKG_VERSION:=3.0
-+
-+PKG_SOURCE:=$(PKG_NAME)$(PKG_REV).tar.gz
-+PKG_SOURCE_URL:=@SF/infozip
-+PKG_HASH:=f0e8bb1f9b7eb0b01285495a2699df3a4b766784c1765a8f1aeedf63c0806369
-+
-+PKG_LICENSE:=BSD-4-Clause
-+PKG_LICENSE_FILES:=LICENSE
-+
-+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)/zip$(PKG_REV)
-+HOST_BUILD_PARALLEL:=1
-+
-+include $(INCLUDE_DIR)/host-build.mk
-+
-+define Host/Compile
-+	+$(HOST_MAKE_VARS) $(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) -I. -f unix/Makefile zip
-+endef
-+
-+define Host/Install
-+	$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/
-+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/zip $(STAGING_DIR_HOST)/bin/
-+endef
-+
-+$(eval $(call HostBuild))
-+#$(eval $(call BuildPackage,zip))
-diff --git a/tools/zip/patches/001-unix-configure-borrow-the-LFS-test-from-autotools.patch b/tools/zip/patches/001-unix-configure-borrow-the-LFS-test-from-autotools.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..ef0de6fd9b9bb1f2ee29a9609ce0dbd7799f3410
---- /dev/null
-+++ b/tools/zip/patches/001-unix-configure-borrow-the-LFS-test-from-autotools.patch
-@@ -0,0 +1,89 @@
-+From fc392c939b9a18959482f588aff0afc29dd6d30a Mon Sep 17 00:00:00 2001
-+From: Romain Naour <romain.naour at openwide.fr>
-+Date: Fri, 23 Jan 2015 22:20:18 +0100
-+Subject: [PATCH 6/6] unix/configure: borrow the LFS test from autotools.
-+
-+Infozip's LFS check can't work for cross-compilation
-+since it try to run a target's binary on the host system.
-+
-+Instead, use to LFS test used by autotools which is a
-+compilation test.
-+(see autotools/lib/autoconf/specific.m4)
-+
-+Reported-by: Richard Genoud <richard.genoud at gmail.com>
-+Signed-off-by: Romain Naour <romain.naour at openwide.fr>
-+---
-+ configure |   46 +++++++++++++++-------------------------------
-+ 1 file changed, 15 insertions(+), 31 deletions(-)
-+
-+--- a/unix/configure
-++++ b/unix/configure
-+@@ -399,9 +399,8 @@ else
-+ fi
-+ 
-+ 
-+-# Now we set the 64-bit file environment and check the size of off_t
-+-# Added 11/4/2003 EG
-+-# Revised 8/12/2004 EG
-++# LFS check borrowed from autotools sources
-++# lib/autoconf/specific.m4
-+ 
-+ echo Check for Large File Support
-+ cat > conftest.c << _EOF_
-+@@ -410,23 +409,19 @@ cat > conftest.c << _EOF_
-+ # define _FILE_OFFSET_BITS 64       /* select default interface as 64 bit */
-+ # define _LARGE_FILES        /* some OSes need this for 64-bit off_t */
-+ #include <sys/types.h>
-+-#include <sys/stat.h>
-+-#include <unistd.h>
-+-#include <stdio.h>
-++
-++ /* Check that off_t can represent 2**63 - 1 correctly.
-++    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-++    since some C++ compilers masquerading as C compilers
-++    incorrectly reject 9223372036854775807.  */
-++#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-++  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-++		       && LARGE_OFF_T % 2147483647 == 1)
-++		      ? 1 : -1];
-++
-+ int main()
-+ {
-+-  off_t offset;
-+-  struct stat s;
-+-  /* see if have 64-bit off_t */
-+-  if (sizeof(offset) < 8)
-+-    return 1;
-+-  printf("  off_t is %d bytes\n", sizeof(off_t));
-+-  /* see if have 64-bit stat */
-+-  if (sizeof(s.st_size) < 8) {
-+-    printf("  s.st_size is %d bytes\n", sizeof(s.st_size));
-+-    return 2;
-+-  }
-+-  return 3;
-++  return 0;
-+ }
-+ _EOF_
-+ # compile it
-+@@ -434,19 +429,8 @@ $CC -o conftest conftest.c >/dev/null 2>
-+ if [ $? -ne 0 ]; then
-+   echo -- no Large File Support
-+ else
-+-# run it
-+-  ./conftest
-+-  r=$?
-+-  if [ $r -eq 1 ]; then
-+-    echo -- no Large File Support - no 64-bit off_t
-+-  elif [ $r -eq 2 ]; then
-+-    echo -- no Large File Support - no 64-bit stat
-+-  elif [ $r -eq 3 ]; then
-+-    echo -- yes we have Large File Support!
-+-    CFLAGS="${CFLAGS} -DLARGE_FILE_SUPPORT"
-+-  else
-+-    echo -- no Large File Support - conftest returned $r
-+-  fi
-++  echo -- yes we have Large File Support!
-++  CFLAGS="${CFLAGS} -DLARGE_FILE_SUPPORT"
-+ fi
-+ 
-+ 
-diff --git a/tools/zip/patches/004-do-not-set-unwanted-cflags.patch b/tools/zip/patches/004-do-not-set-unwanted-cflags.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..bfd226077a9742f87a1988747a81e9226e89dfaf
---- /dev/null
-+++ b/tools/zip/patches/004-do-not-set-unwanted-cflags.patch
-@@ -0,0 +1,15 @@
-+From: Santiago Vila <sanvila@debian.org>
-+Subject: Do not set unwanted CFLAGS, as it breaks DEB_BUILD_OPTIONS
-+X-Debian-version: 2.32-1
-+
-+--- a/unix/configure
-++++ b/unix/configure
-+@@ -98,7 +98,7 @@ int main()
-+ _EOF_
-+       $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
-+       if test $? -eq 0; then
-+-        CFLAGS_OPT='-O3'
-++        # CFLAGS_OPT='-O3'
-+         echo "  GNU C ($CFLAGS_OPT)"
-+         # Special Mac OS X shared library "ld" option?
-+         if test ` uname -s 2> /dev/null ` = 'Darwin'; then
-diff --git a/tools/zip/patches/006-stack-markings-to-avoid-executable-stack.patch b/tools/zip/patches/006-stack-markings-to-avoid-executable-stack.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..8b479faedaeedbe83d378306d386a0a88493b282
---- /dev/null
-+++ b/tools/zip/patches/006-stack-markings-to-avoid-executable-stack.patch
-@@ -0,0 +1,21 @@
-+From: Kees Cook <kees@debian.org>
-+Subject: put stack markings in i386 assembly to avoid executable stack
-+Bug-Debian: http://bugs.debian.org/528280
-+X-Debian-version: 3.0-2
-+
-+--- a/crc_i386.S
-++++ b/crc_i386.S
-+@@ -302,3 +302,5 @@ _crc32:                         /* ulg c
-+ #endif /* i386 || _i386 || _I386 || __i386 */
-+ 
-+ #endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
-++.section .note.GNU-stack, "", @progbits
-++.previous
-+--- a/match.S
-++++ b/match.S
-+@@ -405,3 +405,5 @@ L__return:
-+ #endif /* i386 || _I386 || _i386 || __i386  */
-+ 
-+ #endif /* !USE_ZLIB */
-++.section .note.GNU-stack, "", @progbits
-++.previous
-diff --git a/tools/zip/patches/007-fclose-in-file-not-fclose-x.patch b/tools/zip/patches/007-fclose-in-file-not-fclose-x.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..402f90a2d5ef3d08a7d71268fe4f5e2484a10664
---- /dev/null
-+++ b/tools/zip/patches/007-fclose-in-file-not-fclose-x.patch
-@@ -0,0 +1,16 @@
-+From: Christian Spieler
-+Subject: zipnote.c: Close in_file instead of undefined file x
-+Bug-Debian: http://bugs.debian.org/628594
-+X-Debian-version: 3.0-4
-+
-+--- a/zipnote.c
-++++ b/zipnote.c
-+@@ -661,7 +661,7 @@ char **argv;            /* command line
-+     if ((r = zipcopy(z)) != ZE_OK)
-+       ziperr(r, "was copying an entry");
-+   }
-+-  fclose(x);
-++  fclose(in_file);
-+ 
-+   /* Write central directory and end of central directory with new comments */
-+   if ((c = zftello(y)) == (zoff_t)-1)    /* get start of central */
-diff --git a/tools/zip/patches/008-hardening-build-fix-1.patch b/tools/zip/patches/008-hardening-build-fix-1.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..a0c3a91eeec064b2305c3873a8a95669c750ea9b
---- /dev/null
-+++ b/tools/zip/patches/008-hardening-build-fix-1.patch
-@@ -0,0 +1,25 @@
-+From: Santiago Vila <sanvila@debian.org>
-+Subject: Use format specifier %s to print strings, not the string itself
-+Bug-Debian: http://bugs.debian.org/673476
-+X-Debian-version: 3.0-5
-+
-+--- a/zip.c
-++++ b/zip.c
-+@@ -1028,7 +1028,7 @@ local void help_extended()
-+ 
-+   for (i = 0; i < sizeof(text)/sizeof(char *); i++)
-+   {
-+-    printf(text[i]);
-++    printf("%s", text[i]);
-+     putchar('\n');
-+   }
-+ #ifdef DOS
-+@@ -1225,7 +1225,7 @@ local void version_info()
-+             CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
-+   for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++)
-+   {
-+-    printf(cryptnote[i]);
-++    printf("%s", cryptnote[i]);
-+     putchar('\n');
-+   }
-+   ++i;  /* crypt support means there IS at least one compilation option */
-diff --git a/tools/zip/patches/009-hardening-build-fix-2.patch b/tools/zip/patches/009-hardening-build-fix-2.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..e295ffbc641879768cc9257641fae85af327a338
---- /dev/null
-+++ b/tools/zip/patches/009-hardening-build-fix-2.patch
-@@ -0,0 +1,16 @@
-+From: Santiago Vila <sanvila@debian.org>
-+Subject: unix/configure: Take linking flags from the environment
-+Bug-Debian: http://bugs.debian.org/673476
-+X-Debian-version: 3.0-5
-+
-+--- a/unix/configure
-++++ b/unix/configure
-+@@ -18,7 +18,7 @@ trap "rm -f conftest* core a.out; exit 1
-+ 
-+ CC=${1-cc}
-+ CFLAGS=${2-"-I. -DUNIX"}
-+-LFLAGS1=''
-++LFLAGS1=${LDFLAGS}
-+ LFLAGS2=''
-+ LN="ln -s"
-+ 
-diff --git a/tools/zip/patches/010-remove-build-date.patch b/tools/zip/patches/010-remove-build-date.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..5fc385228a8f6bff01416748bb6c392f2e986322
---- /dev/null
-+++ b/tools/zip/patches/010-remove-build-date.patch
-@@ -0,0 +1,15 @@
-+From: Santiago Vila <sanvila@debian.org>
-+Subject: Remove (optional) build date to make the build reproducible
-+Bug-Debian: http://bugs.debian.org/779042
-+
-+--- a/unix/unix.c
-++++ b/unix/unix.c
-+@@ -1020,7 +1020,7 @@ void version_local()
-+ 
-+ 
-+ /* Define the compile date string */
-+-#ifdef __DATE__
-++#if 0
-+ #  define COMPILE_DATE " on " __DATE__
-+ #else
-+ #  define COMPILE_DATE ""
-diff --git a/tools/zip/patches/011-add-option-for-reproducible-archives.patch b/tools/zip/patches/011-add-option-for-reproducible-archives.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..45b9d67e159327798535db55cd264ab9eeec6c38
---- /dev/null
-+++ b/tools/zip/patches/011-add-option-for-reproducible-archives.patch
-@@ -0,0 +1,145 @@
-+From 6d659fc87451c02c8777dc33f750b16834e4c715 Mon Sep 17 00:00:00 2001
-+From: Mathias Kresin <dev@kresin.me>
-+Date: Sat, 12 Jan 2019 19:33:33 +0100
-+Subject: [PATCH] add option for reproducible archives
-+
-+Add the option -mt/--mtime to pass a timestamp which is used as filedate
-+for the containing files.
-+
-+So far, it isn't used for anything written to the extra fields,
-+therefore requires the -X (eXclude eXtra file attributes) parameter to
-+be effective.
-+
-+Signed-off-by: Mathias Kresin <dev@kresin.me>
-+---
-+ globals.c |  1 +
-+ util.c    | 22 ++++++++++++++++++++++
-+ zip.c     |  6 ++++++
-+ zip.h     |  1 +
-+ zipup.c   |  4 +++-
-+ 5 files changed, 33 insertions(+), 1 deletion(-)
-+
-+--- a/globals.c
-++++ b/globals.c
-+@@ -205,6 +205,7 @@ uzoff_t bytes_this_split = 0;     /* byt
-+ int read_split_archive = 0;       /* 1=scanzipf_reg detected spanning signature */
-+ int split_method = 0;             /* 0=no splits, 1=seekable, 2=data desc, -1=no */
-+ uzoff_t split_size = 0;           /* how big each split should be */
-++time_t timestamp = -1;             /* fixed timestamp for archive content filedate */
-+ int split_bell = 0;               /* when pause for next split ring bell */
-+ uzoff_t bytes_prev_splits = 0;    /* total bytes written to all splits before this */
-+ uzoff_t bytes_this_entry = 0;     /* bytes written for this entry across all splits */
-+--- a/util.c
-++++ b/util.c
-+@@ -1217,6 +1217,7 @@ int DisplayNumString(file, i)
-+   return 0;
-+ }
-+ 
-++
-+ /* Read numbers with trailing size multiplier (like 10M) and return number.
-+    10/30/04 EG */
-+ 
-+@@ -1279,6 +1280,29 @@ uzoff_t ReadNumString( numstring )
-+ }
-+ 
-+ 
-++uzoff_t ReadNumStringUL( numstring )
-++  char *numstring;
-++{
-++  zoff_t num = 0;
-++
-++  /* check if valid number (currently no negatives) */
-++  if (numstring == NULL) {
-++    zipwarn("Unable to read empty number in ReadNumString", "");
-++    return (uzoff_t)-1;
-++  }
-++  if (numstring[0] < '0' || numstring[0] > '9') {
-++    zipwarn("Unable to read number (must start with digit): ", numstring);
-++    return (uzoff_t)-1;
-++  }
-++  if (strlen(numstring) > 10) {
-++    zipwarn("Number too long to read (10 characters max): ", numstring);
-++    return (uzoff_t)-1;
-++  }
-++
-++  return (uzoff_t)atoll(numstring);
-++}
-++
-++
-+ /* Write the number as a string with a multiplier (like 10M) to outstring.
-+    Always writes no more than 3 digits followed maybe by a multiplier and
-+    returns the characters written or -1 if error.
-+--- a/zip.c
-++++ b/zip.c
-+@@ -1942,6 +1942,7 @@ int set_filetype(out_path)
-+ #ifdef UNICODE_TEST
-+ #define o_sC            0x146
-+ #endif
-++#define o_mt            0x255
-+ 
-+ 
-+ /* the below is mainly from the old main command line
-+@@ -2036,6 +2037,7 @@ struct option_struct far options[] = {
-+     {"m",  "move",        o_NO_VALUE,       o_NOT_NEGATABLE, 'm',  "add files to archive then delete files"},
-+     {"mm", "",            o_NO_VALUE,       o_NOT_NEGATABLE, o_mm, "not used"},
-+     {"MM", "must-match",  o_NO_VALUE,       o_NOT_NEGATABLE, o_MM, "error if in file not matched/not readable"},
-++    {"mt", "mtime",       o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_mt, "use fixed timestamp for archive content filedate"},
-+     {"n",  "suffixes",    o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'n',  "suffixes to not compress: .gz:.zip"},
-+     {"nw", "no-wild",     o_NO_VALUE,       o_NOT_NEGATABLE, o_nw, "no wildcards during add or update"},
-+ #if defined(AMIGA) || defined(MACOS)
-+@@ -2440,6 +2442,7 @@ char **argv;            /* command line
-+   split_method = 0;           /* 0=no splits, 1=update LHs, 2=data descriptors */
-+   split_size = 0;             /* how big each split should be */
-+   split_bell = 0;             /* when pause for next split ring bell */
-++  timestamp = -1;             /* fixed timestamp for archive content filedate */
-+   bytes_prev_splits = 0;      /* total bytes written to all splits before this */
-+   bytes_this_entry = 0;       /* bytes written for this entry across all splits */
-+   noisy_splits = 0;           /* be verbose about creating splits */
-+@@ -2897,6 +2900,9 @@ char **argv;            /* command line
-+           dispose = 1;  break;
-+         case o_MM:  /* Exit with error if input file can't be read */
-+           bad_open_is_error = 1; break;
-++        case o_mt:  /* fixed timestamp for archive content filedate */
-++          timestamp = ReadNumStringUL(value);
-++          break;
-+         case 'n':   /* Don't compress files with a special suffix */
-+           special = value;
-+           /* special = NULL; */ /* will be set at next argument */
-+--- a/zip.h
-++++ b/zip.h
-+@@ -502,6 +502,7 @@ extern uzoff_t bytes_this_split; /* byte
-+ extern int read_split_archive;   /* 1=scanzipf_reg detected spanning signature */
-+ extern int split_method;         /* 0=no splits, 1=seekable, 2=data descs, -1=no */
-+ extern uzoff_t split_size;       /* how big each split should be */
-++extern time_t timestamp;         /* fixed timestamp for archive content filedate */
-+ extern int split_bell;           /* when pause for next split ring bell */
-+ extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */
-+ extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */
-+@@ -789,6 +790,7 @@ char *zip_fzofft       OF((zoff_t, char
-+ int DisplayNumString OF ((FILE *file, uzoff_t i));
-+ int WriteNumString OF((uzoff_t num, char *outstring));
-+ uzoff_t ReadNumString OF((char *numstring));
-++uzoff_t ReadNumStringUL OF((char *numstring));
-+ 
-+ /* returns true if abbrev is abbreviation for string */
-+ int abbrevmatch OF((char *, char *, int, int));
-+--- a/zipup.c
-++++ b/zipup.c
-+@@ -415,7 +415,6 @@ struct zlist far *z;    /* zip entry to
-+   char *tempextra = NULL;
-+   char *tempcextra = NULL;
-+ 
-+-
-+ #ifdef WINDLL
-+ # ifdef ZIP64_SUPPORT
-+   extern _int64 filesize64;
-+@@ -441,6 +440,9 @@ struct zlist far *z;    /* zip entry to
-+   if (tim == 0 || q == (zoff_t) -3)
-+     return ZE_OPEN;
-+ 
-++  if (timestamp > 0)
-++    tim = unix2dostime(&timestamp);
-++
-+   /* q is set to -1 if the input file is a device, -2 for a volume label */
-+   if (q == (zoff_t) -2) {
-+      isdir = 1;
diff --git a/patches/openwrt/0018-firmware-utils-add-sercomm-netgear-tool.patch b/patches/openwrt/0018-firmware-utils-add-sercomm-netgear-tool.patch
deleted file mode 100644
index e2fd53d2d..000000000
--- a/patches/openwrt/0018-firmware-utils-add-sercomm-netgear-tool.patch
+++ /dev/null
@@ -1,469 +0,0 @@
-From: Ludwig Thomeczek <ledesrc@wxorx.net>
-Date: Tue, 12 Jun 2018 21:16:40 +0200
-Subject: firmware-utils: add sercomm/netgear tool
-
-This adds a tool to generate a firmware file accepted
-by Netgear or sercomm devices.
-
-They use a zip-packed rootfs with header and a custom
-checksum. The generated Image can be flashed via the
-nmrpflash tool or the webinterface of the router.
-
-Signed-off-by: Ludwig Thomeczek <ledesrc@wxorx.net>
-
-firmware-utils/mksercommfw: fix musl build
-
-* add missing <sys/types.h> for musl
-
-Signed-off-by: Andy Walsh <andy.walsh44+github@gmail.com>
-
-firmware-utils/mksercommfw: fix build with clang/macOS
-
-fixes error: non-void function 'main' should return a value
-
-Fixes: FS#1770
-
-Signed-off-by: Ryan Mounce <ryan@mounce.com.au>
-
-ramips: fix image generation for mt76x8
-
-Buildbot fails to generate images for targets also generating a
-Sercomm binary with following error:
-
-Opening file: /mnt/ramdisk/koen/firmware/builds/owrt_mt76x8/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/tmp/openwrt-ramips-mt76x8-netgear_r6120-squashfs-factory.img.rootfs.zip
-Filesize: 3648606 .
-mksercommfw: malloc.c:2427: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
-Makefile:287: recipe for target '/mnt/ramdisk/koen/firmware/builds/owrt_mt76x8/build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/tmp/openwrt-ramips-mt76x8-netgear_r6120-squashfs-factory.img' failed
-
-Debugging using valgrind shows stack corruption due to a buffer overflow.
-The author of the generator assumes the filename ends with "root",
-while it should be "rootfs".
-
-Fix this by accounting for the 2 missing characters which solves the build issues.
-
-More work is required to cleanup this source, which will be done later on.
-
-Reported-by: Hannu Nyman <hannu.nyman@iki.fi>
-Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
-
-ramips: fix netgear r6120 factory image generation
-
-as indicated in commit c5bf408ed6bd "(ramips: fix image generation for mt76x8")
-more rework was needed to fix the other issues.
-
-Building on another machine, but using the same arch, showed
-the application failing again for different reasons.
-
-Fix this by completely rewriting the application, fixing following found issues:
-
-- buffer overflows, resulting in stack corruption
-- flaws in memory requirement calculations (too small, too large)
-- memory leaks
-- missing bounds checking on string handling
-- non-reproducable images, by using unitilized memory in checksum calculation
-- missing error handling, resulting in succes on specific image errors
-- endianness errors when building on BE machines
-- various minor build warnings
-- documentation did not match the code actions (header item locations)
-- allowing input to be decimal, hex or octal now
-
-Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
-
-tools: firmware-utils: mksercommfw build on Darwin
-
-asm/byteorder.h & hence __cpu_to_be32() doesn't exist on Darwin
-
-Shamelessly copy some byte swap functions from oseama.c
-
-Acked-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
-Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
-
-firmware-utils: mksercommfw: overhaul image creation
-
-Move the zip compression into a build recipe. Pad the image using the
-existing build recipes as well to remove duplicate functionality
-
-Change the code to append header and footer in two steps. Allow to use a
-fixed filename as the netgear update image does.
-
-Use a fixed timestamp within the zip archive to make the images
-reproducible.
-
-Due to the changes we are now compatible to the gnu89 c standard used by
-default on the buildbots and we don't need to force a more recent
-standard anymore.
-
-Beside all changes, the footer still looks wrong in compare to the
-netgear update image.
-
-Signed-off-by: Mathias Kresin <dev@kresin.me>
-
-diff --git a/include/image-commands.mk b/include/image-commands.mk
-index 552d8db1cbacf533c12d0d8e2e5cffbe5591adb4..aec044294365bf5e964906e022d468d1a1c95fba 100644
---- a/include/image-commands.mk
-+++ b/include/image-commands.mk
-@@ -115,6 +115,16 @@ define Build/tplink-safeloader
- 		$(if $(findstring sysupgrade,$(word 1,$(1))),-S) && mv $@.new $@ || rm -f $@
- endef
- 
-+define Build/mksercommfw
-+	-$(STAGING_DIR_HOST)/bin/mksercommfw \
-+		$@ \
-+		$(KERNEL_OFFSET) \
-+		$(HWID) \
-+		$(HWVER) \
-+		$(SWVER)
-+endef
-+
-+
- define Build/append-dtb
- 	cat $(KDIR)/image-$(firstword $(DEVICE_DTS)).dtb >> $@
- endef
-@@ -152,6 +162,16 @@ define Build/gzip
- 	@mv $@.new $@
- endef
- 
-+define Build/zip
-+	mkdir $@.tmp
-+	mv $@ $@.tmp/$(1)
-+
-+	zip -j -X \
-+		$(if $(SOURCE_DATE_EPOCH),--mtime="$(SOURCE_DATE_EPOCH)") \
-+		$@ $@.tmp/$(if $(1),$(1),$@)
-+	rm -rf $@.tmp
-+endef
-+
- define Build/jffs2
- 	rm -rf $(KDIR_TMP)/$(DEVICE_NAME)/jffs2 && \
- 		mkdir -p $(KDIR_TMP)/$(DEVICE_NAME)/jffs2/$$(dirname $(1)) && \
-diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
-index bc282666d8c1a4b6ce5beabe2b492331fb48a23a..f1bf78e0713a1bc47d4ac384efdac1d08c1bd8bc 100644
---- a/target/linux/ramips/image/mt76x8.mk
-+++ b/target/linux/ramips/image/mt76x8.mk
-@@ -2,17 +2,22 @@
- # MT76x8 Profiles
- #
- 
--DEVICE_VARS += SERCOMM_KERNEL_OFFSET SERCOMM_HWID SERCOMM_HWVER SERCOMM_SWVER
-+DEVICE_VARS += SERCOMM_HWID SERCOMM_HWVER SERCOMM_SWVER
- 
--define Build/mksercommfw
-+define Build/sercom-seal
- 	$(STAGING_DIR_HOST)/bin/mksercommfw \
--		$@ \
--		$(SERCOMM_KERNEL_OFFSET) \
--		$(SERCOMM_HWID) \
--		$(SERCOMM_HWVER) \
--		$(SERCOMM_SWVER)
-+		-i $@ \
-+		-b $(SERCOMM_HWID) \
-+		-r $(SERCOMM_HWVER) \
-+		-v $(SERCOMM_SWVER) \
-+		$(1)
- endef
- 
-+define Build/sercom-footer
-+	$(call Build/sercom-seal,-f)
-+endef
-+
-+
- define Device/tplink
-   TPLINK_FLASHLAYOUT :=
-   TPLINK_HWID :=
-@@ -107,14 +112,14 @@ define Device/netgear_r6120
-   IMAGE_SIZE := $(ralink_default_fw_size_16M)
-   DEVICE_TITLE := Netgear R6120
-   DEVICE_PACKAGES := kmod-usb2 kmod-usb-ohci
--  SERCOMM_KERNEL_OFFSET := 90000
-   SERCOMM_HWID := CGQ
-   SERCOMM_HWVER := A001
--  SERCOMM_SWVER := 0040
-+  SERCOMM_SWVER := 0x0040
-   IMAGES += factory.img
-   IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE)| append-rootfs | pad-rootfs
-   IMAGE/sysupgrade.bin := $$(IMAGE/default) | append-metadata | check-size $$$$(IMAGE_SIZE)
--  IMAGE/factory.img := $$(IMAGE/default) | mksercommfw
-+  IMAGE/factory.img := pad-extra 576k | $$(IMAGE/default) | \
-+	sercom-footer | pad-to 128 | zip R6120.bin | sercom-seal
- endef
- TARGET_DEVICES += netgear_r6120
- 
-diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
-index a6379e35eb01f1cbbe2b1ece3fc9eb20bcd68d90..ca7722163d68d028b88e4cca2f0457875e633af6 100644
---- a/tools/firmware-utils/Makefile
-+++ b/tools/firmware-utils/Makefile
-@@ -85,6 +85,7 @@ define Host/Compile
- 	$(call cc,mkdhpimg buffalo-lib, -Wall)
- 	$(call cc,mkdlinkfw mkdlinkfw-lib, -lz -Wall --std=gnu99)
- 	$(call cc,dns313-header, -Wall)
-+	$(call cc,mksercommfw, -Wall)
- endef
- 
- define Host/Install
-diff --git a/tools/firmware-utils/src/mksercommfw.c b/tools/firmware-utils/src/mksercommfw.c
-new file mode 100644
-index 0000000000000000000000000000000000000000..f6f1d93f37970be0cdf94e71a5e1093b3e92c040
---- /dev/null
-+++ b/tools/firmware-utils/src/mksercommfw.c
-@@ -0,0 +1,261 @@
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <byteswap.h>
-+#include <endian.h>
-+#include <getopt.h>
-+
-+#if !defined(__BYTE_ORDER)
-+#error "Unknown byte order"
-+#endif
-+
-+#if __BYTE_ORDER == __BIG_ENDIAN
-+#define cpu_to_be32(x)  (x)
-+#elif __BYTE_ORDER == __LITTLE_ENDIAN
-+#define cpu_to_be32(x)  bswap_32(x)
-+#else
-+#error "Unsupported endianness"
-+#endif
-+
-+/* #define DEBUG 1 */
-+
-+#ifdef DEBUG
-+#define DBG(...) {printf(__VA_ARGS__); }
-+#else
-+#define DBG(...) {}
-+#endif
-+
-+#define ERR(...) {printf(__VA_ARGS__); }
-+
-+/*
-+ * Fw Header Layout for Netgear / Sercomm devices (bytes)
-+ *
-+ * Size : 512 bytes + zipped image size
-+ *
-+ * Locations:
-+ * magic  : 0-6    ASCII
-+ * version: 7-11   fixed
-+ * hwID   : 11-44  ASCII
-+ * hwVer  : 45-54  ASCII
-+ * swVer  : 55-62  uint32_t in BE
-+ * magic  : 63-69  ASCII
-+ * ChkSum : 511    Inverse value of the full image checksum while this location is 0x00
-+ */
-+static const char* magic = "sErCoMm"; /* 7 */
-+static const unsigned char version[4] = { 0x00, 0x01, 0x00, 0x00 };
-+static const int header_sz = 512;
-+static const int footer_sz = 71;
-+
-+static int is_header = 1;
-+
-+struct file_info {
-+	char* file_name; /* name of the file */
-+	char* file_data; /* data of the file in memory */
-+	u_int32_t file_size; /* length of the file */
-+};
-+
-+static u_int8_t getCheckSum(char* data, int len) {
-+	u_int8_t new = 0;
-+	int i;
-+
-+	if (!data) {
-+		ERR("Invalid pointer provided!\n");
-+		return 0;
-+	}
-+
-+	for (i = 0; i < len; i++) {
-+		new += data[i];
-+	}
-+
-+	return new;
-+}
-+
-+/*
-+ * read file into buffer
-+ * add space for header/footer
-+ */
-+static int copyToOutputBuf(struct file_info* finfo) {
-+	FILE* fp = NULL;
-+
-+	int file_sz = 0;
-+	int extra_sz;
-+	int hdr_pos;
-+	int img_pos;
-+
-+	if (!finfo || !finfo->file_name) {
-+		ERR("Invalid pointer provided!\n");
-+		return -1;
-+	}
-+
-+	DBG("Opening file: %s\n", finfo->file_name);
-+
-+	if (!(fp = fopen(finfo->file_name, "rb"))) {
-+		ERR("Error opening file: %s\n", finfo->file_name);
-+		return -1;
-+	}
-+
-+	/* Get filesize */
-+	rewind(fp);
-+	fseek(fp, 0L, SEEK_END);
-+	file_sz = ftell(fp);
-+	rewind(fp);
-+
-+	if (file_sz < 1) {
-+		ERR("Error getting filesize: %s\n", finfo->file_name);
-+		fclose(fp);
-+		return -1;
-+	}
-+
-+	if (is_header) {
-+		extra_sz = header_sz;
-+		hdr_pos = 0;
-+		img_pos = header_sz;
-+	} else {
-+		extra_sz = footer_sz;
-+		hdr_pos = file_sz;
-+		img_pos = 0;
-+	}
-+
-+	DBG("Filesize: %i\n", file_sz);
-+	finfo->file_size = file_sz + extra_sz;
-+
-+	if (!(finfo->file_data = malloc(finfo->file_size))) {
-+		ERR("Out of memory!\n");
-+		fclose(fp);
-+		return -1;
-+	}
-+
-+	/* init header/footer bytes */
-+	memset(finfo->file_data + hdr_pos, 0, extra_sz);
-+
-+	/* read file and take care of leading header if exists */
-+	if (fread(finfo->file_data + img_pos, 1, file_sz, fp) != file_sz) {
-+		ERR("Error reading file %s\n", finfo->file_name);
-+		fclose(fp);
-+		return -1;
-+	}
-+
-+	DBG("File: read successful\n");
-+	fclose(fp);
-+
-+	return hdr_pos;
-+}
-+
-+static int writeFile(struct file_info* finfo) {
-+	FILE* fp;
-+
-+	if (!finfo || !finfo->file_name) {
-+		ERR("Invalid pointer provided!\n");
-+		return -1;
-+	}
-+
-+	DBG("Opening file: %s\n", finfo->file_name);
-+
-+	if (!(fp = fopen(finfo->file_name, "w"))) {
-+		ERR("Error opening file: %s\n", finfo->file_name);
-+		return -1;
-+	}
-+
-+	DBG("Writing file: %s\n", finfo->file_name);
-+
-+	if (fwrite(finfo->file_data, 1, finfo->file_size, fp) != finfo->file_size) {
-+		ERR("Wanted to write, but something went wrong!\n");
-+		fclose(fp);
-+		return -1;
-+	}
-+
-+	fclose(fp);
-+	return 0;
-+}
-+
-+static void usage(char* argv[]) {
-+	printf("Usage: %s [OPTIONS...]\n"
-+	       "\n"
-+	       "Options:\n"
-+	       "  -f            add sercom footer (if absent, header)\n"
-+	       "  -b <hwid>     use hardware id specified with <hwid> (ASCII)\n"
-+	       "  -r <hwrev>    use hardware revision specified with <hwrev> (ASCII)\n"
-+	       "  -v <version>  set image version to <version> (decimal, hex or octal notation)\n"
-+	       "  -i <file>     input file\n"
-+	       , argv[0]);
-+}
-+
-+int main(int argc, char* argv[]) {
-+	struct file_info image = { 0 };
-+
-+	char* hwID = NULL;
-+	char* hwVer = NULL;
-+	u_int32_t swVer = 0;
-+	u_int8_t chkSum;
-+	int hdr_offset;
-+
-+	while ( 1 ) {
-+		int c;
-+
-+		c = getopt(argc, argv, "b:i:r:v:f");
-+		if (c == -1)
-+			break;
-+
-+		switch (c) {
-+		case 'b':
-+			hwID = optarg;
-+			break;
-+		case 'f':
-+			is_header = 0;
-+			break;
-+		case 'i':
-+			image.file_name = optarg;
-+			break;
-+		case 'r':
-+			hwVer = optarg;
-+			break;
-+		case 'v':
-+			swVer = (u_int32_t) strtol(optarg, NULL, 0);
-+			swVer = cpu_to_be32(swVer);
-+			break;
-+		default:
-+			usage(argv);
-+			return EXIT_FAILURE;
-+		}
-+	}
-+
-+	if (!hwID || !hwVer || !image.file_name) {
-+			usage(argv);
-+			return EXIT_FAILURE;
-+	}
-+
-+	/*
-+	 * copy input to buffer, add extra space for header/footer and return
-+	 * header position
-+	 */
-+	hdr_offset = copyToOutputBuf(&image);
-+	if (hdr_offset < 0)
-+		return EXIT_FAILURE;
-+
-+	DBG("Filling header: %s %s %2X %s\n", hwID, hwVer, swVer, magic);
-+
-+	strncpy(image.file_data + hdr_offset + 0, magic, 7);
-+	memcpy(image.file_data + hdr_offset + 7, version, sizeof(version));
-+	strncpy(image.file_data + hdr_offset + 11, hwID, 34);
-+	strncpy(image.file_data + hdr_offset + 45, hwVer, 10);
-+	memcpy(image.file_data + hdr_offset + 55, &swVer, sizeof(swVer));
-+	strncpy(image.file_data + hdr_offset + 63, magic, 7);
-+
-+	/* calculate checksum and invert checksum */
-+	if (is_header) {
-+		chkSum = getCheckSum(image.file_data, image.file_size);
-+		chkSum = (chkSum ^ 0xFF) + 1;
-+		DBG("Checksum for Image: %hhX\n", chkSum);
-+
-+		/* write checksum to header */
-+		image.file_data[511] = (char) chkSum;
-+	}
-+
-+	/* overwrite input file */
-+	if (writeFile(&image))
-+		return EXIT_FAILURE;
-+
-+	return EXIT_SUCCESS;
-+}
diff --git a/patches/openwrt/0019-ath10k-ct-fix-incorrect-multicast-broadcast-rate-setting.patch b/patches/openwrt/0019-ath10k-ct-fix-incorrect-multicast-broadcast-rate-setting.patch
deleted file mode 100644
index 63d625e0c..000000000
--- a/patches/openwrt/0019-ath10k-ct-fix-incorrect-multicast-broadcast-rate-setting.patch
+++ /dev/null
@@ -1,113 +0,0 @@
-From: Sven Eckelmann <sven@narfation.org>
-Date: Mon, 25 Feb 2019 20:42:28 +0100
-Subject: ath10k-ct: fix incorrect multicast/broadcast rate setting
-
-If no mcast_rate is set for the wifi-iface then there is no rate_idx (0)
-set for the bss. This can break for example 5GHz meshpoint interfaces
-because 0 maps to a CCK rate (11Mbit/s).
-
-It must also be avoided that the internal state for the rates is not synced
-with the mac80211 rates state. Otherwise, the a rate (e.g. a wifi-iface
-mcast_rate for a meshpoint interface) will be set on startup. And a short
-while after that, ath10k-ct specific code in
-ath10k_check_apply_special_rates is missing a valid rate in its own
-structures and is then recalculating a new default rate. This default rate
-is in most situations not the requested rate.
-
-Fixes: 4df3c71cd4c5 ("ath10k-ct: Update to 2018-12-11 and use version based on 4.19")
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-
-Forwarded: https://github.com/openwrt/openwrt/pull/1862
-
-diff --git a/package/kernel/ath10k-ct/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch b/package/kernel/ath10k-ct/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..0e4f0565d6191a4e91eb2cfdffb25a850dd69a28
---- /dev/null
-+++ b/package/kernel/ath10k-ct/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch
-@@ -0,0 +1,43 @@
-+From: Pradeep kumar Chitrapu <pradeepc@codeaurora.org>
-+Date: Mon, 10 Dec 2018 20:56:11 -0800
-+Subject: ath10k: fix incorrect multicast/broadcast rate setting
-+
-+Invalid rate code is sent to firmware when multicast rate value of 0 is
-+sent to driver indicating disabled case, causing broken mesh path.
-+so fix that.
-+
-+Tested on QCA9984 with firmware 10.4-3.6.1-00827
-+
-+Fixes: cd93b83ad92 ("ath10k: support for multicast rate control")
-+Co-developed-by: Zhi Chen <zhichen@codeaurora.org>
-+Signed-off-by: Zhi Chen <zhichen@codeaurora.org>
-+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+
-+Origin: other, https://patchwork.kernel.org/patch/10723033/
-+
-+--- a/ath10k-4.13/mac.c
-++++ b/ath10k-4.13/mac.c
-+@@ -6264,8 +6264,8 @@ static void ath10k_bss_info_changed(stru
-+ 	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-+ 	u16 bitrate, hw_value;
-+-	u8 rate, basic_rate_idx;
-+-	int rateidx, ret = 0, hw_rate_code;
-++	u8 rate, basic_rate_idx, rateidx;
-++	int ret = 0, hw_rate_code, mcast_rate;
-+ 	enum nl80211_band band;
-+ 	const struct ieee80211_supported_band *sband;
-+ 
-+@@ -6438,7 +6438,11 @@ static void ath10k_bss_info_changed(stru
-+ 	if (changed & BSS_CHANGED_MCAST_RATE &&
-+ 	    !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
-+ 		band = def.chan->band;
-+-		rateidx = vif->bss_conf.mcast_rate[band] - 1;
-++		mcast_rate = vif->bss_conf.mcast_rate[band];
-++		if (mcast_rate > 0)
-++			rateidx = mcast_rate - 1;
-++		else
-++			rateidx = ffs(vif->bss_conf.basic_rates) - 1;
-+ 
-+ 		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-+ 			rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
-diff --git a/package/kernel/ath10k-ct/patches/980-ath10k-commit-rates-from-mac80211.patch b/package/kernel/ath10k-ct/patches/980-ath10k-commit-rates-from-mac80211.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..6b12ba0995cdbd56f1e5dce8c5aba14e7af95c3c
---- /dev/null
-+++ b/package/kernel/ath10k-ct/patches/980-ath10k-commit-rates-from-mac80211.patch
-@@ -0,0 +1,37 @@
-+From: Sven Eckelmann <sven@narfation.org>
-+Date: Mon, 10 Dec 2018 20:56:11 -0800
-+Subject: ath10k-ct: apply mac80211 rates to ath10k-ct rate state
-+
-+The rates from mac80211 have to be copied to the state of ath10k-ct or
-+otherwise the ath10k_check_apply_special_rates function overwrites
-+them again with some default values. This breaks for example the
-+mcast_rate set for a wifi-iface.
-+
-+Signed-off-by: Sven Eckelmann <sven@narfation.org>
-+
-+--- a/ath10k-4.13/mac.c
-++++ b/ath10k-4.13/mac.c
-+@@ -6460,6 +6460,7 @@ static void ath10k_bss_info_changed(stru
-+ 			   "mac vdev %d mcast_rate %x\n",
-+ 			   arvif->vdev_id, rate);
-+ 
-++		arvif->mcast_rate[band] = rate;
-+ 		vdev_param = ar->wmi.vdev_param->mcast_data_rate;
-+ 		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-+ 						vdev_param, rate);
-+@@ -6468,6 +6469,7 @@ static void ath10k_bss_info_changed(stru
-+ 				    "failed to set mcast rate on vdev %i: %d\n",
-+ 				    arvif->vdev_id,  ret);
-+ 
-++		arvif->bcast_rate[band] = rate;
-+ 		vdev_param = ar->wmi.vdev_param->bcast_data_rate;
-+ 		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
-+ 						vdev_param, rate);
-+@@ -6494,6 +6496,7 @@ static void ath10k_bss_info_changed(stru
-+ 			return;
-+ 		}
-+ 
-++		arvif->mgt_rate[def.chan->band] = hw_rate_code;
-+ 		vdev_param = ar->wmi.vdev_param->mgmt_rate;
-+ 		ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
-+ 						hw_rate_code);
diff --git a/patches/openwrt/0020-mac80211-ath10k-fix-incorrect-multicast-broadcast-rate-setting.patch b/patches/openwrt/0020-mac80211-ath10k-fix-incorrect-multicast-broadcast-rate-setting.patch
deleted file mode 100644
index 17f976089..000000000
--- a/patches/openwrt/0020-mac80211-ath10k-fix-incorrect-multicast-broadcast-rate-setting.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From: Sven Eckelmann <sven@narfation.org>
-Date: Mon, 25 Feb 2019 20:42:28 +0100
-Subject: mac80211: ath10k: fix incorrect multicast/broadcast rate setting
-
-If no mcast_rate is set for the wifi-iface then there is no rate_idx (0)
-set for the bss. This breaks for example 5GHz meshpoint interfaces because
-0 maps to a CCK rate (11Mbit/s).
-
-Fixes: db90c243a0b9 ("mac80211: update to version based on 4.19-rc4")
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-
-diff --git a/package/kernel/mac80211/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch b/package/kernel/mac80211/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..8695b7e094885bb479e14386a0461a25cf57603d
---- /dev/null
-+++ b/package/kernel/mac80211/patches/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch
-@@ -0,0 +1,43 @@
-+From: Pradeep kumar Chitrapu <pradeepc@codeaurora.org>
-+Date: Mon, 10 Dec 2018 20:56:11 -0800
-+Subject: ath10k: fix incorrect multicast/broadcast rate setting
-+
-+Invalid rate code is sent to firmware when multicast rate value of 0 is
-+sent to driver indicating disabled case, causing broken mesh path.
-+so fix that.
-+
-+Tested on QCA9984 with firmware 10.4-3.6.1-00827
-+
-+Fixes: cd93b83ad92 ("ath10k: support for multicast rate control")
-+Co-developed-by: Zhi Chen <zhichen@codeaurora.org>
-+Signed-off-by: Zhi Chen <zhichen@codeaurora.org>
-+Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
-+
-+Origin: other, https://patchwork.kernel.org/patch/10723033/
-+
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -5484,8 +5484,8 @@ static void ath10k_bss_info_changed(stru
-+ 	struct cfg80211_chan_def def;
-+ 	u32 vdev_param, pdev_param, slottime, preamble;
-+ 	u16 bitrate, hw_value;
-+-	u8 rate, basic_rate_idx;
-+-	int rateidx, ret = 0, hw_rate_code;
-++	u8 rate, basic_rate_idx, rateidx;
-++	int ret = 0, hw_rate_code, mcast_rate;
-+ 	enum nl80211_band band;
-+ 	const struct ieee80211_supported_band *sband;
-+ 
-+@@ -5658,7 +5658,11 @@ static void ath10k_bss_info_changed(stru
-+ 	if (changed & BSS_CHANGED_MCAST_RATE &&
-+ 	    !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) {
-+ 		band = def.chan->band;
-+-		rateidx = vif->bss_conf.mcast_rate[band] - 1;
-++		mcast_rate = vif->bss_conf.mcast_rate[band];
-++		if (mcast_rate > 0)
-++			rateidx = mcast_rate - 1;
-++		else
-++			rateidx = ffs(vif->bss_conf.basic_rates) - 1;
-+ 
-+ 		if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
-+ 			rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
diff --git a/patches/openwrt/0021-ramips-fix-R6120-factory-image.patch b/patches/openwrt/0021-ramips-fix-R6120-factory-image.patch
deleted file mode 100644
index ea93569e5..000000000
--- a/patches/openwrt/0021-ramips-fix-R6120-factory-image.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 9 May 2019 18:01:13 +0200
-Subject: ramips: fix R6120 factory image
-
-The factory firmware omits the JFFS2 end-marker while flashing via
-web-interface. Add a 64k padding after the marker fixes this problem.
-
-When the end-marker is not present, OpenWRT won't save the overlayfs
-after initial flash.
-
-Reported-by: Andreas Ziegler <dev@andreas-ziegler.de>
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk
-index f1bf78e0713a1bc47d4ac384efdac1d08c1bd8bc..a096720b09be18bae450edaab187df8be734fe13 100644
---- a/target/linux/ramips/image/mt76x8.mk
-+++ b/target/linux/ramips/image/mt76x8.mk
-@@ -118,7 +118,7 @@ define Device/netgear_r6120
-   IMAGES += factory.img
-   IMAGE/default := append-kernel | pad-to $$$$(BLOCKSIZE)| append-rootfs | pad-rootfs
-   IMAGE/sysupgrade.bin := $$(IMAGE/default) | append-metadata | check-size $$$$(IMAGE_SIZE)
--  IMAGE/factory.img := pad-extra 576k | $$(IMAGE/default) | \
-+  IMAGE/factory.img := pad-extra 576k | $$(IMAGE/default) | pad-to $$$$(BLOCKSIZE) | \
- 	sercom-footer | pad-to 128 | zip R6120.bin | sercom-seal
- endef
- TARGET_DEVICES += netgear_r6120
diff --git a/patches/openwrt/0022-firmware-utils-tplink-safeloader-Add-CPE210-v3.patch b/patches/openwrt/0022-firmware-utils-tplink-safeloader-Add-CPE210-v3.patch
deleted file mode 100644
index 71b394ea1..000000000
--- a/patches/openwrt/0022-firmware-utils-tplink-safeloader-Add-CPE210-v3.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-Date: Wed, 10 Oct 2018 20:05:53 +0200
-Subject: firmware-utils: tplink-safeloader: Add CPE210 v3
-
-Add TP-Link CPE210 v3 to the support list.
-It's identical to the v2.
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-[Use separate definition to prevent cross-updates]
-Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-
-diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c
-index 4b227e1c97b6c5b236dba29dbdd5f0bcd68621cb..de15faf6796c993efc6c2a36b22bb1e978e3be90 100644
---- a/tools/firmware-utils/src/tplink-safeloader.c
-+++ b/tools/firmware-utils/src/tplink-safeloader.c
-@@ -197,6 +197,42 @@ static struct device_info boards[] = {
- 		.last_sysupgrade_partition = "support-list",
- 	},
- 
-+	/** Firmware layout for the CPE210 V3 */
-+	{
-+		.id     = "CPE210V3",
-+		.vendor = "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
-+		.support_list =
-+			"SupportList:\r\n"
-+			"CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
-+			"CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
-+			"CPE210(TP-LINK|UN|N300-2):3.0\r\n"
-+			"CPE210(TP-LINK|EU|N300-2):3.0\r\n",
-+		.support_trail = '\xff',
-+		.soft_ver = NULL,
-+
-+		.partitions = {
-+			{"fs-uboot", 0x00000, 0x20000},
-+			{"partition-table", 0x20000, 0x02000},
-+			{"default-mac", 0x30000, 0x00020},
-+			{"product-info", 0x31100, 0x00100},
-+			{"device-info", 0x31400, 0x00400},
-+			{"signature", 0x32000, 0x00400},
-+			{"device-id", 0x33000, 0x00100},
-+			{"os-image", 0x40000, 0x1c0000},
-+			{"file-system", 0x200000, 0x5b0000},
-+			{"soft-version", 0x7b0000, 0x00100},
-+			{"support-list", 0x7b1000, 0x01000},
-+			{"user-config", 0x7c0000, 0x10000},
-+			{"default-config", 0x7d0000, 0x10000},
-+			{"log", 0x7e0000, 0x10000},
-+			{"radio", 0x7f0000, 0x10000},
-+			{NULL, 0, 0}
-+		},
-+
-+		.first_sysupgrade_partition = "os-image",
-+		.last_sysupgrade_partition = "support-list",
-+	},
-+
- 	/** Firmware layout for the CPE510/520 */
- 	{
- 		.id	= "CPE510",
diff --git a/patches/openwrt/0023-ar71xx-Add-support-for-TP-Link-CPE210-v3.patch b/patches/openwrt/0023-ar71xx-Add-support-for-TP-Link-CPE210-v3.patch
deleted file mode 100644
index 20213733b..000000000
--- a/patches/openwrt/0023-ar71xx-Add-support-for-TP-Link-CPE210-v3.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-From: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-Date: Wed, 10 Oct 2018 20:13:09 +0200
-Subject: ar71xx: Add support for TP-Link CPE210 v3
-
-Looks identical to the v2
-
-This PR adds support for a popular low-cost 2.4GHz N based AP
-
-Specifications:
- - SoC: Qualcomm Atheros QCA9533 (650MHz)
- - RAM: 64MB
- - Storage: 8 MB SPI NOR
- - Wireless: 2.4GHz N based built into SoC 2x2
- - Ethernet: 1x 100/10 Mbps, integrated into SoC, 24V POE IN
-
-Installation:
-Flash factory image through stock firmware WEB UI or
-through TFTP
-To get to TFTP recovery just hold reset button while
-powering on for around 4-5 seconds and release.
-Rename factory image to recovery.bin
-Stock TFTP server IP:192.168.0.100
-Stock device TFTP address:192.168.0.254
-
-Signed-off-by: Robert Marko <robimarko@gmail.com>
-[Adjusted for separate safeloader entry, do not inherit device
-definition from cpe210-v2]
-Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
-
-diff --git a/target/linux/ar71xx/base-files/etc/board.d/01_leds b/target/linux/ar71xx/base-files/etc/board.d/01_leds
-index 23f3d23bf53883fb08944bc65b98cac06a16c0a5..e0222f3637b60b89a6ef6c0d10cfb20fbe73f075 100755
---- a/target/linux/ar71xx/base-files/etc/board.d/01_leds
-+++ b/target/linux/ar71xx/base-files/etc/board.d/01_leds
-@@ -249,6 +249,7 @@ cf-e530n)
- 	;;
- cpe210|\
- cpe210-v2|\
-+cpe210-v3|\
- cpe510|\
- wbs210|\
- wbs510)
-@@ -259,7 +260,8 @@ wbs510)
- 	ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:green:link4" "wlan0" "76" "100" "-75" "13"
- 
- 	case "$board" in
--	cpe210-v2)
-+	cpe210-v2|\
-+	cpe210-v3)
- 		ucidef_set_led_netdev "lan" "LAN" "tp-link:green:lan0" "eth0"
- 		;;
- 	*)
-diff --git a/target/linux/ar71xx/base-files/etc/board.d/02_network b/target/linux/ar71xx/base-files/etc/board.d/02_network
-index e9522252a2b8ba7de1c8ca7d070ff7f2897aade9..386d93e58451b953937320b1bfe8d71ed73c69fd 100755
---- a/target/linux/ar71xx/base-files/etc/board.d/02_network
-+++ b/target/linux/ar71xx/base-files/etc/board.d/02_network
-@@ -75,6 +75,7 @@ ar71xx_setup_interfaces()
- 	cf-e380ac-v1|\
- 	cf-e380ac-v2|\
- 	cpe210-v2|\
-+	cpe210-v3|\
- 	dr342|\
- 	eap120|\
- 	eap300v2|\
-diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh
-index ccbd4e77c324a36e7fba6e6dccad59d8f94a3921..2200069c647b33220126e797b6a61928d1fb428e 100755
---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
-+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
-@@ -583,6 +583,10 @@ ar71xx_board_detect() {
- 		name="cpe210-v2"
- 		tplink_pharos_board_detect "$(tplink_pharos_v2_get_model_string)"
- 		;;
-+	*"CPE210 v3")
-+		name="cpe210-v3"
-+		tplink_pharos_board_detect "$(tplink_pharos_v2_get_model_string)"
-+		;;
- 	*"CPE505N")
- 		name="cpe505n"
- 		;;
-diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
-index ca1270b7fdc84c53f8417c226f18ca4fff1f27d8..a04dd7441d28e9db4dc7c744707bb5f35936da00 100755
---- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
-@@ -587,7 +587,8 @@ platform_check_image() {
- 		tplink_pharos_check_image "$1" "7f454c46" "$(tplink_pharos_get_model_string)" '' && return 0
- 		return 1
- 		;;
--	cpe210-v2)
-+	cpe210-v2|\
-+	cpe210-v3)
- 		tplink_pharos_check_image "$1" "01000000" "$(tplink_pharos_v2_get_model_string)" '\0\xff\r' && return 0
- 		return 1
- 		;;
-diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c
-index ceb1769ddd522d51014228fe65e2662f2f3e627c..f25a69f08e8a69d9b6de0ca9d7d7d14f8dff5fa0 100644
---- a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c
-+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c
-@@ -236,6 +236,9 @@ MIPS_MACHINE(ATH79_MACH_CPE210, "CPE210", "TP-LINK CPE210/220",
- MIPS_MACHINE(ATH79_MACH_CPE210_V2, "CPE210V2", "TP-LINK CPE210 v2",
- 	     cpe210_v2_setup);
- 
-+MIPS_MACHINE(ATH79_MACH_CPE210_V3, "CPE210V3", "TP-LINK CPE210 v3",
-+             cpe210_v2_setup);
-+
- MIPS_MACHINE(ATH79_MACH_CPE510, "CPE510", "TP-LINK CPE510/520",
- 	     cpe510_setup);
- 
-diff --git a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
-index 80f6e1d95b7a4e5559e7d5da041b32d962ad4e84..c82cb17cf613bdb3796a15e384215d4579767468 100644
---- a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
-+++ b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
-@@ -75,6 +75,7 @@ enum ath79_mach_type {
- 	ATH79_MACH_CF_E530N,			/* COMFAST CF-E530N */
- 	ATH79_MACH_CPE210,			/* TP-LINK CPE210 v1 */
- 	ATH79_MACH_CPE210_V2,			/* TP-LINK CPE210 v2 */
-+	ATH79_MACH_CPE210_V3,			/* TP-LINK CPE210 v3 */
- 	ATH79_MACH_CPE505N,			/* P&W CPE505N */
- 	ATH79_MACH_CPE510,			/* TP-LINK CPE510 */
- 	ATH79_MACH_CPE830,			/* YunCore CPE830 */
-diff --git a/target/linux/ar71xx/image/generic-tp-link.mk b/target/linux/ar71xx/image/generic-tp-link.mk
-index daf6c35ae4610d844bd9e8f44ea5deab72143a48..8ad1f6e38228b639d1d127937ba875c030a6a632 100644
---- a/target/linux/ar71xx/image/generic-tp-link.mk
-+++ b/target/linux/ar71xx/image/generic-tp-link.mk
-@@ -195,6 +195,18 @@ define Device/cpe210-v2
- endef
- TARGET_DEVICES += cpe210-v2
- 
-+define Device/cpe210-v3
-+  $(Device/cpexxx)
-+  DEVICE_TITLE := TP-LINK CPE210 v3
-+  BOARDNAME := CPE210V3
-+  TPLINK_BOARD_ID := CPE210V3
-+  KERNEL := kernel-bin | patch-cmdline | lzma | tplink-v1-header
-+  TPLINK_HWID := 0x0
-+  TPLINK_HWREV := 0
-+  TPLINK_HEADER_VERSION := 1
-+endef
-+TARGET_DEVICES += cpe210-v3
-+
- define Device/wbs210-v1
-   $(Device/cpe510-520-v1)
-   DEVICE_TITLE := TP-LINK WBS210 v1
diff --git a/patches/openwrt/0024-ramips-add-support-for-ASUS-RT-AC57U.patch b/patches/openwrt/0024-ramips-add-support-for-ASUS-RT-AC57U.patch
deleted file mode 100644
index 67bf6a9a2..000000000
--- a/patches/openwrt/0024-ramips-add-support-for-ASUS-RT-AC57U.patch
+++ /dev/null
@@ -1,292 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Sun, 23 Jun 2019 15:10:01 +0200
-Subject: ramips: add support for ASUS RT-AC57U
-
-SoC:   MediaTek MT7621AT
-RAM:   128M (Winbond W631GG6KB-15)
-FLASH: 16MB (Spansion S25FL128SA)
-WiFi:  MediaTek MT7603EN bgn 2SS
-WiFi:  MediaTek MT7612EN nac 2SS
-BTN:   Reset - WPS
-LED:    - Power
-        - LAN {1-4}
-        - WAN
-        - WiFi 2.4 GHz
-        - WiFi 5 GHz
-        - USB
-UART:  UART is present next to the Power LED.
-       TX - RX - GND - 3V3 / 57600-8N1
-       3V3 is the nearest one to the Power LED.
-
-Installation
-------------
-Via TFTP:
-1. Set your computers IP-Address to 192.168.1.75.
-2. Power up the Router with the Reset button pressed.
-3. Release the Reset button after 5 seconds.
-4. Upload OpenWRT sysupgrade image via TFTP:
- > tftp -4 -v -m binary 192.168.1.1 -c put <IMAGE>
-
-Via SSH:
-Note: User/password for SSH is identical with the one used in the
-Web-interface.
-1. Complete the initial setup wizard.
-2. Activate SSH under "Administration" -> "System".
-3. Transfer the OpenWrt sysupgrade image via scp:
- > scp owrt.bin admin@192.168.1.1:/tmp
-4. Connect via SSH to the router.
- > ssh admin@192.168.1.1
-5. Write the OpenWrt image to flash.
- > mtd-write -i /tmp/owrt.bin -d linux
-6. Reboot the router
- > reboot
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
-
-diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
-index 9424c7ddfd64f9149a24ff91e63b71990265d211..7ceec7742aa7a0248ea3c31053b9adda2b247c9c 100755
---- a/target/linux/ramips/base-files/etc/board.d/02_network
-+++ b/target/linux/ramips/base-files/etc/board.d/02_network
-@@ -186,6 +186,7 @@ ramips_setup_interfaces()
- 		ucidef_add_switch "switch0" \
- 			"1:lan" "2:lan" "3:lan" "4:lan" "6t@eth0"
- 		;;
-+	asus,rt-ac57u|\
- 	atp-52b|\
- 	awm002-evb-4M|\
- 	awm002-evb-8M|\
-@@ -413,6 +414,11 @@ ramips_setup_macs()
- 	wmdr-143n)
- 		lan_mac=$(cat /sys/class/net/eth0/address)
- 		;;
-+	asus,rt-ac57u|\
-+	vr500)
-+		lan_mac=$(mtd_get_mac_binary factory 57344)
-+		wan_mac=$(mtd_get_mac_binary factory 57350)
-+		;;
- 	all0239-3g|\
- 	carambola|\
- 	freestation5|\
-@@ -541,10 +547,6 @@ ramips_setup_macs()
- 		lan_mac=$(mtd_get_mac_ascii u-boot-env LAN_MAC_ADDR)
- 		wan_mac=$(mtd_get_mac_ascii u-boot-env WAN_MAC_ADDR)
- 		;;
--	vr500)
--		lan_mac=$(mtd_get_mac_binary factory 57344)
--		wan_mac=$(mtd_get_mac_binary factory 57350)
--		;;
- 	w306r-v20)
- 		lan_mac=$(cat /sys/class/net/eth0/address)
- 		wan_mac=$(macaddr_add "$lan_mac" 5)
-diff --git a/target/linux/ramips/base-files/etc/diag.sh b/target/linux/ramips/base-files/etc/diag.sh
-index 097cc6df569518f64dbfd641eeccc1a4b1b37a2b..16e482c3879ff727faea9ffde31da634004fee93 100644
---- a/target/linux/ramips/base-files/etc/diag.sh
-+++ b/target/linux/ramips/base-files/etc/diag.sh
-@@ -141,6 +141,7 @@ get_status_led() {
- 	youhua,wr1200js)
- 		status_led="$boardname:blue:wps"
- 		;;
-+	asus,rt-ac57u|\
- 	d240|\
- 	dap-1350|\
- 	na930|\
-diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-index 7213b22d0c2734488bd96bc34e921f08649b8c2f..e4d813341b0e4d1ac804ee8cf0ec258e9c08fcd1 100755
---- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
-+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
-@@ -27,6 +27,7 @@ platform_check_image() {
- 	ar725w|\
- 	asl26555-8M|\
- 	asl26555-16M|\
-+	asus,rt-ac57u|\
- 	awapn2403|\
- 	awm002-evb-4M|\
- 	awm002-evb-8M|\
-diff --git a/target/linux/ramips/dts/RT-AC57U.dts b/target/linux/ramips/dts/RT-AC57U.dts
-new file mode 100644
-index 0000000000000000000000000000000000000000..cdab94676e13d259eb80afbcb28347d75d1f08f6
---- /dev/null
-+++ b/target/linux/ramips/dts/RT-AC57U.dts
-@@ -0,0 +1,150 @@
-+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-+/dts-v1/;
-+
-+#include "mt7621.dtsi"
-+
-+#include <dt-bindings/gpio/gpio.h>
-+#include <dt-bindings/input/input.h>
-+
-+/ {
-+	compatible = "asus,rt-ac57u", "mediatek,mt7621-soc";
-+	model = "ASUS RT-AC57U";
-+
-+	aliases {
-+		led-boot = &led_power;
-+		led-failsafe = &led_power;
-+		led-running = &led_power;
-+		led-upgrade = &led_power;
-+	};
-+
-+	memory@0 {
-+		device_type = "memory";
-+		reg = <0x0 0x8000000>;
-+	};
-+
-+	chosen {
-+		bootargs = "console=ttyS0,57600";
-+	};
-+
-+	leds {
-+		compatible = "gpio-leds";
-+
-+		led_power: power {
-+			label = "rt-ac57u:blue:power";
-+			gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
-+		};
-+
-+		usb {
-+			label = "rt-ac57u:blue:usb";
-+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
-+		};
-+	};
-+
-+	keys {
-+		compatible = "gpio-keys-polled";
-+		poll-interval = <20>;
-+
-+		wps {
-+			label = "wps";
-+			gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
-+			linux,code = <KEY_WPS_BUTTON>;
-+		};
-+
-+		reset {
-+			label = "reset";
-+			gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
-+			linux,code = <KEY_RESTART>;
-+		};
-+	};
-+
-+	led-regulator {
-+		compatible = "regulator-fixed";
-+		regulator-name = "LED-Power";
-+		gpio = <&gpio1 14 GPIO_ACTIVE_LOW>;
-+		regulator-min-microvolt = <3300000>;
-+		regulator-max-microvolt = <3300000>;
-+		regulator-always-on;
-+	};
-+};
-+
-+&spi0 {
-+	status = "okay";
-+
-+	flash@0 {
-+		compatible = "jedec,spi-nor";
-+		reg = <0>;
-+		spi-max-frequency = <10000000>;
-+
-+		partitions {
-+			compatible = "fixed-partitions";
-+			#address-cells = <1>;
-+			#size-cells = <1>;
-+
-+			partition@0 {
-+				label = "u-boot";
-+				reg = <0x0 0x30000>;
-+				read-only;
-+			};
-+
-+			partition@30000 {
-+				label = "config";
-+				reg = <0x30000 0x10000>;
-+				read-only;
-+			};
-+
-+			factory: partition@40000 {
-+				label = "factory";
-+				reg = <0x40000 0x10000>;
-+				read-only;
-+			};
-+
-+			partition@50000 {
-+				compatible = "denx,uimage";
-+				label = "firmware";
-+				reg = <0x50000 0xfb0000>;
-+			};
-+		};
-+	};
-+};
-+
-+&pcie {
-+	status = "okay";
-+
-+	pcie0 {
-+		wifi@0,0 {
-+			reg = <0x0000 0 0 0 0>;
-+			mediatek,mtd-eeprom = <&factory 0x8000>;
-+			device_type = "pci";
-+
-+			led {
-+				led-sources = <2>;
-+				led-active-low;
-+			};
-+		};
-+	};
-+
-+	pcie1 {
-+		wifi@0,0 {
-+			reg = <0x0000 0 0 0 0>;
-+			mediatek,mtd-eeprom = <&factory 0x0000>;
-+			device_type = "pci";
-+
-+			led {
-+				led-active-low;
-+			};
-+		};
-+	};
-+};
-+
-+&ethernet {
-+	mtd-mac-address = <&factory 0x4e000>;
-+};
-+
-+&pinctrl {
-+	state_default: pinctrl0 {
-+		gpio {
-+			ralink,group = "sdhci";
-+			ralink,function = "gpio";
-+		};
-+	};
-+};
-diff --git a/target/linux/ramips/image/mt7621.mk b/target/linux/ramips/image/mt7621.mk
-index c8de8bd5ff7d1bec4de5c4ffd84a589892871ecb..e0f8cc65ebbfc93b4bfd765db5e62b5afda27c40 100644
---- a/target/linux/ramips/image/mt7621.mk
-+++ b/target/linux/ramips/image/mt7621.mk
-@@ -49,6 +49,14 @@ define Device/11acnas
- endef
- TARGET_DEVICES += 11acnas
- 
-+define Device/asus_rt-ac57u
-+  DTS := RT-AC57U
-+  DEVICE_TITLE := ASUS RT-AC57U
-+  IMAGE_SIZE := $(ralink_default_fw_size_16M)
-+  DEVICE_PACKAGES := kmod-mt7603 kmod-mt76x2 kmod-usb3 kmod-usb-ledtrig-usbport wpad-basic
-+endef
-+TARGET_DEVICES += asus_rt-ac57u
-+
- define Device/dir-860l-b1
-   DTS := DIR-860L-B1
-   BLOCKSIZE := 64k
-diff --git a/target/linux/ramips/mt7621/config-4.14 b/target/linux/ramips/mt7621/config-4.14
-index 2ea80a3ab0c174374fa8febc19031ff5a4dae4c3..0e060237802f2b1d6918f65894368934c225cb17 100644
---- a/target/linux/ramips/mt7621/config-4.14
-+++ b/target/linux/ramips/mt7621/config-4.14
-@@ -228,6 +228,8 @@ CONFIG_RCU_STALL_COMMON=y
- CONFIG_REGMAP=y
- CONFIG_REGMAP_I2C=y
- CONFIG_REGMAP_SPI=y
-+CONFIG_REGULATOR=y
-+CONFIG_REGULATOR_FIXED_VOLTAGE=y
- CONFIG_RESET_CONTROLLER=y
- CONFIG_RFS_ACCEL=y
- CONFIG_RPS=y
diff --git a/patches/openwrt/0025-uboot-fritz4040-add-fixes-for-bootloader-image-generation.patch b/patches/openwrt/0025-uboot-fritz4040-add-fixes-for-bootloader-image-generation.patch
deleted file mode 100644
index 06cd5209e..000000000
--- a/patches/openwrt/0025-uboot-fritz4040-add-fixes-for-bootloader-image-generation.patch
+++ /dev/null
@@ -1,111 +0,0 @@
-From: Matthias Schiffer <mschiffer@universe-factory.net>
-Date: Sat, 20 Jul 2019 13:12:58 +0200
-Subject: uboot-fritz4040: add fixes for bootloader image generation
-
-Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
-
-diff --git a/package/boot/uboot-fritz4040/patches/200-fritzcreator-replace-obscure-padding-generation-with.patch b/package/boot/uboot-fritz4040/patches/200-fritzcreator-replace-obscure-padding-generation-with.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..44062b88048f483b618992c51b1dffdfe7ca511a
---- /dev/null
-+++ b/package/boot/uboot-fritz4040/patches/200-fritzcreator-replace-obscure-padding-generation-with.patch
-@@ -0,0 +1,63 @@
-+From 9af24ea29494a279eba01d2b284c9c94d4fdb267 Mon Sep 17 00:00:00 2001
-+Message-Id: <9af24ea29494a279eba01d2b284c9c94d4fdb267.1563619497.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Sat, 20 Jul 2019 12:35:01 +0200
-+Subject: [PATCH 1/2] fritzcreator: replace obscure padding generation with
-+ something more compatible
-+
-+It as reported that OpenWrt/Gluon would sometimes generate invalid
-+bootloader images with insufficient for the FritzBox 4040, presumably
-+depending on the distro version used on the build host.
-+
-+This commit tries to fix this by replacing the printf-based padding
-+generation (that in one case relies on 65536 arguments being passed to the
-+printf command) with a more compatible read from /dev/zero.
-+
-+[1] https://github.com/freifunk-gluon/gluon/issues/1766
-+---
-+ fritz/fritzcreator.sh | 8 ++++----
-+ 1 file changed, 4 insertions(+), 4 deletions(-)
-+
-+diff --git a/fritz/fritzcreator.sh b/fritz/fritzcreator.sh
-+index 8ed0c08cc5ed..8ea412e5aca5 100755
-+--- a/fritz/fritzcreator.sh
-++++ b/fritz/fritzcreator.sh
-+@@ -55,7 +55,7 @@ cat "$FRITZ_DTB" "$FRITZ_DTB" "$FRITZ_DTB" "$FRITZ_DTB" >> $UBOOT_FRITZ4040
-+ rm -f "$FRITZ_DTB"
-+ 
-+ # Add 512 bytes of pad area
-+-printf "%0.s\0" {1..512} >> $UBOOT_FRITZ4040
-++dd if=/dev/zero bs=512 count=1 >> $UBOOT_FRITZ4040
-+ 
-+ # This table links to the individual DTBs for every HWSubRevision.
-+ # A table entry consists of two 32-bit words.
-+@@ -84,7 +84,7 @@ mv "$UBOOT_FRITZ4040.new" "$UBOOT_FRITZ4040"
-+ 
-+ 
-+ # Add 64k bytes of pad area
-+-printf "%0.s\0" {1..65536} >> $UBOOT_FRITZ4040
-++dd if=/dev/zero bs=1024 count=64 >> $UBOOT_FRITZ4040
-+ 
-+ # Pack it with lzma
-+ fritz/lzma e "$UBOOT_FRITZ4040" -lc1 -lp2 -pb2 "$UBOOT_FRITZ4040.new"
-+@@ -99,7 +99,7 @@ fritz/lzma2eva $UBOOT_LOADADDR $UBOOT_LOADADDR "$UBOOT_FRITZ4040.new" "$UBOOT_FR
-+ # The next bit. The hshqs partition should be aligned to 0x100
-+ let size=$(stat -c%s "$UBOOT_FRITZ4040")
-+ let "pad = 256 - ( $size % 256) % 256"
-+-( printf "%0.s\377" {1..256} | dd conv=sync bs=$pad count=1 ) > $UBOOT_FRITZ4040.pad
-++dd if=/dev/zero bs=$pad count=1 | tr '\0' '\377' > $UBOOT_FRITZ4040.pad
-+ 
-+ cat "$UBOOT_FRITZ4040" "$UBOOT_FRITZ4040.pad" > $UBOOT_FRITZ4040.new
-+ 
-+@@ -109,7 +109,7 @@ rm -f "$UBOOT_FRITZ4040.pad"
-+ 
-+ # Apparently, EVA checks for the SquashFS filesystem MAGIC too. Likely for the rootfs
-+ # entry.
-+-(cat "$UBOOT_FRITZ4040"; echo "hsqs"; printf "%0.s\0" {1..124} ) > $UBOOT_FRITZ4040.new
-++(cat "$UBOOT_FRITZ4040"; echo "hsqs"; dd if=/dev/zero bs=124 count=1 ) > $UBOOT_FRITZ4040.new
-+ 
-+ # Make it so that this fits into 512k (Note: we have to add 8 Bytes for the final checksum
-+ # so 524280 is 512k - 8.
-+-- 
-+2.22.0
-+
-diff --git a/package/boot/uboot-fritz4040/patches/201-fritzcreator-actually-add-checksum-spacer.patch b/package/boot/uboot-fritz4040/patches/201-fritzcreator-actually-add-checksum-spacer.patch
-new file mode 100644
-index 0000000000000000000000000000000000000000..f92060a23312a4961ddc75716fd06b9d6a106a1d
---- /dev/null
-+++ b/package/boot/uboot-fritz4040/patches/201-fritzcreator-actually-add-checksum-spacer.patch
-@@ -0,0 +1,30 @@
-+From dd05d1bb619b372e4717a74da560450dd93d4c3b Mon Sep 17 00:00:00 2001
-+Message-Id: <dd05d1bb619b372e4717a74da560450dd93d4c3b.1563619497.git.mschiffer@universe-factory.net>
-+In-Reply-To: <9af24ea29494a279eba01d2b284c9c94d4fdb267.1563619497.git.mschiffer@universe-factory.net>
-+References: <9af24ea29494a279eba01d2b284c9c94d4fdb267.1563619497.git.mschiffer@universe-factory.net>
-+From: Matthias Schiffer <mschiffer@universe-factory.net>
-+Date: Sat, 20 Jul 2019 12:43:48 +0200
-+Subject: [PATCH 2/2] fritzcreator: actually add checksum spacer
-+
-+The spacer was written to $UBOOT_FRITZ4040.new, but this file was not used
-+at all before it was overwritten again.
-+---
-+ fritz/fritzcreator.sh | 2 +-
-+ 1 file changed, 1 insertion(+), 1 deletion(-)
-+
-+diff --git a/fritz/fritzcreator.sh b/fritz/fritzcreator.sh
-+index 8ea412e5aca5..ea5a50df1f87 100755
-+--- a/fritz/fritzcreator.sh
-++++ b/fritz/fritzcreator.sh
-+@@ -94,7 +94,7 @@ fritz/lzma2eva $UBOOT_LOADADDR $UBOOT_LOADADDR "$UBOOT_FRITZ4040.new" "$UBOOT_FR
-+ 
-+ # The bootloader seems to add a TI checksum signature (8 Bytes) as part of the
-+ # "check mtd1" command in the FTP prompt. To make this easier we add spacer here.
-+-(cat "$UBOOT_FRITZ4040"; printf "\xff\xff\xff\xff\xff\xff\xff\xff" ) > $UBOOT_FRITZ4040.new
-++printf "\xff\xff\xff\xff\xff\xff\xff\xff" >> $UBOOT_FRITZ4040
-+ 
-+ # The next bit. The hshqs partition should be aligned to 0x100
-+ let size=$(stat -c%s "$UBOOT_FRITZ4040")
-+-- 
-+2.22.0
-+
-- 
GitLab